commit 71c5db4732175d551e6988afda0e8c4a3b035bb7
parent c01ce454b1b57569f7f207c2b66e0f33558f8666
Author: William Casarin <jb55@jb55.com>
Date: Mon, 9 Feb 2026 11:17:48 -0800
dave: gate rfd dependency for Android compatibility
Move rfd to target-specific dependencies that only compile on desktop
platforms (Windows, macOS, Linux). Gate the folder picker dialog code
in directory_picker.rs with cfg attributes.
Also consolidate rfd version to workspace and fix rand to use workspace.
Diffstat:
9 files changed, 79 insertions(+), 223 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -260,24 +260,6 @@ dependencies = [
[[package]]
name = "ashpd"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093"
-dependencies = [
- "async-fs",
- "async-net",
- "enumflags2",
- "futures-channel",
- "futures-util",
- "rand 0.8.5",
- "serde",
- "serde_repr",
- "url",
- "zbus 4.4.0",
-]
-
-[[package]]
-name = "ashpd"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
@@ -292,7 +274,7 @@ dependencies = [
"serde",
"serde_repr",
"url",
- "zbus 5.7.1",
+ "zbus",
]
[[package]]
@@ -1677,7 +1659,7 @@ dependencies = [
"objc2-foundation 0.3.1",
"parking_lot",
"percent-encoding",
- "pollster 0.4.0",
+ "pollster",
"profiling",
"raw-window-handle",
"static_assertions",
@@ -3821,19 +3803,6 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
-dependencies = [
- "bitflags 2.9.1",
- "cfg-if",
- "cfg_aliases",
- "libc",
- "memoffset",
-]
-
-[[package]]
-name = "nix"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
@@ -4124,7 +4093,7 @@ dependencies = [
"profiling",
"puffin",
"puffin_egui",
- "rfd 0.15.3",
+ "rfd",
"rmpv",
"robius-open",
"security-framework 2.11.1",
@@ -4167,7 +4136,7 @@ dependencies = [
"notedeck",
"notedeck_ui",
"rand 0.9.2",
- "rfd 0.14.1",
+ "rfd",
"serde",
"serde_json",
"sha2",
@@ -4348,17 +4317,6 @@ dependencies = [
]
[[package]]
-name = "objc-foundation"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
-dependencies = [
- "block",
- "objc",
- "objc_id",
-]
-
-[[package]]
name = "objc-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4632,15 +4590,6 @@ dependencies = [
]
[[package]]
-name = "objc_id"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
-dependencies = [
- "objc",
-]
-
-[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5007,12 +4956,6 @@ dependencies = [
[[package]]
name = "pollster"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
-
-[[package]]
-name = "pollster"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
@@ -5613,34 +5556,11 @@ dependencies = [
[[package]]
name = "rfd"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251"
-dependencies = [
- "ashpd 0.8.1",
- "block",
- "dispatch",
- "js-sys",
- "log",
- "objc",
- "objc-foundation",
- "objc_id",
- "pollster 0.3.0",
- "raw-window-handle",
- "urlencoding",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "rfd"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80c844748fdc82aae252ee4594a89b6e7ebef1063de7951545564cbc4e57075d"
dependencies = [
- "ashpd 0.11.0",
+ "ashpd",
"block2 0.6.1",
"dispatch2 0.2.0",
"js-sys",
@@ -5649,7 +5569,7 @@ dependencies = [
"objc2-app-kit 0.3.1",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
- "pollster 0.4.0",
+ "pollster",
"raw-window-handle",
"urlencoding",
"wasm-bindgen",
@@ -8424,16 +8344,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b"
[[package]]
-name = "xdg-home"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
-dependencies = [
- "libc",
- "windows-sys 0.59.0",
-]
-
-[[package]]
name = "xkbcommon-dl"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8496,44 +8406,6 @@ dependencies = [
[[package]]
name = "zbus"
-version = "4.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
-dependencies = [
- "async-broadcast",
- "async-executor",
- "async-fs",
- "async-io",
- "async-lock",
- "async-process",
- "async-recursion",
- "async-task",
- "async-trait",
- "blocking",
- "enumflags2",
- "event-listener",
- "futures-core",
- "futures-sink",
- "futures-util",
- "hex",
- "nix 0.29.0",
- "ordered-stream",
- "rand 0.8.5",
- "serde",
- "serde_repr",
- "sha1",
- "static_assertions",
- "tracing",
- "uds_windows",
- "windows-sys 0.52.0",
- "xdg-home",
- "zbus_macros 4.4.0",
- "zbus_names 3.0.0",
- "zvariant 4.2.0",
-]
-
-[[package]]
-name = "zbus"
version = "5.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68"
@@ -8552,7 +8424,7 @@ dependencies = [
"futures-core",
"futures-lite",
"hex",
- "nix 0.30.1",
+ "nix",
"ordered-stream",
"serde",
"serde_repr",
@@ -8560,22 +8432,9 @@ dependencies = [
"uds_windows",
"windows-sys 0.59.0",
"winnow",
- "zbus_macros 5.7.1",
- "zbus_names 4.2.0",
- "zvariant 5.5.3",
-]
-
-[[package]]
-name = "zbus_macros"
-version = "4.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn 2.0.104",
- "zvariant_utils 2.1.0",
+ "zbus_macros",
+ "zbus_names",
+ "zvariant",
]
[[package]]
@@ -8588,20 +8447,9 @@ dependencies = [
"proc-macro2",
"quote",
"syn 2.0.104",
- "zbus_names 4.2.0",
- "zvariant 5.5.3",
- "zvariant_utils 3.2.0",
-]
-
-[[package]]
-name = "zbus_names"
-version = "3.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
-dependencies = [
- "serde",
- "static_assertions",
- "zvariant 4.2.0",
+ "zbus_names",
+ "zvariant",
+ "zvariant_utils",
]
[[package]]
@@ -8613,7 +8461,7 @@ dependencies = [
"serde",
"static_assertions",
"winnow",
- "zvariant 5.5.3",
+ "zvariant",
]
[[package]]
@@ -8768,20 +8616,6 @@ dependencies = [
[[package]]
name = "zvariant"
-version = "4.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
-dependencies = [
- "endi",
- "enumflags2",
- "serde",
- "static_assertions",
- "url",
- "zvariant_derive 4.2.0",
-]
-
-[[package]]
-name = "zvariant"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1"
@@ -8791,21 +8625,8 @@ dependencies = [
"serde",
"url",
"winnow",
- "zvariant_derive 5.5.3",
- "zvariant_utils 3.2.0",
-]
-
-[[package]]
-name = "zvariant_derive"
-version = "4.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn 2.0.104",
- "zvariant_utils 2.1.0",
+ "zvariant_derive",
+ "zvariant_utils",
]
[[package]]
@@ -8818,18 +8639,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 2.0.104",
- "zvariant_utils 3.2.0",
-]
-
-[[package]]
-name = "zvariant_utils"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.104",
+ "zvariant_utils",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
@@ -106,6 +106,7 @@ blurhash = "0.2.3"
android-activity = { git = "https://github.com/damus-io/android-activity", rev = "4ee16f1585e4a75031dc10785163d4b920f95805", features = [ "game-activity" ] }
keyring = { version = "3.6.3", features = ["apple-native", "windows-native", "linux-native-sync-persistent", "vendored"] }
android-keyring = "0.2.0"
+rfd = "0.15"
[profile.small]
inherits = 'release'
diff --git a/crates/notedeck_columns/Cargo.toml b/crates/notedeck_columns/Cargo.toml
@@ -61,7 +61,7 @@ oot_bitset = { workspace = true }
human_format = "1.1.0"
[target.'cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))'.dependencies]
-rfd = "0.15"
+rfd = { workspace = true }
[dev-dependencies]
tempfile = { workspace = true }
diff --git a/crates/notedeck_dave/Cargo.toml b/crates/notedeck_dave/Cargo.toml
@@ -20,7 +20,7 @@ serde = { workspace = true }
nostrdb = { workspace = true }
hex = { workspace = true }
chrono = { workspace = true }
-rand = "0.9.0"
+rand = { workspace = true }
uuid = { version = "1", features = ["v4"] }
bytemuck = "1.22.0"
futures = "0.3.31"
@@ -28,9 +28,11 @@ dashmap = "6"
#reqwest = "0.12.15"
egui_extras = { workspace = true }
similar = "2"
-rfd = "0.14"
dirs = "5"
+[target.'cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))'.dependencies]
+rfd = { workspace = true }
+
[dev-dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros", "test-util"] }
diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs
@@ -618,7 +618,9 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
// Add agentic-specific UI state if available
if let Some(agentic) = &mut session.agentic {
ui_builder = ui_builder
- .permission_message_state(agentic.permission_message_state)
+ .permission_message_state(
+ agentic.permission_message_state,
+ )
.question_answers(&mut agentic.question_answers)
.question_index(&mut agentic.question_index)
.is_compacting(agentic.is_compacting);
@@ -714,8 +716,13 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
});
ui.separator();
}
- SessionListUi::new(&self.session_manager, &self.focus_queue, ctrl_held, self.ai_mode)
- .ui(ui)
+ SessionListUi::new(
+ &self.session_manager,
+ &self.focus_queue,
+ ctrl_held,
+ self.ai_mode,
+ )
+ .ui(ui)
})
.inner
})
@@ -783,7 +790,13 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
.fill(ui.visuals().faint_bg_color)
.inner_margin(egui::Margin::symmetric(8, 12))
.show(ui, |ui| {
- SessionListUi::new(&self.session_manager, &self.focus_queue, ctrl_held, self.ai_mode).ui(ui)
+ SessionListUi::new(
+ &self.session_manager,
+ &self.focus_queue,
+ ctrl_held,
+ self.ai_mode,
+ )
+ .ui(ui)
})
.inner;
if let Some(action) = session_action {
@@ -872,9 +885,9 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
// Add to recent directories
self.directory_picker.add_recent(cwd.clone());
- let id = self
- .session_manager
- .new_resumed_session(cwd, resume_session_id, title, self.ai_mode);
+ let id =
+ self.session_manager
+ .new_resumed_session(cwd, resume_session_id, title, self.ai_mode);
// Request focus on the new session's input
if let Some(session) = self.session_manager.get_mut(id) {
session.focus_requested = true;
@@ -890,7 +903,11 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
/// Clone the active agent, creating a new session with the same working directory
fn clone_active_agent(&mut self) {
- if let Some(cwd) = self.session_manager.get_active().and_then(|s| s.cwd().cloned()) {
+ if let Some(cwd) = self
+ .session_manager
+ .get_active()
+ .and_then(|s| s.cwd().cloned())
+ {
self.create_session_with_cwd(cwd);
}
}
@@ -904,7 +921,9 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
// Drain all pending connections (non-blocking)
while let Some(mut pending) = listener.try_recv() {
// Create the session and get its ID
- let id = self.session_manager.new_session(pending.cwd.clone(), self.ai_mode);
+ let id = self
+ .session_manager
+ .new_session(pending.cwd.clone(), self.ai_mode);
self.directory_picker.add_recent(pending.cwd);
// Focus on new session
diff --git a/crates/notedeck_dave/src/session.rs b/crates/notedeck_dave/src/session.rs
@@ -79,7 +79,12 @@ impl AgenticSessionData {
}
/// Update a subagent's output (appending new content, keeping only the tail)
- pub fn update_subagent_output(&mut self, chat: &mut [Message], task_id: &str, new_output: &str) {
+ pub fn update_subagent_output(
+ &mut self,
+ chat: &mut [Message],
+ task_id: &str,
+ new_output: &str,
+ ) {
if let Some(&idx) = self.subagent_indices.get(task_id) {
if let Some(Message::Subagent(subagent)) = chat.get_mut(idx) {
subagent.output.push_str(new_output);
diff --git a/crates/notedeck_dave/src/ui/directory_picker.rs b/crates/notedeck_dave/src/ui/directory_picker.rs
@@ -253,6 +253,11 @@ impl DirectoryPicker {
paint_keybind_hint(ui, hint_center, "B", 18.0);
}
+ #[cfg(any(
+ target_os = "windows",
+ target_os = "macos",
+ target_os = "linux"
+ ))]
if response
.on_hover_text("Open folder picker dialog (B)")
.clicked()
@@ -268,6 +273,17 @@ impl DirectoryPicker {
});
self.pending_folder_pick = Some(rx);
}
+
+ // On platforms without rfd (e.g., Android), just show the button disabled
+ #[cfg(not(any(
+ target_os = "windows",
+ target_os = "macos",
+ target_os = "linux"
+ )))]
+ {
+ let _ = response;
+ let _ = trigger_browse;
+ }
});
if self.pending_folder_pick.is_some() {
diff --git a/crates/notedeck_dave/src/ui/keybindings.rs b/crates/notedeck_dave/src/ui/keybindings.rs
@@ -130,7 +130,8 @@ pub fn check_keybindings(
}
// Ctrl+\ to toggle auto-steal focus mode (Ctrl+Space conflicts with macOS input source switching) - agentic only
- if is_agentic && ctx.input(|i| i.modifiers.matches_exact(ctrl) && i.key_pressed(Key::Backslash)) {
+ if is_agentic && ctx.input(|i| i.modifiers.matches_exact(ctrl) && i.key_pressed(Key::Backslash))
+ {
return Some(KeyAction::ToggleAutoSteal);
}
@@ -178,7 +179,8 @@ pub fn check_keybindings(
// IMPORTANT: Only handle these when no text input has focus, to avoid
// capturing keypresses when user is typing a message in tentative state
// AskUserQuestion uses number keys for option selection, so we skip these bindings
- if is_agentic && has_pending_permission && !has_pending_question && !ctx.wants_keyboard_input() {
+ if is_agentic && has_pending_permission && !has_pending_question && !ctx.wants_keyboard_input()
+ {
// Shift+1 = tentative accept, Shift+2 = tentative deny
// Note: egui may report shifted keys as their symbol (e.g., Shift+1 as Exclamationmark)
// We check for both the symbol key and Shift+Num key to handle different behaviors
diff --git a/crates/notedeck_dave/src/ui/scene.rs b/crates/notedeck_dave/src/ui/scene.rs
@@ -268,7 +268,8 @@ impl AgentScene {
for session in session_manager.iter() {
if let Some(agentic) = &session.agentic {
- let agent_pos = Pos2::new(agentic.scene_position.x, agentic.scene_position.y);
+ let agent_pos =
+ Pos2::new(agentic.scene_position.x, agentic.scene_position.y);
if selection_rect.contains(agent_pos) {
self.selected.push(session.id);
}