Skip to content

[Bug]: Desktop window never appears on Linux/Wayland (Electron ready-to-show deadlock) #2216

@mwolson

Description

@mwolson

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. Linux + Wayland session (reproduced on niri; root cause is in Electron, not the compositor).
  2. Run a recent nightly AppImage (e.g. T3-Code-0.0.20-x86_64.AppImage).
  3. Process starts and the renderer loads (verified via network requests to /api/project-favicon), but no window ever appears.

Expected behavior

The main window should appear once the renderer is ready, as on macOS / Windows / X11.

Actual behavior

No window appears. The main process is alive, the renderer process is alive, the React app loads, and the WebSocket connects, but the window stays hidden indefinitely.

Root cause

createWindow() in apps/desktop/src/main.ts constructs the BrowserWindow with show: false and reveals it on ready-to-show. On Wayland, ready-to-show only fires after show() is called for windows created with show: false, because the wl_surface has no role assigned until then and the compositor never reports the surface as ready. The standard "wait for ready, then show" pattern deadlocks: nothing ever calls show(), so ready-to-show never fires.

Confirmed by attaching the Node inspector to the running main process:

  • webContents.isLoading() transitioned to false and did-finish-load fired.
  • ready-to-show did NOT fire during the observation window.
  • After forcing window.show() from the inspector, ready-to-show then fired and the window appeared.

Impact

Blocks work completely

Version or commit

0.0.20 nightly. Reproduces on the current main (66c326b8).

Environment

Linux (niri compositor, Wayland session), Electron 40.6.0, AppImage build (T3-Code-0.0.20-x86_64.AppImage).

Workaround

None at runtime. Forcing show() from a debugger surfaces the window, but there is no user-facing workaround.

Fix

PR incoming: also subscribe to did-finish-load (Linux only) and reveal on whichever event fires first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions