fix: filter by active workspace in overlap notify

This commit is contained in:
Ashley Wulber 2024-12-05 12:13:31 -05:00 • committed by Victoria Brekenfeld
parent fc84fa9948
commit 76863aaf9b
3 changed files with 45 additions and 4 deletions

View file

@ -37,6 +37,19 @@ impl OverlapNotifyHandler for State {
let shell = self.common.shell.read().unwrap(); let shell = self.common.shell.read().unwrap();
shell.outputs().cloned().collect::<Vec<_>>().into_iter() shell.outputs().cloned().collect::<Vec<_>>().into_iter()
} }
fn active_workspaces(
&self,
) -> impl Iterator<Item = crate::wayland::protocols::workspace::WorkspaceHandle> {
let shell = self.common.shell.read().unwrap();
shell
.workspaces
.sets
.iter()
.map(|(_, set)| set.workspaces[set.active].handle)
.collect::<Vec<_>>()
.into_iter()
}
} }
delegate_overlap_notify!(State); delegate_overlap_notify!(State);

View file

@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use std::{collections::HashMap, sync::Mutex}; use std::{
collections::{HashMap, HashSet},
sync::Mutex,
};
use cosmic_protocols::{ use cosmic_protocols::{
overlap_notify::v1::server::{ overlap_notify::v1::server::{
@ -32,8 +35,11 @@ use wayland_backend::server::{GlobalId, ObjectId};
use crate::utils::prelude::{RectExt, RectGlobalExt, RectLocalExt}; use crate::utils::prelude::{RectExt, RectGlobalExt, RectLocalExt};
use super::toplevel_info::{ use super::{
ToplevelHandleState, ToplevelInfoGlobalData, ToplevelInfoHandler, ToplevelState, Window, toplevel_info::{
ToplevelHandleState, ToplevelInfoGlobalData, ToplevelInfoHandler, ToplevelState, Window,
},
workspace::WorkspaceHandle,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -82,8 +88,10 @@ impl OverlapNotifyState {
+ 'static, + 'static,
W: Window + 'static, W: Window + 'static,
{ {
let active_workspaces: Vec<_> = state.active_workspaces().collect();
for output in state.outputs() { for output in state.outputs() {
let map = layer_map_for_output(&output); let map = layer_map_for_output(&output);
for layer_surface in map.layers() { for layer_surface in map.layers() {
if let Some(data) = layer_surface if let Some(data) = layer_surface
.user_data() .user_data()
@ -100,7 +108,22 @@ impl OverlapNotifyState {
.as_local() .as_local()
.to_global(&output); .to_global(&output);
for window in state.toplevel_info_state().registered_toplevels() { for window in
state
.toplevel_info_state()
.registered_toplevels()
.filter(|w| {
let state = w
.user_data()
.get::<ToplevelState>()
.unwrap()
.lock()
.unwrap();
active_workspaces.iter().any(|active_workspace| {
state.in_workspace(&active_workspace)
})
})
{
if let Some(window_geo) = window.global_geometry() { if let Some(window_geo) = window.global_geometry() {
if let Some(intersection) = layer_geo.intersection(window_geo) { if let Some(intersection) = layer_geo.intersection(window_geo) {
// relative to layer location // relative to layer location
@ -146,6 +169,7 @@ pub trait OverlapNotifyHandler: ToplevelInfoHandler {
fn overlap_notify_state(&mut self) -> &mut OverlapNotifyState; fn overlap_notify_state(&mut self) -> &mut OverlapNotifyState;
fn layer_surface_from_resource(&self, resource: ZwlrLayerSurfaceV1) -> Option<LayerSurface>; fn layer_surface_from_resource(&self, resource: ZwlrLayerSurfaceV1) -> Option<LayerSurface>;
fn outputs(&self) -> impl Iterator<Item = Output>; fn outputs(&self) -> impl Iterator<Item = Output>;
fn active_workspaces(&self) -> impl Iterator<Item = (WorkspaceHandle)>;
} }
pub struct OverlapNotifyGlobalData { pub struct OverlapNotifyGlobalData {

View file

@ -80,6 +80,10 @@ impl ToplevelStateInner {
pub fn foreign_handle(&self) -> Option<&ForeignToplevelHandle> { pub fn foreign_handle(&self) -> Option<&ForeignToplevelHandle> {
self.foreign_handle.as_ref() self.foreign_handle.as_ref()
} }
pub fn in_workspace(&self, handle: &WorkspaceHandle) -> bool {
self.workspaces.contains(handle)
}
} }
pub struct ToplevelHandleStateInner<W: Window> { pub struct ToplevelHandleStateInner<W: Window> {