YaLTeR / niri

A scrollable-tiling Wayland compositor.
https://matrix.to/#/#niri:matrix.org
GNU General Public License v3.0
4.14k stars 123 forks source link

Modifiers aren't sent to clients with pointer focus #826

Open sodiboo opened 4 days ago

sodiboo commented 4 days ago

The documentation for wl_keyboard::modifiers states:

The compositor may send this event without a surface of the client having keyboard focus, for example to tie modifier information to pointer focus instead.

But niri doesn't currently do this. It only sends this event upon keyboard focus.


You can notice this in e.g. a web browser. Focusing a tab in firefox, then focusing a different window entirely (and not another firefox window), then holding Shift and then pressing a different tab should cause the range of tabs to be selected. Instead, it only focuses the second tab. Do the same thing but don't focus a different window, and the range will be selected as expected.

This can also be noticed in my wayland backend branch, which now handles the modifiers event (https://github.com/sodiboo/niri/commit/8c1a0c529fca7823766da7574e27d2427b79ce8b). Unfocus the nested compositor, then hold Alt to initiate an interactive move, and try to move a window by LMB-dragging anywhere on it. Nothing will happen. You can only initiate interactive move with the modifier if the nested compositor is already focused. This is how i noticed the issue exists in the first place.


Given that routing of such events is mostly handled by Smithay, this might be an entirely smithay-side issue? But i'm not quite sure, and didn't feel like investigating to be honest. I have not extensively investigated whether other compositors have the same issue, but i'm pretty sure labwc does have the same issue.


System Information

YaLTeR commented 4 days ago

Interesting. Yeah I'm also not sure, might be something for Smithay to handle. Especially since pointer grabs arbitrarily modify which surface has pointer focus. (Which btw is why I recently renamed the niri variable from pointer_focus to pointer_contents.)