Move workspace related code from MetaDisplay to MetaWorkspaceManager

https://bugzilla.gnome.org/show_bug.cgi?id=759538
This commit is contained in:
Armin Krezović 2017-08-27 21:02:40 +02:00 committed by Jonas Ådahl
parent e05cd6009a
commit 81c1c70c0a
18 changed files with 1093 additions and 996 deletions

View File

@ -24,6 +24,7 @@
#include <config.h> #include <config.h>
#include "boxes-private.h" #include "boxes-private.h"
#include "constraints.h" #include "constraints.h"
#include "meta-workspace-manager-private.h"
#include "workspace-private.h" #include "workspace-private.h"
#include "place.h" #include "place.h"
#include <meta/prefs.h> #include <meta/prefs.h>
@ -412,7 +413,7 @@ setup_constraint_info (ConstraintInfo *info,
&info->entire_monitor); &info->entire_monitor);
} }
cur_workspace = window->display->active_workspace; cur_workspace = window->display->workspace_manager->active_workspace;
info->usable_screen_region = info->usable_screen_region =
meta_workspace_get_onscreen_region (cur_workspace); meta_workspace_get_onscreen_region (cur_workspace);
info->usable_monitor_region = info->usable_monitor_region =
@ -499,7 +500,7 @@ place_window_if_needed(MetaWindow *window,
meta_window_get_work_area_for_logical_monitor (window, meta_window_get_work_area_for_logical_monitor (window,
logical_monitor, logical_monitor,
&info->work_area_monitor); &info->work_area_monitor);
cur_workspace = window->display->active_workspace; cur_workspace = window->display->workspace_manager->active_workspace;
info->usable_monitor_region = info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor); meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
@ -926,6 +927,7 @@ constrain_maximization (MetaWindow *window,
ConstraintPriority priority, ConstraintPriority priority,
gboolean check_only) gboolean check_only)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaRectangle target_size; MetaRectangle target_size;
MetaRectangle min_size, max_size; MetaRectangle min_size, max_size;
gboolean hminbad, vminbad; gboolean hminbad, vminbad;
@ -965,7 +967,7 @@ constrain_maximization (MetaWindow *window,
direction = META_DIRECTION_HORIZONTAL; direction = META_DIRECTION_HORIZONTAL;
else else
direction = META_DIRECTION_VERTICAL; 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; target_size = info->current;
meta_rectangle_expand_to_avoiding_struts (&target_size, meta_rectangle_expand_to_avoiding_struts (&target_size,

View File

@ -24,6 +24,7 @@
#include <config.h> #include <config.h>
#include "core.h" #include "core.h"
#include "frame.h" #include "frame.h"
#include "meta-workspace-manager-private.h"
#include "workspace-private.h" #include "workspace-private.h"
#include <meta/prefs.h> #include <meta/prefs.h>
#include <meta/meta-x11-errors.h> #include <meta/meta-x11-errors.h>
@ -77,6 +78,8 @@ static gboolean
lower_window_and_transients (MetaWindow *window, lower_window_and_transients (MetaWindow *window,
gpointer data) gpointer data)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
meta_window_lower (window); meta_window_lower (window);
meta_window_foreach_transient (window, lower_window_and_transients, NULL); 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. * Do extra sanity checks to avoid possible race conditions.
* (Borrowed from window.c.) * (Borrowed from window.c.)
*/ */
if (window->display->active_workspace && if (workspace_manager->active_workspace &&
meta_window_located_on_workspace (window, meta_window_located_on_workspace (window,
window->display->active_workspace)) workspace_manager->active_workspace))
{ {
GList* link; GList* link;
link = g_list_find (window->display->active_workspace->mru_list, link = g_list_find (workspace_manager->active_workspace->mru_list,
window); window);
g_assert (link); g_assert (link);
window->display->active_workspace->mru_list = workspace_manager->active_workspace->mru_list =
g_list_remove_link (window->display->active_workspace->mru_list, g_list_remove_link (workspace_manager->active_workspace->mru_list,
link); link);
g_list_free (link); g_list_free (link);
window->display->active_workspace->mru_list = workspace_manager->active_workspace->mru_list =
g_list_append (window->display->active_workspace->mru_list, g_list_append (workspace_manager->active_workspace->mru_list,
window); window);
} }
} }
@ -116,6 +119,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
guint32 timestamp) guint32 timestamp)
{ {
MetaWindow *window = get_window (xdisplay, frame_xwindow); MetaWindow *window = get_window (xdisplay, frame_xwindow);
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
lower_window_and_transients (window, NULL); 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, * the focus window, assume that's always the case. (Typically,
* this will be invoked via keyboard action or by a mouse action; * 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.) */ * 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, NULL,
timestamp); timestamp);
} }

View File

