aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2020-04-07 21:48:56 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2020-04-07 21:48:56 +0200
commitfa653337897b327a62b25840bea1713c262f45a6 (patch)
treee7e54b0d861cf9eaa504ea9c266f88ed24cc1de9
parent15f97314a9a72685a3468dcb72bac4e534b05b35 (diff)
downloadriver-fa653337897b327a62b25840bea1713c262f45a6.tar.gz
river-fa653337897b327a62b25840bea1713c262f45a6.tar.xz
Refactor keybindings to be runtime defined.
-rw-r--r--src/command.zig31
-rw-r--r--src/config.zig62
-rw-r--r--src/keyboard.zig4
-rw-r--r--src/output.zig14
-rw-r--r--src/root.zig10
-rw-r--r--src/seat.zig13
-rw-r--r--src/server.zig44
-rw-r--r--src/view.zig6
8 files changed, 116 insertions, 68 deletions
diff --git a/src/command.zig b/src/command.zig
index 9c100f4..a325fe9 100644
--- a/src/command.zig
+++ b/src/command.zig
@@ -4,23 +4,33 @@ const c = @import("c.zig");
const Server = @import("server.zig").Server;
const ViewStack = @import("view_stack.zig").ViewStack;
+pub const Arg = union {
+ int: i32,
+ uint: u32,
+ float: f64,
+ none: void,
+};
+
+pub const Command = fn (server: *Server, arg: Arg) void;
+
/// Exit the compositor, terminating the wayland session.
-pub fn exitCompositor(server: *Server) void {
+pub fn exitCompositor(server: *Server, arg: Arg) void {
c.wl_display_terminate(server.wl_display);
}
/// Shift focus to the next visible view, wrapping if needed.
-pub fn focusNextView(server: *Server) void {
+pub fn focusNextView(server: *Server, arg: Arg) void {
server.root.focusNextView();
}
/// Shift focus to the previous visible view, wrapping if needed.
-pub fn focusPrevView(server: *Server) void {
+pub fn focusPrevView(server: *Server, arg: Arg) void {
server.root.focusPrevView();
}
/// Modify the number of master views
-pub fn modifyMasterCount(server: *Server, delta: i32) void {
+pub fn modifyMasterCount(server: *Server, arg: Arg) void {
+ const delta = arg.int;
server.root.master_count = @intCast(u32, std.math.max(
0,
@intCast(i32, server.root.master_count) + delta,
@@ -29,7 +39,8 @@ pub fn modifyMasterCount(server: *Server, delta: i32) void {
}
/// Modify the percent of the width of the screen that the master views occupy.
-pub fn modifyMasterFactor(server: *Server, delta: f64) void {
+pub fn modifyMasterFactor(server: *Server, arg: Arg) void {
+ const delta = arg.float;
const new_master_factor = std.math.min(
std.math.max(server.root.master_factor + delta, 0.05),
0.95,
@@ -42,7 +53,7 @@ pub fn modifyMasterFactor(server: *Server, delta: f64) void {
/// Bump the focused view to the top of the stack.
/// TODO: if the top of the stack is focused, bump the next visible view.
-pub fn zoom(server: *Server) void {
+pub fn zoom(server: *Server, arg: Arg) void {
if (server.root.focused_view) |current_focus| {
const node = @fieldParentPtr(ViewStack.Node, "view", current_focus);
if (node != server.root.views.first) {
@@ -54,13 +65,15 @@ pub fn zoom(server: *Server) void {
}
/// Switch focus to the passed tags.
-pub fn focusTags(server: *Server, tags: u32) void {
+pub fn focusTags(server: *Server, arg: Arg) void {
+ const tags = arg.uint;
server.root.pending_focused_tags = tags;
server.root.arrange();
}
/// Set the tags of the focused view.
-pub fn setFocusedViewTags(server: *Server, tags: u32) void {
+pub fn setFocusedViewTags(server: *Server, arg: Arg) void {
+ const tags = arg.uint;
if (server.root.focused_view) |view| {
if (view.current_tags != tags) {
view.pending_tags = tags;
@@ -71,7 +84,7 @@ pub fn setFocusedViewTags(server: *Server, tags: u32) void {
/// Spawn a program.
/// TODO: make this take a program as a paramter and spawn that
-pub fn spawn(server: *Server) void {
+pub fn spawn(server: *Server, arg: Arg) void {
const argv = [_][]const u8{ "/bin/sh", "-c", "alacritty" };
const child = std.ChildProcess.init(&argv, std.heap.c_allocator) catch unreachable;
std.ChildProcess.spawn(child) catch unreachable;
diff --git a/src/config.zig b/src/config.zig
new file mode 100644
index 0000000..ac67071
--- /dev/null
+++ b/src/config.zig
@@ -0,0 +1,62 @@
+const std = @import("std");
+const c = @import("c.zig");
+const command = @import("command.zig");
+
+const Server = @import("server.zig");
+
+pub const Config = struct {
+ const Self = @This();
+
+ /// Width of borders in pixels
+ border_width: u32 = 2,
+
+ /// Amount of view padding in pixels
+ view_padding: u32 = 10,
+
+ const Keybind = struct {
+ keysym: c.xkb_keysym_t,
+ modifiers: u32,
+ command: command.Command,
+ arg: command.Arg,
+ };
+
+ /// All user-defined keybindings
+ keybinds: std.ArrayList(Keybind),
+
+ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void {
+ self.border_width = 2;
+ self.view_padding = 10;
+
+ self.keybinds = std.ArrayList(Keybind).init(allocator);
+
+ const mod = c.WLR_MODIFIER_LOGO;
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_e, .modifiers = mod, .command = command.exitCompositor, .arg = .{ .none = {} } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_j, .modifiers = mod, .command = command.focusNextView, .arg = .{ .none = {} } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_k, .modifiers = mod, .command = command.focusPrevView, .arg = .{ .none = {} } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_h, .modifiers = mod, .command = command.modifyMasterFactor, .arg = .{ .float = 0.05 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_l, .modifiers = mod, .command = command.modifyMasterFactor, .arg = .{ .float = -0.05 } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_Return, .modifiers = mod, .command = command.zoom, .arg = .{ .none = {} } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_1, .modifiers = mod, .command = command.focusTags, .arg = .{ .uint = 1 << 0 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_2, .modifiers = mod, .command = command.focusTags, .arg = .{ .uint = 1 << 1 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_3, .modifiers = mod, .command = command.focusTags, .arg = .{ .uint = 1 << 2 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_4, .modifiers = mod, .command = command.focusTags, .arg = .{ .uint = 1 << 3 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_5, .modifiers = mod, .command = command.focusTags, .arg = .{ .uint = 1 << 4 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_6, .modifiers = mod, .command = command.focusTags, .arg = .{ .uint = 1 << 5 } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_h, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.modifyMasterCount, .arg = .{ .int = 1 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_l, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.modifyMasterCount, .arg = .{ .int = -1 } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_Return, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.spawn, .arg = .{ .none = {} } });
+
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_1, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 1 << 0 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_2, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 1 << 1 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_3, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 1 << 2 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_4, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 1 << 3 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_5, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 1 << 4 } });
+ try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_6, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 1 << 5 } });
+ }
+};
diff --git a/src/keyboard.zig b/src/keyboard.zig
index 8be9975..af2786f 100644
--- a/src/keyboard.zig
+++ b/src/keyboard.zig
@@ -112,7 +112,7 @@ pub const Keyboard = struct {
if (keyboard.handleBuiltinKeybind(translated_keysyms.?[i])) {
handled = true;
break;
- } else if (keyboard.seat.server.handleKeybinding(translated_keysyms.?[i], modifiers)) {
+ } else if (keyboard.seat.handleKeybinding(translated_keysyms.?[i], modifiers)) {
handled = true;
break;
}
@@ -123,7 +123,7 @@ pub const Keyboard = struct {
if (keyboard.handleBuiltinKeybind(raw_keysyms.?[i])) {
handled = true;
break;
- } else if (keyboard.seat.server.handleKeybinding(raw_keysyms.?[i], modifiers)) {
+ } else if (keyboard.seat.handleKeybinding(raw_keysyms.?[i], modifiers)) {
handled = true;
break;
}
diff --git a/src/output.zig b/src/output.zig
index 44fa5c4..790c8d2 100644
--- a/src/output.zig
+++ b/src/output.zig
@@ -129,8 +129,8 @@ pub const Output = struct {
// If we have a stashed buffer, we are in the middle of a transaction
// and need to render that buffer until the transaction is complete.
if (view.stashed_buffer) |buffer| {
- const border_width = view.root.border_width;
- const view_padding = view.root.view_padding;
+ const border_width = view.root.server.config.border_width;
+ const view_padding = view.root.server.config.view_padding;
var box = c.wlr_box{
.x = view.current_box.x + @intCast(i32, border_width + view_padding),
.y = view.current_box.y + @intCast(i32, border_width + view_padding),
@@ -194,11 +194,13 @@ pub const Output = struct {
return;
}
+ const border_width = view.root.server.config.border_width;
+ const view_padding = view.root.server.config.view_padding;
var box = c.wlr_box{
.x = @floatToInt(c_int, rdata.ox) + view.current_box.x + sx +
- @intCast(c_int, view.root.border_width + view.root.view_padding),
+ @intCast(c_int, border_width + view_padding),
.y = @floatToInt(c_int, rdata.oy) + view.current_box.y + sy +
- @intCast(c_int, view.root.border_width + view.root.view_padding),
+ @intCast(c_int, border_width + view_padding),
.width = surface.current.width,
.height = surface.current.height,
};
@@ -229,8 +231,8 @@ pub const Output = struct {
[_]f32{ 0.57647059, 0.63137255, 0.63137255, 1.0 } // Solarized base1
else
[_]f32{ 0.34509804, 0.43137255, 0.45882353, 1.0 }; // Solarized base01
- const border_width = self.root.border_width;
- const view_padding = self.root.view_padding;
+ const border_width = self.root.server.config.border_width;
+ const view_padding = self.root.server.config.view_padding;
// left border
border.x = @floatToInt(c_int, ox) + view.current_box.x + @intCast(c_int, view_padding);
diff --git a/src/root.zig b/src/root.zig
index 3754b8b..9700827 100644
--- a/src/root.zig
+++ b/src/root.zig
@@ -34,12 +34,6 @@ pub const Root = struct {
/// Percentage of the total screen that the master section takes up.
master_factor: f64,
- /// Width of borders in pixels
- border_width: u32,
-
- /// Amount of view padding in pixels
- view_padding: u32,
-
/// Number of pending configures sent in the current transaction.
/// A value of 0 means there is no current transaction.
pending_configures: u32,
@@ -69,10 +63,6 @@ pub const Root = struct {
self.master_factor = 0.6;
- self.border_width = 4;
-
- self.view_padding = 10;
-
self.pending_configures = 0;
self.transaction_timer = null;
diff --git a/src/seat.zig b/src/seat.zig
index 8767323..eacdf8d 100644
--- a/src/seat.zig
+++ b/src/seat.zig
@@ -41,6 +41,19 @@ pub const Seat = struct {
self.cursor.destroy();
}
+ /// Handle any user-defined keybinding for the passed keysym and modifiers
+ /// Returns true if the key was handled
+ pub fn handleKeybinding(self: Self, keysym: c.xkb_keysym_t, modifiers: u32) bool {
+ for (self.server.config.keybinds.items) |keybind| {
+ if (modifiers == keybind.modifiers and keysym == keybind.keysym) {
+ // Execute the bound command
+ keybind.command(self.server, keybind.arg);
+ return true;
+ }
+ }
+ return false;
+ }
+
fn addKeyboard(self: *Self, device: *c.wlr_input_device) !void {
c.wlr_seat_set_keyboard(self.wlr_seat, device);
diff --git a/src/server.zig b/src/server.zig
index d7c43f1..c729fd3 100644
--- a/src/server.zig
+++ b/src/server.zig
@@ -2,6 +2,7 @@ const std = @import("std");
const c = @import("c.zig");
const command = @import("command.zig");
+const Config = @import("config.zig").Config;
const DecorationManager = @import("decoration_manager.zig").DecorationManager;
const Output = @import("output.zig").Output;
const Root = @import("root.zig").Root;
@@ -25,6 +26,8 @@ pub const Server = struct {
root: Root,
seat: Seat,
+ config: Config,
+
listen_new_output: c.wl_listener,
listen_new_xdg_surface: c.wl_listener,
@@ -73,6 +76,8 @@ pub const Server = struct {
try self.seat.init(self);
+ try self.config.init(self.allocator);
+
// Register our listeners for new outputs and xdg_surfaces.
self.listen_new_output.notify = handleNewOutput;
c.wl_signal_add(&self.wlr_backend.events.new_output, &self.listen_new_output);
@@ -112,45 +117,6 @@ pub const Server = struct {
c.wl_display_run(self.wl_display);
}
- /// Handle all compositor keybindings
- /// Note: this is a hacky initial implementation for testing and will be rewritten eventually
- pub fn handleKeybinding(self: *Self, sym: c.xkb_keysym_t, modifiers: u32) bool {
- if (modifiers & @intCast(u32, c.WLR_MODIFIER_LOGO) == 0) {
- return false;
- }
- if (modifiers & @intCast(u32, c.WLR_MODIFIER_SHIFT) != 0) {
- switch (sym) {
- c.XKB_KEY_H => command.modifyMasterCount(self, 1),
- c.XKB_KEY_L => command.modifyMasterCount(self, -1),
- c.XKB_KEY_Return => command.spawn(self),
- c.XKB_KEY_1 => command.setFocusedViewTags(self, 1 << 0),
- c.XKB_KEY_2 => command.setFocusedViewTags(self, 1 << 1),
- c.XKB_KEY_3 => command.setFocusedViewTags(self, 1 << 2),
- c.XKB_KEY_4 => command.setFocusedViewTags(self, 1 << 3),
- c.XKB_KEY_5 => command.setFocusedViewTags(self, 1 << 4),
- c.XKB_KEY_6 => command.setFocusedViewTags(self, 1 << 5),
- else => return false,
- }
- } else {
- switch (sym) {
- c.XKB_KEY_e => command.exitCompositor(self),
- c.XKB_KEY_j => command.focusNextView(self),
- c.XKB_KEY_k => command.focusPrevView(self),
- c.XKB_KEY_h => command.modifyMasterFactor(self, 0.05),
- c.XKB_KEY_l => command.modifyMasterFactor(self, -0.05),
- c.XKB_KEY_Return => command.zoom(self),
- c.XKB_KEY_1 => command.focusTags(self, 1 << 0),
- c.XKB_KEY_2 => command.focusTags(self, 1 << 1),
- c.XKB_KEY_3 => command.focusTags(self, 1 << 2),
- c.XKB_KEY_4 => command.focusTags(self, 1 << 3),
- c.XKB_KEY_5 => command.focusTags(self, 1 << 4),
- c.XKB_KEY_6 => command.focusTags(self, 1 << 5),
- else => return false,
- }
- }
- return true;
- }
-
fn handleNewOutput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const server = @fieldParentPtr(Server, "listen_new_output", listener.?);
const wlr_output = @ptrCast(*c.wlr_output, @alignCast(@alignOf(*c.wlr_output), data));
diff --git a/src/view.zig b/src/view.zig
index b1a741c..17a0621 100644
--- a/src/view.zig
+++ b/src/view.zig
@@ -91,10 +91,12 @@ pub const View = struct {
pub fn configurePending(self: *Self) void {
if (self.pending_box) |pending_box| {
+ const border_width = self.root.server.config.border_width;
+ const view_padding = self.root.server.config.view_padding;
self.pending_serial = c.wlr_xdg_toplevel_set_size(
self.wlr_xdg_surface,
- pending_box.width - self.root.border_width * 2 - self.root.view_padding * 2,
- pending_box.height - self.root.border_width * 2 - self.root.view_padding * 2,
+ pending_box.width - border_width * 2 - view_padding * 2,
+ pending_box.height - border_width * 2 - view_padding * 2,
);
} else {
// TODO: log warning