Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/desktop-electron/src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ export function createMenu(deps: Deps) {
{ role: "reload" },
{ role: "toggleDevTools" },
{ type: "separator" },
{ role: "resetZoom" },
{ role: "zoomIn" },
{ role: "zoomOut" },
{ label: "Actual Size", accelerator: "Cmd+0", click: () => deps.trigger("zoom.reset") },
{ label: "Zoom In", accelerator: "Cmd+=", click: () => deps.trigger("zoom.in") },
{ label: "Zoom Out", accelerator: "Cmd+-", click: () => deps.trigger("zoom.out") },
{ type: "separator" },
{ role: "togglefullscreen" },
],
Expand Down
6 changes: 3 additions & 3 deletions packages/desktop-electron/src/main/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ function loadWindow(win: BrowserWindow, html: string) {
}
function wireZoom(win: BrowserWindow) {
win.webContents.setZoomFactor(1)
win.webContents.on("zoom-changed", () => {
win.webContents.setZoomFactor(1)
})
// Let renderer-owned zoom handle keyboard/menu changes without Chromium's
// visual zoom path racing it back to 1.
void win.webContents.setVisualZoomLevelLimits(1, 1).catch(() => undefined)
}

function upsertKeyValue(obj: Record<string, any>, keyToChange: string, value: any) {
Expand Down
5 changes: 4 additions & 1 deletion packages/desktop-electron/src/renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { createEffect, createResource, onCleanup, onMount, Show } from "solid-js
import { render } from "solid-js/web"
import pkg from "../../package.json"
import { initI18n, t } from "./i18n"
import { webviewZoom } from "./webview-zoom"
import { webviewZoom, zoomIn, zoomOut, zoomReset } from "./webview-zoom"
import "./styles.css"
import { useTheme } from "@opencode-ai/ui/theme"

Expand Down Expand Up @@ -267,6 +267,9 @@ const createPlatform = (): Platform => {

let menuTrigger = null as null | ((id: string) => void)
window.api.onMenuCommand((id) => {
if (id === "zoom.in") return zoomIn()
if (id === "zoom.out") return zoomOut()
if (id === "zoom.reset") return zoomReset()
menuTrigger?.(id)
})
listenForDeepLinks()
Expand Down
61 changes: 47 additions & 14 deletions packages/desktop-electron/src/renderer/webview-zoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,61 @@ const OS_NAME = (() => {
return "unknown"
})()

const [webviewZoom, setWebviewZoom] = createSignal(1)
const MIN_ZOOM = 0.2
const MAX_ZOOM = 10
const KEY_STEP = 0.2
const WHEEL_STEP = 0.1

const MAX_ZOOM_LEVEL = 10
const MIN_ZOOM_LEVEL = 0.2
const clamp = (value: number) => Math.min(Math.max(value, MIN_ZOOM), MAX_ZOOM)

const clamp = (value: number) => Math.min(Math.max(value, MIN_ZOOM_LEVEL), MAX_ZOOM_LEVEL)
const [webviewZoom, setWebviewZoom] = createSignal(1)

const applyZoom = (next: number) => {
setWebviewZoom(next)
void window.api.setZoomFactor(next)
const apply = (next: number) => {
const clamped = clamp(next)
if (Math.abs(clamped - webviewZoom()) < 1e-6) return
setWebviewZoom(clamped)
void window.api.setZoomFactor(clamped).catch(() => undefined)
}

window.addEventListener("keydown", (event) => {
if (!(OS_NAME === "macos" ? event.metaKey : event.ctrlKey)) return
export const zoomIn = () => apply(webviewZoom() + KEY_STEP)
export const zoomOut = () => apply(webviewZoom() - KEY_STEP)
export const zoomReset = () => apply(1)

let newZoom = webviewZoom()
void window.api
.getZoomFactor()
.then((initial) => {
if (typeof initial === "number" && Number.isFinite(initial)) setWebviewZoom(clamp(initial))
})
.catch(() => undefined)

if (event.key === "-") newZoom -= 0.2
if (event.key === "=" || event.key === "+") newZoom += 0.2
if (event.key === "0") newZoom = 1
window.addEventListener("keydown", (event) => {
const mod = OS_NAME === "macos" ? event.metaKey : event.ctrlKey
if (!mod || event.altKey) return

applyZoom(clamp(newZoom))
if (event.key === "-" || event.key === "_") {
event.preventDefault()
zoomOut()
return
}
if (event.key === "=" || event.key === "+") {
event.preventDefault()
zoomIn()
return
}
if (event.key === "0") {
event.preventDefault()
zoomReset()
}
})

window.addEventListener(
"wheel",
(event) => {
if (!event.ctrlKey && !event.metaKey) return
event.preventDefault()
apply(webviewZoom() + (event.deltaY > 0 ? -WHEEL_STEP : WHEEL_STEP))
},
{ passive: false },
)

export { webviewZoom }
Loading