seat: add GrabStartData to PointerGrab
Stores the data about the event that started the grab. Will be useful for things like move and resize requests.
This commit is contained in:
parent
24af494cbf
commit
03392bf7d1
|
@ -15,7 +15,7 @@ use smithay::{
|
|||
wayland::{
|
||||
compositor::{compositor_init, CompositorToken, RegionAttributes, SurfaceAttributes, SurfaceEvent},
|
||||
data_device::DnDIconRole,
|
||||
seat::{AxisFrame, CursorImageRole, PointerGrab, PointerInnerHandle, Seat},
|
||||
seat::{AxisFrame, CursorImageRole, GrabStartData, PointerGrab, PointerInnerHandle, Seat},
|
||||
shell::{
|
||||
legacy::{
|
||||
wl_shell_init, ShellRequest, ShellState as WlShellState, ShellSurfaceKind, ShellSurfaceRole,
|
||||
|
@ -47,9 +47,9 @@ pub type MyWindowMap = WindowMap<
|
|||
pub type MyCompositorToken = CompositorToken<Roles>;
|
||||
|
||||
struct MoveSurfaceGrab {
|
||||
start_data: GrabStartData,
|
||||
window_map: Rc<RefCell<MyWindowMap>>,
|
||||
toplevel: SurfaceKind<Roles>,
|
||||
initial_pointer_location: (f64, f64),
|
||||
initial_window_location: (i32, i32),
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,8 @@ impl PointerGrab for MoveSurfaceGrab {
|
|||
_serial: u32,
|
||||
_time: u32,
|
||||
) {
|
||||
let dx = location.0 - self.initial_pointer_location.0;
|
||||
let dy = location.1 - self.initial_pointer_location.1;
|
||||
let dx = location.0 - self.start_data.location.0;
|
||||
let dy = location.1 - self.start_data.location.1;
|
||||
let new_window_x = (self.initial_window_location.0 as f64 + dx) as i32;
|
||||
let new_window_y = (self.initial_window_location.1 as f64 + dy) as i32;
|
||||
|
||||
|
@ -90,6 +90,10 @@ impl PointerGrab for MoveSurfaceGrab {
|
|||
fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) {
|
||||
handle.axis(details)
|
||||
}
|
||||
|
||||
fn start_data(&self) -> &GrabStartData {
|
||||
&self.start_data
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_shell(
|
||||
|
@ -156,13 +160,15 @@ pub fn init_shell(
|
|||
// TODO: touch move.
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
|
||||
let start_data = pointer.grab_start_data().unwrap();
|
||||
|
||||
let toplevel = SurfaceKind::Xdg(surface);
|
||||
let initial_window_location = xdg_window_map.borrow().location(&toplevel).unwrap();
|
||||
|
||||
let grab = MoveSurfaceGrab {
|
||||
start_data,
|
||||
window_map: xdg_window_map.clone(),
|
||||
toplevel,
|
||||
initial_pointer_location: pointer.current_location(),
|
||||
initial_window_location,
|
||||
};
|
||||
|
||||
|
@ -204,13 +210,15 @@ pub fn init_shell(
|
|||
// TODO: touch move.
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
|
||||
let start_data = pointer.grab_start_data().unwrap();
|
||||
|
||||
let toplevel = SurfaceKind::Wl(surface);
|
||||
let initial_window_location = shell_window_map.borrow().location(&toplevel).unwrap();
|
||||
|
||||
let grab = MoveSurfaceGrab {
|
||||
start_data,
|
||||
window_map: shell_window_map.clone(),
|
||||
toplevel,
|
||||
initial_pointer_location: pointer.current_location(),
|
||||
initial_window_location,
|
||||
};
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ use wayland_server::{
|
|||
|
||||
use crate::wayland::{
|
||||
compositor::{roles::Role, CompositorToken},
|
||||
seat::{AxisFrame, PointerGrab, PointerInnerHandle, Seat},
|
||||
seat::{AxisFrame, GrabStartData, PointerGrab, PointerInnerHandle, Seat},
|
||||
};
|
||||
|
||||
use super::{with_source_metadata, DataDeviceData, DnDIconRole, SeatData};
|
||||
|
||||
pub(crate) struct DnDGrab<R> {
|
||||
start_data: GrabStartData,
|
||||
data_source: Option<wl_data_source::WlDataSource>,
|
||||
current_focus: Option<wl_surface::WlSurface>,
|
||||
pending_offers: Vec<wl_data_offer::WlDataOffer>,
|
||||
|
@ -27,6 +28,7 @@ pub(crate) struct DnDGrab<R> {
|
|||
|
||||
impl<R: Role<DnDIconRole> + 'static> DnDGrab<R> {
|
||||
pub(crate) fn new(
|
||||
start_data: GrabStartData,
|
||||
source: Option<wl_data_source::WlDataSource>,
|
||||
origin: wl_surface::WlSurface,
|
||||
seat: Seat,
|
||||
|
@ -35,6 +37,7 @@ impl<R: Role<DnDIconRole> + 'static> DnDGrab<R> {
|
|||
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
|
||||
) -> DnDGrab<R> {
|
||||
DnDGrab {
|
||||
start_data,
|
||||
data_source: source,
|
||||
current_focus: None,
|
||||
pending_offers: Vec::with_capacity(1),
|
||||
|
@ -222,6 +225,10 @@ impl<R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<R> {
|
|||
// we just forward the axis events as is
|
||||
handle.axis(details);
|
||||
}
|
||||
|
||||
fn start_data(&self) -> &GrabStartData {
|
||||
&self.start_data
|
||||
}
|
||||
}
|
||||
|
||||
struct OfferData {
|
||||
|
|
|
@ -69,7 +69,7 @@ use wayland_server::{
|
|||
|
||||
use crate::wayland::{
|
||||
compositor::{roles::Role, CompositorToken},
|
||||
seat::Seat,
|
||||
seat::{GrabStartData, Seat},
|
||||
};
|
||||
|
||||
mod data_source;
|
||||
|
@ -354,8 +354,13 @@ pub fn set_data_device_selection(seat: &Seat, mime_types: Vec<String>) {
|
|||
/// You'll receive events generated by the interaction of clients with your
|
||||
/// drag'n'drop in the provided callback. See [`ServerDndEvent`] for details about
|
||||
/// which events can be generated and what response is expected from you to them.
|
||||
pub fn start_dnd<C>(seat: &Seat, serial: u32, metadata: SourceMetadata, callback: C)
|
||||
where
|
||||
pub fn start_dnd<C>(
|
||||
seat: &Seat,
|
||||
serial: u32,
|
||||
start_data: GrabStartData,
|
||||
metadata: SourceMetadata,
|
||||
callback: C,
|
||||
) where
|
||||
C: FnMut(ServerDndEvent) + 'static,
|
||||
{
|
||||
// TODO: same question as in set_data_device_focus
|
||||
|
@ -366,7 +371,12 @@ where
|
|||
});
|
||||
if let Some(pointer) = seat.get_pointer() {
|
||||
pointer.set_grab(
|
||||
server_dnd_grab::ServerDnDGrab::new(metadata, seat.clone(), Rc::new(RefCell::new(callback))),
|
||||
server_dnd_grab::ServerDnDGrab::new(
|
||||
start_data,
|
||||
metadata,
|
||||
seat.clone(),
|
||||
Rc::new(RefCell::new(callback)),
|
||||
),
|
||||
serial,
|
||||
);
|
||||
return;
|
||||
|
@ -466,8 +476,10 @@ where
|
|||
source: source.clone(),
|
||||
icon: icon.clone(),
|
||||
});
|
||||
let start_data = pointer.grab_start_data().unwrap();
|
||||
pointer.set_grab(
|
||||
dnd_grab::DnDGrab::new(
|
||||
start_data,
|
||||
source,
|
||||
origin,
|
||||
seat.clone(),
|
||||
|
|
|
@ -7,7 +7,7 @@ use wayland_server::{
|
|||
NewResource,
|
||||
};
|
||||
|
||||
use crate::wayland::seat::{AxisFrame, PointerGrab, PointerInnerHandle, Seat};
|
||||
use crate::wayland::seat::{AxisFrame, GrabStartData, PointerGrab, PointerInnerHandle, Seat};
|
||||
|
||||
use super::{DataDeviceData, SeatData};
|
||||
|
||||
|
@ -37,6 +37,7 @@ pub enum ServerDndEvent {
|
|||
}
|
||||
|
||||
pub(crate) struct ServerDnDGrab<C: 'static> {
|
||||
start_data: GrabStartData,
|
||||
metadata: super::SourceMetadata,
|
||||
current_focus: Option<wl_surface::WlSurface>,
|
||||
pending_offers: Vec<wl_data_offer::WlDataOffer>,
|
||||
|
@ -47,11 +48,13 @@ pub(crate) struct ServerDnDGrab<C: 'static> {
|
|||
|
||||
impl<C: 'static> ServerDnDGrab<C> {
|
||||
pub(crate) fn new(
|
||||
start_data: GrabStartData,
|
||||
metadata: super::SourceMetadata,
|
||||
seat: Seat,
|
||||
callback: Rc<RefCell<C>>,
|
||||
) -> ServerDnDGrab<C> {
|
||||
ServerDnDGrab {
|
||||
start_data,
|
||||
metadata,
|
||||
current_focus: None,
|
||||
pending_offers: Vec::with_capacity(1),
|
||||
|
@ -212,6 +215,10 @@ where
|
|||
// we just forward the axis events as is
|
||||
handle.axis(details);
|
||||
}
|
||||
|
||||
fn start_data(&self) -> &GrabStartData {
|
||||
&self.start_data
|
||||
}
|
||||
}
|
||||
|
||||
struct OfferData {
|
||||
|
|
|
@ -49,7 +49,8 @@ mod pointer;
|
|||
pub use self::{
|
||||
keyboard::{keysyms, Error as KeyboardError, KeyboardHandle, Keysym, ModifiersState, XkbConfig},
|
||||
pointer::{
|
||||
AxisFrame, CursorImageRole, CursorImageStatus, PointerGrab, PointerHandle, PointerInnerHandle,
|
||||
AxisFrame, CursorImageRole, CursorImageStatus, GrabStartData, PointerGrab, PointerHandle,
|
||||
PointerInnerHandle,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -166,6 +166,15 @@ impl PointerHandle {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the start data for the grab, if any.
|
||||
pub fn grab_start_data(&self) -> Option<GrabStartData> {
|
||||
let guard = self.inner.borrow();
|
||||
match &guard.grab {
|
||||
GrabStatus::Active(_, g) => Some(g.start_data().clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Notify that the pointer moved
|
||||
///
|
||||
/// You provide the new location of the pointer, in the form of:
|
||||
|
@ -226,6 +235,19 @@ impl PointerHandle {
|
|||
}
|
||||
}
|
||||
|
||||
/// Data about the event that started the grab.
|
||||
#[derive(Clone)]
|
||||
pub struct GrabStartData {
|
||||
/// The focused surface and its location, if any, at the start of the grab.
|
||||
///
|
||||
/// The location coordinates are in the global compositor space.
|
||||
pub focus: Option<(WlSurface, (f64, f64))>,
|
||||
/// The button that initiated the grab.
|
||||
pub button: u32,
|
||||
/// The location of the click that initiated the grab, in the global compositor space.
|
||||
pub location: (f64, f64),
|
||||
}
|
||||
|
||||
/// A trait to implement a pointer grab
|
||||
///
|
||||
/// In some context, it is necessary to temporarily change the behavior of the pointer. This is
|
||||
|
@ -262,6 +284,8 @@ pub trait PointerGrab {
|
|||
);
|
||||
/// An axis scroll was reported
|
||||
fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame);
|
||||
/// The data about the event that started the grab.
|
||||
fn start_data(&self) -> &GrabStartData;
|
||||
}
|
||||
|
||||
/// This inner handle is accessed from inside a pointer grab logic, and directly
|
||||
|
@ -631,11 +655,14 @@ impl PointerGrab for DefaultGrab {
|
|||
time: u32,
|
||||
) {
|
||||
handle.button(button, state, serial, time);
|
||||
let current_focus = handle.current_focus().cloned();
|
||||
handle.set_grab(
|
||||
serial,
|
||||
ClickGrab {
|
||||
current_focus,
|
||||
start_data: GrabStartData {
|
||||
focus: handle.current_focus().cloned(),
|
||||
button,
|
||||
location: handle.current_location(),
|
||||
},
|
||||
pending_focus: None,
|
||||
},
|
||||
);
|
||||
|
@ -643,6 +670,9 @@ impl PointerGrab for DefaultGrab {
|
|||
fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) {
|
||||
handle.axis(details);
|
||||
}
|
||||
fn start_data(&self) -> &GrabStartData {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
// A click grab, basic grab started when an user clicks a surface
|
||||
|
@ -651,7 +681,7 @@ impl PointerGrab for DefaultGrab {
|
|||
// In case the user maintains several simultaneous clicks, release
|
||||
// the grab once all are released.
|
||||
struct ClickGrab {
|
||||
current_focus: Option<(WlSurface, (f64, f64))>,
|
||||
start_data: GrabStartData,
|
||||
pending_focus: Option<(WlSurface, (f64, f64))>,
|
||||
}
|
||||
|
||||
|
@ -666,7 +696,7 @@ impl PointerGrab for ClickGrab {
|
|||
) {
|
||||
// buffer the future focus, but maintain the current one
|
||||
self.pending_focus = focus;
|
||||
handle.motion(location, self.current_focus.clone(), serial, time);
|
||||
handle.motion(location, self.start_data.focus.clone(), serial, time);
|
||||
}
|
||||
fn button(
|
||||
&mut self,
|
||||
|
@ -685,4 +715,7 @@ impl PointerGrab for ClickGrab {
|
|||
fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) {
|
||||
handle.axis(details);
|
||||
}
|
||||
fn start_data(&self) -> &GrabStartData {
|
||||
&self.start_data
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue