fix(desktop): stabilize Windows titlebar zoom (#25813)
This commit is contained in:
@@ -11,7 +11,7 @@ import type {
|
||||
WslConfig,
|
||||
} from "../preload/types"
|
||||
import { getStore } from "./store"
|
||||
import { setTitlebar } from "./windows"
|
||||
import { setTitlebar, updateTitlebar } from "./windows"
|
||||
|
||||
const pickerFilters = (ext?: string[]) => {
|
||||
if (!ext || ext.length === 0) return undefined
|
||||
@@ -183,7 +183,12 @@ export function registerIpcHandlers(deps: Deps) {
|
||||
})
|
||||
|
||||
ipcMain.handle("get-zoom-factor", (event: IpcMainInvokeEvent) => event.sender.getZoomFactor())
|
||||
ipcMain.handle("set-zoom-factor", (event: IpcMainInvokeEvent, factor: number) => event.sender.setZoomFactor(factor))
|
||||
ipcMain.handle("set-zoom-factor", (event: IpcMainInvokeEvent, factor: number) => {
|
||||
event.sender.setZoomFactor(factor)
|
||||
const win = BrowserWindow.fromWebContents(event.sender)
|
||||
if (!win) return
|
||||
updateTitlebar(win)
|
||||
})
|
||||
ipcMain.handle("set-titlebar", (event: IpcMainInvokeEvent, theme: TitlebarTheme) => {
|
||||
const win = BrowserWindow.fromWebContents(event.sender)
|
||||
if (!win) return
|
||||
|
||||
@@ -21,6 +21,8 @@ protocol.registerSchemesAsPrivileged([
|
||||
])
|
||||
|
||||
let backgroundColor: string | undefined
|
||||
const titlebarThemes = new WeakMap<BrowserWindow, Partial<TitlebarTheme>>()
|
||||
const titlebarHeight = 40
|
||||
|
||||
export function setBackgroundColor(color: string) {
|
||||
backgroundColor = color
|
||||
@@ -43,18 +45,23 @@ function tone() {
|
||||
return nativeTheme.shouldUseDarkColors ? "dark" : "light"
|
||||
}
|
||||
|
||||
function overlay(theme: Partial<TitlebarTheme> = {}) {
|
||||
function overlay(theme: Partial<TitlebarTheme> = {}, zoom = 1) {
|
||||
const mode = theme.mode ?? tone()
|
||||
return {
|
||||
color: "#00000000",
|
||||
symbolColor: mode === "dark" ? "white" : "black",
|
||||
height: 40,
|
||||
height: Math.max(titlebarHeight, Math.round(titlebarHeight * zoom)),
|
||||
}
|
||||
}
|
||||
|
||||
export function setTitlebar(win: BrowserWindow, theme: Partial<TitlebarTheme> = {}) {
|
||||
titlebarThemes.set(win, theme)
|
||||
updateTitlebar(win)
|
||||
}
|
||||
|
||||
export function updateTitlebar(win: BrowserWindow) {
|
||||
if (process.platform !== "win32") return
|
||||
win.setTitleBarOverlay(overlay(theme))
|
||||
win.setTitleBarOverlay(overlay(titlebarThemes.get(win), win.webContents.getZoomFactor()))
|
||||
}
|
||||
|
||||
export function setDockIcon() {
|
||||
@@ -188,6 +195,7 @@ function wireZoom(win: BrowserWindow) {
|
||||
win.webContents.setZoomFactor(1)
|
||||
win.webContents.on("zoom-changed", () => {
|
||||
win.webContents.setZoomFactor(1)
|
||||
updateTitlebar(win)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ const OS_NAME = (() => {
|
||||
})()
|
||||
|
||||
const [webviewZoom, setWebviewZoom] = createSignal(1)
|
||||
let requestedZoom = 1
|
||||
|
||||
const MAX_ZOOM_LEVEL = 10
|
||||
const MIN_ZOOM_LEVEL = 0.2
|
||||
@@ -19,8 +20,14 @@ const MIN_ZOOM_LEVEL = 0.2
|
||||
const clamp = (value: number) => Math.min(Math.max(value, MIN_ZOOM_LEVEL), MAX_ZOOM_LEVEL)
|
||||
|
||||
const applyZoom = (next: number) => {
|
||||
setWebviewZoom(next)
|
||||
void window.api.setZoomFactor(next)
|
||||
requestedZoom = next
|
||||
void window.api.setZoomFactor(next).then(() => {
|
||||
if (requestedZoom !== next) return
|
||||
setWebviewZoom(next)
|
||||
}).catch(() => {
|
||||
if (requestedZoom !== next) return
|
||||
requestedZoom = webviewZoom()
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", (event) => {
|
||||
@@ -28,12 +35,12 @@ window.addEventListener("keydown", (event) => {
|
||||
|
||||
if (event.key === "-") {
|
||||
event.preventDefault()
|
||||
applyZoom(clamp(webviewZoom() - 0.2))
|
||||
applyZoom(clamp(requestedZoom - 0.2))
|
||||
return
|
||||
}
|
||||
if (event.key === "=" || event.key === "+") {
|
||||
event.preventDefault()
|
||||
applyZoom(clamp(webviewZoom() + 0.2))
|
||||
applyZoom(clamp(requestedZoom + 0.2))
|
||||
return
|
||||
}
|
||||
if (event.key === "0") {
|
||||
|
||||
Reference in New Issue
Block a user