GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat: Application::handle_pinch — first-class trackpad pinch hook
The pinch gesture was only ever delivered as a synthesized ctrl+wheel
PixelDelta sized for the graph's zoom mapping, which underfeeds any
surface with different zoom constants. Apps can now consume the raw
per-update scale factor (1:1 direct manipulation); returning false
keeps the legacy synthesis, so existing ctrl-scroll zoom surfaces are
unchanged.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/backend/window_runner.rs | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 882c242..b9fb9f4 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -2406,6 +2406,16 @@ pub trait Application: Sized + 'static {
fn handle_pointer_move(&mut self, pos: LogicalPosition, needs_rebuild: &mut bool);
fn handle_mouse_input(&mut self, button: MouseButton, state: ElementState, pos: LogicalPosition, needs_rebuild: &mut bool) -> Option<Self::Message>;
fn handle_mouse_wheel(&mut self, delta: &MouseScrollDelta, pos: LogicalPosition, needs_rebuild: &mut bool);
+ /// Trackpad pinch (zwp_pointer_gestures pinch). `factor` is the scale
+ /// change SINCE THE LAST update (1.0 = no change, >1 = fingers spreading),
+ /// so direct-manipulation zoom is `content_scale *= factor`. Return true
+ /// to consume; returning false falls back to the engine's legacy
+ /// synthesis — a ctrl+wheel PixelDelta sized for the graph's zoom mapping
+ /// (`y = (factor-1)/0.015`) — so ctrl-scroll-zoom surfaces keep working
+ /// without implementing this.
+ fn handle_pinch(&mut self, _factor: f32, _pos: LogicalPosition, _needs_rebuild: &mut bool) -> bool {
+ false
+ }
fn handle_key_input(&mut self, event: &KeyEvent, needs_rebuild: &mut bool) -> Option<Self::Message>;
/// Keyboard focus entered/left the window (the compositor keyboard-focuses
/// the focused window, so this is the "am I the focused window" signal —
@@ -3779,6 +3789,16 @@ impl<A: Application> wayland_client::Dispatch<ZwpPointerGesturePinchV1, ()> for
let (px, py) = state.cursor_pos;
let mut rebuild = false;
+ // First offer the gesture as-is: apps with true pinch
+ // surfaces (the designer's 3D viewport) consume it here at
+ // 1:1 scale instead of through the wheel synthesis below.
+ if state.inner.as_mut().unwrap().handle_pinch(factor, LogicalPosition::new(px, py), &mut rebuild) {
+ if rebuild {
+ state.redraw = true;
+ }
+ return;
+ }
+
// Calculate the y_delta for PixelDelta mapping.
// Since cce-graph interprets factor = 1.0 + y_delta * 0.015, we reverse it:
let y_delta = (factor - 1.0) / 0.015;