experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 60 lines 3.8 kB view raw view rendered
1# Cmd Palette macOS Space Switching Analysis 2 3## Problem 4 5When the user is on macOS Desktop Space 2 (or any non-primary Space) and opens the cmd palette via Alt+Space, macOS switches them back to the Space where the Peek app was initially started. 6 7## Root Cause 8 9The cmd palette window is created as a `keepLive` window with `modal: true`, `type: 'panel'`, and `alwaysOnTop: true`. When a keepLive window is reused (shown after being hidden), the `show()` + `focus()` calls on the BrowserWindow cause macOS to switch to the Space where the window was originally created. 10 11macOS treats BrowserWindow display Spaces based on the `visibleOnAllWorkspaces` property. Without this property set, a window is bound to the Space where it was first created. When `show()` is called, macOS brings the user to that Space. 12 13## Architecture 14 15### Cmd Panel Window Lifecycle 16 171. **First open**: `openPanelWindow()` in `extensions/cmd/background.js` calls `api.window.open()` with `keepLive: true`, `modal: true`, `type: 'panel'`, `alwaysOnTop: true`. 182. **IPC handler**: `window-open` in `backend/electron/ipc.ts` creates a BrowserWindow with `type: 'panel'` (macOS) and `alwaysOnTop` set. 193. **Subsequent opens**: When the global shortcut is triggered again, the keepLive window is found by key and reused via `existingWindow.window.show()` + `.focus()` (ipc.ts lines ~2187-2195). 204. **Dismiss**: ESC or blur hides the window via `closeOrHideWindow()` which calls `win.hide()` for keepLive windows. 21 22### Key Files 23 24- `/Users/dietrich/misc/mpeek/extensions/cmd/background.js` - `openPanelWindow()` defines the window params 25- `/Users/dietrich/misc/mpeek/extensions/cmd/config.js` - Global shortcut default (Option+Space) 26- `/Users/dietrich/misc/mpeek/backend/electron/ipc.ts` - `window-open` IPC handler creates/reuses windows 27- `/Users/dietrich/misc/mpeek/backend/electron/shortcuts.ts` - Global shortcut registration (no app.focus()) 28- `/Users/dietrich/misc/mpeek/backend/electron/windows.ts` - `closeOrHideWindow()` handles keepLive hide 29 30### What Was NOT the Cause 31 32- No `app.focus()` or `app.show()` calls in the shortcut path 33- The `type: 'panel'` is already correct (panel-type windows don't activate the app's main window) 34- The shortcut handler simply calls `openPanelWindow()` which calls `api.window.open()` 35 36## Fix Applied 37 38Two changes in `/Users/dietrich/misc/mpeek/backend/electron/ipc.ts`: 39 40### 1. New modal window creation 41 42After creating a new BrowserWindow for a modal window, call `setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true })`. This ensures the window is not bound to a specific Space. 43 44### 2. keepLive window reuse 45 46Before calling `show()` + `focus()` on a reused keepLive window, reinforce `setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true })`. This handles the case where the property might have been lost or needs reinforcement. 47 48### Why `setVisibleOnAllWorkspaces()` and not constructor option 49 50The `visibleOnAllWorkspaces` property is not available in Electron's `BrowserWindowConstructorOptions` TypeScript type -- it's only available as an instance property and via the `setVisibleOnAllWorkspaces()` method. The method also accepts a `visibleOnFullScreen` option which ensures correct behavior in fullscreen Spaces. 51 52## Scope of Impact 53 54The fix applies to all windows opened with `modal: true`, which includes: 55- Cmd palette (the primary use case) 56- Any other modal/palette windows that might be opened via the same code path 57 58The HUD window is NOT affected because it uses `focusable: false` and has separate hide/show logic via `did-resign-active`/`did-become-active`. 59 60Regular content windows (web pages) are NOT affected -- they remain bound to their creation Space, which is the expected macOS behavior.