From c79be2bbb7200c4040d2ef729c47266b9d7bf2a5 Mon Sep 17 00:00:00 2001 From: Drew VanDine Date: Wed, 3 Jun 2026 08:53:33 -0400 Subject: [PATCH 1/2] feat: show loading spinner on Click Here buttons while app is running Co-Authored-By: Claude Sonnet 4.6 --- src/manualtest.py | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/manualtest.py b/src/manualtest.py index 741b442..77b5fed 100644 --- a/src/manualtest.py +++ b/src/manualtest.py @@ -1,4 +1,6 @@ import gi +import subprocess +import threading gi.require_version("Adw", "1") gi.require_version("Gdk", "4.0") @@ -416,6 +418,29 @@ def on_touchscreen_toggled(self, button): print(d) self.check_status() + def _launch_app_with_spinner(self, button, command): + spinner = Gtk.Spinner() + spinner.start() + button.set_child(spinner) + button.set_sensitive(False) + + def _run(): + try: + proc = subprocess.Popen( + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + proc.wait() + except Exception: + pass + GLib.idle_add(_restore) + + def _restore(): + button.set_label("Click Here") + button.set_sensitive(True) + return False + + threading.Thread(target=_run, daemon=True).start() + # Launch the fullscreen touchscreen test def on_touchscreen_clicked(self, button): print("ManualTest:on_touchscreen_clicked") @@ -425,10 +450,11 @@ def on_touchscreen_clicked(self, button): # means such a crash only fails the test rather than killing the # provisioning app. import os - import subprocess import sys - import threading + spinner = Gtk.Spinner() + spinner.start() + button.set_child(spinner) button.set_sensitive(False) self.touchscreen_button.set_sensitive(False) @@ -465,6 +491,7 @@ def _on_touchscreen_test_complete(self, passed, click_button=None): self.touchscreen_button.set_active(passed) self.touchscreen_button.set_sensitive(True) if click_button is not None: + click_button.set_label("Click Here") click_button.set_sensitive(True) return False @@ -492,7 +519,7 @@ def on_wifi_toggled(self, button): # Launch the screen-test app when clicked def on_screentest_clicked(self, button): print("ManualTest:on_screentest_clicked") - self.utils.launch_app("screen-test") + self._launch_app_with_spinner(button, "screen-test") # Launch the gnome-text-editor app when clicked def on_keyboard_clicked(self, button): @@ -503,11 +530,14 @@ def on_keyboard_clicked(self, button): def on_webcam_clicked(self, button): print("ManualTest:on_webcam_clicked") if self.utils.file_exists_and_executable("/usr/bin/guvcview"): - self.utils.launch_app("guvcview") + cmd = "guvcview" elif self.utils.file_exists_and_executable("/usr/bin/cheese"): - self.utils.launch_app("cheese") + cmd = "cheese" elif self.utils.file_exists_and_executable("/usr/bin/snapshot"): - self.utils.launch_app("snapshot") + cmd = "snapshot" + else: + return + self._launch_app_with_spinner(button, cmd) # Handle toggled event for the browser button def on_browser_toggled(self, button): @@ -519,7 +549,7 @@ def on_browser_toggled(self, button): # Launch the xdg-open app to open https://vimeo.com/116979416 in browser def on_browser_clicked(self, button): print("Manual:on_browser_clicked") - self.utils.launch_app("xdg-open https://vimeo.com/116979416") + self._launch_app_with_spinner(button, "xdg-open https://vimeo.com/116979416") def check_status(self): print("ManualTest:check_status") From d93ad40c576845406f18d2b89e3e983dd7d9bb34 Mon Sep 17 00:00:00 2001 From: Drew VanDine Date: Thu, 18 Jun 2026 21:59:28 -0400 Subject: [PATCH 2/2] fix: address Copilot review findings in _launch_app_with_spinner - Use communicate() instead of wait() to drain stdout/stderr pipes and prevent potential deadlock when launched apps produce output - Log exceptions instead of silently swallowing them - Stop spinner before restoring button label in both _restore and _on_touchscreen_test_complete to avoid leaving spinner running Co-Authored-By: Claude Sonnet 4.6 --- src/manualtest.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/manualtest.py b/src/manualtest.py index 77b5fed..e7b8abd 100644 --- a/src/manualtest.py +++ b/src/manualtest.py @@ -429,12 +429,13 @@ def _run(): proc = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - proc.wait() - except Exception: - pass + proc.communicate() + except Exception as e: + print(f"_launch_app_with_spinner: failed to launch '{command}': {e}") GLib.idle_add(_restore) def _restore(): + spinner.stop() button.set_label("Click Here") button.set_sensitive(True) return False @@ -491,6 +492,9 @@ def _on_touchscreen_test_complete(self, passed, click_button=None): self.touchscreen_button.set_active(passed) self.touchscreen_button.set_sensitive(True) if click_button is not None: + child = click_button.get_child() + if isinstance(child, Gtk.Spinner): + child.stop() click_button.set_label("Click Here") click_button.set_sensitive(True) return False