mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Add touchpad magnify and rotate gestures support for macOS (#2157)
* Add touchpad magnify support for macOS * Add touchpad rotate support for macOS * Add macOS rotate and magnify gesture cancelled phases * Correct docs for TouchpadRotate event * Fix tracing macros
This commit is contained in:
parent
76f158d310
commit
da2cef97a3
|
@ -10,6 +10,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
|
|
||||||
- On Windows, added `WindowExtWindows::set_undecorated_shadow` and `WindowBuilderExtWindows::with_undecorated_shadow` to draw the drop shadow behind a borderless window.
|
- On Windows, added `WindowExtWindows::set_undecorated_shadow` and `WindowBuilderExtWindows::with_undecorated_shadow` to draw the drop shadow behind a borderless window.
|
||||||
- On Windows, fixed default window features (ie snap, animations, shake, etc.) when decorations are disabled.
|
- On Windows, fixed default window features (ie snap, animations, shake, etc.) when decorations are disabled.
|
||||||
|
- On macOS, add support for two-finger touchpad magnification and rotation gestures with new events `WindowEvent::TouchpadMagnify` and `WindowEvent::TouchpadRotate`.
|
||||||
|
|
||||||
# 0.27.2 (2022-8-12)
|
# 0.27.2 (2022-8-12)
|
||||||
|
|
||||||
|
|
43
examples/touchpad_gestures.rs
Normal file
43
examples/touchpad_gestures.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use simple_logger::SimpleLogger;
|
||||||
|
use winit::{
|
||||||
|
event::{Event, WindowEvent},
|
||||||
|
event_loop::{ControlFlow, EventLoop},
|
||||||
|
window::WindowBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
SimpleLogger::new().init().unwrap();
|
||||||
|
let event_loop = EventLoop::new();
|
||||||
|
|
||||||
|
let _window = WindowBuilder::new()
|
||||||
|
.with_title("Touchpad gestures")
|
||||||
|
.build(&event_loop)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("Only supported on macOS at the moment.");
|
||||||
|
|
||||||
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
||||||
|
if let Event::WindowEvent { event, .. } = event {
|
||||||
|
match event {
|
||||||
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
|
WindowEvent::TouchpadMagnify { delta, .. } => {
|
||||||
|
if delta > 0.0 {
|
||||||
|
println!("Zoomed in {}", delta);
|
||||||
|
} else {
|
||||||
|
println!("Zoomed out {}", delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WindowEvent::TouchpadRotate { delta, .. } => {
|
||||||
|
if delta > 0.0 {
|
||||||
|
println!("Rotated counterclockwise {}", delta);
|
||||||
|
} else {
|
||||||
|
println!("Rotated clockwise {}", delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
64
src/event.rs
64
src/event.rs
|
@ -426,6 +426,34 @@ pub enum WindowEvent<'a> {
|
||||||
modifiers: ModifiersState,
|
modifiers: ModifiersState,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Touchpad magnification event with two-finger pinch gesture.
|
||||||
|
///
|
||||||
|
/// Positive delta values indicate magnification (zooming in) and
|
||||||
|
/// negative delta values indicate shrinking (zooming out).
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - Only available on **macOS**.
|
||||||
|
TouchpadMagnify {
|
||||||
|
device_id: DeviceId,
|
||||||
|
delta: f64,
|
||||||
|
phase: TouchPhase,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Touchpad rotation event with two-finger rotation gesture.
|
||||||
|
///
|
||||||
|
/// Positive delta values indicate rotation counterclockwise and
|
||||||
|
/// negative delta values indicate rotation clockwise.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - Only available on **macOS**.
|
||||||
|
TouchpadRotate {
|
||||||
|
device_id: DeviceId,
|
||||||
|
delta: f32,
|
||||||
|
phase: TouchPhase,
|
||||||
|
},
|
||||||
|
|
||||||
/// Touchpad pressure event.
|
/// Touchpad pressure event.
|
||||||
///
|
///
|
||||||
/// At the moment, only supported on Apple forcetouch-capable macbooks.
|
/// At the moment, only supported on Apple forcetouch-capable macbooks.
|
||||||
|
@ -549,6 +577,24 @@ impl Clone for WindowEvent<'static> {
|
||||||
button: *button,
|
button: *button,
|
||||||
modifiers: *modifiers,
|
modifiers: *modifiers,
|
||||||
},
|
},
|
||||||
|
TouchpadMagnify {
|
||||||
|
device_id,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
} => TouchpadMagnify {
|
||||||
|
device_id: *device_id,
|
||||||
|
delta: *delta,
|
||||||
|
phase: *phase,
|
||||||
|
},
|
||||||
|
TouchpadRotate {
|
||||||
|
device_id,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
} => TouchpadRotate {
|
||||||
|
device_id: *device_id,
|
||||||
|
delta: *delta,
|
||||||
|
phase: *phase,
|
||||||
|
},
|
||||||
TouchpadPressure {
|
TouchpadPressure {
|
||||||
device_id,
|
device_id,
|
||||||
pressure,
|
pressure,
|
||||||
|
@ -637,6 +683,24 @@ impl<'a> WindowEvent<'a> {
|
||||||
button,
|
button,
|
||||||
modifiers,
|
modifiers,
|
||||||
}),
|
}),
|
||||||
|
TouchpadMagnify {
|
||||||
|
device_id,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
} => Some(TouchpadMagnify {
|
||||||
|
device_id,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
}),
|
||||||
|
TouchpadRotate {
|
||||||
|
device_id,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
} => Some(TouchpadRotate {
|
||||||
|
device_id,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
}),
|
||||||
TouchpadPressure {
|
TouchpadPressure {
|
||||||
device_id,
|
device_id,
|
||||||
pressure,
|
pressure,
|
||||||
|
|
|
@ -301,6 +301,14 @@ static VIEW_CLASS: Lazy<ViewClass> = Lazy::new(|| unsafe {
|
||||||
sel!(scrollWheel:),
|
sel!(scrollWheel:),
|
||||||
scroll_wheel as extern "C" fn(&Object, Sel, id),
|
scroll_wheel as extern "C" fn(&Object, Sel, id),
|
||||||
);
|
);
|
||||||
|
decl.add_method(
|
||||||
|
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(
|
decl.add_method(
|
||||||
sel!(pressureChangeWithEvent:),
|
sel!(pressureChangeWithEvent:),
|
||||||
pressure_change_with_event as extern "C" fn(&Object, Sel, id),
|
pressure_change_with_event as extern "C" fn(&Object, Sel, id),
|
||||||
|
@ -1196,6 +1204,64 @@ extern "C" fn scroll_wheel(this: &Object, _sel: Sel, event: id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn magnify_with_event(this: &Object, _sel: Sel, event: id) {
|
||||||
|
trace_scope!("magnifyWithEvent:");
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let state_ptr: *mut c_void = *this.get_ivar("winitState");
|
||||||
|
let state = &mut *(state_ptr as *mut ViewState);
|
||||||
|
|
||||||
|
let delta = event.magnification();
|
||||||
|
let phase = match event.phase() {
|
||||||
|
NSEventPhase::NSEventPhaseBegan => TouchPhase::Started,
|
||||||
|
NSEventPhase::NSEventPhaseChanged => TouchPhase::Moved,
|
||||||
|
NSEventPhase::NSEventPhaseCancelled => TouchPhase::Cancelled,
|
||||||
|
NSEventPhase::NSEventPhaseEnded => TouchPhase::Ended,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let window_event = Event::WindowEvent {
|
||||||
|
window_id: WindowId(get_window_id(state.ns_window)),
|
||||||
|
event: WindowEvent::TouchpadMagnify {
|
||||||
|
device_id: DEVICE_ID,
|
||||||
|
delta,
|
||||||
|
phase,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
AppState::queue_event(EventWrapper::StaticEvent(window_event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" fn rotate_with_event(this: &Object, _sel: Sel, event: id) {
|
||||||
|
trace_scope!("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::NSEventPhaseCancelled => TouchPhase::Cancelled,
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn pressure_change_with_event(this: &Object, _sel: Sel, event: id) {
|
extern "C" fn pressure_change_with_event(this: &Object, _sel: Sel, event: id) {
|
||||||
trace_scope!("pressureChangeWithEvent:");
|
trace_scope!("pressureChangeWithEvent:");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue