fix: cycle panel window-switching bugs (full-screen, junk windows, custom modifiers)#37
Open
pa wants to merge 7 commits into
Open
fix: cycle panel window-switching bugs (full-screen, junk windows, custom modifiers)#37pa wants to merge 7 commits into
pa wants to merge 7 commits into
Conversation
The flags monitor hardcoded Control to detect "released", so any user who remapped the activate modifier (e.g. to Option) either could not commit a selection or had the panel dismiss immediately. Capture the configured activate modifiers when the panel opens and commit when they are released. Logic extracted to a pure, unit-tested predicate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Window.id fell back to 0 for every window whose CGWindowID could not be resolved, violating Identifiable uniqueness; use a per-instance fallback. - handleActivate compared apps by display title to decide the starting window index; compare by bundle id instead via a new Application.isSameApplication(as:) helper, which also de-duplicates the identical logic in CyclePanelController.isShowingSwitcher. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Without Accessibility permission, window enumeration always returns empty and the panel showed a misleading "Focus app". Detect the missing permission and show an "Enable Accessibility Access…" item that opens the relevant System Settings pane. Decision logic extracted to a unit-tested CyclePanelState.fallbackAction(isRunning:isAccessibilityTrusted:). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ad-hoc signed debug builds cannot validate a downloaded update, so the automatic launch check always failed with an "improperly signed" error. Skip the auto-check in DEBUG; the manual "Check for updates…" item and all release behavior are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Native full-screen apps report an empty kAXWindowsAttribute (the full-screen window lives on its own Space), so the panel showed only "Focus app". Fall back to the app's focused/main window, which AX still exposes for full-screen windows, when the windows array is empty. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Chromium-based apps expose hidden helper windows (empty title + AXUnknown subrole) via kAXWindowsAttribute, which showed up as blank rows in the switcher. Keep a window only if it is a standard window or has a non-empty title. Predicate is unit-tested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
Author
I've used a ton of window managers like Yabai, AeroSpace, Rectangle, Raycast, and Tuna, but yours is definitely unique. I really love the idea of keeping window switching so simple and clean. Sure I'll wait no problem. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A set of fixes to the cycle-panel window switcher, found while testing across full-screen apps, Chromium-based browsers, and customized modifier keys. No new features — bug fixes only.
Fixes
Full-screen apps showed only "Focus app." Native full-screen apps report an empty
kAXWindowsAttribute(the full-screen window lives on its own Space).getWindows()now falls back to the app's focused/main window — which Accessibility still exposes — so the window appears instead of the no-window action. (Reef/Models/Application.swift)Chromium browsers listed blank rows. Chromium exposes hidden helper windows (empty title +
AXUnknownsubrole). Windows are now filtered to standard-or-titled, dropping the junk. (Reef/Models/Application.swift,isRelevantWindow(subrole:title:))Custom activate-modifier broke the panel. The flags monitor hardcoded Control to detect "released," so remapping the activate modifier (e.g. to Option) either prevented committing a selection or dismissed the panel immediately. It now commits when the user's configured activate modifiers are released. (
Reef/UI/CyclePanel/CyclePanelController.swift)Misleading "Focus app" when Accessibility is denied. Without permission, window enumeration always returns empty. The panel now shows an "Enable Accessibility Access…" item that opens the relevant System Settings pane. (
Reef/Models/CyclePanelState.swift,Reef/UI/CyclePanel/CyclePanelController.swift)Non-unique
Window.id.idfell back to0for every window whoseCGWindowIDcouldn't be resolved, violatingIdentifiableuniqueness; now uses a per-instance fallback. (Reef/Models/Window.swift)Fragile app-identity check.
handleActivatecompared apps by display title to choose the starting window index; it now compares by bundle id via a newApplication.isSameApplication(as:), which also de-duplicates the identical logic inCyclePanelController.isShowingSwitcher. (Reef/Models/Application.swift,Reef/UI/KeyboardShortcuts/ShortcutController.swift)Dev experience: skip the automatic Sparkle update check in DEBUG builds (ad-hoc-signed debug builds can't validate updates and hit an "improperly signed" error). Release behavior unchanged. (
Reef/Updates/SparkleConnector.swift)Known limitation (documented in code)
kAXWindowsAttributeis Space-scoped: when the current Space is a full-screen app's Space, querying another app returns zero windows, so only that app's focused window can be shown — not its full list. Enumerating windows across Spaces would need continuous background AX observation or private Spaces APIs. Noted inApplication.getWindows().Tests
New unit tests (13): activate-modifier commit predicate, the no-windows fallback action (permission-aware), and the junk-window filter. All passing via
xcodebuild test.🤖 Generated with Claude Code