feat: pointer scroll events

This commit is contained in:
drendog 2025-12-22 09:39:10 +01:00
parent 573f9606ea
commit 53dc2e7218
Signed by: dwenya
GPG key ID: 8DD77074645332D0
4 changed files with 132 additions and 2 deletions

View file

@ -243,6 +243,33 @@ impl Dispatch<WlPointer, ()> for AppState {
surface.handle_pointer_button(serial, button_state);
}
}
wl_pointer::Event::AxisSource { axis_source } => {
if let (Some(surface), WEnum::Value(axis_source)) =
(state.active_surface_mut(), axis_source)
{
surface.handle_axis_source(axis_source);
}
}
wl_pointer::Event::Axis { time, axis, value } => {
if let (Some(surface), WEnum::Value(axis)) = (state.active_surface_mut(), axis) {
surface.handle_axis(time, axis, value);
}
}
wl_pointer::Event::AxisDiscrete { axis, discrete } => {
if let (Some(surface), WEnum::Value(axis)) = (state.active_surface_mut(), axis) {
surface.handle_axis_discrete(axis, discrete);
}
}
wl_pointer::Event::AxisStop { time, axis } => {
if let (Some(surface), WEnum::Value(axis)) = (state.active_surface_mut(), axis) {
surface.handle_axis_stop(time, axis);
}
}
wl_pointer::Event::Frame => {
if let Some(surface) = state.active_surface_mut() {
surface.handle_pointer_frame();
}
}
_ => {}
}
}

View file

@ -138,6 +138,34 @@ impl SurfaceState {
self.dispatch_to_active_window(event);
}
pub(crate) fn handle_axis_source(&mut self, axis_source: wl_pointer::AxisSource) {
self.set_axis_source(axis_source);
}
pub(crate) fn handle_axis(&mut self, _time: u32, axis: wl_pointer::Axis, value: f64) {
self.accumulate_axis(axis, value);
}
pub(crate) fn handle_axis_discrete(&mut self, axis: wl_pointer::Axis, discrete: i32) {
self.accumulate_axis_discrete(axis, discrete);
}
#[allow(clippy::unused_self)]
pub(crate) fn handle_axis_stop(&mut self, _time: u32, _axis: wl_pointer::Axis) {}
pub(crate) fn handle_pointer_frame(&mut self) {
let (delta_x, delta_y) = self.take_accumulated_axis();
if delta_x.abs() > f32::EPSILON || delta_y.abs() > f32::EPSILON {
let position = self.current_pointer_position();
self.dispatch_to_active_window(WindowEvent::PointerScrolled {
position,
delta_x,
delta_y,
});
}
}
pub(crate) fn handle_fractional_scale(&mut self, proxy: &WpFractionalScaleV1, scale: u32) {
use crate::wayland::surfaces::display_metrics::DisplayMetrics;
let scale_float = DisplayMetrics::scale_factor_from_120ths(scale);

View file

@ -5,7 +5,11 @@ use slint::platform::{WindowAdapter, WindowEvent};
use slint::{LogicalPosition, PhysicalSize};
use std::cell::Cell;
use std::rc::Rc;
use wayland_client::{Proxy, backend::ObjectId, protocol::wl_surface::WlSurface};
use wayland_client::{
Proxy,
backend::ObjectId,
protocol::{wl_pointer, wl_surface::WlSurface},
};
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1;
pub struct SharedPointerSerial {
@ -43,6 +47,9 @@ pub struct EventContext {
last_pointer_serial: u32,
shared_pointer_serial: Option<Rc<SharedPointerSerial>>,
active_surface: ActiveWindow,
accumulated_axis_x: f32,
accumulated_axis_y: f32,
axis_source: Option<wl_pointer::AxisSource>,
}
impl EventContext {
@ -61,6 +68,9 @@ impl EventContext {
last_pointer_serial: 0,
shared_pointer_serial: None,
active_surface: ActiveWindow::None,
accumulated_axis_x: 0.0,
accumulated_axis_y: 0.0,
axis_source: None,
}
}
@ -157,6 +167,7 @@ impl EventContext {
WindowEvent::PointerMoved { .. }
| WindowEvent::PointerPressed { .. }
| WindowEvent::PointerReleased { .. }
| WindowEvent::PointerScrolled { .. }
);
if let Some(popup_manager) = &self.popup_manager {
@ -188,4 +199,47 @@ impl EventContext {
.update_scale_for_fractional_scale_object(fractional_scale_proxy, scale_120ths);
}
}
pub fn set_axis_source(&mut self, axis_source: wl_pointer::AxisSource) {
self.axis_source = Some(axis_source);
}
#[allow(clippy::cast_possible_truncation)]
pub fn accumulate_axis(&mut self, axis: wl_pointer::Axis, value: f64) {
match axis {
wl_pointer::Axis::HorizontalScroll => {
self.accumulated_axis_x += value as f32;
}
wl_pointer::Axis::VerticalScroll => {
self.accumulated_axis_y += value as f32;
}
_ => {}
}
}
#[allow(clippy::cast_precision_loss)]
pub fn accumulate_axis_discrete(&mut self, axis: wl_pointer::Axis, discrete: i32) {
let delta = discrete as f32 * 60.0;
match axis {
wl_pointer::Axis::HorizontalScroll => {
self.accumulated_axis_x += delta;
}
wl_pointer::Axis::VerticalScroll => {
self.accumulated_axis_y += delta;
}
_ => {}
}
}
pub fn take_accumulated_axis(&mut self) -> (f32, f32) {
let delta_x = self.accumulated_axis_x;
let delta_y = self.accumulated_axis_y;
self.accumulated_axis_x = 0.0;
self.accumulated_axis_y = 0.0;
self.axis_source = None;
(delta_x, delta_y)
}
}

View file

@ -20,7 +20,10 @@ use slint::{LogicalPosition, PhysicalSize};
use slint::platform::WindowEvent;
use slint_interpreter::{ComponentInstance, CompilationResult};
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
use wayland_client::{protocol::wl_surface::WlSurface, Proxy};
use wayland_client::{
Proxy,
protocol::{wl_pointer, wl_surface::WlSurface},
};
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1;
pub struct SurfaceState {
@ -272,6 +275,24 @@ impl SurfaceState {
self.event_context.borrow().dispatch_to_active_window(event);
}
pub fn set_axis_source(&self, axis_source: wl_pointer::AxisSource) {
self.event_context.borrow_mut().set_axis_source(axis_source);
}
pub fn accumulate_axis(&self, axis: wl_pointer::Axis, value: f64) {
self.event_context.borrow_mut().accumulate_axis(axis, value);
}
pub fn accumulate_axis_discrete(&self, axis: wl_pointer::Axis, discrete: i32) {
self.event_context
.borrow_mut()
.accumulate_axis_discrete(axis, discrete);
}
pub fn take_accumulated_axis(&self) -> (f32, f32) {
self.event_context.borrow_mut().take_accumulated_axis()
}
#[allow(clippy::cast_precision_loss)]
pub fn update_scale_for_fractional_scale_object(
&mut self,