1
0
Fork 0
forked from wry/wry

wayland: implement wl_touch

Co-authored-by: Julian Orth <ju.orth@gmail.com>
This commit is contained in:
Amine Hassane 2024-04-21 14:48:26 +01:00 committed by Julian Orth
parent 905e2dd7ba
commit 681c1ad033
35 changed files with 1071 additions and 52 deletions

View file

@ -66,7 +66,7 @@ impl Global for JayCompositorGlobal {
}
fn version(&self) -> u32 {
3
4
}
fn required_caps(&self) -> ClientCaps {
@ -336,7 +336,7 @@ impl JayCompositorRequestHandler for JayCompositor {
}
fn get_input(&self, req: GetInput, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let sc = Rc::new(JayInput::new(req.id, &self.client));
let sc = Rc::new(JayInput::new(req.id, &self.client, self.version));
track!(self.client, sc);
self.client.add_client_obj(&sc)?;
Ok(())

View file

@ -24,14 +24,18 @@ pub struct JayInput {
pub id: JayInputId,
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
pub version: Version,
}
const CALIBRATION_MATRIX_SINCE: Version = Version(4);
impl JayInput {
pub fn new(id: JayInputId, client: &Rc<Client>) -> Self {
pub fn new(id: JayInputId, client: &Rc<Client>, version: Version) -> Self {
Self {
id,
client: client.clone(),
tracker: Default::default(),
version,
}
}
@ -138,6 +142,19 @@ impl JayInput {
});
}
}
if self.version >= CALIBRATION_MATRIX_SINCE {
if let Some(m) = dev.calibration_matrix() {
self.client.event(CalibrationMatrix {
self_id: self.id,
m00: m[0][0],
m01: m[0][1],
m02: m[0][2],
m10: m[1][0],
m11: m[1][1],
m12: m[1][2],
});
}
}
}
fn device(&self, id: u32) -> Result<Rc<DeviceHandlerData>, JayInputError> {
@ -424,11 +441,24 @@ impl JayInputRequestHandler for JayInput {
Ok(())
})
}
fn set_calibration_matrix(
&self,
req: SetCalibrationMatrix,
_slf: &Rc<Self>,
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.device
.set_calibration_matrix([[req.m00, req.m01, req.m02], [req.m10, req.m11, req.m12]]);
Ok(())
})
}
}
object_base! {
self = JayInput;
version = Version(1);
version = self.version;
}
impl Object for JayInput {}

View file

