Daemon icon indicating copy to clipboard operation
Daemon copied to clipboard

Mouse capture issue on Mac

Open slipher opened this issue 3 years ago • 4 comments

Steps to reproduce:

  1. Launch Unvanquished in a window with a map, like ./daemon -set r_fullscreen 0 -set r_mode 9 +devmap plat23
  2. Click on Unvanquished's icon in the task bar before it finishes loading the map.
  3. 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.

slipher avatar May 26 '22 04:05 slipher

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.

slipher avatar May 26 '22 21:05 slipher

Good to know… and another argument in favor of recommending our own builds !

illwieckz avatar May 26 '22 22:05 illwieckz

The SDL 2.0.22 part would hopefully be solved by https://github.com/DaemonEngine/Daemon/issues/600.

necessarily-equal avatar Jun 22 '22 20:06 necessarily-equal

The SDL 2.0.22 part would hopefully be solved by #600.

The symptoms of these bugs don't look similar to me :\

slipher avatar Jun 22 '22 22:06 slipher

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.

illwieckz avatar May 10 '23 14:05 illwieckz

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

illwieckz avatar May 12 '23 12:05 illwieckz

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.

slipher avatar May 14 '23 17:05 slipher

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.

slipher avatar May 15 '23 10:05 slipher

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);
                }
        }
    }
}

slipher avatar May 15 '23 11:05 slipher

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.

slipher avatar May 15 '23 12:05 slipher

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).

slipher avatar May 15 '23 12:05 slipher

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

illwieckz avatar May 15 '23 12:05 illwieckz

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: @.***>

necessarily-equal avatar May 15 '23 13:05 necessarily-equal

Yes this bug can still be fixed with SDL 2.26.5

slipher avatar May 15 '23 17:05 slipher

This was fixed by #857 and https://github.com/Unvanquished/Unvanquished/pull/2695.

slipher avatar May 25 '23 20:05 slipher