Update pointer constraints handling

This commit is contained in:
Ottatop 2024-12-17 17:00:35 -06:00
parent 7d6c1a25a7
commit f33c7bbd78
2 changed files with 21 additions and 46 deletions

View file

@ -22,8 +22,8 @@ use smithay::{
delegate_security_context, delegate_shm, delegate_tablet_manager, delegate_viewporter, delegate_security_context, delegate_shm, delegate_tablet_manager, delegate_viewporter,
delegate_xdg_activation, delegate_xwayland_keyboard_grab, delegate_xwayland_shell, delegate_xdg_activation, delegate_xwayland_keyboard_grab, delegate_xwayland_shell,
desktop::{ desktop::{
self, find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output, PopupKind, self, find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output,
PopupManager, WindowSurfaceType, space::SpaceElement, PopupKind, PopupManager, WindowSurfaceType,
}, },
input::{ input::{
keyboard::LedState, keyboard::LedState,
@ -914,7 +914,24 @@ impl PointerConstraintsHandler for State {
pointer: &PointerHandle<Self>, pointer: &PointerHandle<Self>,
location: Point<f64, Logical>, location: Point<f64, Logical>,
) { ) {
todo!() if with_pointer_constraint(surface, pointer, |constraint| {
constraint.is_some_and(|c| c.is_active())
}) {
// TODO: cache the current focus's location so you don't have to get it on demand
// through the current pointer location
let Some((current_focus, current_focus_loc)) = self
.pinnacle
.pointer_focus_target_under(pointer.current_location())
else {
return;
};
if current_focus.wl_surface().as_deref() != Some(surface) {
return;
}
pointer.set_location(current_focus_loc + location);
}
} }
} }
delegate_pointer_constraints!(State); delegate_pointer_constraints!(State);

View file

@ -124,9 +124,6 @@ pub struct InputState {
pub libinput_settings: HashMap<Discriminant<Setting>, Box<dyn Fn(&mut input::Device) + Send>>, pub libinput_settings: HashMap<Discriminant<Setting>, Box<dyn Fn(&mut input::Device) + Send>>,
/// All libinput devices that have been connected /// All libinput devices that have been connected
pub libinput_devices: Vec<input::Device>, pub libinput_devices: Vec<input::Device>,
locked_pointer_position_hint: Option<Point<f64, Logical>>,
// Keys that were used in a keybind and should not be released // Keys that were used in a keybind and should not be released
no_release_keys: HashSet<u32>, no_release_keys: HashSet<u32>,
} }
@ -340,46 +337,7 @@ impl State {
let location = pointer.current_location(); let location = pointer.current_location();
let surface_under = self.pinnacle.pointer_focus_target_under(location); let surface_under = self.pinnacle.pointer_focus_target_under(location);
// PERF: I'm not really a fan of polling all the time looking for locked pointer
// updates, but there doesn't seem to be a great way to get the final cursor
// position hint before destruction. I experimented with a
// `PointerConstraintsHandler::constraint_destroyed` method but doing so
// required threading the state through a bunch of different functions.
// Additionally, `PointerConstraintRef::deactivate` gets called in `WlSurface::leave`,
// so that would require all compositors implement `PointerConstraintsHandler`
// which seems very scuffed.
if pointer.current_focus().as_ref() == surface_under.as_ref().map(|s| &s.0) { if pointer.current_focus().as_ref() == surface_under.as_ref().map(|s| &s.0) {
if let Some((surf, surf_loc)) =
surface_under.and_then(|(foc, loc)| Some((foc.wl_surface()?.into_owned(), loc)))
{
let unlocked = with_pointer_constraint(&surf, &pointer, |constraint| {
let Some(constraint) = constraint else {
return true;
};
if !constraint.is_active() {
return true;
}
match &*constraint {
PointerConstraint::Confined(_) => true,
PointerConstraint::Locked(locked) => {
self.pinnacle.input_state.locked_pointer_position_hint =
locked.cursor_position_hint();
false
}
}
});
if unlocked {
if let Some(hint) = self
.pinnacle
.input_state
.locked_pointer_position_hint
.take()
{
self.warp_cursor_to_global_loc(hint + surf_loc.to_f64());
}
}
}
return; return;
} }
@ -809,7 +767,7 @@ impl State {
let Some(constraint) = constraint else { let Some(constraint) = constraint else {
return; return;
}; };
tracing::debug!(constraint = ?*constraint);
if !constraint.is_active() { if !constraint.is_active() {
return; return;
} }