ei: add support for libei
This commit is contained in:
parent
084fe50259
commit
40e87f8f91
69 changed files with 4340 additions and 72 deletions
|
|
@ -25,6 +25,7 @@ use {
|
|||
async_engine::SpawnedFuture,
|
||||
client::{Client, ClientError, ClientId},
|
||||
cursor_user::{CursorUser, CursorUserGroup, CursorUserOwner},
|
||||
ei::ei_ifs::ei_seat::EiSeat,
|
||||
fixed::Fixed,
|
||||
globals::{Global, GlobalName},
|
||||
ifs::{
|
||||
|
|
@ -84,6 +85,7 @@ use {
|
|||
WlSeatId, WlTouchId, ZwlrDataControlDeviceV1Id, ZwpPrimarySelectionDeviceV1Id,
|
||||
ZwpRelativePointerV1Id, ZwpTextInputV3Id,
|
||||
},
|
||||
wire_ei::EiSeatId,
|
||||
xkbcommon::{DynKeyboardState, KeyboardState, KeymapId, XkbKeymap, XkbState},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
|
|
@ -195,6 +197,7 @@ pub struct WlSeatGlobal {
|
|||
pinch_bindings: PerClientBindings<ZwpPointerGesturePinchV1>,
|
||||
hold_bindings: PerClientBindings<ZwpPointerGestureHoldV1>,
|
||||
tablet: TabletSeatData,
|
||||
ei_seats: CopyHashMap<(ClientId, EiSeatId), Rc<EiSeat>>,
|
||||
}
|
||||
|
||||
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
||||
|
|
@ -263,6 +266,7 @@ impl WlSeatGlobal {
|
|||
pinch_bindings: Default::default(),
|
||||
hold_bindings: Default::default(),
|
||||
tablet: Default::default(),
|
||||
ei_seats: Default::default(),
|
||||
});
|
||||
slf.pointer_cursor.set_owner(slf.clone());
|
||||
let seat = slf.clone();
|
||||
|
|
@ -280,10 +284,14 @@ impl WlSeatGlobal {
|
|||
slf
|
||||
}
|
||||
|
||||
fn update_capabilities(&self) {
|
||||
pub fn update_capabilities(&self) {
|
||||
let mut caps = POINTER | KEYBOARD;
|
||||
if self.num_touch_devices.get() > 0 {
|
||||
caps |= TOUCH;
|
||||
} else {
|
||||
if self.ei_seats.lock().values().any(|s| s.is_touch_input()) {
|
||||
caps |= TOUCH;
|
||||
}
|
||||
}
|
||||
if self.capabilities.replace(caps) != caps {
|
||||
for client in self.bindings.borrow().values() {
|
||||
|
|
@ -481,6 +489,9 @@ impl WlSeatGlobal {
|
|||
}
|
||||
|
||||
fn handle_xkb_state_change(&self, old: &XkbState, new: &XkbState) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_xkb_state_change(old.kb_state.id, &new.kb_state);
|
||||
});
|
||||
let Some(surface) = self.keyboard_node.get().node_into_surface() else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -888,6 +899,7 @@ impl WlSeatGlobal {
|
|||
self.hold_bindings.clear();
|
||||
self.cursor_user_group.detach();
|
||||
self.tablet_clear();
|
||||
self.ei_seats.clear();
|
||||
}
|
||||
|
||||
pub fn id(&self) -> SeatId {
|
||||
|
|
@ -982,6 +994,30 @@ impl WlSeatGlobal {
|
|||
self.pointer_owner
|
||||
.set_window_management_enabled(self, enabled);
|
||||
}
|
||||
|
||||
pub fn add_ei_seat(&self, ei: &Rc<EiSeat>) {
|
||||
self.ei_seats.set((ei.client.id, ei.id), ei.clone());
|
||||
self.update_capabilities();
|
||||
}
|
||||
|
||||
pub fn remove_ei_seat(&self, ei: &EiSeat) {
|
||||
self.ei_seats.remove(&(ei.client.id, ei.id));
|
||||
self.update_capabilities();
|
||||
}
|
||||
|
||||
pub fn seat_xkb_state(&self) -> Rc<dyn DynKeyboardState> {
|
||||
self.seat_xkb_state.get()
|
||||
}
|
||||
|
||||
pub fn latest_xkb_state(&self) -> Rc<dyn DynKeyboardState> {
|
||||
self.latest_kb_state.get()
|
||||
}
|
||||
|
||||
pub fn output_extents_changed(&self) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.regions_changed();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl CursorUserOwner for WlSeatGlobal {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::{ConnectorId, InputDeviceId, InputEvent, KeyState, AXIS_120},
|
||||
backend::{
|
||||
AxisSource, ConnectorId, InputDeviceId, InputEvent, KeyState, ScrollAxis, AXIS_120,
|
||||
},
|
||||
client::ClientId,
|
||||
config::InvokedShortcut,
|
||||
ei::ei_ifs::ei_seat::EiSeat,
|
||||
fixed::Fixed,
|
||||
ifs::{
|
||||
ipc::{
|
||||
|
|
@ -245,10 +248,7 @@ impl WlSeatGlobal {
|
|||
| InputEvent::TabletPadModeSwitch { time_usec, .. }
|
||||
| InputEvent::TabletPadRing { time_usec, .. }
|
||||
| InputEvent::TabletPadStrip { time_usec, .. }
|
||||
| InputEvent::TouchDown { time_usec, .. }
|
||||
| InputEvent::TouchUp { time_usec, .. }
|
||||
| InputEvent::TouchMotion { time_usec, .. }
|
||||
| InputEvent::TouchCancel { time_usec, .. } => {
|
||||
| InputEvent::TouchFrame { 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() {
|
||||
|
|
@ -262,7 +262,10 @@ impl WlSeatGlobal {
|
|||
| InputEvent::Axis120 { .. }
|
||||
| InputEvent::TabletToolAdded { .. }
|
||||
| InputEvent::TabletToolRemoved { .. }
|
||||
| InputEvent::TouchFrame => {}
|
||||
| InputEvent::TouchDown { .. }
|
||||
| InputEvent::TouchUp { .. }
|
||||
| InputEvent::TouchMotion { .. }
|
||||
| InputEvent::TouchCancel { .. } => {}
|
||||
}
|
||||
match event {
|
||||
InputEvent::ConnectorPosition { .. }
|
||||
|
|
@ -297,7 +300,7 @@ impl WlSeatGlobal {
|
|||
InputEvent::TouchUp { .. } => {}
|
||||
InputEvent::TouchMotion { .. } => {}
|
||||
InputEvent::TouchCancel { .. } => {}
|
||||
InputEvent::TouchFrame => {}
|
||||
InputEvent::TouchFrame { .. } => {}
|
||||
}
|
||||
match event {
|
||||
InputEvent::Key {
|
||||
|
|
@ -324,19 +327,21 @@ impl WlSeatGlobal {
|
|||
state,
|
||||
} => self.button_event(time_usec, button, state),
|
||||
|
||||
InputEvent::AxisSource { source } => self.pointer_owner.axis_source(source),
|
||||
InputEvent::AxisSource { source } => self.axis_source(source),
|
||||
InputEvent::Axis120 {
|
||||
dist,
|
||||
axis,
|
||||
inverted,
|
||||
} => self.pointer_owner.axis_120(dist, axis, inverted),
|
||||
} => self.axis_120(dist, axis, inverted),
|
||||
InputEvent::AxisPx {
|
||||
dist,
|
||||
axis,
|
||||
inverted,
|
||||
} => self.pointer_owner.axis_px(dist, axis, inverted),
|
||||
InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis),
|
||||
InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(dev, self, time_usec),
|
||||
} => self.axis_px(dist, axis, inverted),
|
||||
InputEvent::AxisStop { axis } => self.axis_stop(axis),
|
||||
InputEvent::AxisFrame { time_usec } => {
|
||||
self.axis_frame(dev.px_per_scroll_wheel.get(), time_usec)
|
||||
}
|
||||
InputEvent::SwipeBegin {
|
||||
time_usec,
|
||||
finger_count,
|
||||
|
|
@ -445,7 +450,7 @@ impl WlSeatGlobal {
|
|||
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(),
|
||||
InputEvent::TouchFrame { time_usec } => self.touch_frame(time_usec),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +486,14 @@ impl WlSeatGlobal {
|
|||
let pos = output.global.pos.get();
|
||||
x += Fixed::from_int(pos.x1());
|
||||
y += Fixed::from_int(pos.y1());
|
||||
(x, y) = self.set_pointer_cursor_position(x, y);
|
||||
self.motion_event_abs(time_usec, x, y);
|
||||
}
|
||||
|
||||
pub fn motion_event_abs(self: &Rc<Self>, time_usec: u64, x: Fixed, y: Fixed) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_motion_abs(time_usec, x, y);
|
||||
});
|
||||
let (x, y) = self.set_pointer_cursor_position(x, y);
|
||||
if let Some(c) = self.constraint.get() {
|
||||
if c.ty == ConstraintType::Lock || !c.contains(x.round_down(), y.round_down()) {
|
||||
c.deactivate();
|
||||
|
|
@ -493,7 +505,7 @@ impl WlSeatGlobal {
|
|||
self.cursor_moved(time_usec);
|
||||
}
|
||||
|
||||
fn motion_event(
|
||||
pub fn motion_event(
|
||||
self: &Rc<Self>,
|
||||
time_usec: u64,
|
||||
dx: Fixed,
|
||||
|
|
@ -501,6 +513,9 @@ impl WlSeatGlobal {
|
|||
dx_unaccelerated: Fixed,
|
||||
dy_unaccelerated: Fixed,
|
||||
) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_motion(time_usec, dx, dy);
|
||||
});
|
||||
self.pointer_owner.relative_motion(
|
||||
self,
|
||||
time_usec,
|
||||
|
|
@ -545,13 +560,37 @@ impl WlSeatGlobal {
|
|||
self.cursor_moved(time_usec);
|
||||
}
|
||||
|
||||
fn button_event(self: &Rc<Self>, time_usec: u64, button: u32, state: KeyState) {
|
||||
pub fn button_event(self: &Rc<Self>, time_usec: u64, button: u32, state: KeyState) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_button(time_usec, button, state);
|
||||
});
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_button(self.id, time_usec, button, state);
|
||||
});
|
||||
self.pointer_owner.button(self, time_usec, button, state);
|
||||
}
|
||||
|
||||
pub fn axis_source(&self, axis_source: AxisSource) {
|
||||
self.pointer_owner.axis_source(axis_source);
|
||||
}
|
||||
|
||||
pub fn axis_120(&self, delta: i32, axis: ScrollAxis, inverted: bool) {
|
||||
self.pointer_owner.axis_120(delta, axis, inverted);
|
||||
}
|
||||
|
||||
pub fn axis_px(&self, delta: Fixed, axis: ScrollAxis, inverted: bool) {
|
||||
self.pointer_owner.axis_px(delta, axis, inverted);
|
||||
}
|
||||
|
||||
pub fn axis_stop(&self, axis: ScrollAxis) {
|
||||
self.pointer_owner.axis_stop(axis);
|
||||
}
|
||||
|
||||
pub fn axis_frame(self: &Rc<Self>, px_per_scroll_wheel: f64, time_usec: u64) {
|
||||
self.pointer_owner
|
||||
.frame(px_per_scroll_wheel, self, time_usec);
|
||||
}
|
||||
|
||||
fn swipe_begin(self: &Rc<Self>, time_usec: u64, finger_count: u32) {
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_swipe_begin(self.id, time_usec, finger_count);
|
||||
|
|
@ -660,16 +699,26 @@ impl WlSeatGlobal {
|
|||
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.touch_down_at(time_usec, id, x, y);
|
||||
}
|
||||
|
||||
pub fn touch_down_at(self: &Rc<Self>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_touch_down(id as _, x, y);
|
||||
});
|
||||
self.cursor_group().deactivate();
|
||||
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) {
|
||||
pub fn touch_up(self: &Rc<Self>, time_usec: u64, id: i32) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_touch_up(id as _);
|
||||
});
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_touch_up(self.id, time_usec, id);
|
||||
});
|
||||
|
|
@ -684,9 +733,16 @@ impl WlSeatGlobal {
|
|||
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.touch_motion_at(time_usec, id, x, y);
|
||||
}
|
||||
|
||||
pub fn touch_motion_at(self: &Rc<Self>, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_touch_motion(id as _, x, y);
|
||||
});
|
||||
self.cursor_group().deactivate();
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_touch_motion(self.id, time_usec, id, x, y);
|
||||
});
|
||||
|
|
@ -694,16 +750,31 @@ impl WlSeatGlobal {
|
|||
}
|
||||
|
||||
fn touch_cancel(self: &Rc<Self>, time_usec: u64, id: i32) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_touch_up(id as _);
|
||||
});
|
||||
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>) {
|
||||
pub fn touch_frame(self: &Rc<Self>, time_usec: u64) {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_touch_frame(time_usec);
|
||||
});
|
||||
self.touch_owner.frame(self);
|
||||
}
|
||||
|
||||
pub fn key_event_with_seat_state(
|
||||
self: &Rc<Self>,
|
||||
time_usec: u64,
|
||||
key: u32,
|
||||
key_state: KeyState,
|
||||
) {
|
||||
self.key_event(time_usec, key, key_state, || self.seat_xkb_state.get());
|
||||
}
|
||||
|
||||
pub(super) fn key_event<F>(
|
||||
self: &Rc<Self>,
|
||||
time_usec: u64,
|
||||
|
|
@ -787,8 +858,14 @@ impl WlSeatGlobal {
|
|||
Some(g) => g.on_key(time_usec, key, state, &xkb_state.kb_state),
|
||||
_ => node.node_on_key(self, time_usec, key, state, &xkb_state.kb_state),
|
||||
}
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_key(time_usec, key, state, &xkb_state.kb_state);
|
||||
});
|
||||
}
|
||||
if new_mods {
|
||||
self.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_modifiers_changed(&xkb_state.kb_state);
|
||||
});
|
||||
self.state.for_each_seat_tester(|t| {
|
||||
t.send_modifiers(self.id, &xkb_state.kb_state.mods);
|
||||
});
|
||||
|
|
@ -808,6 +885,14 @@ impl WlSeatGlobal {
|
|||
drop(xkb_state);
|
||||
self.latest_kb_state.set(xkb_state_rc);
|
||||
}
|
||||
|
||||
pub(super) fn for_each_ei_seat(&self, mut f: impl FnMut(&Rc<EiSeat>)) {
|
||||
if self.ei_seats.is_not_empty() {
|
||||
for ei_seat in self.ei_seats.lock().values() {
|
||||
f(ei_seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WlSeatGlobal {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use {
|
|||
wl_surface::{dnd_icon::DndIcon, WlSurface},
|
||||
xdg_toplevel_drag_v1::XdgToplevelDragV1,
|
||||
},
|
||||
state::DeviceHandlerData,
|
||||
tree::{ContainingNode, FindTreeUsecase, FoundNode, Node, ToplevelNode, WorkspaceNode},
|
||||
utils::{clonecell::CloneCell, smallmap::SmallMap},
|
||||
},
|
||||
|
|
@ -73,15 +72,18 @@ impl PointerOwnerHolder {
|
|||
self.pending_scroll.stop[axis as usize].set(true);
|
||||
}
|
||||
|
||||
pub fn frame(&self, dev: &DeviceHandlerData, seat: &Rc<WlSeatGlobal>, time_usec: u64) {
|
||||
pub fn frame(&self, px_per_scroll_wheel: f64, seat: &Rc<WlSeatGlobal>, time_usec: u64) {
|
||||
self.pending_scroll.time_usec.set(time_usec);
|
||||
let pending = self.pending_scroll.take();
|
||||
for axis in 0..2 {
|
||||
if let Some(dist) = pending.v120[axis].get() {
|
||||
let px = (dist as f64 / AXIS_120 as f64) * dev.px_per_scroll_wheel.get();
|
||||
let px = (dist as f64 / AXIS_120 as f64) * px_per_scroll_wheel;
|
||||
pending.px[axis].set(Some(Fixed::from_f64(px)));
|
||||
}
|
||||
}
|
||||
seat.for_each_ei_seat(|ei_seat| {
|
||||
ei_seat.handle_pending_scroll(time_usec, &pending);
|
||||
});
|
||||
seat.state.for_each_seat_tester(|t| {
|
||||
t.send_axis(seat.id, time_usec, &pending);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue