Skip to content

fix(fullscreen): route keystroke through Chrome process during Zoom share#521

Merged
sonichi merged 1 commit intomainfrom
fix/inline-fullscreen-zoom-share
Apr 26, 2026
Merged

fix(fullscreen): route keystroke through Chrome process during Zoom share#521
sonichi merged 1 commit intomainfrom
fix/inline-fullscreen-zoom-share

Conversation

@sonichi
Copy link
Copy Markdown
Owner

@sonichi sonichi commented Apr 26, 2026

Summary

  • The fullscreen inline tool sends a plain keystroke "f" to System Events. Zoom's floating control bar grabs global keystroke focus during screen-share and intercepts it before Chrome sees it — slide deck's F → requestFullscreen() never fires.
  • Mirror the fix already in skills/personal-iclr-highlight/tools.ts: route through tell process "Google Chrome".
  • Two tools shared this bug. The model preferred fullscreen over fullscreen_presenter, so the patched skill tool never ran.

Test plan

  • TS clean
  • Voice "fullscreen" with Zoom mid-share → slide deck enters fullscreen
  • Voice "fullscreen" without Zoom → still works (regression check)

🤖 Generated with Claude Code

…hare

The `fullscreen` inline tool sent `keystroke "f"` to System Events
without targeting a process. When Zoom is screen-sharing, Zoom's
floating control bar grabs global keystroke focus and intercepts the
keystroke before it reaches Chrome — so the slide deck's F-key binding
to requestFullscreen() never fires.

Mirror the fix already in skills/personal-iclr-highlight/tools.ts:
route through `tell process "Google Chrome"` so the keystroke lands
in Chrome regardless of which app is frontmost in Zoom's view.

Why two tools have the same bug: voice-agent exposes both `fullscreen`
(this file) and `fullscreen_presenter` (personal-iclr skill). The model
picks the shorter name, so the patched skill tool never ran.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonichi sonichi merged commit 9e4b348 into main Apr 26, 2026
1 check passed
@sonichi sonichi deleted the fix/inline-fullscreen-zoom-share branch April 26, 2026 01:56
sonichi added a commit that referenced this pull request Apr 26, 2026
…Chrome (#522)

PR #521 hardcoded `tell process "Google Chrome"`, but this is a generic
tool — its description says "Toggle fullscreen mode on the presentation
slides", not "fullscreen Chrome". When the foreground app isn't Chrome
the bare-Chrome targeting either steals focus to a Chrome window without
the slides or sends the keystroke to a hidden Chrome process.

Detect the frontmost process inside System Events and target it. If the
slide-tab activation block above ran successfully, frontmost is Chrome
(unchanged behavior). Otherwise the keystroke goes to whatever the user
actually has up.

Still survives Zoom screen-share — process-level routing bypasses Zoom's
floating-control-bar focus grab.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sonichi added a commit that referenced this pull request Apr 28, 2026
…cess-explicit

Strip out the URL matching and the QuickTime-vs-slides branching. Both
were over-engineered Chi-specific knowledge masquerading as a generic
tool, and neither survived contact with reality:

- URL matcher only knew localhost:8888 / index-sutando / index-bodhi;
  Chi's slide deck moved to localhost:7877 long ago. Add-localhost-7877
  was the wrong fix shape — every URL move would need another patch.
- QT-doc detection forced QT-fullscreen even when QT was in background
  and the user was looking at something else (regression I caused
  yesterday across PRs #520-#527).
- The Chrome branch sent 'f' to the frontmost process — fine when
  Chrome activate succeeded, broken when Zoom screen-share held focus
  through the activate (PR #522 regression of #521's Chrome-explicit
  routing).

New shape, matching Chi's Sunday-afternoon design intent ("find the app
on top and full screen that"):

1. Read frontmost app.
2. If frontmost is Zoom (screen-share case), pick the next visible
   non-Zoom non-background app — the window the user was actually using.
3. Activate that app.
4. Send keystroke via `tell process <target>` — process-explicit routing
   that bypasses the focus race.
5. Chrome → 'f' (reveal.js slide fullscreen). Everything else →
   Cmd+Ctrl+F (macOS standard window fullscreen — works for QuickTime,
   VSCode, Slack, Mail, anything).

-55 +33 net. Tool description rewritten to describe the new generic shape
so the model doesn't think it's slide-deck-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sonichi added a commit that referenced this pull request Apr 28, 2026
…xplicit (#542)

* fix(fullscreen): add localhost:7877 + iclr-slides to URL matcher

Chi's slide deck is now served at http://localhost:7877/slides (Python
http.server), but the fullscreen tool's matcher only knew about
localhost:8888 / index-sutando / index-bodhi. The matcher missed the
slide tab → Chrome activation block was a no-op for the actual deck →
Cmd+F dropped onto whatever tab was frontmost (could be GitHub, Mail,
etc), instead of triggering reveal.js fullscreen on the deck.

Adds 'localhost:7877' (current Python server) + 'iclr-slides' (covers
file:// path renames and future URL variants) to the OR chain. Same
shape as the existing matchers.

Reproduces the talk-day flow: slide deck open in any tab, "fullscreen"
voice cue → tool finds it via matcher → switches to it → Cmd+F.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(fullscreen): truly generic — find frontmost, skip Zoom, route process-explicit

Strip out the URL matching and the QuickTime-vs-slides branching. Both
were over-engineered Chi-specific knowledge masquerading as a generic
tool, and neither survived contact with reality:

- URL matcher only knew localhost:8888 / index-sutando / index-bodhi;
  Chi's slide deck moved to localhost:7877 long ago. Add-localhost-7877
  was the wrong fix shape — every URL move would need another patch.
- QT-doc detection forced QT-fullscreen even when QT was in background
  and the user was looking at something else (regression I caused
  yesterday across PRs #520-#527).
- The Chrome branch sent 'f' to the frontmost process — fine when
  Chrome activate succeeded, broken when Zoom screen-share held focus
  through the activate (PR #522 regression of #521's Chrome-explicit
  routing).

New shape, matching Chi's Sunday-afternoon design intent ("find the app
on top and full screen that"):

1. Read frontmost app.
2. If frontmost is Zoom (screen-share case), pick the next visible
   non-Zoom non-background app — the window the user was actually using.
3. Activate that app.
4. Send keystroke via `tell process <target>` — process-explicit routing
   that bypasses the focus race.
5. Chrome → 'f' (reveal.js slide fullscreen). Everything else →
   Cmd+Ctrl+F (macOS standard window fullscreen — works for QuickTime,
   VSCode, Slack, Mail, anything).

-55 +33 net. Tool description rewritten to describe the new generic shape
so the model doesn't think it's slide-deck-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(fullscreen): drop Chrome-specific 'f' branch — Cmd+Ctrl+F universal

Chi tested: Cmd+Ctrl+F on Chrome gives the same clean slide-fills-screen
result regardless of "Always Show Toolbar in Fullscreen" Chrome
preference. So the Chrome→'f' branch I just added isn't needed.

Drop it. Single keystroke (Cmd+Ctrl+F) works for every target:
- Chrome (slide deck or any other tab)
- QuickTime
- VSCode / Slack / Mail / arbitrary native windows

Process-explicit routing (`tell process <target>`) still preserved — that's
what survives the Zoom screen-share focus race.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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