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": {