fix: Shift and Space combine, and a held Shift doesn't freeze the press

This commit is contained in:
elwrcl committed 2026-10-03 02:46:53 +03:00
1 parent 4de96f5018
commit 6dfa418f8c
2 files changed
+52 -6

No files matched your search

+1 -2
View File
@@ -309,9 +309,8 @@ impl Overlay {
PointerEventKind::Press {
button: BTN_LEFT, ..
} => {
self.selection.press(p);
// Modifiers already held apply from the start.
self.selection.set_mods(self.mods);
self.selection.press_with(p, self.mods);
self.anchor = Some(i);
}
PointerEventKind::Press {
+51 -4
View File
@@ -47,11 +47,15 @@ pub enum Selection {
}
impl Selection {
/// A press with no modifiers held (tests use it).
#[cfg(test)]
pub fn press(&mut self, p: Point) {
let mods = match self {
Selection::Dragging(d) => d.mods,
Selection::Idle => Mods::default(),
};
self.press_with(p, Mods::default());
}
/// Starts a drag with `mods` already held. A held Shift doesn't lock an
/// axis yet: there is nothing to keep until the selection has a size.
pub fn press_with(&mut self, p: Point, mods: Mods) {
*self = Selection::Dragging(Drag {
start: p,
end: p,
@@ -70,6 +74,13 @@ impl Selection {
x: d.start.x + dx,
y: d.start.y + dy,
};
// A Shift lock moves along, or releasing Space would snap back.
if let Some((frozen, _)) = &mut d.lock {
*frozen = Point {
x: frozen.x + dx,
y: frozen.y + dy,
};
}
d.end = Point {
x: d.end.x + dx,
y: d.end.y + dy,
@@ -434,6 +445,42 @@ mod tests {
assert_eq!(s.corners(), Some((pt(5.0, 0.0), pt(55.0, 40.0))));
}
#[test]
fn moving_with_space_carries_the_shift_lock_along() {
let mut s = Selection::default();
s.press(pt(0.0, 0.0));
s.motion(pt(40.0, 30.0));
s.set_mods(SHIFT);
s.motion(pt(60.0, 31.0)); // axis X
s.set_mods(Mods {
shift: true,
alt: false,
space: true,
});
s.motion(pt(60.0, 131.0)); // moved 100 down
assert_eq!(s.corners(), Some((pt(0.0, 100.0), pt(60.0, 130.0))));
s.set_mods(SHIFT);
s.motion(pt(70.0, 131.0));
assert_eq!(
s.corners(),
Some((pt(0.0, 100.0), pt(70.0, 130.0))),
"no jump back"
);
}
#[test]
fn shift_held_at_the_press_does_not_freeze_the_press_point() {
let mut s = Selection::default();
s.press_with(pt(10.0, 10.0), SHIFT);
s.set_mods(SHIFT);
s.motion(pt(60.0, 40.0));
assert_eq!(
s.corners(),
Some((pt(10.0, 10.0), pt(60.0, 40.0))),
"a real rectangle"
);
}
#[test]
fn release_applies_the_held_modifiers() {
let mut s = Selection::default();