Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Keyboard: fix modifiers with X11/Wayland backend
The modifiers event is never emitted by the libinput backend.
The Wayland backend also has been working fine thus far despite
the modifiers event never being sent by the backend, the Wayland
protocol notifies the wlroots Wayland backend of the currently
held keys when focus is gained. However, the host compositor
changing modifier state through a side channel rather than a
key press was broken with the Wayland backend.
With the X11 backend, things were terribly broken since X11 does
not communicate the currently held keys when keyboard focus is gained.
It should work a lot better now, but do note that modifiers may be
out-of-sync with the host until the first key press after keyboard
focus is gained.
river/Keyboard.zig | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index 037eb8d..e2bb194 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -69,7 +69,16 @@ pub fn create(seat: *Seat, wlr_device: *wlr.InputDevice, virtual: bool) !*Keyboa
wlr_keyboard.events.key.add(&keyboard.key);
wlr_keyboard.events.modifiers.add(&keyboard.modifiers);
- wlr_keyboard.events.keymap.add(&keyboard.keymap);
+
+ if (virtual) {
+ wlr_keyboard.events.keymap.add(&keyboard.keymap);
+ } else {
+ keyboard.keymap.link.init();
+ // We must set a keymap even though this is not the wlr_keyboard river
+ // exposes to clients. If there is no keymap set, wlroots will not emit
+ // the modifiers event when using the Wayland or X11 backend.
+ _ = wlr_keyboard.setKeymap(keyboard.config.keymap);
+ }
return keyboard;
}
@@ -109,6 +118,7 @@ pub fn setRepeatInfo(keyboard: *Keyboard, rate: u31, delay: u31) void {
pub fn setKeymap(keyboard: *Keyboard, keymap: *xkb.Keymap) void {
assert(!keyboard.device.virtual);
+ _ = keyboard.device.wlr_device.toKeyboard().setKeymap(keymap);
if (keyboard.config.keymap) |old| old.unref();
keyboard.config.keymap = keymap.ref();
if (keyboard.group) |group| {