idea: fallback to TUI when GUI can't be initialized #33

Closed
opened 2026-07-16 11:05:53 +00:00 by hugo · 2 comments
Owner

this is mostly for linux servers - if the GUI can't be initialized due to missing display, the TUI should be automatically selected and opened instead. That way it doesn't matter where the app is, when I start it, it will open an UI, either graphical or text oriented.

this is mostly for linux servers - if the GUI can't be initialized due to missing display, the TUI should be automatically selected and opened instead. That way it doesn't matter where the app is, when I start it, it will open an UI, either graphical or text oriented.
hugo added the idea label 2026-07-16 11:05:53 +00:00
Author
Owner

Implemented in 381deb4.

Desktop mode now falls back to the TUI when no graphical display is available:

  • New BDS.Server.effective_mode/3: when BDS_MODE resolves to desktop on a non-Darwin unix system and neither DISPLAY nor WAYLAND_DISPLAY is set (or they are empty), the app boots in tui mode instead — headless server + SSH daemon + a TUI on the launching terminal — rather than crashing wx. Starting the app anywhere now always opens a UI, graphical or text.
  • Explicit BDS_MODE=server/tui are never rewritten, and macOS/Windows always keep desktop mode (a launched app has a graphical session there).
  • The endpoint's webview-token auth follows the effective mode, so SSH-tunneled GUI clients aren't locked out in fallback mode.
  • A log line records the mode switch at boot.

Covered by tests in test/bds/server_test.exs (effective_mode/3 describe block), spec updated in specs/server.allium (ModeResolution rule, allium check clean). Build, full test suite, credo, deps.audit and dialyzer are all clean.

Implemented in 381deb4. Desktop mode now falls back to the TUI when no graphical display is available: - New `BDS.Server.effective_mode/3`: when `BDS_MODE` resolves to desktop on a non-Darwin unix system and neither `DISPLAY` nor `WAYLAND_DISPLAY` is set (or they are empty), the app boots in tui mode instead — headless server + SSH daemon + a TUI on the launching terminal — rather than crashing wx. Starting the app anywhere now always opens a UI, graphical or text. - Explicit `BDS_MODE=server`/`tui` are never rewritten, and macOS/Windows always keep desktop mode (a launched app has a graphical session there). - The endpoint's webview-token auth follows the effective mode, so SSH-tunneled GUI clients aren't locked out in fallback mode. - A log line records the mode switch at boot. Covered by tests in test/bds/server_test.exs (effective_mode/3 describe block), spec updated in specs/server.allium (ModeResolution rule, allium check clean). Build, full test suite, credo, deps.audit and dialyzer are all clean.
hugo closed this issue 2026-07-16 15:46:49 +00:00
Author
Owner

Follow-up fix in 59333ac — the first implementation checked the display too late: the :desktop dependency application boots wx inside its own Application.start, before any BDS code runs, so the VM crashed on hermes before the fallback could fire.

Two changes:

  • config/runtime.exs now calls BDS.Server.prepare_boot_env() — runtime config is the only hook that runs before dependency applications start (both mix run and releases). For every non-desktop effective mode it sets NO_WX=1, elixir-desktop's own switch that turns all of its wx calls into no-ops, so the :desktop app starts inert and the TUI fallback can actually boot. This also fixes explicit BDS_MODE=server/tui on display-less machines, which crashed the same way.
  • Headless detection is now per platform: non-Darwin unix needs DISPLAY/WAYLAND_DISPLAY (plain ssh is covered by that; ssh -X with a forwarded display keeps the GUI). macOS never sets DISPLAY, so there an ssh session (SSH_CONNECTION/SSH_CLIENT/SSH_TTY) is the headless signal — local launches on Mac always get the GUI. Windows always boots the GUI.

So: GUI on a proper graphical session, TUI when there is none — including ssh into a Mac or Linux box.

Please retry mix run --no-halt on hermes. Tests cover the new env preparation and all platform/ssh combinations; spec, build, full test suite, credo, deps.audit and dialyzer are clean.

Follow-up fix in 59333ac — the first implementation checked the display too late: the :desktop dependency application boots wx inside its own Application.start, before any BDS code runs, so the VM crashed on hermes before the fallback could fire. Two changes: - `config/runtime.exs` now calls `BDS.Server.prepare_boot_env()` — runtime config is the only hook that runs before dependency applications start (both `mix run` and releases). For every non-desktop effective mode it sets `NO_WX=1`, elixir-desktop's own switch that turns all of its wx calls into no-ops, so the :desktop app starts inert and the TUI fallback can actually boot. This also fixes explicit `BDS_MODE=server`/`tui` on display-less machines, which crashed the same way. - Headless detection is now per platform: non-Darwin unix needs `DISPLAY`/`WAYLAND_DISPLAY` (plain ssh is covered by that; `ssh -X` with a forwarded display keeps the GUI). macOS never sets `DISPLAY`, so there an ssh session (`SSH_CONNECTION`/`SSH_CLIENT`/`SSH_TTY`) is the headless signal — local launches on Mac always get the GUI. Windows always boots the GUI. So: GUI on a proper graphical session, TUI when there is none — including ssh into a Mac or Linux box. Please retry `mix run --no-halt` on hermes. Tests cover the new env preparation and all platform/ssh combinations; spec, build, full test suite, credo, deps.audit and dialyzer are clean.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hugo/bDS2#33