8000 Fix scrolling across platforms by TheRedDeveloper · Pull Request #661 · not-fl3/miniquad · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion js/gl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,15 @@ var importObject = {
canvas.addEventListener('wheel',
function (event) {
event.preventDefault();
wasm_exports.mouse_wheel(-event.deltaX, -event.deltaY);
var scale = 1.0;
if (event.deltaMode === 1) { // DOM_DELTA_LINE
scale = 1.0 / 3.0;
} else if (event.deltaMode === 2) { // DOM_DELTA_PAGE
scale = 10.0;
} else { // DOM_DELTA_PIXEL
scale = 1.0 / 100.0;
}
wasm_exports.mouse_wheel(-event.deltaX * scale, -event.deltaY * scale);
});
canvas. (event) {
var relative_position = mouse_relative_position(event.clientX, event.clientY);
Expand Down
92 changes: 81 additions & 11 deletions src/native/linux_wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct WaylandPayload {
viewporter: *mut extensions::viewporter::wp_viewporter,
shm: *mut wl_shm,
seat: *mut wl_seat,
seat_version: u32,
data_device_manager: *mut wl_data_device_manager,
data_device: *mut wl_data_device,
xkb_context: *mut xkb_context,
Expand Down Expand Up @@ -327,6 +328,9 @@ struct PointerContext {
locked_pointer: *mut extensions::cursor::zwp_locked_pointer_v1,
relative_pointer_manager: *mut extensions::cursor::zwp_relative_pointer_manager_v1,
relative_pointer: *mut extensions::cursor::zwp_relative_pointer_v1,
axis_v120: (Option<f32>, Option<f32>),
axis_discrete: (Option<f32>, Option<f32>),
axis_value: (Option<f32>, Option<f32>),
}
impl PointerContext {
fn new() -> Self {
Expand All @@ -342,6 +346,9 @@ impl PointerContext {
locked_pointer: std::ptr::null_mut(),
relative_pointer_manager: std::ptr::null_mut(),
relative_pointer: std::ptr::null_mut(),
axis_v120: (None, None),
axis_discrete: (None, None),
axis_value: (None, None),
}
}
unsafe fn set_cursor_with_serial(
Expand Down Expand Up @@ -481,6 +488,9 @@ unsafe extern "C" fn seat_handle_capabilities(
POINTER_LISTENER.motion = pointer_handle_motion;
POINTER_LISTENER.button = pointer_handle_button;
POINTER_LISTENER.leave = pointer_handle_leave;
POINTER_LISTENER.frame = pointer_handle_frame;
POINTER_LISTENER.axis_discrete = pointer_handle_axis_discrete;
POINTER_LISTENER.axis_value120 = pointer_handle_axis_value120;
(display.client.wl_proxy_add_listener)(
display.pointer_context.pointer as _,
&POINTER_LISTENER as *const _ as _,
Expand Down Expand Up @@ -744,6 +754,36 @@ unsafe extern "C" fn pointer_handle_button(
.push(WaylandEvent::PointerButton(button, state == 1));
}
}
unsafe extern "C" fn pointer_handle_axis_value120(
data: *mut ::core::ffi::c_void,
_wl_pointer: *mut wl_pointer,
axis: u32,
value120: i32,
) {
let display: &mut WaylandPayload = &mut *(data as *mut _);
let delta = (value120 as f32) / 120.0;
if axis == 0 {
display.pointer_context.axis_v120.1 = Some(-delta);
} else if axis == 1 {
display.pointer_context.axis_v120.0 = Some(-delta);
}
}

unsafe extern "C" fn pointer_handle_axis_discrete(
data: *mut ::core::ffi::c_void,
_wl_pointer: *mut wl_pointer,
axis: u32,
discrete: i32,
) {
let display: &mut WaylandPayload = &mut *(data as *mut _);
let delta = discrete as f32;
if axis == 0 {
display.pointer_context.axis_discrete.1 = Some(-delta);
} else if axis == 1 {
display.pointer_context.axis_discrete.0 = Some(-delta);
}
}

unsafe extern "C" fn pointer_handle_axis(
data: *mut ::core::ffi::c_void,
_wl_pointer: *mut wl_pointer,
Expand All @@ -752,16 +792,44 @@ unsafe extern "C" fn pointer_handle_axis(
value: i32,
) {
let display: &mut WaylandPayload = &mut *(data as *mut _);
let mut value = wl_fixed_to_double(value);
// https://wayland-book.com/seat/pointer.html
if axis == 0 {
// Vertical scroll
// Wayland defines the direction differently to miniquad so lets flip it
value = -value;
display.events.push(WaylandEvent::PointerAxis(0.0, value));
} else if axis == 1 {
// Horizontal scroll
display.events.push(WaylandEvent::PointerAxis(value, 0.0));
let value = (wl_fixed_to_double(value) as f32) / 15.0;
if display.seat_version < 5 {
if axis == 0 {
display.events.push(WaylandEvent::PointerAxis(0.0, -value));
} else if axis == 1 {
display.events.push(WaylandEvent::PointerAxis(-value, 0.0));
}
} else {
if axis == 0 {
display.pointer_context.axis_value.1 = Some(-value);
} else if axis == 1 {
display.pointer_context.axis_value.0 = Some(-value);
}
}
}

unsafe extern "C" fn pointer_handle_frame(
data: *mut ::core::ffi::c_void,
_wl_pointer: *mut wl_pointer,
) {
let display: &mut WaylandPayload = &mut *(data as *mut _);
let ctx = &mut d 8000 isplay.pointer_context;

let scroll_x = ctx.axis_v120.0
.or(ctx.axis_discrete.0)
.or(ctx.axis_value.0)
.unwrap_or(0.0);
let scroll_y = ctx.axis_v120.1
.or(ctx.axis_discrete.1)
.or(ctx.axis_value.1)
.unwrap_or(0.0);

ctx.axis_v120 = (None, None);
ctx.axis_discrete = (None, None);
ctx.axis_value = (None, None);

if scroll_x != 0.0 || scroll_y != 0.0 {
display.events.push(WaylandEvent::PointerAxis(scroll_x, scroll_y));
}
}

Expand Down Expand Up @@ -987,7 +1055,8 @@ unsafe extern "C" fn registry_add_object(
as _;
}
"wl_seat" => {
let seat_version = 4.min(version);
let seat_version = 8.min(version);
display.seat_version = seat_version;
display.seat = display.client.wl_registry_bind(
registry,
name,
Expand Down Expand Up @@ -1086,6 +1155,7 @@ where
viewporter: std::ptr::null_mut(),
shm: std::ptr::null_mut(),
seat: std::ptr::null_mut(),
seat_version: 0,
data_device_manager: std::ptr::null_mut(),
data_device: std::ptr::null_mut(),
xkb_context,
Expand Down
63 changes: 46 additions & 17 deletions src/native/linux_x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
cursor_visible: bool,
update_requested: bool,
drag_n_drop: drag_n_drop::X11DnD,
scroll_valuators: HashMap<(i32, i32), xi_input::ScrollValuator>,
has_smooth_scrolling: bool,
last_xi_scroll_time: Option<std::time::Instant>,
}

impl X11Display {
Expand Down Expand Up @@ -95,20 +98,26 @@
if btn != crate::event::MouseButton::Unknown {
event_handler.mouse_button_down_event(btn, x, y);
} else {
match event.xbutton.button {
4 => {
event_handler.mouse_wheel_event(0.0, 1.0);
}
5 => {
event_handler.mouse_wheel_event(0.0, -1.0);
}
6 => {
event_handler.mouse_wheel_event(1.0, 0.0);
}
7 => {
event_handler.mouse_wheel_event(-1.0, 0.0);
let is_duplicate_xi = self
.last_xi_scroll_time
.map(|t| t.elapsed().as_millis() < 25)
.unwrap_or(false);
if !is_duplicate_xi {
match event.xbutton.button {
4 => {
event_handler.mouse_wheel_event(0.0, 1.0);
}
5 => {
event_handler.mouse_wheel_event(0.0, -1.0);
}
6 => {
event_handler.mouse_wheel_event(1.0, 0.0);
}
7 => {
event_handler.mouse_wheel_event(-1.0, 0.0);
}
_ => {}
}
_ => {}
}
}
}
Expand Down Expand Up @@ -247,6 +256,13 @@
if event.xcookie.evtype == xi_input::XI_RawMotion {
let (dx, dy) = self.libxi.read_cookie(&mut event.xcookie, self.display);
event_handler.raw_mouse_motion(dx as f32, dy as f32);
} else if event.xcookie.evtype == xi_input::XI_Motion {
let (dx, dy, x, y) = self.libxi.read_motion_cookie(&mut event.xcookie, self.display, &mut self.scroll_valuators);
event_handler.mouse_motion_event(x as f32, y as f32);
if dx != 0.0 || dy != 0.0 {
self.last_xi_scroll_time = Some(std::time::Instant::now());
event_handler.mouse_wheel_event(dx as f32, dy as f32);
}
}
}
_ => {}
Expand Down Expand Up @@ -464,6 +480,13 @@
.libx11
.create_window(display.root, display.display, visual, depth, conf);

display.has_smooth_scrolling = display.libxi.query_xi_extension(
&mut display.libx11,
display.display,
display.window,
&mut display.scroll_valuators,
);

let (glx_context, glx_window) = glx.create_context(display.display, display.window);
glx.swap_interval(
display.display,
Expand Down Expand Up @@ -558,6 +581,13 @@
.libx11
.create_window(display.root, display.display, std::ptr::null_mut(), 0, conf);

display.has_smooth_scrolling = display.libxi.query_xi_extension(
&mut display.libx11,
display.display,
display.window,
&mut display.scroll_valuators,
);

let (context, config, egl_display) = egl::create_egl_context(
&mut egl_lib,
display.display as *mut _,
Expand Down Expand Up @@ -681,7 +711,7 @@
(libx11.XkbSetDetectableAutoRepeat)(x11_display, true as _, std::ptr::null_mut());

libx11.load_extensions(x11_display);
let mut display = X11Display {

Check warning on line 714 in src/native/linux_x11.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, x86_64-unknown-linux-gnu)

variable does not need to be mutable

Check warning on line 714 in src/native/linux_x11.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, armv7-unknown-linux-gnueabihf)

variable does not need to be mutable

Check warning on line 714 in src/native/linux_x11.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, aarch64-unknown-linux-gnu)

variable does not need to be mutable
empty_cursor: x_cursor::create_empty_cursor(x11_display, x11_root, &mut libx11),
display: x11_display,
root: x11_root,
Expand All @@ -695,12 +725,11 @@
drag_n_drop: Default::default(),
cursor_icon: CursorIcon::Default,
cursor_visible: true,
scroll_valuators: HashMap::new(),
has_smooth_scrolling: false,
last_xi_scroll_time: None,
};

display
.libxi
.query_xi_extension(&mut display.libx11, display.display);

match conf.platform.linux_x11_gl {
crate::conf::LinuxX11Gl::GLXOnly => {
glx_main_loop(display, conf, f, x11_screen).ok().unwrap();
Expand Down
Loading
Loading
0