Skip to content

Add GUI status window with logs viewer for macOS app shutdown#162

Merged
thawn merged 6 commits intomasterfrom
copilot/fix-app-shutdown-macos
Jan 4, 2026
Merged

Add GUI status window with logs viewer for macOS app shutdown#162
thawn merged 6 commits intomasterfrom
copilot/fix-app-shutdown-macos

Conversation

Copy link
Contributor

Copilot AI commented Jan 4, 2026

  • Fix test failures in Docker containers without tkinter
    • Wrap tkinter import in try/except block with noqa comments
    • Add _tkinter_available flag to track tkinter availability
    • Update should_use_gui() to check tkinter availability
    • Add RuntimeError in ServerStatusWindow.init if tkinter unavailable
    • Use Any type hints for tk/ttk objects to avoid type checker issues
    • Add type: ignore comments where needed
  • Test the fix
    • Both failing tests now pass (test_default_uses_production_server, test_dev_flag_shows_warning)
    • All tests in test_production_flag.py pass (3/3)
    • Application starts correctly
    • Passes all pre-commit hooks
Original prompt

This section details on the original issue you should resolve

<issue_title>unable to shut down v2.0 app on Mac OS</issue_title>
<issue_description>it is not possible to shut down the v2.0 app on MacOS, since the process just forks to the background and opens a browser window.

  • we need an app window that shows the server status and shuts down the server process when it is closed. On windows, this is already possible because launching the app opens a terminal window. maybe we can achieve the same on Mac?</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits January 4, 2026 16:05
Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix app shutdown process on Mac OS v2.0 Add GUI status window for macOS app shutdown Jan 4, 2026
Copilot AI requested a review from thawn January 4, 2026 16:12
@thawn
Copy link
Owner

thawn commented Jan 4, 2026

@copilot research why console=True does not work on mac os. Maybe there is a way to get this to work.

if that fails, keep the gui and add a button that shows the server logs

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 4, 2026

@copilot research why console=True does not work on mac os. Maybe there is a way to get this to work.

if that fails, keep the gui and add a button that shows the server logs

I researched the console=True issue on macOS. The problem is that macOS .app bundles (created by the BUNDLE() directive in PyInstaller) ignore console=True by design - macOS always treats .app bundles as GUI applications and won't show a console window.

Why console=True doesn't work:

  • The BUNDLE() wrapper creates a macOS application bundle
  • Even with console=True, the .app hides the console
  • This is intentional macOS behavior for .app bundles

Solution implemented (commit a57cbcc):
I kept the GUI and added a "Show Logs" button that opens a scrollable logs viewer window. This follows the pattern used by professional Mac apps like MAMP and Docker Desktop.

New features:

  • "Show Logs" button in the status window
  • Opens a separate 700x500 scrollable logs window
  • Fetches latest logs from the /logs endpoint (up to 500 lines)
  • "Refresh" button to reload logs
  • "Clear" button to clear the display
  • Uses Courier font for better log readability

The logs window displays server output in real-time and can be refreshed as needed. This is more user-friendly than a console window since:

  • It's searchable and scrollable
  • Can stay open while using the app
  • Follows macOS design patterns
  • Doesn't clutter the screen

Copilot AI changed the title Add GUI status window for macOS app shutdown Add GUI status window with logs viewer for macOS app shutdown Jan 4, 2026
@thawn
Copy link
Owner

thawn commented Jan 4, 2026

@copilot two of the new tests fail (only in the docker container build):

