commit 1d22963394b6915207aef18f0bc1434476c1ce40
parent 0feda7967188d69547272464b7057f54e5f2fb6a
Author: William Casarin <jb55@jb55.com>
Date: Tue, 27 Jan 2026 07:10:48 -0800
dave: show keybinding hints only when Ctrl is held
Instead of always showing agent numbers and [N] keybinding hints,
now show the first letter of agent titles by default and only reveal
the numeric keybindings when Ctrl is held. This allows users to
intuitively discover keybindings by holding Ctrl.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat:
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs
@@ -321,6 +321,9 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
self.session_manager.switch_to(attention_id);
}
+ // Check if Ctrl is held for showing keybinding hints
+ let ctrl_held = ui.input(|i| i.modifiers.ctrl);
+
StripBuilder::new(ui)
.size(Size::relative(0.25)) // Scene area: 25%
.size(Size::remainder()) // Chat panel: 75%
@@ -330,9 +333,15 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
strip.cell(|ui| {
// Scene toolbar at top
ui.horizontal(|ui| {
+ // Show keybinding hint only when Ctrl is held
+ let new_agent_label = if ctrl_held {
+ "+ New Agent [N]"
+ } else {
+ "+ New Agent"
+ };
if ui
- .button("+ New Agent [N]")
- .on_hover_text("Press N to spawn new agent")
+ .button(new_agent_label)
+ .on_hover_text("Hold Ctrl to see keybindings")
.clicked()
{
dave_response = DaveResponse::new(DaveAction::NewChat);
@@ -348,8 +357,8 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
});
ui.separator();
- // Render the scene
- scene_response = Some(self.scene.ui(&self.session_manager, ui));
+ // Render the scene, passing ctrl_held for keybinding hints
+ scene_response = Some(self.scene.ui(&self.session_manager, ui, ctrl_held));
});
// Chat side panel
diff --git a/crates/notedeck_dave/src/ui/scene.rs b/crates/notedeck_dave/src/ui/scene.rs
@@ -136,7 +136,12 @@ impl AgentScene {
}
/// Render the scene
- pub fn ui(&mut self, session_manager: &SessionManager, ui: &mut egui::Ui) -> SceneResponse {
+ pub fn ui(
+ &mut self,
+ session_manager: &SessionManager,
+ ui: &mut egui::Ui,
+ ctrl_held: bool,
+ ) -> SceneResponse {
let mut response = SceneResponse::default();
// Update camera animation towards target
@@ -184,7 +189,7 @@ impl AgentScene {
let is_selected = selected_ids.contains(&id);
let agent_response =
- Self::draw_agent(ui, id, position, status, title, is_selected);
+ Self::draw_agent(ui, id, position, status, title, is_selected, ctrl_held);
if agent_response.clicked() {
let shift = ui.input(|i| i.modifiers.shift);
@@ -315,6 +320,7 @@ impl AgentScene {
status: AgentStatus,
title: &str,
is_selected: bool,
+ show_keybinding: bool,
) -> Response {
let agent_radius = 30.0;
let center = Pos2::new(position.x, position.y);
@@ -350,12 +356,16 @@ impl AgentScene {
};
painter.circle_filled(center, agent_radius - 2.0, fill_color);
- // Agent number in center
- let node_number = id.to_string();
+ // Agent icon in center: show number when Ctrl held (keybinding hint), otherwise first letter
+ let icon_text = if show_keybinding {
+ id.to_string()
+ } else {
+ title.chars().next().unwrap_or('?').to_uppercase().collect()
+ };
painter.text(
center,
egui::Align2::CENTER_CENTER,
- &node_number,
+ &icon_text,
egui::FontId::proportional(20.0),
ui.visuals().text_color(),
);