Skip to content

Commit

Permalink
implement proper touch
Browse files Browse the repository at this point in the history
  • Loading branch information
cmeissl committed Feb 13, 2024
1 parent e340717 commit 110d66f
Show file tree
Hide file tree
Showing 36 changed files with 2,432 additions and 390 deletions.
104 changes: 101 additions & 3 deletions anvil/src/focus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ pub use smithay::{
};
use smithay::{
desktop::Window,
input::pointer::{
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent, GesturePinchEndEvent,
GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
input::{
pointer::{
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent, GesturePinchEndEvent,
GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
},
touch::TouchTarget,
},
};

Expand Down Expand Up @@ -349,6 +352,101 @@ impl<BackendData: Backend> KeyboardTarget<AnvilState<BackendData>> for KeyboardF
}
}

impl<BackendData: Backend> TouchTarget<AnvilState<BackendData>> for PointerFocusTarget {
fn down(
&self,
seat: &Seat<AnvilState<BackendData>>,
data: &mut AnvilState<BackendData>,
event: &smithay::input::touch::DownEvent,
seq: Serial,
) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::down(w, seat, data, event, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::down(w, seat, data, event, seq),
PointerFocusTarget::SSD(w) => TouchTarget::down(w, seat, data, event, seq),
}
}

fn up(
&self,
seat: &Seat<AnvilState<BackendData>>,
data: &mut AnvilState<BackendData>,
event: &smithay::input::touch::UpEvent,
seq: Serial,
) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::up(w, seat, data, event, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::up(w, seat, data, event, seq),
PointerFocusTarget::SSD(w) => TouchTarget::up(w, seat, data, event, seq),
}
}

fn motion(
&self,
seat: &Seat<AnvilState<BackendData>>,
data: &mut AnvilState<BackendData>,
event: &smithay::input::touch::MotionEvent,
seq: Serial,
) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::motion(w, seat, data, event, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::motion(w, seat, data, event, seq),
PointerFocusTarget::SSD(w) => TouchTarget::motion(w, seat, data, event, seq),
}
}

fn frame(&self, seat: &Seat<AnvilState<BackendData>>, data: &mut AnvilState<BackendData>, seq: Serial) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::frame(w, seat, data, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::frame(w, seat, data, seq),
PointerFocusTarget::SSD(w) => TouchTarget::frame(w, seat, data, seq),
}
}

fn cancel(&self, seat: &Seat<AnvilState<BackendData>>, data: &mut AnvilState<BackendData>, seq: Serial) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::cancel(w, seat, data, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::cancel(w, seat, data, seq),
PointerFocusTarget::SSD(w) => TouchTarget::cancel(w, seat, data, seq),
}
}

fn shape(
&self,
seat: &Seat<AnvilState<BackendData>>,
data: &mut AnvilState<BackendData>,
event: &smithay::input::touch::ShapeEvent,
seq: Serial,
) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::shape(w, seat, data, event, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::shape(w, seat, data, event, seq),
PointerFocusTarget::SSD(w) => TouchTarget::shape(w, seat, data, event, seq),
}
}

fn orientation(
&self,
seat: &Seat<AnvilState<BackendData>>,
data: &mut AnvilState<BackendData>,
event: &smithay::input::touch::OrientationEvent,
seq: Serial,
) {
match self {
PointerFocusTarget::WlSurface(w) => TouchTarget::orientation(w, seat, data, event, seq),
#[cfg(feature = "xwayland")]
PointerFocusTarget::X11Surface(w) => TouchTarget::orientation(w, seat, data, event, seq),
PointerFocusTarget::SSD(w) => TouchTarget::orientation(w, seat, data, event, seq),
}
}
}

