home · contact · privacy
To have _ClientWindowManager.log use parent's ._log, factor window selection into...
authorChristian Heller <c.heller@plomlompom.de>
Sun, 10 Aug 2025 12:45:33 +0000 (14:45 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sun, 10 Aug 2025 12:45:33 +0000 (14:45 +0200)
ircplom/client_tui.py
ircplom/tui_base.py

index dfef804cb8b925eac0581701a2d967b2b3d59b3e..f29317d9c7457fba9c2ca792ddb71619c7864ff4 100644 (file)
@@ -3,7 +3,7 @@
 from getpass import getuser
 from dataclasses import asdict as dc_asdict
 from inspect import signature
-from typing import Callable, Optional
+from typing import Callable, Optional, Sequence
 # ourselves
 from ircplom.tui_base import (BaseTui, PromptWidget, TuiEvent, Window,
                               CMD_SHORTCUTS)
@@ -92,7 +92,9 @@ class _ClientWindowsManager:
     nick_confirmed: bool = False
     nickname: str = '?'
 
-    def __init__(self, new_window: Callable) -> None:
+    def __init__(self, client_id: str, new_window: Callable, tui_log: Callable
+                 ) -> None:
+        self.log = lambda **kw: tui_log(client_id=client_id, **kw) or True
         self.windows: list[_ClientWindow] = []
         self._tui_new_window = new_window
         for stream in (STREAM_SERVER, STREAM_RAW):
@@ -117,14 +119,6 @@ class _ClientWindowsManager:
             return win
         return self._new_window(stream)
 
-    def log(self, msg: str, stream: str) -> None:
-        'Log msg to stram.'
-        if stream == STREAM_ALL:
-            for win in self.windows:
-                win.history.append(msg)
-        else:
-            self.window(stream).history.append(msg)
-
     def update(self, **kwargs) -> bool:
         'Apply settings in kwargs, follow represntation update triggres.'
         for k, v in kwargs.items():
@@ -145,12 +139,20 @@ class ClientTui(BaseTui):
         super().__init__(**kwargs)
         self._client_mngrs: dict[str, _ClientWindowsManager] = {}
 
+    def _log_target_wins(self, **kwargs) -> Sequence[Window]:
+        stream = kwargs.get('stream', _STREAM_SAME)
+        if stream != _STREAM_SAME and 'client_id' in kwargs:
+            m = self._client_mngrs[kwargs['client_id']]
+            return m.windows if stream == STREAM_ALL else [m.window(stream)]
+        return super()._log_target_wins(**kwargs)
+
     def for_client_do(self, client_id: str, todo: str, **kwargs) -> None:
-        'Forward todo to appropriate ClientTuiMgr.'
+        'Forward todo to appropriate _ClientWindowManager.'
         if client_id not in self._client_mngrs:
             self._client_mngrs[client_id] = _ClientWindowsManager(
-                new_window=lambda cls, **kwargs: self._new_window(
-                    cls, _q_out=self._q_out, client_id=client_id, **kwargs))
+                client_id=client_id, tui_log=self._targeted_log,
+                new_window=lambda cls, **kw: self._new_window(
+                    cls, _q_out=self._q_out, client_id=client_id, **kw))
         client_data = self._client_mngrs[client_id]
         method = getattr(client_data, todo)
         if method(**kwargs) or signature(method).return_annotation is None:
@@ -217,11 +219,7 @@ class _ClientKnowingTui(Client):
             for k, v in dc_asdict(kwargs['conn_setup']).items():
                 to_log += [f'  {k}: [{v}]']
         for item in to_log:
-            if stream == _STREAM_SAME:
-                self._put(TuiEvent.affector('_log').kw(msg=item))
-                self._put(TuiEvent.affector('redraw_affected'))
-            else:
-                self._client_tui_trigger('log', stream=stream, msg=item)
+            self._client_tui_trigger('log', stream=stream, msg=item)
 
     def update_login(self, nick_confirmed: bool, nickname: str = '') -> None:
         super().update_login(nick_confirmed, nickname)
index 8d02901da64678d88ccc0e54c30493dc39a37eee..354a533a2a614952185987d67f2a8b50bcf61b58 100644 (file)
@@ -5,7 +5,8 @@ from base64 import b64decode
 from contextlib import contextmanager
 from inspect import _empty as inspect_empty, signature, stack
 from signal import SIGWINCH, signal
-from typing import Callable, Generator, Iterator, NamedTuple, Optional
+from typing import (Callable, Generator, Iterator, NamedTuple, Optional,
+                    Sequence)
 # requirements.txt
 from blessed import Terminal as BlessedTerminal
 # ourselves
@@ -369,13 +370,18 @@ class BaseTui(QueueMixin):
         self._window_idx = 0
         self._windows: list[Window] = []
         self._new_window()
-        self._log = Logger(
-            lambda msg:  # pylint: disable=unnecessary-lambda  # to keep up-to…
-            self.window.history.append(msg)                    # …-date _what_…
-            ).add                                          # …window's .history
+        self._log = Logger(self._targeted_log).add
         self._set_screen()
         signal(SIGWINCH, lambda *_: self._set_screen())
 
+    def _log_target_wins(self, **_) -> Sequence[Window]:
+        # separated to serve as hook for subclass window selection
+        return [self.window]
+
+    def _targeted_log(self, msg: str, **kwargs) -> None:
+        for win in self._log_target_wins(**kwargs):
+            win.history.append(msg)
+
     def _new_window(self, win_class=Window, **kwargs) -> Window:
         new_idx = len(self._windows)
         win = win_class(idx=new_idx, term=self._term, **kwargs)