void meta_workspace_invalidate_work_area (MetaWorkspace *workspace) { GList *tmp; GList *windows; int i; if (workspace->work_areas_invalid) { meta_topic (META_DEBUG_WORKAREA, "Work area for workspace %d is already invalid\n", meta_workspace_index (workspace)); return; } meta_topic (META_DEBUG_WORKAREA, "Invalidating work area for workspace %d\n", meta_workspace_index (workspace)); /* If we are in the middle of a resize or move operation, we * might have cached pointers to the workspace's edges */ if (workspace == workspace->screen->active_workspace) meta_display_cleanup_edges (workspace->screen->display); g_free (workspace->work_area_monitor); workspace->work_area_monitor = NULL; workspace_free_struts (workspace); for (i = 0; i < workspace->screen->n_monitor_infos; i++) g_list_free_full (workspace->monitor_region[i], g_free); g_free (workspace->monitor_region); g_list_free_full (workspace->screen_region, g_free); g_list_free_full (workspace->screen_edges, g_free); g_list_free_full (workspace->monitor_edges, g_free); workspace->monitor_region = NULL; workspace->screen_region = NULL; workspace->screen_edges = NULL; workspace->monitor_edges = NULL; workspace->work_areas_invalid = TRUE; /* redo the size/position constraints on all windows */ windows = meta_workspace_list_windows (workspace); tmp = windows; while (tmp != NULL) { MetaWindow *w = tmp->data; meta_window_queue (w, META_QUEUE_MOVE_RESIZE); tmp = tmp->next; } g_list_free (windows); meta_screen_queue_workarea_recalc (workspace->screen); }
static void prepare_workspace_content(MosesOverview *self, MetaWorkspace *ws) { MosesOverviewPrivate* priv = self->priv; GList* l = meta_workspace_list_windows(ws); if (!priv->clones) { priv->clones = g_ptr_array_new(); } while (l) { MetaWindow* win = l->data; MetaWindowActor* win_actor = META_WINDOW_ACTOR(meta_window_get_compositor_private(win)); if (meta_window_get_window_type(win) == META_WINDOW_DESKTOP) { g_debug("%s: got desktop actor", __func__); priv->background_actor = clutter_clone_new(CLUTTER_ACTOR(win_actor)); } else if (meta_window_get_window_type(win) == META_WINDOW_NORMAL && !meta_window_is_hidden(win)) { ClutterActor* clone = clutter_clone_new(CLUTTER_ACTOR(win_actor)); clutter_actor_set_reactive(clone, TRUE); float x = 0.0, y = 0.0; clutter_actor_get_position(CLUTTER_ACTOR(win_actor), &x, &y); clutter_actor_set_position(clone, x, y); clutter_actor_hide(CLUTTER_ACTOR(win_actor)); g_ptr_array_add(priv->clones, clone); clutter_actor_add_child(CLUTTER_ACTOR(self), clone); g_object_connect(clone, "signal::transitions-completed", G_CALLBACK(on_effect_complete), self, "signal::button-press-event", on_thumb_button_press, self, "signal::enter-event", on_thumb_enter, self, "signal::leave-event", on_thumb_leave, self, NULL); } l = l->next; } ClutterColor clr = CLUTTER_COLOR_INIT(0xff, 0xff, 0xff, 0xff); clutter_actor_set_background_color(CLUTTER_ACTOR(self), &clr); if (priv->background_actor) { #if 0 ClutterEffect* blur = moses_blur_effect_new(); clutter_actor_add_effect_with_name(priv->background_actor, "blur", blur); clutter_actor_insert_child_below(CLUTTER_ACTOR(self), priv->background_actor, NULL); clutter_actor_hide(clutter_clone_get_source(CLUTTER_CLONE(priv->background_actor))); clutter_actor_set_reactive(priv->background_actor, TRUE); #endif } g_object_connect(priv->background_actor ? priv->background_actor: CLUTTER_ACTOR(self), "signal::button-press-event", on_bg_button_press, self, NULL); }
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace) { GList *tmp; GList *windows; int i; if (workspace->work_areas_invalid) { meta_topic (META_DEBUG_WORKAREA, "Work area for workspace %d is already invalid\n", meta_workspace_index (workspace)); return; } meta_topic (META_DEBUG_WORKAREA, "Invalidating work area for workspace %d\n", meta_workspace_index (workspace)); g_free (workspace->work_area_xinerama); workspace->work_area_xinerama = NULL; workspace_free_struts (workspace); for (i = 0; i < workspace->screen->n_xinerama_infos; i++) meta_rectangle_free_list_and_elements (workspace->xinerama_region[i]); g_free (workspace->xinerama_region); meta_rectangle_free_list_and_elements (workspace->screen_region); meta_rectangle_free_list_and_elements (workspace->screen_edges); meta_rectangle_free_list_and_elements (workspace->xinerama_edges); workspace->xinerama_region = NULL; workspace->screen_region = NULL; workspace->screen_edges = NULL; workspace->xinerama_edges = NULL; workspace->work_areas_invalid = TRUE; /* redo the size/position constraints on all windows */ windows = meta_workspace_list_windows (workspace); tmp = windows; while (tmp != NULL) { MetaWindow *w = tmp->data; meta_window_queue (w, META_QUEUE_MOVE_RESIZE); tmp = tmp->next; } g_list_free (windows); meta_screen_queue_workarea_recalc (workspace->screen); }
static void load_initial_windows (ShellWindowTracker *monitor) { GList *workspaces, *iter; MetaScreen *screen = shell_global_get_screen (shell_global_get ()); workspaces = meta_screen_get_workspaces (screen); for (iter = workspaces; iter; iter = iter->next) { MetaWorkspace *workspace = iter->data; GList *windows = meta_workspace_list_windows (workspace); GList *window_iter; for (window_iter = windows; window_iter; window_iter = window_iter->next) { MetaWindow *window = window_iter->data; track_window (monitor, window); } g_list_free (windows); } }
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); } }