notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 7e46d846662fcde2234a5df93b6fc6772aca6493
parent 4a14d59f404e5adc0028c26ae93c04eb837bdb5d
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  9 Feb 2026 11:36:27 -0800

dave: fix box-selection coordinate space mismatch

Convert screen-space drag coordinates to scene-space before comparing
with agent positions, fixing selection when camera is panned/zoomed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Diffstat:
Mcrates/notedeck_dave/src/ui/scene.rs | 17+++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/crates/notedeck_dave/src/ui/scene.rs b/crates/notedeck_dave/src/ui/scene.rs @@ -147,7 +147,7 @@ impl AgentScene { let mut scene_rect = self.scene_rect; let selected_ids = &self.selected; - egui::Scene::new() + let scene_response = egui::Scene::new() .zoom_range(0.1..=1.0) .show(ui, &mut scene_rect, |ui| { // Draw agents and collect interaction responses @@ -208,6 +208,9 @@ impl AgentScene { } }); + // Get the viewport rect for coordinate transforms + let viewport_rect = scene_response.response.rect; + self.scene_rect = scene_rect; // Process agent click @@ -263,7 +266,17 @@ impl AgentScene { // Handle box selection completion if let Some(drag) = &self.drag_select { if ui.input(|i| i.pointer.primary_released()) { - let selection_rect = Rect::from_two_pos(drag.start, drag.current); + // Convert screen-space drag coordinates to scene-space + // Screen -> Scene: scene_pos = scene_rect.min + (screen_pos - viewport.min) / viewport.size() * scene_rect.size() + let screen_to_scene = |screen_pos: Pos2| -> Pos2 { + let rel = (screen_pos - viewport_rect.min) / viewport_rect.size(); + scene_rect.min + rel * scene_rect.size() + }; + + let scene_start = screen_to_scene(drag.start); + let scene_current = screen_to_scene(drag.current); + let selection_rect = Rect::from_two_pos(scene_start, scene_current); + self.selected.clear(); for session in session_manager.iter() {