{"record":{"id":"24805d36cce36374","repo":"elkowar/eww","slug":"could-not-get-default-display-24805d","errorCode":null,"errorMessage":"could not get default display","messagePattern":"could not get default display","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/eww/src/server.rs","lineNumber":142,"sourceCode":"                Some(ui_event) = ui_recv.recv() => {\n                    app.handle_command(ui_event).await;\n                }\n                else => break,\n            }\n        }\n    });\n\n    // allow the GTK main thread to do tokio things\n    let _g = tokio_handle.enter();\n\n    gtk::main();\n    log::info!(\"main application thread finished\");\n\n    Ok(ForkResult::Child)\n}\n\nfn connect_monitor_added(ui_send: UnboundedSender<DaemonCommand>) {\n    let display = gtk::gdk::Display::default().expect(\"could not get default display\");\n    display.connect_monitor_added({\n        move |_display: &gtk::gdk::Display, _monitor: &gtk::gdk::Monitor| {\n            log::info!(\"New monitor connected, reloading configuration\");\n            let _ = reload_config_and_css(&ui_send);\n        }\n    });\n}\n\nfn reload_config_and_css(ui_send: &UnboundedSender<DaemonCommand>) -> Result<()> {\n    let (daemon_resp_sender, mut daemon_resp_response) = daemon_response::create_pair();\n    ui_send.send(DaemonCommand::ReloadConfigAndCss(daemon_resp_sender))?;\n    tokio::spawn(async move {\n        match daemon_resp_response.recv().await {\n            Some(daemon_response::DaemonResponse::Success(_)) => log::info!(\"Reloaded config successfully\"),\n            Some(daemon_response::DaemonResponse::Failure(e)) => eprintln!(\"{}\", e),\n            None => log::error!(\"No response to reload configuration-reload request\"),\n        }\n    });","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/elkowar/eww/blob/48f5aa8b379adf29da0b0bb9ca04164f65d8bdaa/crates/eww/src/server.rs#L124-L160","documentation":"This panic comes from gtk::gdk::Display::default() returning None, meaning GDK could not open a connection to the display server. eww's daemon expects a valid default display (X11 or Wayland) so it can watch for monitor connect/disconnect events and reload the configuration when one appears.","triggerScenarios":"Calling connect_monitor_added (during initialize_server) in an environment where no display is available: DISPLAY unset or pointing at a dead X server, Wayland without XWayland/GDK backend, running under systemd before graphical.target, SSH session without X forwarding, or DISPLAY set to a display that has shut down.","commonSituations":"Users starting `eww daemon` from cron/systemd user units before login, SSH shells, CI containers, or after logging out of the graphical session while the daemon keeps running. Wayland-only setups where GDK was built without the wayland backend.","solutions":["Ensure a display server is reachable: verify `echo $DISPLAY` (X11) or `XDG_SESSION_TYPE=wayland` and that the daemon inherits the session environment (`dbus-launch`, `systemctl --user import-environment DISPLAY WAYLAND_DISPLAY`).","Start eww from inside the graphical session (autostart/desktop entry) rather than from a login shell or system service.","Under Wayland, use `eww daemon` with GDK Wayland support, or force the X11 backend via `GDK_BACKEND=x11` with XWayland running.","If running headless intentionally, guard the call: fall back to skipping monitor watching when Display::default() is None instead of panicking.","Check that GDK was compiled with a usable backend (`GDK_BACKEND=x11,wayland` debug) and that libgtk is the expected version."],"exampleFix":"// before\nlet display = gtk::gdk::Display::default().expect(\"could not get default display\");\ndisplay.connect_monitor_added(...);\n// after\nlet display = match gtk::gdk::Display::default() {\n    Some(d) => d,\n    None => {\n        log::warn!(\"No default display available; monitor watching disabled\");\n        return;\n    }\n};\ndisplay.connect_monitor_added(...);","handlingStrategy":"fallback","validationCode":"// before starting the daemon\nif std::env::var(\"DISPLAY\").is_err() && std::env::var(\"WAYLAND_DISPLAY\").is_err() {\n    eprintln!(\"No DISPLAY/WAYLAND_DISPLAY set; eww needs a graphical session\");\n    std::process::exit(1);\n}","typeGuard":"fn has_default_display() -> bool { gtk::gdk::Display::default().is_some() }","tryCatchPattern":"// Rust panics cannot be caught idiomatically here; use catch_unwind only as a last resort\nlet result = std::panic::catch_unwind(connect_monitor_added_safe);","preventionTips":["Start eww from within the graphical session, not cron/SSH/boot scripts","Import session env into systemd user units: systemctl --user import-environment DISPLAY WAYLAND_DISPLAY","Check `echo $DISPLAY` / `XDG_SESSION_TYPE` before launching","Under Wayland ensure XWayland or a GDK wayland backend is available"],"tags":["gtk","gdk","display-server","daemon"],"backgroundTag":"missing-env-var","analyzedSha":"48f5aa8b379adf29da0b0bb9ca04164f65d8bdaa","analyzedAt":"2026-09-08T03:13:26.897Z","contentChangedAt":"2026-09-08T03:13:26.897Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}