From ae49d8716659c0d574a52227c830ac3596d42799 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Mon, 25 May 2026 00:23:44 +0800 Subject: [PATCH] fix: sync gutter element heights during editor font size zoom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS variable changes alone don't trigger CodeMirror's measure cycle, so gutter element heights would diverge from content line heights. The fix reconfigures the font theme compartment (throttled to once per rAF) to force a proper state transition → measure → syncGutters path. Also adds missing fontFamily on .cm-gutters and i18n for "Follow app theme". --- .../editor/EditorSettingsDialog.vue | 2 +- .../src/components/editor/QueryEditor.vue | 36 ++++++++++++++++++- apps/desktop/src/i18n/locales/en.ts | 1 + apps/desktop/src/i18n/locales/zh-CN.ts | 1 + apps/desktop/src/lib/editorThemes.ts | 1 + 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index bd0d970e34..3b79ffc05f 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -733,7 +733,7 @@ watch( : 'bg-muted-foreground/30 border-muted-foreground/40' " /> - {{ theme.label }} + {{ theme.value === "app" ? t("settings.followAppTheme") : theme.label }} diff --git a/apps/desktop/src/components/editor/QueryEditor.vue b/apps/desktop/src/components/editor/QueryEditor.vue index d8cd840567..358d216222 100644 --- a/apps/desktop/src/components/editor/QueryEditor.vue +++ b/apps/desktop/src/components/editor/QueryEditor.vue @@ -187,6 +187,37 @@ function syncEditorFontCssVars(fontSize = liveFontSize.value, fontFamily = setti if (!editorRef.value) return; editorRef.value.style.setProperty(EDITOR_FONT_SIZE_CSS_VAR, `${clampEditorFontSize(fontSize)}px`); editorRef.value.style.setProperty(EDITOR_FONT_FAMILY_CSS_VAR, fontFamily); + const cm = editorRef.value.querySelector(".cm-editor") as HTMLElement | null; + if (cm) cm.style.lineHeight = "1.6"; +} + +let pendingFontReconfig: { size: number; family: string } | null = null; +let fontReconfigScheduled = false; + +function reconfigureFontTheme(size: number, family: string) { + if (!fontThemeComp || !editorViewModule || !view.value) return; + view.value.dispatch({ + effects: fontThemeComp.reconfigure( + editorFontTheme(editorViewModule.EditorView, size, family, { + fixedHeight: true, + scrollable: true, + }), + ), + }); +} + +function scheduleFontThemeReconfig(size: number, family: string) { + pendingFontReconfig = { size, family }; + if (fontReconfigScheduled) return; + fontReconfigScheduled = true; + requestAnimationFrame(() => { + fontReconfigScheduled = false; + const p = pendingFontReconfig; + if (p) { + pendingFontReconfig = null; + reconfigureFontTheme(p.size, p.family); + } + }); } function applyLiveFontSize(size: number) { @@ -194,7 +225,10 @@ function applyLiveFontSize(size: number) { if (liveFontSize.value === next) return; liveFontSize.value = next; syncEditorFontCssVars(next); - view.value?.requestMeasure(); + // Throttle compartment reconfiguration to at most once per animation + // frame so that CSS variable changes remain smooth on every wheel tick, + // while the CodeMirror measure → syncGutters path keeps gutters aligned. + scheduleFontThemeReconfig(next, settingsStore.editorSettings.fontFamily); } function commitFontSize(size: number) { diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 1e7f216c48..92b9c6f099 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -1286,6 +1286,7 @@ export default { fontSize: "Font Size", theme: "Theme", selectTheme: "Select theme...", + followAppTheme: "Follow app theme", appLayout: "Interface Layout", appLayoutSeparated: "Modern separated", appLayoutSeparatedDescription: "Clear panel separation with block-style tabs.", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index 6b9e060c7d..219f048377 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -1263,6 +1263,7 @@ export default { fontSize: "字号", theme: "主题", selectTheme: "选择主题...", + followAppTheme: "跟随应用主题", appLayout: "界面布局", appLayoutSeparated: "现代分隔", appLayoutSeparatedDescription: "面板分隔更清晰,标签页为块状样式。", diff --git a/apps/desktop/src/lib/editorThemes.ts b/apps/desktop/src/lib/editorThemes.ts index 77cee7a43c..ca860f2dec 100644 --- a/apps/desktop/src/lib/editorThemes.ts +++ b/apps/desktop/src/lib/editorThemes.ts @@ -106,6 +106,7 @@ export function buildEditorFontThemeRules( ".cm-gutters": { borderRight: "0 !important", fontSize: `var(${EDITOR_FONT_SIZE_CSS_VAR}, ${defaults?.size ?? 13}px)`, + fontFamily: `var(${EDITOR_FONT_FAMILY_CSS_VAR}, ${defaults?.family ?? "monospace"})`, position: "relative", }, ".cm-gutters:after": {