Mouse capture issue on Mac
Steps to reproduce:
- Launch Unvanquished in a window with a map, like
./daemon -set r_fullscreen 0 -set r_mode 9 +devmap plat23 - Click on Unvanquished's icon in the task bar before it finishes loading the map.
- Leave the cursor outside the window until loading finishes.
On 0.52 with SDL 2.0.12, the bug manifests as following: the cursor is outside the window, but the game responds to mouse movements (changing view direction). The program returns to a normal state upon moving the cursor into the window.
With SDL 2.0.22, the bug is worse. The game does not respond to mouse movements and does not capture the mouse, even if you move the mouse into the window and click on it. To get out of the buggy state you must click on another program and then click on Unvanquished again.
It's worse than I thought with 2.0.22. The bug occurs after every cgame restart, even if you keep the mouse in the window. I think I'll hold back SDL to 2.0.12 for the release.
Good to know… and another argument in favor of recommending our own builds !
The SDL 2.0.22 part would hopefully be solved by https://github.com/DaemonEngine/Daemon/issues/600.
The SDL 2.0.22 part would hopefully be solved by #600.
The symptoms of these bugs don't look similar to me :\
On 0.52 with SDL 2.0.12, the bug manifests as following: the cursor is outside the window, but the game responds to mouse movements (changing view direction). The program returns to a normal state upon moving the cursor into the window.
For information this bug is also present on Linux.
This is a game bug, the game should not capture the mouse on map loading screen to begin with:
- https://github.com/Unvanquished/Unvanquished/pull/2688
Another way to produce the bug is to start the game like ./daemon -resetconfig -set r_mode 7 -set r_fullscreen 0 +map parpax with the mouse outside the window when it starts, and then not touch anything until the map loads. I guess the important thing is that when the game loads the app has focus but the mouse is outside of it.
I think the problem is that IN_CenterMouse doesn't work when the cursor is outside the window.
Actually IN_CenterMouse just wasn't called when switching to deltas mode (I misread the code). With some difficulty I was able to get it to center the mouse in that case, but it still didn't help anything. The real problem is that the mouse does not get trapped in the window. When enabling deltas mode we do SDL_SetWindowGrab(SDL_ENABLE) and SDL_SetRelativeMouseMode(SDL_ENABLE), both of which are supposed to confine the cursor to the window, but they don't work. The cursor is not grabbed and it is still possible to move the cursor outside the window. The mouse is only grabbed after you click inside the window.
Some more ways to produce the bug:
- Open the console, move the cursor outside the window, then close the console
- Click on Unvanquished in the taskbar while it is unfocused
On Windows there is the correct behavior in all cases: whenever Deltas mode is activated, the cursor gets confined to the window (regardless of where it was located before). On Mac the APIs are not working as advertised in the case that the cursor starts outside the window.
In the simple test program below, SDL_SetWindowGrab works as expected. When enabled it relocates the cursor to the inside of the window and prevents it from escaping. (SDL_SetRelativeMouseMode, on the other hand, does not keep the cursor confined on its own.) So something within the greater complexity of Daemon makes it not work.
#include <SDL.h>
#include <iostream>
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
int main(int arc, char ** argv) {
if (SDL_Init( SDL_INIT_VIDEO ) < 0) {
std::cout << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
}
auto* window = SDL_CreateWindow(
"SDL2 Demo",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN
);
bool grabby = false;
while (true) {
SDL_Event e;
SDL_WaitEvent(&e);
switch (e.type) {
case SDL_QUIT:
return 0;
case SDL_KEYDOWN:
if (e.key.keysym.sym == SDLK_SPACE ) {
grabby = !grabby;
std::cout << "grabby set to " << grabby << std::endl;
SDL_SetWindowGrab(window, (SDL_bool)grabby);
//SDL_SetRelativeMouseMode((SDL_bool)grabby);
}
}
}
}
Oh, it's precisely SDL_SetRelativeMouseMode that makes it not work! If I uncomment the call to SDL_SetRelativeMouseMode in the demo above, then grabbing no longer works if the cursor is outside the window.
The demo with both SDL_SetWindowGrab and SDL_SetRelativeMouseMode is broken on SDL 2.0.12, but works on SDL 2.0.22. And I have found that this bug (#628) is fixed by the combination of updating to newer SDL and adding a call to SDL_PumpEvents (#871).
The demo with both SDL_SetWindowGrab and SDL_SetRelativeMouseMode is broken on SDL 2.0.12, but works on SDL 2.0.22. And I have found that this bug (#628) is fixed by the combination of updating to newer SDL and adding a call to SDL_PumpEvents (#871).
Does updating to SDL2 2.26.5 still works?
- https://github.com/DaemonEngine/Daemon/pull/857
Let's avoid testing things with SDL 2.0.22, because there is a related regression https://github.com/libsdl-org/SDL/issues/5569.
On Mon, May 15 2023 at 05:31:30 -07:00:00, Thomas Debesse @.***> wrote:
The demo with both SDL_SetWindowGrab and SDL_SetRelativeMouseMode is broken on SDL 2.0.12, but works on SDL 2.0.22. And I have found that this bug (#628) is fixed by the combination of updating to newer SDL and adding a call to SDL_PumpEvents (#871).
Does updating to SDL2 2.26.5 still works?
#857 — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
Yes this bug can still be fixed with SDL 2.26.5
This was fixed by #857 and https://github.com/Unvanquished/Unvanquished/pull/2695.