TestDevFlag.test_default_uses_production_server ________________
#15 20.90 tests/unit/test_production_flag.py:87: in test_default_uses_production_server
#15 20.90     assert (
#15 20.90 E   AssertionError: Should use Waitress by default
#15 20.90 E   assert ('Starting production server' in '2026-01-04 16:48:32,143 - ttmp32gme.log_handler - INFO - Log level changed to INFO\n2026-01-04 16:48:32,144 - __main__ - INFO - Verbose mode enabled (INFO level)\n2026-01-04 16:48:32,146 - __main__ - INFO - Initialized library_path in database: /root/.ttmp32gme/library\n2026-01-04 16:48:32,146 - __main__ - INFO - Updating config...\n2026-01-04 16:48:32,149 - ttmp32gme.db_handler - INFO - Executed update function, result: 0\n2026-01-04 16:48:32,149 - ttmp32gme.db_handler - INFO - Executed update function, result: 0\n2026-01-04 16:48:32,151 - __main__ - INFO - Update successful.\n2026-01-04 16:48:32,151 - __main__ - INFO - Using tttool: /usr/local/bin/tttool\n2026-01-04 16:48:32,151 - __main__ - INFO - Server running on http://127.0.0.1:10030/\n2026-01-04 16:48:32,151 - __main__ - INFO - Open this URL in your web browser to continue.\nTraceback (most recent call last):\n  File "<frozen runpy>", line 198, in _run_module_as_main\n  File "<frozen runpy>", line 88, in _run_code\n  File "/app/src/ttmp32gme/ttmp32gme.py", line 878, in <module>\n    main()\n  File "/app/src/ttmp32gme/ttmp32gme.py", line 835, in main\n    from ttmp32gme.gui_handler import should_use_gui, start_gui_server\n  File "/app/src/ttmp32gme/gui_handler.py", line 7, in <module>\n    import tkinter as tk\n  File "/usr/local/lib/python3.12/tkinter/__init__.py", line 38, in <module>\n    import _tkinter # If this fails your Python may not be configured for Tk\n    ^^^^^^^^^^^^^^^\nImportError: libtk8.6.so: cannot open shared object file: No such file or directory\n' or 'Serving on' in '2026-01-04 16:48:32,143 - ttmp32gme.log_handler - INFO - Log level changed to INFO\n2026-01-04 16:48:32,144 - __main__ - INFO - Verbose mode enabled (INFO level)\n2026-01-04 16:48:32,146 - __main__ - INFO - Initialized library_path in database: /root/.ttmp32gme/library\n2026-01-04 16:48:32,146 - __main__ - INFO - Updating config...\n2026-01-04 16:48:32,149 - ttmp32gme.db_handler - INFO - Executed update function, result: 0\n2026-01-04 16:48:32,149 - ttmp32gme.db_handler - INFO - Executed update function, result: 0\n2026-01-04 16:48:32,151 - __main__ - INFO - Update successful.\n2026-01-04 16:48:32,151 - __main__ - INFO - Using tttool: /usr/local/bin/tttool\n2026-01-04 16:48:32,151 - __main__ - INFO - Server running on http://127.0.0.1:10030/\n2026-01-04 16:48:32,151 - __main__ - INFO - Open this URL in your web browser to continue.\nTraceback (most recent call last):\n  File "<frozen runpy>", line 198, in _run_module_as_main\n  File "<frozen runpy>", line 88, in _run_code\n  File "/app/src/ttmp32gme/ttmp32gme.py", line 878, in <module>\n    main()\n  File "/app/src/ttmp32gme/ttmp32gme.py", line 835, in main\n    from ttmp32gme.gui_handler import should_use_gui, start_gui_server\n  File "/app/src/ttmp32gme/gui_handler.py", line 7, in <module>\n    import tkinter as tk\n  File "/usr/local/lib/python3.12/tkinter/__init__.py", line 38, in <module>\n    import _tkinter # If this fails your Python may not be configured for Tk\n    ^^^^^^^^^^^^^^^\nImportError: libtk8.6.so: cannot open shared object file: No such file or directory\n')
#15 20.90 ___________________ TestDevFlag.test_dev_flag_shows_warning ____________________
#15 20.90 tests/unit/test_production_flag.py:112: in test_dev_flag_shows_warning
#15 20.90     assert (
#15 20.90 E   AssertionError: Dev server should show warning with --dev flag
#15 20.90 E   assert 'WARNING: This is a development server' in '2026-01-04 16:48:37,224 - ttmp32gme.log_handler - INFO - Log level changed to INFO\n2026-01-04 16:48:37,224 - __main__ - INFO - Verbose mode enabled (INFO level)\n2026-01-04 16:48:37,225 - __main__ - INFO - Using tttool: /usr/local/bin/tttool\n2026-01-04 16:48:37,225 - __main__ - INFO - Server running on http://127.0.0.1:10031/\n2026-01-04 16:48:37,225 - __main__ - INFO - Open this URL in your web browser to continue.\nTraceback (most recent call last):\n  File "<frozen runpy>", line 198, in _run_module_as_main\n  File "<frozen runpy>", line 88, in _run_code\n  File "/app/src/ttmp32gme/ttmp32gme.py", line 878, in <module>\n    main()\n  File "/app/src/ttmp32gme/ttmp32gme.py", line 835, in main\n    from ttmp32gme.gui_handler import should_use_gui, start_gui_server\n  File "/app/src/ttmp32gme/gui_handler.py", line 7, in <module>\n    import tkinter as tk\n  File "/usr/local/lib/python3.12/tkinter/__init__.py", line 38, in <module>\n    import _tkinter # If this fails your Python may not be configured for Tk\n    ^^^^^^^^^^^^^^^\nImportError: libtk8.6.so: cannot open shared object file: No such file or directory\n'

this is likely due to a missing libtk dependency. Skip these tests if the import fails (which should only happen in the docker container or on other linux systems without tk)

Co-authored-by: thawn <1308449+thawn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 4, 2026

@copilot two of the new tests fail (only in the docker container build):

TestDevFlag.test_default_uses_production_server ________________...

Fixed in commit 89b068b. The issue was that gui_handler.py imported tkinter at the module level, causing an ImportError in Docker containers without the tkinter library (libtk8.6.so).

Solution:

  • Wrapped tkinter imports in try/except block
  • Added _tkinter_available flag to track availability
  • Updated should_use_gui() to return False when tkinter is unavailable
  • The application now starts successfully even without tkinter

Both failing tests now pass:

  • test_default_uses_production_server
  • test_dev_flag_shows_warning

The Docker build will no longer fail due to missing tkinter, while the GUI functionality remains available on macOS with PyInstaller where tkinter is bundled.

@thawn thawn marked this pull request as ready for review January 4, 2026 17:12
@thawn thawn merged commit aa2ff16 into master Jan 4, 2026
13 checks passed
@thawn thawn deleted the copilot/fix-app-shutdown-macos branch January 4, 2026 17:22
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.

unable to shut down v2.0 app on Mac OS

2 participants