impl WaylandFocus for PointerFocusTarget {
fn wl_surface(&self) -> Option<WlSurface> {
match self {
Expand Down
125 changes: 119 additions & 6 deletions anvil/src/input_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,17 @@ use smithay::{
input::{
Device, DeviceCapability, GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _,
GestureSwipeUpdateEvent as _, PointerMotionEvent, ProximityState, TabletToolButtonEvent,
TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState,
TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent,
},
session::Session,
},
input::pointer::{
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent, GesturePinchEndEvent,
GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
RelativeMotionEvent,
input::{
pointer::{
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent, GesturePinchEndEvent,
GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
RelativeMotionEvent,
},
touch::{DownEvent, UpEvent},
},
wayland::{
pointer_constraints::{with_pointer_constraint, PointerConstraint},
Expand Down Expand Up @@ -257,6 +260,7 @@ impl<BackendData: Backend> AnvilState<BackendData> {

fn update_keyboard_focus(&mut self, location: Point<f64, Logical>, serial: Serial) {
let keyboard = self.seat.get_keyboard().unwrap();
let touch = self.seat.get_touch();
let input_method = self.seat.input_method();
// change the keyboard focus unless the pointer or keyboard is grabbed
// We test for any matching surface type here but always use the root
Expand All @@ -267,7 +271,10 @@ impl<BackendData: Backend> AnvilState<BackendData> {
// subsurface menus (for example firefox-wayland).
// see here for a discussion about that issue:
// https://gitlab.freedesktop.org/wayland/wayland/-/issues/294
if !self.pointer.is_grabbed() && (!keyboard.is_grabbed() || input_method.keyboard_grabbed()) {
if !self.pointer.is_grabbed()
&& (!keyboard.is_grabbed() || input_method.keyboard_grabbed())
&& !touch.map(|touch| touch.is_grabbed()).unwrap_or(false)
{
let output = self.space.output_under(location).next().cloned();
if let Some(output) = output.as_ref() {
let output_geo = self.space.output_geometry(output).unwrap();
Expand Down Expand Up @@ -756,12 +763,22 @@ impl AnvilState<UdevData> {
InputEvent::GesturePinchEnd { event, .. } => self.on_gesture_pinch_end::<B>(event),
InputEvent::GestureHoldBegin { event, .. } => self.on_gesture_hold_begin::<B>(event),
InputEvent::GestureHoldEnd { event, .. } => self.on_gesture_hold_end::<B>(event),

InputEvent::TouchDown { event } => self.on_touch_down::<B>(event),
InputEvent::TouchUp { event } => self.on_touch_up::<B>(event),
InputEvent::TouchMotion { event } => self.on_touch_motion::<B>(event),
InputEvent::TouchFrame { event } => self.on_touch_frame::<B>(event),
InputEvent::TouchCancel { event } => self.on_touch_cancel::<B>(event),

InputEvent::DeviceAdded { device } => {
if device.has_capability(DeviceCapability::TabletTool) {
self.seat
.tablet_seat()
.add_tablet::<Self>(dh, &TabletDescriptor::from(&device));
}
if device.has_capability(DeviceCapability::Touch) && self.seat.get_touch().is_none() {
self.seat.add_touch();
}
}
InputEvent::DeviceRemoved { device } => {
if device.has_capability(DeviceCapability::TabletTool) {
Expand Down Expand Up @@ -1173,6 +1190,102 @@ impl AnvilState<UdevData> {
);
}

fn touch_location_transformed<B: InputBackend, E: AbsolutePositionEvent<B>>(
&self,
evt: &E,
) -> Option<Point<f64, Logical>> {
let output = self
.space
.outputs()
.find(|output| output.name().starts_with("eDP"))
.or_else(|| self.space.outputs().next());

let Some(output) = output else {
return None;
};

let Some(output_geometry) = self.space.output_geometry(output) else {
return None;
};

let transform = output.current_transform();
let size = transform.invert().transform_size(output_geometry.size);
Some(
transform.transform_point_in(evt.position_transformed(size), &size.to_f64())
+ output_geometry.loc.to_f64(),
)
}

fn on_touch_down<B: InputBackend>(&mut self, evt: B::TouchDownEvent) {
let Some(handle) = self.seat.get_touch() else {
return;
};

let Some(touch_location) = self.touch_location_transformed(&evt) else {
return;
};

let serial = SCOUNTER.next_serial();
self.update_keyboard_focus(touch_location, serial);

let under = self.surface_under(touch_location);
handle.down(
self,
under,
&DownEvent {
slot: evt.slot(),
location: touch_location,
serial,
time: evt.time_msec(),
},
);
}
fn on_touch_up<B: InputBackend>(&mut self, evt: B::TouchUpEvent) {
let Some(handle) = self.seat.get_touch() else {
return;
};
let serial = SCOUNTER.next_serial();
handle.up(
self,
&UpEvent {
slot: evt.slot(),
serial,
time: evt.time_msec(),
},
)
}
fn on_touch_motion<B: InputBackend>(&mut self, evt: B::TouchMotionEvent) {
let Some(handle) = self.seat.get_touch() else {
return;
};
let Some(touch_location) = self.touch_location_transformed(&evt) else {
return;
};

let under = self.surface_under(touch_location);
handle.motion(
self,
under,
&smithay::input::touch::MotionEvent {
slot: evt.slot(),
location: touch_location,
time: evt.time_msec(),
},
);
}
fn on_touch_frame<B: InputBackend>(&mut self, _evt: B::TouchFrameEvent) {
let Some(handle) = self.seat.get_touch() else {
return;
};
handle.frame(self);
}
fn on_touch_cancel<B: InputBackend>(&mut self, _evt: B::TouchCancelEvent) {
let Some(handle) = self.seat.get_touch() else {
return;
};
handle.cancel(self);
}

fn clamp_coords(&self, pos: Point<f64, Logical>) -> Point<f64, Logical> {
if self.space.outputs().next().is_none() {
return pos;
Expand Down
65 changes: 65 additions & 0 deletions anvil/src/shell/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use smithay::{
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent,
GestureSwipeUpdateEvent, MotionEvent, PointerTarget, RelativeMotionEvent,
},
touch::TouchTarget,
Seat,
},
output::Output,
Expand Down Expand Up @@ -316,6 +317,70 @@ impl<Backend: crate::state::Backend> PointerTarget<AnvilState<Backend>> for SSD
}
}

impl<Backend: crate::state::Backend> TouchTarget<AnvilState<Backend>> for SSD {
fn down(
&self,
seat: &Seat<AnvilState<Backend>>,
data: &mut AnvilState<Backend>,
event: &smithay::input::touch::DownEvent,
_seq: Serial,
) {
let mut state = self.0.decoration_state();
if state.is_ssd {
state.header_bar.pointer_enter(event.location);
state.header_bar.touch_down(seat, data, &self.0, event.serial);
}
}

fn up(
&self,
seat: &Seat<AnvilState<Backend>>,
data: &mut AnvilState<Backend>,
event: &smithay::input::touch::UpEvent,
_seq: Serial,
) {
let mut state = self.0.decoration_state();
if state.is_ssd {
state.header_bar.touch_up(seat, data, &self.0, event.serial);
}
}

fn motion(
&self,
_seat: &Seat<AnvilState<Backend>>,
_data: &mut AnvilState<Backend>,
event: &smithay::input::touch::MotionEvent,
_seq: Serial,
) {
let mut state = self.0.decoration_state();
if state.is_ssd {
state.header_bar.pointer_enter(event.location);
}
}

fn frame(&self, _seat: &Seat<AnvilState<Backend>>, _data: &mut AnvilState<Backend>, _seq: Serial) {}

fn cancel(&self, _seat: &Seat<AnvilState<Backend>>, _data: &mut AnvilState<Backend>, _seq: Serial) {}

fn shape(
&self,
_seat: &Seat<AnvilState<Backend>>,
_data: &mut AnvilState<Backend>,
_event: &smithay::input::touch::ShapeEvent,
_seq: Serial,
) {
}

fn orientation(
&self,
_seat: &Seat<AnvilState<Backend>>,
_data: &mut AnvilState<Backend>,
_event: &smithay::input::touch::OrientationEvent,
_seq: Serial,
) {
}
}

impl SpaceElement for WindowElement {
fn geometry(&self) -> Rectangle<i32, Logical> {
let mut geo = match self {
Expand Down
Loading

0 comments on commit 110d66f

Please sign in to comment.