server: scale tablet_tool motion events
Also add missing Distance event handler. Closes #179, closes #123
This commit is contained in:
parent
70f15d5085
commit
03cbb2ee3a
4 changed files with 141 additions and 17 deletions
|
|
@ -264,6 +264,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> Entity {
|
||||||
|
self.key.get().copied().expect("Object key is not set")
|
||||||
|
}
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
key: OnceLock::new(),
|
key: OnceLock::new(),
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ use wayland_protocols::{
|
||||||
tablet::zv2::{
|
tablet::zv2::{
|
||||||
client::{
|
client::{
|
||||||
zwp_tablet_pad_group_v2, zwp_tablet_pad_ring_v2, zwp_tablet_pad_strip_v2,
|
zwp_tablet_pad_group_v2, zwp_tablet_pad_ring_v2, zwp_tablet_pad_strip_v2,
|
||||||
zwp_tablet_pad_v2, zwp_tablet_seat_v2, zwp_tablet_tool_v2, zwp_tablet_v2,
|
zwp_tablet_pad_v2, zwp_tablet_seat_v2, zwp_tablet_tool_v2,
|
||||||
|
zwp_tablet_v2::{self, ZwpTabletV2 as TabletClient},
|
||||||
},
|
},
|
||||||
server::{
|
server::{
|
||||||
zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2 as TabletPadGroupServer,
|
zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2 as TabletPadGroupServer,
|
||||||
|
|
@ -739,7 +740,10 @@ impl Event for client::wl_touch::Event {
|
||||||
cmd.run_on(&mut state.world);
|
cmd.run_on(&mut state.world);
|
||||||
}
|
}
|
||||||
Self::Motion { time, id, x, y } => {
|
Self::Motion { time, id, x, y } => {
|
||||||
let (touch, scale) = state.world.query_one_mut::<(&WlTouch, &SurfaceScaleFactor)>(target).unwrap();
|
let (touch, scale) = state
|
||||||
|
.world
|
||||||
|
.query_one_mut::<(&WlTouch, &SurfaceScaleFactor)>(target)
|
||||||
|
.unwrap();
|
||||||
touch.motion(time, id, x * scale.0, y * scale.0);
|
touch.motion(time, id, x * scale.0, y * scale.0);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
@ -1327,27 +1331,55 @@ impl Event for zwp_tablet_pad_v2::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_tool_v2::Event {
|
impl Event for zwp_tablet_tool_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let tool = state.world.get::<&TabletToolServer>(target).unwrap();
|
|
||||||
match self {
|
match self {
|
||||||
Self::ProximityIn {
|
Self::ProximityIn {
|
||||||
serial,
|
serial,
|
||||||
tablet,
|
tablet,
|
||||||
surface,
|
surface,
|
||||||
} => {
|
} => {
|
||||||
let (e_tab, s_tablet) = from_client::<TabletServer, _, _>(&tablet, state);
|
let mut cmd = CommandBuffer::new();
|
||||||
let Some(surface) = surface
|
{
|
||||||
.data()
|
let Some(mut query) = surface.data().copied().and_then(|key| {
|
||||||
.copied()
|
state
|
||||||
.and_then(|key| state.world.get::<&WlSurface>(key).ok())
|
.world
|
||||||
else {
|
.query_one::<(&WlSurface, &SurfaceScaleFactor)>(key)
|
||||||
|
.ok()
|
||||||
|
}) else {
|
||||||
|
warn!("tablet tool proximity_in failed: stale surface");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
tool.proximity_in(serial, &s_tablet, &surface);
|
let (surface, scale) = query.get().unwrap();
|
||||||
drop(tool);
|
cmd.insert(target, (*scale,));
|
||||||
drop(surface);
|
|
||||||
state.world.spawn_at(e_tab, (tablet, s_tablet));
|
let Some(s_tablet) =
|
||||||
|
tablet
|
||||||
|
.data()
|
||||||
|
.and_then(|key: &LateInitObjectKey<TabletClient>| {
|
||||||
|
state.world.get::<&TabletServer>(key.get()).ok()
|
||||||
|
})
|
||||||
|
else {
|
||||||
|
warn!("tablet tool proximity_in failed: stale tablet");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
state
|
||||||
|
.world
|
||||||
|
.get::<&TabletToolServer>(target)
|
||||||
|
.unwrap()
|
||||||
|
.proximity_in(serial, &s_tablet, surface);
|
||||||
|
}
|
||||||
|
cmd.run_on(&mut state.world);
|
||||||
|
}
|
||||||
|
Self::Motion { x, y } => {
|
||||||
|
let (tool, scale) = state
|
||||||
|
.world
|
||||||
|
.query_one_mut::<(&TabletToolServer, Option<&SurfaceScaleFactor>)>(target)
|
||||||
|
.unwrap();
|
||||||
|
let scale = scale.map(|s| s.0).unwrap_or(1.0);
|
||||||
|
tool.motion(x * scale, y * scale);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
let tool = state.world.get::<&TabletToolServer>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
tool, self => [
|
tool, self => [
|
||||||
Type { |tool_type| convert_wenum(tool_type) },
|
Type { |tool_type| convert_wenum(tool_type) },
|
||||||
|
|
@ -1359,7 +1391,7 @@ impl Event for zwp_tablet_tool_v2::Event {
|
||||||
ProximityOut,
|
ProximityOut,
|
||||||
Down { serial },
|
Down { serial },
|
||||||
Up,
|
Up,
|
||||||
Motion { x, y },
|
Distance { distance },
|
||||||
Pressure { pressure },
|
Pressure { pressure },
|
||||||
Tilt { tilt_x, tilt_y },
|
Tilt { tilt_x, tilt_y },
|
||||||
Rotation { degrees },
|
Rotation { degrees },
|
||||||
|
|
|
||||||
|
|
@ -2290,6 +2290,75 @@ fn touch_fractional_scale() {
|
||||||
assert_eq!(y, 40.0 * 1.5);
|
assert_eq!(y, 40.0 * 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tablet_tool_fractional_scale() {
|
||||||
|
let mut f = TestFixture::new_pre_connect(|testwl| {
|
||||||
|
testwl.enable_fractional_scale();
|
||||||
|
});
|
||||||
|
let comp = f.compositor();
|
||||||
|
let (_, output) = f.new_output(0, 0);
|
||||||
|
let toplevel = unsafe { Window::new(1) };
|
||||||
|
let (_, id) = f.create_toplevel(&comp, toplevel);
|
||||||
|
let surface_data = f.testwl.get_surface_data(id).unwrap();
|
||||||
|
let fractional = surface_data.fractional.as_ref().cloned().unwrap();
|
||||||
|
let server_surface = surface_data.surface.clone();
|
||||||
|
f.testwl.move_surface_to_output(id, &output);
|
||||||
|
|
||||||
|
let seat = TestObject::<ZwpTabletSeatV2>::from_request(
|
||||||
|
&comp.tablet_man.obj,
|
||||||
|
zwp_tablet_manager_v2::Request::GetTabletSeat {
|
||||||
|
seat: comp.seat.obj,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// Not sure why exactly this requires 4 runs but it works so idk
|
||||||
|
for _ in 0..4 {
|
||||||
|
f.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tool = None;
|
||||||
|
for event in seat.data.events.lock().unwrap().drain(..) {
|
||||||
|
if let zwp_tablet_seat_v2::Event::ToolAdded { id } = event {
|
||||||
|
tool = Some(id.clone());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let client_tool = tool.expect("Didn't get tool");
|
||||||
|
let client_data = f.object_data(&client_tool);
|
||||||
|
let server_tool = f.testwl.tablet_tool().clone();
|
||||||
|
let tablet = f.testwl.tablet().clone();
|
||||||
|
|
||||||
|
let get_motion = || {
|
||||||
|
let events = &mut *client_data.events.lock().unwrap();
|
||||||
|
let event = events.pop();
|
||||||
|
let Some(zwp_tablet_tool_v2::Event::Motion { x, y }) = event else {
|
||||||
|
panic!("Didn't get motion event: {event:?}");
|
||||||
|
};
|
||||||
|
(x, y)
|
||||||
|
};
|
||||||
|
|
||||||
|
server_tool.proximity_in(0, &tablet, &server_surface);
|
||||||
|
server_tool.motion(20.0, 40.0);
|
||||||
|
f.testwl.dispatch();
|
||||||
|
f.run();
|
||||||
|
f.run();
|
||||||
|
|
||||||
|
let (x, y) = get_motion();
|
||||||
|
assert_eq!(x, 20.0);
|
||||||
|
assert_eq!(y, 40.0);
|
||||||
|
|
||||||
|
fractional.preferred_scale(180); // 1.5 scale
|
||||||
|
server_tool.proximity_in(0, &tablet, &server_surface);
|
||||||
|
server_tool.motion(20.0, 40.0);
|
||||||
|
f.testwl.dispatch();
|
||||||
|
f.run();
|
||||||
|
f.run();
|
||||||
|
|
||||||
|
let (x, y) = get_motion();
|
||||||
|
assert_eq!(x, 20.0 * 1.5);
|
||||||
|
assert_eq!(y, 40.0 * 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
/// See Pointer::handle_event for an explanation.
|
/// See Pointer::handle_event for an explanation.
|
||||||
#[test]
|
#[test]
|
||||||
fn popup_pointer_motion_workaround() {}
|
fn popup_pointer_motion_workaround() {}
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,8 @@ struct State {
|
||||||
pointer: Option<WlPointer>,
|
pointer: Option<WlPointer>,
|
||||||
keyboard: Option<KeyboardState>,
|
keyboard: Option<KeyboardState>,
|
||||||
touch: Option<WlTouch>,
|
touch: Option<WlTouch>,
|
||||||
|
tablet: Option<ZwpTabletV2>,
|
||||||
|
tablet_tool: Option<ZwpTabletToolV2>,
|
||||||
configure_serial: u32,
|
configure_serial: u32,
|
||||||
selection: Option<WlDataSource>,
|
selection: Option<WlDataSource>,
|
||||||
data_device_man: Option<WlDataDeviceManager>,
|
data_device_man: Option<WlDataDeviceManager>,
|
||||||
|
|
@ -251,6 +253,8 @@ impl Default for State {
|
||||||
pointer: None,
|
pointer: None,
|
||||||
keyboard: None,
|
keyboard: None,
|
||||||
touch: None,
|
touch: None,
|
||||||
|
tablet: None,
|
||||||
|
tablet_tool: None,
|
||||||
configure_serial: 0,
|
configure_serial: 0,
|
||||||
selection: None,
|
selection: None,
|
||||||
data_device_man: None,
|
data_device_man: None,
|
||||||
|
|
@ -760,6 +764,19 @@ impl Server {
|
||||||
pub fn touch(&mut self) -> &WlTouch {
|
pub fn touch(&mut self) -> &WlTouch {
|
||||||
self.state.touch.as_ref().expect("No touch object created")
|
self.state.touch.as_ref().expect("No touch object created")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub fn tablet_tool(&mut self) -> &ZwpTabletToolV2 {
|
||||||
|
self.state
|
||||||
|
.tablet_tool
|
||||||
|
.as_ref()
|
||||||
|
.expect("No tablet tool created")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub fn tablet(&mut self) -> &ZwpTabletV2 {
|
||||||
|
self.state.tablet.as_ref().expect("No tablet created")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
|
|
@ -779,7 +796,7 @@ simple_global_dispatch!(WpFractionalScaleManagerV1);
|
||||||
|
|
||||||
impl Dispatch<ZwpTabletManagerV2, ()> for State {
|
impl Dispatch<ZwpTabletManagerV2, ()> for State {
|
||||||
fn request(
|
fn request(
|
||||||
_: &mut Self,
|
state: &mut Self,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
_: &ZwpTabletManagerV2,
|
_: &ZwpTabletManagerV2,
|
||||||
request: <ZwpTabletManagerV2 as Resource>::Request,
|
request: <ZwpTabletManagerV2 as Resource>::Request,
|
||||||
|
|
@ -794,11 +811,13 @@ impl Dispatch<ZwpTabletManagerV2, ()> for State {
|
||||||
seat.tablet_added(&tablet);
|
seat.tablet_added(&tablet);
|
||||||
tablet.name("tabby".to_owned());
|
tablet.name("tabby".to_owned());
|
||||||
tablet.done();
|
tablet.done();
|
||||||
|
state.tablet = Some(tablet);
|
||||||
|
|
||||||
let tool = client.create_resource::<_, _, State>(dhandle, 1, ()).unwrap();
|
let tool = client.create_resource::<_, _, State>(dhandle, 1, ()).unwrap();
|
||||||
seat.tool_added(&tool);
|
seat.tool_added(&tool);
|
||||||
tool._type(zwp_tablet_tool_v2::Type::Finger);
|
tool._type(zwp_tablet_tool_v2::Type::Finger);
|
||||||
tool.done();
|
tool.done();
|
||||||
|
state.tablet_tool = Some(tool);
|
||||||
|
|
||||||
let pad = client.create_resource::<_, _, State>(dhandle, 1, ()).unwrap();
|
let pad = client.create_resource::<_, _, State>(dhandle, 1, ()).unwrap();
|
||||||
let group = client.create_resource::<_, _, State>(dhandle, 1, ()).unwrap();
|
let group = client.create_resource::<_, _, State>(dhandle, 1, ()).unwrap();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue