Root: use Output.PendingState for fallback

Using the same type for these has the potential to simplify some future
code.
This commit is contained in:
Isaac Freund 2024-01-12 16:49:04 -06:00
parent 62dbe34bda
commit 6e9bd83e1d
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
3 changed files with 41 additions and 48 deletions

View File

@ -39,6 +39,28 @@ const View = @import("View.zig");
const log = std.log.scoped(.output); const log = std.log.scoped(.output);
pub const PendingState = struct {
/// A bit field of focused tags
tags: u32 = 1 << 0,
/// The stack of views in focus/rendering order.
///
/// This contains views that aren't currently visible because they do not
/// match the tags of the output.
///
/// This list is used to update the rendering order of nodes in the scene
/// graph when the pending state is committed.
focus_stack: wl.list.Head(View, .pending_focus_stack_link),
/// The stack of views acted upon by window management commands such
/// as focus-view, zoom, etc.
///
/// This contains views that aren't currently visible because they do not
/// match the tags of the output. This means that a filtered version of the
/// list must be used for window management commands.
///
/// This includes both floating/fullscreen views and those arranged in the layout.
wm_stack: wl.list.Head(View, .pending_wm_stack_link),
};
wlr_output: *wlr.Output, wlr_output: *wlr.Output,
scene_output: *wlr.SceneOutput, scene_output: *wlr.SceneOutput,
@ -113,27 +135,7 @@ gamma_dirty: bool = false,
/// ///
/// Any time pending state is modified Root.applyPending() must be called /// Any time pending state is modified Root.applyPending() must be called
/// before yielding back to the event loop. /// before yielding back to the event loop.
pending: struct { pending: PendingState,
/// A bit field of focused tags
tags: u32 = 1 << 0,
/// The stack of views in focus/rendering order.
///
/// This contains views that aren't currently visible because they do not
/// match the tags of the output.
///
/// This list is used to update the rendering order of nodes in the scene
/// graph when the pending state is committed.
focus_stack: wl.list.Head(View, .pending_focus_stack_link),
/// The stack of views acted upon by window management commands such
/// as focus-view, zoom, etc.
///
/// This contains views that aren't currently visible because they do not
/// match the tags of the output. This means that a filtered version of the
/// list must be used for window management commands.
///
/// This includes both floating/fullscreen views and those arranged in the layout.
wm_stack: wl.list.Head(View, .pending_wm_stack_link),
},
/// The state most recently sent to the layout generator and clients. /// The state most recently sent to the layout generator and clients.
/// This state is immutable until all clients have replied and the transaction /// This state is immutable until all clients have replied and the transaction

View File