@ -468,6 +468,46 @@ impl JaySeatEvents {
ring,
});
}
pub fn send_touch_down(&self, seat: SeatId, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
self.client.event(TouchDown {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
x,
y,
});
}
pub fn send_touch_up(&self, seat: SeatId, time_usec: u64, id: i32) {
self.client.event(TouchUp {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
});
}
pub fn send_touch_motion(&self, seat: SeatId, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
self.client.event(TouchMotion {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
x,
y,
});
}
pub fn send_touch_cancel(&self, seat: SeatId, time_usec: u64, id: i32) {
self.client.event(TouchCancel {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
});
}
}
impl JaySeatEventsRequestHandler for JaySeatEvents {

View file

@ -6,6 +6,7 @@ mod kb_owner;
mod pointer_owner;
pub mod tablet;
pub mod text_input;
mod touch_owner;
pub mod wl_keyboard;
pub mod wl_pointer;
pub mod wl_touch;
@ -52,6 +53,7 @@ use {
zwp_input_method_keyboard_grab_v2::ZwpInputMethodKeyboardGrabV2,
zwp_input_method_v2::ZwpInputMethodV2, zwp_text_input_v3::ZwpTextInputV3,
},
touch_owner::TouchOwnerHolder,
wl_keyboard::{WlKeyboard, WlKeyboardError, REPEAT_INFO_SINCE},
wl_pointer::WlPointer,
wl_touch::WlTouch,
@ -79,7 +81,7 @@ use {
},
wire::{
wl_seat::*, ExtIdleNotificationV1Id, WlDataDeviceId, WlKeyboardId, WlPointerId,
WlSeatId, ZwlrDataControlDeviceV1Id, ZwpPrimarySelectionDeviceV1Id,
WlSeatId, WlTouchId, ZwlrDataControlDeviceV1Id, ZwpPrimarySelectionDeviceV1Id,
ZwpRelativePointerV1Id, ZwpTextInputV3Id,
},
xkbcommon::{DynKeyboardState, KeyboardState, KeymapId, XkbKeymap, XkbState},
@ -103,7 +105,6 @@ pub use {
pub const POINTER: u32 = 1;
const KEYBOARD: u32 = 2;
#[allow(dead_code)]
const TOUCH: u32 = 4;
#[allow(dead_code)]
@ -142,6 +143,8 @@ pub struct WlSeatGlobal {
name: GlobalName,
state: Rc<State>,
seat_name: String,
capabilities: Cell<u32>,
num_touch_devices: NumCell<u32>,
pos_time_usec: Cell<u64>,
pointer_stack: RefCell<Vec<Rc<dyn Node>>>,
pointer_stack_modified: Cell<bool>,
@ -173,6 +176,7 @@ pub struct WlSeatGlobal {
pointer_owner: PointerOwnerHolder,
kb_owner: KbOwnerHolder,
gesture_owner: GestureOwnerHolder,
touch_owner: TouchOwnerHolder,
dropped_dnd: RefCell<Option<DroppedDnd>>,
shortcuts: RefCell<AHashMap<u32, SmallMap<u32, u32, 2>>>,
queue_link: RefCell<Option<LinkedNode<Rc<Self>>>>,
@ -213,6 +217,8 @@ impl WlSeatGlobal {
name,
state: state.clone(),
seat_name: seat_name.to_string(),
capabilities: Cell::new(0),
num_touch_devices: Default::default(),
pos_time_usec: Cell::new(0),
pointer_stack: RefCell::new(vec![]),
pointer_stack_modified: Cell::new(false),
@ -237,6 +243,7 @@ impl WlSeatGlobal {
pointer_owner: Default::default(),
kb_owner: Default::default(),
gesture_owner: Default::default(),
touch_owner: Default::default(),
dropped_dnd: RefCell::new(None),
shortcuts: Default::default(),
queue_link: Default::default(),
@ -269,9 +276,24 @@ impl WlSeatGlobal {
}
});
slf.tree_changed_handler.set(Some(future));
slf.update_capabilities();
slf
}
fn update_capabilities(&self) {
let mut caps = POINTER | KEYBOARD;
if self.num_touch_devices.get() > 0 {
caps |= TOUCH;
}
if self.capabilities.replace(caps) != caps {
for client in self.bindings.borrow().values() {
for seat in client.values() {
seat.send_capabilities();
}
}
}
}
pub fn keymap(&self) -> Rc<XkbKeymap> {
self.seat_kb_map.get()
}
@ -852,6 +874,7 @@ impl WlSeatGlobal {
self.primary_selection.set(None);
self.pointer_owner.clear();
self.kb_owner.clear();
self.touch_owner.clear();
*self.dropped_dnd.borrow_mut() = None;
self.queue_link.take();
self.tree_changed_handler.set(None);
@ -888,6 +911,7 @@ impl WlSeatGlobal {
pointers: Default::default(),
relative_pointers: Default::default(),
keyboards: Default::default(),
touches: Default::default(),
version,
tracker: Default::default(),
});
@ -994,6 +1018,7 @@ pub struct WlSeat {
pointers: CopyHashMap<WlPointerId, Rc<WlPointer>>,
relative_pointers: CopyHashMap<ZwpRelativePointerV1Id, Rc<ZwpRelativePointerV1>>,
keyboards: CopyHashMap<WlKeyboardId, Rc<WlKeyboard>>,
touches: CopyHashMap<WlTouchId, Rc<WlTouch>>,
version: Version,
tracker: Tracker<Self>,
}
@ -1004,7 +1029,7 @@ impl WlSeat {
fn send_capabilities(self: &Rc<Self>) {
self.client.event(Capabilities {
self_id: self.id,
capabilities: POINTER | KEYBOARD,
capabilities: self.global.capabilities.get(),
})
}
@ -1059,6 +1084,7 @@ impl WlSeatRequestHandler for WlSeat {
let p = Rc::new(WlTouch::new(req.id, slf));
track!(self.client, p);
self.client.add_client_obj(&p)?;
self.touches.set(req.id, p);
Ok(())
}
@ -1096,6 +1122,7 @@ impl Object for WlSeat {
self.pointers.clear();
self.relative_pointers.clear();
self.keyboards.clear();
self.touches.clear();
}
}
@ -1146,6 +1173,10 @@ impl DeviceHandlerData {
if let Some(info) = &self.tablet_pad_init {
old.tablet_remove_tablet_pad(info.id);
}
if self.is_touch {
old.num_touch_devices.fetch_sub(1);
old.update_capabilities();
}
}
self.update_xkb_state();
if let Some(seat) = &seat {
@ -1155,6 +1186,10 @@ impl DeviceHandlerData {
if let Some(info) = &self.tablet_pad_init {
seat.tablet_add_tablet_pad(self.device.id(), info);
}
if self.is_touch {
seat.num_touch_devices.fetch_add(1);
seat.update_capabilities();
}
}
}

View file

@ -24,6 +24,7 @@ use {
AXIS_STOP_SINCE_VERSION, AXIS_VALUE120_SINCE_VERSION, IDENTICAL, INVERTED,
POINTER_FRAME_SINCE_VERSION, WHEEL_TILT, WHEEL_TILT_SINCE_VERSION,
},
wl_touch::WlTouch,
zwp_pointer_constraints_v1::{ConstraintType, SeatConstraintStatus},
zwp_relative_pointer_v1::ZwpRelativePointerV1,
Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, CHANGE_TREE,
@ -31,6 +32,7 @@ use {
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
},
object::Version,
rect::Rect,
state::DeviceHandlerData,
tree::{Direction, Node, ToplevelNode},
utils::{bitflags::BitflagsExt, hash_map_ext::HashMapExt, smallmap::SmallMap},
@ -54,6 +56,7 @@ pub struct NodeSeatState {
pointer_foci: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
kb_foci: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
gesture_foci: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
touch_foci: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
pointer_grabs: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
dnd_targets: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
tablet_pad_foci: SmallMap<TabletPadId, Rc<TabletPad>, 1>,
@ -111,6 +114,14 @@ impl NodeSeatState {
self.tablet_tool_foci.remove(&tool.id);
}
pub(super) fn touch_begin(&self, seat: &Rc<WlSeatGlobal>) {
self.touch_foci.insert(seat.id, seat.clone());
}
pub(super) fn touch_end(&self, seat: &WlSeatGlobal) {
self.touch_foci.remove(&seat.id);
}
pub(super) fn add_dnd_target(&self, seat: &Rc<WlSeatGlobal>) {
self.dnd_targets.insert(seat.id, seat.clone());
}
@ -184,6 +195,9 @@ impl NodeSeatState {
while let Some((_, pad)) = self.tablet_pad_foci.pop() {
pad.pad_owner.focus_root(&pad);
}
while let Some((_, seat)) = self.touch_foci.pop() {
seat.touch_owner.cancel(&seat);
}
self.release_kb_focus2(focus_last);
}
@ -230,7 +244,11 @@ impl WlSeatGlobal {
| InputEvent::TabletPadButton { time_usec, .. }
| InputEvent::TabletPadModeSwitch { time_usec, .. }
| InputEvent::TabletPadRing { time_usec, .. }
| InputEvent::TabletPadStrip { time_usec, .. } => {
| InputEvent::TabletPadStrip { time_usec, .. }
| InputEvent::TouchDown { time_usec, .. }
| InputEvent::TouchUp { time_usec, .. }
| InputEvent::TouchMotion { time_usec, .. }
| InputEvent::TouchCancel { time_usec, .. } => {
self.last_input_usec.set(time_usec);
if self.idle_notifications.is_not_empty() {
for notification in self.idle_notifications.lock().drain_values() {
@ -243,7 +261,8 @@ impl WlSeatGlobal {
| InputEvent::AxisStop { .. }
| InputEvent::Axis120 { .. }
| InputEvent::TabletToolAdded { .. }
| InputEvent::TabletToolRemoved { .. } => {}
| InputEvent::TabletToolRemoved { .. }
| InputEvent::TouchFrame => {}
}
match event {
InputEvent::ConnectorPosition { .. }
@ -274,6 +293,11 @@ impl WlSeatGlobal {
InputEvent::TabletPadModeSwitch { .. } => {}
InputEvent::TabletPadRing { .. } => {}
InputEvent::TabletPadStrip { .. } => {}
InputEvent::TouchDown { .. } => {}
InputEvent::TouchUp { .. } => {}
InputEvent::TouchMotion { .. } => {}
InputEvent::TouchCancel { .. } => {}
InputEvent::TouchFrame => {}
}
match event {
InputEvent::Key {
@ -407,6 +431,21 @@ impl WlSeatGlobal {
source,
position,
} => self.tablet_event_pad_strip(pad, strip, source, position, time_usec),
InputEvent::TouchDown {
time_usec,
id,
x_normed,
y_normed,
} => self.touch_down(time_usec, id, dev.get_rect(&self.state), x_normed, y_normed),
InputEvent::TouchUp { time_usec, id } => self.touch_up(time_usec, id),
InputEvent::TouchMotion {
time_usec,
id,
x_normed,
y_normed,
} => self.touch_motion(time_usec, id, dev.get_rect(&self.state), x_normed, y_normed),
InputEvent::TouchCancel { time_usec, id } => self.touch_cancel(time_usec, id),
InputEvent::TouchFrame => self.touch_frame(),
}
}
@ -613,6 +652,58 @@ impl WlSeatGlobal {
}
}
fn touch_down(
self: &Rc<Self>,
time_usec: u64,
id: i32,
rect: Rect,
x_normed: Fixed,
y_normed: Fixed,
) {
self.cursor_group().deactivate();
let x = Fixed::from_f64(rect.x1() as f64 + rect.width() as f64 * x_normed.to_f64());
let y = Fixed::from_f64(rect.y1() as f64 + rect.height() as f64 * y_normed.to_f64());
self.state.for_each_seat_tester(|t| {
t.send_touch_down(self.id, time_usec, id, x, y);
});
self.touch_owner.down(self, time_usec, id, x, y);
}
fn touch_up(self: &Rc<Self>, time_usec: u64, id: i32) {
self.state.for_each_seat_tester(|t| {
t.send_touch_up(self.id, time_usec, id);
});
self.touch_owner.up(self, time_usec, id);
}
fn touch_motion(
self: &Rc<Self>,
time_usec: u64,
id: i32,
rect: Rect,
x_normed: Fixed,
y_normed: Fixed,
) {
self.cursor_group().deactivate();
let x = Fixed::from_f64(rect.x1() as f64 + rect.width() as f64 * x_normed.to_f64());
let y = Fixed::from_f64(rect.y1() as f64 + rect.height() as f64 * y_normed.to_f64());
self.state.for_each_seat_tester(|t| {
t.send_touch_motion(self.id, time_usec, id, x, y);
});
self.touch_owner.motion(self, time_usec, id, x, y);
}
fn touch_cancel(self: &Rc<Self>, time_usec: u64, id: i32) {
self.state.for_each_seat_tester(|t| {
t.send_touch_cancel(self.id, time_usec, id);
});
self.touch_owner.cancel(self);
}
fn touch_frame(self: &Rc<Self>) {
self.touch_owner.frame(self);
}
pub(super) fn key_event<F>(
self: &Rc<Self>,
time_usec: u64,
@ -744,7 +835,7 @@ impl WlSeatGlobal {
self.kb_owner.set_kb_node(self, node);
}
fn for_each_seat<C>(&self, ver: Version, client: ClientId, mut f: C)
pub(super) fn for_each_seat<C>(&self, ver: Version, client: ClientId, mut f: C)
where
C: FnMut(&Rc<WlSeat>),
{
@ -794,6 +885,18 @@ impl WlSeatGlobal {
})
}
fn for_each_touch<C>(&self, ver: Version, client: ClientId, mut f: C)
where
C: FnMut(&Rc<WlTouch>),
{
self.for_each_seat(ver, client, |seat| {
let touches = seat.touches.lock();
for touch in touches.values() {
f(touch);
}
})
}
pub fn for_each_data_device<C>(&self, ver: Version, client: ClientId, mut f: C)
where
C: FnMut(&Rc<WlDataDevice>),
@ -869,6 +972,16 @@ impl WlSeatGlobal {
// client.flush();
}
pub fn surface_touch_event<F>(&self, ver: Version, surface: &WlSurface, mut f: F)
where
F: FnMut(&Rc<WlTouch>),
{
let client = &surface.client;
self.for_each_touch(ver, client.id, |p| {
f(p);
});
}
fn cursor_moved(self: &Rc<Self>, time_usec: u64) {
self.pos_time_usec.set(time_usec);
self.changes.or_assign(CHANGE_CURSOR_MOVED);
@ -1133,6 +1246,53 @@ impl WlSeatGlobal {
}
}
// Touch callbacks
impl WlSeatGlobal {
pub fn touch_down_surface(
self: &Rc<Self>,
surface: &WlSurface,
time_usec: u64,
id: i32,
x: Fixed,
y: Fixed,
) {
let serial = surface.client.next_serial();
let time = (time_usec / 1000) as _;
self.surface_touch_event(Version::ALL, surface, |t| {
t.send_down(serial, time, surface.id, id, x, y)
});
if let Some(node) = surface.get_focus_node(self.id) {
self.focus_node(node);
}
}
pub fn touch_up_surface(&self, surface: &WlSurface, time_usec: u64, id: i32) {
let serial = surface.client.next_serial();
let time = (time_usec / 1000) as _;
self.surface_touch_event(Version::ALL, surface, |t| t.send_up(serial, time, id))
}
pub fn touch_motion_surface(
&self,
surface: &WlSurface,
time_usec: u64,
id: i32,
x: Fixed,
y: Fixed,
) {
let time = (time_usec / 1000) as _;
self.surface_touch_event(Version::ALL, surface, |t| t.send_motion(time, id, x, y));
}
pub fn touch_frame_surface(&self, surface: &WlSurface) {
self.surface_touch_event(Version::ALL, surface, |t| t.send_frame())
}
pub fn touch_cancel_surface(&self, surface: &WlSurface) {
self.surface_touch_event(Version::ALL, surface, |t| t.send_cancel())
}
}
// Dnd callbacks
impl WlSeatGlobal {
pub fn dnd_surface_leave(&self, surface: &WlSurface, dnd: &Dnd) {

View file

@ -0,0 +1,167 @@
use {
crate::{
fixed::Fixed,
ifs::wl_seat::WlSeatGlobal,
tree::{FindTreeUsecase, FoundNode, Node},
utils::{clonecell::CloneCell, smallmap::SmallMap},
},
std::rc::Rc,
};
pub struct TouchOwnerHolder {
default: Rc<DefaultTouchOwner>,
owner: CloneCell<Rc<dyn TouchOwner>>,
}
impl Default for TouchOwnerHolder {
fn default() -> Self {
Self {
default: Rc::new(DefaultTouchOwner),
owner: CloneCell::new(Rc::new(DefaultTouchOwner)),
}
}
}
impl TouchOwnerHolder {
pub fn down(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
self.owner.get().down(seat, time_usec, id, x, y)
}
pub fn up(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32) {
self.owner.get().up(seat, time_usec, id)
}
pub fn motion(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
self.owner.get().motion(seat, time_usec, id, x, y)
}
pub fn frame(&self, seat: &Rc<WlSeatGlobal>) {
self.owner.get().frame(seat)
}
pub fn cancel(&self, seat: &Rc<WlSeatGlobal>) {
self.owner.get().cancel(seat)
}
pub fn clear(&self) {
self.set_default_owner();
}
fn set_default_owner(&self) {
self.owner.set(self.default.clone());
}
}
struct DefaultTouchOwner;
struct GrabTouchOwner {
node: Rc<dyn Node>,
down_ids: SmallMap<i32, (), 10>,
}
trait TouchOwner {
fn down(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed);
fn up(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32);
fn motion(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed);
fn frame(&self, seat: &Rc<WlSeatGlobal>);
fn cancel(&self, seat: &Rc<WlSeatGlobal>);
}
impl TouchOwner for DefaultTouchOwner {
fn down(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
let mut found_tree = seat.found_tree.borrow_mut();
let x_int = x.round_down();
let y_int = y.round_down();
found_tree.push(FoundNode {
node: seat.state.root.clone(),
x: x_int,
y: y_int,
});
seat.state
.root
.node_find_tree_at(x_int, y_int, &mut found_tree, FindTreeUsecase::None);
let node = found_tree.pop();
found_tree.clear();
drop(found_tree);
if let Some(node) = node {
node.node.node_seat_state().touch_begin(seat);
let owner = Rc::new(GrabTouchOwner {
node: node.node,
down_ids: Default::default(),
});
seat.touch_owner.owner.set(owner.clone());
owner.down(seat, time_usec, id, x, y);
}
}
fn up(&self, _seat: &Rc<WlSeatGlobal>, _time_usec: u64, _id: i32) {
// nothing
}
fn motion(&self, _seat: &Rc<WlSeatGlobal>, _time_usec: u64, _id: i32, _x: Fixed, _y: Fixed) {
// nothing
}
fn frame(&self, _seat: &Rc<WlSeatGlobal>) {
// nothing
}
fn cancel(&self, _seat: &Rc<WlSeatGlobal>) {
// nothing
}
}
impl GrabTouchOwner {
fn translate(&self, x: Fixed, y: Fixed) -> (Fixed, Fixed) {
let x_int = x.round_down();
let y_int = y.round_down();
let (x_int, y_int) = self.node.node_absolute_position().translate(x_int, y_int);
(x.apply_fract(x_int), y.apply_fract(y_int))
}
fn revert_to_default(&self, seat: &Rc<WlSeatGlobal>) {
self.node.node_seat_state().touch_end(seat);
seat.touch_owner.set_default_owner();
}
}
impl TouchOwner for GrabTouchOwner {
fn down(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
if self.down_ids.insert(id, ()).is_some() {
return;
}
let (x, y) = self.translate(x, y);
self.node
.clone()
.node_on_touch_down(seat, time_usec, id, x, y);
}
fn up(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32) {
if self.down_ids.remove(&id).is_none() {
return;
}
self.node.clone().node_on_touch_up(seat, time_usec, id);
}
fn motion(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
if !self.down_ids.contains(&id) {
return;
}
let (x, y) = self.translate(x, y);
self.node
.clone()
.node_on_touch_motion(seat, time_usec, id, x, y);
}
fn frame(&self, seat: &Rc<WlSeatGlobal>) {
self.node.node_on_touch_frame(seat);
if self.down_ids.is_empty() {
self.revert_to_default(seat);
}
}
fn cancel(&self, seat: &Rc<WlSeatGlobal>) {
self.node.node_on_touch_cancel(seat);
self.revert_to_default(seat);
}
}

View file

@ -1,29 +1,20 @@
use {
crate::{
client::ClientError,
fixed::Fixed,
ifs::wl_seat::WlSeat,
leaks::Tracker,
object::Object,
wire::{wl_touch::*, WlTouchId},
object::{Object, Version},
wire::{wl_touch::*, WlSurfaceId, WlTouchId},
},
std::rc::Rc,
thiserror::Error,
};
#[allow(dead_code)]
const DOWN: u32 = 0;
pub const SHAPE_SINCE_VERSION: Version = Version(6);
#[allow(dead_code)]
const UP: u32 = 1;
#[allow(dead_code)]
const MOTION: u32 = 2;
#[allow(dead_code)]
const FRAME: u32 = 3;
#[allow(dead_code)]
const CANCEL: u32 = 4;
#[allow(dead_code)]
const SHAPE: u32 = 5;
#[allow(dead_code)]
const ORIENTATION: u32 = 6;
pub const ORIENTATION_DIRECTION_SINCE_VERSION: Version = Version(6);
pub struct WlTouch {
id: WlTouchId,
@ -39,12 +30,79 @@ impl WlTouch {
tracker: Default::default(),
}
}
pub fn send_down(
&self,
serial: u32,
time: u32,
surface: WlSurfaceId,
id: i32,
x: Fixed,
y: Fixed,
) {
self.seat.client.event(Down {
self_id: self.id,
serial,
time,
surface,
id,
x,
y,
})
}
pub fn send_up(&self, serial: u32, time: u32, id: i32) {
self.seat.client.event(Up {
self_id: self.id,
serial,
time,
id,
})
}
pub fn send_motion(&self, time: u32, id: i32, x: Fixed, y: Fixed) {
self.seat.client.event(Motion {
self_id: self.id,
time,
id,
x,
y,
})
}
pub fn send_frame(&self) {
self.seat.client.event(Frame { self_id: self.id })
}
pub fn send_cancel(&self) {
self.seat.client.event(Cancel { self_id: self.id })
}
#[allow(dead_code)]
pub fn send_shape(&self, id: i32, major: Fixed, minor: Fixed) {
self.seat.client.event(Shape {
self_id: self.id,
id,
major,
minor,
})
}
#[allow(dead_code)]
pub fn send_orientation(&self, id: i32, orientation: Fixed) {
self.seat.client.event(Orientation {
self_id: self.id,
id,
orientation,
})
}
}
impl WlTouchRequestHandler for WlTouch {
type Error = WlTouchError;
fn release(&self, _req: Release, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.seat.touches.remove(&self.id);
self.seat.client.remove_obj(self)?;
Ok(())
}

View file

@ -1643,6 +1643,40 @@ impl Node for WlSurface {
seat.mods_surface(self, kb_state);
}
fn node_on_touch_down(
self: Rc<Self>,
seat: &Rc<WlSeatGlobal>,
time_usec: u64,
id: i32,
x: Fixed,
y: Fixed,
) {
seat.touch_down_surface(&self, time_usec, id, x, y)
}
fn node_on_touch_up(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, time_usec: u64, id: i32) {
seat.touch_up_surface(&self, time_usec, id)
}
fn node_on_touch_motion(
self: Rc<Self>,
seat: &WlSeatGlobal,
time_usec: u64,
id: i32,
x: Fixed,
y: Fixed,
) {
seat.touch_motion_surface(&self, time_usec, id, x, y)
}
fn node_on_touch_frame(&self, seat: &WlSeatGlobal) {
seat.touch_frame_surface(&self)
}
fn node_on_touch_cancel(&self, seat: &WlSeatGlobal) {
seat.touch_cancel_surface(&self)
}
fn node_on_button(
self: Rc<Self>,
seat: &Rc<WlSeatGlobal>,