From d9ebb6197d7d52861be089c6e778818fb73b199c Mon Sep 17 00:00:00 2001 From: Harrison DiAmbrosio Date: Sun, 26 Oct 2025 21:17:23 -0400 Subject: [PATCH] keyboard groups work in drm mode --- output.txt | 27 +++++++++++++++++++++++++++ src/cursor.zig | 2 +- src/keyboard.zig | 28 +++++++++++++--------------- src/seat.zig | 26 ++++++++++++++++++++++++++ src/server.zig | 6 ++---- src/view.zig | 4 ++-- 6 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 output.txt diff --git a/output.txt b/output.txt new file mode 100644 index 0000000..109e1bc --- /dev/null +++ b/output.txt @@ -0,0 +1,27 @@ +info: Starting mezzaluna +info: Creating root of mezzaluna + +debug: Loaded lua +info: Starting backend +error: New input request for input that is not a keyboard or pointer: Lid Switch +info: Handling a new output - eDP-1 +debug: adding output: eDP-1 +info: Starting server +warn: wayland.c:1777: compositor does not implement the primary selection interface +warn: wayland.c:1780: compositor does not implement XDG activation, bell.urgent will fall back to coloring the window margins red +warn: wayland.c:1786: compositor does not implement fractional scaling +warn: wayland.c:1789: compositor does not implement server-side cursors, falling back to client-side cursors +warn: wayland.c:1794: compositor does not implement the XDG toplevel icon protocol +warn: wayland.c:1799: text input interface not implemented by compositor; IME will be disabled +debug: Request for new toplevel +debug: Mapping view 'foot' +Segmentation fault at address 0xc8f8920 +???:?:?: 0xc8f8920 in ??? (???) +Unwind information for `???:0xc8f8920` was not available, trace may be incomplete + + err: wayland.c:1675: failed to read events from the Wayland socket: Broken pipe + err: wayland.c:2318: failed to roundtrip Wayland display: Broken pipe + err: wayland.c:2318: failed to roundtrip Wayland display: Broken pipe + err: wayland.c:2318: failed to roundtrip Wayland display: Broken pipe +warn: terminal.c:2029: slave exited with signal 1 (Hangup) + err: wayland.c:2283: failed to flush wayland socket: Broken pipe diff --git a/src/cursor.zig b/src/cursor.zig index 5cf3f62..f5726d6 100644 --- a/src/cursor.zig +++ b/src/cursor.zig @@ -138,7 +138,7 @@ fn handleButton( switch (event.state) { .pressed => { - if(server.keyboard.wlr_keyboard.getModifiers().alt) { + if(server.seat.keyboard_group.keyboard.getModifiers().alt) { // Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE if(server.seat.focused_view) |view| { // Keep track of where the drag started diff --git a/src/keyboard.zig b/src/keyboard.zig index 0c168e1..96d070c 100644 --- a/src/keyboard.zig +++ b/src/keyboard.zig @@ -7,6 +7,7 @@ const std = @import("std"); const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; const Keymap = @import("keymap.zig"); +const Utils = @import("utils.zig"); const wl = @import("wayland").server.wl; const wlr = @import("wlroots"); @@ -16,8 +17,6 @@ wlr_keyboard: *wlr.Keyboard, context: *xkb.Context, device: *wlr.InputDevice, -keyboards: wl.list.Head(Keyboard, .link) = undefined, - link: wl.list.Link = undefined, // Keyboard listeners @@ -28,8 +27,9 @@ modifiers: wl.Listener(*wlr.Keyboard) = .init(handleModifiers), // Device listeners destroy: wl.Listener(*wlr.InputDevice) = .init(handleDestroy), +pub fn init(device: *wlr.InputDevice) *Keyboard { + const self = gpa.create(Keyboard) catch Utils.oomPanic(); -pub fn init(self: *Keyboard, device: *wlr.InputDevice) void { errdefer { std.log.err("Unable to initialize new keyboard, exiting", .{}); std.process.exit(6); @@ -40,14 +40,10 @@ pub fn init(self: *Keyboard, device: *wlr.InputDevice) void { .wlr_keyboard = device.toKeyboard(), .device = device, }; - defer self.context.unref(); - - const keymap = xkb.Keymap.newFromNames(self.context, null, .no_flags) orelse return error.KeymapFailed; - defer keymap.unref(); // TODO: configure this via lua later // Should handle this error here - if (!self.wlr_keyboard.setKeymap(keymap)) return error.SetKeymapFailed; + if (!self.wlr_keyboard.setKeymap(server.seat.keymap)) return error.SetKeymapFailed; self.wlr_keyboard.setRepeatInfo(25, 600); self.wlr_keyboard.events.modifiers.add(&self.modifiers); @@ -56,12 +52,14 @@ pub fn init(self: *Keyboard, device: *wlr.InputDevice) void { device.events.destroy.add(&self.destroy); - std.log.debug("adding keyboard: {s}", .{self.wlr_keyboard.base.name orelse "(null)"}); + self.wlr_keyboard.data = self; - server.seat.wlr_seat.setKeyboard(self.wlr_keyboard); + std.log.err("Adding new keyboard {s}", .{device.name orelse "(unnamed)"}); + if(!server.seat.keyboard_group.addKeyboard(self.wlr_keyboard)) { + std.log.err("Adding new keyboard {s} failed", .{device.name orelse "(unnamed)"}); + } - self.keyboards.init(); - self.keyboards.append(self); + return self; } pub fn deinit (self: *Keyboard) void { @@ -80,8 +78,8 @@ fn handleKey(_: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboard.even const keycode = event.keycode + 8; var handled = false; - const modifiers = server.keyboard.wlr_keyboard.getModifiers(); - for (server.keyboard.wlr_keyboard.xkb_state.?.keyGetSyms(keycode)) |sym| { + const modifiers = server.seat.keyboard_group.keyboard.getModifiers(); + for (server.seat.keyboard_group.keyboard.xkb_state.?.keyGetSyms(keycode)) |sym| { if (server.keymaps.get(Keymap.hash(modifiers, sym))) |map| { if (event.state == .pressed and map.lua_press_ref_idx > 0) { map.callback(false); @@ -94,7 +92,7 @@ fn handleKey(_: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboard.even } if (!handled) { - server.seat.wlr_seat.setKeyboard(server.keyboard.wlr_keyboard); + server.seat.wlr_seat.setKeyboard(&server.seat.keyboard_group.keyboard); server.seat.wlr_seat.keyboardNotifyKey(event.time_msec, event.keycode, event.state); } } diff --git a/src/seat.zig b/src/seat.zig index 02950fb..279ae0a 100644 --- a/src/seat.zig +++ b/src/seat.zig @@ -3,6 +3,7 @@ const Seat = @This(); const std = @import("std"); const wlr = @import("wlroots"); const wl = @import("wayland").server.wl; +const xkb = @import("xkbcommon"); const Utils = @import("utils.zig"); const View = @import("view.zig"); @@ -14,6 +15,9 @@ wlr_seat: *wlr.Seat, focused_view: ?*View, focused_output: ?*Output, +keyboard_group: *wlr.KeyboardGroup, +keymap: *xkb.Keymap, + request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = .init(handleRequestSetCursor), request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = .init(handleRequestSetSelection), // request_set_primary_selection @@ -22,11 +26,32 @@ request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = .init( pub fn init(self: *Seat) void { errdefer Utils.oomPanic(); + const xkb_context = xkb.Context.new(.no_flags) orelse { + std.log.err("Unable to create a xkb context, exiting", .{}); + std.process.exit(7); + }; + defer xkb_context.unref(); + + const keymap = xkb.Keymap.newFromNames(xkb_context, null, .no_flags) orelse { + std.log.err("Unable to create a xkb keymap, exiting", .{}); + std.process.exit(8); + }; + defer keymap.unref(); + self.* = .{ .wlr_seat = try wlr.Seat.create(server.wl_server, "default"), .focused_view = null, .focused_output = null, + .keyboard_group = try wlr.KeyboardGroup.create(), + .keymap = keymap.ref(), }; + errdefer { + self.keyboard_group.destroy(); + self.wlr_seat.destroy(); + } + + _ = self.keyboard_group.keyboard.setKeymap(self.keymap); + self.wlr_seat.setKeyboard(&self.keyboard_group.keyboard); self.wlr_seat.events.request_set_cursor.add(&self.request_set_cursor); self.wlr_seat.events.request_set_selection.add(&self.request_set_selection); @@ -36,6 +61,7 @@ pub fn deinit(self: *Seat) void { self.request_set_cursor.link.remove(); self.request_set_selection.link.remove(); + self.keyboard_group.destroy(); self.wlr_seat.destroy(); } diff --git a/src/server.zig b/src/server.zig index f2fb4cb..d564f4f 100644 --- a/src/server.zig +++ b/src/server.zig @@ -34,7 +34,6 @@ allocator: *wlr.Allocator, root: Root, seat: Seat, cursor: Cursor, -keyboard: Keyboard, keymaps: std.AutoHashMap(u64, Keymap), // Backend listeners @@ -90,7 +89,6 @@ pub fn init(self: *Server) void { .root = undefined, .seat = undefined, .cursor = undefined, - .keyboard = undefined, .keymaps = .init(gpa), }; @@ -145,7 +143,7 @@ fn handleNewInput( device: *wlr.InputDevice ) void { switch (device.type) { - .keyboard => server.keyboard.init(device), + .keyboard => _ = Keyboard.init(device), .pointer => server.cursor.wlr_cursor.attachInputDevice(device), else => { std.log.err( @@ -157,7 +155,7 @@ fn handleNewInput( server.seat.wlr_seat.setCapabilities(.{ .pointer = true, - .keyboard = server.keyboard.keyboards.length() > 0, + .keyboard = true, }); } diff --git a/src/view.zig b/src/view.zig index f210922..bedb2c7 100644 --- a/src/view.zig +++ b/src/view.zig @@ -110,8 +110,8 @@ fn handleMap(listener: *wl.Listener(void)) void { const xdg_surface = view.xdg_toplevel.base; server.seat.wlr_seat.keyboardNotifyEnter( xdg_surface.surface, - server.keyboard.wlr_keyboard.keycodes[0..server.keyboard.wlr_keyboard.num_keycodes], - &server.keyboard.wlr_keyboard.modifiers + server.seat.keyboard_group.keyboard.keycodes[0..server.seat.keyboard_group.keyboard.num_keycodes], + &server.seat.keyboard_group.keyboard.modifiers ); if(view.xdg_toplevel_decoration) |decoration| {