Skip to content

Route terminal scroll to focused pane#143

Open
jkp wants to merge 4 commits intomuxy-app:mainfrom
jkp:codex/fix-terminal-scroll-focus
Open

Route terminal scroll to focused pane#143
jkp wants to merge 4 commits intomuxy-app:mainfrom
jkp:codex/fix-terminal-scroll-focus

Conversation

@jkp
Copy link
Copy Markdown
Contributor

@jkp jkp commented Apr 15, 2026

Summary

Fixes synthetic/window-level terminal scroll events landing on the wrong split pane.

  • Tracks the currently focused terminal pane in TerminalViewRegistry
  • Updates the focused-pane record when SwiftUI marks a terminal pane as focused
  • Forwards scroll events that land on an unfocused terminal view to the focused terminal view
  • Keeps normal mouse scroll behavior unchanged for the focused pane

Motivation

Keyboard-first utilities such as Home Row can issue scroll input through the app/window accessibility target rather than the exact terminal split. In that case macOS may deliver the scroll to the first terminal view even when another split is selected in Muxy. Routing unfocused terminal scroll events through Muxy's focused-pane state preserves the user's selected split without requiring external tools to understand Muxy's split hierarchy.

Validation

  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer scripts/checks.sh --fix
  • Manual test with Home Row: selecting the second split and scrolling through Home Row scrolls the selected split instead of the first split

@jkp jkp marked this pull request as ready for review April 15, 2026 16:36
@saeedvaziry
Copy link
Copy Markdown
Member

@jkp how can I reproduce this issue? wondering to it see on different mac versions

@jkp
Copy link
Copy Markdown
Contributor Author

jkp commented Apr 15, 2026

@saeedvaziry i use a tool call homerow (you might like it!)... download it and set up the scrolling shortcut. then split the panes and get some long content in pane a and b. before this patch if you scroll with the shortcut no matter which pane was selected the first pane scrolls.

there are likely simpler ways to do this but thats the symptom i found. i tried a few approaches to fix before landing on this.

@saeedvaziry
Copy link
Copy Markdown
Member

The reason I am asking, the issue might be broader than just scroll. might be about generally shortcuts being ignored on the active tab

@saeedvaziry
Copy link
Copy Markdown
Member

I just checked the app. not gonna install it probably but to me seems like it relies on accessibilities to work.

So maybe Muxy has some accessibility issues which if we solve, this issue will also get resolved

@jkp
Copy link
Copy Markdown
Contributor Author

jkp commented Apr 15, 2026

@saeedvaziry it wasnt ehough in my testing but ofc if you can make that work great. i think the issue here is that the splits are effectively opaque from an accessibility perspective... i did try a bunch of stuff...lemme get a summary of what we did.

@jkp
Copy link
Copy Markdown
Contributor Author

jkp commented Apr 15, 2026

Here’s the history of what we tried and what we learned.

Goal
Home Row only exposed one scroll target for the Muxy window. When using Home Row to scroll while the second split was selected, macOS/Home Row delivered
the scroll to the first terminal split, so the first split scrolled instead of the focused split.

What We Tried

  1. Make the terminal NSView more accessibility-aware

    • Added accessibility element metadata directly to GhosttyTerminalNSView.
    • Tried exposing role, label, value, frame, focused state, and focused-element notifications.
    • Also tried changing the role from text-like to AXScrollArea.

    Result: Home Row still showed only one target. It did not discover separate terminal split views.

  2. Add SwiftUI accessibility metadata to TerminalPane

    • Added .accessibilityElement, label, identifier, value, and accessibility action on the SwiftUI terminal pane wrapper.

    Result: Home Row still showed only one target.

  3. Add a transparent AppKit accessibility overlay per terminal pane

    • Added a real NSViewRepresentable overlay per terminal split.
    • Made each overlay a concrete NSView with AXScrollArea role, label, identifier, frame, and increment/decrement accessibility actions.
    • Forced the overlay to fill the terminal pane to avoid zero-sized AX frames.

    Result: Home Row still showed only one target. That suggested Home Row was not traversing these child elements, or it filters for a more specific
    structure than custom accessible children.

  4. Launch/test sanity checks

    • Confirmed we were testing the local debug build, not the installed app.
    • Verified the accessibility-overlay approach still did not change Home Row’s visible target list.
  5. Route scroll events by Muxy’s actual focused pane

    • Removed the experimental accessibility overlay/metadata changes.
    • Kept a narrow fix:
      • TerminalViewRegistry tracks the currently focused terminal pane.
      • TerminalPane updates that focused-pane record when SwiftUI marks a terminal as focused.
      • If GhosttyTerminalNSView.scrollWheel receives a scroll while that view is not focused, it forwards the scroll delta to the focused terminal view.

    Result: This fixed the behavior in practice. Home Row still showed one target, but scrolling went to the Muxy-selected/focused split.

Conclusion
We did try to make individual terminal panes visible as accessibility targets in three different ways: directly on the terminal NSView, through SwiftUI
accessibility modifiers, and with a dedicated AppKit accessibility overlay per split. None changed Home Row’s target list.

The working fix does not solve Home Row’s target discovery. It solves the practical routing bug: when an external tool delivers scroll input to the wrong
terminal view, Muxy redirects that scroll to the pane Muxy already considers focused.

So the patch is not a broad accessibility fix. It is a defensive scroll-routing fix for synthetic/window-level scroll events. It preserves normal behavior
for direct mouse scrolling on the focused pane and handles the observed case where assistive tooling sends scroll to the first/incorrect terminal view.

@saeedvaziry
Copy link
Copy Markdown
Member

Hey @jkp ,
It feels like I am talking to your AI agent at this moment.
Can we keep the PRs and issues for us humans? :)
This includes PR summaries, comments, issues, ...
You can let the work to be done by AI of course.
Thanks

@jkp
Copy link
Copy Markdown
Contributor Author

jkp commented Apr 18, 2026

Sorry, I hear you, I've got about 10 things on the go, so I tend to have PRs written by my agent if he can do a better job of explaining than me - there was just a lot to include in that description.

@saeedvaziry
Copy link
Copy Markdown
Member

I reviewed this with different models multiple times and each time something critical shows up that i cannot confirm or fix because I don't hone homerow.

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