fix(activator): guard Terminal.app tab enumeration against tab-less windows - #295
Open
kuznetsov-m wants to merge 1 commit into
Open
fix(activator): guard Terminal.app tab enumeration against tab-less windows#295kuznetsov-m wants to merge 1 commit into
kuznetsov-m wants to merge 1 commit into
Conversation
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
Clicking a session that lives in anything but the first Terminal.app window did
nothing at all — no tab switch, no window raise. The Terminal.app activation
script aborts halfway through whenever
windowscontains a window whose tabscan't be read.
Fixes #294.
Root cause
Sources/CodeIsland/TerminalActivator.swift→activateTerminalApp(ttyPath:cwd:).All three matching strategies iterate windows like this:
The
trycovers the comparison but nottabs of w. Terminal.app can keep awindow that has no tabs at all — an invisible utility window (
name "",visible false) that lives for the whole lifetime of the Terminal process.Asking it for
tabsraises-10000, which tears down the entiretell application "Terminal"block. Two consequences:found by any of the three strategies.
activateon line 772 is never reached either — unlike the iTerm2and Ghostty branches, this block has no outer
try, so the failure alsocosts the app-level raise that would otherwise be the visible fallback.
Observed state (macOS 14.1, Terminal.app 2.14):
Running the enumeration exactly as the app does it:
From the user's side this is indistinguishable from the Strategy 1 misfire
fixed in #124: one session jumps, the others silently do nothing.
Fix
Wrap each window's tab enumeration in its own
try, in all three strategies —the same hardening #202 applied to iTerm2's
select <window>.Semantics are unchanged:
exit repeatstill refers to the tab loop, andif found then exit repeatstays outside the guard, so the outer loop stillstops at the first match. Only windows that cannot be read are skipped.
Why not filter on
visible of wThe issue originally suggested skipping invisible windows, and this PR
deliberately doesn't. Minimized windows are tracked by the separate
miniaturizedproperty, and the comment on lines 775–777 documents that on somemacOS 14 builds minimized windows fall out of
windowsentirely — a visibilityfilter would risk regressing the deminiaturize path added for #124. A bare
tryskips exactly the unreadable windows and nothing else.
Test plan
substituted (
/dev/ttys136,projects) and compiled it withosacompile— nesting of
try/repeatis validselected, Terminal raised
AppleEvent handler failedwhile the patched one returnsfound=trueswift buildRelated
tryttylocal variable shadowing)The iTerm2 branches (lines 588, 617, 653) still enumerate tabs unguarded. They
have an outer
try, so a bad window can't break the app — it just silently endsthe search. Happy to fold that into this PR if you'd prefer one sweep.