pw_console: Use a single global log redraw timer

Previously each separate log pane had it's own redraw timer.  This
could lead to screen redraws triggering unnecessarily in quick
sucession. This change switches to a single log redraw timer with a
max of 10 fps. This is just for new log lines. The prompt_toolkit app
will still run at 30 fps so input is more responsive.

Change-Id: Ibf299630cb7356f739058f1523e44a3cc4abaf30
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/108730
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Anthony DiGirolamo <tonymd@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
diff --git a/pw_console/py/pw_console/console_app.py b/pw_console/py/pw_console/console_app.py
index 2539148..a957100 100644
--- a/pw_console/py/pw_console/console_app.py
+++ b/pw_console/py/pw_console/console_app.py
@@ -21,6 +21,7 @@
 import os
 from pathlib import Path
 import sys
+import time
 from threading import Thread
 from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
 
@@ -143,6 +144,11 @@
         self.prefs = prefs if prefs else ConsolePrefs()
         self.color_depth = get_default_colordepth(color_depth)
 
+        # Max frequency in seconds of prompt_toolkit UI redraws triggered by new
+        # log lines.
+        self.log_ui_update_frequency = 0.1  # 10 FPS
+        self._last_ui_update_time = time.time()
+
         # Create a default global and local symbol table. Values are the same
         # structure as what is returned by globals():
         #   https://docs.python.org/3/library/functions.html#globals
@@ -937,6 +943,16 @@
         """Quit the console prompt_toolkit application UI."""
         self.application.exit()
 
+    def logs_redraw(self):
+        emit_time = time.time()
+        # Has enough time passed since last UI redraw due to new logs?
+        if emit_time > self._last_ui_update_time + self.log_ui_update_frequency:
+            # Update last log time
+            self._last_ui_update_time = emit_time
+
+            # Trigger Prompt Toolkit UI redraw.
+            self.redraw_ui()
+
     def redraw_ui(self):
         """Redraw the prompt_toolkit UI."""
         if hasattr(self, 'application'):
diff --git a/pw_console/py/pw_console/log_view.py b/pw_console/py/pw_console/log_view.py
index 31b7db8..468b463 100644
--- a/pw_console/py/pw_console/log_view.py
+++ b/pw_console/py/pw_console/log_view.py
@@ -23,7 +23,6 @@
 import operator
 from pathlib import Path
 import re
-import time
 from typing import Callable, Dict, List, Optional, Tuple, TYPE_CHECKING
 
 from prompt_toolkit.data_structures import Point
@@ -128,10 +127,6 @@
         self._reset_log_screen_on_next_render: bool = True
         self._user_scroll_event: bool = False
 
-        # Max frequency in seconds of prompt_toolkit UI redraws triggered by new
-        # log lines.
-        self._ui_update_frequency = 0.05
-        self._last_ui_update_time = time.time()
         self._last_log_store_index = 0
         self._new_logs_since_last_render = True
 
@@ -540,18 +535,7 @@
             self.follow_event = FollowEvent.STICKY_FOLLOW
 
         # Trigger a UI update
-        self._update_prompt_toolkit_ui()
-
-    def _update_prompt_toolkit_ui(self):
-        """Update Prompt Toolkit UI if a certain amount of time has passed."""
-        emit_time = time.time()
-        # Has enough time passed since last UI redraw?
-        if emit_time > self._last_ui_update_time + self._ui_update_frequency:
-            # Update last log time
-            self._last_ui_update_time = emit_time
-
-            # Trigger Prompt Toolkit UI redraw.
-            self.log_pane.application.redraw_ui()
+        self.log_pane.application.logs_redraw()
 
     def get_cursor_position(self) -> Point:
         """Return the position of the cursor."""