From 386316bdbd034f6b2cc37ac125cfde04610236ff Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Mon, 21 Dec 2020 16:19:44 +0100 Subject: [PATCH] output: get rid of active field The less state that needs to be maintained, the better --- river/Output.zig | 18 ++++++------------ river/OutputManager.zig | 5 ++--- river/Root.zig | 29 ++++++++++++++++++++--------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/river/Output.zig b/river/Output.zig index 94501db..77a4307 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -76,10 +76,6 @@ attach_mode: AttachMode = .top, /// List of status tracking objects relaying changes to this output to clients. status_trackers: std.SinglyLinkedList(OutputStatus) = .{}, -/// Whether or not the output is active -/// An active output can have focus (e.g. an output turned off by dpms is active) -active: bool = false, - destroy: wl.Listener(*wlr.Output) = undefined, enable: wl.Listener(*wlr.Output) = undefined, frame: wl.Listener(*wlr.Output) = undefined, @@ -496,10 +492,7 @@ fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) v log.debug(.server, "output '{}' destroyed", .{self.wlr_output.name}); // Remove the destroyed output from root if it wasn't already removed - const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); - if (self.active) { - root.removeOutput(node); - } + root.removeOutput(self); var it = root.all_outputs.first; while (it) |all_node| : (it = all_node.next) { @@ -518,16 +511,17 @@ fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) v // Free all memory and clean up the wlr.Output self.wlr_output.data = undefined; util.gpa.free(self.layout); + + const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); util.gpa.destroy(node); } fn handleEnable(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { const self = @fieldParentPtr(Self, "enable", listener); - if (wlr_output.enabled and !self.active) { - const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); - self.root.addOutput(node); - } + // Add the output to root.outputs and the output layout if it has not + // already been added. + if (wlr_output.enabled) self.root.addOutput(self); } fn handleFrame(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { diff --git a/river/OutputManager.zig b/river/OutputManager.zig index 68032fe..9913b6b 100644 --- a/river/OutputManager.zig +++ b/river/OutputManager.zig @@ -95,7 +95,7 @@ fn handleNewOutput(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) ptr_node.data = &node.data; self.root.all_outputs.append(ptr_node); - self.root.addOutput(node); + self.root.addOutput(&node.data); } /// Send the new output configuration to all wlr-output-manager clients @@ -192,8 +192,7 @@ fn applyOutputConfig(self: *Self, config: *wlr.OutputConfigurationV1) bool { } if (disable) { - const node = @fieldParentPtr(std.TailQueue(Output).Node, "data", output); - self.root.removeOutput(node); + self.root.removeOutput(output); self.root.output_layout.remove(output.wlr_output); } diff --git a/river/Root.zig b/river/Root.zig index 4218276..270db31 100644 --- a/river/Root.zig +++ b/river/Root.zig @@ -90,12 +90,18 @@ pub fn deinit(self: *Self) void { self.transaction_timer.remove(); } -/// Removes the output in node.data from self.outputs -/// The node is not freed -pub fn removeOutput(self: *Self, node: *std.TailQueue(Output).Node) void { - const output = &node.data; +/// Remove the output from self.outputs and evacuate views if it is a member of +/// the list. The node is not freed +pub fn removeOutput(self: *Self, output: *Output) void { + const node = @fieldParentPtr(std.TailQueue(Output).Node, "data", output); + + // If the node has already been removed, do nothing + var output_it = self.outputs.first; + while (output_it) |n| : (output_it = n.next) { + if (n == node) break; + } else return; + self.outputs.remove(node); - output.active = false; // Use the first output in the list as fallback. // If there is no other real output, use the noop output. @@ -137,11 +143,16 @@ pub fn removeOutput(self: *Self, node: *std.TailQueue(Output).Node) void { self.startTransaction(); } -/// Adds the output in node.data to self.outputs -/// The Output in node.data must be initalized -pub fn addOutput(self: *Self, node: *std.TailQueue(Output).Node) void { +/// Add the output to self.outputs and the output layout if it has not +/// already been added. +pub fn addOutput(self: *Self, output: *Output) void { + const node = @fieldParentPtr(std.TailQueue(Output).Node, "data", output); + + // If we have already added the output, do nothing and return + var output_it = self.outputs.first; + while (output_it) |n| : (output_it = n.next) if (n == node) return; + self.outputs.append(node); - node.data.active = true; // Add the new output to the layout. The add_auto function arranges outputs // from left-to-right in the order they appear. A more sophisticated