Skip to content

fix: prevent UI freeze in offline robot mode and stop Kokoro label stacking#121

Open
TarunWorks wants to merge 1 commit intosugarlabs:mainfrom
TarunWorks:fix/offline-ui-and-label-cleanup
Open

fix: prevent UI freeze in offline robot mode and stop Kokoro label stacking#121
TarunWorks wants to merge 1 commit intosugarlabs:mainfrom
TarunWorks:fix/offline-ui-and-label-cleanup

Conversation

@TarunWorks
Copy link
Copy Markdown
Contributor

Problem 1: UI freezes in offline robot mode

When internet is unavailable, the offline SLM/brain fallback runs on the
main GTK thread. Since SLM inference is computationally heavy (model loading),
this blocks the UI and causes the application to freeze.

Fix:
Moved the offline fallback (SLM → Brain) to a background thread using the
same pattern as the online LLM path (threading.Thread + GLib.idle_add)
to keep the UI responsive.


Problem 2: Kokoro voice status labels stacking

Rapidly clicking different Kokoro voices creates multiple "Please wait..."
labels that stack up and are not properly cleared.

Fix:
Track the active info label and remove any existing label before adding a new one.
The timeout cleanup now verifies label identity before removing it to avoid race conditions.


Testing

Tested on Sugar desktop running on Ubuntu VM:

  • Verified UI remains responsive in offline robot mode
  • Confirmed Kokoro voice label does not stack on rapid clicks

Copilot AI review requested due to automatic review settings April 7, 2026 17:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses two UI responsiveness issues in activity.py: (1) preventing the GTK UI from freezing when falling back to offline SLM/Brain responses, and (2) preventing Kokoro “Please wait…” status labels from stacking during rapid voice selection changes.

Changes:

  • Moves the offline (no-internet) SLM → Brain response generation to a background thread and posts the final face.say() back to the GTK main loop via GLib.idle_add.
  • Tracks the active Kokoro status label (_kokoro_info_label) and removes any previous label before adding a new one.
  • Makes the timed cleanup remove only the currently-active label to reduce race conditions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread activity.py
Comment on lines +952 to +959
# Remove previously shown status label to avoid stacking labels when
# users rapidly click different voices.
existing_label = getattr(self, '_kokoro_info_label', None)
if existing_label is not None:
try:
self._kokoro_voice_box.remove(existing_label)
except Exception:
pass
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid except Exception: pass when removing the prior Kokoro status label. It can silently mask real widget hierarchy/GTK errors and can also leave the old label in the box (so stacking may still occur) without any diagnostic. Prefer checking existing_label.get_parent() is self._kokoro_voice_box (or membership in get_children()) before removing, and only catch the specific GTK/Python exceptions you expect (optionally log at debug level).

Copilot uses AI. Check for mistakes.
Comment thread activity.py
Comment on lines +1014 to +1020
if getattr(self, '_kokoro_info_label', None) is info_label:
try:
self._kokoro_voice_box.remove(info_label)
except Exception:
pass
self._kokoro_info_label = None
return False
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In _remove_info_label, swallowing all exceptions and then setting _kokoro_info_label = None can make failures hard to detect and can leave a label stuck in the UI with no remaining reference to remove it later. Prefer guarding the removal (e.g., verify the label is still parented to _kokoro_voice_box), catching only expected exceptions, and only clearing _kokoro_info_label once the label is confirmed removed/destroyed.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants