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

commit13a3d1038ab829e938d1fd903399be6ed2858be3
parent2faa72236d
authorIsaac Freund <[email protected]>
date2026-03-04 11:46
OutputManager: exit river if initial modeset fails

 river/OutputManager.zig | 13 +++++++++++++
 river/main.zig          |  2 --
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/river/OutputManager.zig b/river/OutputManager.zig
index 2799e54..a9f8b69 100644
--- a/river/OutputManager.zig
+++ b/river/OutputManager.zig
@@ -24,6 +24,9 @@ const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
 
 const log = std.log.scoped(.output);
 
+/// The very first modeset is different in that if it fails we exit river.
+first_modeset: bool = true,
+
 new_output: wl.Listener(*wlr.Output) = .init(handleNewOutput),
 
 output_layout: *wlr.OutputLayout,
@@ -366,6 +369,15 @@ 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();
@@ -383,6 +395,7 @@ pub fn commitOutputState(om: *OutputManager) void {
             }
             return;
         }
+        om.first_modeset = false;
 
         swapchain_manager.apply();
     }
diff --git a/river/main.zig b/river/main.zig
index d290c40..4f21bd9 100644
--- a/river/main.zig
+++ b/river/main.zig
@@ -154,8 +154,6 @@ pub fn main() anyerror!void {
     log.info("running server", .{});
 
     server.wl_server.run();
-
-    log.info("shutting down", .{});
 }
 
 fn defaultInitPath() !?[:0]const u8 {