winit icon indicating copy to clipboard operation
winit copied to clipboard

Changing the courser grab sometimes gives NotSupported(NotSupportedError) X11

Open benjamin-lieser opened this issue 2 years ago • 2 comments

I have the following code in my eventloop

WindowEvent::Focused(is_focused) => {
  let window = &mut state.as_mut().unwrap().2;
  if is_focused {
    window
      .set_cursor_grab(CursorGrabMode::Confined)
      .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))
      .unwrap();
    window.set_cursor_visible(false);
    window.set_fullscreen(Some(winit::window::Fullscreen::Borderless(None)));
  } else {
    window.set_fullscreen(None);
    window.set_cursor_grab(CursorGrabMode::None).unwrap();
    window.set_cursor_visible(true);
  }
}

I want to grab the courser and be in fullscreen only when I am in focus. Otherwise the courser is still confined in other windows which makes it unusable.

This works sometimes then using Super+Tab in Gnome, but when I get the window in focus again it gives the Err when grabbing the courser, which worked before.

On Windows is works completely as expected

benjamin-lieser avatar Sep 16 '23 11:09 benjamin-lieser

Could be due to the fact that you hit override redirect on X11 which could deny the request iirc. You could probably retry...

kchibisov avatar Sep 16 '23 11:09 kchibisov

I had the same problem, but as @kchibisov mentioned, you can simply retry it. Grabbing the cursor is blocked by X11 for a short time when tabbing back in. I just added a small delay, and it works perfectly now.

WindowEvent::Focused(focused) => {
    if let Some(window) = self.window.as_ref() {
        if focused {
            if let Err(_e) = window.set_cursor_grab(CursorGrabMode::Confined) {
                std::thread::sleep(std::time::Duration::from_millis(100));
                window.set_cursor_grab(CursorGrabMode::Confined).unwrap();
            }
            window.set_cursor_visible(false);
        } else {
            window.set_cursor_grab(CursorGrabMode::None).unwrap();
            window.set_cursor_visible(true);
        }
    }
}

Waiting 50 ms also works (probably even less), but I just wanted to make sure I exceed the blocking time, so I went with 100 ms.

Stoniye avatar Oct 11 '25 11:10 Stoniye