Skip to content

feat(desktop): multi-window support#20521

Open
Aarogaming wants to merge 6 commits intoanomalyco:devfrom
Aarogaming:feat/multi-window
Open

feat(desktop): multi-window support#20521
Aarogaming wants to merge 6 commits intoanomalyco:devfrom
Aarogaming:feat/multi-window

Conversation

@Aarogaming
Copy link
Copy Markdown

@Aarogaming Aarogaming commented Apr 1, 2026

Issue for this PR

Closes #20606

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds a multi-window feature using the Tauri/Electron APIs and SolidJS frontend, allowing users to spawn independent session windows via Cmd+Shift+N or the command palette.

How did you verify your code works?

Verified locally by spawning new windows in the desktop app, ensuring no crashes or overlapping states between multiple instances. E2E tests have also been updated and pass cleanly.

Screenshots / recordings

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Copilot AI review requested due to automatic review settings April 1, 2026 17:59
@Aarogaming Aarogaming requested a review from adamdotdevin as a code owner April 1, 2026 17:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds desktop multi-window support end-to-end (Tauri + Electron backends, shared SolidJS command palette/keybind entry) so users can spawn additional independent app windows.

Changes:

  • Introduces a new Platform.spawnWindow() capability and wires it up in both Tauri and Electron desktop platforms.
  • Adds a new command-palette entry + keybind (mod+shift+n) for “New Window”.
  • Updates an e2e keybind test to avoid the new global shortcut.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/desktop/src/index.tsx Exposes spawnWindow() via the Tauri desktop platform implementation.
packages/desktop/src/bindings.ts Adds a Tauri invoke binding for spawn_window.
packages/desktop/src-tauri/src/windows.rs Generalizes MainWindow::create to accept a custom window label.
packages/desktop/src-tauri/src/lib.rs Adds the spawn_window Tauri command and registers it; updates main window creation callsite.
packages/desktop-electron/src/renderer/index.tsx Exposes spawnWindow() via the Electron renderer platform implementation.
packages/desktop-electron/src/preload/types.ts Extends the preload API typing with spawnWindow().
packages/desktop-electron/src/preload/index.ts Exposes spawnWindow() over IPC from renderer to main.
packages/desktop-electron/src/main/ipc.ts Registers a spawn-window IPC handler.
packages/desktop-electron/src/main/index.ts Implements spawnWindow() by creating a new main BrowserWindow.
packages/app/src/pages/layout.tsx Adds a “New Window” command palette entry and keybind.
packages/app/src/i18n/en.ts Adds a new command category label (Window).
packages/app/src/context/platform.tsx Extends the Platform type with optional spawnWindow().
packages/app/e2e/settings/settings-keybinds.spec.ts Adjusts the key used in a keybind-editing test to avoid the new shortcut.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

id: "window.new",
title: language.t("command.window.new"),
category: language.t("command.category.window"),
keybind: "mod+shift+n",
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

window.new is always registered (and has a global mod+shift+n keybind) even when platform.spawnWindow is undefined. On non-desktop targets this becomes a no-op command that can still steal a common browser shortcut. Consider only adding this command when platform.spawnWindow exists, or marking it disabled: true (and/or omitting keybind) when unsupported so it doesn't intercept keys or appear actionable.

Suggested change
keybind: "mod+shift+n",
keybind: platform.spawnWindow ? "mod+shift+n" : undefined,
disabled: !platform.spawnWindow,

Copilot uses AI. Check for mistakes.
"command.category.workspace": "Workspace",
"command.category.settings": "Settings",
"command.category.window": "Window",

Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UI now references language.t("command.window.new"), but this key is not present in the English dictionary. Add an English entry for command.window.new (and ideally update other locales or provide a fallback strategy) to avoid showing the raw key in the command palette.

Suggested change
"command.window.new": "New window",

Copilot uses AI. Check for mistakes.
Comment on lines +166 to +171
#[tauri::command]
#[specta::specta]
fn spawn_window(app: AppHandle) -> Result<(), String> {
let label = uuid::Uuid::new_v4().to_string();
MainWindow::create(&app, &label).map(|_| ()).map_err(|e| e.to_string())
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spawn_window generates a fresh UUID label for every window. Because the app persists window state per label (via tauri_plugin_window_state), this can lead to unbounded growth of stored window-state entries over time. Consider using a bounded/reusable label scheme (e.g., main-1, main-2, reusing the lowest free index) so closed windows don't leave permanently accumulating state records.

Copilot uses AI. Check for mistakes.
Comment on lines +245 to +248
createMainWindow({
updaterEnabled: UPDATER_ENABLED,
deepLinks: [],
})
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spawnWindow calls createMainWindow() without any per-window state/position differentiation. createMainWindow() uses electron-window-state with default settings, so multiple windows will typically restore the same x/y/width/height and open directly on top of each other. Consider passing a unique windowName/state key for additional windows or applying a small position offset when spawning to ensure the new window is visible.

Suggested change
createMainWindow({
updaterEnabled: UPDATER_ENABLED,
deepLinks: [],
})
const existingWindow =
BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0]
const newWindow = (createMainWindow as any)({
updaterEnabled: UPDATER_ENABLED,
deepLinks: [],
})
if (
existingWindow &&
newWindow &&
typeof newWindow.setPosition === "function"
) {
const [x, y] = existingWindow.getPosition()
newWindow.setPosition(x + 24, y + 24)
}

Copilot uses AI. Check for mistakes.
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.

Feature Request: Multi-window support

2 participants