From 92b3e1cfc39ed5b95eeb24efdebc9114b6e8ec16 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 5 Dec 2024 11:46:42 -0500 Subject: [PATCH] wip: overlap workspace filtering --- src/state.rs | 3 +- src/wayland/protocols/overlap_notify.rs | 61 +++++++++++++------------ src/wayland/protocols/toplevel_info.rs | 6 ++- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/state.rs b/src/state.rs index fc2ba06e..0fd212ba 100644 --- a/src/state.rs +++ b/src/state.rs @@ -501,8 +501,7 @@ impl State { let output_state = OutputManagerState::new_with_xdg_output::(dh); let output_configuration_state = OutputConfigurationState::new(dh, client_is_privileged); let output_power_state = OutputPowerState::new::(dh, client_is_privileged); - let overlap_notify_state = - OverlapNotifyState::new::(dh, client_has_no_security_context); + let overlap_notify_state = OverlapNotifyState::new::<_>(dh, client_has_no_security_context); let presentation_state = PresentationState::new::(dh, clock.id() as u32); let primary_selection_state = PrimarySelectionState::new::(dh); let image_source_state = ImageSourceState::new::(dh, client_is_privileged); diff --git a/src/wayland/protocols/overlap_notify.rs b/src/wayland/protocols/overlap_notify.rs index d29102f3..ca30f3e1 100644 --- a/src/wayland/protocols/overlap_notify.rs +++ b/src/wayland/protocols/overlap_notify.rs @@ -23,18 +23,13 @@ use smithay::{ wayland_server::{Client, Dispatch, DisplayHandle, GlobalDispatch, Resource, Weak}, }, utils::{Logical, Rectangle}, - wayland::{ - foreign_toplevel_list::ForeignToplevelListHandler, - shell::wlr_layer::{ExclusiveZone, Layer}, - }, + wayland::shell::wlr_layer::{ExclusiveZone, Layer}, }; use wayland_backend::server::{GlobalId, ObjectId}; -use crate::utils::prelude::{RectExt, RectGlobalExt, RectLocalExt}; +use crate::utils::prelude::{RectExt, RectGlobalExt, RectLocalExt, State}; -use super::toplevel_info::{ - ToplevelHandleState, ToplevelInfoGlobalData, ToplevelInfoHandler, ToplevelState, Window, -}; +use super::toplevel_info::{ToplevelHandleStateInner, ToplevelInfoHandler, ToplevelState, Window}; #[derive(Debug)] pub struct OverlapNotifyState { @@ -43,16 +38,11 @@ pub struct OverlapNotifyState { } impl OverlapNotifyState { - pub fn new(dh: &DisplayHandle, client_filter: F) -> OverlapNotifyState + pub fn new(dh: &DisplayHandle, client_filter: F) -> OverlapNotifyState where - D: GlobalDispatch - + Dispatch - + Dispatch - + OverlapNotifyHandler - + 'static, F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static, { - let global = dh.create_global::( + let global = dh.create_global::( 1, OverlapNotifyGlobalData { filter: Box::new(client_filter), @@ -68,27 +58,24 @@ impl OverlapNotifyState { self.global.clone() } - pub fn refresh(state: &mut D) - where - D: GlobalDispatch - + Dispatch - + Dispatch - + OverlapNotifyHandler - + GlobalDispatch - + Dispatch - + Dispatch> - + ForeignToplevelListHandler - + ToplevelInfoHandler - + 'static, - W: Window + 'static, - { + pub fn refresh(state: &mut State) { + let shell = state.common.shell.read().unwrap(); + let active_workspaces: HashMap<_, _> = shell + .workspaces + .sets + .iter() + .map(|(output, set)| (output.clone(), set.workspaces[set.active].handle)) + .collect(); + drop(shell); for output in state.outputs() { let map = layer_map_for_output(&output); + for layer_surface in map.layers() { if let Some(data) = layer_surface .user_data() .get::() { + let active_workspace = active_workspaces.get(&output); let mut inner = data.lock().unwrap(); if inner.has_active_notifications() { @@ -100,7 +87,21 @@ impl OverlapNotifyState { .as_local() .to_global(&output); - for window in state.toplevel_info_state().registered_toplevels() { + for window in + state + .toplevel_info_state() + .registered_toplevels() + .filter(|w| { + if let Some(active_workspace) = active_workspace.as_ref() { + ToplevelHandleStateInner::from_window(*w) + .lock() + .unwrap() + .in_workspace(&active_workspace) + } else { + true + } + }) + { if let Some(window_geo) = window.global_geometry() { if let Some(intersection) = layer_geo.intersection(window_geo) { // relative to layer location diff --git a/src/wayland/protocols/toplevel_info.rs b/src/wayland/protocols/toplevel_info.rs index a7f3b64d..e9a7ba2a 100644 --- a/src/wayland/protocols/toplevel_info.rs +++ b/src/wayland/protocols/toplevel_info.rs @@ -95,7 +95,7 @@ pub struct ToplevelHandleStateInner { pub type ToplevelHandleState = Mutex>; impl ToplevelHandleStateInner { - fn from_window(window: &W) -> ToplevelHandleState { + pub fn from_window(window: &W) -> ToplevelHandleState { ToplevelHandleState::new(ToplevelHandleStateInner { outputs: Vec::new(), geometry: None, @@ -120,6 +120,10 @@ impl ToplevelHandleStateInner { window: None, }) } + + pub fn in_workspace(&self, handle: &WorkspaceHandle) -> bool { + self.workspaces.contains(handle) + } } impl GlobalDispatch