add a window surface type

This commit is contained in:
Christian Meissl 2022-01-08 12:22:59 +01:00
parent 050c648bff
commit 8edcdf5cd0
3 changed files with 52 additions and 22 deletions

View File

@ -21,6 +21,8 @@ use std::{
sync::{Arc, Mutex, Weak}, sync::{Arc, Mutex, Weak},
}; };
use super::WindowSurfaceType;
crate::utils::ids::id_gen!(next_layer_id, LAYER_ID, LAYER_IDS); crate::utils::ids::id_gen!(next_layer_id, LAYER_ID, LAYER_IDS);
/// Map of [`LayerSurface`]s on an [`Output`] /// Map of [`LayerSurface`]s on an [`Output`]
@ -428,6 +430,7 @@ impl LayerSurface {
pub fn surface_under<P: Into<Point<f64, Logical>>>( pub fn surface_under<P: Into<Point<f64, Logical>>>(
&self, &self,
point: P, point: P,
surface_type: WindowSurfaceType,
) -> Option<(WlSurface, Point<i32, Logical>)> { ) -> Option<(WlSurface, Point<i32, Logical>)> {
let point = point.into(); let point = point.into();
if let Some(surface) = self.get_surface() { if let Some(surface) = self.get_surface() {
@ -438,13 +441,13 @@ impl LayerSurface {
{ {
if let Some(result) = popup if let Some(result) = popup
.get_surface() .get_surface()
.and_then(|surface| under_from_surface_tree(surface, point, location)) .and_then(|surface| under_from_surface_tree(surface, point, location, surface_type))
{ {
return Some(result); return Some(result);
} }
} }
under_from_surface_tree(surface, point, (0, 0)) under_from_surface_tree(surface, point, (0, 0), surface_type)
} else { } else {
None None
} }

View File

@ -16,6 +16,8 @@ use wayland_server::protocol::wl_surface;
use std::cell::RefCell; use std::cell::RefCell;
use super::WindowSurfaceType;
impl SurfaceState { impl SurfaceState {
/// Returns the size of the surface. /// Returns the size of the surface.
pub fn size(&self) -> Option<Size<i32, Logical>> { pub fn size(&self) -> Option<Size<i32, Logical>> {
@ -174,6 +176,7 @@ pub fn under_from_surface_tree<P>(
surface: &wl_surface::WlSurface, surface: &wl_surface::WlSurface,
point: Point<f64, Logical>, point: Point<f64, Logical>,
location: P, location: P,
surface_type: WindowSurfaceType,
) -> Option<(wl_surface::WlSurface, Point<i32, Logical>)> ) -> Option<(wl_surface::WlSurface, Point<i32, Logical>)>
where where
P: Into<Point<i32, Logical>>, P: Into<Point<i32, Logical>>,
@ -191,17 +194,23 @@ where
location += current.location; location += current.location;
} }
let contains_the_point = data if states.role == Some("subsurface") || surface_type.contains(WindowSurfaceType::TOPLEVEL) {
.map(|data| { let contains_the_point = data
data.borrow() .map(|data| {
.contains_point(&*states.cached_state.current(), point - location.to_f64()) data.borrow()
}) .contains_point(&*states.cached_state.current(), point - location.to_f64())
.unwrap_or(false); })
if contains_the_point { .unwrap_or(false);
*found.borrow_mut() = Some((wl_surface.clone(), location)); if contains_the_point {
*found.borrow_mut() = Some((wl_surface.clone(), location));
}
} }
TraversalAction::DoChildren(location) if surface_type.contains(WindowSurfaceType::SUBSURFACE) {
TraversalAction::DoChildren(location)
} else {
TraversalAction::SkipChildren
}
}, },
|_, _, _| {}, |_, _, _| {},
|_, _, _| { |_, _, _| {

View File

@ -109,6 +109,21 @@ impl Hash for Window {
} }
} }
bitflags::bitflags! {
/// Defines the surface types that can be
/// queried with [`Window::surface_under`]
pub struct WindowSurfaceType: u32 {
/// Include the toplevel surface
const TOPLEVEL = 1;
/// Include all subsurfaces
const SUBSURFACE = 2;
/// Include all popup surfaces
const POPUP = 4;
/// Query all surfaces
const ALL = Self::TOPLEVEL.bits | Self::SUBSURFACE.bits | Self::POPUP.bits;
}
}
impl Window { impl Window {
/// Construct a new [`Window`] from a given compatible toplevel surface /// Construct a new [`Window`] from a given compatible toplevel surface
pub fn new(toplevel: Kind) -> Window { pub fn new(toplevel: Kind) -> Window {
@ -222,24 +237,27 @@ impl Window {
pub fn surface_under<P: Into<Point<f64, Logical>>>( pub fn surface_under<P: Into<Point<f64, Logical>>>(
&self, &self,
point: P, point: P,
surface_type: WindowSurfaceType,
) -> Option<(wl_surface::WlSurface, Point<i32, Logical>)> { ) -> Option<(wl_surface::WlSurface, Point<i32, Logical>)> {
let point = point.into(); let point = point.into();
if let Some(surface) = self.0.toplevel.get_surface() { if let Some(surface) = self.0.toplevel.get_surface() {
for (popup, location) in PopupManager::popups_for_surface(surface) if surface_type.contains(WindowSurfaceType::POPUP) {
.ok() for (popup, location) in PopupManager::popups_for_surface(surface)
.into_iter() .ok()
.flatten() .into_iter()
{ .flatten()
let offset = self.geometry().loc + location - popup.geometry().loc;
if let Some(result) = popup
.get_surface()
.and_then(|surface| under_from_surface_tree(surface, point, offset))
{ {
return Some(result); let offset = self.geometry().loc + location - popup.geometry().loc;
if let Some(result) = popup
.get_surface()
.and_then(|surface| under_from_surface_tree(surface, point, offset, surface_type))
{
return Some(result);
}
} }
} }
under_from_surface_tree(surface, point, (0, 0)) under_from_surface_tree(surface, point, (0, 0), surface_type)
} else { } else {
None None
} }