Skip to content

Commit 510e69f

Browse files
committed
HACK: xwm: filter out unmanaged windows on xdnd
1 parent 9a5912b commit 510e69f

File tree

5 files changed

+70
-20
lines changed

5 files changed

+70
-20
lines changed

src/desktop/space/wayland/x11.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
},
1111
ImportAll, Renderer,
1212
},
13-
desktop::{space::SpaceElement, utils::under_from_surface_tree, WindowSurfaceType},
13+
desktop::{space::SpaceElement, WindowSurfaceType},
1414
utils::{Logical, Physical, Point, Rectangle, Scale},
1515
wayland::seat::WaylandFocus,
1616
xwayland::X11Surface,
@@ -32,11 +32,7 @@ impl SpaceElement for X11Surface {
3232
}
3333

3434
fn is_in_input_region(&self, point: &Point<f64, Logical>) -> bool {
35-
if let Some(surface) = X11Surface::wl_surface(self).as_ref() {
36-
under_from_surface_tree(surface, *point, (0, 0), WindowSurfaceType::ALL).is_some()
37-
} else {
38-
false
39-
}
35+
X11Surface::surface_under(self, *point, (0, 0), WindowSurfaceType::all()).is_some()
4036
}
4137

4238
fn set_activate(&self, activated: bool) {

src/desktop/wayland/window.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -339,20 +339,29 @@ impl Window {
339339
surface_type: WindowSurfaceType,
340340
) -> Option<(wl_surface::WlSurface, Point<i32, Logical>)> {
341341
let point = point.into();
342-
if let Some(surface) = self.wl_surface() {
343-
if surface_type.contains(WindowSurfaceType::POPUP) {
344-
for (popup, location) in PopupManager::popups_for_surface(&surface) {
345-
let offset = self.geometry().loc + location - popup.geometry().loc;
346-
if let Some(result) =
347-
under_from_surface_tree(popup.wl_surface(), point, offset, surface_type)
348-
{
349-
return Some(result);
342+
343+
match &self.0.surface {
344+
WindowSurface::Wayland(surface) => {
345+
let surface = surface.wl_surface();
346+
if surface_type.contains(WindowSurfaceType::POPUP) {
347+
for (popup, location) in PopupManager::popups_for_surface(&surface) {
348+
let offset = self.geometry().loc + location - popup.geometry().loc;
349+
if let Some(result) =
350+
under_from_surface_tree(popup.wl_surface(), point, offset, surface_type)
351+
{
352+
return Some(result);
353+
}
350354
}
351355
}
352-
}
353356

354-
if surface_type.contains(WindowSurfaceType::TOPLEVEL) {
355-
return under_from_surface_tree(&surface, point, (0, 0), surface_type);
357+
if surface_type.contains(WindowSurfaceType::TOPLEVEL) {
358+
return under_from_surface_tree(&surface, point, (0, 0), surface_type);
359+
}
360+
}
361+
WindowSurface::X11(surface) => {
362+
if surface_type.contains(WindowSurfaceType::TOPLEVEL) {
363+
return surface.surface_under(point, (0, 0), surface_type);
364+
}
356365
}
357366
}
358367

src/xwayland/xwm/dnd.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use std::{
44
collections::HashMap,
55
fmt,
66
os::fd::OwnedFd,
7-
sync::{atomic::Ordering, Arc, Mutex, Weak},
7+
sync::{
8+
atomic::{AtomicBool, Ordering},
9+
Arc, Mutex, Weak,
10+
},
811
};
912

1013
use atomic_float::AtomicF64;
@@ -52,6 +55,7 @@ pub struct XWmDnd {
5255
pub selection: XWmSelection,
5356
pub active_offer: Option<XwmActiveOffer>,
5457
pub active_drag: Option<XwmActiveDrag>,
58+
pub xdnd_active: Arc<AtomicBool>,
5559
}
5660

5761
impl XWmDnd {
@@ -71,6 +75,7 @@ impl XWmDnd {
7175
selection,
7276
active_offer: None,
7377
active_drag: None,
78+
xdnd_active: Arc::new(AtomicBool::new(false)),
7479
})
7580
}
7681

@@ -131,12 +136,14 @@ impl XWmDnd {
131136

132137
let active_drag = xwm.dnd.active_drag.take().unwrap();
133138
active_drag.state.lock().unwrap().x11 = X11State::Finished;
139+
xwm.dnd.xdnd_active.store(false, Ordering::Release);
134140
}
135141
}
136142

137143
if event.owner == x11rb::NONE {
138144
trace!("XDND selection went away");
139145
xwm.dnd.active_drag.take();
146+
xwm.dnd.xdnd_active.store(false, Ordering::Release);
140147
return Ok(());
141148
}
142149

@@ -228,6 +235,7 @@ impl XWmDnd {
228235
state,
229236
pending_transfers: xwm.dnd.selection.pending_transfers.clone(),
230237
});
238+
xwm.dnd.xdnd_active.store(true, Ordering::Release);
231239

232240
// create the DndGrab
233241
match (ptr_grab, touch_grab) {
@@ -518,6 +526,7 @@ impl XWmDnd {
518526
if matches!(&state.wayland, &WlState::Cancelled | &WlState::Finished) {
519527
std::mem::drop(state);
520528
self.active_drag.take();
529+
self.xdnd_active.store(false, Ordering::Release);
521530
}
522531
}
523532
Ok(())
@@ -1085,6 +1094,7 @@ impl<D: XwmHandler + SeatHandler> DndFocus<D> for X11Surface {
10851094
// the x11 source was presumably dropped on an x11 window, so we are done here.
10861095
if let Some(active_drag) = xwm.dnd.active_drag.take() {
10871096
active_drag.state.lock().unwrap().x11 = X11State::Finished;
1097+
xwm.dnd.xdnd_active.store(false, Ordering::Release);
10881098
}
10891099
return;
10901100
};

src/xwayland/xwm/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,7 @@ where
13441344
Arc::downgrade(&conn),
13451345
xwm.atoms,
13461346
geometry,
1347+
xwm.dnd.xdnd_active.clone(),
13471348
);
13481349
surface.update_properties()?;
13491350
xwm.windows.push(surface.clone());

src/xwayland/xwm/surface.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use 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
};
1617
use atomic_float::AtomicF64;
1718
use encoding_rs::WINDOWS_1252;
1819
use std::{
1920
collections::HashSet,
20-
sync::{atomic::Ordering, Arc, Mutex, Weak},
21+
sync::{
22+
atomic::{AtomicBool, Ordering},
23+
Arc, Mutex, Weak,
24+
},
2125
};
2226
use tracing::warn;
2327
use 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

Comments
 (0)