aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de>2024-01-03 21:30:46 +0100
committerIsaac Freund <mail@isaacfreund.com>2024-01-07 12:37:03 -0600
commitdd9933b6a15e415e63b52585301d9216ef57b3cf (patch)
tree6f231876927ad74a1904a56e1ef914e26e88ed4e
parent540ca043df650568bdee4d00b933ed6a13b5de70 (diff)
downloadriver-dd9933b6a15e415e63b52585301d9216ef57b3cf.tar.gz
river-dd9933b6a15e415e63b52585301d9216ef57b3cf.tar.xz
keyboard-groups: use globber for identifier matching
-rw-r--r--doc/riverctl.1.scd3
-rw-r--r--river/Keyboard.zig17
-rw-r--r--river/KeyboardGroup.zig37
-rw-r--r--river/command/keyboard_group.zig3
4 files changed, 41 insertions, 19 deletions
diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd
index 5553306..b46185d 100644
--- a/doc/riverctl.1.scd
+++ b/doc/riverctl.1.scd
@@ -442,7 +442,8 @@ matches everything while _\*\*_ and the empty string are invalid.
*keyboard-group-add* _group_name_ _input_device_name_
Add a keyboard to a keyboard group, identified by the keyboard's
input device name. Any currently connected and future keyboards with
- the given name will be added to the group.
+ the given name will be added to the group. Simple globbing patterns are
+ supported, see the rules section for further information on globs.
*keyboard-group-remove* _group_name_ _input_device_name_
Remove a keyboard from a keyboard group, identified by the keyboard's
diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index 97eae23..69c34b2 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -21,6 +21,7 @@ const assert = std.debug.assert;
const wlr = @import("wlroots");
const wl = @import("wayland").server.wl;
const xkb = @import("xkbcommon");
+const globber = @import("globber");
const server = &@import("main.zig").server;
const util = @import("util.zig");
@@ -52,13 +53,15 @@ pub fn init(self: *Self, seat: *Seat, wlr_device: *wlr.InputDevice) !void {
// 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 it = seat.keyboard_groups.first;
- while (it) |node| : (it = node.next) {
- if (node.data.identifiers.contains(self.device.identifier)) {
- // wlroots will log an error if this fails explaining the reason.
- _ = node.data.wlr_group.addKeyboard(wlr_keyboard);
- break;
+ // 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, self.device.identifier)) {
+ // wlroots will log an error if this fails explaining the reason.
+ _ = group_node.data.wlr_group.addKeyboard(wlr_keyboard);
+ break :outer;
+ }
}
}
diff --git a/river/KeyboardGroup.zig b/river/KeyboardGroup.zig
index 617c042..cf68bde 100644
--- a/river/KeyboardGroup.zig
+++ b/river/KeyboardGroup.zig
@@ -20,6 +20,7 @@ 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");
@@ -35,7 +36,7 @@ const Keyboard = @import("Keyboard.zig");
seat: *Seat,
wlr_group: *wlr.KeyboardGroup,
name: []const u8,
-identifiers: std.StringHashMapUnmanaged(void) = .{},
+globs: std.ArrayListUnmanaged([]const u8) = .{},
pub fn create(seat: *Seat, name: []const u8) !void {
log.debug("new keyboard group: '{s}'", .{name});
@@ -63,11 +64,11 @@ pub fn destroy(group: *KeyboardGroup) void {
log.debug("destroying keyboard group: '{s}'", .{group.name});
util.gpa.free(group.name);
- {
- var it = group.identifiers.keyIterator();
- while (it.next()) |id| util.gpa.free(id.*);
+
+ for (group.globs.items) |glob| {
+ util.gpa.free(glob);
}
- group.identifiers.deinit(util.gpa);
+ group.globs.deinit(util.gpa);
group.wlr_group.destroy();
@@ -77,14 +78,23 @@ pub fn destroy(group: *KeyboardGroup) void {
}
pub fn addIdentifier(group: *KeyboardGroup, new_id: []const u8) !void {
- if (group.identifiers.contains(new_id)) return;
+ 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);
- try group.identifiers.put(util.gpa, 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);
@@ -92,7 +102,7 @@ pub fn addIdentifier(group: *KeyboardGroup, new_id: []const u8) !void {
if (device.seat != group.seat) continue;
if (device.wlr_device.type != .keyboard) continue;
- if (mem.eql(u8, new_id, device.identifier)) {
+ 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())) {
@@ -108,8 +118,13 @@ pub fn addIdentifier(group: *KeyboardGroup, new_id: []const u8) !void {
}
pub fn removeIdentifier(group: *KeyboardGroup, id: []const u8) !void {
- if (group.identifiers.fetchRemove(id)) |kv| {
- util.gpa.free(kv.key);
+ 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);
@@ -117,7 +132,7 @@ pub fn removeIdentifier(group: *KeyboardGroup, id: []const u8) !void {
if (device.seat != group.seat) continue;
if (device.wlr_device.type != .keyboard) continue;
- if (mem.eql(u8, device.identifier, id)) {
+ 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/command/keyboard_group.zig b/river/command/keyboard_group.zig
index 4453006..442fbdc 100644
--- a/river/command/keyboard_group.zig
+++ b/river/command/keyboard_group.zig
@@ -17,6 +17,8 @@
const std = @import("std");
const mem = std.mem;
+const globber = @import("globber");
+
const server = &@import("../main.zig").server;
const util = @import("../util.zig");
@@ -69,6 +71,7 @@ pub fn keyboardGroupAdd(
out.* = msg;
return;
};
+ try globber.validate(args[2]);
try group.addIdentifier(args[2]);
}