pw_console: Log redraw fix

Prevent prompt_toolkit redraw events being triggered if a log window
pane is not visible.

Change-Id: Ibe088651b0a8abeffab4240de4fc3fc9be87cc5c
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/110234
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Anthony DiGirolamo <tonymd@google.com>
Reviewed-by: Asad Memon <asadmemon@google.com>
diff --git a/pw_console/py/pw_console/log_view.py b/pw_console/py/pw_console/log_view.py
index 468b463..0388697 100644
--- a/pw_console/py/pw_console/log_view.py
+++ b/pw_console/py/pw_console/log_view.py
@@ -534,8 +534,9 @@
             # Set the follow event flag for the next render_content call.
             self.follow_event = FollowEvent.STICKY_FOLLOW
 
-        # Trigger a UI update
-        self.log_pane.application.logs_redraw()
+        # Trigger a UI update if the log window is visible.
+        if self.log_pane.show_pane:
+            self.log_pane.application.logs_redraw()
 
     def get_cursor_position(self) -> Point:
         """Return the position of the cursor."""
diff --git a/pw_console/py/pw_console/window_list.py b/pw_console/py/pw_console/window_list.py
index ec21b58..5d81526 100644
--- a/pw_console/py/pw_console/window_list.py
+++ b/pw_console/py/pw_console/window_list.py
@@ -252,6 +252,12 @@
     def switch_to_tab(self, index: int):
         self.focused_pane_index = index
 
+        # Make the selected tab visible and hide the rest.
+        for i, pane in enumerate(self.active_panes):
+            pane.show_pane = False
+            if i == index:
+                pane.show_pane = True
+
         # refresh_ui() will focus on the new tab container.
         self.refresh_ui()
 
@@ -259,8 +265,15 @@
         self.display_mode = mode
 
         if self.display_mode == DisplayMode.TABBED:
+            # Default to focusing on the first window / tab.
             self.focused_pane_index = 0
-            # Un-hide all panes, they must be visible to switch between tabs.
+            # Hide all other panes so log redraw events are not triggered.
+            for pane in self.active_panes:
+                pane.show_pane = False
+            # Keep the selected tab visible
+            self.active_panes[self.focused_pane_index].show_pane = True
+        else:
+            # Un-hide all panes if switching from tabbed back to stacked.
             for pane in self.active_panes:
                 pane.show_pane = True
 
@@ -584,11 +597,3 @@
             if next_pane.show_pane:
                 return next_pane
         return None
-
-    def focus_next_visible_pane(self, pane):
-        """Focus on the next visible window pane if possible."""
-        next_visible_pane = self._get_next_visible_pane_after(pane)
-        if next_visible_pane:
-            self.application.layout.focus(next_visible_pane)
-            return
-        self.application.focus_main_menu()
diff --git a/pw_console/py/window_manager_test.py b/pw_console/py/window_manager_test.py
index f9e7095..9b6444e 100644
--- a/pw_console/py/window_manager_test.py
+++ b/pw_console/py/window_manager_test.py
@@ -109,6 +109,9 @@
 def target_list_and_pane(window_manager, list_index, pane_index):
     # pylint: disable=protected-access
     # Bypass prompt_toolkit has_focus()
+    pane = window_manager.window_lists[list_index].active_panes[pane_index]
+    # If the pane is in focus it will be visible.
+    pane.show_pane = True
     window_manager._get_active_window_list_and_pane = (
         MagicMock(  # type: ignore
             return_value=(
@@ -465,6 +468,7 @@
             console_app = _create_console_app(logger_count=4)
 
             window_manager = console_app.window_manager
+            window_manager.window_lists[0].set_display_mode(DisplayMode.STACK)
             self.assertEqual(
                 window_pane_titles(window_manager),
                 [