From 12587339d83a55a140267bb8c20dd3cbbc0afec8 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 15 Oct 2026 16:09:55 +0300 Subject: [PATCH] fix(selection): a fast press-drag starts the selection window at once A left drag only became a lasso/window after the button had been held 150 ms, however far the cursor had moved. A fast flick released inside that delay read as a click and armed a click-click box instead. A press that has moved more than 12 px is now a drag at once; the delay still keeps small movements of a click from becoming one. (#1808) Co-Authored-By: Claude Opus 5.5 --- src/app/mod.rs | 3 +++ src/app/update/viewport.rs | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index ce4ed0734..72f4ee4e7 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -378,6 +378,9 @@ use iced::{mouse, Point, Task, Theme}; use std::sync::Arc; pub(super) const POLY_START_DELAY_MS: u128 = 150; +/// Squared screen distance (12 px) past which a left press is a drag +/// without waiting for `POLY_START_DELAY_MS`. +pub(super) const DRAG_START_FAST_PX2: f32 = 144.0; pub(super) const VARIES_LABEL: &str = "*VARIES*"; // ── File-open progress ───────────────────────────────────────────────────── diff --git a/src/app/update/viewport.rs b/src/app/update/viewport.rs index 3ae282e94..25ca93d02 100644 --- a/src/app/update/viewport.rs +++ b/src/app/update/viewport.rs @@ -8,7 +8,7 @@ use crate::app::helpers::{ polar_constrain_if_near, polar_constrain_near, ucs_rotate_vec, ucs_to_wcs, ucs_z_axis, CoordKind, }; -use crate::app::{Message, OpenCADStudio, POLY_START_DELAY_MS}; +use crate::app::{Message, OpenCADStudio, DRAG_START_FAST_PX2, POLY_START_DELAY_MS}; use crate::modules::ModuleEvent; use crate::scene::model::object::GripApply; use crate::scene::pick::grip::{ @@ -1323,7 +1323,13 @@ impl OpenCADStudio { .left_press_time .map(|t| Instant::now().duration_since(t).as_millis()) .unwrap_or(u128::MAX); - if !sel.input.left_dragging && elapsed_ms >= POLY_START_DELAY_MS && dist2 > 9.0 { + // The delay keeps a click made while the mouse is still moving + // from turning into a drag; a press that has already travelled + // well past click jitter is a drag at once, or a fast flick + // released inside the delay read as a click. (#1808) + let dragged = + dist2 > 9.0 && (elapsed_ms >= POLY_START_DELAY_MS || dist2 > DRAG_START_FAST_PX2); + if !sel.input.left_dragging && dragged { sel.input.left_dragging = true; if self.pick_drag_rect { // PICKDRAG 1 (#226): press-drag spans a RECTANGLE