diff --git a/apps/desktop/src/window/DesktopApplicationMenu.test.ts b/apps/desktop/src/window/DesktopApplicationMenu.test.ts index fa3960a34ee5..a07a24a66c21 100644 --- a/apps/desktop/src/window/DesktopApplicationMenu.test.ts +++ b/apps/desktop/src/window/DesktopApplicationMenu.test.ts @@ -247,13 +247,13 @@ describe("DesktopApplicationMenu", () => { }), ); - it.effect("routes View menu zoom to the main window instead of zoom roles", () => + it.effect("registers macOS command-plus once and routes it through main-window zoom", () => Effect.gen(function* () { const selectedAction = yield* Deferred.make(); const applicationMenuTemplate = yield* Deferred.make(); - yield* configureMenu(selectedAction, applicationMenuTemplate); + yield* configureMenu(selectedAction, applicationMenuTemplate, { platform: "darwin" }); const template = yield* Deferred.await(applicationMenuTemplate); const viewMenu = template.find((item) => item.label === "View"); @@ -268,9 +268,17 @@ describe("DesktopApplicationMenu", () => { ), ); - const zoomIn = viewMenu.submenu.find((item) => item.label === "Zoom In"); + const shiftedEqual = viewMenu.submenu.filter( + (item) => item.accelerator === "CmdOrCtrl+Shift+=", + ); + assert.lengthOf(shiftedEqual, 1); + assert.lengthOf( + viewMenu.submenu.filter((item) => item.accelerator === "CmdOrCtrl+numadd"), + 1, + ); + const zoomIn = shiftedEqual[0]; assert.isDefined(zoomIn); - assert.equal(zoomIn.accelerator, "CmdOrCtrl+="); + assert.isFalse(zoomIn.visible); if (typeof zoomIn.click !== "function") { throw new Error("Expected Zoom In menu item to have a click handler."); } diff --git a/apps/desktop/src/window/DesktopApplicationMenu.ts b/apps/desktop/src/window/DesktopApplicationMenu.ts index c51e13e58673..aeaca8350709 100644 --- a/apps/desktop/src/window/DesktopApplicationMenu.ts +++ b/apps/desktop/src/window/DesktopApplicationMenu.ts @@ -263,6 +263,16 @@ export const make = Effect.gen(function* () { visible: false, click: zoomClick("in"), }, + ...(environment.platform === "darwin" + ? [ + { + label: "Zoom In", + accelerator: "CmdOrCtrl+Shift+=", + visible: false, + click: zoomClick("in"), + }, + ] + : []), { label: "Zoom Out", accelerator: "CmdOrCtrl+-", click: zoomClick("out") }, // The numeric keypad sends its own key codes, so the number-row // accelerators above never match it. diff --git a/apps/desktop/src/window/DesktopWindow.test.ts b/apps/desktop/src/window/DesktopWindow.test.ts index ab59f63e1ad7..56206a227963 100644 --- a/apps/desktop/src/window/DesktopWindow.test.ts +++ b/apps/desktop/src/window/DesktopWindow.test.ts @@ -774,9 +774,10 @@ describe("DesktopWindow", () => { // Chromium hands the main window's zoom level down to embedded preview // guests, so every app zoom has to put the preview browser back at its own // zoom or zooming the UI drags the previewed page with it. - it.effect("restores the preview browser's own zoom after zooming the app", () => + it.effect("zooms main with a focused popup and reapplies preview zoom", () => Effect.gen(function* () { const fakeWindow = makeFakeBrowserWindow(); + const popup = makeFakeBrowserWindow(); const createCount = yield* Ref.make(0); const mainWindow = yield* Ref.make>(Option.none()); const previewZoomReapplies: number[] = []; @@ -785,6 +786,7 @@ describe("DesktopWindow", () => { createCount, mainWindow, previewZoomReapplies, + focusedWindow: popup.window, }); yield* Effect.gen(function* () { @@ -801,6 +803,7 @@ describe("DesktopWindow", () => { [-0.5, -1, -0.5, 0], ); assert.deepEqual(previewZoomReapplies, [-0.5, -1, -0.5, 0]); + assert.equal(popup.setZoomLevel.mock.calls.length, 0); }).pipe(Effect.provide(layer)); }), ); diff --git a/apps/desktop/src/window/DesktopWindow.ts b/apps/desktop/src/window/DesktopWindow.ts index 3926cda14ece..5d14fdfdc53f 100644 --- a/apps/desktop/src/window/DesktopWindow.ts +++ b/apps/desktop/src/window/DesktopWindow.ts @@ -1026,7 +1026,7 @@ export const make = Effect.gen(function* () { }), zoomMain: Effect.fn("desktop.window.zoomMain")(function* (direction) { yield* Effect.annotateCurrentSpan({ direction }); - const window = yield* focusedMainWindow; + const window = yield* electronWindow.main; if (Option.isNone(window) || window.value.isDestroyed()) { return; }