Fix Linux startup theme flash (#195)

This commit is contained in:
Yuri Karamian
2026-08-03 15:54:17 +02:00
parent fcf48a5b7a
commit 18bb6bb702
4 changed files with 58 additions and 4 deletions
+1
View File
@@ -11,6 +11,7 @@
"core:window:allow-minimize", "core:window:allow-minimize",
"core:window:allow-toggle-maximize", "core:window:allow-toggle-maximize",
"core:window:allow-close", "core:window:allow-close",
"core:window:allow-show",
"core:window:allow-is-maximized", "core:window:allow-is-maximized",
"core:window:allow-set-decorations", "core:window:allow-set-decorations",
"core:window:allow-is-fullscreen", "core:window:allow-is-fullscreen",
+10 -1
View File
@@ -313,7 +313,16 @@ pub fn run() {
})); }));
builder = builder.plugin(tauri_plugin_updater::Builder::new().build()); builder = builder.plugin(tauri_plugin_updater::Builder::new().build());
builder = builder.plugin(tauri_plugin_window_state::Builder::default().build()); let window_state_builder = tauri_plugin_window_state::Builder::default();
#[cfg(target_os = "linux")]
let window_state_builder = window_state_builder.with_state_flags(
tauri_plugin_window_state::StateFlags::SIZE
| tauri_plugin_window_state::StateFlags::POSITION
| tauri_plugin_window_state::StateFlags::MAXIMIZED
| tauri_plugin_window_state::StateFlags::DECORATIONS
| tauri_plugin_window_state::StateFlags::FULLSCREEN,
);
builder = builder.plugin(window_state_builder.build());
builder = builder.on_window_event(move |window, event| { builder = builder.on_window_event(move |window, event| {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
+10
View File
@@ -0,0 +1,10 @@
{
"app": {
"windows": [
{
"label": "main",
"visible": false
}
]
}
}
+37 -3
View File
@@ -1,10 +1,11 @@
<script lang="ts"> <script lang="ts">
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount, tick } from 'svelte';
import { appConfig, vaultReady, theme } from '$lib/stores/app'; import { appConfig, vaultReady, theme } from '$lib/stores/app';
import { getAppConfig, openVault, restoreExternalVault, setFontSize } from '$lib/api'; import { getAppConfig, openVault, restoreExternalVault, setFontSize } from '$lib/api';
import { darkThemes, isIOS } from '$lib/platform'; import { darkThemes, isIOS, isMobile } from '$lib/platform';
import { getCurrentWebview } from '@tauri-apps/api/webview'; import { getCurrentWebview } from '@tauri-apps/api/webview';
import { listen } from '@tauri-apps/api/event'; import { listen } from '@tauri-apps/api/event';
import { getCurrentWindow } from '@tauri-apps/api/window';
import VaultPicker from '$lib/components/VaultPicker.svelte'; import VaultPicker from '$lib/components/VaultPicker.svelte';
import AppLayout from '$lib/components/AppLayout.svelte'; import AppLayout from '$lib/components/AppLayout.svelte';
import NoteWindow from '$lib/components/NoteWindow.svelte'; import NoteWindow from '$lib/components/NoteWindow.svelte';
@@ -15,6 +16,28 @@
let fontSizeSaveTimer: ReturnType<typeof setTimeout> | null = null; let fontSizeSaveTimer: ReturnType<typeof setTimeout> | null = null;
let removeEditorZoomShortcuts: (() => void) | null = null; let removeEditorZoomShortcuts: (() => void) | null = null;
let removeFontSizeListener: (() => void) | null = null; let removeFontSizeListener: (() => void) | null = null;
let startupRevealTimer: ReturnType<typeof setTimeout> | null = null;
let startupWindowRevealed = false;
const STARTUP_REVEAL_FAILSAFE_MS = 4000;
async function revealStartupWindow() {
if (isMobile || startupWindowRevealed) return;
await tick();
// Force style resolution while the native window is still hidden so its first
// compositor frame already uses the selected theme.
getComputedStyle(document.body).backgroundColor;
try {
await getCurrentWindow().show();
startupWindowRevealed = true;
if (startupRevealTimer) {
clearTimeout(startupRevealTimer);
startupRevealTimer = null;
}
} catch {
// Plain-browser development has no Tauri window to reveal.
}
}
const defaultEditorFontSize = 14; const defaultEditorFontSize = 14;
const minEditorFontSize = 10; const minEditorFontSize = 10;
@@ -114,6 +137,9 @@
} }
onMount(async () => { onMount(async () => {
if (!isMobile) {
startupRevealTimer = setTimeout(() => void revealStartupWindow(), STARTUP_REVEAL_FAILSAFE_MS);
}
// Check for note window mode // Check for note window mode
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const notePath = params.get('note'); const notePath = params.get('note');
@@ -209,6 +235,7 @@
console.error('Failed to apply interface scale:', e); console.error('Failed to apply interface scale:', e);
} }
} }
await revealStartupWindow();
removeEditorZoomShortcuts = installEditorZoomShortcuts(); removeEditorZoomShortcuts = installEditorZoomShortcuts();
// Auto-open last vault if available // Auto-open last vault if available
@@ -242,14 +269,21 @@
} }
} catch { } catch {
// First launch or no config // First launch or no config
} } finally {
loading = false; loading = false;
await revealStartupWindow();
if (startupRevealTimer) {
clearTimeout(startupRevealTimer);
startupRevealTimer = null;
}
}
}); });
onDestroy(() => { onDestroy(() => {
removeEditorZoomShortcuts?.(); removeEditorZoomShortcuts?.();
removeFontSizeListener?.(); removeFontSizeListener?.();
if (fontSizeSaveTimer) clearTimeout(fontSizeSaveTimer); if (fontSizeSaveTimer) clearTimeout(fontSizeSaveTimer);
if (startupRevealTimer) clearTimeout(startupRevealTimer);
}); });
</script> </script>