git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit939dc6094e29a187e94f7c77534afdd79985b60d
parent81a6bfd760
authorIsaac Freund <[email protected]>
date2025-06-25 23:21
Keyboard: don't add virtual keyboards to group

Also don't set their keymap, the client handles that.

This is the first step towards fixing a regression with fcitx5.

(cherry picked from commit fe759d2d8a050c33cd7e6cf44202ec14ea1d30e1)

 river/InputManager.zig |  6 +++---
 river/Keyboard.zig     | 14 ++++++++------
 river/Seat.zig         | 10 +++++-----
 3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/river/InputManager.zig b/river/InputManager.zig
index 343cd7d..ec8ea50 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -151,7 +151,7 @@ pub fn reconfigureDevices(input_manager: *InputManager) void {
 fn handleNewInput(listener: *wl.Listener(*wlr.InputDevice), wlr_device: *wlr.InputDevice) void {
     const input_manager: *InputManager = @fieldParentPtr("new_input", listener);
 
-    input_manager.defaultSeat().addDevice(wlr_device);
+    input_manager.defaultSeat().addDevice(wlr_device, false);
 }
 
 fn handleNewVirtualPointer(
@@ -169,7 +169,7 @@ fn handleNewVirtualPointer(
         log.debug("Ignoring output suggestion from virtual pointer", .{});
     }
 
-    input_manager.defaultSeat().addDevice(&event.new_pointer.pointer.base);
+    input_manager.defaultSeat().addDevice(&event.new_pointer.pointer.base, true);
 }
 
 fn handleNewVirtualKeyboard(
@@ -177,7 +177,7 @@ fn handleNewVirtualKeyboard(
     virtual_keyboard: *wlr.VirtualKeyboardV1,
 ) void {
     const seat: *Seat = @alignCast(@ptrCast(virtual_keyboard.seat.data));
-    seat.addDevice(&virtual_keyboard.keyboard.base);
+    seat.addDevice(&virtual_keyboard.keyboard.base, true);
 }
 
 fn handleNewConstraint(
diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index bf27bbe..e3111ed 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -96,7 +96,7 @@ pressed: Pressed = .{},
 key: wl.Listener(*wlr.Keyboard.event.Key) = .init(queueKey),
 modifiers: wl.Listener(*wlr.Keyboard) = .init(queueModifiers),
 
-pub fn init(keyboard: *Keyboard, seat: *Seat, wlr_device: *wlr.InputDevice) !void {
+pub fn init(keyboard: *Keyboard, seat: *Seat, wlr_device: *wlr.InputDevice, virtual: bool) !void {
     keyboard.* = .{
         .device = undefined,
     };
@@ -106,12 +106,14 @@ pub fn init(keyboard: *Keyboard, seat: *Seat, wlr_device: *wlr.InputDevice) !voi
     const wlr_keyboard = keyboard.device.wlr_device.toKeyboard();
     wlr_keyboard.data = keyboard;
 
-    // wlroots will log a more detailed error if this fails.
-    if (!wlr_keyboard.setKeymap(server.config.keymap)) return error.OutOfMemory;
+    if (!virtual) {
+        // wlroots will log a more detailed error if this fails.
+        if (!wlr_keyboard.setKeymap(server.config.keymap)) return error.OutOfMemory;
 
-    if (wlr.KeyboardGroup.fromKeyboard(wlr_keyboard) == null) {
-        // wlroots will log an error on failure
-        _ = seat.keyboard_group.addKeyboard(wlr_keyboard);
+        if (wlr.KeyboardGroup.fromKeyboard(wlr_keyboard) == null) {
+            // wlroots will log an error on failure
+            _ = seat.keyboard_group.addKeyboard(wlr_keyboard);
+        }
     }
 
     wlr_keyboard.setRepeatInfo(server.config.repeat_rate, server.config.repeat_delay);
diff --git a/river/Seat.zig b/river/Seat.zig
index 225e6ba..30e0e27 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -202,7 +202,7 @@ pub fn create(name: [*:0]const u8) !void {
     try seat.cursor.init(seat);
     seat.relay.init();
 
-    try seat.tryAddDevice(&seat.keyboard_group.keyboard.base);
+    try seat.tryAddDevice(&seat.keyboard_group.keyboard.base, false);
 
     seat.wlr_seat.events.request_set_selection.add(&seat.request_set_selection);
     seat.wlr_seat.events.request_start_drag.add(&seat.request_start_drag);
@@ -695,19 +695,19 @@ pub fn updateOp(seat: *Seat, x: i32, y: i32) void {
     op.dirty = true;
 }
 
-pub fn addDevice(seat: *Seat, wlr_device: *wlr.InputDevice) void {
-    seat.tryAddDevice(wlr_device) catch |err| switch (err) {
+pub fn addDevice(seat: *Seat, wlr_device: *wlr.InputDevice, virtual: bool) void {
+    seat.tryAddDevice(wlr_device, virtual) catch |err| switch (err) {
         error.OutOfMemory => log.err("out of memory", .{}),
     };
 }
 
-fn tryAddDevice(seat: *Seat, wlr_device: *wlr.InputDevice) !void {
+fn tryAddDevice(seat: *Seat, wlr_device: *wlr.InputDevice, virtual: bool) !void {
     switch (wlr_device.type) {
         .keyboard => {
             const keyboard = try util.gpa.create(Keyboard);
             errdefer util.gpa.destroy(keyboard);
 
-            try keyboard.init(seat, wlr_device);
+            try keyboard.init(seat, wlr_device, virtual);
 
             seat.wlr_seat.setKeyboard(keyboard.device.wlr_device.toKeyboard());
             if (seat.wlr_seat.keyboard_state.focused_surface) |wlr_surface| {