Skip to content

Commit

Permalink
add InputBackend extensions; hook up Device::output() to motion_absolute
Browse files Browse the repository at this point in the history
  • Loading branch information
sodiboo committed Nov 23, 2024
1 parent 118d360 commit d19f77f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 15 deletions.
44 changes: 44 additions & 0 deletions src/input/backend_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use ::input as libinput;
use smithay::backend::input;
use smithay::backend::winit::WinitVirtualDevice;
use smithay::output::Output;

use crate::protocols::virtual_pointer::VirtualPointer;

pub trait NiriInputBackend: input::InputBackend<Device = Self::NiriDevice> {
type NiriDevice: NiriInputDevice;
}
impl<T: input::InputBackend> NiriInputBackend for T
where
Self::Device: NiriInputDevice,
{
type NiriDevice = Self::Device;
}

pub trait NiriInputDevice: input::Device {
// FIXME: should this be per-event? logically yes,
// but right now we only use it for virtual pointers, which have static outputs.
fn output(&self) -> Option<Output>;
}

impl NiriInputDevice for libinput::Device {
fn output(&self) -> Option<Output> {
// FIXME: Allow specifying the output per-device?
// In that case, change the method to take a reference to our state or config or something
// (because we can't easily change the libinput Device struct)
None
}
}

impl NiriInputDevice for WinitVirtualDevice {
fn output(&self) -> Option<Output> {
// here it's actually *correct* to return None, because there is only one output.
None
}
}

impl NiriInputDevice for VirtualPointer {
fn output(&self) -> Option<Output> {
self.output().cloned()
}
}
39 changes: 28 additions & 11 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use niri_ipc::LayoutSwitchTarget;
use smithay::backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _,
InputBackend, InputEvent, KeyState, KeyboardKeyEvent, Keycode, MouseButton, PointerAxisEvent,
InputEvent, KeyState, KeyboardKeyEvent, Keycode, MouseButton, PointerAxisEvent,
PointerButtonEvent, PointerMotionEvent, ProximityState, Switch, SwitchState, SwitchToggleEvent,
TabletToolButtonEvent, TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent,
TabletToolTipState, TouchEvent,
Expand All @@ -28,6 +28,7 @@ use smithay::input::touch::{
DownEvent, GrabStartData as TouchGrabStartData, MotionEvent as TouchMotionEvent, UpEvent,
};
use smithay::input::SeatHandler;
use smithay::output::Output;
use smithay::utils::{Logical, Point, Rectangle, Transform, SERIAL_COUNTER};
use smithay::wayland::keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitor;
use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraint};
Expand All @@ -42,6 +43,7 @@ use crate::ui::screenshot_ui::ScreenshotUi;
use crate::utils::spawning::spawn;
use crate::utils::{center, get_monotonic_time, ResizeEdge};

pub mod backend_ext;
pub mod move_grab;
pub mod resize_grab;
pub mod scroll_tracker;
Expand All @@ -50,6 +52,8 @@ pub mod swipe_tracker;
pub mod touch_move_grab;
pub mod touch_resize_grab;

use backend_ext::{NiriInputBackend as InputBackend, NiriInputDevice as _};

pub const DOUBLE_CLICK_TIME: Duration = Duration::from_millis(400);

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -267,8 +271,10 @@ impl State {
where
I::Device: 'static,
{
let device_output = event.device().output();
let device_output = device_output.as_ref();
let (target_geo, keep_ratio, px, transform) =
if let Some(output) = self.niri.output_for_tablet() {
if let Some(output) = device_output.or_else(|| self.niri.output_for_tablet()) {
(
self.niri.global_space.output_geometry(output).unwrap(),
true,
Expand Down Expand Up @@ -1517,12 +1523,14 @@ impl State {
&mut self,
event: I::PointerMotionAbsoluteEvent,
) {
let Some(output_geo) = self.global_bounding_rectangle() else {
let Some(pos) = self.compute_absolute_location(&event, None).or_else(|| {
self.global_bounding_rectangle().map(|output_geo| {
event.position_transformed(output_geo.size) + output_geo.loc.to_f64()
})
}) else {
return;
};

let pos = event.position_transformed(output_geo.size) + output_geo.loc.to_f64();

let serial = SERIAL_COUNTER.next_serial();

let pointer = self.niri.seat.get_pointer().unwrap();
Expand Down Expand Up @@ -2362,14 +2370,13 @@ impl State {
);
}

/// Computes the cursor position for the touch event.
///
/// This function handles the touch output mapping, as well as coordinate transform
fn compute_touch_location<I: InputBackend, E: AbsolutePositionEvent<I>>(
fn compute_absolute_location<I: InputBackend>(
&self,
evt: &E,
evt: &impl AbsolutePositionEvent<I>,
fallback_output: Option<&Output>,
) -> Option<Point<f64, Logical>> {
let output = self.niri.output_for_touch()?;
let output = evt.device().output();
let output = output.as_ref().or(fallback_output)?;
let output_geo = self.niri.global_space.output_geometry(output).unwrap();
let transform = output.current_transform();
let size = transform.invert().transform_size(output_geo.size);
Expand All @@ -2379,6 +2386,16 @@ impl State {
)
}

/// Computes the cursor position for the touch event.
///
/// This function handles the touch output mapping, as well as coordinate transform
fn compute_touch_location<I: InputBackend>(
&self,
evt: &impl AbsolutePositionEvent<I>,
) -> Option<Point<f64, Logical>> {
self.compute_absolute_location(evt, self.niri.output_for_touch())
}

fn on_touch_down<I: InputBackend>(&mut self, evt: I::TouchDownEvent) {
let Some(handle) = self.niri.seat.get_touch() else {
return;
Expand Down
8 changes: 4 additions & 4 deletions src/protocols/virtual_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use smithay::backend::input::{
PointerMotionAbsoluteEvent, PointerMotionEvent, UnusedEvent,
};
use smithay::input::pointer::AxisFrame;
use smithay::output::Output;
use smithay::reexports::wayland_protocols_wlr;
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
use smithay::reexports::wayland_server::protocol::wl_pointer;
use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat;
use smithay::reexports::wayland_server::{
Expand Down Expand Up @@ -41,7 +41,7 @@ pub struct VirtualPointer {
#[derive(Debug)]
pub struct VirtualPointerUserData {
seat: Option<WlSeat>,
output: Option<WlOutput>,
output: Option<Output>,

axis_frame: Mutex<Option<AxisFrame>>,
}
Expand All @@ -55,7 +55,7 @@ impl VirtualPointer {
self.data().seat.as_ref()
}

pub fn output(&self) -> Option<&WlOutput> {
pub fn output(&self) -> Option<&Output> {
self.data().output.as_ref()
}

Expand Down Expand Up @@ -355,7 +355,7 @@ where
seat,
output,
id,
} => (id, seat, output),
} => (id, seat, output.as_ref().and_then(Output::from_resource)),
zwlr_virtual_pointer_manager_v1::Request::Destroy => return,
_ => unreachable!(),
};
Expand Down

0 comments on commit d19f77f

Please sign in to comment.