wayland: implement new_constraint, remove_constraint and cursor_position_hint for PointerConstraintsHandler
new_constraint: check if the surface has pointer focus, keyboard focus, and if the pointer is within toplevel geometry or constraint region. If these conditions are met, then enable the constraint. remove_constraint: apply last cursor position hint that saved in seat. cursor_position_hint: save the cursor position hints provided by the client to the seat.
This commit is contained in:
parent
4fb7d49316
commit
208c2128cd
4 changed files with 156 additions and 42 deletions
|
|
@ -737,22 +737,23 @@ impl WorkspaceSet {
|
|||
surface: &WlSurface,
|
||||
) -> Option<(Rectangle<i32, Local>, Point<i32, Logical>)> {
|
||||
let mut root = surface.clone();
|
||||
loop {
|
||||
while let Some(parent) = get_parent(&root) {
|
||||
|
||||
while let Some(parent) = get_parent(&root) {
|
||||
root = parent;
|
||||
}
|
||||
|
||||
while smithay::wayland::compositor::get_role(&root) == Some(XDG_POPUP_ROLE) {
|
||||
let parent = with_states(&root, |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<XdgPopupSurfaceData>()
|
||||
.and_then(|m| m.lock().unwrap().parent.as_ref().cloned())
|
||||
});
|
||||
if let Some(parent) = parent {
|
||||
root = parent;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if smithay::wayland::compositor::get_role(&root) == Some(XDG_POPUP_ROLE)
|
||||
&& let Some(parent) = with_states(&root, |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<XdgPopupSurfaceData>()
|
||||
.and_then(|m| m.lock().unwrap().parent.as_ref().cloned())
|
||||
})
|
||||
{
|
||||
root = parent;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
self.sticky_layer
|
||||
|
|
|
|||
|
|
@ -17,8 +17,11 @@ use smithay::{
|
|||
pointer::{CursorImageAttributes, CursorImageStatus},
|
||||
},
|
||||
output::Output,
|
||||
reexports::{input::Device as InputDevice, wayland_server::DisplayHandle},
|
||||
utils::{Buffer, IsAlive, Monotonic, Point, Rectangle, Serial, Time, Transform},
|
||||
reexports::{
|
||||
input::Device as InputDevice,
|
||||
wayland_server::{DisplayHandle, protocol::wl_surface::WlSurface},
|
||||
},
|
||||
utils::{Buffer, IsAlive, Logical, Monotonic, Point, Rectangle, Serial, Time, Transform},
|
||||
wayland::compositor::with_states,
|
||||
};
|
||||
use tracing::warn;
|
||||
|
|
@ -178,6 +181,9 @@ struct ActiveOutput(pub Mutex<Output>);
|
|||
/// The output which currently has keyboard focus
|
||||
struct FocusedOutput(pub Mutex<Option<Output>>);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PointerConstraintHint(pub Mutex<Option<(WlSurface, Point<f64, Logical>)>>);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LastModifierChange(pub Mutex<Option<Serial>>);
|
||||
|
||||
|
|
@ -201,6 +207,7 @@ pub fn create_seat(
|
|||
userdata.insert_if_missing_threadsafe(CursorState::default);
|
||||
userdata.insert_if_missing_threadsafe(|| ActiveOutput(Mutex::new(output.clone())));
|
||||
userdata.insert_if_missing_threadsafe(|| FocusedOutput(Mutex::new(None)));
|
||||
userdata.insert_if_missing_threadsafe(PointerConstraintHint::default);
|
||||
userdata.insert_if_missing_threadsafe(|| Mutex::new(CursorImageStatus::default_named()));
|
||||
|
||||
// A lot of clients bind keyboard and pointer unconditionally once on launch..
|
||||
|
|
@ -252,6 +259,8 @@ pub trait SeatExt {
|
|||
fn supressed_buttons(&self) -> &SupressedButtons;
|
||||
fn modifiers_shortcut_queue(&self) -> &ModifiersShortcutQueue;
|
||||
fn last_modifier_change(&self) -> Option<Serial>;
|
||||
fn pointer_constraint_hint(&self) -> Option<(WlSurface, Point<f64, Logical>)>;
|
||||
fn set_pointer_constraint_hint(&self, hint: Option<(WlSurface, Point<f64, Logical>)>);
|
||||
|
||||
fn cursor_geometry(
|
||||
&self,
|
||||
|
|
@ -337,6 +346,23 @@ impl SeatExt for Seat<State> {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
fn pointer_constraint_hint(&self) -> Option<(WlSurface, Point<f64, Logical>)> {
|
||||
let lock = self.user_data().get::<PointerConstraintHint>().unwrap();
|
||||
let mut hint = lock.0.lock().unwrap();
|
||||
// Check if alive
|
||||
if let Some((ref surface, _)) = *hint
|
||||
&& !surface.alive()
|
||||
{
|
||||
*hint = None;
|
||||
}
|
||||
hint.clone()
|
||||
}
|
||||
|
||||
fn set_pointer_constraint_hint(&self, hint: Option<(WlSurface, Point<f64, Logical>)>) {
|
||||
let lock = self.user_data().get::<PointerConstraintHint>().unwrap();
|
||||
*lock.0.lock().unwrap() = hint;
|
||||
}
|
||||
|
||||
fn cursor_geometry(
|
||||
&self,
|
||||
loc: impl Into<Point<f64, Buffer>>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue