Skip to content

Fix loader lingering or force-quitting on macOS Cmd+Q - #85

Open
peter-bonanni wants to merge 2 commits into
Spacehaven-modding-tools:masterfrom
peter-bonanni:fix-macos-quit-lingering
Open

Fix loader lingering or force-quitting on macOS Cmd+Q#85
peter-bonanni wants to merge 2 commits into
Spacehaven-modding-tools:masterfrom
peter-bonanni:fix-macos-quit-lingering

Conversation

@peter-bonanni

Copy link
Copy Markdown

Summary

  • Register tk::mac::Quit so Cmd+Q on macOS routes through the same guarded quit() as the window close button, instead of bypassing it via Tk's default Quit handler.
  • Mark the background task thread as a daemon so the interpreter can exit once the GUI is gone, instead of lingering as a headless process while waiting on the launched game.

Why

On macOS, Cmd+Q is delivered through Tk's tk::mac::Quit handler rather than WM_DELETE_WINDOW, so it bypassed quit() entirely. Depending on the Tk build this either terminated the process immediately (skipping unload(), leaving spacehaven.jar patched) or destroyed the window while the non-daemon launch thread kept the loader alive as a headless process waiting on the game to exit — matching the ps output in the issue.

Fixes #74

Test plan

  • All existing unit tests pass (uv run python -m unittest discover -s tests)
  • ruff check passes
  • Reproduced the bug with a minimal Tk app (default Quit path kills the process with no cleanup)
  • Verified Cmd+Q is correctly blocked while a background task is running ("Cannot quit while a task is running!")
  • Verified the patched loader exits cleanly (exit code 0) on Cmd+Q when idle, on macOS

On macOS, Cmd+Q is delivered through Tk's tk::mac::Quit handler rather
than WM_DELETE_WINDOW, so it bypassed quit() entirely. Depending on the
Tk build this either terminated the process immediately (skipping
unload(), leaving spacehaven.jar patched) or destroyed the window while
the non-daemon launch thread kept the loader alive as a headless
process waiting on the game.

Register tk::mac::Quit to route Cmd+Q through the same guarded quit()
as the close button, and mark the background task thread as a daemon so
the interpreter can always exit once the GUI is gone.

Fixes Spacehaven-modding-tools#74

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@peter-bonanni
peter-bonanni marked this pull request as draft June 11, 2026 01:19
@peter-bonanni

Copy link
Copy Markdown
Author

Automated fix, take it or leave it. Tested and it seems to work.

@peter-bonanni
peter-bonanni marked this pull request as ready for review June 11, 2026 01:20
If quit() destroys the window while a previously scheduled
update_background_state tick is still pending, the callback fires
afterward and tries to configure launchButton, raising
'invalid command name ...'. handleException then attempts
messagebox.showerror on the now-destroyed root, raising again and
crashing the process (exit code 1) instead of just logging.

Bail out of update_background_state if the window is gone, and make
handleException tolerate a missing root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Loader on MacOS fails to exit

1 participant