System tray

Provides system-tray controls for monitoring, reporting, pause and resume, and application exit.

Runtime dependencies

Dispatcher


source

UiDispatcher

def UiDispatcher(
    root
):

Dispatches callbacks from background threads to Tkinter’s main thread, ensuring UI updates are executed safely through the root event loop.

Report actions


source

open_current_session_report

def open_current_session_report(
    controller, # Controller used to generate current-session report data
    root, submit_ui
):

Show the current-session report when report data is available.


source

open_last_session_report

def open_last_session_report(
    controller, # Controller used to generate last-session report data
    root, submit_ui
):

Show the last-session report when report data is available.

Tray menu and event loop


source

run_tray

def run_tray(
    controller, # Controller that owns monitoring and pause/resume state
    show_last_on_start:bool=False, # Whether to show the last session report on app start up
):

Start the tray integration and block in the Tkinter event loop until exit.

  • root = tk.Tk() runs at module-import time. This creates a GUI object as an import side effect and will also fail in headless environments. Confirm that import-time Tk initialization is intentional.

  • The report helpers call show_report from new daemon threads. This appears inconsistent with the project rule that Tkinter UI operations should run on the Tk main thread, preferably through root.after(...).

  • After pausing, pause_for calls open_current_session_report(controller). Because pausing ends the current session, confirm whether this should instead display the report for the just-ended session.

  • Cancelling the custom pause dialog performs no pause. It does not use DEFAULT_PAUSE_MINUTES; confirm whether this is the intended current behaviour.

  • root is exported as part of the module’s public API because its cell uses #| export. Confirm whether it should remain public or eventually become an internal implementation detail.

  • The public functions accept an untyped controller. The comments document how it is used, but the implementation does not identify a concrete controller type, so no type annotation has been invented.

  • The current notebook output shows that the failed pystray import prevented tk from being imported, which caused the later root = tk.Tk() cell to fail with NameError. This is a cascading notebook-execution failure rather than an independent missing import.