@ -242,16 +242,6 @@ struct _MetaDisplay
guint work_area_later; guint work_area_later;
guint check_fullscreen_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; MetaBell *bell;
MetaWorkspaceManager *workspace_manager; MetaWorkspaceManager *workspace_manager;
}; };
@ -442,46 +432,4 @@ void meta_display_queue_check_fullscreen (MetaDisplay *display);
MetaWindow *meta_display_get_pointer_window (MetaDisplay *display, MetaWindow *meta_display_get_pointer_window (MetaDisplay *display,
MetaWindow *not_this_one); 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 #endif

View File

@ -154,8 +154,7 @@ enum
enum { enum {
PROP_0, PROP_0,
PROP_FOCUS_WINDOW, PROP_FOCUS_WINDOW
PROP_N_WORKSPACES
}; };
static guint display_signals [LAST_SIGNAL] = { 0 }; static guint display_signals [LAST_SIGNAL] = { 0 };
@ -190,9 +189,6 @@ meta_display_get_property(GObject *object,
case PROP_FOCUS_WINDOW: case PROP_FOCUS_WINDOW:
g_value_set_object (value, display->focus_window); g_value_set_object (value, display->focus_window);
break; break;
case PROP_N_WORKSPACES:
g_value_set_int (value, meta_display_get_n_workspaces (display));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -536,14 +532,6 @@ meta_display_class_init (MetaDisplayClass *klass)
META_TYPE_WINDOW, META_TYPE_WINDOW,
G_PARAM_READABLE)); 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); 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: * meta_display_open:
* *
@ -762,13 +738,6 @@ meta_display_open (void)
display->grab_tile_mode = META_TILE_NONE; display->grab_tile_mode = META_TILE_NONE;
display->grab_tile_monitor_number = -1; 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; display->grab_edge_resistance_data = NULL;
meta_display_init_keys (display); meta_display_init_keys (display);
@ -793,25 +762,6 @@ meta_display_open (void)
display->workspace_manager = meta_workspace_manager_new (display); 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); display->startup_notification = meta_startup_notification_get (display);
g_signal_connect (display->startup_notification, "changed", g_signal_connect (display->startup_notification, "changed",
G_CALLBACK (on_startup_notification_changed), display); G_CALLBACK (on_startup_notification_changed), display);
@ -2564,18 +2514,6 @@ prefs_changed_callback (MetaPreference pref,
{ {
meta_display_reload_cursor (display); 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 void
@ -3082,7 +3020,7 @@ on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
MetaBackend *backend; MetaBackend *backend;
MetaCursorRenderer *cursor_renderer; 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 */ /* Fix up monitor for all windows on this display */
meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT, meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT,
@ -3665,6 +3603,7 @@ MetaWindow *
meta_display_get_pointer_window (MetaDisplay *display, meta_display_get_pointer_window (MetaDisplay *display,
MetaWindow *not_this_one) MetaWindow *not_this_one)
{ {
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
MetaBackend *backend = meta_get_backend (); MetaBackend *backend = meta_get_backend ();
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
MetaWindow *window; MetaWindow *window;
@ -3677,718 +3616,24 @@ meta_display_get_pointer_window (MetaDisplay *display,
meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL);
window = meta_stack_get_default_focus_window_at_point (display->stack, window = meta_stack_get_default_focus_window_at_point (display->stack,
display->active_workspace, workspace_manager->active_workspace,
not_this_one, not_this_one,
x, y); x, y);
return window; 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 void
meta_display_focus_default_window (MetaDisplay *display, meta_display_focus_default_window (MetaDisplay *display,
guint32 timestamp) 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, NULL,
timestamp); 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 * MetaWorkspaceManager *
meta_display_get_workspace_manager (MetaDisplay *display) meta_display_get_workspace_manager (MetaDisplay *display)
{ {

View File

@ -23,6 +23,7 @@
#include "edge-resistance.h" #include "edge-resistance.h"
#include "boxes-private.h" #include "boxes-private.h"
#include "display-private.h" #include "display-private.h"
#include "meta-workspace-manager-private.h"
#include "workspace-private.h" #include "workspace-private.h"
/* A simple macro for whether a given window's edges are potentially /* 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 * in the layer that we are working on
*/ */
GSList *rem_windows, *rem_win_stacking; GSList *rem_windows, *rem_win_stacking;
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
g_assert (display->grab_window != NULL); g_assert (display->grab_window != NULL);
meta_topic (META_DEBUG_WINDOW_OPS, meta_topic (META_DEBUG_WINDOW_OPS,
@ -1010,7 +1012,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
*/ */
stacked_windows = stacked_windows =
meta_stack_list_windows (display->stack, 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 * 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, cache_edges (display,
edges, edges,
display->active_workspace->monitor_edges, workspace_manager->active_workspace->monitor_edges,
display->active_workspace->screen_edges); workspace_manager->active_workspace->screen_edges);
g_list_free (edges); g_list_free (edges);
/* /*

View File

@ -29,6 +29,7 @@
#include <config.h> #include <config.h>
#include "keybindings-private.h" #include "keybindings-private.h"
#include "meta-workspace-manager-private.h"
#include "workspace-private.h" #include "workspace-private.h"
#include <meta/compositor.h> #include <meta/compositor.h>
#include <meta/meta-x11-errors.h> #include <meta/meta-x11-errors.h>
@ -2733,8 +2734,9 @@ handle_switch_to_last_workspace (MetaDisplay *display,
MetaKeyBinding *binding, MetaKeyBinding *binding,
gpointer dummy) gpointer dummy)
{ {
gint target = meta_display_get_n_workspaces(display) - 1; MetaWorkspaceManager *workspace_manager = display->workspace_manager;
MetaWorkspace *workspace = meta_display_get_workspace_by_index (display, target); 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); meta_workspace_activate (workspace, event->time);
} }
@ -2746,6 +2748,7 @@ handle_switch_to_workspace (MetaDisplay *display,
gpointer dummy) gpointer dummy)
{ {
gint which = binding->handler->data; gint which = binding->handler->data;
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
MetaWorkspace *workspace; MetaWorkspace *workspace;
if (which < 0) if (which < 0)
@ -2754,12 +2757,12 @@ handle_switch_to_workspace (MetaDisplay *display,
* current workspace. * current workspace.
*/ */
workspace = meta_workspace_get_neighbor (display->active_workspace, workspace = meta_workspace_get_neighbor (workspace_manager->active_workspace,
which); which);
} }
else else
{ {
workspace = meta_display_get_workspace_by_index (display, which); workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which);
} }
if (workspace) if (workspace)
@ -2982,15 +2985,17 @@ handle_show_desktop (MetaDisplay *display,
MetaKeyBinding *binding, MetaKeyBinding *binding,
gpointer dummy) 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_manager_unshow_desktop (workspace_manager);
meta_workspace_focus_default_window (display->active_workspace, meta_workspace_focus_default_window (workspace_manager->active_workspace,
NULL, NULL,
event->time); event->time);
} }
else else
meta_display_show_desktop (display, event->time); meta_workspace_manager_show_desktop (workspace_manager, event->time);
} }
static void static void
@ -3077,6 +3082,7 @@ do_choose_window (MetaDisplay *display,
MetaKeyBinding *binding, MetaKeyBinding *binding,
gboolean backward) gboolean backward)
{ {
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
MetaTabList type = binding->handler->data; MetaTabList type = binding->handler->data;
MetaWindow *window; MetaWindow *window;
@ -3085,7 +3091,7 @@ do_choose_window (MetaDisplay *display,
window = meta_display_get_tab_next (display, window = meta_display_get_tab_next (display,
type, type,
display->active_workspace, workspace_manager->active_workspace,
NULL, NULL,
backward); backward);
@ -3299,14 +3305,15 @@ handle_move_to_workspace_last (MetaDisplay *display,
MetaKeyBinding *binding, MetaKeyBinding *binding,
gpointer dummy) gpointer dummy)
{ {
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
gint which; gint which;
MetaWorkspace *workspace; MetaWorkspace *workspace;
if (window->always_sticky) if (window->always_sticky)
return; return;
which = meta_display_get_n_workspaces (display) - 1; which = meta_workspace_manager_get_n_workspaces (workspace_manager) - 1;
workspace = meta_display_get_workspace_by_index (display, which); workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which);
meta_window_change_workspace (window, workspace); meta_window_change_workspace (window, workspace);
} }
@ -3318,6 +3325,7 @@ handle_move_to_workspace (MetaDisplay *display,
MetaKeyBinding *binding, MetaKeyBinding *binding,
gpointer dummy) gpointer dummy)
{ {
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
gint which = binding->handler->data; gint which = binding->handler->data;
gboolean flip = (which < 0); gboolean flip = (which < 0);
MetaWorkspace *workspace; MetaWorkspace *workspace;
@ -3336,12 +3344,12 @@ handle_move_to_workspace (MetaDisplay *display,
workspace = NULL; workspace = NULL;
if (flip) if (flip)
{ {
workspace = meta_workspace_get_neighbor (display->active_workspace, workspace = meta_workspace_get_neighbor (workspace_manager->active_workspace,
which); which);
} }
else else
{ {
workspace = meta_display_get_workspace_by_index (display, which); workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which);
} }
if (workspace) if (workspace)

View File

@ -48,4 +48,49 @@ struct _MetaWorkspaceManager
MetaWorkspaceManager *meta_workspace_manager_new (MetaDisplay *display); 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 */ #endif /* META_WORKSPACE_MANAGER_PRIVATE_H */

View File

@ -28,7 +28,12 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "core/window-private.h"
#include "core/workspace-private.h"
#include "meta/meta-enum-types.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) G_DEFINE_TYPE (MetaWorkspaceManager, meta_workspace_manager, G_TYPE_OBJECT)
@ -50,6 +55,9 @@ enum {
static guint workspace_manager_signals [LAST_SIGNAL] = { 0 }; static guint workspace_manager_signals [LAST_SIGNAL] = { 0 };
static void prefs_changed_callback (MetaPreference pref,
gpointer data);
static void static void
meta_workspace_manager_get_property (GObject *object, meta_workspace_manager_get_property (GObject *object,
guint prop_id, 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 static void
meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass) 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->get_property = meta_workspace_manager_get_property;
object_class->set_property = meta_workspace_manager_set_property; object_class->set_property = meta_workspace_manager_set_property;
object_class->finalize = meta_workspace_manager_finalize;
workspace_manager_signals[WORKSPACE_ADDED] = workspace_manager_signals[WORKSPACE_ADDED] =
g_signal_new ("workspace-added", g_signal_new ("workspace-added",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
@ -133,6 +153,14 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass)
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL, 0, NULL, NULL, NULL,
G_TYPE_NONE, 0); 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 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 * MetaWorkspaceManager *
meta_workspace_manager_new (MetaDisplay *display) meta_workspace_manager_new (MetaDisplay *display)
{ {
@ -155,11 +196,756 @@ meta_workspace_manager_new (MetaDisplay *display)
workspace_manager->vertical_workspaces = FALSE; workspace_manager->vertical_workspaces = FALSE;
workspace_manager->starting_corner = META_DISPLAY_TOPLEFT; 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; 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 int
meta_workspace_manager_get_n_workspaces (MetaWorkspaceManager *workspace_manager) meta_workspace_manager_get_n_workspaces (MetaWorkspaceManager *workspace_manager)
{ {
return g_list_length (workspace_manager->workspaces); 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);
}
}

View File

@ -27,6 +27,7 @@
#include <config.h> #include <config.h>
#include "stack.h" #include "stack.h"
#include "meta-workspace-manager-private.h"
#include "window-private.h" #include "window-private.h"
#include <meta/meta-x11-errors.h> #include <meta/meta-x11-errors.h>
#include "frame.h" #include "frame.h"
@ -101,6 +102,8 @@ void
meta_stack_add (MetaStack *stack, meta_stack_add (MetaStack *stack,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
g_return_if_fail (meta_window_is_stackable (window)); g_return_if_fail (meta_window_is_stackable (window));
meta_topic (META_DEBUG_STACK, "Adding window %s to the stack\n", window->desc); 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); window->desc, window->stack_position);
stack_sync_to_xserver (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 void
meta_stack_remove (MetaStack *stack, meta_stack_remove (MetaStack *stack,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc); 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 /* 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); 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 void
meta_stack_update_layer (MetaStack *stack, meta_stack_update_layer (MetaStack *stack,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
stack->need_relayer = TRUE; stack->need_relayer = TRUE;
stack_sync_to_xserver (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 void
meta_stack_update_transient (MetaStack *stack, meta_stack_update_transient (MetaStack *stack,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
stack->need_constrain = TRUE; stack->need_constrain = TRUE;
stack_sync_to_xserver (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);
} }
/* raise/lower within a layer */ /* raise/lower within a layer */
@ -181,6 +188,7 @@ void
meta_stack_raise (MetaStack *stack, meta_stack_raise (MetaStack *stack,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
GList *l; GList *l;
int max_stack_position = window->stack_position; int max_stack_position = window->stack_position;
MetaWorkspace *workspace; MetaWorkspace *workspace;
@ -202,13 +210,14 @@ meta_stack_raise (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, max_stack_position); meta_window_set_stack_position_no_sync (window, max_stack_position);
stack_sync_to_xserver (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 void
meta_stack_lower (MetaStack *stack, meta_stack_lower (MetaStack *stack,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
GList *l; GList *l;
int min_stack_position = window->stack_position; int min_stack_position = window->stack_position;
MetaWorkspace *workspace; MetaWorkspace *workspace;
@ -230,7 +239,7 @@ meta_stack_lower (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, min_stack_position); meta_window_set_stack_position_no_sync (window, min_stack_position);
stack_sync_to_xserver (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 void
@ -1457,8 +1466,10 @@ void
meta_window_set_stack_position (MetaWindow *window, meta_window_set_stack_position (MetaWindow *window,
int position) int position)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
meta_window_set_stack_position_no_sync (window, position); meta_window_set_stack_position_no_sync (window, position);
stack_sync_to_xserver (window->display->stack); stack_sync_to_xserver (window->display->stack);
meta_stack_update_window_tile_matches (window->display->stack, meta_stack_update_window_tile_matches (window->display->stack,
window->display->active_workspace); workspace_manager->active_workspace);
} }

View File

@ -33,6 +33,7 @@
#include "util-private.h" #include "util-private.h"
#include "frame.h" #include "frame.h"
#include <meta/meta-x11-errors.h> #include <meta/meta-x11-errors.h>
#include "meta-workspace-manager-private.h"
#include "workspace-private.h" #include "workspace-private.h"
#include "stack.h" #include "stack.h"
#include "keybindings-private.h" #include "keybindings-private.h"
@ -687,9 +688,10 @@ is_desktop_or_dock_foreach (MetaWindow *window,
static void static void
maybe_leave_show_desktop_mode (MetaWindow *window) maybe_leave_show_desktop_mode (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean is_desktop_or_dock; gboolean is_desktop_or_dock;
if (!window->display->active_workspace->showing_desktop) if (!workspace_manager->active_workspace->showing_desktop)
return; return;
/* If the window is a transient for the dock or desktop, don't /* 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) if (!is_desktop_or_dock)
{ {
meta_display_minimize_all_on_active_workspace_except (window->display, meta_workspace_manager_minimize_all_on_active_workspace_except (workspace_manager,
window); window);
meta_display_unshow_desktop (window->display); meta_workspace_manager_unshow_desktop (workspace_manager);
} }
} }
@ -929,6 +931,7 @@ _meta_window_shared_new (MetaDisplay *display,
MetaCompEffect effect, MetaCompEffect effect,
XWindowAttributes *attrs) XWindowAttributes *attrs)
{ {
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
MetaWindow *window; MetaWindow *window;
g_assert (attrs != NULL); g_assert (attrs != NULL);
@ -1238,7 +1241,7 @@ _meta_window_shared_new (MetaDisplay *display,
"Window %s is initially on space %d\n", "Window %s is initially on space %d\n",
window->desc, window->initial_workspace); window->desc, window->initial_workspace);
workspace = meta_display_get_workspace_by_index (window->display, workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager,
window->initial_workspace); window->initial_workspace);
} }
@ -1278,7 +1281,7 @@ _meta_window_shared_new (MetaDisplay *display,
"Putting window %s on active workspace\n", "Putting window %s on active workspace\n",
window->desc); 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); meta_window_update_struts (window);
@ -1378,6 +1381,7 @@ void
meta_window_unmanage (MetaWindow *window, meta_window_unmanage (MetaWindow *window,
guint32 timestamp) guint32 timestamp)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
GList *tmp; GList *tmp;
meta_verbose ("Unmanaging %s\n", window->desc); meta_verbose ("Unmanaging %s\n", window->desc);
@ -1464,7 +1468,7 @@ meta_window_unmanage (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"Focusing default window since we're unmanaging %s\n", "Focusing default window since we're unmanaging %s\n",
window->desc); 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 else
{ {
@ -1510,7 +1514,7 @@ meta_window_unmanage (MetaWindow *window,
g_assert (window->workspace == NULL); g_assert (window->workspace == NULL);
#ifndef G_DISABLE_CHECKS #ifndef G_DISABLE_CHECKS
tmp = window->display->workspaces; tmp = workspace_manager->workspaces;
while (tmp != NULL) while (tmp != NULL)
{ {
MetaWorkspace *workspace = tmp->data; MetaWorkspace *workspace = tmp->data;
@ -1622,6 +1626,7 @@ ancestor_is_minimized (MetaWindow *window)
gboolean gboolean
meta_window_showing_on_its_workspace (MetaWindow *window) meta_window_showing_on_its_workspace (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean showing; gboolean showing;
gboolean is_desktop_or_dock; gboolean is_desktop_or_dock;
MetaWorkspace* workspace_of_window; MetaWorkspace* workspace_of_window;
@ -1641,7 +1646,7 @@ meta_window_showing_on_its_workspace (MetaWindow *window)
&is_desktop_or_dock); &is_desktop_or_dock);
if (window->on_all_workspaces) if (window->on_all_workspaces)
workspace_of_window = window->display->active_workspace; workspace_of_window = workspace_manager->active_workspace;
else if (window->workspace) else if (window->workspace)
workspace_of_window = window->workspace; workspace_of_window = window->workspace;
else /* This only seems to be needed for startup */ else /* This only seems to be needed for startup */
@ -1673,6 +1678,8 @@ meta_window_showing_on_its_workspace (MetaWindow *window)
gboolean gboolean
meta_window_should_be_showing (MetaWindow *window) meta_window_should_be_showing (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
!meta_wayland_surface_get_buffer (window->surface)) !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 /* Windows should be showing if they're located on the
* active workspace and they're showing on their own workspace. */ * 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)); meta_window_showing_on_its_workspace (window));
} }
@ -2551,6 +2558,7 @@ meta_window_show (MetaWindow *window)
static void static void
meta_window_hide (MetaWindow *window) meta_window_hide (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean did_hide; gboolean did_hide;
meta_topic (META_DEBUG_WINDOW_STATE, 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 * 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. * 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) !my_workspace->showing_desktop)
not_this_one = window; 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, not_this_one,
timestamp); timestamp);
} }
@ -3602,6 +3610,7 @@ meta_window_activate_full (MetaWindow *window,
MetaClientType source_indication, MetaClientType source_indication,
MetaWorkspace *workspace) MetaWorkspace *workspace)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean allow_workspace_switch; gboolean allow_workspace_switch;
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"_NET_ACTIVE_WINDOW message sent for %s at time %u " "_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 */ /* Get window on current or given workspace */
if (workspace == NULL) if (workspace == NULL)
workspace = window->display->active_workspace; workspace = workspace_manager->active_workspace;
/* For non-transient windows, we just set up a pulsing indicator, /* For non-transient windows, we just set up a pulsing indicator,
rather than move windows or workspaces. rather than move windows or workspaces.
@ -3839,6 +3848,7 @@ void
meta_window_update_monitor (MetaWindow *window, meta_window_update_monitor (MetaWindow *window,
gboolean user_op) gboolean user_op)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
const MetaLogicalMonitor *old; const MetaLogicalMonitor *old;
old = window->monitor; old = window->monitor;
@ -3858,8 +3868,8 @@ meta_window_update_monitor (MetaWindow *window,
*/ */
if (meta_prefs_get_workspaces_only_on_primary () && user_op && if (meta_prefs_get_workspaces_only_on_primary () && user_op &&
meta_window_is_on_primary_monitor (window) && meta_window_is_on_primary_monitor (window) &&
window->display->active_workspace != window->workspace) workspace_manager->active_workspace != window->workspace)
meta_window_change_workspace (window, window->display->active_workspace); meta_window_change_workspace (window, workspace_manager->active_workspace);
meta_window_main_monitor_changed (window, old); meta_window_main_monitor_changed (window, old);
@ -3894,6 +3904,7 @@ meta_window_move_resize_internal (MetaWindow *window,
* to the client. * to the client.
*/ */
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean did_placement; gboolean did_placement;
MetaRectangle unconstrained_rect; MetaRectangle unconstrained_rect;
MetaRectangle constrained_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_window_foreach_transient (window, maybe_move_attached_dialog, NULL);
meta_stack_update_window_tile_matches (window->display->stack, 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, meta_window_focus (MetaWindow *window,
guint32 timestamp) guint32 timestamp)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaWindow *modal_transient; MetaWindow *modal_transient;
g_return_if_fail (!window->override_redirect); g_return_if_fail (!window->override_redirect);
@ -4631,8 +4643,8 @@ meta_window_focus (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"%s has %s as a modal transient, so focusing it instead.\n", "%s has %s as a modal transient, so focusing it instead.\n",
window->desc, modal_transient->desc); window->desc, modal_transient->desc);
if (!meta_window_located_on_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, window->display->active_workspace); meta_window_change_workspace (modal_transient, workspace_manager->active_workspace);
window = modal_transient; window = modal_transient;
} }
@ -4682,6 +4694,8 @@ set_workspace_state (MetaWindow *window,
gboolean on_all_workspaces, gboolean on_all_workspaces,
MetaWorkspace *workspace) MetaWorkspace *workspace)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
/* If we're on all workspaces, then our new workspace must be NULL. */ /* If we're on all workspaces, then our new workspace must be NULL. */
if (on_all_workspaces) if (on_all_workspaces)
g_assert (workspace == NULL); g_assert (workspace == NULL);
@ -4703,7 +4717,7 @@ set_workspace_state (MetaWindow *window,
else if (window->on_all_workspaces) else if (window->on_all_workspaces)
{ {
GList *l; 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; MetaWorkspace *ws = l->data;
meta_workspace_remove_window (ws, window); meta_workspace_remove_window (ws, window);
@ -4718,7 +4732,7 @@ set_workspace_state (MetaWindow *window,
else if (window->on_all_workspaces) else if (window->on_all_workspaces)
{ {
GList *l; 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; MetaWorkspace *ws = l->data;
meta_workspace_add_window (ws, window); meta_workspace_add_window (ws, window);
@ -4760,6 +4774,7 @@ should_be_on_all_workspaces (MetaWindow *window)
void void
meta_window_on_all_workspaces_changed (MetaWindow *window) 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); gboolean on_all_workspaces = should_be_on_all_workspaces (window);
if (window->on_all_workspaces == on_all_workspaces) 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 /* We're coming out of the sticky state. Put the window on
* the currently active workspace. */ * the currently active workspace. */
workspace = window->display->active_workspace; workspace = workspace_manager->active_workspace;
} }
set_workspace_state (window, on_all_workspaces, workspace); set_workspace_state (window, on_all_workspaces, workspace);
@ -4998,6 +5013,7 @@ meta_window_change_workspace_by_index (MetaWindow *window,
gint space_index, gint space_index,
gboolean append) gboolean append)
{ {
MetaWorkspaceManager *workspace_manager;
MetaWorkspace *workspace; MetaWorkspace *workspace;
MetaDisplay *display; MetaDisplay *display;
@ -5010,12 +5026,13 @@ meta_window_change_workspace_by_index (MetaWindow *window,
} }
display = window->display; display = window->display;
workspace_manager = display->workspace_manager;
workspace = workspace =
meta_display_get_workspace_by_index (display, space_index); meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index);
if (!workspace && append) 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) if (workspace)
meta_window_change_workspace (window, workspace); meta_window_change_workspace (window, workspace);
@ -5115,6 +5132,8 @@ void
meta_window_set_focused_internal (MetaWindow *window, meta_window_set_focused_internal (MetaWindow *window,
gboolean focused) gboolean focused)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
if (focused) if (focused)
{ {
window->has_focus = TRUE; 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 * list only if the window is actually on the active
* workspace. * workspace.
*/ */
if (window->display->active_workspace && if (workspace_manager->active_workspace &&
meta_window_located_on_workspace (window, meta_window_located_on_workspace (window,
window->display->active_workspace)) workspace_manager->active_workspace))
{ {
GList* link; GList* link;
link = g_list_find (window->display->active_workspace->mru_list, link = g_list_find (workspace_manager->active_workspace->mru_list,
window); window);
g_assert (link); g_assert (link);
window->display->active_workspace->mru_list = workspace_manager->active_workspace->mru_list =
g_list_remove_link (window->display->active_workspace->mru_list, g_list_remove_link (workspace_manager->active_workspace->mru_list,
link); link);
g_list_free (link); g_list_free (link);
window->display->active_workspace->mru_list = workspace_manager->active_workspace->mru_list =
g_list_prepend (window->display->active_workspace->mru_list, g_list_prepend (workspace_manager->active_workspace->mru_list,
window); window);
} }
@ -5387,8 +5406,10 @@ idle_update_icon (gpointer data)
GList* GList*
meta_window_get_workspaces (MetaWindow *window) meta_window_get_workspaces (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
if (window->on_all_workspaces) if (window->on_all_workspaces)
return window->display->workspaces; return workspace_manager->workspaces;
else if (window->workspace != NULL) else if (window->workspace != NULL)
return window->workspace->list_containing_self; return window->workspace->list_containing_self;
else if (window->constructing) else if (window->constructing)
@ -5745,6 +5766,7 @@ meta_window_show_menu_for_rect (MetaWindow *window,
void void
meta_window_shove_titlebar_onscreen (MetaWindow *window) meta_window_shove_titlebar_onscreen (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaRectangle frame_rect; MetaRectangle frame_rect;
GList *onscreen_region; GList *onscreen_region;
int horiz_amount, vert_amount; int horiz_amount, vert_amount;
@ -5757,7 +5779,7 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window)
/* Get the basic info we need */ /* Get the basic info we need */
meta_window_get_frame_rect (window, &frame_rect); 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 /* 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 * screen), then shove the window on screen, then return the region to
@ -5785,6 +5807,7 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window)
gboolean gboolean
meta_window_titlebar_is_onscreen (MetaWindow *window) meta_window_titlebar_is_onscreen (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaRectangle titlebar_rect, frame_rect; MetaRectangle titlebar_rect, frame_rect;
GList *onscreen_region; GList *onscreen_region;
gboolean is_onscreen; gboolean is_onscreen;
@ -5809,7 +5832,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window)
* them overlaps with the titlebar sufficiently to consider it onscreen. * them overlaps with the titlebar sufficiently to consider it onscreen.
*/ */
is_onscreen = FALSE; is_onscreen = FALSE;
onscreen_region = window->display->active_workspace->screen_region; onscreen_region = workspace_manager->active_workspace->screen_region;
while (onscreen_region) while (onscreen_region)
{ {
MetaRectangle *spanning_rect = onscreen_region->data; MetaRectangle *spanning_rect = onscreen_region->data;
@ -6882,11 +6905,12 @@ ensure_mru_position_after (MetaWindow *window,
* map. * map.
*/ */
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
GList* active_mru_list; GList* active_mru_list;
GList* window_position; GList* window_position;
GList* after_this_one_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); window_position = g_list_find (active_mru_list, window);
after_this_one_position = g_list_find (active_mru_list, after_this_one); 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)) if (g_list_length (window_position) > g_list_length (after_this_one_position))
{ {
window->display->active_workspace->mru_list = workspace_manager->active_workspace->mru_list =
g_list_delete_link (window->display->active_workspace->mru_list, g_list_delete_link (workspace_manager->active_workspace->mru_list,
window_position); window_position);
window->display->active_workspace->mru_list = workspace_manager->active_workspace->mru_list =
g_list_insert_before (window->display->active_workspace->mru_list, g_list_insert_before (workspace_manager->active_workspace->mru_list,
after_this_one_position->next, after_this_one_position->next,
window); window);
} }
@ -7052,12 +7076,13 @@ meta_window_get_stable_sequence (MetaWindow *window)
void void
meta_window_set_demands_attention (MetaWindow *window) meta_window_set_demands_attention (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaRectangle candidate_rect, other_rect; MetaRectangle candidate_rect, other_rect;
GList *stack = window->display->stack->sorted; GList *stack = window->display->stack->sorted;
MetaWindow *other_window; MetaWindow *other_window;
gboolean obscured = FALSE; gboolean obscured = FALSE;
MetaWorkspace *workspace = window->display->active_workspace; MetaWorkspace *workspace = workspace_manager->active_workspace;
if (window->wm_state_demands_attention) if (window->wm_state_demands_attention)
return; return;
@ -7243,8 +7268,10 @@ meta_window_get_window_type (MetaWindow *window)
MetaWorkspace * MetaWorkspace *
meta_window_get_workspace (MetaWindow *window) meta_window_get_workspace (MetaWindow *window)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
if (window->on_all_workspaces) if (window->on_all_workspaces)
return window->display->active_workspace; return workspace_manager->active_workspace;
else else
return window->workspace; return window->workspace;
} }

View File

@ -38,6 +38,7 @@ struct _MetaWorkspace
{ {
GObject parent_instance; GObject parent_instance;
MetaDisplay *display; MetaDisplay *display;
MetaWorkspaceManager *manager;
GList *windows; GList *windows;
@ -72,7 +73,7 @@ struct _MetaWorkspaceClass
GObjectClass parent_class; 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_remove (MetaWorkspace *workspace);
void meta_workspace_add_window (MetaWorkspace *workspace, void meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window); MetaWindow *window);

View File

@ -36,6 +36,7 @@
#include "backends/meta-logical-monitor.h" #include "backends/meta-logical-monitor.h"
#include "x11/meta-x11-display-private.h" #include "x11/meta-x11-display-private.h"
#include <meta/workspace.h> #include <meta/workspace.h>
#include "meta-workspace-manager-private.h"
#include "workspace-private.h" #include "workspace-private.h"
#include "boxes-private.h" #include "boxes-private.h"
#include <meta/meta-x11-errors.h> #include <meta/meta-x11-errors.h>
@ -223,16 +224,19 @@ meta_workspace_init (MetaWorkspace *workspace)
} }
MetaWorkspace * MetaWorkspace *
meta_workspace_new (MetaDisplay *display) meta_workspace_new (MetaWorkspaceManager *workspace_manager)
{ {
MetaDisplay *display = workspace_manager->display;
MetaWorkspace *workspace; MetaWorkspace *workspace;
GSList *windows, *l; GSList *windows, *l;
workspace = g_object_new (META_TYPE_WORKSPACE, NULL); workspace = g_object_new (META_TYPE_WORKSPACE, NULL);
workspace->display = display; workspace->display = display;
workspace->display->workspaces = workspace->manager = workspace_manager;
g_list_append (workspace->display->workspaces, workspace);
workspace_manager->workspaces =
g_list_append (workspace_manager->workspaces, workspace);
workspace->windows = NULL; workspace->windows = NULL;
workspace->mru_list = NULL; workspace->mru_list = NULL;
@ -319,12 +323,14 @@ assert_workspace_empty (MetaWorkspace *workspace)
void void
meta_workspace_remove (MetaWorkspace *workspace) 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); assert_workspace_empty (workspace);
workspace->display->workspaces = manager->workspaces =
g_list_remove (workspace->display->workspaces, workspace); g_list_remove (manager->workspaces, workspace);
meta_workspace_clear_logical_monitor_data (workspace); meta_workspace_clear_logical_monitor_data (workspace);
@ -439,11 +445,11 @@ workspace_switch_sound(MetaWorkspace *from,
int i, nw, x, y, fi, ti; int i, nw, x, y, fi, ti;
const char *e; 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); fi = meta_workspace_index(from);
ti = meta_workspace_index(to); ti = meta_workspace_index(to);
meta_display_calc_workspace_layout(from->display, meta_workspace_manager_calc_workspace_layout (from->manager,
nw, nw,
fi, fi,
&layout); &layout);
@ -489,7 +495,7 @@ workspace_switch_sound(MetaWorkspace *from,
NULL); NULL);
finish: finish:
meta_display_free_workspace_layout (&layout); meta_workspace_manager_free_workspace_layout (&layout);
#endif /* HAVE_LIBCANBERRA */ #endif /* HAVE_LIBCANBERRA */
} }
@ -519,7 +525,6 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
{ {
MetaWorkspace *old; MetaWorkspace *old;
MetaWindow *move_window; MetaWindow *move_window;
MetaDisplay *display;
MetaCompositor *comp; MetaCompositor *comp;
MetaWorkspaceLayout layout1, layout2; MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space; 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_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace)); meta_workspace_index (workspace));
if (workspace->display->active_workspace == workspace) if (workspace->manager->active_workspace == workspace)
return; return;
/* Free any cached pointers to the workspaces's edges from /* Free any cached pointers to the workspaces's edges from
* a current resize or move operation */ * a current resize or move operation */
meta_display_cleanup_edges (workspace->display); meta_display_cleanup_edges (workspace->display);
if (workspace->display->active_workspace) if (workspace->manager->active_workspace)
workspace_switch_sound (workspace->display->active_workspace, workspace); workspace_switch_sound (workspace->manager->active_workspace, workspace);
/* Note that old can be NULL; e.g. when starting up */ /* 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) if (old == NULL)
return; return;
@ -553,7 +558,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
* _net_showing_desktop hint * _net_showing_desktop hint
*/ */
if (old->showing_desktop != workspace->showing_desktop) 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; move_window = NULL;
if (meta_grab_op_is_moving (workspace->display->grab_op)) if (meta_grab_op_is_moving (workspace->display->grab_op))
@ -578,17 +583,16 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/* /*
* Notify the compositor that the active workspace is changing. * Notify the compositor that the active workspace is changing.
*/ */
display = workspace->display; comp = meta_display_get_compositor (workspace->display);
comp = meta_display_get_compositor (display);
direction = 0; direction = 0;
current_space = meta_workspace_index (old); current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace); new_space = meta_workspace_index (workspace);
num_workspaces = meta_display_get_n_workspaces (workspace->display); num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager);
meta_display_calc_workspace_layout (workspace->display, num_workspaces, meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
current_space, &layout1); current_space, &layout1);
meta_display_calc_workspace_layout (workspace->display, num_workspaces, meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
new_space, &layout2); new_space, &layout2);
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) 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; direction = META_MOTION_UP_LEFT;
} }
meta_display_free_workspace_layout (&layout1); meta_workspace_manager_free_workspace_layout (&layout1);
meta_display_free_workspace_layout (&layout2); meta_workspace_manager_free_workspace_layout (&layout2);
meta_compositor_switch_workspace (comp, old, workspace, direction); 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_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 void
@ -665,7 +670,7 @@ meta_workspace_index (MetaWorkspace *workspace)
{ {
int ret; int ret;
ret = g_list_index (workspace->display->workspaces, workspace); ret = g_list_index (workspace->manager->workspaces, workspace);
if (ret < 0) if (ret < 0)
meta_bug ("Workspace does not exist to index!\n"); 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 /* If we are in the middle of a resize or move operation, we
* might have cached pointers to the workspace's edges */ * 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_display_cleanup_edges (workspace->display);
meta_workspace_clear_logical_monitor_data (workspace); meta_workspace_clear_logical_monitor_data (workspace);
@ -1204,8 +1209,8 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
gboolean ltr; gboolean ltr;
current_space = meta_workspace_index (workspace); current_space = meta_workspace_index (workspace);
num_workspaces = meta_display_get_n_workspaces (workspace->display); num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager);
meta_display_calc_workspace_layout (workspace->display, num_workspaces, meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
current_space, &layout); current_space, &layout);
meta_verbose ("Getting neighbor of %d in direction %s\n", meta_verbose ("Getting neighbor of %d in direction %s\n",
@ -1251,9 +1256,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
meta_verbose ("Neighbor workspace is %d at row %d col %d\n", meta_verbose ("Neighbor workspace is %d at row %d col %d\n",
i, layout.current_row, layout.current_col); 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* const char*

View File

@ -203,24 +203,6 @@ int meta_display_get_monitor_neighbor_index (MetaDisplay *display,
int which_monitor, int which_monitor,
MetaDisplayDirection dir); 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, void meta_display_focus_default_window (MetaDisplay *display,
guint32 timestamp); guint32 timestamp);
@ -239,12 +221,6 @@ typedef enum
META_DISPLAY_BOTTOMRIGHT META_DISPLAY_BOTTOMRIGHT
} MetaDisplayCorner; } 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); MetaWorkspaceManager *meta_display_get_workspace_manager (MetaDisplay *display);
#endif #endif

