@@ -302,6 +302,22 @@ workspace_free_builtin_struts (MetaWorkspace *workspace)
302302 workspace -> builtin_struts = NULL ;
303303}
304304
305+ /**
306+ * workspace_free_layer_shell_struts:
307+ * @workspace: The workspace.
308+ *
309+ * Frees the struts list set with meta_workspace_set_layer_shell_struts
310+ */
311+ static void
312+ workspace_free_layer_shell_struts (MetaWorkspace * workspace )
313+ {
314+ if (workspace -> layer_shell_struts == NULL )
315+ return ;
316+
317+ g_slist_free_full (workspace -> layer_shell_struts , g_free );
318+ workspace -> layer_shell_struts = NULL ;
319+ }
320+
305321/* Ensure that the workspace is empty by making sure that
306322 * all of our windows are on-all-workspaces. */
307323static void
@@ -333,6 +349,7 @@ meta_workspace_remove (MetaWorkspace *workspace)
333349 g_list_free (workspace -> list_containing_self );
334350
335351 workspace_free_builtin_struts (workspace );
352+ workspace_free_layer_shell_struts (workspace );
336353
337354 /* screen.c:update_num_workspaces(), which calls us, removes windows from
338355 * workspaces first, which can cause the workareas on the workspace to be
@@ -899,6 +916,16 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
899916
900917 workspace -> all_struts = copy_strut_list (workspace -> builtin_struts );
901918
919+ /* Add layer-shell struts */
920+ {
921+ GSList * s_iter ;
922+ for (s_iter = workspace -> layer_shell_struts ; s_iter != NULL ; s_iter = s_iter -> next )
923+ {
924+ workspace -> all_struts = g_slist_prepend (workspace -> all_struts ,
925+ copy_strut (s_iter -> data ));
926+ }
927+ }
928+
902929 windows = meta_workspace_list_windows (workspace );
903930 for (tmp = windows ; tmp != NULL ; tmp = tmp -> next )
904931 {
@@ -1161,6 +1188,28 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
11611188 meta_workspace_invalidate_work_area (workspace );
11621189}
11631190
1191+ /**
1192+ * meta_workspace_set_layer_shell_struts:
1193+ * @workspace: a #MetaWorkspace
1194+ * @struts: (element-type Meta.Strut) (transfer none): list of #MetaStrut
1195+ *
1196+ * Sets a list of struts from layer-shell surfaces that will be used
1197+ * in addition to the builtin struts and window struts when computing
1198+ * the work area of the workspace.
1199+ */
1200+ void
1201+ meta_workspace_set_layer_shell_struts (MetaWorkspace * workspace ,
1202+ GSList * struts )
1203+ {
1204+ if (strut_lists_equal (struts , workspace -> layer_shell_struts ))
1205+ return ;
1206+
1207+ workspace_free_layer_shell_struts (workspace );
1208+ workspace -> layer_shell_struts = copy_strut_list (struts );
1209+
1210+ meta_workspace_invalidate_work_area (workspace );
1211+ }
1212+
11641213void
11651214meta_workspace_get_work_area_for_logical_monitor (MetaWorkspace * workspace ,
11661215 MetaLogicalMonitor * logical_monitor ,
@@ -1171,6 +1220,56 @@ meta_workspace_get_work_area_for_logical_monitor (MetaWorkspace *workspace,
11711220 area );
11721221}
11731222
1223+ /**
1224+ * meta_workspace_get_work_area_for_logical_monitor_excluding_layer_shell:
1225+ * @workspace: a #MetaWorkspace
1226+ * @logical_monitor: a #MetaLogicalMonitor
1227+ * @area: (out): location to store the work area
1228+ *
1229+ * Computes work area for @logical_monitor using only builtin struts,
1230+ * excluding layer-shell struts. This is used for positioning layer-shell
1231+ * surfaces so they don't get pushed by their own struts.
1232+ */
1233+ void
1234+ meta_workspace_get_work_area_for_logical_monitor_excluding_layer_shell (
1235+ MetaWorkspace * workspace ,
1236+ MetaLogicalMonitor * logical_monitor ,
1237+ MetaRectangle * area )
1238+ {
1239+ GList * tmp ;
1240+ GList * monitor_region ;
1241+ GSList * struts_for_calculation = NULL ;
1242+ GSList * s_iter ;
1243+
1244+ g_return_if_fail (logical_monitor != NULL );
1245+ g_return_if_fail (area != NULL );
1246+
1247+ /* Start with builtin struts only */
1248+ for (s_iter = workspace -> builtin_struts ; s_iter != NULL ; s_iter = s_iter -> next )
1249+ {
1250+ MetaStrut * strut = s_iter -> data ;
1251+ MetaStrut * copy = g_new0 (MetaStrut , 1 );
1252+ * copy = * strut ;
1253+ struts_for_calculation = g_slist_prepend (struts_for_calculation , copy );
1254+ }
1255+
1256+ /* Calculate region for this monitor using only builtin struts */
1257+ monitor_region =
1258+ meta_rectangle_get_minimal_spanning_set_for_region (& logical_monitor -> rect ,
1259+ struts_for_calculation );
1260+
1261+ /* Find work area from the region */
1262+ * area = logical_monitor -> rect ;
1263+ for (tmp = monitor_region ; tmp != NULL ; tmp = tmp -> next )
1264+ {
1265+ MetaRectangle * rect = tmp -> data ;
1266+ meta_rectangle_intersect (area , rect , area );
1267+ }
1268+
1269+ g_list_free_full (monitor_region , g_free );
1270+ g_slist_free_full (struts_for_calculation , g_free );
1271+ }
1272+
11741273/**
11751274 * meta_workspace_get_work_area_for_monitor:
11761275 * @workspace: a #MetaWorkspace
0 commit comments