diff --git a/src/InterfaceSettings.jsx b/src/InterfaceSettings.jsx index 149c832..f47a660 100644 --- a/src/InterfaceSettings.jsx +++ b/src/InterfaceSettings.jsx @@ -31,10 +31,12 @@ export default function InterfaceSettings({ useEffect(() => { desktopApi.getSettings().then(settings => { const schemeName = settings.colorScheme || 'Default' + const nextUiScale = normalizeUiScale(settings.uiScale) setSelectedColorScheme(schemeName) - setUiScale(normalizeUiScale(settings.uiScale)) + setUiScale(nextUiScale) setOpenDevToolsOnStartup(settings.openDevToolsOnStartup === true) applyColorScheme(schemeName) + desktopApi.applyUiScale(nextUiScale) }) }, []) @@ -51,6 +53,7 @@ export default function InterfaceSettings({ const persistUiScale = (value) => { const nextScale = normalizeUiScale(value) setUiScale(nextScale) + desktopApi.applyUiScale(nextScale) desktopApi.setSetting(UI_SCALE_KEY, nextScale) } diff --git a/src/desktop/desktopApi.js b/src/desktop/desktopApi.js index 774378b..e361e23 100644 --- a/src/desktop/desktopApi.js +++ b/src/desktop/desktopApi.js @@ -24,6 +24,10 @@ const DEFAULT_UPDATE_STATUS = Object.freeze({ restartScheduled: false, }) +const DEFAULT_UI_SCALE = 1 +const MIN_UI_SCALE = 0.7 +const MAX_UI_SCALE = 1.3 + const hasWindow = () => typeof window !== 'undefined' const getElectronApi = () => (hasWindow() ? window.electronAPI : undefined) const getTauriCore = () => (hasWindow() ? window.__TAURI__?.core : undefined) @@ -54,6 +58,32 @@ function defaultSettings() { return { ...DEFAULT_SETTINGS } } +function normalizeUiScale(value) { + const numericValue = Number(value) + if (!Number.isFinite(numericValue)) { + return DEFAULT_UI_SCALE + } + + return Math.min(MAX_UI_SCALE, Math.max(MIN_UI_SCALE, Math.round(numericValue * 100) / 100)) +} + +function applyRendererUiScale(value) { + if (!hasWindow() || !window.document || getElectronApi()) { + return false + } + + const scale = normalizeUiScale(value) + const root = window.document.documentElement + const body = window.document.body + + root?.style?.setProperty('--heimgeist-ui-scale', String(scale)) + if (body?.style) { + body.style.zoom = scale === DEFAULT_UI_SCALE ? '' : String(scale) + } + + return true +} + function defaultUpdateStatus(message = DEFAULT_UPDATE_STATUS.message) { return { ...DEFAULT_UPDATE_STATUS, message } } @@ -110,6 +140,7 @@ const desktopApi = { callElectronApi('getSettings') ?? callTauriCommand('get_settings'), defaultSettings, ), + applyUiScale: (value) => applyRendererUiScale(value), getUpdateStatus: () => resultOrFallback( callElectronApi('getUpdateStatus') ?? callTauriCommand('get_update_status'), defaultUpdateStatus, diff --git a/src/main.jsx b/src/main.jsx index 72ea3c3..2bb5237 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -11,6 +11,7 @@ function Main() { useEffect(() => { desktopApi.getSettings().then(settings => { applyColorScheme(settings.colorScheme || 'Default') + desktopApi.applyUiScale(settings.uiScale) }) }, [])