libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.98k stars 1.84k forks source link

`SDL_SetRelativeMouseMode` in `SDL_EVENT_MOUSE_BUTTON_DOWN` blocks until the button is released #10014

Closed KislyjKisel closed 5 months ago

KislyjKisel commented 5 months ago

1 is printed on left click, 2 is printed only release.

Platform: Fedora, X11

MRE:

#include <SDL3/SDL.h>
#include <stdio.h>

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  SDL_Window* mainWindow = SDL_CreateWindow("Main", 800, 600, 0);
  SDL_Event e;
  int quit = 0;
  while(!quit) {
    while(SDL_PollEvent(&e)) {
      switch (e.type) {
        case SDL_EVENT_QUIT:
          quit = 1;
          break;
        case SDL_EVENT_MOUSE_BUTTON_DOWN:
          if (e.button.button == 1) {
            printf("1\n");
            SDL_SetRelativeMouseMode(SDL_TRUE);
            printf("2\n");
          }
          break;
      }
    }
  }
  SDL_DestroyWindow(mainWindow);
  SDL_Quit();
  return 0;
}
Kontrabant commented 5 months ago

This sound similar to #9917

What is happening is that something else has already grabbed the mouse (XInput2 does this on button presses), resulting in XPointerGrab returning AlreadyGrabbed, which causes the backend to loop for 5 seconds while attempting to grab the mouse, until it times out.

Issuing an XUngrabPointer request before trying to grab the mouse for capturing purposes should fix this.