From 81c1c70c0a4e52e67bfd14dbb40f8740cadb3195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armin=20Krezovi=C4=87?= Date: Sun, 27 Aug 2017 21:02:40 +0200 Subject: [PATCH] Move workspace related code from MetaDisplay to MetaWorkspaceManager https://bugzilla.gnome.org/show_bug.cgi?id=759538 --- src/core/constraints.c | 8 +- src/core/core.c | 20 +- src/core/display-private.h | 52 -- src/core/display.c | 769 +-------------------- src/core/edge-resistance.c | 8 +- src/core/keybindings.c | 34 +- src/core/meta-workspace-manager-private.h | 45 ++ src/core/meta-workspace-manager.c | 786 ++++++++++++++++++++++ src/core/stack.c | 25 +- src/core/window.c | 109 +-- src/core/workspace-private.h | 3 +- src/core/workspace.c | 81 +-- src/meta/display.h | 24 - src/meta/meta-workspace-manager.h | 22 + src/x11/events.c | 19 +- src/x11/meta-x11-display.c | 68 +- src/x11/window-props.c | 5 +- src/x11/window-x11.c | 11 +- 18 files changed, 1093 insertions(+), 996 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index d90e7230c..f84ef7d61 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -24,6 +24,7 @@ #include #include "boxes-private.h" #include "constraints.h" +#include "meta-workspace-manager-private.h" #include "workspace-private.h" #include "place.h" #include @@ -412,7 +413,7 @@ setup_constraint_info (ConstraintInfo *info, &info->entire_monitor); } - cur_workspace = window->display->active_workspace; + cur_workspace = window->display->workspace_manager->active_workspace; info->usable_screen_region = meta_workspace_get_onscreen_region (cur_workspace); info->usable_monitor_region = @@ -499,7 +500,7 @@ place_window_if_needed(MetaWindow *window, meta_window_get_work_area_for_logical_monitor (window, logical_monitor, &info->work_area_monitor); - cur_workspace = window->display->active_workspace; + cur_workspace = window->display->workspace_manager->active_workspace; info->usable_monitor_region = meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor); @@ -926,6 +927,7 @@ constrain_maximization (MetaWindow *window, ConstraintPriority priority, gboolean check_only) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaRectangle target_size; MetaRectangle min_size, max_size; gboolean hminbad, vminbad; @@ -965,7 +967,7 @@ constrain_maximization (MetaWindow *window, direction = META_DIRECTION_HORIZONTAL; else direction = META_DIRECTION_VERTICAL; - active_workspace_struts = window->display->active_workspace->all_struts; + active_workspace_struts = workspace_manager->active_workspace->all_struts; target_size = info->current; meta_rectangle_expand_to_avoiding_struts (&target_size, diff --git a/src/core/core.c b/src/core/core.c index 8aeebe505..7b7f1300a 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -24,6 +24,7 @@ #include #include "core.h" #include "frame.h" +#include "meta-workspace-manager-private.h" #include "workspace-private.h" #include #include @@ -77,6 +78,8 @@ static gboolean lower_window_and_transients (MetaWindow *window, gpointer data) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + meta_window_lower (window); meta_window_foreach_transient (window, lower_window_and_transients, NULL); @@ -87,22 +90,22 @@ lower_window_and_transients (MetaWindow *window, * Do extra sanity checks to avoid possible race conditions. * (Borrowed from window.c.) */ - if (window->display->active_workspace && + if (workspace_manager->active_workspace && meta_window_located_on_workspace (window, - window->display->active_workspace)) + workspace_manager->active_workspace)) { GList* link; - link = g_list_find (window->display->active_workspace->mru_list, + link = g_list_find (workspace_manager->active_workspace->mru_list, window); g_assert (link); - window->display->active_workspace->mru_list = - g_list_remove_link (window->display->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_remove_link (workspace_manager->active_workspace->mru_list, link); g_list_free (link); - window->display->active_workspace->mru_list = - g_list_append (window->display->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_append (workspace_manager->active_workspace->mru_list, window); } } @@ -116,6 +119,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay, guint32 timestamp) { MetaWindow *window = get_window (xdisplay, frame_xwindow); + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; lower_window_and_transients (window, NULL); @@ -123,7 +127,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay, * the focus window, assume that's always the case. (Typically, * this will be invoked via keyboard action or by a mouse action; * in either case the window or a modal child will have been focused.) */ - meta_workspace_focus_default_window (window->display->active_workspace, + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, timestamp); } diff --git a/src/core/display-private.h b/src/core/display-private.h index 769dbb134..c87e0b39b 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -242,16 +242,6 @@ struct _MetaDisplay guint work_area_later; guint check_fullscreen_later; - MetaWorkspace *active_workspace; - - GList *workspaces; - - int rows_of_workspaces; - int columns_of_workspaces; - MetaDisplayCorner starting_corner; - guint vertical_workspaces : 1; - guint workspace_layout_overridden : 1; - MetaBell *bell; MetaWorkspaceManager *workspace_manager; }; @@ -442,46 +432,4 @@ void meta_display_queue_check_fullscreen (MetaDisplay *display); MetaWindow *meta_display_get_pointer_window (MetaDisplay *display, MetaWindow *not_this_one); -void meta_display_init_workspaces (MetaDisplay *display); -void meta_display_update_workspace_layout (MetaDisplay *display, - MetaDisplayCorner starting_corner, - gboolean vertical_layout, - int n_rows, - int n_columns); - -typedef struct MetaWorkspaceLayout MetaWorkspaceLayout; - -struct MetaWorkspaceLayout -{ - int rows; - int cols; - int *grid; - int grid_area; - int current_row; - int current_col; -}; - -void meta_display_calc_workspace_layout (MetaDisplay *display, - int num_workspaces, - int current_space, - MetaWorkspaceLayout *layout); -void meta_display_free_workspace_layout (MetaWorkspaceLayout *layout); - -void meta_display_minimize_all_on_active_workspace_except (MetaDisplay *display, - MetaWindow *keep); - -/* Show/hide the desktop (temporarily hide all windows) */ -void meta_display_show_desktop (MetaDisplay *display, - guint32 timestamp); -void meta_display_unshow_desktop (MetaDisplay *display); - -void meta_display_workspace_switched (MetaDisplay *display, - int from, - int to, - MetaMotionDirection direction); - -void meta_display_update_num_workspaces (MetaDisplay *display, - guint32 timestamp, - int new_num); - #endif diff --git a/src/core/display.c b/src/core/display.c index 97d23f80d..f5cefb4e9 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -154,8 +154,7 @@ enum enum { PROP_0, - PROP_FOCUS_WINDOW, - PROP_N_WORKSPACES + PROP_FOCUS_WINDOW }; static guint display_signals [LAST_SIGNAL] = { 0 }; @@ -190,9 +189,6 @@ meta_display_get_property(GObject *object, case PROP_FOCUS_WINDOW: g_value_set_object (value, display->focus_window); break; - case PROP_N_WORKSPACES: - g_value_set_int (value, meta_display_get_n_workspaces (display)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -536,14 +532,6 @@ meta_display_class_init (MetaDisplayClass *klass) META_TYPE_WINDOW, G_PARAM_READABLE)); - g_object_class_install_property (object_class, - PROP_N_WORKSPACES, - g_param_spec_int ("n-workspaces", - "N Workspaces", - "Number of workspaces", - 1, G_MAXINT, 1, - G_PARAM_READABLE)); - } @@ -688,18 +676,6 @@ on_startup_notification_changed (MetaStartupNotification *sn, g_signal_emit_by_name (display, "startup-sequence-changed", sequence); } -static void -reload_logical_monitors (MetaDisplay *display) -{ - GList *l; - - for (l = display->workspaces; l != NULL; l = l->next) - { - MetaWorkspace *space = l->data; - meta_workspace_invalidate_work_area (space); - } -} - /** * meta_display_open: * @@ -762,13 +738,6 @@ meta_display_open (void) display->grab_tile_mode = META_TILE_NONE; display->grab_tile_monitor_number = -1; - display->active_workspace = NULL; - display->workspaces = NULL; - display->rows_of_workspaces = 1; - display->columns_of_workspaces = -1; - display->vertical_workspaces = FALSE; - display->starting_corner = META_DISPLAY_TOPLEFT; - display->grab_edge_resistance_data = NULL; meta_display_init_keys (display); @@ -793,25 +762,6 @@ meta_display_open (void) display->workspace_manager = meta_workspace_manager_new (display); - /* This is the default layout extracted from default - * variable values in update_num_workspaces () - * This can be overriden using _NET_DESKTOP_LAYOUT in - * meta_x11_display_new (), if it's specified */ - meta_display_update_workspace_layout (display, - META_DISPLAY_TOPLEFT, - FALSE, - -1, - 1); - - /* There must be at least one workspace at all times, - * so create that required workspace. - */ - meta_workspace_new (display); - - meta_display_init_workspaces (display); - - reload_logical_monitors (display); - display->startup_notification = meta_startup_notification_get (display); g_signal_connect (display->startup_notification, "changed", G_CALLBACK (on_startup_notification_changed), display); @@ -2564,18 +2514,6 @@ prefs_changed_callback (MetaPreference pref, { meta_display_reload_cursor (display); } - else if ((pref == META_PREF_NUM_WORKSPACES || - pref == META_PREF_DYNAMIC_WORKSPACES) && - !meta_prefs_get_dynamic_workspaces ()) - { - /* GSettings doesn't provide timestamps, but luckily update_num_workspaces - * often doesn't need it... - */ - guint32 timestamp = - meta_display_get_current_time_roundtrip (display); - int new_num = meta_prefs_get_num_workspaces (); - meta_display_update_num_workspaces (display, timestamp, new_num); - } } void @@ -3082,7 +3020,7 @@ on_monitors_changed_internal (MetaMonitorManager *monitor_manager, MetaBackend *backend; MetaCursorRenderer *cursor_renderer; - reload_logical_monitors (display); + meta_workspace_manager_reload_work_areas (display->workspace_manager); /* Fix up monitor for all windows on this display */ meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT, @@ -3665,6 +3603,7 @@ MetaWindow * meta_display_get_pointer_window (MetaDisplay *display, MetaWindow *not_this_one) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; MetaBackend *backend = meta_get_backend (); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); MetaWindow *window; @@ -3677,718 +3616,24 @@ meta_display_get_pointer_window (MetaDisplay *display, meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); window = meta_stack_get_default_focus_window_at_point (display->stack, - display->active_workspace, + workspace_manager->active_workspace, not_this_one, x, y); return window; } -void -meta_display_init_workspaces (MetaDisplay *display) -{ - int num; - - g_return_if_fail (META_IS_DISPLAY (display)); - - if (meta_prefs_get_dynamic_workspaces ()) - /* This will be properly updated using _NET_NUMBER_OF_DESKTOPS - * (if set) in meta_x11_display_new () */ - num = 1; - else - num = meta_prefs_get_num_workspaces (); - - meta_display_update_num_workspaces (display, META_CURRENT_TIME, num); - - meta_workspace_activate (display->workspaces->data, META_CURRENT_TIME); -} - -int -meta_display_get_n_workspaces (MetaDisplay *display) -{ - return g_list_length (display->workspaces); -} - -/** - * meta_display_get_workspace_by_index: - * @display: a #MetaDisplay - * @index: index of one of the display's workspaces - * - * Gets the workspace object for one of a display's workspaces given the workspace - * index. It's valid to call this function with an out-of-range index and it - * will robustly return %NULL. - * - * Return value: (transfer none): the workspace object with specified index, or %NULL - * if the index is out of range. - */ -MetaWorkspace * -meta_display_get_workspace_by_index (MetaDisplay *display, - int idx) -{ - return g_list_nth_data (display->workspaces, idx); -} - -void -meta_display_remove_workspace (MetaDisplay *display, - MetaWorkspace *workspace, - guint32 timestamp) -{ - GList *l; - GList *next; - MetaWorkspace *neighbour = NULL; - int index; - gboolean active_index_changed; - int new_num; - - l = g_list_find (display->workspaces, workspace); - if (!l) - return; - - next = l->next; - - if (l->prev) - neighbour = l->prev->data; - else if (l->next) - neighbour = l->next->data; - else - { - /* Cannot remove the only workspace! */ - return; - } - - meta_workspace_relocate_windows (workspace, neighbour); - - if (workspace == display->active_workspace) - meta_workspace_activate (neighbour, timestamp); - - /* To emit the signal after removing the workspace */ - index = meta_workspace_index (workspace); - active_index_changed = index < meta_display_get_active_workspace_index (display); - - /* This also removes the workspace from the displays list */ - meta_workspace_remove (workspace); - - new_num = g_list_length (display->workspaces); - - if (!meta_prefs_get_dynamic_workspaces ()) - meta_prefs_set_num_workspaces (new_num); - - /* If deleting a workspace before the current workspace, the active - * workspace index changes, so we need to update that hint */ - if (active_index_changed) - g_signal_emit (display, display_signals[ACTIVE_WORKSPACE_CHANGED], 0, NULL); - - for (l = next; l; l = l->next) - { - MetaWorkspace *w = l->data; - - meta_workspace_index_changed (w); - } - - meta_display_queue_workarea_recalc (display); - - g_signal_emit (display, display_signals[WORKSPACE_REMOVED], 0, index); - g_object_notify (G_OBJECT (display), "n-workspaces"); -} - -/** - * meta_display_append_new_workspace: - * @display: a #MetaDisplay - * @activate: %TRUE if the workspace should be switched to after creation - * @timestamp: if switching to a new workspace, timestamp to be used when - * focusing a window on the new workspace. (Doesn't hurt to pass a valid - * timestamp when available even if not switching workspaces.) - * - * Append a new workspace to the display and (optionally) switch to that - * display. - * - * Return value: (transfer none): the newly appended workspace. - */ -MetaWorkspace * -meta_display_append_new_workspace (MetaDisplay *display, - gboolean activate, - guint32 timestamp) -{ - MetaWorkspace *w; - int new_num; - - /* This also adds the workspace to the display list */ - w = meta_workspace_new (display); - - if (!w) - return NULL; - - if (activate) - meta_workspace_activate (w, timestamp); - - new_num = g_list_length (display->workspaces); - - if (!meta_prefs_get_dynamic_workspaces ()) - meta_prefs_set_num_workspaces (new_num); - - meta_display_queue_workarea_recalc (display); - - g_signal_emit (display, display_signals[WORKSPACE_ADDED], - 0, meta_workspace_index (w)); - g_object_notify (G_OBJECT (display), "n-workspaces"); - - return w; -} - -void -meta_display_update_num_workspaces (MetaDisplay *display, - guint32 timestamp, - int new_num) -{ - int old_num; - GList *l; - int i = 0; - GList *extras = NULL; - MetaWorkspace *last_remaining = NULL; - gboolean need_change_space = FALSE; - - g_assert (new_num > 0); - - if (g_list_length (display->workspaces) == (guint) new_num) - return; - - for (l = display->workspaces; l != NULL; l = l->next) - { - MetaWorkspace *w = l->data; - - if (i >= new_num) - extras = g_list_prepend (extras, w); - else - last_remaining = w; - - ++i; - } - old_num = i; - - g_assert (last_remaining); - - /* Get rid of the extra workspaces by moving all their windows - * to last_remaining, then activating last_remaining if - * one of the removed workspaces was active. This will be a bit - * wacky if the config tool for changing number of workspaces - * is on a removed workspace ;-) - */ - for (l = extras; l != NULL; l = l->next) - { - MetaWorkspace *w = l->data; - - meta_workspace_relocate_windows (w, last_remaining); - - if (w == display->active_workspace) - need_change_space = TRUE; - } - - if (need_change_space) - meta_workspace_activate (last_remaining, timestamp); - - /* Should now be safe to free the workspaces */ - for (l = extras; l != NULL; l = l->next) - { - MetaWorkspace *w = l->data; - - meta_workspace_remove (w); - } - - g_list_free (extras); - - for (i = old_num; i < new_num; i++) - meta_workspace_new (display); - - meta_display_queue_workarea_recalc (display); - - for (i = old_num; i < new_num; i++) - g_signal_emit (display, display_signals[WORKSPACE_ADDED], 0, i); - - g_object_notify (G_OBJECT (display), "n-workspaces"); -} - -void -meta_display_update_workspace_layout (MetaDisplay *display, - MetaDisplayCorner starting_corner, - gboolean vertical_layout, - int n_rows, - int n_columns) -{ - g_return_if_fail (META_IS_DISPLAY (display)); - g_return_if_fail (n_rows > 0 || n_columns > 0); - g_return_if_fail (n_rows != 0 && n_columns != 0); - - if (display->workspace_layout_overridden) - return; - - display->vertical_workspaces = vertical_layout != FALSE; - display->starting_corner = starting_corner; - display->rows_of_workspaces = n_rows; - display->columns_of_workspaces = n_columns; - - meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n", - display->rows_of_workspaces, - display->columns_of_workspaces, - display->vertical_workspaces, - display->starting_corner); -} - -/** - * meta_display_override_workspace_layout: - * @display: a #MetaDisplay - * @starting_corner: the corner at which the first workspace is found - * @vertical_layout: if %TRUE the workspaces are laid out in columns rather than rows - * @n_rows: number of rows of workspaces, or -1 to determine the number of rows from - * @n_columns and the total number of workspaces - * @n_columns: number of columns of workspaces, or -1 to determine the number of columns from - * @n_rows and the total number of workspaces - * - * Explicitly set the layout of workspaces. Once this has been called, the contents of the - * _NET_DESKTOP_LAYOUT property on the root window are completely ignored. - */ -void -meta_display_override_workspace_layout (MetaDisplay *display, - MetaDisplayCorner starting_corner, - gboolean vertical_layout, - int n_rows, - int n_columns) -{ - meta_display_update_workspace_layout (display, - starting_corner, - vertical_layout, - n_rows, - n_columns); - - display->workspace_layout_overridden = TRUE; -} - -#ifdef WITH_VERBOSE_MODE -static const char * -meta_display_corner_to_string (MetaDisplayCorner corner) -{ - switch (corner) - { - case META_DISPLAY_TOPLEFT: - return "TopLeft"; - case META_DISPLAY_TOPRIGHT: - return "TopRight"; - case META_DISPLAY_BOTTOMLEFT: - return "BottomLeft"; - case META_DISPLAY_BOTTOMRIGHT: - return "BottomRight"; - } - - return "Unknown"; -} -#endif /* WITH_VERBOSE_MODE */ - -void -meta_display_calc_workspace_layout (MetaDisplay *display, - int num_workspaces, - int current_space, - MetaWorkspaceLayout *layout) -{ - int rows, cols; - int grid_area; - int *grid; - int i, r, c; - int current_row, current_col; - - rows = display->rows_of_workspaces; - cols = display->columns_of_workspaces; - if (rows <= 0 && cols <= 0) - cols = num_workspaces; - - if (rows <= 0) - rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0); - if (cols <= 0) - cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0); - - /* paranoia */ - if (rows < 1) - rows = 1; - if (cols < 1) - cols = 1; - - g_assert (rows != 0 && cols != 0); - - grid_area = rows * cols; - - meta_verbose ("Getting layout rows = %d cols = %d current = %d " - "num_spaces = %d vertical = %s corner = %s\n", - rows, cols, current_space, num_workspaces, - display->vertical_workspaces ? "(true)" : "(false)", - meta_display_corner_to_string (display->starting_corner)); - - /* ok, we want to setup the distances in the workspace array to go - * in each direction. Remember, there are many ways that a workspace - * array can be setup. - * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html - * and look at the _NET_DESKTOP_LAYOUT section for details. - * For instance: - */ - /* starting_corner = META_DISPLAY_TOPLEFT - * vertical_workspaces = 0 vertical_workspaces=1 - * 1234 1357 - * 5678 2468 - * - * starting_corner = META_DISPLAY_TOPRIGHT - * vertical_workspaces = 0 vertical_workspaces=1 - * 4321 7531 - * 8765 8642 - * - * starting_corner = META_DISPLAY_BOTTOMLEFT - * vertical_workspaces = 0 vertical_workspaces=1 - * 5678 2468 - * 1234 1357 - * - * starting_corner = META_DISPLAY_BOTTOMRIGHT - * vertical_workspaces = 0 vertical_workspaces=1 - * 8765 8642 - * 4321 7531 - * - */ - /* keep in mind that we could have a ragged layout, e.g. the "8" - * in the above grids could be missing - */ - - - grid = g_new (int, grid_area); - - current_row = -1; - current_col = -1; - i = 0; - - switch (display->starting_corner) - { - case META_DISPLAY_TOPLEFT: - if (display->vertical_workspaces) - { - c = 0; - while (c < cols) - { - r = 0; - while (r < rows) - { - grid[r*cols+c] = i; - ++i; - ++r; - } - ++c; - } - } - else - { - r = 0; - while (r < rows) - { - c = 0; - while (c < cols) - { - grid[r*cols+c] = i; - ++i; - ++c; - } - ++r; - } - } - break; - case META_DISPLAY_TOPRIGHT: - if (display->vertical_workspaces) - { - c = cols - 1; - while (c >= 0) - { - r = 0; - while (r < rows) - { - grid[r*cols+c] = i; - ++i; - ++r; - } - --c; - } - } - else - { - r = 0; - while (r < rows) - { - c = cols - 1; - while (c >= 0) - { - grid[r*cols+c] = i; - ++i; - --c; - } - ++r; - } - } - break; - case META_DISPLAY_BOTTOMLEFT: - if (display->vertical_workspaces) - { - c = 0; - while (c < cols) - { - r = rows - 1; - while (r >= 0) - { - grid[r*cols+c] = i; - ++i; - --r; - } - ++c; - } - } - else - { - r = rows - 1; - while (r >= 0) - { - c = 0; - while (c < cols) - { - grid[r*cols+c] = i; - ++i; - ++c; - } - --r; - } - } - break; - case META_DISPLAY_BOTTOMRIGHT: - if (display->vertical_workspaces) - { - c = cols - 1; - while (c >= 0) - { - r = rows - 1; - while (r >= 0) - { - grid[r*cols+c] = i; - ++i; - --r; - } - --c; - } - } - else - { - r = rows - 1; - while (r >= 0) - { - c = cols - 1; - while (c >= 0) - { - grid[r*cols+c] = i; - ++i; - --c; - } - --r; - } - } - break; - } - - if (i != grid_area) - meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n", - G_STRFUNC, i); - - current_row = 0; - current_col = 0; - r = 0; - while (r < rows) - { - c = 0; - while (c < cols) - { - if (grid[r*cols+c] == current_space) - { - current_row = r; - current_col = c; - } - else if (grid[r*cols+c] >= num_workspaces) - { - /* flag nonexistent spaces with -1 */ - grid[r*cols+c] = -1; - } - ++c; - } - ++r; - } - - layout->rows = rows; - layout->cols = cols; - layout->grid = grid; - layout->grid_area = grid_area; - layout->current_row = current_row; - layout->current_col = current_col; - -#ifdef WITH_VERBOSE_MODE - if (meta_is_verbose ()) - { - r = 0; - while (r < layout->rows) - { - meta_verbose (" "); - meta_push_no_msg_prefix (); - c = 0; - while (c < layout->cols) - { - if (r == layout->current_row && - c == layout->current_col) - meta_verbose ("*%2d ", layout->grid[r*layout->cols+c]); - else - meta_verbose ("%3d ", layout->grid[r*layout->cols+c]); - ++c; - } - meta_verbose ("\n"); - meta_pop_no_msg_prefix (); - ++r; - } - } -#endif /* WITH_VERBOSE_MODE */ -} - -void -meta_display_free_workspace_layout (MetaWorkspaceLayout *layout) -{ - g_free (layout->grid); -} - -static void -queue_windows_showing (MetaDisplay *display) -{ - GSList *windows, *l; - - /* Must operate on all windows on display instead of just on the - * active_workspace's window list, because the active_workspace's - * window list may not contain the on_all_workspace windows. - */ - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - - for (l = windows; l != NULL; l = l->next) - { - MetaWindow *w = l->data; - meta_window_queue (w, META_QUEUE_CALC_SHOWING); - } - - g_slist_free (windows); -} - -void -meta_display_minimize_all_on_active_workspace_except (MetaDisplay *display, - MetaWindow *keep) -{ - GList *l; - - for (l = display->active_workspace->windows; l != NULL; l = l->next) - { - MetaWindow *w = l->data; - - if (w->has_minimize_func && w != keep) - meta_window_minimize (w); - } -} - -void -meta_display_show_desktop (MetaDisplay *display, - guint32 timestamp) -{ - GList *l; - - if (display->active_workspace->showing_desktop) - return; - - display->active_workspace->showing_desktop = TRUE; - - queue_windows_showing (display); - - /* Focus the most recently used META_WINDOW_DESKTOP window, if there is one; - * see bug 159257. - */ - for (l = display->active_workspace->mru_list; l != NULL; l = l->next) - { - MetaWindow *w = l->data; - - if (w->type == META_WINDOW_DESKTOP) - { - meta_window_focus (w, timestamp); - break; - } - } - - g_signal_emit (display, display_signals[SHOWING_DESKTOP_CHANGED], 0, NULL); -} - -void -meta_display_unshow_desktop (MetaDisplay *display) -{ - if (!display->active_workspace->showing_desktop) - return; - - display->active_workspace->showing_desktop = FALSE; - - queue_windows_showing (display); - - g_signal_emit (display, display_signals[SHOWING_DESKTOP_CHANGED], 0, NULL); -} - -/** - * meta_display_get_workspaces: (skip) - * @display: a #MetaDisplay - * - * Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @display - */ -GList * -meta_display_get_workspaces (MetaDisplay *display) -{ - return display->workspaces; -} - -int -meta_display_get_active_workspace_index (MetaDisplay *display) -{ - MetaWorkspace *active = display->active_workspace; - - if (!active) - return -1; - - return meta_workspace_index (active); -} - -/** - * meta_display_get_active_workspace: - * @display: A #MetaDisplay - * - * Returns: (transfer none): The current workspace - */ -MetaWorkspace * -meta_display_get_active_workspace (MetaDisplay *display) -{ - return display->active_workspace; -} - void meta_display_focus_default_window (MetaDisplay *display, guint32 timestamp) { - meta_workspace_focus_default_window (display->active_workspace, + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, timestamp); } -void -meta_display_workspace_switched (MetaDisplay *display, - int from, - int to, - MetaMotionDirection direction) -{ - g_signal_emit (display, display_signals[WORKSPACE_SWITCHED], 0, - from, to, direction); -} - MetaWorkspaceManager * meta_display_get_workspace_manager (MetaDisplay *display) { diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c index 245e6ae52..963b365d9 100644 --- a/src/core/edge-resistance.c +++ b/src/core/edge-resistance.c @@ -23,6 +23,7 @@ #include "edge-resistance.h" #include "boxes-private.h" #include "display-private.h" +#include "meta-workspace-manager-private.h" #include "workspace-private.h" /* A simple macro for whether a given window's edges are potentially @@ -999,6 +1000,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) * in the layer that we are working on */ GSList *rem_windows, *rem_win_stacking; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; g_assert (display->grab_window != NULL); meta_topic (META_DEBUG_WINDOW_OPS, @@ -1010,7 +1012,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) */ stacked_windows = meta_stack_list_windows (display->stack, - display->active_workspace); + workspace_manager->active_workspace); /* * 2nd: we need to separate that stacked list into a list of windows that @@ -1172,8 +1174,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) */ cache_edges (display, edges, - display->active_workspace->monitor_edges, - display->active_workspace->screen_edges); + workspace_manager->active_workspace->monitor_edges, + workspace_manager->active_workspace->screen_edges); g_list_free (edges); /* diff --git a/src/core/keybindings.c b/src/core/keybindings.c index ebce5396f..3152c8058 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -29,6 +29,7 @@ #include #include "keybindings-private.h" +#include "meta-workspace-manager-private.h" #include "workspace-private.h" #include #include @@ -2733,8 +2734,9 @@ handle_switch_to_last_workspace (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - gint target = meta_display_get_n_workspaces(display) - 1; - MetaWorkspace *workspace = meta_display_get_workspace_by_index (display, target); + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + gint target = meta_workspace_manager_get_n_workspaces (workspace_manager) - 1; + MetaWorkspace *workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, target); meta_workspace_activate (workspace, event->time); } @@ -2746,6 +2748,7 @@ handle_switch_to_workspace (MetaDisplay *display, gpointer dummy) { gint which = binding->handler->data; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; MetaWorkspace *workspace; if (which < 0) @@ -2754,12 +2757,12 @@ handle_switch_to_workspace (MetaDisplay *display, * current workspace. */ - workspace = meta_workspace_get_neighbor (display->active_workspace, + workspace = meta_workspace_get_neighbor (workspace_manager->active_workspace, which); } else { - workspace = meta_display_get_workspace_by_index (display, which); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which); } if (workspace) @@ -2982,15 +2985,17 @@ handle_show_desktop (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - if (display->active_workspace->showing_desktop) + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + + if (workspace_manager->active_workspace->showing_desktop) { - meta_display_unshow_desktop (display); - meta_workspace_focus_default_window (display->active_workspace, + meta_workspace_manager_unshow_desktop (workspace_manager); + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, event->time); } else - meta_display_show_desktop (display, event->time); + meta_workspace_manager_show_desktop (workspace_manager, event->time); } static void @@ -3077,6 +3082,7 @@ do_choose_window (MetaDisplay *display, MetaKeyBinding *binding, gboolean backward) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; MetaTabList type = binding->handler->data; MetaWindow *window; @@ -3085,7 +3091,7 @@ do_choose_window (MetaDisplay *display, window = meta_display_get_tab_next (display, type, - display->active_workspace, + workspace_manager->active_workspace, NULL, backward); @@ -3299,14 +3305,15 @@ handle_move_to_workspace_last (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; gint which; MetaWorkspace *workspace; if (window->always_sticky) return; - which = meta_display_get_n_workspaces (display) - 1; - workspace = meta_display_get_workspace_by_index (display, which); + which = meta_workspace_manager_get_n_workspaces (workspace_manager) - 1; + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which); meta_window_change_workspace (window, workspace); } @@ -3318,6 +3325,7 @@ handle_move_to_workspace (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; gint which = binding->handler->data; gboolean flip = (which < 0); MetaWorkspace *workspace; @@ -3336,12 +3344,12 @@ handle_move_to_workspace (MetaDisplay *display, workspace = NULL; if (flip) { - workspace = meta_workspace_get_neighbor (display->active_workspace, + workspace = meta_workspace_get_neighbor (workspace_manager->active_workspace, which); } else { - workspace = meta_display_get_workspace_by_index (display, which); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which); } if (workspace) diff --git a/src/core/meta-workspace-manager-private.h b/src/core/meta-workspace-manager-private.h index 1dafa5039..261c4d47c 100644 --- a/src/core/meta-workspace-manager-private.h +++ b/src/core/meta-workspace-manager-private.h @@ -48,4 +48,49 @@ struct _MetaWorkspaceManager MetaWorkspaceManager *meta_workspace_manager_new (MetaDisplay *display); +void meta_workspace_manager_init_workspaces (MetaWorkspaceManager *workspace_manager); +void meta_workspace_manager_update_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns); + +void meta_workspace_manager_reload_work_areas (MetaWorkspaceManager *workspace_manager); + +typedef struct MetaWorkspaceLayout MetaWorkspaceLayout; + +struct MetaWorkspaceLayout +{ + int rows; + int cols; + int *grid; + int grid_area; + int current_row; + int current_col; +}; + +void meta_workspace_manager_calc_workspace_layout (MetaWorkspaceManager *workspace_manager, + int num_workspaces, + int current_space, + MetaWorkspaceLayout *layout); + +void meta_workspace_manager_free_workspace_layout (MetaWorkspaceLayout *layout); + +void meta_workspace_manager_minimize_all_on_active_workspace_except (MetaWorkspaceManager *workspace_manager, + MetaWindow *keep); + +/* Show/hide the desktop (temporarily hide all windows) */ +void meta_workspace_manager_show_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp); +void meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager); + +void meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manager, + int from, + int to, + MetaMotionDirection direction); + +void meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspace_manager, + guint32 timestamp, + int new_num); + #endif /* META_WORKSPACE_MANAGER_PRIVATE_H */ diff --git a/src/core/meta-workspace-manager.c b/src/core/meta-workspace-manager.c index 0521337e1..2670f4938 100644 --- a/src/core/meta-workspace-manager.c +++ b/src/core/meta-workspace-manager.c @@ -28,7 +28,12 @@ #include #include +#include "core/window-private.h" +#include "core/workspace-private.h" + #include "meta/meta-enum-types.h" +#include "meta/prefs.h" +#include "meta/util.h" G_DEFINE_TYPE (MetaWorkspaceManager, meta_workspace_manager, G_TYPE_OBJECT) @@ -50,6 +55,9 @@ enum { static guint workspace_manager_signals [LAST_SIGNAL] = { 0 }; +static void prefs_changed_callback (MetaPreference pref, + gpointer data); + static void meta_workspace_manager_get_property (GObject *object, guint prop_id, @@ -83,6 +91,16 @@ meta_workspace_manager_set_property (GObject *object, } } +static void +meta_workspace_manager_finalize (GObject *object) +{ + MetaWorkspaceManager *workspace_manager = META_WORKSPACE_MANAGER (object); + + meta_prefs_remove_listener (prefs_changed_callback, workspace_manager); + + G_OBJECT_CLASS (meta_workspace_manager_parent_class)->finalize (object); +} + static void meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass) { @@ -91,6 +109,8 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass) object_class->get_property = meta_workspace_manager_get_property; object_class->set_property = meta_workspace_manager_set_property; + object_class->finalize = meta_workspace_manager_finalize; + workspace_manager_signals[WORKSPACE_ADDED] = g_signal_new ("workspace-added", G_TYPE_FROM_CLASS (klass), @@ -133,6 +153,14 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + + g_object_class_install_property (object_class, + PROP_N_WORKSPACES, + g_param_spec_int ("n-workspaces", + "N Workspaces", + "Number of workspaces", + 1, G_MAXINT, 1, + G_PARAM_READABLE)); } static void @@ -140,6 +168,19 @@ meta_workspace_manager_init (MetaWorkspaceManager *workspace_manager) { } +void +meta_workspace_manager_reload_work_areas (MetaWorkspaceManager *workspace_manager) +{ + GList *l; + + for (l = workspace_manager->workspaces; l; l = l->next) + { + MetaWorkspace *workspace = l->data; + + meta_workspace_invalidate_work_area (workspace); + } +} + MetaWorkspaceManager * meta_workspace_manager_new (MetaDisplay *display) { @@ -155,11 +196,756 @@ meta_workspace_manager_new (MetaDisplay *display) workspace_manager->vertical_workspaces = FALSE; workspace_manager->starting_corner = META_DISPLAY_TOPLEFT; + /* This is the default layout extracted from default + * variable values in update_num_workspaces () + * This can be overriden using _NET_DESKTOP_LAYOUT in + * meta_x11_display_new (), if it's specified */ + meta_workspace_manager_update_workspace_layout (workspace_manager, + META_DISPLAY_TOPLEFT, + FALSE, + -1, + 1); + + /* There must be at least one workspace at all times, + * so create that required workspace. + */ + meta_workspace_new (workspace_manager); + + meta_workspace_manager_init_workspaces (workspace_manager); + + meta_prefs_add_listener (prefs_changed_callback, workspace_manager); + return workspace_manager; } +void +meta_workspace_manager_init_workspaces (MetaWorkspaceManager *workspace_manager) +{ + int num; + + g_return_if_fail (META_IS_WORKSPACE_MANAGER (workspace_manager)); + + if (meta_prefs_get_dynamic_workspaces ()) + /* This will be properly updated using _NET_NUMBER_OF_DESKTOPS + * (if set) in meta_x11_display_new () */ + num = 1; + else + num = meta_prefs_get_num_workspaces (); + + meta_workspace_manager_update_num_workspaces (workspace_manager, META_CURRENT_TIME, num); + + meta_workspace_activate (workspace_manager->workspaces->data, META_CURRENT_TIME); + + meta_workspace_manager_reload_work_areas (workspace_manager); +} + int meta_workspace_manager_get_n_workspaces (MetaWorkspaceManager *workspace_manager) { return g_list_length (workspace_manager->workspaces); } + +/** + * meta_workspace_manager_get_workspace_by_index: + * @workspace_manager: a #MetaWorkspaceManager + * @index: index of one of the display's workspaces + * + * Gets the workspace object for one of a workspace manager's workspaces given the workspace + * index. It's valid to call this function with an out-of-range index and it + * will robustly return %NULL. + * + * Return value: (transfer none): the workspace object with specified index, or %NULL + * if the index is out of range. + */ +MetaWorkspace * +meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager, + int idx) +{ + return g_list_nth_data (workspace_manager->workspaces, idx); +} + +void +meta_workspace_manager_remove_workspace (MetaWorkspaceManager *workspace_manager, + MetaWorkspace *workspace, + guint32 timestamp) +{ + GList *l; + GList *next; + MetaWorkspace *neighbour = NULL; + int index; + int active_index; + gboolean active_index_changed; + int new_num; + + l = g_list_find (workspace_manager->workspaces, workspace); + if (!l) + return; + + next = l->next; + + if (l->prev) + neighbour = l->prev->data; + else if (l->next) + neighbour = l->next->data; + else + { + /* Cannot remove the only workspace! */ + return; + } + + meta_workspace_relocate_windows (workspace, neighbour); + + if (workspace == workspace_manager->active_workspace) + meta_workspace_activate (neighbour, timestamp); + + /* To emit the signal after removing the workspace */ + index = meta_workspace_index (workspace); + active_index = meta_workspace_manager_get_active_workspace_index (workspace_manager); + active_index_changed = index < active_index; + + /* This also removes the workspace from the displays list */ + meta_workspace_remove (workspace); + + new_num = g_list_length (workspace_manager->workspaces); + + if (!meta_prefs_get_dynamic_workspaces ()) + meta_prefs_set_num_workspaces (new_num); + + /* If deleting a workspace before the current workspace, the active + * workspace index changes, so we need to update that hint */ + if (active_index_changed) + g_signal_emit (workspace_manager, + workspace_manager_signals[ACTIVE_WORKSPACE_CHANGED], + 0, NULL); + + for (l = next; l; l = l->next) + { + MetaWorkspace *w = l->data; + meta_workspace_index_changed (w); + } + + meta_display_queue_workarea_recalc (workspace_manager->display); + + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACE_REMOVED], + 0, index); + g_object_notify (G_OBJECT (workspace_manager), "n-workspaces"); +} + +/** + * meta_workspace_manager_append_new_workspace: + * @workspace_manager: a #MetaWorkspaceManager + * @activate: %TRUE if the workspace should be switched to after creation + * @timestamp: if switching to a new workspace, timestamp to be used when + * focusing a window on the new workspace. (Doesn't hurt to pass a valid + * timestamp when available even if not switching workspaces.) + * + * Append a new workspace to the workspace manager and (optionally) switch to that + * display. + * + * Return value: (transfer none): the newly appended workspace. + */ +MetaWorkspace * +meta_workspace_manager_append_new_workspace (MetaWorkspaceManager *workspace_manager, + gboolean activate, + guint32 timestamp) +{ + MetaWorkspace *w; + int new_num; + + /* This also adds the workspace to the workspace manager list */ + w = meta_workspace_new (workspace_manager); + + if (!w) + return NULL; + + if (activate) + meta_workspace_activate (w, timestamp); + + new_num = g_list_length (workspace_manager->workspaces); + + if (!meta_prefs_get_dynamic_workspaces ()) + meta_prefs_set_num_workspaces (new_num); + + meta_display_queue_workarea_recalc (workspace_manager->display); + + g_signal_emit (workspace_manager, workspace_manager_signals[WORKSPACE_ADDED], + 0, meta_workspace_index (w)); + g_object_notify (G_OBJECT (workspace_manager), "n-workspaces"); + + return w; +} + +void +meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspace_manager, + guint32 timestamp, + int new_num) +{ + int old_num; + GList *l; + int i = 0; + GList *extras = NULL; + MetaWorkspace *last_remaining = NULL; + gboolean need_change_space = FALSE; + + g_assert (new_num > 0); + + if (g_list_length (workspace_manager->workspaces) == (guint) new_num) + return; + + for (l = workspace_manager->workspaces; l; l = l->next) + { + MetaWorkspace *w = l->data; + + if (i >= new_num) + extras = g_list_prepend (extras, w); + else + last_remaining = w; + + ++i; + } + old_num = i; + + g_assert (last_remaining); + + /* Get rid of the extra workspaces by moving all their windows + * to last_remaining, then activating last_remaining if + * one of the removed workspaces was active. This will be a bit + * wacky if the config tool for changing number of workspaces + * is on a removed workspace ;-) + */ + for (l = extras; l; l = l->next) + { + MetaWorkspace *w = l->data; + + meta_workspace_relocate_windows (w, last_remaining); + + if (w == workspace_manager->active_workspace) + need_change_space = TRUE; + } + + if (need_change_space) + meta_workspace_activate (last_remaining, timestamp); + + /* Should now be safe to free the workspaces */ + for (l = extras; l; l = l->next) + { + MetaWorkspace *w = l->data; + + meta_workspace_remove (w); + } + + g_list_free (extras); + + for (i = old_num; i < new_num; i++) + meta_workspace_new (workspace_manager); + + meta_display_queue_workarea_recalc (workspace_manager->display); + + for (i = old_num; i < new_num; i++) + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACE_ADDED], + 0, i); + + g_object_notify (G_OBJECT (workspace_manager), "n-workspaces"); +} + +void +meta_workspace_manager_update_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns) +{ + g_return_if_fail (META_IS_WORKSPACE_MANAGER (workspace_manager)); + g_return_if_fail (n_rows > 0 || n_columns > 0); + g_return_if_fail (n_rows != 0 && n_columns != 0); + + if (workspace_manager->workspace_layout_overridden) + return; + + workspace_manager->vertical_workspaces = vertical_layout != FALSE; + workspace_manager->starting_corner = starting_corner; + workspace_manager->rows_of_workspaces = n_rows; + workspace_manager->columns_of_workspaces = n_columns; + + meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n", + workspace_manager->rows_of_workspaces, + workspace_manager->columns_of_workspaces, + workspace_manager->vertical_workspaces, + workspace_manager->starting_corner); +} + +/** + * meta_workspace_manager_override_workspace_layout: + * @workspace_manager: a #MetaWorkspaceManager + * @starting_corner: the corner at which the first workspace is found + * @vertical_layout: if %TRUE the workspaces are laid out in columns rather than rows + * @n_rows: number of rows of workspaces, or -1 to determine the number of rows from + * @n_columns and the total number of workspaces + * @n_columns: number of columns of workspaces, or -1 to determine the number of columns from + * @n_rows and the total number of workspaces + * + * Explicitly set the layout of workspaces. Once this has been called, the contents of the + * _NET_DESKTOP_LAYOUT property on the root window are completely ignored. + */ +void +meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns) +{ + meta_workspace_manager_update_workspace_layout (workspace_manager, + starting_corner, + vertical_layout, + n_rows, + n_columns); + + workspace_manager->workspace_layout_overridden = TRUE; +} + +#ifdef WITH_VERBOSE_MODE +static const char * +meta_workspace_manager_corner_to_string (MetaDisplayCorner corner) +{ + switch (corner) + { + case META_DISPLAY_TOPLEFT: + return "TopLeft"; + case META_DISPLAY_TOPRIGHT: + return "TopRight"; + case META_DISPLAY_BOTTOMLEFT: + return "BottomLeft"; + case META_DISPLAY_BOTTOMRIGHT: + return "BottomRight"; + } + + return "Unknown"; +} +#endif /* WITH_VERBOSE_MODE */ + +void +meta_workspace_manager_calc_workspace_layout (MetaWorkspaceManager *workspace_manager, + int num_workspaces, + int current_space, + MetaWorkspaceLayout *layout) +{ + int rows, cols; + int grid_area; + int *grid; + int i, r, c; + int current_row, current_col; + + rows = workspace_manager->rows_of_workspaces; + cols = workspace_manager->columns_of_workspaces; + if (rows <= 0 && cols <= 0) + cols = num_workspaces; + + if (rows <= 0) + rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0); + if (cols <= 0) + cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0); + + /* paranoia */ + if (rows < 1) + rows = 1; + if (cols < 1) + cols = 1; + + g_assert (rows != 0 && cols != 0); + + grid_area = rows * cols; + + meta_verbose ("Getting layout rows = %d cols = %d current = %d " + "num_spaces = %d vertical = %s corner = %s\n", + rows, cols, current_space, num_workspaces, + workspace_manager->vertical_workspaces ? "(true)" : "(false)", + meta_workspace_manager_corner_to_string (workspace_manager->starting_corner)); + + /* ok, we want to setup the distances in the workspace array to go + * in each direction. Remember, there are many ways that a workspace + * array can be setup. + * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html + * and look at the _NET_DESKTOP_LAYOUT section for details. + * For instance: + */ + /* starting_corner = META_DISPLAY_TOPLEFT + * vertical_workspaces = 0 vertical_workspaces=1 + * 1234 1357 + * 5678 2468 + * + * starting_corner = META_DISPLAY_TOPRIGHT + * vertical_workspaces = 0 vertical_workspaces=1 + * 4321 7531 + * 8765 8642 + * + * starting_corner = META_DISPLAY_BOTTOMLEFT + * vertical_workspaces = 0 vertical_workspaces=1 + * 5678 2468 + * 1234 1357 + * + * starting_corner = META_DISPLAY_BOTTOMRIGHT + * vertical_workspaces = 0 vertical_workspaces=1 + * 8765 8642 + * 4321 7531 + * + */ + /* keep in mind that we could have a ragged layout, e.g. the "8" + * in the above grids could be missing + */ + + + grid = g_new (int, grid_area); + + current_row = -1; + current_col = -1; + i = 0; + + switch (workspace_manager->starting_corner) + { + case META_DISPLAY_TOPLEFT: + if (workspace_manager->vertical_workspaces) + { + c = 0; + while (c < cols) + { + r = 0; + while (r < rows) + { + grid[r*cols+c] = i; + ++i; + ++r; + } + ++c; + } + } + else + { + r = 0; + while (r < rows) + { + c = 0; + while (c < cols) + { + grid[r*cols+c] = i; + ++i; + ++c; + } + ++r; + } + } + break; + case META_DISPLAY_TOPRIGHT: + if (workspace_manager->vertical_workspaces) + { + c = cols - 1; + while (c >= 0) + { + r = 0; + while (r < rows) + { + grid[r*cols+c] = i; + ++i; + ++r; + } + --c; + } + } + else + { + r = 0; + while (r < rows) + { + c = cols - 1; + while (c >= 0) + { + grid[r*cols+c] = i; + ++i; + --c; + } + ++r; + } + } + break; + case META_DISPLAY_BOTTOMLEFT: + if (workspace_manager->vertical_workspaces) + { + c = 0; + while (c < cols) + { + r = rows - 1; + while (r >= 0) + { + grid[r*cols+c] = i; + ++i; + --r; + } + ++c; + } + } + else + { + r = rows - 1; + while (r >= 0) + { + c = 0; + while (c < cols) + { + grid[r*cols+c] = i; + ++i; + ++c; + } + --r; + } + } + break; + case META_DISPLAY_BOTTOMRIGHT: + if (workspace_manager->vertical_workspaces) + { + c = cols - 1; + while (c >= 0) + { + r = rows - 1; + while (r >= 0) + { + grid[r*cols+c] = i; + ++i; + --r; + } + --c; + } + } + else + { + r = rows - 1; + while (r >= 0) + { + c = cols - 1; + while (c >= 0) + { + grid[r*cols+c] = i; + ++i; + --c; + } + --r; + } + } + break; + } + + if (i != grid_area) + meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n", + G_STRFUNC, i); + + current_row = 0; + current_col = 0; + r = 0; + while (r < rows) + { + c = 0; + while (c < cols) + { + if (grid[r*cols+c] == current_space) + { + current_row = r; + current_col = c; + } + else if (grid[r*cols+c] >= num_workspaces) + { + /* flag nonexistent spaces with -1 */ + grid[r*cols+c] = -1; + } + ++c; + } + ++r; + } + + layout->rows = rows; + layout->cols = cols; + layout->grid = grid; + layout->grid_area = grid_area; + layout->current_row = current_row; + layout->current_col = current_col; + +#ifdef WITH_VERBOSE_MODE + if (meta_is_verbose ()) + { + r = 0; + while (r < layout->rows) + { + meta_verbose (" "); + meta_push_no_msg_prefix (); + c = 0; + while (c < layout->cols) + { + if (r == layout->current_row && + c == layout->current_col) + meta_verbose ("*%2d ", layout->grid[r*layout->cols+c]); + else + meta_verbose ("%3d ", layout->grid[r*layout->cols+c]); + ++c; + } + meta_verbose ("\n"); + meta_pop_no_msg_prefix (); + ++r; + } + } +#endif /* WITH_VERBOSE_MODE */ +} + +void +meta_workspace_manager_free_workspace_layout (MetaWorkspaceLayout *layout) +{ + g_free (layout->grid); +} + +static void +queue_windows_showing (MetaWorkspaceManager *workspace_manager) +{ + GSList *windows, *l; + + /* Must operate on all windows on display instead of just on the + * active_workspace's window list, because the active_workspace's + * window list may not contain the on_all_workspace windows. + */ + windows = meta_display_list_windows (workspace_manager->display, META_LIST_DEFAULT); + + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + + meta_window_queue (w, META_QUEUE_CALC_SHOWING); + } + + g_slist_free (windows); +} + +void +meta_workspace_manager_minimize_all_on_active_workspace_except (MetaWorkspaceManager *workspace_manager, + MetaWindow *keep) +{ + GList *l; + + for (l = workspace_manager->active_workspace->windows; l; l = l->next) + { + MetaWindow *w = l->data; + + if (w->has_minimize_func && w != keep) + meta_window_minimize (w); + } +} + +void +meta_workspace_manager_show_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp) +{ + GList *l; + + if (workspace_manager->active_workspace->showing_desktop) + return; + + workspace_manager->active_workspace->showing_desktop = TRUE; + + queue_windows_showing (workspace_manager); + + /* Focus the most recently used META_WINDOW_DESKTOP window, if there is one; + * see bug 159257. + */ + for (l = workspace_manager->active_workspace->mru_list; l; l = l->next) + { + MetaWindow *w = l->data; + + if (w->type == META_WINDOW_DESKTOP) + { + meta_window_focus (w, timestamp); + break; + } + } + + g_signal_emit (workspace_manager, + workspace_manager_signals[SHOWING_DESKTOP_CHANGED], + 0, NULL); +} + +void +meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager) +{ + if (!workspace_manager->active_workspace->showing_desktop) + return; + + workspace_manager->active_workspace->showing_desktop = FALSE; + + queue_windows_showing (workspace_manager); + + g_signal_emit (workspace_manager, + workspace_manager_signals[SHOWING_DESKTOP_CHANGED], + 0, NULL); +} + +/** + * meta_workspace_manager_get_workspaces: (skip) + * @workspace_manager: a #MetaWorkspaceManager + * + * Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @display + */ +GList * +meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager) +{ + return workspace_manager->workspaces; +} + +int +meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager) +{ + MetaWorkspace *active = workspace_manager->active_workspace; + + if (!active) + return -1; + + return meta_workspace_index (active); +} + +/** + * meta_workspace_manager_get_active_workspace: + * @workspace_manager: A #MetaWorkspaceManager + * + * Returns: (transfer none): The current workspace + */ +MetaWorkspace * +meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager) +{ + return workspace_manager->active_workspace; +} + +void +meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manager, + int from, + int to, + MetaMotionDirection direction) +{ + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACE_SWITCHED], 0, + from, to, direction); +} + +static void +prefs_changed_callback (MetaPreference pref, + gpointer data) +{ + MetaWorkspaceManager *workspace_manager = data; + + if ((pref == META_PREF_NUM_WORKSPACES || + pref == META_PREF_DYNAMIC_WORKSPACES) && + !meta_prefs_get_dynamic_workspaces ()) + { + guint32 timestamp; + int new_num; + + timestamp = + meta_display_get_current_time_roundtrip (workspace_manager->display); + new_num = meta_prefs_get_num_workspaces (); + meta_workspace_manager_update_num_workspaces (workspace_manager, + timestamp, new_num); + } +} diff --git a/src/core/stack.c b/src/core/stack.c index a7484c5d2..c00e86c76 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -27,6 +27,7 @@ #include #include "stack.h" +#include "meta-workspace-manager-private.h" #include "window-private.h" #include #include "frame.h" @@ -101,6 +102,8 @@ void meta_stack_add (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + g_return_if_fail (meta_window_is_stackable (window)); meta_topic (META_DEBUG_STACK, "Adding window %s to the stack\n", window->desc); @@ -117,13 +120,15 @@ meta_stack_add (MetaStack *stack, window->desc, window->stack_position); stack_sync_to_xserver (stack); - meta_stack_update_window_tile_matches (stack, window->display->active_workspace); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } void meta_stack_remove (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc); /* Set window to top position, so removing it will not leave gaps @@ -153,27 +158,29 @@ meta_stack_remove (MetaStack *stack, } stack_sync_to_xserver (stack); - meta_stack_update_window_tile_matches (stack, window->display->active_workspace); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } void meta_stack_update_layer (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; stack->need_relayer = TRUE; stack_sync_to_xserver (stack); - meta_stack_update_window_tile_matches (stack, window->display->active_workspace); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } void meta_stack_update_transient (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; stack->need_constrain = TRUE; stack_sync_to_xserver (stack); - meta_stack_update_window_tile_matches (stack, window->display->active_workspace); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } /* raise/lower within a layer */ @@ -181,6 +188,7 @@ void meta_stack_raise (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList *l; int max_stack_position = window->stack_position; MetaWorkspace *workspace; @@ -202,13 +210,14 @@ meta_stack_raise (MetaStack *stack, meta_window_set_stack_position_no_sync (window, max_stack_position); stack_sync_to_xserver (stack); - meta_stack_update_window_tile_matches (stack, window->display->active_workspace); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } void meta_stack_lower (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList *l; int min_stack_position = window->stack_position; MetaWorkspace *workspace; @@ -230,7 +239,7 @@ meta_stack_lower (MetaStack *stack, meta_window_set_stack_position_no_sync (window, min_stack_position); stack_sync_to_xserver (stack); - meta_stack_update_window_tile_matches (stack, window->display->active_workspace); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } void @@ -1457,8 +1466,10 @@ void meta_window_set_stack_position (MetaWindow *window, int position) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + meta_window_set_stack_position_no_sync (window, position); stack_sync_to_xserver (window->display->stack); meta_stack_update_window_tile_matches (window->display->stack, - window->display->active_workspace); + workspace_manager->active_workspace); } diff --git a/src/core/window.c b/src/core/window.c index 3335c9bdf..3322ffb0f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -33,6 +33,7 @@ #include "util-private.h" #include "frame.h" #include +#include "meta-workspace-manager-private.h" #include "workspace-private.h" #include "stack.h" #include "keybindings-private.h" @@ -687,9 +688,10 @@ is_desktop_or_dock_foreach (MetaWindow *window, static void maybe_leave_show_desktop_mode (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean is_desktop_or_dock; - if (!window->display->active_workspace->showing_desktop) + if (!workspace_manager->active_workspace->showing_desktop) return; /* If the window is a transient for the dock or desktop, don't @@ -706,9 +708,9 @@ maybe_leave_show_desktop_mode (MetaWindow *window) if (!is_desktop_or_dock) { - meta_display_minimize_all_on_active_workspace_except (window->display, - window); - meta_display_unshow_desktop (window->display); + meta_workspace_manager_minimize_all_on_active_workspace_except (workspace_manager, + window); + meta_workspace_manager_unshow_desktop (workspace_manager); } } @@ -929,6 +931,7 @@ _meta_window_shared_new (MetaDisplay *display, MetaCompEffect effect, XWindowAttributes *attrs) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; MetaWindow *window; g_assert (attrs != NULL); @@ -1238,8 +1241,8 @@ _meta_window_shared_new (MetaDisplay *display, "Window %s is initially on space %d\n", window->desc, window->initial_workspace); - workspace = meta_display_get_workspace_by_index (window->display, - window->initial_workspace); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, + window->initial_workspace); } set_workspace_state (window, on_all_workspaces, workspace); @@ -1278,7 +1281,7 @@ _meta_window_shared_new (MetaDisplay *display, "Putting window %s on active workspace\n", window->desc); - set_workspace_state (window, FALSE, window->display->active_workspace); + set_workspace_state (window, FALSE, workspace_manager->active_workspace); } meta_window_update_struts (window); @@ -1378,6 +1381,7 @@ void meta_window_unmanage (MetaWindow *window, guint32 timestamp) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList *tmp; meta_verbose ("Unmanaging %s\n", window->desc); @@ -1464,7 +1468,7 @@ meta_window_unmanage (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "Focusing default window since we're unmanaging %s\n", window->desc); - meta_workspace_focus_default_window (window->display->active_workspace, NULL, timestamp); + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, timestamp); } else { @@ -1510,7 +1514,7 @@ meta_window_unmanage (MetaWindow *window, g_assert (window->workspace == NULL); #ifndef G_DISABLE_CHECKS - tmp = window->display->workspaces; + tmp = workspace_manager->workspaces; while (tmp != NULL) { MetaWorkspace *workspace = tmp->data; @@ -1622,6 +1626,7 @@ ancestor_is_minimized (MetaWindow *window) gboolean meta_window_showing_on_its_workspace (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean showing; gboolean is_desktop_or_dock; MetaWorkspace* workspace_of_window; @@ -1641,7 +1646,7 @@ meta_window_showing_on_its_workspace (MetaWindow *window) &is_desktop_or_dock); if (window->on_all_workspaces) - workspace_of_window = window->display->active_workspace; + workspace_of_window = workspace_manager->active_workspace; else if (window->workspace) workspace_of_window = window->workspace; else /* This only seems to be needed for startup */ @@ -1673,6 +1678,8 @@ meta_window_showing_on_its_workspace (MetaWindow *window) gboolean meta_window_should_be_showing (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + #ifdef HAVE_WAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && !meta_wayland_surface_get_buffer (window->surface)) @@ -1681,7 +1688,7 @@ meta_window_should_be_showing (MetaWindow *window) /* Windows should be showing if they're located on the * active workspace and they're showing on their own workspace. */ - return (meta_window_located_on_workspace (window, window->display->active_workspace) && + return (meta_window_located_on_workspace (window, workspace_manager->active_workspace) && meta_window_showing_on_its_workspace (window)); } @@ -2551,6 +2558,7 @@ meta_window_show (MetaWindow *window) static void meta_window_hide (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean did_hide; meta_topic (META_DEBUG_WINDOW_STATE, @@ -2621,11 +2629,11 @@ meta_window_hide (MetaWindow *window) * We also pass in NULL if we are in the process of hiding all non-desktop * windows to avoid unexpected changes to the stacking order. */ - if (my_workspace == window->display->active_workspace && + if (my_workspace == workspace_manager->active_workspace && !my_workspace->showing_desktop) not_this_one = window; - meta_workspace_focus_default_window (window->display->active_workspace, + meta_workspace_focus_default_window (workspace_manager->active_workspace, not_this_one, timestamp); } @@ -3602,6 +3610,7 @@ meta_window_activate_full (MetaWindow *window, MetaClientType source_indication, MetaWorkspace *workspace) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean allow_workspace_switch; meta_topic (META_DEBUG_FOCUS, "_NET_ACTIVE_WINDOW message sent for %s at time %u " @@ -3630,7 +3639,7 @@ meta_window_activate_full (MetaWindow *window, /* Get window on current or given workspace */ if (workspace == NULL) - workspace = window->display->active_workspace; + workspace = workspace_manager->active_workspace; /* For non-transient windows, we just set up a pulsing indicator, rather than move windows or workspaces. @@ -3839,6 +3848,7 @@ void meta_window_update_monitor (MetaWindow *window, gboolean user_op) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; const MetaLogicalMonitor *old; old = window->monitor; @@ -3858,8 +3868,8 @@ meta_window_update_monitor (MetaWindow *window, */ if (meta_prefs_get_workspaces_only_on_primary () && user_op && meta_window_is_on_primary_monitor (window) && - window->display->active_workspace != window->workspace) - meta_window_change_workspace (window, window->display->active_workspace); + workspace_manager->active_workspace != window->workspace) + meta_window_change_workspace (window, workspace_manager->active_workspace); meta_window_main_monitor_changed (window, old); @@ -3894,6 +3904,7 @@ meta_window_move_resize_internal (MetaWindow *window, * to the client. */ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean did_placement; MetaRectangle unconstrained_rect; MetaRectangle constrained_rect; @@ -4025,7 +4036,7 @@ meta_window_move_resize_internal (MetaWindow *window, meta_window_foreach_transient (window, maybe_move_attached_dialog, NULL); meta_stack_update_window_tile_matches (window->display->stack, - window->display->active_workspace); + workspace_manager->active_workspace); } /** @@ -4605,6 +4616,7 @@ void meta_window_focus (MetaWindow *window, guint32 timestamp) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaWindow *modal_transient; g_return_if_fail (!window->override_redirect); @@ -4631,8 +4643,8 @@ meta_window_focus (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "%s has %s as a modal transient, so focusing it instead.\n", window->desc, modal_transient->desc); - if (!meta_window_located_on_workspace (modal_transient, window->display->active_workspace)) - meta_window_change_workspace (modal_transient, window->display->active_workspace); + if (!meta_window_located_on_workspace (modal_transient, workspace_manager->active_workspace)) + meta_window_change_workspace (modal_transient, workspace_manager->active_workspace); window = modal_transient; } @@ -4682,6 +4694,8 @@ set_workspace_state (MetaWindow *window, gboolean on_all_workspaces, MetaWorkspace *workspace) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + /* If we're on all workspaces, then our new workspace must be NULL. */ if (on_all_workspaces) g_assert (workspace == NULL); @@ -4703,7 +4717,7 @@ set_workspace_state (MetaWindow *window, else if (window->on_all_workspaces) { GList *l; - for (l = window->display->workspaces; l != NULL; l = l->next) + for (l = workspace_manager->workspaces; l != NULL; l = l->next) { MetaWorkspace *ws = l->data; meta_workspace_remove_window (ws, window); @@ -4718,7 +4732,7 @@ set_workspace_state (MetaWindow *window, else if (window->on_all_workspaces) { GList *l; - for (l = window->display->workspaces; l != NULL; l = l->next) + for (l = workspace_manager->workspaces; l != NULL; l = l->next) { MetaWorkspace *ws = l->data; meta_workspace_add_window (ws, window); @@ -4760,6 +4774,7 @@ should_be_on_all_workspaces (MetaWindow *window) void meta_window_on_all_workspaces_changed (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean on_all_workspaces = should_be_on_all_workspaces (window); if (window->on_all_workspaces == on_all_workspaces) @@ -4775,7 +4790,7 @@ meta_window_on_all_workspaces_changed (MetaWindow *window) { /* We're coming out of the sticky state. Put the window on * the currently active workspace. */ - workspace = window->display->active_workspace; + workspace = workspace_manager->active_workspace; } set_workspace_state (window, on_all_workspaces, workspace); @@ -4998,6 +5013,7 @@ meta_window_change_workspace_by_index (MetaWindow *window, gint space_index, gboolean append) { + MetaWorkspaceManager *workspace_manager; MetaWorkspace *workspace; MetaDisplay *display; @@ -5010,12 +5026,13 @@ meta_window_change_workspace_by_index (MetaWindow *window, } display = window->display; + workspace_manager = display->workspace_manager; workspace = - meta_display_get_workspace_by_index (display, space_index); + meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index); if (!workspace && append) - workspace = meta_display_append_new_workspace (display, FALSE, META_CURRENT_TIME); + workspace = meta_workspace_manager_append_new_workspace (workspace_manager, FALSE, META_CURRENT_TIME); if (workspace) meta_window_change_workspace (window, workspace); @@ -5115,6 +5132,8 @@ void meta_window_set_focused_internal (MetaWindow *window, gboolean focused) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + if (focused) { window->has_focus = TRUE; @@ -5129,22 +5148,22 @@ meta_window_set_focused_internal (MetaWindow *window, * list only if the window is actually on the active * workspace. */ - if (window->display->active_workspace && + if (workspace_manager->active_workspace && meta_window_located_on_workspace (window, - window->display->active_workspace)) + workspace_manager->active_workspace)) { GList* link; - link = g_list_find (window->display->active_workspace->mru_list, + link = g_list_find (workspace_manager->active_workspace->mru_list, window); g_assert (link); - window->display->active_workspace->mru_list = - g_list_remove_link (window->display->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_remove_link (workspace_manager->active_workspace->mru_list, link); g_list_free (link); - window->display->active_workspace->mru_list = - g_list_prepend (window->display->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_prepend (workspace_manager->active_workspace->mru_list, window); } @@ -5387,8 +5406,10 @@ idle_update_icon (gpointer data) GList* meta_window_get_workspaces (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + if (window->on_all_workspaces) - return window->display->workspaces; + return workspace_manager->workspaces; else if (window->workspace != NULL) return window->workspace->list_containing_self; else if (window->constructing) @@ -5745,6 +5766,7 @@ meta_window_show_menu_for_rect (MetaWindow *window, void meta_window_shove_titlebar_onscreen (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaRectangle frame_rect; GList *onscreen_region; int horiz_amount, vert_amount; @@ -5757,7 +5779,7 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) /* Get the basic info we need */ meta_window_get_frame_rect (window, &frame_rect); - onscreen_region = window->display->active_workspace->screen_region; + onscreen_region = workspace_manager->active_workspace->screen_region; /* Extend the region (just in case the window is too big to fit on the * screen), then shove the window on screen, then return the region to @@ -5785,6 +5807,7 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) gboolean meta_window_titlebar_is_onscreen (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaRectangle titlebar_rect, frame_rect; GList *onscreen_region; gboolean is_onscreen; @@ -5809,7 +5832,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window) * them overlaps with the titlebar sufficiently to consider it onscreen. */ is_onscreen = FALSE; - onscreen_region = window->display->active_workspace->screen_region; + onscreen_region = workspace_manager->active_workspace->screen_region; while (onscreen_region) { MetaRectangle *spanning_rect = onscreen_region->data; @@ -6882,11 +6905,12 @@ ensure_mru_position_after (MetaWindow *window, * map. */ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList* active_mru_list; GList* window_position; GList* after_this_one_position; - active_mru_list = window->display->active_workspace->mru_list; + active_mru_list = workspace_manager->active_workspace->mru_list; window_position = g_list_find (active_mru_list, window); after_this_one_position = g_list_find (active_mru_list, after_this_one); @@ -6899,12 +6923,12 @@ ensure_mru_position_after (MetaWindow *window, if (g_list_length (window_position) > g_list_length (after_this_one_position)) { - window->display->active_workspace->mru_list = - g_list_delete_link (window->display->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_delete_link (workspace_manager->active_workspace->mru_list, window_position); - window->display->active_workspace->mru_list = - g_list_insert_before (window->display->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_insert_before (workspace_manager->active_workspace->mru_list, after_this_one_position->next, window); } @@ -7052,12 +7076,13 @@ meta_window_get_stable_sequence (MetaWindow *window) void meta_window_set_demands_attention (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaRectangle candidate_rect, other_rect; GList *stack = window->display->stack->sorted; MetaWindow *other_window; gboolean obscured = FALSE; - MetaWorkspace *workspace = window->display->active_workspace; + MetaWorkspace *workspace = workspace_manager->active_workspace; if (window->wm_state_demands_attention) return; @@ -7243,8 +7268,10 @@ meta_window_get_window_type (MetaWindow *window) MetaWorkspace * meta_window_get_workspace (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + if (window->on_all_workspaces) - return window->display->active_workspace; + return workspace_manager->active_workspace; else return window->workspace; } diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h index f63be9550..35d0e705f 100644 --- a/src/core/workspace-private.h +++ b/src/core/workspace-private.h @@ -38,6 +38,7 @@ struct _MetaWorkspace { GObject parent_instance; MetaDisplay *display; + MetaWorkspaceManager *manager; GList *windows; @@ -72,7 +73,7 @@ struct _MetaWorkspaceClass GObjectClass parent_class; }; -MetaWorkspace* meta_workspace_new (MetaDisplay *display); +MetaWorkspace* meta_workspace_new (MetaWorkspaceManager *workspace_manager); void meta_workspace_remove (MetaWorkspace *workspace); void meta_workspace_add_window (MetaWorkspace *workspace, MetaWindow *window); diff --git a/src/core/workspace.c b/src/core/workspace.c index 6e25a44af..e9b693e0b 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -36,6 +36,7 @@ #include "backends/meta-logical-monitor.h" #include "x11/meta-x11-display-private.h" #include +#include "meta-workspace-manager-private.h" #include "workspace-private.h" #include "boxes-private.h" #include @@ -222,17 +223,20 @@ meta_workspace_init (MetaWorkspace *workspace) { } -MetaWorkspace* -meta_workspace_new (MetaDisplay *display) +MetaWorkspace * +meta_workspace_new (MetaWorkspaceManager *workspace_manager) { + MetaDisplay *display = workspace_manager->display; MetaWorkspace *workspace; GSList *windows, *l; workspace = g_object_new (META_TYPE_WORKSPACE, NULL); workspace->display = display; - workspace->display->workspaces = - g_list_append (workspace->display->workspaces, workspace); + workspace->manager = workspace_manager; + + workspace_manager->workspaces = + g_list_append (workspace_manager->workspaces, workspace); workspace->windows = NULL; workspace->mru_list = NULL; @@ -319,12 +323,14 @@ assert_workspace_empty (MetaWorkspace *workspace) void meta_workspace_remove (MetaWorkspace *workspace) { - g_return_if_fail (workspace != workspace->display->active_workspace); + MetaWorkspaceManager *manager = workspace->display->workspace_manager; + + g_return_if_fail (workspace != manager->active_workspace); assert_workspace_empty (workspace); - workspace->display->workspaces = - g_list_remove (workspace->display->workspaces, workspace); + manager->workspaces = + g_list_remove (manager->workspaces, workspace); meta_workspace_clear_logical_monitor_data (workspace); @@ -439,14 +445,14 @@ workspace_switch_sound(MetaWorkspace *from, int i, nw, x, y, fi, ti; const char *e; - nw = meta_display_get_n_workspaces(from->display); + nw = meta_workspace_manager_get_n_workspaces (from->manager); fi = meta_workspace_index(from); ti = meta_workspace_index(to); - meta_display_calc_workspace_layout(from->display, - nw, - fi, - &layout); + meta_workspace_manager_calc_workspace_layout (from->manager, + nw, + fi, + &layout); for (i = 0; i < nw; i++) if (layout.grid[i] == ti) @@ -489,7 +495,7 @@ workspace_switch_sound(MetaWorkspace *from, NULL); finish: - meta_display_free_workspace_layout (&layout); + meta_workspace_manager_free_workspace_layout (&layout); #endif /* HAVE_LIBCANBERRA */ } @@ -519,7 +525,6 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, { MetaWorkspace *old; MetaWindow *move_window; - MetaDisplay *display; MetaCompositor *comp; MetaWorkspaceLayout layout1, layout2; gint num_workspaces, current_space, new_space; @@ -528,22 +533,22 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, meta_verbose ("Activating workspace %d\n", meta_workspace_index (workspace)); - if (workspace->display->active_workspace == workspace) + if (workspace->manager->active_workspace == workspace) return; /* Free any cached pointers to the workspaces's edges from * a current resize or move operation */ meta_display_cleanup_edges (workspace->display); - if (workspace->display->active_workspace) - workspace_switch_sound (workspace->display->active_workspace, workspace); + if (workspace->manager->active_workspace) + workspace_switch_sound (workspace->manager->active_workspace, workspace); /* Note that old can be NULL; e.g. when starting up */ - old = workspace->display->active_workspace; + old = workspace->manager->active_workspace; - workspace->display->active_workspace = workspace; + workspace->manager->active_workspace = workspace; - g_signal_emit_by_name (workspace->display, "active-workspace-changed"); + g_signal_emit_by_name (workspace->manager, "active-workspace-changed"); if (old == NULL) return; @@ -553,7 +558,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, * _net_showing_desktop hint */ if (old->showing_desktop != workspace->showing_desktop) - g_signal_emit_by_name (workspace->display, "showing-desktop-changed"); + g_signal_emit_by_name (workspace->manager, "showing-desktop-changed"); move_window = NULL; if (meta_grab_op_is_moving (workspace->display->grab_op)) @@ -578,18 +583,17 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, /* * Notify the compositor that the active workspace is changing. */ - display = workspace->display; - comp = meta_display_get_compositor (display); + comp = meta_display_get_compositor (workspace->display); direction = 0; current_space = meta_workspace_index (old); new_space = meta_workspace_index (workspace); - num_workspaces = meta_display_get_n_workspaces (workspace->display); - meta_display_calc_workspace_layout (workspace->display, num_workspaces, - current_space, &layout1); + num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager); + meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, + current_space, &layout1); - meta_display_calc_workspace_layout (workspace->display, num_workspaces, - new_space, &layout2); + meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, + new_space, &layout2); if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) { @@ -626,8 +630,8 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, direction = META_MOTION_UP_LEFT; } - meta_display_free_workspace_layout (&layout1); - meta_display_free_workspace_layout (&layout2); + meta_workspace_manager_free_workspace_layout (&layout1); + meta_workspace_manager_free_workspace_layout (&layout2); meta_compositor_switch_workspace (comp, old, workspace, direction); @@ -650,7 +654,8 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, meta_workspace_focus_default_window (workspace, NULL, timestamp); } - meta_display_workspace_switched (display, current_space, new_space, direction); + meta_workspace_manager_workspace_switched (workspace->manager, current_space, + new_space, direction); } void @@ -665,7 +670,7 @@ meta_workspace_index (MetaWorkspace *workspace) { int ret; - ret = g_list_index (workspace->display->workspaces, workspace); + ret = g_list_index (workspace->manager->workspaces, workspace); if (ret < 0) meta_bug ("Workspace does not exist to index!\n"); @@ -738,7 +743,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *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->display->active_workspace) + if (workspace == workspace->manager->active_workspace) meta_display_cleanup_edges (workspace->display); meta_workspace_clear_logical_monitor_data (workspace); @@ -1204,9 +1209,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, gboolean ltr; current_space = meta_workspace_index (workspace); - num_workspaces = meta_display_get_n_workspaces (workspace->display); - meta_display_calc_workspace_layout (workspace->display, num_workspaces, - current_space, &layout); + num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager); + meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, + current_space, &layout); meta_verbose ("Getting neighbor of %d in direction %s\n", current_space, meta_motion_direction_to_string (direction)); @@ -1251,9 +1256,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, meta_verbose ("Neighbor workspace is %d at row %d col %d\n", i, layout.current_row, layout.current_col); - meta_display_free_workspace_layout (&layout); + meta_workspace_manager_free_workspace_layout (&layout); - return meta_display_get_workspace_by_index (workspace->display, i); + return meta_workspace_manager_get_workspace_by_index (workspace->manager, i); } const char* diff --git a/src/meta/display.h b/src/meta/display.h index 6d446a656..a165421b7 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -203,24 +203,6 @@ int meta_display_get_monitor_neighbor_index (MetaDisplay *display, int which_monitor, MetaDisplayDirection dir); -GList *meta_display_get_workspaces (MetaDisplay *display); - -int meta_display_get_n_workspaces (MetaDisplay *display); - -MetaWorkspace* meta_display_get_workspace_by_index (MetaDisplay *display, - int index); -void meta_display_remove_workspace (MetaDisplay *display, - MetaWorkspace *workspace, - guint32 timestamp); - -MetaWorkspace *meta_display_append_new_workspace (MetaDisplay *display, - gboolean activate, - guint32 timestamp); - -int meta_display_get_active_workspace_index (MetaDisplay *display); - -MetaWorkspace *meta_display_get_active_workspace (MetaDisplay *display); - void meta_display_focus_default_window (MetaDisplay *display, guint32 timestamp); @@ -239,12 +221,6 @@ typedef enum META_DISPLAY_BOTTOMRIGHT } MetaDisplayCorner; -void meta_display_override_workspace_layout (MetaDisplay *display, - MetaDisplayCorner starting_corner, - gboolean vertical_layout, - int n_rows, - int n_columns); - MetaWorkspaceManager *meta_display_get_workspace_manager (MetaDisplay *display); #endif diff --git a/src/meta/meta-workspace-manager.h b/src/meta/meta-workspace-manager.h index 29604f244..52b2f0e30 100644 --- a/src/meta/meta-workspace-manager.h +++ b/src/meta/meta-workspace-manager.h @@ -32,6 +32,28 @@ #define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ()) G_DECLARE_FINAL_TYPE (MetaWorkspaceManager, meta_workspace_manager, META, WORKSPACE_MANAGER, GObject) +GList *meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager); + int meta_workspace_manager_get_n_workspaces (MetaWorkspaceManager *workspace_manager); +MetaWorkspace* meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager, + int index); + +void meta_workspace_manager_remove_workspace (MetaWorkspaceManager *workspace_manager, + MetaWorkspace *workspace, + guint32 timestamp); + +MetaWorkspace *meta_workspace_manager_append_new_workspace (MetaWorkspaceManager *workspace_manager, + gboolean activate, + guint32 timestamp); + +int meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager); + +MetaWorkspace *meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager); + +void meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns); #endif /* META_WORKSPACE_MANAGER_H */ diff --git a/src/x11/events.c b/src/x11/events.c index 397df1b27..53e1aa191 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -32,6 +32,7 @@ #include "meta/meta-backend.h" #include "bell.h" #include "display-private.h" +#include "meta-workspace-manager-private.h" #include "window-private.h" #include "workspace-private.h" #include "backends/meta-cursor-tracker-private.h" @@ -844,6 +845,7 @@ handle_input_xevent (MetaX11Display *x11_display, Window modified; MetaWindow *window; MetaDisplay *display = x11_display->display; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; if (input_event == NULL) return FALSE; @@ -912,7 +914,7 @@ handle_input_xevent (MetaX11Display *x11_display, "Focus got set to None, probably due to " "brain-damage in the X protocol (see bug " "125492). Setting the default focus window.\n"); - meta_workspace_focus_default_window (display->active_workspace, + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, meta_x11_display_get_current_time_roundtrip (x11_display)); } @@ -924,7 +926,7 @@ handle_input_xevent (MetaX11Display *x11_display, "Focus got set to root window, probably due to " "gnome-session logout dialog usage (see bug " "153220). Setting the default focus window.\n"); - meta_workspace_focus_default_window (display->active_workspace, + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, meta_x11_display_get_current_time_roundtrip (x11_display)); } @@ -1197,6 +1199,7 @@ handle_other_xevent (MetaX11Display *x11_display, XEvent *event) { MetaDisplay *display = x11_display->display; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; Window modified; MetaWindow *window; MetaWindow *property_for_window; @@ -1398,12 +1401,12 @@ handle_other_xevent (MetaX11Display *x11_display, if (window->minimized) { meta_window_unminimize (window); - if (window->workspace != window->display->active_workspace) + if (window->workspace != workspace_manager->active_workspace) { meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", window->mapped, window->minimized); meta_window_change_workspace (window, - window->display->active_workspace); + workspace_manager->active_workspace); } } break; @@ -1552,7 +1555,7 @@ handle_other_xevent (MetaX11Display *x11_display, "specified timestamp of %u\n", space, time); - workspace = meta_display_get_workspace_by_index (display, space); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, space); /* Handle clients using the older version of the spec... */ if (time == 0 && workspace) @@ -1593,11 +1596,11 @@ handle_other_xevent (MetaX11Display *x11_display, showing_desktop ? "show" : "hide"); if (showing_desktop) - meta_display_show_desktop (display, timestamp); + meta_workspace_manager_show_desktop (workspace_manager, timestamp); else { - meta_display_unshow_desktop (display); - meta_workspace_focus_default_window (display->active_workspace, NULL, timestamp); + meta_workspace_manager_unshow_desktop (workspace_manager); + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, timestamp); } } else if (event->xclient.message_type == diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 9c48ae312..76433a4b5 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -55,6 +55,7 @@ #include "backends/meta-logical-monitor.h" #include "backends/x11/meta-backend-x11.h" #include "core/frame.h" +#include "core/meta-workspace-manager-private.h" #include "core/util-private.h" #include "core/workspace-private.h" #include "meta/main.h" @@ -793,8 +794,8 @@ init_event_masks (MetaX11Display *x11_display) } static void -set_active_workspace_hint (MetaDisplay *display, - MetaX11Display *x11_display) +set_active_workspace_hint (MetaWorkspaceManager *workspace_manager, + MetaX11Display *x11_display) { unsigned long data[1]; @@ -804,10 +805,10 @@ set_active_workspace_hint (MetaDisplay *display, * on restart. By doing this we keep the current * desktop on restart. */ - if (display->closing > 0) + if (x11_display->display->closing > 0) return; - data[0] = meta_workspace_index (display->active_workspace); + data[0] = meta_workspace_index (workspace_manager->active_workspace); meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]); @@ -821,17 +822,17 @@ set_active_workspace_hint (MetaDisplay *display, } static void -set_number_of_spaces_hint (MetaDisplay *display, - GParamSpec *pspec, - gpointer user_data) +set_number_of_spaces_hint (MetaWorkspaceManager *workspace_manager, + GParamSpec *pspec, + gpointer user_data) { MetaX11Display *x11_display = user_data; unsigned long data[1]; - if (display->closing > 0) + if (x11_display->display->closing > 0) return; - data[0] = meta_display_get_n_workspaces (display); + data[0] = meta_workspace_manager_get_n_workspaces (workspace_manager); meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]); @@ -845,12 +846,12 @@ set_number_of_spaces_hint (MetaDisplay *display, } static void -set_showing_desktop_hint (MetaDisplay *display, - MetaX11Display *x11_display) +set_showing_desktop_hint (MetaWorkspaceManager *workspace_manager, + MetaX11Display *x11_display) { unsigned long data[1]; - data[0] = display->active_workspace->showing_desktop ? 1 : 0; + data[0] = workspace_manager->active_workspace->showing_desktop ? 1 : 0; meta_x11_error_trap_push (x11_display); XChangeProperty (x11_display->xdisplay, @@ -864,12 +865,15 @@ set_showing_desktop_hint (MetaDisplay *display, static void set_workspace_names (MetaX11Display *x11_display) { + MetaWorkspaceManager *workspace_manager; GString *flattened; int i; int n_spaces; + workspace_manager = x11_display->display->workspace_manager; + /* flatten to nul-separated list */ - n_spaces = meta_display_get_n_workspaces (x11_display->display); + n_spaces = meta_workspace_manager_get_n_workspaces (workspace_manager); flattened = g_string_new (""); i = 0; while (i < n_spaces) @@ -903,16 +907,17 @@ static void set_work_area_hint (MetaDisplay *display, MetaX11Display *x11_display) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; int num_workspaces; GList *l; unsigned long *data, *tmp; MetaRectangle area; - num_workspaces = meta_display_get_n_workspaces (display); + num_workspaces = meta_workspace_manager_get_n_workspaces (workspace_manager); data = g_new (unsigned long, num_workspaces * 4); tmp = data; - for (l = display->workspaces; l; l = l->next) + for (l = workspace_manager->workspaces; l; l = l->next) { MetaWorkspace *workspace = l->data; @@ -1252,8 +1257,8 @@ meta_x11_display_new (MetaDisplay *display, GError **error) (int) current_workspace_index); /* Switch to the _NET_CURRENT_DESKTOP workspace */ - current_workspace = meta_display_get_workspace_by_index (display, - current_workspace_index); + current_workspace = meta_workspace_manager_get_workspace_by_index (display->workspace_manager, + current_workspace_index); if (current_workspace != NULL) meta_workspace_activate (current_workspace, timestamp); @@ -1278,25 +1283,25 @@ meta_x11_display_new (MetaDisplay *display, GError **error) meta_XFree (list); } - if (num > meta_display_get_n_workspaces (display)) - meta_display_update_num_workspaces (display, timestamp, num); + if (num > meta_workspace_manager_get_n_workspaces (display->workspace_manager)) + meta_workspace_manager_update_num_workspaces (display->workspace_manager, timestamp, num); } - set_active_workspace_hint (display, x11_display); + set_active_workspace_hint (display->workspace_manager, x11_display); - g_signal_connect_object (display, "active-workspace-changed", + g_signal_connect_object (display->workspace_manager, "active-workspace-changed", G_CALLBACK (set_active_workspace_hint), x11_display, 0); - set_number_of_spaces_hint (display, NULL, x11_display); + set_number_of_spaces_hint (display->workspace_manager, NULL, x11_display); - g_signal_connect_object (display, "notify::n-workspaces", + g_signal_connect_object (display->workspace_manager, "notify::n-workspaces", G_CALLBACK (set_number_of_spaces_hint), x11_display, 0); - set_showing_desktop_hint (display, x11_display); + set_showing_desktop_hint (display->workspace_manager, x11_display); - g_signal_connect_object (display, "showing-desktop-changed", + g_signal_connect_object (display->workspace_manager, "showing-desktop-changed", G_CALLBACK (set_showing_desktop_hint), x11_display, 0); @@ -2013,6 +2018,7 @@ meta_x11_display_update_workspace_names (MetaX11Display *x11_display) void meta_x11_display_update_workspace_layout (MetaX11Display *x11_display) { + MetaWorkspaceManager *workspace_manager = x11_display->display->workspace_manager; gboolean vertical_layout = FALSE; int n_rows = -1; int n_columns = 1; @@ -2020,7 +2026,7 @@ meta_x11_display_update_workspace_layout (MetaX11Display *x11_display) uint32_t *list; int n_items; - if (x11_display->display->workspace_layout_overridden) + if (workspace_manager->workspace_layout_overridden) return; list = NULL; @@ -2098,11 +2104,11 @@ meta_x11_display_update_workspace_layout (MetaX11Display *x11_display) meta_XFree (list); - meta_display_update_workspace_layout (x11_display->display, - starting_corner, - vertical_layout, - n_rows, - n_columns); + meta_workspace_manager_update_workspace_layout (workspace_manager, + starting_corner, + vertical_layout, + n_rows, + n_columns); } } diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 946568cb2..d06a89a21 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -49,6 +49,7 @@ #include #include #include "util-private.h" +#include "meta-workspace-manager-private.h" #ifndef HOST_NAME_MAX /* Solaris headers apparently don't define this so do so manually; #326745 */ @@ -1027,6 +1028,7 @@ reload_net_startup_id (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; guint32 timestamp = window->net_wm_user_time; MetaWorkspace *workspace = NULL; @@ -1049,7 +1051,8 @@ reload_net_startup_id (MetaWindow *window, if (window->initial_timestamp_set) timestamp = window->initial_timestamp; if (window->initial_workspace_set) - workspace = meta_display_get_workspace_by_index (window->display, window->initial_workspace); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, + window->initial_workspace); meta_window_activate_with_workspace (window, timestamp, workspace); } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 267fc3427..2418e6262 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -50,6 +50,7 @@ #include "xprops.h" #include "session.h" #include "workspace-private.h" +#include "meta-workspace-manager-private.h" #include "backends/meta-logical-monitor.h" #include "backends/x11/meta-backend-x11.h" @@ -442,11 +443,12 @@ meta_window_apply_session_info (MetaWindow *window, tmp = info->workspace_indices; while (tmp != NULL) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaWorkspace *space; space = - meta_display_get_workspace_by_index (window->display, - GPOINTER_TO_INT (tmp->data)); + meta_workspace_manager_get_workspace_by_index (workspace_manager, + GPOINTER_TO_INT (tmp->data)); if (space) spaces = g_slist_prepend (spaces, space); @@ -2403,6 +2405,7 @@ meta_window_x11_client_message (MetaWindow *window, x11_display->atom__NET_WM_DESKTOP) { int space; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaWorkspace *workspace; space = event->xclient.data.l[0]; @@ -2411,8 +2414,8 @@ meta_window_x11_client_message (MetaWindow *window, window->desc, space); workspace = - meta_display_get_workspace_by_index (window->display, - space); + meta_workspace_manager_get_workspace_by_index (workspace_manager, + space); if (workspace) meta_window_change_workspace (window, workspace);