diff --git a/apps/desktop-gpui/src/editor_canvas.rs b/apps/desktop-gpui/src/editor_canvas.rs index 14618f7bea7..e39582dffa6 100644 --- a/apps/desktop-gpui/src/editor_canvas.rs +++ b/apps/desktop-gpui/src/editor_canvas.rs @@ -305,12 +305,10 @@ fn overlay_drag_center( } else { snap_moving_rect(raw, targets, 7. / canvas.0.max(1.), 7. / canvas.1.max(1.)) }; - let x = (raw.x + dx).clamp(0., 1.); - let y = (raw.y + dy).clamp(0., 1.); ( XY { - x: (x + raw.w / 2.).clamp(0., 1.), - y: (y + raw.h / 2.).clamp(0., 1.), + x: (raw.x + dx + raw.w / 2.).clamp(0., 1.), + y: (raw.y + dy + raw.h / 2.).clamp(0., 1.), }, guides, ) @@ -2003,6 +2001,59 @@ mod tests { assert!(guides.is_empty()); } + #[test] + fn overlay_drag_preserves_pointer_motion_near_top_and_left_edges() { + let rect = NormRect { + x: -0.1, + y: -0.05, + w: 0.4, + h: 0.3, + }; + for canvas in [(800., 450.), (450., 800.), (500., 500.)] { + let (center, guides) = overlay_drag_center( + rect, + canvas, + (canvas.0 * 0.02, canvas.1 * 0.03), + &SnapTargets::default(), + true, + ); + assert!((center.x - 0.12).abs() < 1e-9, "{center:?}"); + assert!((center.y - 0.13).abs() < 1e-9, "{center:?}"); + assert!(guides.is_empty()); + } + } + + #[test] + fn overlay_drag_clamps_the_center_at_every_frame_edge() { + let rect = NormRect { + x: 0.3, + y: 0.35, + w: 0.4, + h: 0.3, + }; + for (delta, expected) in [((-900., -1600.), 0.), ((900., 1600.), 1.)] { + let (center, _) = + overlay_drag_center(rect, (450., 800.), delta, &SnapTargets::default(), true); + assert!((center.x - expected).abs() < 1e-9, "{center:?}"); + assert!((center.y - expected).abs() < 1e-9, "{center:?}"); + } + } + + #[test] + fn overlay_drag_applies_snapping_while_overhanging_the_frame() { + let rect = NormRect { + x: -0.09, + y: -0.1, + w: 0.2, + h: 0.4, + }; + let targets = build_snap_targets(&[], None); + let (center, guides) = overlay_drag_center(rect, (450., 800.), (0., 0.), &targets, false); + assert!(center.x.abs() < 1e-9, "{center:?}"); + assert!((center.y - 0.1).abs() < 1e-9, "{center:?}"); + assert!(guides.iter().any(|guide| guide.axis == GuideAxis::V)); + } + #[test] fn the_display_clamp_lets_half_the_card_hang_out() { let rect = NormRect {