Skip to content

Open files on the desktop you're actually on; give the title bar room to breathe - #35

Open
productengineered wants to merge 3 commits into
seamoss:mainfrom
productengineered:fix/open-on-active-desktop
Open

Open files on the desktop you're actually on; give the title bar room to breathe#35
productengineered wants to merge 3 commits into
seamoss:mainfrom
productengineered:fix/open-on-active-desktop

Conversation

@productengineered

Copy link
Copy Markdown
Contributor

Two fixes on top of the tabs work from #34.

Files open on the desktop you're actually on

Opening a file from Finder (or open from a terminal) handed it to whichever window last held focus. When that window lived on another macOS Space, focusing it dragged the screen to that desktop — the file arrived, but you left with it.

Only the OS can deliver open-file or a second-instance argv, so the app was necessarily in the background when they arrive and its windows may be on any desktop. Those opens now land as tabs in a window on the desktop you're looking at, and make a new window only when there isn't one.

Knowing which desktop a window is on is the hard part — Electron exposes nothing for it. The window's own renderer does know: macOS marks windows on inactive Spaces as occluded, and Chromium reports that as document.visibilityState === 'hidden'. Measured in both directions on a two-desktop machine:

  • leaving the Space flips it to hidden; returning flips it back
  • but burying the window behind another app flips it too

So visible proves presence and hidden proves nothing, and only the affirmative is trusted. macOS activates the app and raises its windows above other apps' before delivering the open, so a same-desktop window has surfaced by the time it is asked. A misread costs one extra window, never a desktop switch. (isVisible() is no help here — it stayed true throughout.)

Details:

  • Finder sends one open-file per selected file, so the batch is gathered before anything is decided — 120ms, which doubles as the time for occlusion to settle after activation — and lands together rather than one window at a time.
  • A path already open keeps its existing tab: two windows over one file would mean two buffers and two watchers. Only when every requested path is already open does its window get focused, since then there is nothing else to show.
  • In-app opens (⌘O, the palette) and launch arguments are unchanged.
  • A wedged renderer cannot hang an open: no answer within 250ms counts as hidden.

Title bar room to breathe

The bar was sized to the traffic lights, but macOS parks hiddenInset buttons low within it: at 32px the tabs and the document title sat hard against the content below, with about five pixels under the buttons. The bar is deeper now, and the tab strip starts clear of the buttons rather than beside them.

Both are values in tokens.css, so the drag region, the editor's top padding, the preview pane, and the outline and palette offsets all follow from one place. The traffic lights are native and stay where AppKit puts them, gaining the new room rather than needing to be repositioned.

Verification

pnpm test (202 passing) and pnpm typecheck both clean. Checked by hand on a two-desktop macOS setup: a file opened from another desktop lands on the active one instead of switching desktops, and repeated opens reuse the window already there rather than stacking up new ones.

Happy to split this into two PRs if you'd rather review them separately.

A Finder double-click or `open` used to route the file to whichever
window last held focus. Focusing a window that lives on another macOS
Space drags the screen to that desktop — the file arrived, but the
user's view left with it.

Nothing but the OS can deliver open-file or a second-instance argv, so
the app was in the background when they arrived and its windows may be
anywhere. Those opens now make a new window, which macOS places on the
active desktop; windows elsewhere stay put.

A path already open keeps its tab — two windows over one file would
mean two buffers and two watchers. Only when every requested path is
already open does its window get focused, since then there is nothing
else to show. Finder's one-event-per-file burst is gathered for 50ms so
a multi-select lands as tabs of a single window.

Launch-time argument files and in-app opens (⌘O, palette) are
unchanged.
0.12.0 stopped dragging the user's screen to another Space, but paid for
it with a window per opened file: with no way to ask Electron which
desktop a window is on, a new window was the only safe answer.

There is a way to ask, just not of Electron. macOS marks windows on
inactive Spaces as occluded and Chromium reports that as
document.visibilityState === 'hidden', so the window's own renderer
knows. Measured both directions: leaving the Space flips it to hidden
and returning flips it back, but so does burying the window behind
another app — 'visible' proves presence, 'hidden' proves nothing. Only
the affirmative is trusted, and macOS raises the app's windows before
delivering the open, so a same-desktop window has surfaced by the time
it is asked.

Files now land as tabs in a window on the active desktop, falling back
to a new window when none is there. A misread costs one extra window,
never a desktop switch.
The bar was sized to the traffic lights, but macOS parks hiddenInset
buttons low within it: at 32px the tabs and the title sat hard against
the content below, with about five pixels under the buttons. Deeper bar,
and the tab strip starts clear of the buttons rather than beside them.

Both are token values, so the drag region, the editor's top padding, the
preview pane, and the outline and palette offsets all follow from one
place. The traffic lights are native and stay where AppKit puts them,
gaining the new room below rather than needing to be repositioned.
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