attach-mode: implement after <N>
This commit is contained in:
parent
6e9bd83e1d
commit
6a71fc65b0
@ -347,8 +347,20 @@ matches everything while _\*\*_ and the empty string are invalid.
|
|||||||
|
|
||||||
## CONFIGURATION
|
## CONFIGURATION
|
||||||
|
|
||||||
*attach-mode* *top*|*bottom*
|
*attach-mode* *top*|*bottom*|*after <N>*
|
||||||
Configure where new views should attach to the view stack.
|
Set the attach mode to be used by all outputs by default.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
- top: Prepends the newly spawned view at the top of the stack.
|
||||||
|
- bottom: Appends the newly spawned view at the bottom of the stack.
|
||||||
|
- after <N>: Inserts the newly spawned view after N views in the stack.
|
||||||
|
|
||||||
|
*default-attach-mode* *top*|*bottom*|*after <N>*
|
||||||
|
Alias to attach-mode.
|
||||||
|
|
||||||
|
*output-attach-mode* *top*|*bottom*|*after <N>*
|
||||||
|
Set the attach mode of the currently focused output, overriding the value of
|
||||||
|
default-attach-mode if any.
|
||||||
|
|
||||||
*background-color* _0xRRGGBB_|_0xRRGGBBAA_
|
*background-color* _0xRRGGBB_|_0xRRGGBBAA_
|
||||||
Set the background color.
|
Set the background color.
|
||||||
|
@ -31,9 +31,10 @@ const Mode = @import("Mode.zig");
|
|||||||
const RuleList = @import("rule_list.zig").RuleList;
|
const RuleList = @import("rule_list.zig").RuleList;
|
||||||
const View = @import("View.zig");
|
const View = @import("View.zig");
|
||||||
|
|
||||||
pub const AttachMode = enum {
|
pub const AttachMode = union(enum) {
|
||||||
top,
|
top: void,
|
||||||
bottom,
|
bottom: void,
|
||||||
|
after: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FocusFollowsCursorMode = enum {
|
pub const FocusFollowsCursorMode = enum {
|
||||||
@ -112,7 +113,7 @@ default_layout_namespace: []const u8 = &[0]u8{},
|
|||||||
spawn_tagmask: u32 = std.math.maxInt(u32),
|
spawn_tagmask: u32 = std.math.maxInt(u32),
|
||||||
|
|
||||||
/// Determines where new views will be attached to the view stack.
|
/// Determines where new views will be attached to the view stack.
|
||||||
attach_mode: AttachMode = .top,
|
default_attach_mode: AttachMode = .top,
|
||||||
|
|
||||||
/// Keyboard repeat rate in characters per second
|
/// Keyboard repeat rate in characters per second
|
||||||
repeat_rate: u31 = 25,
|
repeat_rate: u31 = 25,
|
||||||
|
@ -36,6 +36,7 @@ const LockSurface = @import("LockSurface.zig");
|
|||||||
const OutputStatus = @import("OutputStatus.zig");
|
const OutputStatus = @import("OutputStatus.zig");
|
||||||
const SceneNodeData = @import("SceneNodeData.zig");
|
const SceneNodeData = @import("SceneNodeData.zig");
|
||||||
const View = @import("View.zig");
|
const View = @import("View.zig");
|
||||||
|
const AttachMode = @import("Config.zig").AttachMode;
|
||||||
|
|
||||||
const log = std.log.scoped(.output);
|
const log = std.log.scoped(.output);
|
||||||
|
|
||||||
@ -166,6 +167,8 @@ current: struct {
|
|||||||
/// Remembered version of tags (from last run)
|
/// Remembered version of tags (from last run)
|
||||||
previous_tags: u32 = 1 << 0,
|
previous_tags: u32 = 1 << 0,
|
||||||
|
|
||||||
|
attach_mode: ?AttachMode = null,
|
||||||
|
|
||||||
/// List of all layouts
|
/// List of all layouts
|
||||||
layouts: std.TailQueue(Layout) = .{},
|
layouts: std.TailQueue(Layout) = .{},
|
||||||
|
|
||||||
@ -608,3 +611,7 @@ pub fn handleLayoutNamespaceChange(self: *Self) void {
|
|||||||
pub fn layoutNamespace(self: Self) []const u8 {
|
pub fn layoutNamespace(self: Self) []const u8 {
|
||||||
return self.layout_namespace orelse server.config.default_layout_namespace;
|
return self.layout_namespace orelse server.config.default_layout_namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn attachMode(self: Self) AttachMode {
|
||||||
|
return self.attach_mode orelse server.config.default_attach_mode;
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@ const SceneNodeData = @import("SceneNodeData.zig");
|
|||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
const XdgToplevel = @import("XdgToplevel.zig");
|
const XdgToplevel = @import("XdgToplevel.zig");
|
||||||
const XwaylandView = @import("XwaylandView.zig");
|
const XwaylandView = @import("XwaylandView.zig");
|
||||||
|
const PendingState = @import("Output.zig").PendingState;
|
||||||
|
|
||||||
const log = std.log.scoped(.view);
|
const log = std.log.scoped(.view);
|
||||||
|
|
||||||
@ -418,9 +419,10 @@ pub fn setPendingOutput(view: *Self, output: *Output) void {
|
|||||||
view.pending_wm_stack_link.remove();
|
view.pending_wm_stack_link.remove();
|
||||||
view.pending_focus_stack_link.remove();
|
view.pending_focus_stack_link.remove();
|
||||||
|
|
||||||
switch (server.config.attach_mode) {
|
switch (output.attachMode()) {
|
||||||
.top => output.pending.wm_stack.prepend(view),
|
.top => output.pending.wm_stack.prepend(view),
|
||||||
.bottom => output.pending.wm_stack.append(view),
|
.bottom => output.pending.wm_stack.append(view),
|
||||||
|
.after => |n| view.attach_after(&output.pending, n),
|
||||||
}
|
}
|
||||||
output.pending.focus_stack.prepend(view);
|
output.pending.focus_stack.prepend(view);
|
||||||
|
|
||||||
@ -476,6 +478,20 @@ pub fn applyConstraints(self: *Self, box: *wlr.Box) void {
|
|||||||
box.height = math.clamp(box.height, self.constraints.min_height, self.constraints.max_height);
|
box.height = math.clamp(box.height, self.constraints.min_height, self.constraints.max_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attach current view after n Views on the pending wm_stack
|
||||||
|
pub fn attach_after(view: *Self, pending_state: *PendingState, n: usize) void {
|
||||||
|
var nvisible: u32 = 0;
|
||||||
|
var it = pending_state.wm_stack.iterator(.forward);
|
||||||
|
|
||||||
|
while (it.next()) |cur_view| {
|
||||||
|
if (nvisible >= n) break;
|
||||||
|
if (!cur_view.pending.float // ignore floating views
|
||||||
|
and cur_view.pending.tags & pending_state.tags != 0) nvisible += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.current.prev.?.insert(&view.pending_wm_stack_link);
|
||||||
|
}
|
||||||
|
|
||||||
/// Called by the impl when the surface is ready to be displayed
|
/// Called by the impl when the surface is ready to be displayed
|
||||||
pub fn map(view: *Self) !void {
|
pub fn map(view: *Self) !void {
|
||||||
log.debug("view '{?s}' mapped", .{view.getTitle()});
|
log.debug("view '{?s}' mapped", .{view.getTitle()});
|
||||||
@ -530,9 +546,10 @@ pub fn map(view: *Self) !void {
|
|||||||
view.pending_wm_stack_link.remove();
|
view.pending_wm_stack_link.remove();
|
||||||
view.pending_focus_stack_link.remove();
|
view.pending_focus_stack_link.remove();
|
||||||
|
|
||||||
switch (server.config.attach_mode) {
|
switch (server.config.default_attach_mode) {
|
||||||
.top => server.root.fallback_pending.wm_stack.prepend(view),
|
.top => server.root.fallback_pending.wm_stack.prepend(view),
|
||||||
.bottom => server.root.fallback_pending.wm_stack.append(view),
|
.bottom => server.root.fallback_pending.wm_stack.append(view),
|
||||||
|
.after => |n| view.attach_after(&server.root.fallback_pending, n),
|
||||||
}
|
}
|
||||||
server.root.fallback_pending.focus_stack.prepend(view);
|
server.root.fallback_pending.focus_stack.prepend(view);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ pub const Orientation = enum {
|
|||||||
const command_impls = std.ComptimeStringMap(
|
const command_impls = std.ComptimeStringMap(
|
||||||
*const fn (*Seat, []const [:0]const u8, *?[]const u8) Error!void,
|
*const fn (*Seat, []const [:0]const u8, *?[]const u8) Error!void,
|
||||||
.{
|
.{
|
||||||
.{ "attach-mode", @import("command/attach_mode.zig").attachMode },
|
.{ "attach-mode", @import("command/attach_mode.zig").defaultAttachMode },
|
||||||
.{ "background-color", @import("command/config.zig").backgroundColor },
|
.{ "background-color", @import("command/config.zig").backgroundColor },
|
||||||
.{ "border-color-focused", @import("command/config.zig").borderColorFocused },
|
.{ "border-color-focused", @import("command/config.zig").borderColorFocused },
|
||||||
.{ "border-color-unfocused", @import("command/config.zig").borderColorUnfocused },
|
.{ "border-color-unfocused", @import("command/config.zig").borderColorUnfocused },
|
||||||
@ -48,6 +48,7 @@ const command_impls = std.ComptimeStringMap(
|
|||||||
.{ "border-width", @import("command/config.zig").borderWidth },
|
.{ "border-width", @import("command/config.zig").borderWidth },
|
||||||
.{ "close", @import("command/close.zig").close },
|
.{ "close", @import("command/close.zig").close },
|
||||||
.{ "declare-mode", @import("command/declare_mode.zig").declareMode },
|
.{ "declare-mode", @import("command/declare_mode.zig").declareMode },
|
||||||
|
.{ "default-attach-mode", @import("command/attach_mode.zig").defaultAttachMode },
|
||||||
.{ "default-layout", @import("command/layout.zig").defaultLayout },
|
.{ "default-layout", @import("command/layout.zig").defaultLayout },
|
||||||
.{ "enter-mode", @import("command/enter_mode.zig").enterMode },
|
.{ "enter-mode", @import("command/enter_mode.zig").enterMode },
|
||||||
.{ "exit", @import("command/exit.zig").exit },
|
.{ "exit", @import("command/exit.zig").exit },
|
||||||
@ -70,6 +71,7 @@ const command_impls = std.ComptimeStringMap(
|
|||||||
.{ "map-pointer", @import("command/map.zig").mapPointer },
|
.{ "map-pointer", @import("command/map.zig").mapPointer },
|
||||||
.{ "map-switch", @import("command/map.zig").mapSwitch },
|
.{ "map-switch", @import("command/map.zig").mapSwitch },
|
||||||
.{ "move", @import("command/move.zig").move },
|
.{ "move", @import("command/move.zig").move },
|
||||||
|
.{ "output-attach-mode", @import("command/attach_mode.zig").outputAttachMode },
|
||||||
.{ "output-layout", @import("command/layout.zig").outputLayout },
|
.{ "output-layout", @import("command/layout.zig").outputLayout },
|
||||||
.{ "resize", @import("command/move.zig").resize },
|
.{ "resize", @import("command/move.zig").resize },
|
||||||
.{ "rule-add", @import("command/rule.zig").ruleAdd },
|
.{ "rule-add", @import("command/rule.zig").ruleAdd },
|
||||||
|
@ -21,20 +21,36 @@ const server = &@import("../main.zig").server;
|
|||||||
|
|
||||||
const Error = @import("../command.zig").Error;
|
const Error = @import("../command.zig").Error;
|
||||||
const Seat = @import("../Seat.zig");
|
const Seat = @import("../Seat.zig");
|
||||||
|
const AttachMode = @import("../Config.zig").AttachMode;
|
||||||
|
|
||||||
pub fn attachMode(
|
fn parseAttachMode(args: []const [:0]const u8) Error!AttachMode {
|
||||||
|
if (args.len < 2) return Error.NotEnoughArguments;
|
||||||
|
|
||||||
|
if (mem.eql(u8, "top", args[1])) {
|
||||||
|
return if (args.len > 2) Error.TooManyArguments else .top;
|
||||||
|
} else if (mem.eql(u8, "bottom", args[1])) {
|
||||||
|
return if (args.len > 2) Error.TooManyArguments else .bottom;
|
||||||
|
} else if (mem.eql(u8, "after", args[1])) {
|
||||||
|
if (args.len < 3) return Error.NotEnoughArguments;
|
||||||
|
if (args.len > 3) return Error.TooManyArguments;
|
||||||
|
return .{ .after = try std.fmt.parseInt(usize, args[2], 10) };
|
||||||
|
}
|
||||||
|
return Error.UnknownOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outputAttachMode(
|
||||||
|
seat: *Seat,
|
||||||
|
args: []const [:0]const u8,
|
||||||
|
_: *?[]const u8,
|
||||||
|
) Error!void {
|
||||||
|
const output = seat.focused_output orelse return;
|
||||||
|
output.attach_mode = try parseAttachMode(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn defaultAttachMode(
|
||||||
_: *Seat,
|
_: *Seat,
|
||||||
args: []const [:0]const u8,
|
args: []const [:0]const u8,
|
||||||
_: *?[]const u8,
|
_: *?[]const u8,
|
||||||
) Error!void {
|
) Error!void {
|
||||||
if (args.len < 2) return Error.NotEnoughArguments;
|
server.config.default_attach_mode = try parseAttachMode(args);
|
||||||
if (args.len > 2) return Error.TooManyArguments;
|
|
||||||
|
|
||||||
if (mem.eql(u8, "top", args[1])) {
|
|
||||||
server.config.attach_mode = .top;
|
|
||||||
} else if (mem.eql(u8, "bottom", args[1])) {
|
|
||||||
server.config.attach_mode = .bottom;
|
|
||||||
} else {
|
|
||||||
return Error.UnknownOption;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user