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

commit81a6bfd7604f3329b45a7da30b0602ffa5158902
parent4d6f699fdd
authorIsaac Freund <[email protected]>
date2025-07-13 11:22
river: remove dead keyboard group code

 river/Keyboard.zig      |  13 ++---
 river/KeyboardGroup.zig | 141 ------------------------------------------------
 river/Seat.zig          |  10 ++--
 3 files changed, 8 insertions(+), 156 deletions(-)

diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index d36214c..bf27bbe 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -109,16 +109,9 @@ pub fn init(keyboard: *Keyboard, seat: *Seat, wlr_device: *wlr.InputDevice) !voi
     // wlroots will log a more detailed error if this fails.
     if (!wlr_keyboard.setKeymap(server.config.keymap)) return error.OutOfMemory;
 
-    // Add to keyboard-group, if applicable.
-    var group_it = seat.keyboard_groups.first;
-    outer: while (group_it) |group_node| : (group_it = group_node.next) {
-        for (group_node.data.globs.items) |glob| {
-            if (globber.match(glob, keyboard.device.identifier)) {
-                // wlroots will log an error if this fails explaining the reason.
-                _ = group_node.data.wlr_group.addKeyboard(wlr_keyboard);
-                break :outer;
-            }
-        }
+    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/KeyboardGroup.zig b/river/KeyboardGroup.zig
deleted file mode 100644
index 74c98a1..0000000
--- a/river/KeyboardGroup.zig
+++ /dev/null
@@ -1,141 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2022 The River Developers
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-const KeyboardGroup = @This();
-
-const std = @import("std");
-const assert = std.debug.assert;
-const mem = std.mem;
-
-const globber = @import("globber");
-const wlr = @import("wlroots");
-const wl = @import("wayland").server.wl;
-const xkb = @import("xkbcommon");
-
-const log = std.log.scoped(.input);
-
-const server = &@import("main.zig").server;
-const util = @import("util.zig");
-
-const Seat = @import("Seat.zig");
-const Keyboard = @import("Keyboard.zig");
-
-seat: *Seat,
-wlr_group: *wlr.KeyboardGroup,
-name: []const u8,
-globs: std.ArrayListUnmanaged([]const u8) = .{},
-
-pub fn create(seat: *Seat, name: []const u8) !void {
-    log.debug("new keyboard group: '{s}'", .{name});
-
-    const node = try util.gpa.create(std.TailQueue(KeyboardGroup).Node);
-    errdefer util.gpa.destroy(node);
-
-    const wlr_group = try wlr.KeyboardGroup.create();
-    errdefer wlr_group.destroy();
-
-    const owned_name = try util.gpa.dupe(u8, name);
-    errdefer util.gpa.free(owned_name);
-
-    node.data = .{
-        .wlr_group = wlr_group,
-        .name = owned_name,
-        .seat = seat,
-    };
-
-    seat.addDevice(&wlr_group.keyboard.base);
-    seat.keyboard_groups.append(node);
-}
-
-pub fn destroy(group: *KeyboardGroup) void {
-    log.debug("destroying keyboard group: '{s}'", .{group.name});
-
-    util.gpa.free(group.name);
-
-    for (group.globs.items) |glob| {
-        util.gpa.free(glob);
-    }
-    group.globs.deinit(util.gpa);
-
-    group.wlr_group.destroy();
-
-    const node: *std.DoublyLinkedList(KeyboardGroup).Node = @fieldParentPtr("data", group);
-    group.seat.keyboard_groups.remove(node);
-    util.gpa.destroy(node);
-}
-
-pub fn addIdentifier(group: *KeyboardGroup, new_id: []const u8) !void {
-    for (group.globs.items) |glob| {
-        if (mem.eql(u8, glob, new_id)) return;
-    }
-
-    log.debug("keyboard group '{s}' adding identifier: '{s}'", .{ group.name, new_id });
-
-    const owned_id = try util.gpa.dupe(u8, new_id);
-    errdefer util.gpa.free(owned_id);
-
-    // Glob is validated in the command handler.
-    try group.globs.append(util.gpa, owned_id);
-    errdefer {
-        // Not used now, but if at any point this function is modified to that
-        // it may return an error after the glob pattern is added to the list,
-        // the list will have a pointer to freed memory in its last position.
-        _ = group.globs.pop();
-    }
-
-    // Add any existing matching keyboards to the group.
-    var it = server.input_manager.devices.iterator(.forward);
-    while (it.next()) |device| {
-        if (device.seat != group.seat) continue;
-        if (device.wlr_device.type != .keyboard) continue;
-
-        if (globber.match(device.identifier, new_id)) {
-            log.debug("found existing matching keyboard; adding to group", .{});
-
-            if (!group.wlr_group.addKeyboard(device.wlr_device.toKeyboard())) {
-                // wlroots logs an error message to explain why this failed.
-                continue;
-            }
-        }
-
-        // Continue, because we may have more than one device with the exact
-        // same identifier. That is in fact one reason for the keyboard group
-        // feature to exist in the first place.
-    }
-}
-
-pub fn removeIdentifier(group: *KeyboardGroup, id: []const u8) !void {
-    for (group.globs.items, 0..) |glob, index| {
-        if (mem.eql(u8, glob, id)) {
-            _ = group.globs.orderedRemove(index);
-            break;
-        }
-    } else {
-        return;
-    }
-
-    var it = server.input_manager.devices.iterator(.forward);
-    while (it.next()) |device| {
-        if (device.seat != group.seat) continue;
-        if (device.wlr_device.type != .keyboard) continue;
-
-        if (globber.match(device.identifier, id)) {
-            const wlr_keyboard = device.wlr_device.toKeyboard();
-            assert(wlr_keyboard.group == group.wlr_group);
-            group.wlr_group.removeKeyboard(wlr_keyboard);
-        }
-    }
-}
diff --git a/river/Seat.zig b/river/Seat.zig
index 6432b5d..225e6ba 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -34,7 +34,6 @@ const InputDevice = @import("InputDevice.zig");
 const InputManager = @import("InputManager.zig");
 const InputRelay = @import("InputRelay.zig");
 const Keyboard = @import("Keyboard.zig");
-const KeyboardGroup = @import("KeyboardGroup.zig");
 const LockSurface = @import("LockSurface.zig");
 const Output = @import("Output.zig");
 const PointerBinding = @import("PointerBinding.zig");
@@ -159,7 +158,7 @@ op: ?struct {
 
 relay: InputRelay,
 
-keyboard_groups: std.DoublyLinkedList(KeyboardGroup) = .{},
+keyboard_group: *wlr.KeyboardGroup,
 
 focused: Focus = .none,
 
@@ -189,6 +188,7 @@ pub fn create(name: [*:0]const u8) !void {
         .pointer_bindings = undefined,
         .cursor = undefined,
         .relay = undefined,
+        .keyboard_group = try wlr.KeyboardGroup.create(),
     };
     seat.wlr_seat.data = seat;
 
@@ -202,6 +202,8 @@ pub fn create(name: [*:0]const u8) !void {
     try seat.cursor.init(seat);
     seat.relay.init();
 
+    try seat.tryAddDevice(&seat.keyboard_group.keyboard.base);
+
     seat.wlr_seat.events.request_set_selection.add(&seat.request_set_selection);
     seat.wlr_seat.events.request_start_drag.add(&seat.request_start_drag);
     seat.wlr_seat.events.start_drag.add(&seat.start_drag);
@@ -219,9 +221,7 @@ pub fn destroy(seat: *Seat) void {
 
     seat.cursor.deinit();
 
-    while (seat.keyboard_groups.first) |node| {
-        node.data.destroy();
-    }
+    seat.keyboard_group.destroy();
 
     seat.request_set_selection.link.remove();
     seat.request_start_drag.link.remove();