Commit 9529672263b7
tarball5 files changed+89-18
@@ -4,6 +4,7 @@
44
55
use crate::backend::{Backend, logical_area};66
use crate::devices::Devices;7
+use crate::input::Motion;78
use crate::scene::Draw;89
use crate::state::Services;910
use crate::state::{State, now_ns};@@ -1148,8 +1149,9 @@ fn on_input(state: &mut State, event: InputEvent<LibinputInputBackend>) {
11481149
state.key(event.key_code(), event.state(), time);11491150
}11501151
InputEvent::PointerMotion { event } => {1151
- let pos = clamp(state, state.input.pointer_pos + event.delta());1152
- state.pointer_to(pos, event.time());1152
+ let (delta, unaccel) = (event.delta(), event.delta_unaccel());1153
+ let pos = clamp(state, state.input.pointer_pos + delta);1154
+ state.pointer_motion(pos, Motion::Relative { delta, unaccel }, event.time());11531155
state.pointer_frame();11541156
state.dirty.cursor = true;11551157
}@@ -1166,7 +1168,7 @@ fn on_input(state: &mut State, event: InputEvent<LibinputInputBackend>) {
11661168
};11671169
let p = event.position_transformed((area.w as i32, area.h as i32).into());11681170
let pos = clamp(state, Point::from((area.x + p.x, area.y + p.y)));1169
- state.pointer_to(pos, event.time());1171
+ state.pointer_motion(pos, Motion::Absolute, event.time());11701172
state.pointer_frame();11711173
state.dirty.cursor = true;11721174
}@@ -22,6 +22,7 @@ use smithay::wayland::image_capture_source::{
2222
use smithay::wayland::image_copy_capture::ImageCopyCaptureState;2323
use smithay::wayland::output::OutputManagerState;2424
use smithay::wayland::presentation::PresentationState;25
+use smithay::wayland::relative_pointer::RelativePointerManagerState;2526
use smithay::wayland::selection::data_device::DataDeviceState;2627
use smithay::wayland::selection::ext_data_control::DataControlState as ExtDataControlState;2728
use smithay::wayland::selection::primary_selection::PrimarySelectionState;@@ -70,6 +71,7 @@ pub struct Protocols {
7071
_single_pixel_buffer: SinglePixelBufferState,7172
_fractional_scale: FractionalScaleManagerState,7273
_presentation: PresentationState,74
+ _relative_pointer: RelativePointerManagerState,7375
}7476
7577
impl Protocols {@@ -134,6 +136,7 @@ impl Protocols {
134136
_single_pixel_buffer: SinglePixelBufferState::new::<State>(dh),135137
_fractional_scale: FractionalScaleManagerState::new::<State>(dh),136138
_presentation: PresentationState::new::<State>(dh, Monotonic::ID as u32),139
+ _relative_pointer: RelativePointerManagerState::new::<State>(dh),137140
}138141
}139142
}@@ -7,15 +7,41 @@ use monolith_layout::{Axis, Dir, Layout, MIN_FLOAT_SIZE, Rect, WindowId, clamp_f
77
use smithay::backend::input::{ButtonState, InputTime, KeyState};88
use smithay::backend::session::Session;99
use smithay::input::keyboard::{FilterResult, Keycode, xkb};10
-use smithay::input::pointer::{AxisFrame, ButtonEvent, CursorIcon, CursorImageStatus, MotionEvent};10
+use smithay::input::pointer::{11
+ AxisFrame, ButtonEvent, CursorIcon, CursorImageStatus, MotionEvent, RelativeMotionEvent,12
+};1113
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;1214
use smithay::reexports::wayland_server::Resource;15
+use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;1316
use smithay::utils::{Logical, Point, SERIAL_COUNTER};1417
use smithay::wayland::shell::wlr_layer::Layer;1518
use smithay::xwayland::xwm::ResizeEdge;1619
20
+/// How the pointer got to where a motion wants it.21
+pub enum Motion {22
+ Relative {23
+ delta: Point<f64, Logical>,24
+ unaccel: Point<f64, Logical>,25
+ },26
+ Absolute,27
+ Warp,28
+}29
+1730
impl State {18
- pub fn pointer_to(&mut self, pos: Point<f64, Logical>, time: InputTime) {31
+ pub fn pointer_motion(&mut self, wanted: Point<f64, Logical>, motion: Motion, time: InputTime) {32
+ let (delta, unaccel) = match motion {33
+ Motion::Relative { delta, unaccel } => {34
+ self.input.absolute = None;35
+ (delta, unaccel)36
+ }37
+ Motion::Absolute => {38
+ let from = self.input.absolute.replace(wanted);39
+ let delta = wanted - from.unwrap_or(self.input.pointer_pos);40
+ (delta, delta)41
+ }42
+ Motion::Warp => Default::default(),43
+ };44
+ let pos = wanted;1945
self.input.pointer_pos = pos;2046
self.follow_pointer_scale();2147
self.activity();@@ -32,6 +58,7 @@ impl State {
3258
if std::mem::replace(&mut self.input.hover, hover) != hover {3359
self.dirty.cursor = true;3460
}61
+ self.relative_motion(under.clone(), delta, unaccel, time);3562
pointer.motion(3663
self,3764
under,@@ -48,6 +75,36 @@ impl State {
4875
}4976
}5077
78
+ fn relative_motion(79
+ &mut self,80
+ under: Option<(WlSurface, Point<f64, Logical>)>,81
+ delta: Point<f64, Logical>,82
+ unaccel: Point<f64, Logical>,83
+ time: InputTime,84
+ ) {85
+ if delta == Point::default() && unaccel == Point::default() {86
+ return;87
+ }88
+ if let Some(pointer) = self.input.seat.get_pointer() {89
+ let event = RelativeMotionEvent {90
+ delta,91
+ delta_unaccel: unaccel,92
+ time,93
+ };94
+ pointer.relative_motion(self, under, &event);95
+ }96
+ }97
+98
+ /// Puts the pointer somewhere without telling clients it moved, which a99
+ /// relative motion would, and without letting focus follow it.100
+ pub fn warp_pointer(&mut self, pos: Point<f64, Logical>, time: InputTime) {101
+ self.input.warping = true;102
+ self.pointer_motion(pos, Motion::Warp, time);103
+ self.input.warping = false;104
+ self.pointer_frame();105
+ self.dirty.cursor = true;106
+ }107
+51108
pub fn pointer_button(&mut self, button: u32, pressed: ButtonState, time: InputTime) {52109
self.activity();53110
if pressed == ButtonState::Released {@@ -246,14 +303,10 @@ impl State {
246303
let Some((_, r, _)) = focused.and_then(|id| self.wm.get(id)?.placed) else {247304
return;248305
};249
- self.input.warping = true;250
- self.pointer_to(306
+ self.warp_pointer(251307
Point::from((r.x + r.w / 2.0, r.y + r.h / 2.0)),252308
InputTime::now(),253309
);254
- self.input.warping = false;255
- self.pointer_frame();256
- self.dirty.cursor = true;257310
}258311
}259312
@@ -1,13 +1,22 @@
11
//! The host seat, forwarded into monolith's own.22
3
+use crate::input::Motion;34
use crate::state::State;45
use smithay::backend::input::{Axis, ButtonState, InputTime, KeyState};56
use smithay::input::keyboard::Keycode;67
use smithay::input::pointer::AxisFrame;7
-use smithay::utils::Point;8
+use smithay::utils::{Logical, Point};89
use wayland_client::protocol::{wl_keyboard, wl_pointer, wl_seat};910
use wayland_client::{Connection, Dispatch, QueueHandle, WEnum};1011
12
+fn host_position(state: &State, x: f64, y: f64) -> Point<f64, Logical> {13
+ let scale = state14
+ .backend15
+ .nested()16
+ .map_or(1.0, |h| h.output.current_scale().fractional_scale());17
+ Point::from((x / scale, y / scale))18
+}19
+1120
impl Dispatch<wl_seat::WlSeat, ()> for State {1221
fn event(1322
_: &mut Self,@@ -46,18 +55,18 @@ impl Dispatch<wl_pointer::WlPointer, ()> for State {
4655
surface_x,4756
surface_y,4857
..58
+ } => {59
+ let pos = host_position(state, surface_x, surface_y);60
+ state.input.absolute = Some(pos);61
+ state.pointer_motion(pos, Motion::Absolute, time);4962
}50
- | wl_pointer::Event::Motion {63
+ wl_pointer::Event::Motion {5164
surface_x,5265
surface_y,5366
..5467
} => {55
- let scale = state56
- .backend57
- .nested()58
- .map_or(1.0, |h| h.output.current_scale().fractional_scale());59
- let pos = Point::from((surface_x / scale, surface_y / scale));60
- state.pointer_to(pos, time);68
+ let pos = host_position(state, surface_x, surface_y);69
+ state.pointer_motion(pos, Motion::Absolute, time);6170
}6271
wl_pointer::Event::Button {6372
button,@@ -65,6 +65,9 @@ pub struct Input {
6565
pub hover: Option<crate::input::Edges>,6666
/// The output the pointer was last on, whose scale cursor and drag icon surfaces follow.6767
pub pointer_output: Option<String>,68
+ /// Where the last absolute device event put the pointer, so the next69
+ /// one yields a relative delta even while the pointer is held in place.70
+ pub absolute: Option<Point<f64, Logical>>,6871
}6972
7073
/// What needs doing after this batch of events.@@ -198,6 +201,7 @@ impl State {
198201
dnd_icon: None,199202
hover: None,200203
pointer_output: None,204
+ absolute: None,201205
},202206
dirty: Dirty {203207
redraw: true,