Move passive grab handling to the X11 c-m backend
In order to detect the relevant mouse button presses and global keycombos over foreign windows on X11, mutter does:
- Set up passive button grabs on
- The currently focused toplevel window, on buttons 1/2/3 with super/alt modifiers pressed. To move, show menu, etc
- Every other unfocused toplevel window, on buttons 1/2/3 with no modifiers. In order to implement click-to-raise
- On button press handling:
- Let passively grabbed button events go be handled by the client in addition (
XIReplayDevice
). So pressing and dragging on a background window would both raise it and e.g. allow to select text. - For any other unforeseen circumstance, the events are thawed to the compositor until button release (
XISyncDevice
).
- Let passively grabbed button events go be handled by the client in addition (
- Set up passive key grabs for every global shortcut on
- The root window, for overlay/locate-pointer/next-group keygrabs, and all general shortcuts
- Every toplevel window, for all general shortcuts
- On key/shortcut event handling:
- Generally (
process_key_events()
), received shortcuts events are all thawed and consumed by the compositor (XIAsyncDevice
), except - Some shenanigans with locate_pointer and overlay keys, in order to detect press+release alone, but allow these keys to participate in (maybe client-side) shortcuts.
- Generally (
All of this interaction happens on the X11 backend's Display
connection, as that is the connection dealing with all input events and grabs. Most specifically, this only makes sense for the compositing-manager X11 backend, because the nested backend has the same benefits than the Wayland native backend of being able to handle all its own events without meddling with foreign windows.
It would make sense to move all these X11-dependent bits of under src/backends/x11/cm/
, a possible (although optimistic, and gory in the details) plan to handle this in a way that minimizes interactions and #define
s is:
- Adding MetaKeybindingManager API to either get the keybinding list, or let external code iterate through the keybindings (e.g. foreach()`)
- In MetaBackendX11CM:
- Track toplevel X11 windows in the backend, through MetaDisplay::window-created, MetaWindow::unmanage, MetaWindow::notify::decorated, and start/stop passive grabs from there.
- Set up passive button grabs on all windows, super/alt modifier dependent on focus
- Set up passive key grabs on all windows
- Deal with the changes in the focus window by tracking it through MetaDisplay::focus-window, in addition.
- Set up passive key grabs on the root window for overlay/locate-pointer/next-group, might need more MetaKeybindingManager accessors.
- Track toplevel X11 windows in the backend, through MetaDisplay::window-created, MetaWindow::unmanage, MetaWindow::notify::decorated, and start/stop passive grabs from there.
- Adding MetaBackend API generic API to hint what to do with the event queue (sync/async/replay)
- Implement in only in the x11-cm backend, through XIAllowEvents
- Call it after every button and key event in
src/core/
, with the appropriate hints
- Adding a MetaDisplay signal to hint keybinding changes, and again let the x11-cm backend update from there
I think this ties in nicely with other changes in the "frontend" layers, where src/wayland
and src/x11
handle themselves through signals from src/core/
.
A possible further improvement might be to make the MetaBackend API take a bi-state (e.g. consumed/let-through), instead of having knowledge about the special X11 freeze modes in src/core/
code. It might be possible to XIAsyncDevice and XISyncDevice conflated in the backend somehow, or decided within it, but any possible simplifications deserve a close look.
CC @bilelmoussaoui, this is the promised brain-dump :).