11use crate :: {
22 backend:: input:: KeyState ,
3+ desktop:: { utils:: under_from_surface_tree, WindowSurfaceType } ,
34 input:: {
45 keyboard:: { KeyboardTarget , KeysymHandle , ModifiersState } ,
56 pointer:: {
@@ -10,14 +11,17 @@ use crate::{
1011 touch:: TouchTarget ,
1112 Seat , SeatHandler ,
1213 } ,
13- utils:: { user_data:: UserDataMap , Client , IsAlive , Logical , Rectangle , Serial , Size } ,
14+ utils:: { user_data:: UserDataMap , Client , IsAlive , Logical , Point , Rectangle , Serial , Size } ,
1415 wayland:: { compositor, seat:: keyboard:: enter_internal} ,
1516} ;
1617use atomic_float:: AtomicF64 ;
1718use encoding_rs:: WINDOWS_1252 ;
1819use std:: {
1920 collections:: HashSet ,
20- sync:: { atomic:: Ordering , Arc , Mutex , Weak } ,
21+ sync:: {
22+ atomic:: { AtomicBool , Ordering } ,
23+ Arc , Mutex , Weak ,
24+ } ,
2125} ;
2226use tracing:: warn;
2327use wayland_server:: protocol:: wl_surface:: WlSurface ;
@@ -48,6 +52,7 @@ pub struct X11Surface {
4852 pub ( super ) conn : Weak < RustConnection > ,
4953 pub ( super ) atoms : super :: Atoms ,
5054 pub ( crate ) state : Arc < Mutex < SharedSurfaceState > > ,
55+ pub ( super ) xdnd_active : Arc < AtomicBool > ,
5156 user_data : Arc < UserDataMap > ,
5257}
5358
@@ -182,6 +187,7 @@ impl X11Surface {
182187 conn : Weak < RustConnection > ,
183188 atoms : super :: Atoms ,
184189 geometry : Rectangle < i32 , Logical > ,
190+ xdnd_active : Arc < AtomicBool > ,
185191 ) -> X11Surface {
186192 X11Surface {
187193 xwm : xwm. map ( |wm| wm. id ) ,
@@ -212,6 +218,7 @@ impl X11Surface {
212218 opacity : None ,
213219 pending_enter : None ,
214220 } ) ) ,
221+ xdnd_active,
215222 user_data : Arc :: new ( UserDataMap :: new ( ) ) ,
216223 }
217224 }
@@ -1018,6 +1025,33 @@ impl X11Surface {
10181025 }
10191026 Ok ( 0 )
10201027 }
1028+
1029+ /// Returns the topmost (sub-)surface under a given position of the surface.
1030+ ///
1031+ /// In case the window is not mapped or is unmanaged while an XDND operation is on-going the point [`None`] is returned.
1032+ ///
1033+ /// - `point` has to be the position to query, relative to (0, 0) of the given surface + `location`.
1034+ /// - `location` can be used to offset the returned point.
1035+ /// - `surface_type` can be used to filter the underlying surface tree
1036+ #[ cfg( feature = "desktop" ) ]
1037+ pub fn surface_under (
1038+ & self ,
1039+ point : Point < f64 , Logical > ,
1040+ location : impl Into < Point < i32 , Logical > > ,
1041+ surface_type : WindowSurfaceType ,
1042+ ) -> Option < ( WlSurface , Point < i32 , Logical > ) > {
1043+ if !surface_type. contains ( WindowSurfaceType :: TOPLEVEL ) {
1044+ return None ;
1045+ }
1046+ if self . xdnd_active . load ( Ordering :: Acquire ) && self . is_override_redirect ( ) {
1047+ return None ;
1048+ }
1049+ if let Some ( surface) = X11Surface :: wl_surface ( self ) . as_ref ( ) {
1050+ return under_from_surface_tree ( surface, point, location, surface_type) ;
1051+ }
1052+
1053+ return None ;
1054+ }
10211055}
10221056
10231057/// Trait for objects, that represent an x11 window in some shape or form
0 commit comments