From 35d80c32f2183732f082bf915aad2037190c4151 Mon Sep 17 00:00:00 2001 From: pax Date: Wed, 8 Apr 2026 20:01:16 -0500 Subject: [PATCH] popout/window: route adapter logger to stderr for terminal capture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to commit 14a. The booru logger has only the in-app QTextEdit LogHandler attached (main_window.py:436-440), so the POPOUT_FSM dispatch trace from the state machine adapter only reaches the Ctrl+L log panel — invisible from the shell. Adds a stderr StreamHandler attached directly to the `booru.popout.adapter` logger so: python -m booru_viewer.main_gui 2>&1 | grep POPOUT_FSM works during the commit-14a verification gate. The user can capture the dispatch trace per scenario and compare it to the legacy path's actions before commit 14b switches authority. The handler is tagged with a `_is_popout_fsm_stderr` sentinel attribute so re-imports of window.py don't stack duplicate handlers (defensive — module-level code only runs once per process, but the check costs nothing). Format: `[HH:MM:SS.mmm] POPOUT_FSM | -> | effects=[...]` The millisecond precision matters for the seek scenario where the race window is sub-100ms. Propagation to the parent booru logger is left enabled, so dispatch trace lines also continue to land in the in-app log panel for the user who prefers Ctrl+L. Tests still pass (81 / 81). No behavior change to widgets — this only affects log output routing. --- booru_viewer/gui/popout/window.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/booru_viewer/gui/popout/window.py b/booru_viewer/gui/popout/window.py index 8bfbff0..8576d6b 100644 --- a/booru_viewer/gui/popout/window.py +++ b/booru_viewer/gui/popout/window.py @@ -45,7 +45,31 @@ from .viewport import Viewport, _DRIFT_TOLERANCE # dispatch call logs at DEBUG with the event name, state transition, # and effect list. The user filters by `POPOUT_FSM` substring to see # only the state machine activity during the manual sweep. +# +# The booru logger (parent) only has the in-app QTextEdit LogHandler +# attached (see main_window.py:436-440), so propagating to it routes +# the dispatch trace to the Ctrl+L log panel — useful but invisible +# from the shell. We additionally attach a stderr StreamHandler to +# the adapter logger so `python -m booru_viewer.main_gui 2>&1 | +# grep POPOUT_FSM` works during the commit-14a verification gate. +# The handler is tagged with a sentinel attribute so re-imports +# don't stack duplicates. +import sys as _sys _fsm_log = logging.getLogger("booru.popout.adapter") +_fsm_log.setLevel(logging.DEBUG) +if not any( + getattr(h, "_is_popout_fsm_stderr", False) for h in _fsm_log.handlers +): + _stderr_handler = logging.StreamHandler(_sys.stderr) + _stderr_handler.setLevel(logging.DEBUG) + _stderr_handler.setFormatter( + logging.Formatter( + "[%(asctime)s.%(msecs)03d] %(message)s", + datefmt="%H:%M:%S", + ) + ) + _stderr_handler._is_popout_fsm_stderr = True + _fsm_log.addHandler(_stderr_handler) ## Overlay styling for the popout's translucent toolbar / controls bar