View File

@ -32,6 +32,28 @@
#define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ()) #define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ())
G_DECLARE_FINAL_TYPE (MetaWorkspaceManager, meta_workspace_manager, META, WORKSPACE_MANAGER, GObject) 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); 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 */ #endif /* META_WORKSPACE_MANAGER_H */

View File

@ -32,6 +32,7 @@
#include "meta/meta-backend.h" #include "meta/meta-backend.h"
#include "bell.h" #include "bell.h"
#include "display-private.h" #include "display-private.h"
#include "meta-workspace-manager-private.h"
#include "window-private.h" #include "window-private.h"
#include "workspace-private.h" #include "workspace-private.h"
#include "backends/meta-cursor-tracker-private.h" #include "backends/meta-cursor-tracker-private.h"
@ -844,6 +845,7 @@ handle_input_xevent (MetaX11Display *x11_display,
Window modified; Window modified;
MetaWindow *window; MetaWindow *window;
MetaDisplay *display = x11_display->display; MetaDisplay *display = x11_display->display;
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
if (input_event == NULL) if (input_event == NULL)
return FALSE; return FALSE;
@ -912,7 +914,7 @@ handle_input_xevent (MetaX11Display *x11_display,
"Focus got set to None, probably due to " "Focus got set to None, probably due to "
"brain-damage in the X protocol (see bug " "brain-damage in the X protocol (see bug "
"125492). Setting the default focus window.\n"); "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, NULL,
meta_x11_display_get_current_time_roundtrip (x11_display)); 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 " "Focus got set to root window, probably due to "
"gnome-session logout dialog usage (see bug " "gnome-session logout dialog usage (see bug "
"153220). Setting the default focus window.\n"); "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, NULL,
meta_x11_display_get_current_time_roundtrip (x11_display)); meta_x11_display_get_current_time_roundtrip (x11_display));
} }
@ -1197,6 +1199,7 @@ handle_other_xevent (MetaX11Display *x11_display,
XEvent *event) XEvent *event)
{ {
MetaDisplay *display = x11_display->display; MetaDisplay *display = x11_display->display;
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
Window modified; Window modified;
MetaWindow *window; MetaWindow *window;
MetaWindow *property_for_window; MetaWindow *property_for_window;
@ -1398,12 +1401,12 @@ handle_other_xevent (MetaX11Display *x11_display,
if (window->minimized) if (window->minimized)
{ {
meta_window_unminimize (window); 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", meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n",
window->mapped, window->minimized); window->mapped, window->minimized);
meta_window_change_workspace (window, meta_window_change_workspace (window,
window->display->active_workspace); workspace_manager->active_workspace);
} }
} }
break; break;
@ -1552,7 +1555,7 @@ handle_other_xevent (MetaX11Display *x11_display,
"specified timestamp of %u\n", "specified timestamp of %u\n",
space, time); 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... */ /* Handle clients using the older version of the spec... */
if (time == 0 && workspace) if (time == 0 && workspace)
@ -1593,11 +1596,11 @@ handle_other_xevent (MetaX11Display *x11_display,
showing_desktop ? "show" : "hide"); showing_desktop ? "show" : "hide");
if (showing_desktop) if (showing_desktop)
meta_display_show_desktop (display, timestamp); meta_workspace_manager_show_desktop (workspace_manager, timestamp);
else else
{ {
meta_display_unshow_desktop (display); meta_workspace_manager_unshow_desktop (workspace_manager);
meta_workspace_focus_default_window (display->active_workspace, NULL, timestamp); meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, timestamp);
} }
} }
else if (event->xclient.message_type == else if (event->xclient.message_type ==

View File

@ -55,6 +55,7 @@
#include "backends/meta-logical-monitor.h" #include "backends/meta-logical-monitor.h"
#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-backend-x11.h"
#include "core/frame.h" #include "core/frame.h"
#include "core/meta-workspace-manager-private.h"
#include "core/util-private.h" #include "core/util-private.h"
#include "core/workspace-private.h" #include "core/workspace-private.h"
#include "meta/main.h" #include "meta/main.h"
@ -793,7 +794,7 @@ init_event_masks (MetaX11Display *x11_display)
} }
static void static void
set_active_workspace_hint (MetaDisplay *display, set_active_workspace_hint (MetaWorkspaceManager *workspace_manager,
MetaX11Display *x11_display) MetaX11Display *x11_display)
{ {
unsigned long data[1]; unsigned long data[1];
@ -804,10 +805,10 @@ set_active_workspace_hint (MetaDisplay *display,
* on restart. By doing this we keep the current * on restart. By doing this we keep the current
* desktop on restart. * desktop on restart.
*/ */
if (display->closing > 0) if (x11_display->display->closing > 0)
return; 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]); meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
@ -821,17 +822,17 @@ set_active_workspace_hint (MetaDisplay *display,
} }
static void static void
set_number_of_spaces_hint (MetaDisplay *display, set_number_of_spaces_hint (MetaWorkspaceManager *workspace_manager,
GParamSpec *pspec, GParamSpec *pspec,
gpointer user_data) gpointer user_data)
{ {
MetaX11Display *x11_display = user_data; MetaX11Display *x11_display = user_data;
unsigned long data[1]; unsigned long data[1];
if (display->closing > 0) if (x11_display->display->closing > 0)
return; 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]); 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 static void
set_showing_desktop_hint (MetaDisplay *display, set_showing_desktop_hint (MetaWorkspaceManager *workspace_manager,
MetaX11Display *x11_display) MetaX11Display *x11_display)
{ {
unsigned long data[1]; 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); meta_x11_error_trap_push (x11_display);
XChangeProperty (x11_display->xdisplay, XChangeProperty (x11_display->xdisplay,
@ -864,12 +865,15 @@ set_showing_desktop_hint (MetaDisplay *display,
static void static void
set_workspace_names (MetaX11Display *x11_display) set_workspace_names (MetaX11Display *x11_display)
{ {
MetaWorkspaceManager *workspace_manager;
GString *flattened; GString *flattened;
int i; int i;
int n_spaces; int n_spaces;
workspace_manager = x11_display->display->workspace_manager;
/* flatten to nul-separated list */ /* 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 (""); flattened = g_string_new ("");
i = 0; i = 0;
while (i < n_spaces) while (i < n_spaces)
@ -903,16 +907,17 @@ static void
set_work_area_hint (MetaDisplay *display, set_work_area_hint (MetaDisplay *display,
MetaX11Display *x11_display) MetaX11Display *x11_display)
{ {
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
int num_workspaces; int num_workspaces;
GList *l; GList *l;
unsigned long *data, *tmp; unsigned long *data, *tmp;
MetaRectangle area; 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); data = g_new (unsigned long, num_workspaces * 4);
tmp = data; tmp = data;
for (l = display->workspaces; l; l = l->next) for (l = workspace_manager->workspaces; l; l = l->next)
{ {
MetaWorkspace *workspace = l->data; MetaWorkspace *workspace = l->data;
@ -1252,7 +1257,7 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
(int) current_workspace_index); (int) current_workspace_index);
/* Switch to the _NET_CURRENT_DESKTOP workspace */ /* Switch to the _NET_CURRENT_DESKTOP workspace */
current_workspace = meta_display_get_workspace_by_index (display, current_workspace = meta_workspace_manager_get_workspace_by_index (display->workspace_manager,
current_workspace_index); current_workspace_index);
if (current_workspace != NULL) if (current_workspace != NULL)
@ -1278,25 +1283,25 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
meta_XFree (list); meta_XFree (list);
} }
if (num > meta_display_get_n_workspaces (display)) if (num > meta_workspace_manager_get_n_workspaces (display->workspace_manager))
meta_display_update_num_workspaces (display, timestamp, num); 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), G_CALLBACK (set_active_workspace_hint),
x11_display, 0); 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), G_CALLBACK (set_number_of_spaces_hint),
x11_display, 0); 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), G_CALLBACK (set_showing_desktop_hint),
x11_display, 0); x11_display, 0);
@ -2013,6 +2018,7 @@ meta_x11_display_update_workspace_names (MetaX11Display *x11_display)
void void
meta_x11_display_update_workspace_layout (MetaX11Display *x11_display) meta_x11_display_update_workspace_layout (MetaX11Display *x11_display)
{ {
MetaWorkspaceManager *workspace_manager = x11_display->display->workspace_manager;
gboolean vertical_layout = FALSE; gboolean vertical_layout = FALSE;
int n_rows = -1; int n_rows = -1;
int n_columns = 1; int n_columns = 1;
@ -2020,7 +2026,7 @@ meta_x11_display_update_workspace_layout (MetaX11Display *x11_display)
uint32_t *list; uint32_t *list;
int n_items; int n_items;
if (x11_display->display->workspace_layout_overridden) if (workspace_manager->workspace_layout_overridden)
return; return;
list = NULL; list = NULL;
@ -2098,7 +2104,7 @@ meta_x11_display_update_workspace_layout (MetaX11Display *x11_display)
meta_XFree (list); meta_XFree (list);
meta_display_update_workspace_layout (x11_display->display, meta_workspace_manager_update_workspace_layout (workspace_manager,
starting_corner, starting_corner,
vertical_layout, vertical_layout,
n_rows, n_rows,

View File

@ -49,6 +49,7 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include "util-private.h" #include "util-private.h"
#include "meta-workspace-manager-private.h"
#ifndef HOST_NAME_MAX #ifndef HOST_NAME_MAX
/* Solaris headers apparently don't define this so do so manually; #326745 */ /* Solaris headers apparently don't define this so do so manually; #326745 */
@ -1027,6 +1028,7 @@ reload_net_startup_id (MetaWindow *window,
MetaPropValue *value, MetaPropValue *value,
gboolean initial) gboolean initial)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
guint32 timestamp = window->net_wm_user_time; guint32 timestamp = window->net_wm_user_time;
MetaWorkspace *workspace = NULL; MetaWorkspace *workspace = NULL;
@ -1049,7 +1051,8 @@ reload_net_startup_id (MetaWindow *window,
if (window->initial_timestamp_set) if (window->initial_timestamp_set)
timestamp = window->initial_timestamp; timestamp = window->initial_timestamp;
if (window->initial_workspace_set) 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); meta_window_activate_with_workspace (window, timestamp, workspace);
} }

View File

@ -50,6 +50,7 @@
#include "xprops.h" #include "xprops.h"
#include "session.h" #include "session.h"
#include "workspace-private.h" #include "workspace-private.h"
#include "meta-workspace-manager-private.h"
#include "backends/meta-logical-monitor.h" #include "backends/meta-logical-monitor.h"
#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-backend-x11.h"
@ -442,10 +443,11 @@ meta_window_apply_session_info (MetaWindow *window,
tmp = info->workspace_indices; tmp = info->workspace_indices;
while (tmp != NULL) while (tmp != NULL)
{ {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaWorkspace *space; MetaWorkspace *space;
space = space =
meta_display_get_workspace_by_index (window->display, meta_workspace_manager_get_workspace_by_index (workspace_manager,
GPOINTER_TO_INT (tmp->data)); GPOINTER_TO_INT (tmp->data));
if (space) if (space)
@ -2403,6 +2405,7 @@ meta_window_x11_client_message (MetaWindow *window,
x11_display->atom__NET_WM_DESKTOP) x11_display->atom__NET_WM_DESKTOP)
{ {
int space; int space;
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
MetaWorkspace *workspace; MetaWorkspace *workspace;
space = event->xclient.data.l[0]; space = event->xclient.data.l[0];
@ -2411,7 +2414,7 @@ meta_window_x11_client_message (MetaWindow *window,
window->desc, space); window->desc, space);
workspace = workspace =
meta_display_get_workspace_by_index (window->display, meta_workspace_manager_get_workspace_by_index (workspace_manager,
space); space);
if (workspace) if (workspace)