Skip to content

Commit

Permalink
Add touchpad rotate support for macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
jsatka committed Jan 20, 2022
1 parent bc3f998 commit 0122cf2
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Unreleased

- **Breaking:** Rename the `Exit` variant of `ControlFlow` to `ExitWithCode`, which holds a value to control the exit code after running. Add an `Exit` constant which aliases to `ExitWithCode(0)` instead to avoid major breakage. This shouldn't affect most existing programs.
- On macOS, add support for touchpad magnification gesture with new event `WindowEvent::TouchpadMagnify`.
- On macOS, add support for touchpad magnification and rotation gestures with new events `WindowEvent::TouchpadMagnify` and `WindowEvent::TouchpadRotate`.

# 0.26.1 (2022-01-05)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
let event_loop = EventLoop::new();

let _window = WindowBuilder::new()
.with_title("Touchpad magnify events")
.with_title("Touchpad gestures")
.build(&event_loop)
.unwrap();

Expand All @@ -29,6 +29,13 @@ fn main() {
println!("Zoomed out {}", delta);
}
},
WindowEvent::TouchpadRotate { delta, .. } => {
if delta > 0.0 {
println!("Rotated left {}", delta);
} else {
println!("Rotated right {}", delta);
}
},
_ => (),
},
_ => (),
Expand Down
30 changes: 30 additions & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,18 @@ pub enum WindowEvent<'a> {
phase: TouchPhase,
},

/// Touchpad rotation event with two-finger rotation gesture.
///
/// Positive delta values indicate rotation to left (counterclockwise) and
/// negative delta values indicate rotation to right (clockwise).
///
/// At the moment, only supported on macOS.
TouchpadRotate {
device_id: DeviceId,
delta: f32,
phase: TouchPhase,
},

/// Touchpad pressure event.
///
/// At the moment, only supported on Apple forcetouch-capable macbooks.
Expand Down Expand Up @@ -439,6 +451,15 @@ impl Clone for WindowEvent<'static> {
delta: *delta,
phase: *phase,
},
TouchpadRotate {
device_id,
delta,
phase
} => TouchpadRotate {
device_id: *device_id,
delta: *delta,
phase: *phase,
},
TouchpadPressure {
device_id,
pressure,
Expand Down Expand Up @@ -534,6 +555,15 @@ impl<'a> WindowEvent<'a> {
delta,
phase,
}),
TouchpadRotate {
device_id,
delta,
phase
} => Some(TouchpadRotate {
device_id,
delta,
phase,
}),
TouchpadPressure {
device_id,
pressure,
Expand Down
35 changes: 33 additions & 2 deletions src/platform_impl/macos/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ lazy_static! {
sel!(magnifyWithEvent:),
magnify_with_event as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(rotateWithEvent:),
rotate_with_event as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(pressureChangeWithEvent:),
pressure_change_with_event as extern "C" fn(&Object, Sel, id),
Expand Down Expand Up @@ -1053,8 +1057,6 @@ extern "C" fn scroll_wheel(this: &Object, _sel: Sel, event: id) {
extern "C" fn magnify_with_event(this: &Object, _sel: Sel, event: id) {
trace!("Triggered `magnifyWithEvent`");

mouse_motion(this, event);

unsafe {
let state_ptr: *mut c_void = *this.get_ivar("winitState");
let state = &mut *(state_ptr as *mut ViewState);
Expand All @@ -1081,6 +1083,35 @@ extern "C" fn magnify_with_event(this: &Object, _sel: Sel, event: id) {
trace!("Completed `magnifyWithEvent`");
}

extern "C" fn rotate_with_event(this: &Object, _sel: Sel, event: id) {
trace!("Triggered `rotateWithEvent`");

unsafe {
let state_ptr: *mut c_void = *this.get_ivar("winitState");
let state = &mut *(state_ptr as *mut ViewState);

let delta = event.rotation();
let phase = match event.phase() {
NSEventPhase::NSEventPhaseBegan => TouchPhase::Started,
NSEventPhase::NSEventPhaseChanged => TouchPhase::Moved,
NSEventPhase::NSEventPhaseEnded => TouchPhase::Ended,
_ => return
};

let window_event = Event::WindowEvent {
window_id: WindowId(get_window_id(state.ns_window)),
event: WindowEvent::TouchpadRotate {
device_id: DEVICE_ID,
delta,
phase,
},
};

AppState::queue_event(EventWrapper::StaticEvent(window_event));
}
trace!("Completed `rotateWithEvent`");
}

extern "C" fn pressure_change_with_event(this: &Object, _sel: Sel, event: id) {
trace!("Triggered `pressureChangeWithEvent`");

Expand Down

0 comments on commit 0122cf2

Please sign in to comment.