fix(v3): modal dark-themed directory picker via custom rfd command

This commit is contained in:
Hibryda 2026-03-08 02:05:09 +01:00
parent b1efe8e48d
commit 2a93574d1f
4 changed files with 18 additions and 4 deletions

1
v2/Cargo.lock generated
View file

@ -297,6 +297,7 @@ dependencies = [
"futures-util",
"log",
"notify",
"rfd",
"rusqlite",
"serde",
"serde_json",

View file

@ -28,6 +28,7 @@ dirs = "5"
notify = { version = "6", features = ["macos_fsevent"] }
tauri-plugin-updater = "2.10.0"
tauri-plugin-dialog = "2"
rfd = { version = "0.16", default-features = false, features = ["gtk3"] }
uuid = { version = "1", features = ["v4"] }
tokio-tungstenite = { version = "0.21", features = ["native-tls"] }
tokio = { version = "1", features = ["full"] }

View file

@ -421,7 +421,15 @@ fn project_agent_state_load(
state.session_db.load_project_agent_state(&project_id)
}
// Directory picker: uses tauri-plugin-dialog (frontend API: @tauri-apps/plugin-dialog)
// Directory picker: custom rfd command with parent window for modal behavior on Linux
#[tauri::command]
async fn pick_directory(window: tauri::Window) -> Result<Option<String>, String> {
let dialog = rfd::AsyncFileDialog::new()
.set_title("Select Directory")
.set_parent(&window);
let folder = dialog.pick_folder().await;
Ok(folder.map(|f| f.path().to_string_lossy().into_owned()))
}
// --- CLI argument commands ---
@ -501,6 +509,9 @@ async fn remote_pty_kill(state: State<'_, AppState>, machine_id: String, id: Str
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
// Force dark GTK theme for native dialogs (file chooser, etc.)
std::env::set_var("GTK_THEME", "Adwaita:dark");
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
pty_spawn,
@ -555,6 +566,7 @@ pub fn run() {
project_agent_state_save,
project_agent_state_load,
cli_get_group,
pick_directory,
])
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_dialog::init())

View file

@ -16,7 +16,7 @@
import { getSetting, setSetting } from '../../adapters/settings-bridge';
import { getCurrentTheme, setTheme } from '../../stores/theme.svelte';
import { THEME_LIST, getPalette, type ThemeId } from '../../styles/themes';
import { open as openDialog } from '@tauri-apps/plugin-dialog';
import { invoke } from '@tauri-apps/api/core';
let activeGroupId = $derived(getActiveGroupId());
let activeGroup = $derived(getActiveGroup());
@ -178,8 +178,8 @@
}
async function browseDirectory(): Promise<string | null> {
const selected = await openDialog({ directory: true, multiple: false });
return typeof selected === 'string' ? selected : null;
const selected = await invoke<string | null>('pick_directory');
return selected ?? null;
}
// New project form