output: get rid of active field

The less state that needs to be maintained, the better
This commit is contained in:
Isaac Freund 2020-12-21 16:19:44 +01:00
parent 518fb96604
commit 386316bdbd
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
3 changed files with 28 additions and 24 deletions

View File

@ -76,10 +76,6 @@ attach_mode: AttachMode = .top,
/// List of status tracking objects relaying changes to this output to clients. /// List of status tracking objects relaying changes to this output to clients.
status_trackers: std.SinglyLinkedList(OutputStatus) = .{}, 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, destroy: wl.Listener(*wlr.Output) = undefined,
enable: wl.Listener(*wlr.Output) = undefined, enable: wl.Listener(*wlr.Output) = undefined,
frame: 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}); log.debug(.server, "output '{}' destroyed", .{self.wlr_output.name});
// Remove the destroyed output from root if it wasn't already removed // Remove the destroyed output from root if it wasn't already removed
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); root.removeOutput(self);
if (self.active) {
root.removeOutput(node);
}
var it = root.all_outputs.first; var it = root.all_outputs.first;
while (it) |all_node| : (it = all_node.next) { 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 // Free all memory and clean up the wlr.Output
self.wlr_output.data = undefined; self.wlr_output.data = undefined;
util.gpa.free(self.layout); util.gpa.free(self.layout);
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
util.gpa.destroy(node); util.gpa.destroy(node);
} }
fn handleEnable(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { fn handleEnable(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
const self = @fieldParentPtr(Self, "enable", listener); const self = @fieldParentPtr(Self, "enable", listener);
if (wlr_output.enabled and !self.active) { // Add the output to root.outputs and the output layout if it has not
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); // already been added.
self.root.addOutput(node); if (wlr_output.enabled) self.root.addOutput(self);
}
} }
fn handleFrame(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { fn handleFrame(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {

View File

@ -95,7 +95,7 @@ fn handleNewOutput(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output)
ptr_node.data = &node.data; ptr_node.data = &node.data;
self.root.all_outputs.append(ptr_node); 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 /// 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) { if (disable) {
const node = @fieldParentPtr(std.TailQueue(Output).Node, "data", output); self.root.removeOutput(output);
self.root.removeOutput(node);
self.root.output_layout.remove(output.wlr_output); self.root.output_layout.remove(output.wlr_output);
} }

View File

@ -90,12 +90,18 @@ pub fn deinit(self: *Self) void {
self.transaction_timer.remove(); self.transaction_timer.remove();
} }
/// Removes the output in node.data from self.outputs /// Remove the output from self.outputs and evacuate views if it is a member of
/// The node is not freed /// the list. The node is not freed
pub fn removeOutput(self: *Self, node: *std.TailQueue(Output).Node) void { pub fn removeOutput(self: *Self, output: *Output) void {
const output = &node.data; 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); self.outputs.remove(node);
output.active = false;
// Use the first output in the list as fallback. // Use the first output in the list as fallback.
// If there is no other real output, use the noop output. // 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(); self.startTransaction();
} }
/// Adds the output in node.data to self.outputs /// Add the output to self.outputs and the output layout if it has not
/// The Output in node.data must be initalized /// already been added.
pub fn addOutput(self: *Self, node: *std.TailQueue(Output).Node) void { 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); self.outputs.append(node);
node.data.active = true;
// Add the new output to the layout. The add_auto function arranges outputs // 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 // from left-to-right in the order they appear. A more sophisticated