feat(wayland): switch pointer focus dynamically
This commit is contained in:
@@ -99,6 +99,7 @@ impl Default for ToplevelState {
|
|||||||
pub struct PanelItem {
|
pub struct PanelItem {
|
||||||
node: Weak<Node>,
|
node: Weak<Node>,
|
||||||
client_credentials: Option<Credentials>,
|
client_credentials: Option<Credentials>,
|
||||||
|
toplevel_surface: WlWeak<WlSurface>,
|
||||||
pub toplevel: WlWeak<XdgToplevel>,
|
pub toplevel: WlWeak<XdgToplevel>,
|
||||||
pub cursor: Mutex<Option<WlWeak<WlSurface>>>,
|
pub cursor: Mutex<Option<WlWeak<WlSurface>>>,
|
||||||
seat_data: SeatData,
|
seat_data: SeatData,
|
||||||
@@ -119,6 +120,12 @@ impl PanelItem {
|
|||||||
let panel_item = Arc::new(PanelItem {
|
let panel_item = Arc::new(PanelItem {
|
||||||
node: Arc::downgrade(&node),
|
node: Arc::downgrade(&node),
|
||||||
client_credentials,
|
client_credentials,
|
||||||
|
toplevel_surface: toplevel
|
||||||
|
.data::<XdgToplevelData>()
|
||||||
|
.unwrap()
|
||||||
|
.xdg_surface_data
|
||||||
|
.wl_surface
|
||||||
|
.clone(),
|
||||||
toplevel: toplevel.downgrade(),
|
toplevel: toplevel.downgrade(),
|
||||||
cursor: Mutex::new(None),
|
cursor: Mutex::new(None),
|
||||||
seat_data,
|
seat_data,
|
||||||
@@ -283,7 +290,7 @@ impl PanelItem {
|
|||||||
let Some(pointer) = panel_item.seat_data.pointer() else { return Ok(()) };
|
let Some(pointer) = panel_item.seat_data.pointer() else { return Ok(()) };
|
||||||
|
|
||||||
pointer.leave(0, &wl_surface);
|
pointer.leave(0, &wl_surface);
|
||||||
*panel_item.seat_data.pointer_active.lock() = false;
|
*panel_item.seat_data.pointer_focus.lock() = None;
|
||||||
pointer.frame();
|
pointer.frame();
|
||||||
core_surface.flush_clients();
|
core_surface.flush_clients();
|
||||||
|
|
||||||
@@ -302,11 +309,21 @@ impl PanelItem {
|
|||||||
let mut position: Vector2<f64> = deserialize(data)?;
|
let mut position: Vector2<f64> = deserialize(data)?;
|
||||||
position.x = position.x.clamp(0.0, pointer_surface_size.x as f64);
|
position.x = position.x.clamp(0.0, pointer_surface_size.x as f64);
|
||||||
position.y = position.y.clamp(0.0, pointer_surface_size.y as f64);
|
position.y = position.y.clamp(0.0, pointer_surface_size.y as f64);
|
||||||
if panel_item.seat_data.pointer_active() {
|
|
||||||
pointer.motion(0, position.x, position.y);
|
let mut pointer_focus = panel_item.seat_data.pointer_focus.lock();
|
||||||
} else {
|
if let Some(old_surface) = pointer_focus
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|surf| surf.upgrade().ok())
|
||||||
|
.filter(|surf| surf.id() != wl_surface.id())
|
||||||
|
{
|
||||||
|
pointer.leave(0, &old_surface);
|
||||||
|
*pointer_focus = None;
|
||||||
|
}
|
||||||
|
if pointer_focus.is_none() {
|
||||||
pointer.enter(0, &wl_surface, position.x, position.y);
|
pointer.enter(0, &wl_surface, position.x, position.y);
|
||||||
*panel_item.seat_data.pointer_active.lock() = true;
|
*pointer_focus = Some(wl_surface.downgrade());
|
||||||
|
} else {
|
||||||
|
pointer.motion(0, position.x, position.y);
|
||||||
}
|
}
|
||||||
pointer.frame();
|
pointer.frame();
|
||||||
core_surface.flush_clients();
|
core_surface.flush_clients();
|
||||||
|
|||||||
@@ -17,12 +17,14 @@ use smithay::{
|
|||||||
wl_surface::WlSurface,
|
wl_surface::WlSurface,
|
||||||
wl_touch::{self, WlTouch},
|
wl_touch::{self, WlTouch},
|
||||||
},
|
},
|
||||||
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
|
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Weak as WlWeak,
|
||||||
},
|
},
|
||||||
wayland::compositor,
|
wayland::compositor,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::{
|
||||||
use std::{ops::Deref, sync::Weak};
|
ops::Deref,
|
||||||
|
sync::{Arc, Weak},
|
||||||
|
};
|
||||||
use xkbcommon::xkb::{self, Keymap};
|
use xkbcommon::xkb::{self, Keymap};
|
||||||
|
|
||||||
pub struct Cursor {
|
pub struct Cursor {
|
||||||
@@ -79,7 +81,7 @@ impl SeatData {
|
|||||||
global_id: OnceCell::new(),
|
global_id: OnceCell::new(),
|
||||||
panel_item: OnceCell::new(),
|
panel_item: OnceCell::new(),
|
||||||
pointer: OnceCell::new(),
|
pointer: OnceCell::new(),
|
||||||
pointer_active: Mutex::new(false),
|
pointer_focus: Mutex::new(None),
|
||||||
keyboard: OnceCell::new(),
|
keyboard: OnceCell::new(),
|
||||||
keyboard_info: Mutex::new(None),
|
keyboard_info: Mutex::new(None),
|
||||||
touch: OnceCell::new(),
|
touch: OnceCell::new(),
|
||||||
@@ -106,7 +108,7 @@ pub struct SeatDataInner {
|
|||||||
global_id: OnceCell<GlobalId>,
|
global_id: OnceCell<GlobalId>,
|
||||||
pub panel_item: OnceCell<Weak<PanelItem>>,
|
pub panel_item: OnceCell<Weak<PanelItem>>,
|
||||||
pointer: OnceCell<WlPointer>,
|
pointer: OnceCell<WlPointer>,
|
||||||
pub pointer_active: Mutex<bool>,
|
pub pointer_focus: Mutex<Option<WlWeak<WlSurface>>>,
|
||||||
keyboard: OnceCell<WlKeyboard>,
|
keyboard: OnceCell<WlKeyboard>,
|
||||||
pub keyboard_info: Mutex<Option<KeyboardInfo>>,
|
pub keyboard_info: Mutex<Option<KeyboardInfo>>,
|
||||||
touch: OnceCell<WlTouch>,
|
touch: OnceCell<WlTouch>,
|
||||||
@@ -116,7 +118,13 @@ impl SeatDataInner {
|
|||||||
self.pointer.get()
|
self.pointer.get()
|
||||||
}
|
}
|
||||||
pub fn pointer_active(&self) -> bool {
|
pub fn pointer_active(&self) -> bool {
|
||||||
*self.pointer_active.lock()
|
self.pointer_focus.lock().is_some()
|
||||||
|
}
|
||||||
|
pub fn pointer_focused_surface(&self) -> Option<WlSurface> {
|
||||||
|
self.pointer_focus
|
||||||
|
.lock()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|focus| focus.upgrade().ok())
|
||||||
}
|
}
|
||||||
pub fn keyboard(&self) -> Option<&WlKeyboard> {
|
pub fn keyboard(&self) -> Option<&WlKeyboard> {
|
||||||
self.keyboard.get()
|
self.keyboard.get()
|
||||||
|
|||||||
Reference in New Issue
Block a user