From 210c9f426015b9e451da0f3f7e0acfe8f09ac86b Mon Sep 17 00:00:00 2001 From: elwrcl Date: Sun, 4 Oct 2026 16:34:24 +0300 Subject: [PATCH] zoom: a magnifier cursor (zoom-in), a grabbing hand while dragging --- docs/test-checklist.md | 1 + src/zoom/mod.rs | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/test-checklist.md b/docs/test-checklist.md index a59b79c..87ab451 100644 --- a/docs/test-checklist.md +++ b/docs/test-checklist.md @@ -54,6 +54,7 @@ image, a cancel brought the thumbnail back, and a swipe still dismissed it. ## Zoom (Phase 4) - [ ] `valw zoom` → the focused output freezes at 1×; Esc and `q` leave, nothing saved, exit 0, thumbnails come back. +- [ ] The pointer is a magnifier (zoom-in) over the zoom, a grabbing hand while dragging, the magnifier again after. - [ ] Wheel zooms towards the pointer (the point under it stays put), smoothly, up to 32×; pixels stay crisp. - [ ] Touchpad scrolling zooms smoothly too. - [ ] Left drag pans 1:1 and never shows anything outside the screenshot; the cursor turns into a grabbing hand. diff --git a/src/zoom/mod.rs b/src/zoom/mod.rs index 07f683e..83f6de9 100644 --- a/src/zoom/mod.rs +++ b/src/zoom/mod.rs @@ -238,8 +238,8 @@ impl Zoom { let p = (event.position.0 * self.ratio, event.position.1 * self.ratio); match event.kind { PointerEventKind::Enter { serial } => { - if let Some(cursor) = cursor { - cursor.set_shape(serial, Shape::Default); + if let Some(device) = cursor { + device.set_shape(serial, self::cursor(self.panning.is_some())); } self.pointer = p; } @@ -249,8 +249,8 @@ impl Zoom { .. } => { self.panning = Some(p); - if let Some(cursor) = cursor { - cursor.set_shape(serial, Shape::Grabbing); + if let Some(device) = cursor { + device.set_shape(serial, self::cursor(true)); } } PointerEventKind::Release { @@ -259,8 +259,8 @@ impl Zoom { .. } => { self.panning = None; - if let Some(cursor) = cursor { - cursor.set_shape(serial, Shape::Default); + if let Some(device) = cursor { + device.set_shape(serial, self::cursor(false)); } } PointerEventKind::Motion { .. } => { @@ -320,10 +320,26 @@ impl Zoom { } } +/// The pointer over a zoom: a magnifier, so it reads as zoom mode, and a +/// grabbing hand while dragging the view. +fn cursor(panning: bool) -> Shape { + if panning { + Shape::Grabbing + } else { + Shape::ZoomIn + } +} + #[cfg(test)] mod tests { use super::*; + #[test] + fn the_cursor_says_zoom_and_grabs_while_dragging() { + assert_eq!(cursor(false), Shape::ZoomIn); + assert_eq!(cursor(true), Shape::Grabbing); + } + #[test] fn keys() { assert_eq!(command(Keysym::Escape), Some(Command::Leave));