@ -74,14 +74,7 @@ hidden: struct {
/// There is no need for inflight lists, instead the inflight links of views are /// There is no need for inflight lists, instead the inflight links of views are
/// remove()'d from their current list and init()'d so they may be remove()'d again /// remove()'d from their current list and init()'d so they may be remove()'d again
/// when an output becomes available and they are moved to the output's inflight lists. /// when an output becomes available and they are moved to the output's inflight lists.
fallback: struct { fallback_pending: Output.PendingState,
tags: u32 = 1 << 0,
pending: struct {
focus_stack: wl.list.Head(View, .pending_focus_stack_link),
wm_stack: wl.list.Head(View, .pending_wm_stack_link),
},
},
views: wl.list.Head(View, .link), views: wl.list.Head(View, .link),
@ -165,12 +158,10 @@ pub fn init(self: *Self) !void {
.wm_stack = undefined, .wm_stack = undefined,
}, },
}, },
.fallback = .{ .fallback_pending = .{
.pending = .{
.focus_stack = undefined, .focus_stack = undefined,
.wm_stack = undefined, .wm_stack = undefined,
}, },
},
.views = undefined, .views = undefined,
.output_layout = output_layout, .output_layout = output_layout,
.all_outputs = undefined, .all_outputs = undefined,
@ -185,8 +176,8 @@ pub fn init(self: *Self) !void {
self.hidden.inflight.focus_stack.init(); self.hidden.inflight.focus_stack.init();
self.hidden.inflight.wm_stack.init(); self.hidden.inflight.wm_stack.init();
self.fallback.pending.focus_stack.init(); self.fallback_pending.focus_stack.init();
self.fallback.pending.wm_stack.init(); self.fallback_pending.wm_stack.init();
self.views.init(); self.views.init();
self.all_outputs.init(); self.all_outputs.init();
@ -292,7 +283,7 @@ pub fn deactivateOutput(root: *Self, output: *Output) void {
} }
} }
// Use the first output in the list as fallback. If the last real output // Use the first output in the list as fallback. If the last real output
// is being removed, store the views in Root.fallback. // is being removed, store the views in Root.fallback_pending.
const fallback_output = blk: { const fallback_output = blk: {
var it = root.active_outputs.iterator(.forward); var it = root.active_outputs.iterator(.forward);
if (it.next()) |o| break :blk o; if (it.next()) |o| break :blk o;
@ -305,11 +296,11 @@ pub fn deactivateOutput(root: *Self, output: *Output) void {
} else { } else {
var it = output.pending.focus_stack.iterator(.forward); var it = output.pending.focus_stack.iterator(.forward);
while (it.next()) |view| view.pending.output = null; while (it.next()) |view| view.pending.output = null;
root.fallback.pending.focus_stack.prependList(&output.pending.focus_stack); root.fallback_pending.focus_stack.prependList(&output.pending.focus_stack);
root.fallback.pending.wm_stack.prependList(&output.pending.wm_stack); root.fallback_pending.wm_stack.prependList(&output.pending.wm_stack);
// Store the focused output tags if we are hotplugged down to // Store the focused output tags if we are hotplugged down to
// 0 real outputs so they can be restored on gaining a new output. // 0 real outputs so they can be restored on gaining a new output.
root.fallback.tags = output.pending.tags; root.fallback_pending.tags = output.pending.tags;
} }
// Close all layer surfaces on the removed output // Close all layer surfaces on the removed output
@ -377,9 +368,9 @@ pub fn activateOutput(root: *Self, output: *Output) void {
const log = std.log.scoped(.output_manager); const log = std.log.scoped(.output_manager);
log.debug("moving views from fallback stacks to new output", .{}); log.debug("moving views from fallback stacks to new output", .{});
output.pending.tags = root.fallback.tags; output.pending.tags = root.fallback_pending.tags;
{ {
var it = root.fallback.pending.wm_stack.safeIterator(.reverse); var it = root.fallback_pending.wm_stack.safeIterator(.reverse);
while (it.next()) |view| view.setPendingOutput(output); while (it.next()) |view| view.setPendingOutput(output);
} }
{ {
@ -391,8 +382,8 @@ pub fn activateOutput(root: *Self, output: *Output) void {
} }
} }
} }
assert(root.fallback.pending.focus_stack.empty()); assert(root.fallback_pending.focus_stack.empty());
assert(root.fallback.pending.wm_stack.empty()); assert(root.fallback_pending.wm_stack.empty());
} }
/// Trigger asynchronous application of pending state for all outputs and views. /// Trigger asynchronous application of pending state for all outputs and views.

View File

@ -513,7 +513,7 @@ pub fn map(view: *Self) !void {
} }
view.pending.tags = blk: { view.pending.tags = blk: {
const default = if (output) |o| o.pending.tags else server.root.fallback.tags; const default = if (output) |o| o.pending.tags else server.root.fallback_pending.tags;
if (server.config.rules.tags.match(view)) |tags| break :blk tags; if (server.config.rules.tags.match(view)) |tags| break :blk tags;
const tags = default & server.config.spawn_tagmask; const tags = default & server.config.spawn_tagmask;
break :blk if (tags != 0) tags else default; break :blk if (tags != 0) tags else default;
@ -531,10 +531,10 @@ pub fn map(view: *Self) !void {
view.pending_focus_stack_link.remove(); view.pending_focus_stack_link.remove();
switch (server.config.attach_mode) { switch (server.config.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),
} }
server.root.fallback.pending.focus_stack.prepend(view); server.root.fallback_pending.focus_stack.prepend(view);
view.inflight_wm_stack_link.remove(); view.inflight_wm_stack_link.remove();
view.inflight_wm_stack_link.init(); view.inflight_wm_stack_link.init();