feat: toggle window always on top

This commit is contained in:
2026-01-21 13:05:15 -08:00
parent 3fc89a4366
commit 2aa05acb66
5 changed files with 47 additions and 1 deletions
+6
View File
@@ -55,6 +55,9 @@ pub struct HikariConfig {
#[serde(default = "default_notification_volume")]
pub notification_volume: f32,
#[serde(default)]
pub always_on_top: bool,
}
impl Default for HikariConfig {
@@ -70,6 +73,7 @@ impl Default for HikariConfig {
greeting_custom_prompt: None,
notifications_enabled: true,
notification_volume: 0.7,
always_on_top: false,
}
}
}
@@ -109,6 +113,7 @@ mod tests {
assert_eq!(config.theme, Theme::Dark);
assert!(config.greeting_enabled);
assert!(config.greeting_custom_prompt.is_none());
assert!(!config.always_on_top);
}
#[test]
@@ -124,6 +129,7 @@ mod tests {
greeting_custom_prompt: Some("Hello!".to_string()),
notifications_enabled: true,
notification_volume: 0.7,
always_on_top: true,
};
let json = serde_json::to_string(&config).unwrap();
+30
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import { configStore, type HikariConfig, type Theme } from "$lib/stores/config";
import { claudeStore } from "$lib/stores/claude";
import { getCurrentWindow } from "@tauri-apps/api/window";
let config: HikariConfig = $state({
model: null,
@@ -13,6 +14,7 @@
greeting_custom_prompt: null,
notifications_enabled: true,
notification_volume: 0.7,
always_on_top: false,
});
let isOpen = $state(false);
@@ -95,6 +97,13 @@
function importFromSession() {
config.auto_granted_tools = [...new Set([...config.auto_granted_tools, ...grantedTools])];
}
async function handleAlwaysOnTopChange(enabled: boolean) {
config.always_on_top = enabled;
const window = getCurrentWindow();
await window.setAlwaysOnTop(enabled);
await configStore.updateConfig({ always_on_top: enabled });
}
</script>
<!-- Backdrop -->
@@ -396,6 +405,27 @@
</div>
</section>
<!-- Window Section -->
<section class="mb-6">
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
Window
</h3>
<!-- Always on Top Toggle -->
<div class="mb-4">
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
checked={config.always_on_top}
onchange={(e) => handleAlwaysOnTopChange(e.currentTarget.checked)}
class="w-4 h-4 text-[var(--accent-primary)] bg-[var(--bg-primary)] border-[var(--border-color)] rounded focus:ring-[var(--accent-primary)] focus:ring-2"
/>
<span class="text-sm text-gray-300">Always on top</span>
</label>
<p class="text-xs text-gray-500 mt-1 ml-7">Keep the window above other windows</p>
</div>
</section>
<!-- Notifications Section -->
<section class="mb-6">
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
+1
View File
@@ -43,6 +43,7 @@
greeting_custom_prompt: null,
notifications_enabled: true,
notification_volume: 0.5,
always_on_top: false,
});
onMount(async () => {
+2
View File
@@ -14,6 +14,7 @@ export interface HikariConfig {
greeting_custom_prompt: string | null;
notifications_enabled: boolean;
notification_volume: number;
always_on_top: boolean;
}
const defaultConfig: HikariConfig = {
@@ -27,6 +28,7 @@ const defaultConfig: HikariConfig = {
greeting_custom_prompt: null,
notifications_enabled: true,
notification_volume: 0.7,
always_on_top: false,
};
function createConfigStore() {
+8 -1
View File
@@ -4,6 +4,7 @@
import { configStore, applyTheme } from "$lib/stores/config";
import { initNotificationSync, cleanupNotificationSync } from "$lib/stores/notifications";
import { conversationsStore } from "$lib/stores/conversations";
import { getCurrentWindow } from "@tauri-apps/api/window";
import "$lib/notifications/testNotifications";
import Terminal from "$lib/components/Terminal.svelte";
import InputBar from "$lib/components/InputBar.svelte";
@@ -27,10 +28,16 @@
await initializeTauriListeners();
await configStore.loadConfig();
// Apply saved theme on startup
// Apply saved settings on startup
const config = configStore.getConfig();
applyTheme(config.theme);
// Apply always-on-top setting
if (config.always_on_top) {
const window = getCurrentWindow();
await window.setAlwaysOnTop(true);
}
// Initialize notification settings sync
initNotificationSync();
}