aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/riverctl.1.scd4
-rw-r--r--river/command.zig1
-rw-r--r--river/command/map.zig72
3 files changed, 55 insertions, 22 deletions
diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd
index 044af09..dc268e4 100644
--- a/doc/riverctl.1.scd
+++ b/doc/riverctl.1.scd
@@ -200,6 +200,10 @@ that tag 1 through 9 are visible.
Removes the mapping defined by the arguments *-release*, *modifiers* and *key* from *mode*.
See *map* for an explanation of the arguments.
+*unmap-pointer* _mode_ _modifiers_ _button_
+ Removes the mapping defined by the arguments *modifiers* and *button* from *mode*.
+ See *map-pointer* for an explanation of the arguments.
+
*view-padding* _pixels_
Set the padding around the edge of each view to _pixels_.
diff --git a/river/command.zig b/river/command.zig
index 998a9e0..0867ca7 100644
--- a/river/command.zig
+++ b/river/command.zig
@@ -76,6 +76,7 @@ const str_to_impl_fn = [_]struct {
.{ .name = "toggle-fullscreen", .impl = @import("command/toggle_fullscreen.zig").toggleFullscreen },
.{ .name = "toggle-view-tags", .impl = @import("command/tags.zig").toggleViewTags },
.{ .name = "unmap", .impl = @import("command/map.zig").unmap },
+ .{ .name = "unmap-pointer", .impl = @import("command/map.zig").unmapPointer },
.{ .name = "view-padding", .impl = @import("command/config.zig").viewPadding },
.{ .name = "xcursor-theme", .impl = @import("command/xcursor_theme.zig").xcursorTheme },
.{ .name = "zoom", .impl = @import("command/zoom.zig").zoom },
diff --git a/river/command/map.zig b/river/command/map.zig
index f97162e..c5b421d 100644
--- a/river/command/map.zig
+++ b/river/command/map.zig
@@ -89,29 +89,16 @@ pub fn mapPointer(
const mode_id = try modeNameToId(allocator, seat, args[1], out);
const modifiers = try parseModifiers(allocator, args[2], out);
+ const event_code = try parseEventCode(allocator, args[3], out);
- const event_code = blk: {
- const event_code_name = try std.cstr.addNullByte(allocator, args[3]);
- defer allocator.free(event_code_name);
- const ret = c.libevdev_event_code_from_name(c.EV_KEY, event_code_name);
- if (ret < 1) {
- out.* = try std.fmt.allocPrint(allocator, "unknown button {}", .{args[3]});
- return Error.Other;
- }
- break :blk @intCast(u32, ret);
- };
-
- // Check if the mapping already exists
const mode_pointer_mappings = &seat.input_manager.server.config.modes.items[mode_id].pointer_mappings;
- for (mode_pointer_mappings.items) |existing| {
- if (existing.event_code == event_code and existing.modifiers == modifiers) {
- out.* = try std.fmt.allocPrint(
- allocator,
- "a pointer mapping for modifiers '{}' and button '{}' already exists",
- .{ args[2], args[3] },
- );
- return Error.Other;
- }
+ if (pointerMappingExists(mode_pointer_mappings, modifiers, event_code)) |_| {
+ out.* = try std.fmt.allocPrint(
+ allocator,
+ "a pointer mapping for modifiers '{}' and button '{}' already exists",
+ .{ args[2], args[3] },
+ );
+ return Error.Other;
}
const action = if (std.mem.eql(u8, args[4], "move-view"))
@@ -139,7 +126,7 @@ fn modeNameToId(allocator: *std.mem.Allocator, seat: *Seat, mode_name: []const u
return config.mode_to_id.get(mode_name) orelse {
out.* = try std.fmt.allocPrint(
allocator,
- "cannot add mapping to non-existant mode '{}'",
+ "cannot add/remove mapping to/from non-existant mode '{}'",
.{mode_name},
);
return Error.Other;
@@ -157,6 +144,17 @@ fn mappingExists(mappings: *std.ArrayList(Mapping), modifiers: u32, keysym: u32,
return null;
}
+/// Returns the index of the PointerMapping with matching modifiers and event code, if any.
+fn pointerMappingExists(pointer_mappings: *std.ArrayList(PointerMapping), modifiers: u32, event_code: u32) ?usize {
+ for (pointer_mappings.items) |mapping, i| {
+ if (mapping.modifiers == modifiers and mapping.event_code == event_code) {
+ return i;
+ }
+ }
+
+ return null;
+}
+
fn parseEventCode(allocator: *std.mem.Allocator, event_code_str: []const u8, out: *?[]const u8) !u32 {
const event_code_name = try std.cstr.addNullByte(allocator, event_code_str);
defer allocator.free(event_code_name);
@@ -270,3 +268,33 @@ pub fn unmap(
var mapping = mode_mappings.swapRemove(mapping_idx);
mapping.deinit();
}
+
+/// Remove a pointer mapping for a given mode
+///
+/// Example:
+/// unmap-pointer normal Mod4 BTN_LEFT
+pub fn unmapPointer(
+ allocator: *std.mem.Allocator,
+ seat: *Seat,
+ args: []const []const u8,
+ out: *?[]const u8,
+) Error!void {
+ if (args.len < 4) return Error.NotEnoughArguments;
+ if (args.len > 4) return Error.TooManyArguments;
+
+ const mode_id = try modeNameToId(allocator, seat, args[1], out);
+ const modifiers = try parseModifiers(allocator, args[2], out);
+ const event_code = try parseEventCode(allocator, args[3], out);
+
+ const mode_pointer_mappings = &seat.input_manager.server.config.modes.items[mode_id].pointer_mappings;
+ const mapping_idx = pointerMappingExists(mode_pointer_mappings, modifiers, event_code) orelse {
+ out.* = try std.fmt.allocPrint(
+ allocator,
+ "there is no mapping for modifiers '{}' and button '{}'",
+ .{ args[2], args[3] },
+ );
+ return Error.Other;
+ };
+
+ _ = mode_pointer_mappings.swapRemove(mapping_idx);
+}