Refactor focus next/prev view/output commands
This commit is contained in:
parent
6914f32ce3
commit
e0c6b5bf72
2 changed files with 52 additions and 44 deletions
|
@ -7,11 +7,17 @@ const Seat = @import("seat.zig").Seat;
|
||||||
const View = @import("view.zig").View;
|
const View = @import("view.zig").View;
|
||||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||||
|
|
||||||
|
pub const Direction = enum {
|
||||||
|
Next,
|
||||||
|
Prev,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Arg = union {
|
pub const Arg = union {
|
||||||
int: i32,
|
int: i32,
|
||||||
uint: u32,
|
uint: u32,
|
||||||
float: f64,
|
float: f64,
|
||||||
str: []const u8,
|
str: []const u8,
|
||||||
|
direction: Direction,
|
||||||
none: void,
|
none: void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,17 +28,18 @@ pub fn exitCompositor(seat: *Seat, arg: Arg) void {
|
||||||
c.wl_display_terminate(seat.input_manager.server.wl_display);
|
c.wl_display_terminate(seat.input_manager.server.wl_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Focus either the next or the previous visible view, depending on the bool
|
/// Focus either the next or the previous visible view, depending on the enum
|
||||||
/// passed.
|
/// passed. Does nothing if there are 1 or 0 views in the stack.
|
||||||
fn focusNextPrevView(seat: *Seat, next: bool) void {
|
pub fn focusView(seat: *Seat, arg: Arg) void {
|
||||||
|
const direction = arg.direction;
|
||||||
const output = seat.focused_output;
|
const output = seat.focused_output;
|
||||||
if (seat.focused_view) |current_focus| {
|
if (seat.focused_view) |current_focus| {
|
||||||
// If there is a currently focused view, focus the next visible view in the stack.
|
// If there is a currently focused view, focus the next visible view in the stack.
|
||||||
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
||||||
var it = if (next)
|
var it = switch (direction) {
|
||||||
ViewStack(View).iterator(focused_node, output.current_focused_tags)
|
.Next => ViewStack(View).iterator(focused_node, output.current_focused_tags),
|
||||||
else
|
.Prev => ViewStack(View).reverseIterator(focused_node, output.current_focused_tags),
|
||||||
ViewStack(View).reverseIterator(focused_node, output.current_focused_tags);
|
};
|
||||||
|
|
||||||
// Skip past the focused node
|
// Skip past the focused node
|
||||||
_ = it.next();
|
_ = it.next();
|
||||||
|
@ -45,27 +52,17 @@ fn focusNextPrevView(seat: *Seat, next: bool) void {
|
||||||
|
|
||||||
// There is either no currently focused view or the last visible view in the
|
// There is either no currently focused view or the last visible view in the
|
||||||
// stack is focused and we need to wrap.
|
// stack is focused and we need to wrap.
|
||||||
var it = if (next)
|
var it = switch (direction) {
|
||||||
ViewStack(View).iterator(output.views.first, output.current_focused_tags)
|
.Next => ViewStack(View).iterator(output.views.first, output.current_focused_tags),
|
||||||
else
|
.Prev => ViewStack(View).reverseIterator(output.views.last, output.current_focused_tags),
|
||||||
ViewStack(View).reverseIterator(output.views.last, output.current_focused_tags);
|
};
|
||||||
seat.focus(if (it.next()) |node| &node.view else null);
|
seat.focus(if (it.next()) |node| &node.view else null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Focus the next visible view in the stack, wrapping if needed. Does
|
|
||||||
/// nothing if there is only one view in the stack.
|
|
||||||
pub fn focusNextView(seat: *Seat, arg: Arg) void {
|
|
||||||
focusNextPrevView(seat, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Focus the previous view in the stack, wrapping if needed. Does nothing
|
|
||||||
/// if there is only one view in the stack.
|
|
||||||
pub fn focusPrevView(seat: *Seat, arg: Arg) void {
|
|
||||||
focusNextPrevView(seat, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Focus either the next or the previous output, depending on the bool passed.
|
/// Focus either the next or the previous output, depending on the bool passed.
|
||||||
fn focusNextPrevOutput(seat: *Seat, next: bool) void {
|
/// Does nothing if there is only one output.
|
||||||
|
pub fn focusOutput(seat: *Seat, arg: Arg) void {
|
||||||
|
const direction = arg.direction;
|
||||||
const root = &seat.input_manager.server.root;
|
const root = &seat.input_manager.server.root;
|
||||||
// If the noop output is focused, there are no other outputs to switch to
|
// If the noop output is focused, there are no other outputs to switch to
|
||||||
if (seat.focused_output == &root.noop_output) {
|
if (seat.focused_output == &root.noop_output) {
|
||||||
|
@ -73,27 +70,16 @@ fn focusNextPrevOutput(seat: *Seat, next: bool) void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Focus the next/prev output in the list if there is one, else wrap
|
||||||
const focused_node = @fieldParentPtr(std.TailQueue(Output).Node, "data", seat.focused_output);
|
const focused_node = @fieldParentPtr(std.TailQueue(Output).Node, "data", seat.focused_output);
|
||||||
seat.focused_output = if (if (next) focused_node.next else focused_node.prev) |output_node|
|
seat.focused_output = switch (direction) {
|
||||||
// Focus the next/prev output in the list if there is one
|
.Next => if (focused_node.next) |node| &node.data else &root.outputs.first.?.data,
|
||||||
&output_node.data
|
.Prev => if (focused_node.prev) |node| &node.data else &root.outputs.last.?.data,
|
||||||
else if (next) &root.outputs.first.?.data else &root.outputs.last.?.data;
|
};
|
||||||
|
|
||||||
seat.focus(null);
|
seat.focus(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Focus the next output, wrapping if needed. Does nothing if there is
|
|
||||||
/// only one output.
|
|
||||||
pub fn focusNextOutput(seat: *Seat, arg: Arg) void {
|
|
||||||
focusNextPrevOutput(seat, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Focus the previous output, wrapping if needed. Does nothing if there is
|
|
||||||
/// only one output.
|
|
||||||
pub fn focusPrevOutput(seat: *Seat, arg: Arg) void {
|
|
||||||
focusNextPrevOutput(seat, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Modify the number of master views
|
/// Modify the number of master views
|
||||||
pub fn modifyMasterCount(seat: *Seat, arg: Arg) void {
|
pub fn modifyMasterCount(seat: *Seat, arg: Arg) void {
|
||||||
const delta = arg.int;
|
const delta = arg.int;
|
||||||
|
|
|
@ -45,8 +45,20 @@ pub const Config = struct {
|
||||||
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_e, .modifiers = mod, .command = command.exitCompositor, .arg = .{ .none = {} } });
|
||||||
|
|
||||||
// Mod+J and Mod+K to focus the next/previous view in the layout stack
|
// Mod+J and Mod+K to focus the next/previous view in the layout stack
|
||||||
try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_j, .modifiers = mod, .command = command.focusNextView, .arg = .{ .none = {} } });
|
try self.keybinds.append(
|
||||||
try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_k, .modifiers = mod, .command = command.focusPrevView, .arg = .{ .none = {} } });
|
Keybind{
|
||||||
|
.keysym = c.XKB_KEY_j,
|
||||||
|
.modifiers = mod,
|
||||||
|
.command = command.focusView,
|
||||||
|
.arg = .{ .direction = .Next },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
try self.keybinds.append(Keybind{
|
||||||
|
.keysym = c.XKB_KEY_k,
|
||||||
|
.modifiers = mod,
|
||||||
|
.command = command.focusView,
|
||||||
|
.arg = .{ .direction = .Prev },
|
||||||
|
});
|
||||||
|
|
||||||
// Mod+Return to bump the focused view to the top of the layout stack, making it the new master
|
// Mod+Return to bump the focused view to the top of the layout stack, making it the new master
|
||||||
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_Return, .modifiers = mod, .command = command.zoom, .arg = .{ .none = {} } });
|
||||||
|
@ -98,7 +110,17 @@ pub const Config = struct {
|
||||||
try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_0, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 0xFFFFFFFF } });
|
try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_0, .modifiers = mod | c.WLR_MODIFIER_SHIFT, .command = command.setFocusedViewTags, .arg = .{ .uint = 0xFFFFFFFF } });
|
||||||
|
|
||||||
// Mod+Period and Mod+Comma to focus the next/previous output
|
// Mod+Period and Mod+Comma to focus the next/previous output
|
||||||
try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_period, .modifiers = mod, .command = command.focusNextOutput, .arg = .{ .none = {} } });
|
try self.keybinds.append(Keybind{
|
||||||
try self.keybinds.append(Keybind{ .keysym = c.XKB_KEY_comma, .modifiers = mod, .command = command.focusPrevOutput, .arg = .{ .none = {} } });
|
.keysym = c.XKB_KEY_period,
|
||||||
|
.modifiers = mod,
|
||||||
|
.command = command.focusOutput,
|
||||||
|
.arg = .{ .direction = .Next },
|
||||||
|
});
|
||||||
|
try self.keybinds.append(Keybind{
|
||||||
|
.keysym = c.XKB_KEY_comma,
|
||||||
|
.modifiers = mod,
|
||||||
|
.command = command.focusOutput,
|
||||||
|
.arg = .{ .direction = .Prev },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue