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,6 +194,7 @@ where
location += current.location; location += current.location;
} }
if states.role == Some("subsurface") || surface_type.contains(WindowSurfaceType::TOPLEVEL) {
let contains_the_point = data let contains_the_point = data
.map(|data| { .map(|data| {
data.borrow() data.borrow()
@ -200,8 +204,13 @@ where
if contains_the_point { if contains_the_point {
*found.borrow_mut() = Some((wl_surface.clone(), location)); *found.borrow_mut() = Some((wl_surface.clone(), location));
} }
}
if surface_type.contains(WindowSurfaceType::SUBSURFACE) {
TraversalAction::DoChildren(location) 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,9 +237,11 @@ 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() {
if surface_type.contains(WindowSurfaceType::POPUP) {
for (popup, location) in PopupManager::popups_for_surface(surface) for (popup, location) in PopupManager::popups_for_surface(surface)
.ok() .ok()
.into_iter() .into_iter()
@ -233,13 +250,14 @@ impl Window {
let offset = self.geometry().loc + location - popup.geometry().loc; let offset = self.geometry().loc + location - popup.geometry().loc;
if let Some(result) = popup if let Some(result) = popup
.get_surface() .get_surface()
.and_then(|surface| under_from_surface_tree(surface, point, offset)) .and_then(|surface| under_from_surface_tree(surface, point, offset, 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
} }