static GList* get_monitor_edges (int which_monitor_set, int which_strut_set) { GList *ret; GSList *struts; GList *xins; xins = NULL; g_assert (which_monitor_set >=0 && which_monitor_set <= 3); switch (which_monitor_set) { case 0: xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 1200)); break; case 1: xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 800, 1200)); xins = g_list_prepend (xins, new_meta_rect (800, 0, 800, 1200)); break; case 2: xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 600)); xins = g_list_prepend (xins, new_meta_rect ( 0, 600, 1600, 600)); break; case 3: xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 600)); xins = g_list_prepend (xins, new_meta_rect ( 0, 600, 800, 600)); xins = g_list_prepend (xins, new_meta_rect (800, 600, 800, 600)); break; } ret = NULL; struts = get_strut_list (which_strut_set); ret = meta_rectangle_find_nonintersected_monitor_edges (xins, struts); free_strut_list (struts); meta_rectangle_free_list_and_elements (xins); return ret; }
static void ensure_work_areas_validated (MetaWorkspace *workspace) { GList *windows; GList *tmp; MetaRectangle work_area; int i; /* C89 absolutely sucks... */ if (!workspace->work_areas_invalid) return; g_assert (workspace->all_struts == NULL); g_assert (workspace->monitor_region == NULL); g_assert (workspace->screen_region == NULL); g_assert (workspace->screen_edges == NULL); g_assert (workspace->monitor_edges == NULL); /* STEP 1: Get the list of struts */ workspace->all_struts = copy_strut_list (workspace->builtin_struts); windows = meta_workspace_list_windows (workspace); for (tmp = windows; tmp != NULL; tmp = tmp->next) { MetaWindow *win = tmp->data; GSList *s_iter; for (s_iter = win->struts; s_iter != NULL; s_iter = s_iter->next) { workspace->all_struts = g_slist_prepend (workspace->all_struts, copy_strut(s_iter->data)); } } g_list_free (windows); /* STEP 2: Get the maximal/spanning rects for the onscreen and * on-single-monitor regions */ g_assert (workspace->monitor_region == NULL); g_assert (workspace->screen_region == NULL); workspace->monitor_region = g_new (GList*, workspace->screen->n_monitor_infos); for (i = 0; i < workspace->screen->n_monitor_infos; i++) { workspace->monitor_region[i] = meta_rectangle_get_minimal_spanning_set_for_region ( &workspace->screen->monitor_infos[i].rect, workspace->all_struts); } workspace->screen_region = meta_rectangle_get_minimal_spanning_set_for_region ( &workspace->screen->rect, workspace->all_struts); /* STEP 3: Get the work areas (region-to-maximize-to) for the screen and * monitors. */ work_area = workspace->screen->rect; /* start with the screen */ if (workspace->screen_region == NULL) work_area = meta_rect (0, 0, -1, -1); else meta_rectangle_clip_to_region (workspace->screen_region, FIXED_DIRECTION_NONE, &work_area); /* Lots of paranoia checks, forcing work_area_screen to be sane */ #define MIN_SANE_AREA 100 if (work_area.width < MIN_SANE_AREA) { meta_warning ("struts occupy an unusually large percentage of the screen; " "available remaining width = %d < %d", work_area.width, MIN_SANE_AREA); if (work_area.width < 1) { work_area.x = (workspace->screen->rect.width - MIN_SANE_AREA)/2; work_area.width = MIN_SANE_AREA; } else { int amount = (MIN_SANE_AREA - work_area.width)/2; work_area.x -= amount; work_area.width += 2*amount; } } if (work_area.height < MIN_SANE_AREA) { meta_warning ("struts occupy an unusually large percentage of the screen; " "available remaining height = %d < %d", work_area.height, MIN_SANE_AREA); if (work_area.height < 1) { work_area.y = (workspace->screen->rect.height - MIN_SANE_AREA)/2; work_area.height = MIN_SANE_AREA; } else { int amount = (MIN_SANE_AREA - work_area.height)/2; work_area.y -= amount; work_area.height += 2*amount; } } workspace->work_area_screen = work_area; meta_topic (META_DEBUG_WORKAREA, "Computed work area for workspace %d: %d,%d %d x %d\n", meta_workspace_index (workspace), workspace->work_area_screen.x, workspace->work_area_screen.y, workspace->work_area_screen.width, workspace->work_area_screen.height); /* Now find the work areas for each monitor */ g_free (workspace->work_area_monitor); workspace->work_area_monitor = g_new (MetaRectangle, workspace->screen->n_monitor_infos); for (i = 0; i < workspace->screen->n_monitor_infos; i++) { work_area = workspace->screen->monitor_infos[i].rect; if (workspace->monitor_region[i] == NULL) /* FIXME: constraints.c untested with this, but it might be nice for * a screen reader or magnifier. */ work_area = meta_rect (work_area.x, work_area.y, -1, -1); else meta_rectangle_clip_to_region (workspace->monitor_region[i], FIXED_DIRECTION_NONE, &work_area); workspace->work_area_monitor[i] = work_area; meta_topic (META_DEBUG_WORKAREA, "Computed work area for workspace %d " "monitor %d: %d,%d %d x %d\n", meta_workspace_index (workspace), i, workspace->work_area_monitor[i].x, workspace->work_area_monitor[i].y, workspace->work_area_monitor[i].width, workspace->work_area_monitor[i].height); } /* STEP 4: Make sure the screen_region is nonempty (separate from step 2 * since it relies on step 3). */ if (workspace->screen_region == NULL) { MetaRectangle *nonempty_region; nonempty_region = g_new (MetaRectangle, 1); *nonempty_region = workspace->work_area_screen; workspace->screen_region = g_list_prepend (NULL, nonempty_region); } /* STEP 5: Cache screen and monitor edges for edge resistance and snapping */ g_assert (workspace->screen_edges == NULL); g_assert (workspace->monitor_edges == NULL); workspace->screen_edges = meta_rectangle_find_onscreen_edges (&workspace->screen->rect, workspace->all_struts); tmp = NULL; for (i = 0; i < workspace->screen->n_monitor_infos; i++) tmp = g_list_prepend (tmp, &workspace->screen->monitor_infos[i].rect); workspace->monitor_edges = meta_rectangle_find_nonintersected_monitor_edges (tmp, workspace->all_struts); g_list_free (tmp); /* We're all done, YAAY! Record that everything has been validated. */ workspace->work_areas_invalid = FALSE; { /* * Notify the compositor that the workspace geometry has changed. */ MetaScreen *screen = workspace->screen; MetaDisplay *display = meta_screen_get_display (screen); MetaCompositor *comp = meta_display_get_compositor (display); if (comp) meta_compositor_update_workspace_geometry (comp, workspace); } }