@@ -182,6 +182,7 @@ impl DockItem {
182182 is_focused : bool ,
183183 dot_border_radius : [ f32 ; 4 ] ,
184184 window_id : window:: Id ,
185+ filter : Option < & dyn Fn ( & ToplevelInfo ) -> bool > ,
185186 ) -> Element < ' _ , Message > {
186187 let Self {
187188 toplevels,
@@ -190,6 +191,16 @@ impl DockItem {
190191 ..
191192 } = self ;
192193
194+ let filtered_toplevels: Vec < _ > = if let Some ( filter_fn) = filter {
195+ toplevels
196+ . iter ( )
197+ . filter ( |( info, _) | filter_fn ( info) )
198+ . collect ( )
199+ } else {
200+ toplevels. iter ( ) . collect ( )
201+ } ;
202+ let toplevel_count = filtered_toplevels. len ( ) ;
203+
193204 let app_icon = AppletIconData :: new ( applet) ;
194205
195206 let cosmic_icon = fde:: IconSource :: from_unknown ( desktop_info. icon ( ) . unwrap_or_default ( ) )
@@ -200,7 +211,7 @@ impl DockItem {
200211 . height ( app_icon. icon_size . into ( ) ) ;
201212
202213 let indicator = {
203- let container = if toplevels . len ( ) <= 1 {
214+ let container = if toplevel_count <= 1 {
204215 vertical_space ( ) . height ( Length :: Fixed ( 0.0 ) )
205216 } else {
206217 match applet. anchor {
@@ -215,7 +226,7 @@ impl DockItem {
215226 . apply ( container)
216227 . padding ( app_icon. dot_radius ) ;
217228
218- if toplevels . is_empty ( ) {
229+ if toplevel_count == 0 {
219230 container
220231 } else {
221232 container. class ( theme:: Container :: custom ( move |theme| container:: Style {
@@ -272,10 +283,10 @@ impl DockItem {
272283 let icon_button: Element < _ > = if interaction_enabled {
273284 mouse_area (
274285 icon_button
275- . on_press_maybe ( if toplevels . is_empty ( ) {
286+ . on_press_maybe ( if toplevel_count == 0 {
276287 launch_on_preferred_gpu ( desktop_info, gpus)
277- } else if toplevels . len ( ) == 1 {
278- toplevels
288+ } else if toplevel_count == 1 {
289+ filtered_toplevels
279290 . first ( )
280291 . map ( |t| Message :: Toggle ( t. 0 . foreign_toplevel . clone ( ) ) )
281292 } else {
@@ -635,6 +646,32 @@ impl CosmicAppList {
635646 . collect :: < Vec < _ > > ( ) ;
636647 }
637648
649+ fn is_on_current_monitor_and_workspace ( & self , toplevel_info : & ToplevelInfo ) -> bool {
650+ use cosmic_app_list_config:: TopLevelFilter ;
651+
652+ let on_active_workspace = self . active_workspaces . is_empty ( )
653+ || toplevel_info. workspace . is_empty ( )
654+ || self . active_workspaces
655+ . iter ( )
656+ . any ( |workspace| toplevel_info. workspace . contains ( workspace) ) ;
657+
658+ match & self . config . filter_top_levels {
659+ None => true ,
660+ Some ( TopLevelFilter :: ActiveWorkspace ) => on_active_workspace,
661+ Some ( TopLevelFilter :: ConfiguredOutput ) => {
662+ let on_active_output = self
663+ . output_list
664+ . iter ( )
665+ . find ( |( _, info) | info. name . as_ref ( ) == Some ( & self . core . applet . output_name ) )
666+ . map_or ( true , |( active_output, _) | {
667+ toplevel_info. output . iter ( ) . any ( |output| output == active_output)
668+ } ) ;
669+
670+ on_active_output && on_active_workspace
671+ }
672+ }
673+ }
674+
638675 // Update pinned items using the cached desktop entries as a source.
639676 fn update_pinned_list ( & mut self ) {
640677 self . pinned_list = find_desktop_entries ( & self . desktop_entries , & self . config . favorites )
@@ -1715,6 +1752,12 @@ impl cosmic::Application for CosmicAppList {
17151752 . iter ( )
17161753 . rev ( )
17171754 . map ( |dock_item| {
1755+ let filtered_is_focused = dock_item
1756+ . toplevels
1757+ . iter ( )
1758+ . filter ( |( info, _) | self . is_on_current_monitor_and_workspace ( info) )
1759+ . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ;
1760+
17181761 self . core
17191762 . applet
17201763 . applet_tooltip :: < Message > (
@@ -1724,12 +1767,10 @@ impl cosmic::Application for CosmicAppList {
17241767 self . popup . is_none ( ) ,
17251768 self . config . enable_drag_source ,
17261769 self . gpus . as_deref ( ) ,
1727- dock_item
1728- . toplevels
1729- . iter ( )
1730- . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ,
1770+ filtered_is_focused,
17311771 dot_radius,
17321772 self . core . main_window_id ( ) . unwrap ( ) ,
1773+ Some ( & |info| self . is_on_current_monitor_and_workspace ( info) ) ,
17331774 ) ,
17341775 dock_item
17351776 . desktop_info
@@ -1772,6 +1813,12 @@ impl cosmic::Application for CosmicAppList {
17721813 . as_ref ( )
17731814 . and_then ( |o| o. dock_item . as_ref ( ) . map ( |item| ( item, o. preview_index ) ) )
17741815 {
1816+ let filtered_is_focused = item
1817+ . toplevels
1818+ . iter ( )
1819+ . filter ( |( info, _) | self . is_on_current_monitor_and_workspace ( info) )
1820+ . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ;
1821+
17751822 favorites. insert (
17761823 index. min ( favorites. len ( ) ) ,
17771824 item. as_icon (
@@ -1780,11 +1827,10 @@ impl cosmic::Application for CosmicAppList {
17801827 false ,
17811828 self . config . enable_drag_source ,
17821829 self . gpus . as_deref ( ) ,
1783- item. toplevels
1784- . iter ( )
1785- . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ,
1830+ filtered_is_focused,
17861831 dot_radius,
17871832 self . core . main_window_id ( ) . unwrap ( ) ,
1833+ Some ( & |info| self . is_on_current_monitor_and_workspace ( info) ) ,
17881834 ) ,
17891835 ) ;
17901836 } else if self . is_listening_for_dnd && self . pinned_list . is_empty ( ) {
@@ -1799,9 +1845,19 @@ impl cosmic::Application for CosmicAppList {
17991845 ) ;
18001846 }
18011847
1848+ let filtered_active_list: Vec < _ > = self
1849+ . active_list
1850+ . iter ( )
1851+ . filter ( |dock_item| {
1852+ dock_item. toplevels . iter ( ) . any ( |( toplevel_info, _) | {
1853+ self . is_on_current_monitor_and_workspace ( toplevel_info)
1854+ } )
1855+ } )
1856+ . collect ( ) ;
1857+
18021858 let mut active: Vec < _ > =
1803- self . active_list [ ..active_popup_cutoff. map_or ( self . active_list . len ( ) , |n| {
1804- if n < self . active_list . len ( ) {
1859+ filtered_active_list [ ..active_popup_cutoff. map_or ( filtered_active_list . len ( ) , |n| {
1860+ if n < filtered_active_list . len ( ) {
18051861 n. saturating_sub ( 1 )
18061862 } else {
18071863 n
@@ -1824,6 +1880,7 @@ impl cosmic::Application for CosmicAppList {
18241880 . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ,
18251881 dot_radius,
18261882 self . core . main_window_id ( ) . unwrap ( ) ,
1883+ None ,
18271884 ) ,
18281885 dock_item
18291886 . desktop_info
@@ -1838,7 +1895,7 @@ impl cosmic::Application for CosmicAppList {
18381895 } )
18391896 . collect ( ) ;
18401897
1841- if active_popup_cutoff. is_some_and ( |n| n < self . active_list . len ( ) ) {
1898+ if active_popup_cutoff. is_some_and ( |n| n < filtered_active_list . len ( ) ) {
18421899 // button to show more active
18431900 let icon = match self . core . applet . anchor {
18441901 PanelAnchor :: Bottom => "go-up-symbolic" ,
@@ -1987,21 +2044,26 @@ impl cosmic::Application for CosmicAppList {
19872044 ..
19882045 } ) = self . popup . as_ref ( ) . filter ( |p| id == p. id )
19892046 {
1990- let (
1991- DockItem {
1992- toplevels,
1993- desktop_info,
1994- ..
1995- } ,
1996- is_pinned,
1997- ) = match self . pinned_list . iter ( ) . find ( |i| i. id == * id) {
2047+ let ( dock_item, is_pinned) = match self . pinned_list . iter ( ) . find ( |i| i. id == * id) {
19982048 Some ( e) => ( e, true ) ,
19992049 None => match self . active_list . iter ( ) . find ( |i| i. id == * id) {
20002050 Some ( e) => ( e, false ) ,
20012051 None => return text:: body ( "" ) . into ( ) ,
20022052 } ,
20032053 } ;
20042054
2055+ // Filter toplevels to only show windows on current monitor and workspace
2056+ let filtered_toplevels: Vec < _ > = dock_item
2057+ . toplevels
2058+ . iter ( )
2059+ . filter ( |( toplevel_info, _) | {
2060+ self . is_on_current_monitor_and_workspace ( toplevel_info)
2061+ } )
2062+ . collect ( ) ;
2063+
2064+ let toplevels = & filtered_toplevels;
2065+ let desktop_info = & dock_item. desktop_info ;
2066+
20052067 match popup_type {
20062068 PopupType :: RightClickMenu => {
20072069 fn menu_button < ' a , Message : Clone + ' a > (
@@ -2203,14 +2265,23 @@ impl cosmic::Application for CosmicAppList {
22032265
22042266 let focused_item = self . currently_active_toplevel ( ) ;
22052267 let dot_radius = theme. cosmic ( ) . radius_xs ( ) ;
2206- // show the overflow popup for active list
2207- let active : Vec < _ > = self
2268+
2269+ let filtered_active_list : Vec < _ > = self
22082270 . active_list
2271+ . iter ( )
2272+ . filter ( |dock_item| {
2273+ dock_item. toplevels . iter ( ) . any ( |( toplevel_info, _) | {
2274+ self . is_on_current_monitor_and_workspace ( toplevel_info)
2275+ } )
2276+ } )
2277+ . collect ( ) ;
2278+
2279+ let active: Vec < _ > = filtered_active_list
22092280 . iter ( )
22102281 . rev ( )
2211- . take ( active_popup_cutoff. map_or ( self . active_list . len ( ) , |n| {
2212- if n < self . active_list . len ( ) {
2213- self . active_list . len ( ) - n + 1
2282+ . take ( active_popup_cutoff. map_or ( filtered_active_list . len ( ) , |n| {
2283+ if n < filtered_active_list . len ( ) {
2284+ filtered_active_list . len ( ) - n + 1
22142285 } else {
22152286 0
22162287 }
@@ -2231,6 +2302,7 @@ impl cosmic::Application for CosmicAppList {
22312302 . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ,
22322303 dot_radius,
22332304 id,
2305+ None ,
22342306 ) ,
22352307 dock_item
22362308 . desktop_info
@@ -2290,6 +2362,7 @@ impl cosmic::Application for CosmicAppList {
22902362 let focused_item = self . currently_active_toplevel ( ) ;
22912363 let dot_radius = theme. cosmic ( ) . radius_xs ( ) ;
22922364 // show the overflow popup for favorites list
2365+
22932366 let mut favorite_to_remove = if let Some ( cutoff) = favorite_popup_cutoff {
22942367 if cutoff < self . pinned_list . len ( ) {
22952368 self . pinned_list . len ( ) - cutoff + 1
@@ -2319,6 +2392,12 @@ impl cosmic::Application for CosmicAppList {
23192392 . iter ( )
23202393 . rev ( )
23212394 . map ( |dock_item| {
2395+ let filtered_is_focused = dock_item
2396+ . toplevels
2397+ . iter ( )
2398+ . filter ( |( info, _) | self . is_on_current_monitor_and_workspace ( info) )
2399+ . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ;
2400+
23222401 self . core
23232402 . applet
23242403 . applet_tooltip (
@@ -2328,12 +2407,10 @@ impl cosmic::Application for CosmicAppList {
23282407 self . popup . is_none ( ) ,
23292408 self . config . enable_drag_source ,
23302409 self . gpus . as_deref ( ) ,
2331- dock_item
2332- . toplevels
2333- . iter ( )
2334- . any ( |y| focused_item. contains ( & y. 0 . foreign_toplevel ) ) ,
2410+ filtered_is_focused,
23352411 dot_radius,
23362412 id,
2413+ Some ( & |info| self . is_on_current_monitor_and_workspace ( info) ) ,
23372414 ) ,
23382415 dock_item
23392416 . desktop_info
0 commit comments