Skip to content

X11: SDL_SetWindowMouseRect not working reliably #12671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
GoaLitiuM opened this issue Mar 29, 2025 · 7 comments
Open

X11: SDL_SetWindowMouseRect not working reliably #12671

GoaLitiuM opened this issue Mar 29, 2025 · 7 comments
Assignees
Milestone

Comments

@GoaLitiuM
Copy link

I'm trying to restrict the cursor to small area in the application, but the restriction does not seem to take place if the cursor is initially outside of the restricted area. On Windows and Wayland, the cursor is moved inside the area without needing to warp it explicitly, but X11 seems to require it.

Another issue occurs when I warp the cursor inside the area first before calling SDL_SetWindowMouseRect, the cursor can escape from the constrained region if the cursor is already being moved while warping it. This can be more easily reproduced by setting the rectangle very small.

I tried to reproduce this in one of the test samples, but running testsprite with --confine-cursor 40,40,10,10 does not restrict the cursor to the given area at all.

@slouken slouken added this to the 3.2.10 milestone Mar 29, 2025
@Kontrabant
Copy link
Contributor

An arbitrary confinement region in testsprite works for me on a real X11 session, but is broken on XWayland. Looking at XWayland, it doesn't seem to support confining to arbitrary regions at all, just the whole window or nothing.

https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/hw/xwayland/xwayland-input.c#L3578

@Kontrabant
Copy link
Contributor

Kontrabant commented Mar 30, 2025

On Windows and Wayland, the cursor is moved inside the area without needing to warp it explicitly, but X11 seems to require it.

I think this happens on Windows as a side-effect of the cursor clipping code, and if it is happening on Wayland, that's compositor-specific behavior, as neither the SDL mouse rect code, nor the backend Wayland code, is doing this.

I tried to reproduce this in one of the test samples, but running testsprite with --confine-cursor 40,40,10,10 does not restrict the cursor to the given area at all.

The testcursor example creates the confinement region before the window is actually mapped, which seems to result in some Wayland compositors ignoring the confinement region until it's recreated. I'm fixing the Wayland backend to defer creating the confinement region until the window is actually mapped, which fixes this.

If the confinement region is created while the pointer is outside of it, and the pointer then enters the confinement region at a later time, some compositors won't actually capture the pointer until a grabbing event such as a mouse click occurs. This is compositor behavior that we can't really do anything about.

Another issue occurs when I warp the cursor inside the area first before calling SDL_SetWindowMouseRect, the cursor can escape from the constrained region if the cursor is already being moved while warping it. This can be more easily reproduced by setting the rectangle very small.

We might be able to mitigate this by committing immediately after creating the confinement region, so that the double-buffered confinement region state takes effect sooner, although there are no guarantees since this is still ultimately racing the pointer, and if the compositor lets it escape, we can't do anything about it.

@Kontrabant
Copy link
Contributor

Kontrabant commented Mar 31, 2025

I pushed a couple of small fixes to address Wayland issues like the confinement region not working in testsprite, and the moving pointer escaping small regions.

Wayland compositor behavior is all over the place regarding arbitrary confinement regions (on KDE, it seems that it will never activate unless the pointer is inside of the region when it is created). I have an idea to normalize it, but it's much easier to build that on the changes in #12626

As I mentioned earlier, XWayland doesn't support confining the pointer to an arbitrary region within the window, so there's nothing we can do to fix that, unless they add support for it upstream.

@GoaLitiuM
Copy link
Author

I haven't tested the behaviour on XWayland, as I always use the Wayland driver on Wayland session (though I keep forgetting X11 driver is still the default one on Wayland session in test sample projects), where I haven't noticed any issues with the confinement region so far.

@slouken slouken modified the milestones: 3.2.10, 3.2.12 Mar 31, 2025
@slouken
Copy link
Collaborator

slouken commented Apr 24, 2025

@Kontrabant, is there anything we can do here, or should we close this as not planned?

@Kontrabant
Copy link
Contributor

I cleaned up the Wayland behavior in the multi-seat work for 3.4, so it is more consistent with other platforms (some compositors still have bugs that allow a pointer to escape if moving very quickly, but that's not our bug), but I have no idea what to do about X11. XWayland doesn't seem to support arbitrary barriers at all (just a whole window or nothing), and everything looks like it should work under a real X session as XFIXES reports the correct version and there are no reported errors, but neither GNOME nor KDE actually seem to honor the barriers (more X bitrot?)

@slouken
Copy link
Collaborator

slouken commented Apr 26, 2025

Okay, I’m going to move this out of the milestone, pending developments on the XWayland side.

@slouken slouken modified the milestones: 3.2.12, 3.x Apr 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants