Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions anvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ use smithay::{
KeyboardShortcutsInhibitHandler, KeyboardShortcutsInhibitState, KeyboardShortcutsInhibitor,
},
output::{OutputHandler, OutputManagerState},
pointer_constraints::{PointerConstraintsHandler, PointerConstraintsState, with_pointer_constraint},
pointer_constraints::{
PointerConstraint, PointerConstraintsHandler, PointerConstraintsState, with_pointer_constraint,
},
pointer_gestures::PointerGesturesState,
presentation::PresentationState,
relative_pointer::RelativePointerManagerState,
Expand Down Expand Up @@ -380,23 +382,26 @@ impl<BackendData: Backend> PointerConstraintsHandler for AnvilState<BackendData>
}
}

fn remove_constraint(&mut self, surface: &WlSurface, pointer: &PointerHandle<Self>) {
if with_pointer_constraint(surface, pointer, |constraint| constraint.is_none()) {
if let Some((hint_surface, hint_location)) = &self.cursor_position_hint {
let origin = self
.space
.elements()
.find_map(|window| {
(window.wl_surface().as_deref() == Some(hint_surface)).then(|| window.geometry())
})
.unwrap_or_default()
.loc
.to_f64();

pointer.set_location(origin + *hint_location);
}
self.cursor_position_hint = None;
fn remove_constraint(
&mut self,
_surface: &WlSurface,
pointer: &PointerHandle<Self>,
_constraint: Option<&PointerConstraint>,
) {
if let Some((hint_surface, hint_location)) = &self.cursor_position_hint {
let origin = self
.space
.elements()
.find_map(|window| {
(window.wl_surface().as_deref() == Some(hint_surface)).then(|| window.geometry())
})
.unwrap_or_default()
.loc
.to_f64();

pointer.set_location(origin + *hint_location);
}
self.cursor_position_hint = None;
}

fn cursor_position_hint(
Expand Down
3 changes: 3 additions & 0 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use smithay::{
CompositorClientState, CompositorHandler, CompositorState, SurfaceAttributes, TraversalAction,
with_surface_tree_downward,
},
pointer_constraints::PointerConstraintsHandler,
selection::{
SelectionHandler,
data_device::{DataDeviceHandler, DataDeviceState, WaylandDndGrabHandler},
Expand Down Expand Up @@ -116,6 +117,8 @@ impl SeatHandler for App {
fn cursor_image(&mut self, _seat: &Seat<Self>, _image: smithay::input::pointer::CursorImageStatus) {}
}

impl PointerConstraintsHandler for App {}

struct App {
compositor_state: CompositorState,
xdg_shell_state: XdgShellState,
Expand Down
3 changes: 3 additions & 0 deletions examples/seat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use smithay::reexports::wayland_server::{
protocol::wl_surface::WlSurface,
};
use smithay::wayland::compositor::{CompositorClientState, CompositorHandler, CompositorState};
use smithay::wayland::pointer_constraints::PointerConstraintsHandler;

struct App {
compositor_state: CompositorState,
Expand All @@ -27,6 +28,8 @@ impl SeatHandler for App {
fn cursor_image(&mut self, _seat: &Seat<Self>, _image: smithay::input::pointer::CursorImageStatus) {}
}

impl PointerConstraintsHandler for App {}

fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut display: Display<App> = Display::new()?;
let dh = display.handle();
Expand Down
3 changes: 3 additions & 0 deletions smallvil/src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use smithay::reexports::wayland_server::Resource;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::Serial;
use smithay::wayland::output::OutputHandler;
use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
use smithay::wayland::selection::SelectionHandler;
use smithay::wayland::selection::data_device::{
DataDeviceHandler, DataDeviceState, WaylandDndGrabHandler, set_data_device_focus,
Expand All @@ -37,6 +38,8 @@ impl SeatHandler for Smallvil {
}
}

impl PointerConstraintsHandler for Smallvil {}

//
// Wl Data Device
//
Expand Down
2 changes: 2 additions & 0 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ impl<D: SeatHandler + 'static> Seat<D> {
///
/// ```no_run
/// # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
/// # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
/// # use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
/// # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
/// #
Expand All @@ -672,6 +673,7 @@ impl<D: SeatHandler + 'static> Seat<D> {
/// # fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
/// # fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
/// # }
/// # impl PointerConstraintsHandler for State {}
/// # let mut seat: Seat<State> = unimplemented!();
/// let touch_handle = seat.add_touch();
/// ```
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/idle_notify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! use smithay::wayland::idle_notify::{IdleNotifierState, IdleNotifierHandler};
//! # use smithay::input::{Seat, SeatHandler, SeatState, pointer::CursorImageStatus};
//! # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
//! # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
//!
//! struct State { idle_notifier: IdleNotifierState<Self> }
//! # let mut event_loop = smithay::reexports::calloop::EventLoop::<State>::try_new().unwrap();
Expand All @@ -33,6 +34,7 @@
//! # fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
//! # fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
//! # }
//! # impl PointerConstraintsHandler for State {}
//! impl IdleNotifierHandler for State {
//! fn idle_notifier_state(&mut self) -> &mut IdleNotifierState<Self> {
//! &mut self.idle_notifier
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/input_method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! use smithay::wayland::input_method::{InputMethodManagerState, InputMethodHandler, PopupSurface};
//! use smithay::wayland::text_input::TextInputManagerState;
//! use smithay::reexports::wayland_server::{Display, protocol::wl_surface::WlSurface};
//! # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
//! # use smithay::reexports::wayland_server::Client;
//! use smithay::utils::{Rectangle, Logical};
//!
Expand Down Expand Up @@ -41,6 +42,7 @@
//! fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
//! fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
//! }
//! # impl PointerConstraintsHandler for State {}
//!
//! # impl CompositorHandler for State {
//! # fn compositor_state(&mut self) -> &mut CompositorState { unimplemented!() }
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/keyboard_shortcuts_inhibit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ pub trait KeyboardShortcutsInhibitorSeat {
/// use smithay::wayland::keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat;
/// # use smithay::input::{SeatHandler, SeatState, pointer::CursorImageStatus};
/// # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
/// # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
/// # struct State;
/// # impl CompositorHandler for State {
/// # fn compositor_state(&mut self) -> &mut CompositorState { unimplemented!() }
Expand All @@ -199,6 +200,7 @@ pub trait KeyboardShortcutsInhibitorSeat {
/// # fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
/// # fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
/// # }
/// # impl PointerConstraintsHandler for State {}
///
/// # let wl_surface: WlSurface = todo!();
///
Expand Down
50 changes: 33 additions & 17 deletions src/wayland/pointer_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ pub trait PointerConstraintsHandler: SeatHandler {
/// Pointer lock or confinement constraint created for `pointer` on `surface`
///
/// Use [`with_pointer_constraint`] to access the constraint.
fn new_constraint(&mut self, surface: &WlSurface, pointer: &PointerHandle<Self>);
fn new_constraint(&mut self, _surface: &WlSurface, _pointer: &PointerHandle<Self>) {}

/// Constraint removed for `pointer` on `surface`
/// Pointer constraint removed for `pointer` on `surface`
///
/// Use [`with_pointer_constraint`] to access the constraint.
fn remove_constraint(&mut self, surface: &WlSurface, pointer: &PointerHandle<Self>);
/// Don't use [`with_pointer_constraint`] to access the constraint
fn remove_constraint(
&mut self,
_surface: &WlSurface,
_pointer: &PointerHandle<Self>,
_constraint: Option<&PointerConstraint>,
) {
}

/// The client holding a LockedPointer has committed a cursor position hint.
///
Expand All @@ -49,10 +55,11 @@ pub trait PointerConstraintsHandler: SeatHandler {
/// Use [`with_pointer_constraint`] to access the constraint and check if it is active.
fn cursor_position_hint(
&mut self,
surface: &WlSurface,
pointer: &PointerHandle<Self>,
location: Point<f64, Logical>,
);
_surface: &WlSurface,
_pointer: &PointerHandle<Self>,
_location: Point<f64, Logical>,
) {
}
}

/// Constraint confining pointer to a region of the surface
Expand Down Expand Up @@ -121,7 +128,7 @@ impl<D: SeatHandler + 'static> ops::Deref for PointerConstraintRef<'_, D> {
}
}

impl<D: SeatHandler + 'static> PointerConstraintRef<'_, D> {
impl<D: SeatHandler + PointerConstraintsHandler + 'static> PointerConstraintRef<'_, D> {
/// Send `locked`/`unlocked`
///
/// This is not sent automatically since compositors may have different
Expand All @@ -147,7 +154,7 @@ impl<D: SeatHandler + 'static> PointerConstraintRef<'_, D> {
///
/// This is sent automatically when the surface loses pointer focus, but
/// may also be invoked while the surface is focused.
pub fn deactivate(self) {
pub fn deactivate(self, state: &mut D, surface: &WlSurface, pointer: &PointerHandle<D>) {
let deactivated = match self.entry.get() {
PointerConstraint::Confined(confined) => {
if confined.active.swap(false, Ordering::SeqCst) {
Expand All @@ -167,6 +174,11 @@ impl<D: SeatHandler + 'static> PointerConstraintRef<'_, D> {
}
};

if deactivated {
let constraint = self.entry.get();
state.remove_constraint(surface, pointer, Some(constraint));
}

if deactivated && self.lifetime() == WEnum::Value(Lifetime::Oneshot) {
self.entry.remove_entry();
}
Expand Down Expand Up @@ -354,17 +366,19 @@ fn remove_constraint<D: SeatHandler + PointerConstraintsHandler + 'static>(
surface: &WlSurface,
pointer: &PointerHandle<D>,
) {
let is_removed = with_constraint_data::<D, _, _>(surface, |data| {
let (is_removed, constraint) = with_constraint_data::<D, _, _>(surface, |data| {
if let Some(data) = data {
if let Some(_constraint) = data.constraints.remove(pointer) {
return true;
if let Some(constraint) = data.constraints.remove(pointer) {
return (true, Some(constraint));
}
}
false
(false, None)
});

if is_removed {
state.remove_constraint(surface, pointer);
if let Some(constraint) = constraint {
state.remove_constraint(surface, pointer, Some(&constraint));
}
}
}

Expand Down Expand Up @@ -476,7 +490,8 @@ where

impl<D> Dispatch2<ZwpConfinedPointerV1, D> for PointerConstraintUserData<D>
where
D: SeatHandler + PointerConstraintsHandler,
D: SeatHandler,
D: PointerConstraintsHandler,
D: 'static,
{
fn request(
Expand Down Expand Up @@ -523,7 +538,8 @@ where

impl<D> Dispatch2<ZwpLockedPointerV1, D> for PointerConstraintUserData<D>
where
D: SeatHandler + PointerConstraintsHandler,
D: SeatHandler,
D: PointerConstraintsHandler,
D: 'static,
{
fn request(
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/pointer_warp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
//! #
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
//! # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
//! # use smithay::reexports::wayland_server::Client;
//! # impl CompositorHandler for State {
//! # fn compositor_state(&mut self) -> &mut CompositorState { unimplemented!() }
Expand All @@ -30,6 +31,7 @@
//! # todo!()
//! # }
//! # }
//! # impl PointerConstraintsHandler for State {}
//!
//! PointerWarpManager::new::<State>(
//! &display.handle(),
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/seat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! use smithay::reexports::wayland_server::{Display, protocol::wl_surface::WlSurface};
//! # use smithay::wayland::compositor::{CompositorHandler, CompositorState, CompositorClientState};
//! # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
//! # use smithay::reexports::wayland_server::Client;
//!
//! # struct State { seat_state: SeatState<Self> };
Expand Down Expand Up @@ -42,6 +43,7 @@
//! // ...
//! }
//! }
//! # impl PointerConstraintsHandler for State {}
//!
//! smithay::delegate_dispatch2!(State);
//!
Expand Down
13 changes: 9 additions & 4 deletions src/wayland/seat/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use crate::{
},
},
utils::{Client as ClientCoords, Point, Serial, iter::new_locked_obj_iter_from_vec},
wayland::{Dispatch2, compositor, pointer_constraints::with_pointer_constraint},
wayland::{
Dispatch2, compositor,
pointer_constraints::{PointerConstraintsHandler, with_pointer_constraint},
},
};

use super::{SeatHandler, WaylandFocus};
Expand Down Expand Up @@ -235,22 +238,24 @@ impl WlPointerHandle {

impl<D> PointerTarget<D> for WlSurface
where
D: SeatHandler + 'static,
D: SeatHandler,
D: PointerConstraintsHandler,
D: 'static,
{
fn enter(&self, seat: &Seat<D>, _data: &mut D, event: &MotionEvent) {
if let Some(pointer) = seat.get_pointer() {
pointer.wl_pointer.enter::<D>(self, event);
}
}

fn leave(&self, seat: &Seat<D>, _data: &mut D, serial: Serial, time: u32) {
fn leave(&self, seat: &Seat<D>, data: &mut D, serial: Serial, time: u32) {
if let Some(pointer) = seat.get_pointer() {
pointer.wp_pointer_gestures.leave::<D>(self, serial, time);
pointer.wl_pointer.leave(self, serial, time);

with_pointer_constraint(self, &pointer, |constraint| {
if let Some(constraint) = constraint {
constraint.deactivate();
constraint.deactivate(data, self, &pointer);
}
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/selection/data_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
//! use smithay::wayland::selection::data_device::{WaylandDndGrabHandler, DataDeviceState, DataDeviceHandler};
//! # use smithay::input::{Seat, SeatState, SeatHandler, pointer::CursorImageStatus};
//! # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
//! # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
//!
//! # struct State { data_device_state: DataDeviceState }
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
Expand All @@ -57,6 +58,7 @@
//! # fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
//! # fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
//! # }
//! # impl PointerConstraintsHandler for State {}
//! impl WaylandDndGrabHandler for State {
//! // ... implement `dnd_requested` to handle drag&drop operations
//! }
Expand Down
2 changes: 2 additions & 0 deletions src/wayland/selection/ext_data_control/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//! use smithay::wayland::selection::ext_data_control::{DataControlState, DataControlHandler};
//! # use smithay::input::{Seat, SeatHandler, SeatState, pointer::CursorImageStatus};
//! # use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
//! # use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
//!
//! # struct State { data_control_state: DataControlState }
//! # let mut display = wayland_server::Display::<State>::new().unwrap();
Expand All @@ -38,6 +39,7 @@
//! # fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&WlSurface>) { unimplemented!() }
//! # fn cursor_image(&mut self, seat: &Seat<Self>, image: CursorImageStatus) { unimplemented!() }
//! # }
//! # impl PointerConstraintsHandler for State {}
//! impl SelectionHandler for State {
//! type SelectionUserData = ();
//! }
Expand Down
Loading
Loading