aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Keyboard.zig13
-rw-r--r--river/KeycodeSet.zig5
-rw-r--r--river/Seat.zig38
3 files changed, 47 insertions, 9 deletions
diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index 3007e26..c93c7b2 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -17,6 +17,7 @@
const Self = @This();
const std = @import("std");
+const assert = std.debug.assert;
const wlr = @import("wlroots");
const wl = @import("wayland").server.wl;
const xkb = @import("xkbcommon");
@@ -61,6 +62,7 @@ pub fn init(self: *Self, seat: *Seat, input_device: *wlr.InputDevice) !void {
defer keymap.unref();
const wlr_keyboard = self.input_device.device.keyboard;
+ wlr_keyboard.data = @ptrToInt(self);
if (!wlr_keyboard.setKeymap(keymap)) return error.SetKeymapFailed;
@@ -111,9 +113,14 @@ fn handleKey(listener: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboa
if (!released and handleBuiltinMapping(sym)) return;
}
- // Handle user-defined mapping
- const mapped = self.seat.handleMapping(keycode, modifiers, released, xkb_state);
- if (mapped and !released) self.eaten_keycodes.add(event.keycode);
+ // Handle user-defined mappings
+ const mapped = self.seat.hasMapping(keycode, modifiers, released, xkb_state);
+ if (mapped) {
+ if (!released) self.eaten_keycodes.add(event.keycode);
+
+ const handled = self.seat.handleMapping(keycode, modifiers, released, xkb_state);
+ assert(handled);
+ }
const eaten = if (released) self.eaten_keycodes.remove(event.keycode) else mapped;
diff --git a/river/KeycodeSet.zig b/river/KeycodeSet.zig
index bceb039..a70e0ec 100644
--- a/river/KeycodeSet.zig
+++ b/river/KeycodeSet.zig
@@ -50,3 +50,8 @@ pub fn remove(self: *Self, old: u32) bool {
return false;
}
+
+/// Removes other's contents from self (if present)
+pub fn subtract(self: *Self, other: Self) void {
+ for (other.items[0..other.len]) |item| _ = self.remove(item);
+}
diff --git a/river/Seat.zig b/river/Seat.zig
index baf1056..54cd853 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -31,6 +31,7 @@ const DragIcon = @import("DragIcon.zig");
const Cursor = @import("Cursor.zig");
const InputManager = @import("InputManager.zig");
const Keyboard = @import("Keyboard.zig");
+const KeycodeSet = @import("KeycodeSet.zig");
const Switch = @import("Switch.zig");
const Mapping = @import("Mapping.zig");
const LayerSurface = @import("LayerSurface.zig");
@@ -253,12 +254,20 @@ pub fn setFocusRaw(self: *Self, new_focus: FocusTarget) void {
// Send keyboard enter/leave events and handle pointer constraints
if (target_surface) |wlr_surface| {
- if (self.wlr_seat.getKeyboard()) |keyboard| {
+ if (self.wlr_seat.getKeyboard()) |wlr_keyboard| {
+ var keycodes = KeycodeSet{
+ .items = wlr_keyboard.keycodes,
+ .len = wlr_keyboard.num_keycodes,
+ };
+
+ const keyboard = @intToPtr(*Keyboard, wlr_keyboard.data);
+ keycodes.subtract(keyboard.eaten_keycodes);
+
self.wlr_seat.keyboardNotifyEnter(
wlr_surface,
- &keyboard.keycodes,
- keyboard.num_keycodes,
- &keyboard.modifiers,
+ &keycodes.items,
+ keycodes.len,
+ &wlr_keyboard.modifiers,
);
} else {
self.wlr_seat.keyboardNotifyEnter(wlr_surface, null, 0, null);
@@ -349,8 +358,25 @@ pub fn handleViewUnmap(self: *Self, view: *View) void {
if (self.focused == .view and self.focused.view == view) self.focus(null);
}
+/// Is there a user-defined mapping for passed keycode, modifiers and keyboard state?
+pub fn hasMapping(
+ self: *Self,
+ keycode: xkb.Keycode,
+ modifiers: wlr.Keyboard.ModifierMask,
+ released: bool,
+ xkb_state: *xkb.State,
+) bool {
+ const modes = &server.config.modes;
+ for (modes.items[self.mode_id].mappings.items) |*mapping| {
+ if (mapping.match(keycode, modifiers, released, xkb_state)) {
+ return true;
+ }
+ }
+ return false;
+}
+
/// Handle any user-defined mapping for passed keycode, modifiers and keyboard state
-/// Returns true if the key was handled
+/// Returns true if at least one mapping was run
pub fn handleMapping(
self: *Self,
keycode: xkb.Keycode,
@@ -359,7 +385,7 @@ pub fn handleMapping(
xkb_state: *xkb.State,
) bool {
const modes = &server.config.modes;
- // In case more than on mapping matches, all of them are activated
+ // In case more than one mapping matches, all of them are activated
var handled = false;
for (modes.items[self.mode_id].mappings.items) |*mapping| {
if (mapping.match(keycode, modifiers, released, xkb_state)) {