1
0
Fork 0
forked from wry/wry

wayland: implement wl_seat v8

This commit is contained in:
Julian Orth 2022-05-27 15:39:48 +02:00
parent 145e4dbc24
commit 50c87d6da7
10 changed files with 111 additions and 80 deletions

View file

@ -148,6 +148,8 @@ pub enum AxisSource {
Continuous = CONTINUOUS as _, Continuous = CONTINUOUS as _,
} }
pub const AXIS_120: i32 = 120;
#[derive(Debug)] #[derive(Debug)]
pub enum InputEvent { pub enum InputEvent {
Key { Key {
@ -174,7 +176,7 @@ pub enum InputEvent {
state: KeyState, state: KeyState,
}, },
Axis { AxisSmooth {
dist: Fixed, dist: Fixed,
axis: ScrollAxis, axis: ScrollAxis,
}, },
@ -184,7 +186,7 @@ pub enum InputEvent {
AxisStop { AxisStop {
axis: ScrollAxis, axis: ScrollAxis,
}, },
AxisDiscrete { Axis120 {
dist: i32, dist: i32,
axis: ScrollAxis, axis: ScrollAxis,
}, },

View file

@ -3,7 +3,6 @@ use {
backend::{AxisSource, InputEvent, KeyState, ScrollAxis}, backend::{AxisSource, InputEvent, KeyState, ScrollAxis},
backends::metal::MetalBackend, backends::metal::MetalBackend,
fixed::Fixed, fixed::Fixed,
ifs::wl_seat::PX_PER_SCROLL,
libinput::{ libinput::{
consts::{ consts::{
LIBINPUT_BUTTON_STATE_PRESSED, LIBINPUT_KEY_STATE_PRESSED, LIBINPUT_BUTTON_STATE_PRESSED, LIBINPUT_KEY_STATE_PRESSED,
@ -127,7 +126,6 @@ impl MetalBackend {
} }
fn handle_pointer_axis(self: &Rc<Self>, event: LibInputEvent, source: AxisSource) { fn handle_pointer_axis(self: &Rc<Self>, event: LibInputEvent, source: AxisSource) {
const ONE_TWENTRY: f64 = 120.0;
let (event, dev) = unpack!(self, event, pointer_event); let (event, dev) = unpack!(self, event, pointer_event);
let axes = [ let axes = [
( (
@ -137,30 +135,28 @@ impl MetalBackend {
(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical), (LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical),
]; ];
dev.event(InputEvent::AxisSource { source }); dev.event(InputEvent::AxisSource { source });
for (axis, sa) in axes { for (pointer_axis, axis) in axes {
if !event.has_axis(axis) { if !event.has_axis(pointer_axis) {
continue; continue;
} }
let mut scroll = match source { let scroll = match source {
AxisSource::Wheel => event.scroll_value_v120(axis), AxisSource::Wheel => event.scroll_value_v120(pointer_axis),
_ => event.scroll_value(axis), _ => event.scroll_value(pointer_axis),
}; };
if scroll == 0.0 { let ie = if scroll == 0.0 {
dev.event(InputEvent::AxisStop { axis: sa }); InputEvent::AxisStop { axis }
} else { } else if source == AxisSource::Wheel {
if source == AxisSource::Wheel { InputEvent::Axis120 {
let scroll_discrete = scroll / ONE_TWENTRY; dist: scroll as _,
dev.event(InputEvent::AxisDiscrete { axis,
dist: scroll_discrete as _,
axis: sa,
});
scroll = PX_PER_SCROLL * scroll_discrete;
} }
dev.event(InputEvent::Axis { } else {
InputEvent::AxisSmooth {
dist: Fixed::from_f64(scroll), dist: Fixed::from_f64(scroll),
axis: sa, axis,
}); }
} };
dev.event(ie);
} }
dev.event(InputEvent::AxisFrame { dev.event(InputEvent::AxisFrame {
time_usec: event.time_usec(), time_usec: event.time_usec(),

View file

@ -5,11 +5,10 @@ use {
AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId,
ConnectorKernelId, DrmDeviceId, InputDevice, InputDeviceAccelProfile, ConnectorKernelId, DrmDeviceId, InputDevice, InputDeviceAccelProfile,
InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo,
ScrollAxis, TransformMatrix, ScrollAxis, TransformMatrix, AXIS_120,
}, },
fixed::Fixed, fixed::Fixed,
format::XRGB8888, format::XRGB8888,
ifs::wl_seat::PX_PER_SCROLL,
render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture}, render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture},
state::State, state::State,
time::now_usec, time::now_usec,
@ -765,9 +764,8 @@ impl XBackend {
seat.mouse_event(InputEvent::AxisSource { seat.mouse_event(InputEvent::AxisSource {
source: AxisSource::Wheel, source: AxisSource::Wheel,
}); });
seat.mouse_event(InputEvent::AxisDiscrete { dist: val, axis }); seat.mouse_event(InputEvent::Axis120 {
seat.mouse_event(InputEvent::Axis { dist: val * AXIS_120,
dist: Fixed::from_f64(val as f64 * PX_PER_SCROLL),
axis, axis,
}); });
seat.mouse_event(InputEvent::AxisFrame { seat.mouse_event(InputEvent::AxisFrame {

View file

@ -729,7 +729,7 @@ impl Global for WlSeatGlobal {
} }
fn version(&self) -> u32 { fn version(&self) -> u32 {
7 8
} }
fn break_loops(&self) { fn break_loops(&self) {

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
backend::{ConnectorId, InputEvent, KeyState}, backend::{ConnectorId, InputEvent, KeyState, AXIS_120},
client::{Client, ClientId}, client::{Client, ClientId},
fixed::Fixed, fixed::Fixed,
ifs::{ ifs::{
@ -16,10 +16,11 @@ use {
wl_pointer::{ wl_pointer::{
self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION, self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION,
AXIS_SOURCE_SINCE_VERSION, AXIS_STOP_SINCE_VERSION, AXIS_SOURCE_SINCE_VERSION, AXIS_STOP_SINCE_VERSION,
POINTER_FRAME_SINCE_VERSION, WHEEL_TILT, WHEEL_TILT_SINCE_VERSION, AXIS_VALUE120_SINCE_VERSION, POINTER_FRAME_SINCE_VERSION, WHEEL_TILT,
WHEEL_TILT_SINCE_VERSION,
}, },
zwp_relative_pointer_v1::ZwpRelativePointerV1, zwp_relative_pointer_v1::ZwpRelativePointerV1,
Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, PX_PER_SCROLL,
}, },
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface}, wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
}, },
@ -192,8 +193,8 @@ impl WlSeatGlobal {
} => self.pointer_owner.button(self, time_usec, button, state), } => self.pointer_owner.button(self, time_usec, button, state),
InputEvent::AxisSource { source } => self.pointer_owner.axis_source(source), InputEvent::AxisSource { source } => self.pointer_owner.axis_source(source),
InputEvent::AxisDiscrete { dist, axis } => self.pointer_owner.axis_discrete(dist, axis), InputEvent::Axis120 { dist, axis } => self.pointer_owner.axis_120(dist, axis),
InputEvent::Axis { dist, axis } => self.pointer_owner.axis(dist, axis), InputEvent::AxisSmooth { dist, axis } => self.pointer_owner.axis_smooth(dist, axis),
InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis), InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis),
InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(self, time_usec), InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(self, time_usec),
} }
@ -546,22 +547,28 @@ impl WlSeatGlobal {
self.surface_pointer_event(since, surface, |p| p.send_axis_source(source)); self.surface_pointer_event(since, surface, |p| p.send_axis_source(source));
} }
let time = (event.time_usec.get() / 1000) as _; let time = (event.time_usec.get() / 1000) as _;
for i in 0..1 { self.for_each_pointer(0, surface.client.id, |p| {
if let Some(delta) = event.discrete[i].get() { for i in 0..1 {
self.surface_pointer_event(AXIS_DISCRETE_SINCE_VERSION, surface, |p| { let axis = i as _;
p.send_axis_discrete(i as _, delta) if let Some(delta) = event.v120[i].get() {
}); if p.seat.version >= AXIS_VALUE120_SINCE_VERSION {
p.send_axis_value120(axis, delta);
} else if p.seat.version >= AXIS_DISCRETE_SINCE_VERSION {
p.send_axis_discrete(axis, delta / AXIS_120);
}
let px = (delta as f64 / AXIS_120 as f64) * PX_PER_SCROLL;
p.send_axis(time, axis, Fixed::from_f64(px));
} else if let Some(delta) = event.smooth[i].get() {
p.send_axis(time, axis, delta);
}
if p.seat.version >= AXIS_STOP_SINCE_VERSION && event.stop[i].get() {
p.send_axis_stop(time, axis);
}
} }
if let Some(delta) = event.axis[i].get() { if p.seat.version >= POINTER_FRAME_SINCE_VERSION {
self.surface_pointer_event(0, surface, |p| p.send_axis(time, i as _, delta)); p.send_frame();
} }
if event.stop[i].get() { });
self.surface_pointer_event(AXIS_STOP_SINCE_VERSION, surface, |p| {
p.send_axis_stop(time, i as _)
});
}
}
self.surface_pointer_frame(surface);
} }
} }

View file

@ -39,12 +39,12 @@ impl PointerOwnerHolder {
self.pending_scroll.source.set(Some(axis_source as _)); self.pending_scroll.source.set(Some(axis_source as _));
} }
pub fn axis_discrete(&self, delta: i32, axis: ScrollAxis) { pub fn axis_120(&self, delta: i32, axis: ScrollAxis) {
self.pending_scroll.discrete[axis as usize].set(Some(delta)); self.pending_scroll.v120[axis as usize].set(Some(delta));
} }
pub fn axis(&self, delta: Fixed, axis: ScrollAxis) { pub fn axis_smooth(&self, delta: Fixed, axis: ScrollAxis) {
self.pending_scroll.axis[axis as usize].set(Some(delta)); self.pending_scroll.smooth[axis as usize].set(Some(delta));
} }
pub fn axis_stop(&self, axis: ScrollAxis) { pub fn axis_stop(&self, axis: ScrollAxis) {

View file

@ -33,11 +33,12 @@ pub const AXIS_SOURCE_SINCE_VERSION: u32 = 5;
pub const AXIS_DISCRETE_SINCE_VERSION: u32 = 5; pub const AXIS_DISCRETE_SINCE_VERSION: u32 = 5;
pub const AXIS_STOP_SINCE_VERSION: u32 = 5; pub const AXIS_STOP_SINCE_VERSION: u32 = 5;
pub const WHEEL_TILT_SINCE_VERSION: u32 = 6; pub const WHEEL_TILT_SINCE_VERSION: u32 = 6;
pub const AXIS_VALUE120_SINCE_VERSION: u32 = 8;
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct PendingScroll { pub struct PendingScroll {
pub discrete: [Cell<Option<i32>>; 2], pub v120: [Cell<Option<i32>>; 2],
pub axis: [Cell<Option<Fixed>>; 2], pub smooth: [Cell<Option<Fixed>>; 2],
pub stop: [Cell<bool>; 2], pub stop: [Cell<bool>; 2],
pub source: Cell<Option<u32>>, pub source: Cell<Option<u32>>,
pub time_usec: Cell<u64>, pub time_usec: Cell<u64>,
@ -46,13 +47,13 @@ pub struct PendingScroll {
impl PendingScroll { impl PendingScroll {
pub fn take(&self) -> Self { pub fn take(&self) -> Self {
Self { Self {
discrete: [ v120: [
Cell::new(self.discrete[0].take()), Cell::new(self.v120[0].take()),
Cell::new(self.discrete[1].take()), Cell::new(self.v120[1].take()),
], ],
axis: [ smooth: [
Cell::new(self.axis[0].take()), Cell::new(self.smooth[0].take()),
Cell::new(self.axis[1].take()), Cell::new(self.smooth[1].take()),
], ],
stop: [ stop: [
Cell::new(self.stop[0].take()), Cell::new(self.stop[0].take()),
@ -156,6 +157,14 @@ impl WlPointer {
}) })
} }
pub fn send_axis_value120(&self, axis: u32, value120: i32) {
self.seat.client.event(AxisValue120 {
self_id: self.id,
axis,
value120,
})
}
fn set_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), WlPointerError> { fn set_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), WlPointerError> {
let req: SetCursor = self.seat.client.parse(self, parser)?; let req: SetCursor = self.seat.client.parse(self, parser)?;
if !self.seat.client.valid_serial(req.serial) { if !self.seat.client.valid_serial(req.serial) {

View file

@ -307,12 +307,8 @@ impl TestBackendMouse {
self.common.event(InputEvent::AxisSource { self.common.event(InputEvent::AxisSource {
source: AxisSource::Wheel, source: AxisSource::Wheel,
}); });
self.common.event(InputEvent::AxisDiscrete { self.common.event(InputEvent::Axis120 {
dist: dy, dist: dy * 120,
axis: ScrollAxis::Vertical,
});
self.common.event(InputEvent::Axis {
dist: Fixed::from_int(dy * 15),
axis: ScrollAxis::Vertical, axis: ScrollAxis::Vertical,
}); });
self.common.event(InputEvent::AxisFrame { self.common.event(InputEvent::AxisFrame {
@ -324,7 +320,7 @@ impl TestBackendMouse {
self.common.event(InputEvent::AxisSource { self.common.event(InputEvent::AxisSource {
source: AxisSource::Wheel, source: AxisSource::Wheel,
}); });
self.common.event(InputEvent::Axis { self.common.event(InputEvent::AxisSmooth {
dist: Fixed::from_int(dy), dist: Fixed::from_int(dy),
axis: ScrollAxis::Vertical, axis: ScrollAxis::Vertical,
}); });

View file

@ -1,27 +1,45 @@
use { use {
crate::ifs::wl_seat::{ crate::{
wl_pointer::{PendingScroll, VERTICAL_SCROLL}, backend::AXIS_120,
PX_PER_SCROLL, ifs::wl_seat::{
wl_pointer::{PendingScroll, VERTICAL_SCROLL},
PX_PER_SCROLL,
},
}, },
std::cell::Cell, std::cell::Cell,
}; };
#[derive(Default)] #[derive(Default)]
pub struct Scroller { pub struct Scroller {
scroll: Cell<f64>, v120: Cell<i32>,
smooth: Cell<f64>,
} }
impl Scroller { impl Scroller {
pub fn handle(&self, scroll: &PendingScroll) -> Option<i32> { pub fn handle(&self, scroll: &PendingScroll) -> Option<i32> {
if let Some(d) = scroll.discrete[VERTICAL_SCROLL as usize].get() { let n = if let Some(d) = scroll.v120[VERTICAL_SCROLL as usize].get() {
self.scroll.set(0.0); self.smooth.set(0.0);
Some(d) let mut v120 = self.v120.get() + d;
} else if let Some(scroll) = scroll.axis[VERTICAL_SCROLL as usize].get() { let discrete = v120 / AXIS_120;
let mut scroll = self.scroll.get() + scroll.to_f64(); v120 -= discrete * AXIS_120;
let discrete = (scroll / PX_PER_SCROLL).trunc(); self.v120.set(v120);
scroll -= discrete * PX_PER_SCROLL; discrete
self.scroll.set(scroll); } else if let Some(smooth) = scroll.smooth[VERTICAL_SCROLL as usize].get() {
Some(discrete as i32) self.v120.set(0);
let mut smooth = self.smooth.get() + smooth.to_f64();
let discrete = (smooth / PX_PER_SCROLL).trunc();
smooth -= discrete * PX_PER_SCROLL;
self.smooth.set(smooth);
discrete as _
} else {
0
};
if scroll.stop[VERTICAL_SCROLL as usize].get() {
self.v120.set(0);
self.smooth.set(0.0);
}
if n != 0 {
Some(n)
} else { } else {
None None
} }

View file

@ -61,3 +61,8 @@ msg axis_discrete = 8 {
axis: u32, axis: u32,
discrete: i32, discrete: i32,
} }
msg axis_value120 = 9 {
axis: u32,
value120: i32,
}