Skip to content

feat: improve focus restoration when restoring window from tray#1060

Open
AAClause wants to merge 1 commit intomasterfrom
focusFromTray
Open

feat: improve focus restoration when restoring window from tray#1060
AAClause wants to merge 1 commit intomasterfrom
focusFromTray

Conversation

@AAClause
Copy link
Member

@AAClause AAClause commented Feb 26, 2026

  • Save focused control (weakref) on minimize; restore it on show
  • Defer focus restore by 80ms so window is visible first
  • Fall back to prompt, panel, or frame if saved control is invalid
  • Add _restore_focus() used by on_restore and post_screen_capture
  • IPC handler calls _restore_focus when window is already visible

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced window focus restoration when bringing the main window to the foreground and after returning from minimization
    • Focus now intelligently reverts to the previously active control with intelligent fallback mechanisms for improved UI interaction

- Save focused control (weakref) on minimize; restore it on show
- Defer focus restore by 80ms so window is visible first
- Fall back to prompt, panel, or frame if saved control is invalid
- Add _restore_focus() used by on_restore and post_screen_capture
- IPC handler calls _restore_focus when window is already visible
@AAClause AAClause requested a review from clementb49 February 26, 2026 16:20
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Walkthrough

Introduces a new focus restoration mechanism in the main frame that remembers the last focused control before window minimization. On restore, it attempts to refocus that control with fallbacks to current tab panels or the main frame. Updates the app to use this new restoration path instead of direct focus forcing.

Changes

Cohort / File(s) Summary
Focus Restoration Mechanism
basilisk/gui/main_frame.py, basilisk/main_app.py
Implements new focus restoration system with _restore_focus method that stores weak reference to last focused control on minimize and restores it on window restore with fallback to default panels. Updates app to use new restoration path instead of direct focus forcing in conversation file handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding focus restoration functionality when a window is restored from the system tray.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch focusFromTray

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@basilisk/gui/main_frame.py`:
- Around line 429-431: The saved weak reference _last_focused_before_minimize is
not cleared after a successful restore, allowing stale controls to be refocused
later; update the minimize/restore logic (where _last_focused_before_minimize is
set and where _restore_focus() runs) so that after you successfully set focus to
the referenced window you immediately clear/consume the weakref (set
_last_focused_before_minimize to None or similar) to prevent subsequent calls
from using a stale reference; ensure both the code that assigns the weakref (the
block using wx.Window.FindFocus()) and the block in _restore_focus() that
actually refocuses the control are updated to clear the ref after success.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 283b4f1 and b325bac.

📒 Files selected for processing (2)
  • basilisk/gui/main_frame.py
  • basilisk/main_app.py

Comment on lines +429 to +431
focused = wx.Window.FindFocus()
if focused and focused.GetTopLevelParent() == self:
self._last_focused_before_minimize = weakref.ref(focused)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Consume _last_focused_before_minimize after restore to avoid stale refocus.

The saved weak reference is kept when restore succeeds, so later _restore_focus() calls can incorrectly force focus back to an old control from a previous minimize cycle.

🔧 Proposed fix
 def on_minimize(self, event: wx.Event | None):
 	"""Minimize the main application frame to the system tray.
@@
-	focused = wx.Window.FindFocus()
-	if focused and focused.GetTopLevelParent() == self:
-		self._last_focused_before_minimize = weakref.ref(focused)
+	focused = wx.Window.FindFocus()
+	self._last_focused_before_minimize = None
+	if focused and focused.GetTopLevelParent() == self:
+		self._last_focused_before_minimize = weakref.ref(focused)
@@
 def _restore_focus(self):
 	"""Restore focus to the last focused control or a meaningful fallback."""
-	if self._last_focused_before_minimize:
+	focus_ref = self._last_focused_before_minimize
+	self._last_focused_before_minimize = None
+	if focus_ref:
 		try:
-			ctrl = self._last_focused_before_minimize()
+			ctrl = focus_ref()
 			if (
 				ctrl is not None
 				and ctrl.IsShown()
 				and ctrl.GetTopLevelParent() == self
 			):
 				ctrl.SetFocus()
 				return
 		except (AttributeError, RuntimeError) as e:
 			log.error("Failed to restore focus to last control: %s", e)
-		self._last_focused_before_minimize = None

Also applies to: 451-463

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@basilisk/gui/main_frame.py` around lines 429 - 431, The saved weak reference
_last_focused_before_minimize is not cleared after a successful restore,
allowing stale controls to be refocused later; update the minimize/restore logic
(where _last_focused_before_minimize is set and where _restore_focus() runs) so
that after you successfully set focus to the referenced window you immediately
clear/consume the weakref (set _last_focused_before_minimize to None or similar)
to prevent subsequent calls from using a stale reference; ensure both the code
that assigns the weakref (the block using wx.Window.FindFocus()) and the block
in _restore_focus() that actually refocuses the control are updated to clear the
ref after success.

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.

1 participant