git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit16969e1f2adb5f56e8b7bb4b1c46e5f1cc6f05d3
parent13a3d1038a
authorIsaac Freund <[email protected]>
date2026-03-04 12:15
OutputManager: fix inconsistent modeset test/commit failure

 river/OutputManager.zig | 73 +++++++++++++++++++++----------------------------
 1 file changed, 31 insertions(+), 42 deletions(-)

diff --git a/river/OutputManager.zig b/river/OutputManager.zig
index a9f8b69..8174429 100644
--- a/river/OutputManager.zig
+++ b/river/OutputManager.zig
@@ -337,23 +337,7 @@ pub fn commitOutputState(om: *OutputManager) void {
 
         if (!swapchain_manager.prepare(states.items)) {
             log.err("failed to prepare new output configuration", .{});
-            // TODO search for a working fallback
-
-            if (wm.sent.output_config) |config| {
-                config.sendFailed();
-                config.destroy();
-                wm.sent.output_config = null;
-            }
-
-            {
-                // Revert to last working state on failure
-                var it = wm.sent.outputs.iterator(.forward);
-                while (it.next()) |output| {
-                    output.scheduled = output.current;
-                    output.sent = output.current;
-                }
-                wm.dirtyWindowing();
-            }
+            om.modesetFailed();
             return;
         }
 
@@ -368,31 +352,7 @@ pub fn commitOutputState(om: *OutputManager) void {
 
         if (!server.backend.commit(states.items)) {
             log.err("failed to commit new output configuration", .{});
-
-            // If the very first modeset fails, the user's hardware/drivers are
-            // probably not compatible with river. In this case, exit rather
-            // than running forever without rendering anything.
-            if (om.first_modeset) {
-                log.err("initial modeset failed, exiting river", .{});
-                server.wl_server.terminate();
-                return;
-            }
-
-            if (wm.sent.output_config) |config| {
-                config.sendFailed();
-                config.destroy();
-                wm.sent.output_config = null;
-            }
-
-            {
-                // Revert to last working state on failure
-                var it = wm.sent.outputs.iterator(.forward);
-                while (it.next()) |output| {
-                    output.scheduled = output.current;
-                    output.sent = output.current;
-                }
-                wm.dirtyWindowing();
-            }
+            om.modesetFailed();
             return;
         }
         om.first_modeset = false;
@@ -434,6 +394,35 @@ pub fn commitOutputState(om: *OutputManager) void {
     };
 }
 
+fn modesetFailed(om: *OutputManager) void {
+    const wm = &server.wm;
+
+    // If the very first modeset fails, the user's hardware/drivers are
+    // probably not compatible with river. In this case, exit rather
+    // than running forever without rendering anything.
+    if (om.first_modeset) {
+        log.err("initial modeset failed, exiting river", .{});
+        server.wl_server.terminate();
+        return;
+    }
+
+    if (wm.sent.output_config) |config| {
+        config.sendFailed();
+        config.destroy();
+        wm.sent.output_config = null;
+    }
+
+    {
+        // Revert to last working state on failure
+        var it = wm.sent.outputs.iterator(.forward);
+        while (it.next()) |output| {
+            output.scheduled = output.current;
+            output.sent = output.current;
+        }
+        wm.dirtyWindowing();
+    }
+}
+
 /// Send the current output state to all wlr-output-manager clients.
 fn sendConfig(om: *OutputManager) !void {
     const config = try wlr.OutputConfigurationV1.create();