elkowar/eww · error
could not get default display
Error message
could not get default display
What it means
`wait_for_monitor_model` polls the GDK display until every connected monitor reports a model string, which eww uses to build its monitor model. `gdk::Display::default()` returned `None`, meaning no default display is available in this process, and the `expect` panics with this message. Without a display there is nothing to wait on.
Solutions
- Ensure `DISPLAY` (X11) or `WAYLAND_DISPLAY`/`XDG_RUNTIME_DIR` env vars are set to a live session before invoking eww.
- Run eww inside the graphical session, e.g. via `systemctl --user import-environment DISPLAY WAYLAND_DISPLAY` or launching from the compositor's autostart.
- Retry after the window manager/session is up; the call will succeed once a display exists.
Example fix
// before (crontab/systemd unit) ExecStart = eww daemon // after ExecStart = /bin/sh -c '. $HOME/.profile && exec eww daemon' # with DISPLAY exported
Defensive patterns
Strategy: try-catch
Validate before calling
if std::env::var("DISPLAY").is_err() && std::env::var("WAYLAND_DISPLAY").is_err() {
eprintln!("no graphical session: set DISPLAY or WAYLAND_DISPLAY before running eww");
std::process::exit(1);
} Try / catch
match gdk::Display::default() {
Some(display) => /* poll monitors */,
None => eprintln!("no default display; is the graphical session running?"),
} Prevention
- Launch eww from within the graphical session or a systemd user unit that imports DISPLAY/WAYLAND_DISPLAY.
- Delay eww start until the compositor/X server is up.
- Check `echo $DISPLAY` / `$WAYLAND_DISPLAY` in the exact environment eww runs in.
When it happens
Trigger: Calling `try_handle_command` → `wait_for_monitor_model` in an environment where GTK/GDK cannot open a default display: no X server/Wayland compositor, or DISPLAY/WAYLAND_DISPLAY unset.
Common situations: Running `eww` commands from a systemd service, cron job, SSH session, or TTY where `DISPLAY` is not set; starting eww before the compositor/X server.
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/f852eaaf1f9125de.
Report an issue: GitHub.
Appendix: source
Thrown at crates/eww/src/app.rs:153
pub phantom: PhantomData<B>,
}
impl<B: DisplayBackend> std::fmt::Debug for App<B> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("App")
.field("scope_graph", &*self.scope_graph.borrow())
.field("eww_config", &self.eww_config)
.field("open_windows", &self.open_windows)
.field("failed_windows", &self.failed_windows)
.field("window_arguments", &self.instance_id_to_args)
.field("paths", &self.paths)
.finish()
}
}
/// Wait until the .model() is available for all monitors (or there is a timeout)
async fn wait_for_monitor_model() {
let display = gdk::Display::default().expect("could not get default display");
let start = std::time::Instant::now();
loop {
let all_monitors_set =
(0..display.n_monitors()).all(|i| display.monitor(i).and_then(|monitor| monitor.model()).is_some());
if all_monitors_set {
break;
}
tokio::time::sleep(Duration::from_millis(10)).await;
if std::time::Instant::now() - start > Duration::from_millis(500) {
log::warn!("Timed out waiting for monitor model to be set");
break;
}
}
}
impl<B: DisplayBackend> App<B> {
/// Handle a [`DaemonCommand`] event, logging any errors that occur.
pub async fn handle_command(&mut self, event: DaemonCommand) {View on GitHub (pinned to 48f5aa8b37)