Skip to content

Tray "Quit" leaves Electron processes (Hyperia.exe) running after full exit (win32) #126

Description

@kordless

Summary

Choosing Quit from the system-tray menu does not fully terminate the app on Windows. The Rust sidecar exits cleanly, but the Electron process tree keeps running (main + GPU + utility processes). This is reproducible/recurring, not a one-off.

Observed

After a complete tray Quit, four processes remained alive:

PID Role
14204 main process
32592 GPU process
6348, 32868 utility processes

hyperia-sidecar.exe was gone (so killSidecar() ran), but …\AppData\Local\Programs\Hyperia\Hyperia.exe (main) and its GPU/utility children persisted indefinitely. They must be killed manually (Stop-Process).

Expected

Tray Quit terminates the entire process tree — main, GPU, and all utility/renderer children — with no leftovers.

Repro

  1. Launch the installed Hyperia (win32).
  2. System tray → Quit.
  3. `Get-CimInstance Win32_Process | ? { $_.Name -eq 'Hyperia.exe' }` → still lists ~4 processes.

Code pointers

  • Tray Quit item → `app.quit()` — `app/notify.ts:131`
  • `app.on('before-quit')` → `destroyTray()` + `stopBridge()` + `killSidecar()` — `app/index.ts:609`. This runs (sidecar dies), but the quit doesn't complete to process exit.
  • `window-all-closed` is intentionally a no-op on non-darwin (keep tray/sidecar alive) — `app/index.ts:601`.

Likely causes to investigate

  • Hidden, never-destroyed windows keeping the app alive. Sticky-note windows `hide()` instead of close/destroy (`app/sticky.ts:1133, 1227, 1241`); a hidden `BrowserWindow` that's never destroyed can block process exit on `app.quit()`.
  • A `BrowserWindow` `'close'` handler holding the window open (`app/window-state.ts:151`), or a lingering handle (node-pty PTYs, webview guests, open sockets/timers) keeping the libuv loop alive so the main process never exits — orphaning the GPU/utility children.
  • `before-quit` does teardown but nothing force-exits stragglers.

Possible fix directions

  • On quit, destroy all windows (including hidden sticky windows) before/within `before-quit`.
  • Ensure all child handles (PTYs, webviews) are torn down.
  • As a backstop, after cleanup call `app.exit(0)` (or a short watchdog → `app.exit`) so a stray handle can't keep the tree alive.

Environment

  • OS: Windows 11 Pro (10.0.26200)
  • Installed build at `C:\Users\kordl\AppData\Local\Programs\Hyperia\Hyperia.exe`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions