@@ -736,6 +736,75 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
736736 return workspace_windows ;
737737}
738738
739+ /**
740+ * meta_workspace_list_unobscured_windows:
741+ * @workspace: a #MetaWorkspace
742+ *
743+ * This is the same as meta_workspace_list_windows, except it will
744+ * only return windows that are not completely covered by other
745+ * windows. Windows are returned in stacking order (bottom to top).
746+ *
747+ * Return value: (transfer container) (element-type MetaWindow): the
748+ * list of visible windows in stacking order.
749+ */
750+ GList *
751+ meta_workspace_list_unobscured_windows (MetaWorkspace * workspace )
752+ {
753+ GList * stacked_windows ;
754+ GList * visible_windows ;
755+ GList * stack_iter ;
756+ cairo_region_t * visible_region ;
757+ GHashTable * visible_set ;
758+
759+ stacked_windows = meta_stack_list_windows (workspace -> display -> stack , workspace );
760+ visible_region = cairo_region_create_rectangle (& workspace -> work_area_screen );
761+ visible_set = g_hash_table_new (g_direct_hash , g_direct_equal );
762+
763+ // Process windows from top to bottom in stacking order
764+ for (stack_iter = g_list_last (stacked_windows );
765+ stack_iter != NULL ;
766+ stack_iter = stack_iter -> prev )
767+ {
768+ MetaWindow * window = stack_iter -> data ;
769+ cairo_region_t * window_region ;
770+
771+ if (!meta_window_located_on_workspace (window , workspace ))
772+ continue ;
773+
774+ if (window -> minimized || !window -> mapped )
775+ continue ;
776+
777+ // Check what part of this window intersects the visible region
778+ window_region = cairo_region_create_rectangle (& window -> rect );
779+ cairo_region_intersect (window_region , visible_region );
780+
781+ if (!cairo_region_is_empty (window_region ))
782+ {
783+ g_hash_table_add (visible_set , window );
784+ cairo_region_subtract (visible_region , window_region );
785+ }
786+
787+ cairo_region_destroy (window_region );
788+ }
789+
790+ cairo_region_destroy (visible_region );
791+
792+ // Build result list in stacking order (bottom to top)
793+ visible_windows = NULL ;
794+ for (stack_iter = stacked_windows ; stack_iter != NULL ; stack_iter = stack_iter -> next )
795+ {
796+ MetaWindow * window = stack_iter -> data ;
797+
798+ if (g_hash_table_contains (visible_set , window ))
799+ visible_windows = g_list_append (visible_windows , window );
800+ }
801+
802+ g_hash_table_destroy (visible_set );
803+ g_list_free (stacked_windows );
804+
805+ return visible_windows ;
806+ }
807+
739808void
740809meta_workspace_invalidate_work_area (MetaWorkspace * workspace )
741810{
0 commit comments