Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
session-lock: fix assertion failures and clean up
The removed assertions aren't possible to guarantee due to the fact that
the lock render state is updated asynchronously as the output is
rendered.
river/LockManager.zig | 10 +---------
river/LockSurface.zig | 5 +----
river/Output.zig | 27 +++++++++++++++++++--------
3 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/river/LockManager.zig b/river/LockManager.zig
index fdafc32..7196398 100644
--- a/river/LockManager.zig
+++ b/river/LockManager.zig
@@ -142,14 +142,6 @@ fn handleLockSurfacesTimeout(manager: *LockManager) c_int {
while (it) |node| : (it = node.next) {
const output = &node.data;
- switch (output.lock_render_state) {
- .unlocked, .pending_lock_surface => {},
- .pending_blank, .blanked, .lock_surface => {
- assert(!output.normal_content.node.enabled);
- assert(output.locked_content.node.enabled);
- },
- }
-
output.normal_content.node.setEnabled(false);
output.locked_content.node.setEnabled(true);
}
@@ -169,7 +161,7 @@ pub fn maybeLock(manager: *LockManager) void {
while (it) |node| : (it = node.next) {
const output = &node.data;
switch (output.lock_render_state) {
- .unlocked, .pending_blank, .pending_lock_surface => {
+ .pending_unlock, .unlocked, .pending_blank, .pending_lock_surface => {
all_outputs_blanked = false;
all_outputs_rendered_lock_surface = false;
},
diff --git a/river/LockSurface.zig b/river/LockSurface.zig
index 8f58f45..9cfb4ff 100644
--- a/river/LockSurface.zig
+++ b/river/LockSurface.zig
@@ -100,12 +100,9 @@ fn handleOutputMode(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
fn handleMap(listener: *wl.Listener(void)) void {
const lock_surface = @fieldParentPtr(LockSurface, "map", listener);
-
const output = lock_surface.getOutput();
- assert(output.normal_content.node.enabled);
- output.normal_content.node.setEnabled(false);
- assert(!output.locked_content.node.enabled);
+ output.normal_content.node.setEnabled(false);
output.locked_content.node.setEnabled(true);
{
diff --git a/river/Output.zig b/river/Output.zig
index b28fb66..361358c 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -78,6 +78,8 @@ layers: struct {
/// If using the DRM backend it will be blanked with the initial modeset.
/// If using the Wayland or X11 backend nothing will be visible until the first frame is rendered.
lock_render_state: enum {
+ /// Submitted an unlocked buffer but the buffer has not yet been presented.
+ pending_unlock,
/// Normal, "unlocked" content may be visible.
unlocked,
/// Submitted a blank buffer but the buffer has not yet been presented.
@@ -393,7 +395,7 @@ fn handleEnable(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) vo
if (wlr_output.enabled) {
switch (server.lock_manager.state) {
.unlocked => {
- self.lock_render_state = .unlocked;
+ assert(self.lock_render_state == .blanked);
self.normal_content.node.setEnabled(true);
self.locked_content.node.setEnabled(false);
},
@@ -406,6 +408,8 @@ fn handleEnable(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) vo
} else {
// Disabling and re-enabling an output always blanks it.
self.lock_render_state = .blanked;
+ self.normal_content.node.setEnabled(false);
+ self.locked_content.node.setEnabled(true);
}
// Add the output to root.outputs and the output layout if it has not
@@ -447,7 +451,7 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
switch (server.lock_manager.state) {
.unlocked => unreachable,
.locked => switch (output.lock_render_state) {
- .unlocked, .pending_blank, .pending_lock_surface => unreachable,
+ .pending_unlock, .unlocked, .pending_blank, .pending_lock_surface => unreachable,
.blanked, .lock_surface => {},
},
.waiting_for_blank => {
@@ -461,6 +465,10 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
}
},
}
+ } else {
+ if (output.lock_render_state != .unlocked) {
+ output.lock_render_state = .pending_unlock;
+ }
}
} else {
log.err("output commit failed for {s}", .{output.wlr_output.name});
@@ -477,18 +485,21 @@ fn handlePresent(
) void {
const output = @fieldParentPtr(Self, "present", listener);
+ if (!event.presented) {
+ return;
+ }
+
switch (output.lock_render_state) {
+ .pending_unlock => {
+ assert(server.lock_manager.state != .locked);
+ output.lock_render_state = .unlocked;
+ },
.unlocked => assert(server.lock_manager.state != .locked),
.pending_blank, .pending_lock_surface => {
- if (!event.presented) {
- output.lock_render_state = .unlocked;
- return;
- }
-
output.lock_render_state = switch (output.lock_render_state) {
.pending_blank => .blanked,
.pending_lock_surface => .lock_surface,
- .unlocked, .blanked, .lock_surface => unreachable,
+ .pending_unlock, .unlocked, .blanked, .lock_surface => unreachable,
};
if (server.lock_manager.state != .locked) {