fix: apply the X11 input shape before setIgnoreMouseEvents() returns (#54487)

The XShape request that setIgnoreMouseEvents() issues on X11 stayed in the
client-side output buffer until the UI thread next returned to its message
loop, so the window kept receiving (or kept ignoring) mouse events for as
long as the caller stayed busy. Round-trip to the server after updating the
region. A flush alone only writes the request to the socket; the server
gives no ordering guarantee between clients, so only a reply shows that the
shape is in place before another client's next request is processed.
This commit is contained in:
Shelley Vohr authored and GitHub committed 2026-09-28 08:01:59 +02:00
1 parent d1e8dad911
commit 4205b3641d
3 files changed
+13 -5

No files matched your search

+3 -1
View File
@@ -1421,7 +1421,9 @@ Makes the window ignore all mouse events.
All mouse events happened in this window will be passed to the window below
this window, but if this window has focus, it will still receive keyboard
events. On Linux this is supported on both X11 and Wayland.
events. On Linux this is supported on both X11 and Wayland. On X11 the X server
has applied the window's new input shape when the call returns; on Wayland the
new input region is applied with the window's next frame.
#### `win.setContentProtection(enable)` _macOS_ _Windows_
+3 -1
View File
@@ -1624,7 +1624,9 @@ Makes the window ignore all mouse events.
All mouse events happened in this window will be passed to the window below
this window, but if this window has focus, it will still receive keyboard
events. On Linux this is supported on both X11 and Wayland.
events. On Linux this is supported on both X11 and Wayland. On X11 the X server
has applied the window's new input shape when the call returns; on Wayland the
new input region is applied with the window's next frame.
#### `win.setContentProtection(enable)` _macOS_ _Windows_
+7 -3
View File
@@ -1414,10 +1414,14 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore, bool forward) {
views::DesktopWindowTreeHostLinux::GetHostForWidget(
GetAcceleratedWidget()))) {
tree_host->UpdateFrameHints();
// Wayland applies a new input region with the next surface commit; an
// idle window may not produce one for a while, so force a frame.
if (auto* compositor = tree_host->compositor())
if (x11_util::IsX11()) {
// Round-trip so the server has applied the input shape on return.
x11::Connection::Get()->Sync();
} else if (auto* compositor = tree_host->compositor()) {
// Wayland applies a new input region with the next surface commit; an
// idle window may not produce one for a while, so force a frame.
compositor->ScheduleFullRedraw();
}
}
#endif
}