parent
b98fa84524
commit
70f15d5085
3 changed files with 114 additions and 22 deletions
|
|
@ -711,29 +711,49 @@ impl Event for client::wl_keyboard::Event {
|
||||||
|
|
||||||
impl Event for client::wl_touch::Event {
|
impl Event for client::wl_touch::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let touch = state.world.get::<&WlTouch>(target).unwrap();
|
match self {
|
||||||
|
Self::Down {
|
||||||
|
serial,
|
||||||
|
time,
|
||||||
|
surface,
|
||||||
|
id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
} => {
|
||||||
|
let mut cmd = CommandBuffer::new();
|
||||||
|
{
|
||||||
|
let Some(mut s_query) = surface.data().copied().and_then(|key| {
|
||||||
|
state
|
||||||
|
.world
|
||||||
|
.query_one::<(&WlSurface, &SurfaceScaleFactor)>(key)
|
||||||
|
.ok()
|
||||||
|
}) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let s_surf;
|
let (s_surface, s_factor) = s_query.get().unwrap();
|
||||||
simple_event_shunt! {
|
cmd.insert(target, (*s_factor,));
|
||||||
touch, self => [
|
let touch = state.world.get::<&WlTouch>(target).unwrap();
|
||||||
Down {
|
touch.down(serial, time, s_surface, id, x * s_factor.0, y * s_factor.0);
|
||||||
serial,
|
}
|
||||||
time,
|
cmd.run_on(&mut state.world);
|
||||||
|surface| {
|
}
|
||||||
s_surf = surface.data().copied().and_then(|key| state.world.get::<&WlSurface>(key).ok());
|
Self::Motion { time, id, x, y } => {
|
||||||
if let Some(s) = &s_surf { s } else { return; }
|
let (touch, scale) = state.world.query_one_mut::<(&WlTouch, &SurfaceScaleFactor)>(target).unwrap();
|
||||||
},
|
touch.motion(time, id, x * scale.0, y * scale.0);
|
||||||
id,
|
}
|
||||||
x,
|
_ => {
|
||||||
y
|
let touch = state.world.get::<&WlTouch>(target).unwrap();
|
||||||
},
|
simple_event_shunt! {
|
||||||
Up { serial, time, id },
|
touch, self => [
|
||||||
Motion { time, id, x, y },
|
Up { serial, time, id },
|
||||||
Frame,
|
Frame,
|
||||||
Cancel,
|
Cancel,
|
||||||
Shape { id, major, minor },
|
Shape { id, major, minor },
|
||||||
Orientation { id, orientation }
|
Orientation { id, orientation }
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ use wayland_client::{
|
||||||
wl_shm::{Format, WlShm},
|
wl_shm::{Format, WlShm},
|
||||||
wl_shm_pool::WlShmPool,
|
wl_shm_pool::WlShmPool,
|
||||||
wl_surface::WlSurface,
|
wl_surface::WlSurface,
|
||||||
|
wl_touch::{self, WlTouch},
|
||||||
},
|
},
|
||||||
Connection, Proxy, WEnum,
|
Connection, Proxy, WEnum,
|
||||||
};
|
};
|
||||||
|
|
@ -2246,6 +2247,49 @@ fn transient_for_toplevel() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn touch_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 touch = TestObject::<WlTouch>::from_request(&comp.seat.obj, wl_seat::Request::GetTouch {});
|
||||||
|
f.run();
|
||||||
|
|
||||||
|
let toplevel = unsafe { Window::new(1) };
|
||||||
|
let (_, id) = f.create_toplevel(&comp, toplevel);
|
||||||
|
f.testwl.move_surface_to_output(id, &output);
|
||||||
|
|
||||||
|
let data = f.testwl.get_surface_data(id).unwrap();
|
||||||
|
let server_surface = data.surface.clone();
|
||||||
|
let fractional = data.fractional.as_ref().cloned().unwrap();
|
||||||
|
|
||||||
|
let do_touch = |f: &mut TestFixture, x, y| {
|
||||||
|
f.testwl.touch().down(0, 0, &server_surface, 0, x, y);
|
||||||
|
f.testwl.dispatch();
|
||||||
|
f.run();
|
||||||
|
f.run();
|
||||||
|
let events = &mut touch.data.events.lock().unwrap();
|
||||||
|
assert_eq!(events.len(), 1);
|
||||||
|
let event = events.pop().unwrap();
|
||||||
|
let wl_touch::Event::Down { x, y, .. } = event else {
|
||||||
|
panic!("Got unexpected event: {event:?}");
|
||||||
|
};
|
||||||
|
(x, y)
|
||||||
|
};
|
||||||
|
|
||||||
|
let (x, y) = do_touch(&mut f, 20.0, 40.0);
|
||||||
|
assert_eq!(x, 20.0);
|
||||||
|
assert_eq!(y, 40.0);
|
||||||
|
|
||||||
|
fractional.preferred_scale(180); // 1.5 scale
|
||||||
|
f.run();
|
||||||
|
let (x, y) = do_touch(&mut f, 20.0, 40.0);
|
||||||
|
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() {}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ use wayland_server::{
|
||||||
wl_shm::WlShm,
|
wl_shm::WlShm,
|
||||||
wl_shm_pool::WlShmPool,
|
wl_shm_pool::WlShmPool,
|
||||||
wl_surface::WlSurface,
|
wl_surface::WlSurface,
|
||||||
|
wl_touch::{self, WlTouch},
|
||||||
},
|
},
|
||||||
Client, Dispatch, Display, DisplayHandle, GlobalDispatch, Resource, WEnum,
|
Client, Dispatch, Display, DisplayHandle, GlobalDispatch, Resource, WEnum,
|
||||||
};
|
};
|
||||||
|
|
@ -225,6 +226,7 @@ struct State {
|
||||||
seat: Option<WlSeat>,
|
seat: Option<WlSeat>,
|
||||||
pointer: Option<WlPointer>,
|
pointer: Option<WlPointer>,
|
||||||
keyboard: Option<KeyboardState>,
|
keyboard: Option<KeyboardState>,
|
||||||
|
touch: Option<WlTouch>,
|
||||||
configure_serial: u32,
|
configure_serial: u32,
|
||||||
selection: Option<WlDataSource>,
|
selection: Option<WlDataSource>,
|
||||||
data_device_man: Option<WlDataDeviceManager>,
|
data_device_man: Option<WlDataDeviceManager>,
|
||||||
|
|
@ -248,6 +250,7 @@ impl Default for State {
|
||||||
seat: None,
|
seat: None,
|
||||||
pointer: None,
|
pointer: None,
|
||||||
keyboard: None,
|
keyboard: None,
|
||||||
|
touch: None,
|
||||||
configure_serial: 0,
|
configure_serial: 0,
|
||||||
selection: None,
|
selection: None,
|
||||||
data_device_man: None,
|
data_device_man: None,
|
||||||
|
|
@ -752,6 +755,11 @@ impl Server {
|
||||||
.create_global::<State, WpFractionalScaleManagerV1, _>(1, ());
|
.create_global::<State, WpFractionalScaleManagerV1, _>(1, ());
|
||||||
self.display.flush_clients().unwrap();
|
self.display.flush_clients().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub fn touch(&mut self) -> &WlTouch {
|
||||||
|
self.state.touch.as_ref().expect("No touch object created")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
|
|
@ -1067,6 +1075,9 @@ impl Dispatch<WlSeat, ()> for State {
|
||||||
current_focus: None,
|
current_focus: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
wl_seat::Request::GetTouch { id } => {
|
||||||
|
state.touch = Some(data_init.init(id, ()));
|
||||||
|
}
|
||||||
wl_seat::Request::Release => {}
|
wl_seat::Request::Release => {}
|
||||||
other => todo!("unhandled request {other:?}"),
|
other => todo!("unhandled request {other:?}"),
|
||||||
}
|
}
|
||||||
|
|
@ -1125,6 +1136,23 @@ impl Dispatch<WlKeyboard, ()> for State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Dispatch<WlTouch, ()> for State {
|
||||||
|
fn request(
|
||||||
|
_: &mut Self,
|
||||||
|
_: &Client,
|
||||||
|
_: &WlTouch,
|
||||||
|
request: <WlTouch as Resource>::Request,
|
||||||
|
_: &(),
|
||||||
|
_: &DisplayHandle,
|
||||||
|
_: &mut wayland_server::DataInit<'_, Self>,
|
||||||
|
) {
|
||||||
|
match request {
|
||||||
|
wl_touch::Request::Release => {}
|
||||||
|
other => todo!("unhandled request {other:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Dispatch<XdgPopup, SurfaceId> for State {
|
impl Dispatch<XdgPopup, SurfaceId> for State {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue