diff options
| author | Isaac Freund <ifreund@ifreund.xyz> | 2020-03-27 02:05:57 +0100 |
|---|---|---|
| committer | Isaac Freund <ifreund@ifreund.xyz> | 2020-03-27 02:05:57 +0100 |
| commit | 51e81910314331f696eb3dd9aefb4bf341feaf42 (patch) | |
| tree | b26a5fc9bc91cd318892974344902974dc044e65 /src/root.zig | |
| parent | 647545d9fbf1993c488d1d5352225d9f4b57b67d (diff) | |
| download | river-51e81910314331f696eb3dd9aefb4bf341feaf42.tar.gz river-51e81910314331f696eb3dd9aefb4bf341feaf42.tar.xz | |
Flesh out focus handling and add keybinds
Diffstat (limited to 'src/root.zig')
| -rw-r--r-- | src/root.zig | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/root.zig b/src/root.zig index e31d2e1..77efc27 100644 --- a/src/root.zig +++ b/src/root.zig @@ -19,13 +19,14 @@ pub const Root = struct { views: std.TailQueue(View), unmapped_views: std.TailQueue(View), + focused_view: ?*View, + // Number of pending configures sent in the current transaction. // A value of 0 means there is no current transaction. pending_count: u32, pub fn init(self: *Self, server: *Server) !void { self.server = server; - self.pending_count = 0; // Create an output layout, which a wlroots utility for working with an // arrangement of screens in a physical layout. @@ -34,8 +35,13 @@ pub const Root = struct { errdefer c.wlr_output_layout_destroy(self.wlr_output_layout); self.outputs = std.TailQueue(Output).init(); + self.views = std.TailQueue(View).init(); self.unmapped_views = std.TailQueue(View).init(); + + self.focused_view = null; + + self.pending_count = 0; } pub fn destroy(self: *Self) void { @@ -55,7 +61,7 @@ pub const Root = struct { self.unmapped_views.append(node); } - /// Finds the top most view under the output layout coordinates lx, ly + /// Finds the topmost view under the output layout coordinates lx, ly /// returns the view if found, and a pointer to the wlr_surface as well as the surface coordinates pub fn viewAt(self: *Self, lx: f64, ly: f64, surface: *?*c.wlr_surface, sx: *f64, sy: *f64) ?*View { var it = self.views.last; @@ -67,6 +73,46 @@ pub const Root = struct { return null; } + /// Focus the next view in the stack, wrapping if needed. Does nothing + /// if there is only one view in the stack. + pub fn focusNextView(self: *Self) void { + if (self.focused_view) |current_focus| { + // If there is a currently focused view, focus the next view in the stack. + const node = @fieldParentPtr(std.TailQueue(View).Node, "data", current_focus); + if (node.next) |next_node| { + const view = &next_node.data; + view.focus(view.wlr_xdg_surface.surface); + return; + } + } + // There is either no currently focused view or the last view in the + // stack is focused and we need to wrap. + if (self.views.first) |first_node| { + const view = &first_node.data; + view.focus(view.wlr_xdg_surface.surface); + } + } + + /// Focus the previous view in the stack, wrapping if needed. Does nothing + /// if there is only one view in the stack. + pub fn focusPrevView(self: *Self) void { + if (self.focused_view) |current_focus| { + // If there is a currently focused view, focus the previous view in the stack. + const node = @fieldParentPtr(std.TailQueue(View).Node, "data", current_focus); + if (node.prev) |prev_node| { + const view = &prev_node.data; + view.focus(view.wlr_xdg_surface.surface); + return; + } + } + // There is either no currently focused view or the first view in the + // stack is focused and we need to wrap. + if (self.views.last) |last_node| { + const view = &last_node.data; + view.focus(view.wlr_xdg_surface.surface); + } + } + pub fn arrange(self: *Self) void { if (self.views.len == 0) { return; |
