Skip to content

Commit c02dd06

Browse files
authored
fix(desktop): keep mac titlebar stable under zoom (anomalyco#11747)
1 parent 141fdef commit c02dd06

4 files changed

Lines changed: 33 additions & 18 deletions

File tree

packages/app/src/components/titlebar.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export function Titlebar() {
2424
const mac = createMemo(() => platform.platform === "desktop" && platform.os === "macos")
2525
const windows = createMemo(() => platform.platform === "desktop" && platform.os === "windows")
2626
const web = createMemo(() => platform.platform === "web")
27+
const zoom = () => platform.webviewZoom?.() ?? 1
28+
const minHeight = () => (mac() ? `${40 / zoom()}px` : undefined)
2729

2830
const [history, setHistory] = createStore({
2931
stack: [] as string[],
@@ -134,6 +136,7 @@ export function Titlebar() {
134136
return (
135137
<header
136138
class="h-10 shrink-0 bg-background-base relative grid grid-cols-[auto_minmax(0,1fr)_auto] items-center"
139+
style={{ "min-height": minHeight() }}
137140
data-tauri-drag-region
138141
>
139142
<div
@@ -145,7 +148,7 @@ export function Titlebar() {
145148
data-tauri-drag-region
146149
>
147150
<Show when={mac()}>
148-
<div class="w-[72px] h-full shrink-0" data-tauri-drag-region />
151+
<div class="h-full shrink-0" style={{ width: `${72 / zoom()}px` }} data-tauri-drag-region />
149152
<div class="xl:hidden w-10 shrink-0 flex items-center justify-center">
150153
<IconButton
151154
icon="menu"

packages/app/src/context/platform.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createSimpleContext } from "@opencode-ai/ui/context"
22
import { AsyncStorage, SyncStorage } from "@solid-primitives/storage"
3+
import type { Accessor } from "solid-js"
34

45
export type Platform = {
56
/** Platform discriminator */
@@ -55,6 +56,9 @@ export type Platform = {
5556

5657
/** Parse markdown to HTML using native parser (desktop only, returns unprocessed code blocks) */
5758
parseMarkdown?(markdown: string): Promise<string>
59+
60+
/** Webview zoom level (desktop only) */
61+
webviewZoom?: Accessor<number>
5862
}
5963

6064
export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({

packages/desktop/src/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// @refresh reload
2-
import "./webview-zoom"
2+
import { webviewZoom } from "./webview-zoom"
33
import { render } from "solid-js/web"
44
import { AppBaseProviders, AppInterface, PlatformProvider, Platform } from "@opencode-ai/app"
55
import { open, save } from "@tauri-apps/plugin-dialog"
@@ -346,6 +346,8 @@ const createPlatform = (password: Accessor<string | null>): Platform => ({
346346
parseMarkdown: async (markdown: string) => {
347347
return invoke<string>("parse_markdown_command", { markdown })
348348
},
349+
350+
webviewZoom,
349351
})
350352

351353
createMenu()

packages/desktop/src/webview-zoom.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,34 @@
44

55
import { invoke } from "@tauri-apps/api/core"
66
import { type as ostype } from "@tauri-apps/plugin-os"
7+
import { createSignal } from "solid-js"
78

89
const OS_NAME = ostype()
910

10-
let zoomLevel = 1
11+
const [webviewZoom, setWebviewZoom] = createSignal(1)
1112

1213
const MAX_ZOOM_LEVEL = 10
1314
const MIN_ZOOM_LEVEL = 0.2
1415

16+
const clamp = (value: number) => Math.min(Math.max(value, MIN_ZOOM_LEVEL), MAX_ZOOM_LEVEL)
17+
18+
const applyZoom = (next: number) => {
19+
setWebviewZoom(next)
20+
invoke("plugin:webview|set_webview_zoom", {
21+
value: next,
22+
})
23+
}
24+
1525
window.addEventListener("keydown", (event) => {
16-
if (OS_NAME === "macos" ? event.metaKey : event.ctrlKey) {
17-
if (event.key === "-") {
18-
zoomLevel -= 0.2
19-
} else if (event.key === "=" || event.key === "+") {
20-
zoomLevel += 0.2
21-
} else if (event.key === "0") {
22-
zoomLevel = 1
23-
} else {
24-
return
25-
}
26-
zoomLevel = Math.min(Math.max(zoomLevel, MIN_ZOOM_LEVEL), MAX_ZOOM_LEVEL)
27-
invoke("plugin:webview|set_webview_zoom", {
28-
value: zoomLevel,
29-
})
30-
}
26+
if (!(OS_NAME === "macos" ? event.metaKey : event.ctrlKey)) return
27+
28+
let newZoom = webviewZoom()
29+
30+
if (event.key === "-") newZoom -= 0.2
31+
if (event.key === "=" || event.key === "+") newZoom += 0.2
32+
if (event.key === "0") newZoom = 1
33+
34+
applyZoom(clamp(newZoom))
3135
})
36+
37+
export { webviewZoom }

0 commit comments

Comments
 (0)