[mutter] Move workspace handling to MetaDisplay and MetaX11Display
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] Move workspace handling to MetaDisplay and MetaX11Display
- Date: Sat, 7 Jul 2018 10:00:14 +0000 (UTC)
commit b7c3dada81eec424662caab621d86788597aaa83
Author: Armin Krezović <krezovic armin gmail com>
Date: Sat Aug 26 21:39:46 2017 +0200
Move workspace handling to MetaDisplay and MetaX11Display
https://bugzilla.gnome.org/show_bug.cgi?id=759538
src/core/constraints.c | 6 +-
src/core/core.c | 16 +-
src/core/display-private.h | 44 ++
src/core/display.c | 993 ++++++++++++++++++++++++++++++-
src/core/edge-resistance.c | 6 +-
src/core/keybindings.c | 28 +-
src/core/screen-private.h | 53 +-
src/core/screen.c | 1125 +-----------------------------------
src/core/stack.c | 14 +-
src/core/window.c | 86 +--
src/core/workspace-private.h | 4 +-
src/core/workspace.c | 136 +++--
src/meta/display.h | 42 ++
src/meta/screen.h | 42 --
src/meta/workspace.h | 2 +-
src/x11/events.c | 21 +-
src/x11/meta-x11-display-private.h | 8 +
src/x11/meta-x11-display.c | 106 ++++
src/x11/window-props.c | 2 +-
src/x11/window-x11.c | 8 +-
20 files changed, 1349 insertions(+), 1393 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index f5360ef9d..d90e7230c 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -412,7 +412,7 @@ setup_constraint_info (ConstraintInfo *info,
&info->entire_monitor);
}
- cur_workspace = window->screen->active_workspace;
+ cur_workspace = window->display->active_workspace;
info->usable_screen_region =
meta_workspace_get_onscreen_region (cur_workspace);
info->usable_monitor_region =
@@ -499,7 +499,7 @@ place_window_if_needed(MetaWindow *window,
meta_window_get_work_area_for_logical_monitor (window,
logical_monitor,
&info->work_area_monitor);
- cur_workspace = window->screen->active_workspace;
+ cur_workspace = window->display->active_workspace;
info->usable_monitor_region =
meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor);
@@ -965,7 +965,7 @@ constrain_maximization (MetaWindow *window,
direction = META_DIRECTION_HORIZONTAL;
else
direction = META_DIRECTION_VERTICAL;
- active_workspace_struts = window->screen->active_workspace->all_struts;
+ active_workspace_struts = window->display->active_workspace->all_struts;
target_size = info->current;
meta_rectangle_expand_to_avoiding_struts (&target_size,
diff --git a/src/core/core.c b/src/core/core.c
index d0caeca7a..15949fa6e 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -87,22 +87,22 @@ lower_window_and_transients (MetaWindow *window,
* Do extra sanity checks to avoid possible race conditions.
* (Borrowed from window.c.)
*/
- if (window->screen->active_workspace &&
+ if (window->display->active_workspace &&
meta_window_located_on_workspace (window,
- window->screen->active_workspace))
+ window->display->active_workspace))
{
GList* link;
- link = g_list_find (window->screen->active_workspace->mru_list,
+ link = g_list_find (window->display->active_workspace->mru_list,
window);
g_assert (link);
- window->screen->active_workspace->mru_list =
- g_list_remove_link (window->screen->active_workspace->mru_list,
+ window->display->active_workspace->mru_list =
+ g_list_remove_link (window->display->active_workspace->mru_list,
link);
g_list_free (link);
- window->screen->active_workspace->mru_list =
- g_list_append (window->screen->active_workspace->mru_list,
+ window->display->active_workspace->mru_list =
+ g_list_append (window->display->active_workspace->mru_list,
window);
}
}
@@ -123,7 +123,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
* the focus window, assume that's always the case. (Typically,
* this will be invoked via keyboard action or by a mouse action;
* in either case the window or a modal child will have been focused.) */
- meta_workspace_focus_default_window (window->screen->active_workspace,
+ meta_workspace_focus_default_window (window->display->active_workspace,
NULL,
timestamp);
}
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 48a9c93cf..5ab6791fd 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -245,6 +245,16 @@ struct _MetaDisplay
guint work_area_later;
guint check_fullscreen_later;
+
+ MetaWorkspace *active_workspace;
+
+ GList *workspaces;
+
+ int rows_of_workspaces;
+ int columns_of_workspaces;
+ MetaDisplayCorner starting_corner;
+ guint vertical_workspaces : 1;
+ guint workspace_layout_overridden : 1;
};
struct _MetaDisplayClass
@@ -434,4 +444,38 @@ void meta_display_queue_check_fullscreen (MetaDisplay *display);
MetaWindow *meta_display_get_pointer_window (MetaDisplay *display,
MetaWindow *not_this_one);
+void meta_display_init_workspaces (MetaDisplay *display);
+void meta_display_update_workspace_layout (MetaDisplay *display);
+
+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);
+
#endif
diff --git a/src/core/display.c b/src/core/display.c
index d00229cab..a0bdab91f 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -138,6 +138,9 @@ enum
PAD_MODE_SWITCH,
WINDOW_ENTERED_MONITOR,
WINDOW_LEFT_MONITOR,
+ WORKSPACE_ADDED,
+ WORKSPACE_REMOVED,
+ WORKSPACE_SWITCHED,
IN_FULLSCREEN_CHANGED,
STARTUP_SEQUENCE_CHANGED,
MONITORS_CHANGED,
@@ -149,7 +152,8 @@ enum
enum {
PROP_0,
- PROP_FOCUS_WINDOW
+ PROP_FOCUS_WINDOW,
+ PROP_N_WORKSPACES
};
static guint display_signals [LAST_SIGNAL] = { 0 };
@@ -171,6 +175,10 @@ static void on_monitors_changed (MetaMonitorManager *monitor_manager,
static void prefs_changed_callback (MetaPreference pref,
void *data);
+static void set_workspace_names (MetaDisplay *display);
+static void update_num_workspaces (MetaDisplay *display,
+ guint32 timestamp);
+
static int mru_cmp (gconstpointer a,
gconstpointer b);
@@ -187,6 +195,9 @@ meta_display_get_property(GObject *object,
case PROP_FOCUS_WINDOW:
g_value_set_object (value, display->focus_window);
break;
+ case PROP_N_WORKSPACES:
+ g_value_set_int (value, meta_display_get_n_workspaces (display));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -446,6 +457,38 @@ meta_display_class_init (MetaDisplayClass *klass)
G_TYPE_INT,
META_TYPE_WINDOW);
+ display_signals[WORKSPACE_ADDED] =
+ g_signal_new ("workspace-added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ display_signals[WORKSPACE_REMOVED] =
+ g_signal_new ("workspace-removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ display_signals[WORKSPACE_SWITCHED] =
+ g_signal_new ("workspace-switched",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ META_TYPE_MOTION_DIRECTION);
+
display_signals[IN_FULLSCREEN_CHANGED] =
g_signal_new ("in-fullscreen-changed",
G_TYPE_FROM_CLASS (klass),
@@ -488,6 +531,15 @@ meta_display_class_init (MetaDisplayClass *klass)
"Currently focused window",
META_TYPE_WINDOW,
G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_N_WORKSPACES,
+ g_param_spec_int ("n-workspaces",
+ "N Workspaces",
+ "Number of workspaces",
+ 1, G_MAXINT, 1,
+ G_PARAM_READABLE));
+
}
@@ -629,6 +681,18 @@ on_startup_notification_changed (MetaStartupNotification *sn,
g_signal_emit_by_name (display, "startup-sequence-changed", sequence);
}
+static void
+reload_logical_monitors (MetaDisplay *display)
+{
+ GList *l;
+
+ for (l = display->workspaces; l != NULL; l = l->next)
+ {
+ MetaWorkspace *space = l->data;
+ meta_workspace_invalidate_work_area (space);
+ }
+}
+
/**
* meta_display_open:
*
@@ -694,6 +758,13 @@ meta_display_open (void)
display->grab_tile_mode = META_TILE_NONE;
display->grab_tile_monitor_number = -1;
+ display->active_workspace = NULL;
+ display->workspaces = NULL;
+ display->rows_of_workspaces = 1;
+ display->columns_of_workspaces = -1;
+ display->vertical_workspaces = FALSE;
+ display->starting_corner = META_DISPLAY_TOPLEFT;
+
display->grab_edge_resistance_data = NULL;
meta_display_init_keys (display);
@@ -729,6 +800,15 @@ meta_display_open (void)
display->stack = meta_stack_new (display);
display->stack_tracker = meta_stack_tracker_new (display);
+ reload_logical_monitors (display);
+
+ meta_display_update_workspace_layout (display);
+
+ /* There must be at least one workspace at all times,
+ * so create that required workspace.
+ */
+ meta_workspace_new (display);
+
meta_bell_init (display);
display->last_focus_time = timestamp;
@@ -762,7 +842,7 @@ meta_display_open (void)
g_signal_connect (display->startup_notification, "changed",
G_CALLBACK (on_startup_notification_changed), display);
- meta_screen_init_workspaces (screen);
+ meta_display_init_workspaces (display);
enable_compositor (display);
@@ -2496,6 +2576,21 @@ prefs_changed_callback (MetaPreference pref,
{
meta_display_reload_cursor (display);
}
+ else if ((pref == META_PREF_NUM_WORKSPACES ||
+ pref == META_PREF_DYNAMIC_WORKSPACES) &&
+ !meta_prefs_get_dynamic_workspaces ())
+ {
+ /* GSettings doesn't provide timestamps, but luckily update_num_workspaces
+ * often doesn't need it...
+ */
+ guint32 timestamp =
+ meta_display_get_current_time_roundtrip (display);
+ update_num_workspaces (display, timestamp);
+ }
+ else if (pref == META_PREF_WORKSPACE_NAMES)
+ {
+ set_workspace_names (display);
+ }
}
void
@@ -2993,12 +3088,12 @@ on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
MetaBackend *backend;
MetaCursorRenderer *cursor_renderer;
- meta_screen_on_monitors_changed (display->screen);
-
meta_monitor_manager_get_screen_size (monitor_manager,
&display->rect.width,
&display->rect.height);
+ reload_logical_monitors (display);
+
/* Fix up monitor for all windows on this display */
meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT,
(MetaDisplayWindowFunc)
@@ -3264,17 +3359,16 @@ static void
set_work_area_hint (MetaDisplay *display)
{
MetaX11Display *x11_display = display->x11_display;
- MetaScreen *screen = display->screen;
int num_workspaces;
GList *l;
unsigned long *data, *tmp;
MetaRectangle area;
- num_workspaces = meta_screen_get_n_workspaces (screen);
+ num_workspaces = meta_display_get_n_workspaces (display);
data = g_new (unsigned long, num_workspaces * 4);
tmp = data;
- for (l = screen->workspaces; l; l = l->next)
+ for (l = display->workspaces; l; l = l->next)
{
MetaWorkspace *workspace = l->data;
@@ -3639,9 +3733,892 @@ meta_display_get_pointer_window (MetaDisplay *display,
meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL);
window = meta_stack_get_default_focus_window_at_point (display->stack,
- display->screen->active_workspace,
+ display->active_workspace,
not_this_one,
x, y);
return window;
}
+
+void
+meta_display_init_workspaces (MetaDisplay *display)
+{
+ MetaWorkspace *current_workspace;
+ uint32_t current_workspace_index = 0;
+ guint32 timestamp;
+
+ g_return_if_fail (META_IS_DISPLAY (display));
+
+ timestamp = display->x11_display->wm_sn_timestamp;
+
+ /* Get current workspace */
+ if (meta_prop_get_cardinal (display->x11_display,
+ display->x11_display->xroot,
+ display->x11_display->atom__NET_CURRENT_DESKTOP,
+ ¤t_workspace_index))
+ meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n",
+ (int) current_workspace_index);
+ else
+ meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
+
+ update_num_workspaces (display, timestamp);
+
+ set_workspace_names (display);
+
+ /* Switch to the _NET_CURRENT_DESKTOP workspace */
+ current_workspace = meta_display_get_workspace_by_index (display,
+ current_workspace_index);
+
+ if (current_workspace != NULL)
+ meta_workspace_activate (current_workspace, timestamp);
+ else
+ meta_workspace_activate (display->workspaces->data, timestamp);
+}
+
+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);
+
+ meta_x11_display_set_number_of_spaces_hint (display->x11_display, new_num);
+
+ 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)
+ meta_x11_display_set_active_workspace_hint (display->x11_display);
+
+ 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);
+
+ meta_x11_display_set_number_of_spaces_hint (display->x11_display, new_num);
+
+ 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;
+}
+
+static void
+update_num_workspaces (MetaDisplay *display,
+ guint32 timestamp)
+{
+ int new_num, old_num;
+ GList *l;
+ int i;
+ GList *extras;
+ MetaWorkspace *last_remaining;
+ gboolean need_change_space;
+
+ if (meta_prefs_get_dynamic_workspaces ())
+ {
+ int n_items;
+ uint32_t *list;
+
+ n_items = 0;
+ list = NULL;
+
+ if (meta_prop_get_cardinal_list (display->x11_display,
+ display->x11_display->xroot,
+ display->x11_display->atom__NET_NUMBER_OF_DESKTOPS,
+ &list, &n_items))
+ {
+ new_num = list[0];
+ meta_XFree (list);
+ }
+ else
+ {
+ new_num = 1;
+ }
+ }
+ else
+ {
+ new_num = meta_prefs_get_num_workspaces ();
+ }
+
+ g_assert (new_num > 0);
+
+ if (g_list_length (display->workspaces) == (guint) new_num)
+ return;
+
+ last_remaining = NULL;
+ extras = NULL;
+ i = 0;
+ 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 ;-)
+ */
+ need_change_space = FALSE;
+ 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_x11_display_set_number_of_spaces_hint (display->x11_display, new_num);
+
+ 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");
+}
+
+#define _NET_WM_ORIENTATION_HORZ 0
+#define _NET_WM_ORIENTATION_VERT 1
+
+#define _NET_WM_TOPLEFT 0
+#define _NET_WM_TOPRIGHT 1
+#define _NET_WM_BOTTOMRIGHT 2
+#define _NET_WM_BOTTOMLEFT 3
+
+void
+meta_display_update_workspace_layout (MetaDisplay *display)
+{
+ uint32_t *list;
+ int n_items;
+
+ if (display->workspace_layout_overridden)
+ return;
+
+ list = NULL;
+ n_items = 0;
+
+ if (meta_prop_get_cardinal_list (display->x11_display,
+ display->x11_display->xroot,
+ display->x11_display->atom__NET_DESKTOP_LAYOUT,
+ &list, &n_items))
+ {
+ if (n_items == 3 || n_items == 4)
+ {
+ int cols, rows;
+
+ switch (list[0])
+ {
+ case _NET_WM_ORIENTATION_HORZ:
+ display->vertical_workspaces = FALSE;
+ break;
+ case _NET_WM_ORIENTATION_VERT:
+ display->vertical_workspaces = TRUE;
+ break;
+ default:
+ meta_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n");
+ break;
+ }
+
+ cols = list[1];
+ rows = list[2];
+
+ if (rows <= 0 && cols <= 0)
+ {
+ meta_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols);
+ }
+ else
+ {
+ if (rows > 0)
+ display->rows_of_workspaces = rows;
+ else
+ display->rows_of_workspaces = -1;
+
+ if (cols > 0)
+ display->columns_of_workspaces = cols;
+ else
+ display->columns_of_workspaces = -1;
+ }
+
+ if (n_items == 4)
+ {
+ switch (list[3])
+ {
+ case _NET_WM_TOPLEFT:
+ display->starting_corner = META_DISPLAY_TOPLEFT;
+ break;
+ case _NET_WM_TOPRIGHT:
+ display->starting_corner = META_DISPLAY_TOPRIGHT;
+ break;
+ case _NET_WM_BOTTOMRIGHT:
+ display->starting_corner = META_DISPLAY_BOTTOMRIGHT;
+ break;
+ case _NET_WM_BOTTOMLEFT:
+ display->starting_corner = META_DISPLAY_BOTTOMLEFT;
+ break;
+ default:
+ meta_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n");
+ break;
+ }
+ }
+ else
+ display->starting_corner = META_DISPLAY_TOPLEFT;
+ }
+ else
+ {
+ meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 "
+ "(3 is accepted for backwards compat)\n", n_items);
+ }
+
+ meta_XFree (list);
+ }
+
+ 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)
+{
+ 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);
+
+ display->workspace_layout_overridden = TRUE;
+ display->vertical_workspaces = vertical_layout != FALSE;
+ display->starting_corner = starting_corner;
+ display->rows_of_workspaces = n_rows;
+ display->columns_of_workspaces = n_columns;
+
+ /* In theory we should remove _NET_DESKTOP_LAYOUT from _NET_SUPPORTED at this
+ * point, but it's unlikely that anybody checks that, and it's unlikely that
+ * anybody who checks that handles changes, so we'd probably just create
+ * a race condition. And it's hard to implement with the code in set_supported_hint()
+ */
+}
+
+static void
+set_workspace_names (MetaDisplay *display)
+{
+ /* This updates names on root window when the pref changes,
+ * note we only get prefs change notify if things have
+ * really changed.
+ */
+ MetaX11Display *x11_display = display->x11_display;
+ GString *flattened;
+ int i;
+ int n_spaces;
+
+ /* flatten to nul-separated list */
+ n_spaces = meta_display_get_n_workspaces (display);
+ flattened = g_string_new ("");
+ i = 0;
+ while (i < n_spaces)
+ {
+ const char *name;
+
+ name = meta_prefs_get_workspace_name (i);
+
+ if (name)
+ g_string_append_len (flattened, name,
+ strlen (name) + 1);
+ else
+ g_string_append_len (flattened, "", 1);
+
+ ++i;
+ }
+
+ meta_error_trap_push (x11_display);
+ XChangeProperty (x11_display->xdisplay,
+ x11_display->xroot,
+ x11_display->atom__NET_DESKTOP_NAMES,
+ x11_display->atom_UTF8_STRING,
+ 8, PropModeReplace,
+ (unsigned char *)flattened->str, flattened->len);
+ meta_error_trap_pop (x11_display);
+
+ g_string_free (flattened, 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;
+ }
+ }
+
+ meta_x11_display_update_showing_desktop_hint (display->x11_display);
+}
+
+void
+meta_display_unshow_desktop (MetaDisplay *display)
+{
+ if (!display->active_workspace->showing_desktop)
+ return;
+
+ display->active_workspace->showing_desktop = FALSE;
+
+ queue_windows_showing (display);
+
+ meta_x11_display_update_showing_desktop_hint (display->x11_display);
+}
+
+/**
+ * meta_display_get_workspaces: (skip)
+ * @display: a #MetaDisplay
+ *
+ * Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @display
+ */
+GList *
+meta_display_get_workspaces (MetaDisplay *display)
+{
+ return display->workspaces;
+}
+
+int
+meta_display_get_active_workspace_index (MetaDisplay *display)
+{
+ MetaWorkspace *active = display->active_workspace;
+
+ if (!active)
+ return -1;
+
+ return meta_workspace_index (active);
+}
+
+/**
+ * meta_display_get_active_workspace:
+ * @display: A #MetaDisplay
+ *
+ * Returns: (transfer none): The current workspace
+ */
+MetaWorkspace *
+meta_display_get_active_workspace (MetaDisplay *display)
+{
+ return display->active_workspace;
+}
+
+void
+meta_display_focus_default_window (MetaDisplay *display,
+ guint32 timestamp)
+{
+ meta_workspace_focus_default_window (display->active_workspace,
+ NULL,
+ timestamp);
+}
+
+void
+meta_display_workspace_switched (MetaDisplay *display,
+ int from,
+ int to,
+ MetaMotionDirection direction)
+{
+ g_signal_emit (display, display_signals[WORKSPACE_SWITCHED], 0,
+ from, to, direction);
+}
diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c
index 47ac4d1e0..1983904b4 100644
--- a/src/core/edge-resistance.c
+++ b/src/core/edge-resistance.c
@@ -1010,7 +1010,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
*/
stacked_windows =
meta_stack_list_windows (display->stack,
- display->screen->active_workspace);
+ display->active_workspace);
/*
* 2nd: we need to separate that stacked list into a list of windows that
@@ -1168,8 +1168,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
*/
cache_edges (display,
edges,
- display->screen->active_workspace->monitor_edges,
- display->screen->active_workspace->screen_edges);
+ display->active_workspace->monitor_edges,
+ display->active_workspace->screen_edges);
g_list_free (edges);
/*
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 5e68a4b09..85fb98910 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -2752,8 +2752,8 @@ handle_switch_to_last_workspace (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
- gint target = meta_screen_get_n_workspaces(screen) - 1;
- MetaWorkspace *workspace = meta_screen_get_workspace_by_index (screen, target);
+ gint target = meta_display_get_n_workspaces(display) - 1;
+ MetaWorkspace *workspace = meta_display_get_workspace_by_index (display, target);
meta_workspace_activate (workspace, event->time);
}
@@ -2774,12 +2774,12 @@ handle_switch_to_workspace (MetaDisplay *display,
* current workspace.
*/
- workspace = meta_workspace_get_neighbor (screen->active_workspace,
+ workspace = meta_workspace_get_neighbor (display->active_workspace,
which);
}
else
{
- workspace = meta_screen_get_workspace_by_index (screen, which);
+ workspace = meta_display_get_workspace_by_index (display, which);
}
if (workspace)
@@ -3016,15 +3016,15 @@ handle_show_desktop (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
- if (screen->active_workspace->showing_desktop)
+ if (display->active_workspace->showing_desktop)
{
- meta_screen_unshow_desktop (screen);
- meta_workspace_focus_default_window (screen->active_workspace,
+ meta_display_unshow_desktop (display);
+ meta_workspace_focus_default_window (display->active_workspace,
NULL,
event->time);
}
else
- meta_screen_show_desktop (screen, event->time);
+ meta_display_show_desktop (display, event->time);
}
static void
@@ -3122,7 +3122,7 @@ do_choose_window (MetaDisplay *display,
window = meta_display_get_tab_next (display,
type,
- screen->active_workspace,
+ display->active_workspace,
NULL,
backward);
@@ -3357,8 +3357,8 @@ handle_move_to_workspace_last (MetaDisplay *display,
if (window->always_sticky)
return;
- which = meta_screen_get_n_workspaces (screen) - 1;
- workspace = meta_screen_get_workspace_by_index (screen, which);
+ which = meta_display_get_n_workspaces (display) - 1;
+ workspace = meta_display_get_workspace_by_index (display, which);
meta_window_change_workspace (window, workspace);
}
@@ -3389,12 +3389,12 @@ handle_move_to_workspace (MetaDisplay *display,
workspace = NULL;
if (flip)
{
- workspace = meta_workspace_get_neighbor (screen->active_workspace,
+ workspace = meta_workspace_get_neighbor (display->active_workspace,
which);
}
else
{
- workspace = meta_screen_get_workspace_by_index (screen, which);
+ workspace = meta_display_get_workspace_by_index (display, which);
}
if (workspace)
@@ -3406,7 +3406,7 @@ handle_move_to_workspace (MetaDisplay *display,
meta_topic (META_DEBUG_FOCUS,
"Resetting mouse_mode to FALSE due to "
"handle_move_to_workspace() call with flip set.\n");
- meta_display_clear_mouse_mode (workspace->screen->display);
+ meta_display_clear_mouse_mode (workspace->display);
meta_workspace_activate_with_focus (workspace,
window,
event->time);
diff --git a/src/core/screen-private.h b/src/core/screen-private.h
index bc9406cd4..8e746e5a7 100644
--- a/src/core/screen-private.h
+++ b/src/core/screen-private.h
@@ -46,16 +46,6 @@ struct _MetaScreen
MetaDisplay *display;
- MetaWorkspace *active_workspace;
-
- GList *workspaces;
-
- int rows_of_workspaces;
- int columns_of_workspaces;
- MetaScreenCorner starting_corner;
- guint vertical_workspaces : 1;
- guint workspace_layout_overridden : 1;
-
int closing;
};
@@ -68,48 +58,7 @@ MetaScreen* meta_screen_new (MetaDisplay *displ
guint32 timestamp);
void meta_screen_free (MetaScreen *screen,
guint32 timestamp);
-void meta_screen_init_workspaces (MetaScreen *screen);
-void meta_screen_manage_all_windows (MetaScreen *screen);
-
-void meta_screen_update_workspace_layout (MetaScreen *screen);
-void meta_screen_update_workspace_names (MetaScreen *screen);
-
-typedef struct MetaWorkspaceLayout MetaWorkspaceLayout;
-
-struct MetaWorkspaceLayout
-{
- int rows;
- int cols;
- int *grid;
- int grid_area;
- int current_row;
- int current_col;
-};
-
-void meta_screen_calc_workspace_layout (MetaScreen *screen,
- int num_workspaces,
- int current_space,
- MetaWorkspaceLayout *layout);
-void meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout);
-
-void meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
- MetaWindow *keep);
-
-/* Show/hide the desktop (temporarily hide all windows) */
-void meta_screen_show_desktop (MetaScreen *screen,
- guint32 timestamp);
-void meta_screen_unshow_desktop (MetaScreen *screen);
-/* Update whether the destkop is being shown for the current active_workspace */
-void meta_screen_update_showing_desktop_hint (MetaScreen *screen);
-
-void meta_screen_workspace_switched (MetaScreen *screen,
- int from,
- int to,
- MetaMotionDirection direction);
-
-void meta_screen_set_active_workspace_hint (MetaScreen *screen);
-
-void meta_screen_on_monitors_changed (MetaScreen *screen);
+void meta_screen_manage_all_windows (MetaScreen *screen);
#endif
diff --git a/src/core/screen.c b/src/core/screen.c
index 003d082c5..f9da8102d 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -63,28 +63,6 @@
#include "backends/x11/meta-backend-x11.h"
#include "backends/meta-cursor-sprite-xcursor.h"
-static void update_num_workspaces (MetaScreen *screen,
- guint32 timestamp);
-static void set_workspace_names (MetaScreen *screen);
-static void prefs_changed_callback (MetaPreference pref,
- gpointer data);
-
-enum
-{
- PROP_N_WORKSPACES = 1,
-};
-
-enum
-{
- WORKSPACE_ADDED,
- WORKSPACE_REMOVED,
- WORKSPACE_SWITCHED,
-
- LAST_SIGNAL
-};
-
-static guint screen_signals[LAST_SIGNAL] = { 0 };
-
G_DEFINE_TYPE (MetaScreen, meta_screen, G_TYPE_OBJECT);
static void
@@ -111,13 +89,12 @@ meta_screen_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
+#if 0
MetaScreen *screen = META_SCREEN (object);
+#endif
switch (prop_id)
{
- case PROP_N_WORKSPACES:
- g_value_set_int (value, meta_screen_get_n_workspaces (screen));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -134,53 +111,10 @@ static void
meta_screen_class_init (MetaScreenClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
object_class->get_property = meta_screen_get_property;
object_class->set_property = meta_screen_set_property;
object_class->finalize = meta_screen_finalize;
-
- pspec = g_param_spec_int ("n-workspaces",
- "N Workspaces",
- "Number of workspaces",
- 1, G_MAXINT, 1,
- G_PARAM_READABLE);
-
- screen_signals[WORKSPACE_ADDED] =
- g_signal_new ("workspace-added",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 1,
- G_TYPE_INT);
-
- screen_signals[WORKSPACE_REMOVED] =
- g_signal_new ("workspace-removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 1,
- G_TYPE_INT);
-
- screen_signals[WORKSPACE_SWITCHED] =
- g_signal_new ("workspace-switched",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 3,
- G_TYPE_INT,
- G_TYPE_INT,
- META_TYPE_MOTION_DIRECTION);
-
- g_object_class_install_property (object_class,
- PROP_N_WORKSPACES,
- pspec);
}
static void
@@ -188,18 +122,6 @@ meta_screen_init (MetaScreen *screen)
{
}
-static void
-reload_logical_monitors (MetaScreen *screen)
-{
- GList *l;
-
- for (l = screen->workspaces; l != NULL; l = l->next)
- {
- MetaWorkspace *space = l->data;
- meta_workspace_invalidate_work_area (space);
- }
-}
-
MetaScreen*
meta_screen_new (MetaDisplay *display,
guint32 timestamp)
@@ -218,24 +140,6 @@ meta_screen_new (MetaDisplay *display,
screen->display = display;
- screen->active_workspace = NULL;
- screen->workspaces = NULL;
- screen->rows_of_workspaces = 1;
- screen->columns_of_workspaces = -1;
- screen->vertical_workspaces = FALSE;
- screen->starting_corner = META_SCREEN_TOPLEFT;
-
- reload_logical_monitors (screen);
-
- meta_screen_update_workspace_layout (screen);
-
- /* Screens must have at least one workspace at all times,
- * so create that required workspace.
- */
- meta_workspace_new (screen);
-
- meta_prefs_add_listener (prefs_changed_callback, screen);
-
meta_verbose ("Added screen %d ('%s') root 0x%lx\n",
number, display->x11_display->screen_name,
xroot);
@@ -243,957 +147,15 @@ meta_screen_new (MetaDisplay *display,
return screen;
}
-void
-meta_screen_init_workspaces (MetaScreen *screen)
-{
- MetaDisplay *display = screen->display;
- MetaWorkspace *current_workspace;
- uint32_t current_workspace_index = 0;
- guint32 timestamp;
-
- g_return_if_fail (META_IS_SCREEN (screen));
-
- timestamp = screen->display->x11_display->wm_sn_timestamp;
-
- /* Get current workspace */
- if (meta_prop_get_cardinal (display->x11_display,
- display->x11_display->xroot,
- display->x11_display->atom__NET_CURRENT_DESKTOP,
- ¤t_workspace_index))
- meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n",
- (int) current_workspace_index);
- else
- meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
-
- update_num_workspaces (screen, timestamp);
-
- set_workspace_names (screen);
-
- /* Switch to the _NET_CURRENT_DESKTOP workspace */
- current_workspace = meta_screen_get_workspace_by_index (screen,
- current_workspace_index);
-
- if (current_workspace != NULL)
- meta_workspace_activate (current_workspace, timestamp);
- else
- meta_workspace_activate (screen->workspaces->data, timestamp);
-}
-
void
meta_screen_free (MetaScreen *screen,
guint32 timestamp)
{
screen->closing += 1;
- meta_prefs_remove_listener (prefs_changed_callback, screen);
-
g_object_unref (screen);
}
-static void
-prefs_changed_callback (MetaPreference pref,
- gpointer data)
-{
- MetaScreen *screen = data;
-
- 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 (screen->display);
- update_num_workspaces (screen, timestamp);
- }
- else if (pref == META_PREF_WORKSPACE_NAMES)
- {
- set_workspace_names (screen);
- }
-}
-
-int
-meta_screen_get_n_workspaces (MetaScreen *screen)
-{
- return g_list_length (screen->workspaces);
-}
-
-/**
- * meta_screen_get_workspace_by_index:
- * @screen: a #MetaScreen
- * @index: index of one of the screen's workspaces
- *
- * Gets the workspace object for one of a screen'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_screen_get_workspace_by_index (MetaScreen *screen,
- int idx)
-{
- return g_list_nth_data (screen->workspaces, idx);
-}
-
-static void
-set_number_of_spaces_hint (MetaScreen *screen,
- int n_spaces)
-{
- MetaX11Display *x11_display = screen->display->x11_display;
- unsigned long data[1];
-
- if (screen->closing > 0)
- return;
-
- data[0] = n_spaces;
-
- meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]);
-
- meta_error_trap_push (x11_display);
- XChangeProperty (x11_display->xdisplay,
- x11_display->xroot,
- x11_display->atom__NET_NUMBER_OF_DESKTOPS,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (x11_display);
-}
-
-void
-meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
- guint32 timestamp)
-{
- GList *l;
- GList *next;
- MetaWorkspace *neighbour = NULL;
- int index;
- gboolean active_index_changed;
- int new_num;
-
- l = g_list_find (screen->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 == screen->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_screen_get_active_workspace_index (screen);
-
- /* This also removes the workspace from the screens list */
- meta_workspace_remove (workspace);
-
- new_num = g_list_length (screen->workspaces);
-
- set_number_of_spaces_hint (screen, new_num);
-
- 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)
- meta_screen_set_active_workspace_hint (screen);
-
- for (l = next; l != NULL; l = l->next)
- {
- MetaWorkspace *w = l->data;
- meta_workspace_index_changed (w);
- }
-
- meta_display_queue_workarea_recalc (screen->display);
-
- g_signal_emit (screen, screen_signals[WORKSPACE_REMOVED], 0, index);
- g_object_notify (G_OBJECT (screen), "n-workspaces");
-}
-
-/**
- * meta_screen_append_new_workspace:
- * @screen: a #MetaScreen
- * @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 screen and (optionally) switch to that
- * screen.
- *
- * Return value: (transfer none): the newly appended workspace.
- */
-MetaWorkspace *
-meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
- guint32 timestamp)
-{
- MetaWorkspace *w;
- int new_num;
-
- /* This also adds the workspace to the screen list */
- w = meta_workspace_new (screen);
-
- if (!w)
- return NULL;
-
- if (activate)
- meta_workspace_activate (w, timestamp);
-
- new_num = g_list_length (screen->workspaces);
-
- set_number_of_spaces_hint (screen, new_num);
-
- if (!meta_prefs_get_dynamic_workspaces ())
- meta_prefs_set_num_workspaces (new_num);
-
- meta_display_queue_workarea_recalc (screen->display);
-
- g_signal_emit (screen, screen_signals[WORKSPACE_ADDED],
- 0, meta_workspace_index (w));
- g_object_notify (G_OBJECT (screen), "n-workspaces");
-
- return w;
-}
-
-
-static void
-update_num_workspaces (MetaScreen *screen,
- guint32 timestamp)
-{
- MetaDisplay *display = screen->display;
- int new_num, old_num;
- GList *l;
- int i;
- GList *extras;
- MetaWorkspace *last_remaining;
- gboolean need_change_space;
-
- if (meta_prefs_get_dynamic_workspaces ())
- {
- int n_items;
- uint32_t *list;
-
- n_items = 0;
- list = NULL;
-
- if (meta_prop_get_cardinal_list (display->x11_display,
- display->x11_display->xroot,
- display->x11_display->atom__NET_NUMBER_OF_DESKTOPS,
- &list, &n_items))
- {
- new_num = list[0];
- meta_XFree (list);
- }
- else
- {
- new_num = 1;
- }
- }
- else
- {
- new_num = meta_prefs_get_num_workspaces ();
- }
-
- g_assert (new_num > 0);
-
- if (g_list_length (screen->workspaces) == (guint) new_num)
- {
- if (screen->display->display_opening)
- set_number_of_spaces_hint (screen, new_num);
- return;
- }
-
- last_remaining = NULL;
- extras = NULL;
- i = 0;
- for (l = screen->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 ;-)
- */
- need_change_space = FALSE;
- for (l = extras; l != NULL; l = l->next)
- {
- MetaWorkspace *w = l->data;
-
- meta_workspace_relocate_windows (w, last_remaining);
-
- if (w == screen->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 (screen);
-
- set_number_of_spaces_hint (screen, new_num);
-
- meta_display_queue_workarea_recalc (display);
-
- for (i = old_num; i < new_num; i++)
- g_signal_emit (screen, screen_signals[WORKSPACE_ADDED], 0, i);
-
- g_object_notify (G_OBJECT (screen), "n-workspaces");
-}
-
-#define _NET_WM_ORIENTATION_HORZ 0
-#define _NET_WM_ORIENTATION_VERT 1
-
-#define _NET_WM_TOPLEFT 0
-#define _NET_WM_TOPRIGHT 1
-#define _NET_WM_BOTTOMRIGHT 2
-#define _NET_WM_BOTTOMLEFT 3
-
-void
-meta_screen_update_workspace_layout (MetaScreen *screen)
-{
- uint32_t *list;
- int n_items;
- MetaDisplay *display = screen->display;
-
- if (screen->workspace_layout_overridden)
- return;
-
- list = NULL;
- n_items = 0;
-
- if (meta_prop_get_cardinal_list (display->x11_display,
- display->x11_display->xroot,
- display->x11_display->atom__NET_DESKTOP_LAYOUT,
- &list, &n_items))
- {
- if (n_items == 3 || n_items == 4)
- {
- int cols, rows;
-
- switch (list[0])
- {
- case _NET_WM_ORIENTATION_HORZ:
- screen->vertical_workspaces = FALSE;
- break;
- case _NET_WM_ORIENTATION_VERT:
- screen->vertical_workspaces = TRUE;
- break;
- default:
- meta_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n");
- break;
- }
-
- cols = list[1];
- rows = list[2];
-
- if (rows <= 0 && cols <= 0)
- {
- meta_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols);
- }
- else
- {
- if (rows > 0)
- screen->rows_of_workspaces = rows;
- else
- screen->rows_of_workspaces = -1;
-
- if (cols > 0)
- screen->columns_of_workspaces = cols;
- else
- screen->columns_of_workspaces = -1;
- }
-
- if (n_items == 4)
- {
- switch (list[3])
- {
- case _NET_WM_TOPLEFT:
- screen->starting_corner = META_SCREEN_TOPLEFT;
- break;
- case _NET_WM_TOPRIGHT:
- screen->starting_corner = META_SCREEN_TOPRIGHT;
- break;
- case _NET_WM_BOTTOMRIGHT:
- screen->starting_corner = META_SCREEN_BOTTOMRIGHT;
- break;
- case _NET_WM_BOTTOMLEFT:
- screen->starting_corner = META_SCREEN_BOTTOMLEFT;
- break;
- default:
- meta_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n");
- break;
- }
- }
- else
- screen->starting_corner = META_SCREEN_TOPLEFT;
- }
- else
- {
- meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 "
- "(3 is accepted for backwards compat)\n", n_items);
- }
-
- meta_XFree (list);
- }
-
- meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n",
- screen->rows_of_workspaces,
- screen->columns_of_workspaces,
- screen->vertical_workspaces,
- screen->starting_corner);
-}
-
-/**
- * meta_screen_override_workspace_layout:
- * @screen: a #MetaScreen
- * @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_screen_override_workspace_layout (MetaScreen *screen,
- MetaScreenCorner starting_corner,
- gboolean vertical_layout,
- int n_rows,
- int n_columns)
-{
- g_return_if_fail (META_IS_SCREEN (screen));
- g_return_if_fail (n_rows > 0 || n_columns > 0);
- g_return_if_fail (n_rows != 0 && n_columns != 0);
-
- screen->workspace_layout_overridden = TRUE;
- screen->vertical_workspaces = vertical_layout != FALSE;
- screen->starting_corner = starting_corner;
- screen->rows_of_workspaces = n_rows;
- screen->columns_of_workspaces = n_columns;
-
- /* In theory we should remove _NET_DESKTOP_LAYOUT from _NET_SUPPORTED at this
- * point, but it's unlikely that anybody checks that, and it's unlikely that
- * anybody who checks that handles changes, so we'd probably just create
- * a race condition. And it's hard to implement with the code in set_supported_hint()
- */
-}
-
-static void
-set_workspace_names (MetaScreen *screen)
-{
- /* This updates names on root window when the pref changes,
- * note we only get prefs change notify if things have
- * really changed.
- */
- MetaX11Display *x11_display = screen->display->x11_display;
- GString *flattened;
- int i;
- int n_spaces;
-
- /* flatten to nul-separated list */
- n_spaces = meta_screen_get_n_workspaces (screen);
- flattened = g_string_new ("");
- i = 0;
- while (i < n_spaces)
- {
- const char *name;
-
- name = meta_prefs_get_workspace_name (i);
-
- if (name)
- g_string_append_len (flattened, name,
- strlen (name) + 1);
- else
- g_string_append_len (flattened, "", 1);
-
- ++i;
- }
-
- meta_error_trap_push (x11_display);
- XChangeProperty (x11_display->xdisplay,
- x11_display->xroot,
- x11_display->atom__NET_DESKTOP_NAMES,
- x11_display->atom_UTF8_STRING,
- 8, PropModeReplace,
- (unsigned char *)flattened->str, flattened->len);
- meta_error_trap_pop (x11_display);
-
- g_string_free (flattened, TRUE);
-}
-
-void
-meta_screen_update_workspace_names (MetaScreen *screen)
-{
- MetaX11Display *x11_display = screen->display->x11_display;
- char **names;
- int n_names;
- int i;
-
- /* this updates names in prefs when the root window property changes,
- * iff the new property contents don't match what's already in prefs
- */
-
- names = NULL;
- n_names = 0;
- if (!meta_prop_get_utf8_list (x11_display,
- x11_display->xroot,
- x11_display->atom__NET_DESKTOP_NAMES,
- &names, &n_names))
- {
- meta_verbose ("Failed to get workspace names from root window\n");
- return;
- }
-
- i = 0;
- while (i < n_names)
- {
- meta_topic (META_DEBUG_PREFS,
- "Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n",
- i, names[i] ? names[i] : "null");
- meta_prefs_change_workspace_name (i, names[i]);
-
- ++i;
- }
-
- g_strfreev (names);
-}
-
-#ifdef WITH_VERBOSE_MODE
-static const char *
-meta_screen_corner_to_string (MetaScreenCorner corner)
-{
- switch (corner)
- {
- case META_SCREEN_TOPLEFT:
- return "TopLeft";
- case META_SCREEN_TOPRIGHT:
- return "TopRight";
- case META_SCREEN_BOTTOMLEFT:
- return "BottomLeft";
- case META_SCREEN_BOTTOMRIGHT:
- return "BottomRight";
- }
-
- return "Unknown";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_screen_calc_workspace_layout (MetaScreen *screen,
- 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 = screen->rows_of_workspaces;
- cols = screen->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,
- screen->vertical_workspaces ? "(true)" : "(false)",
- meta_screen_corner_to_string (screen->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_SCREEN_TOPLEFT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 1234 1357
- * 5678 2468
- *
- * starting_corner = META_SCREEN_TOPRIGHT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 4321 7531
- * 8765 8642
- *
- * starting_corner = META_SCREEN_BOTTOMLEFT
- * vertical_workspaces = 0 vertical_workspaces=1
- * 5678 2468
- * 1234 1357
- *
- * starting_corner = META_SCREEN_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 (screen->starting_corner)
- {
- case META_SCREEN_TOPLEFT:
- if (screen->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_SCREEN_TOPRIGHT:
- if (screen->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_SCREEN_BOTTOMLEFT:
- if (screen->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_SCREEN_BOTTOMRIGHT:
- if (screen->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_screen_free_workspace_layout (MetaWorkspaceLayout *layout)
-{
- g_free (layout->grid);
-}
-
-void
-meta_screen_on_monitors_changed (MetaScreen *screen)
-{
- reload_logical_monitors (screen);
-}
-
-void
-meta_screen_update_showing_desktop_hint (MetaScreen *screen)
-{
- MetaX11Display *x11_display = screen->display->x11_display;
- unsigned long data[1];
-
- data[0] = screen->active_workspace->showing_desktop ? 1 : 0;
-
- meta_error_trap_push (x11_display);
- XChangeProperty (x11_display->xdisplay,
- x11_display->xroot,
- x11_display->atom__NET_SHOWING_DESKTOP,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (x11_display);
-}
-
-static void
-queue_windows_showing (MetaScreen *screen)
-{
- 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 (screen->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_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
- MetaWindow *keep)
-{
- GList *l;
-
- for (l = screen->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_screen_show_desktop (MetaScreen *screen,
- guint32 timestamp)
-{
- GList *l;
-
- if (screen->active_workspace->showing_desktop)
- return;
-
- screen->active_workspace->showing_desktop = TRUE;
-
- queue_windows_showing (screen);
-
- /* Focus the most recently used META_WINDOW_DESKTOP window, if there is one;
- * see bug 159257.
- */
- for (l = screen->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;
- }
- }
-
- meta_screen_update_showing_desktop_hint (screen);
-}
-
-void
-meta_screen_unshow_desktop (MetaScreen *screen)
-{
- if (!screen->active_workspace->showing_desktop)
- return;
-
- screen->active_workspace->showing_desktop = FALSE;
-
- queue_windows_showing (screen);
-
- meta_screen_update_showing_desktop_hint (screen);
-}
-
/**
* meta_screen_get_display:
* @screen: A #MetaScreen
@@ -1207,86 +169,3 @@ meta_screen_get_display (MetaScreen *screen)
{
return screen->display;
}
-
-/**
- * meta_screen_get_workspaces: (skip)
- * @screen: a #MetaScreen
- *
- * Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @screen
- */
-GList *
-meta_screen_get_workspaces (MetaScreen *screen)
-{
- return screen->workspaces;
-}
-
-int
-meta_screen_get_active_workspace_index (MetaScreen *screen)
-{
- MetaWorkspace *active = screen->active_workspace;
-
- if (!active)
- return -1;
-
- return meta_workspace_index (active);
-}
-
-/**
- * meta_screen_get_active_workspace:
- * @screen: A #MetaScreen
- *
- * Returns: (transfer none): The current workspace
- */
-MetaWorkspace *
-meta_screen_get_active_workspace (MetaScreen *screen)
-{
- return screen->active_workspace;
-}
-
-void
-meta_screen_focus_default_window (MetaScreen *screen,
- guint32 timestamp)
-{
- meta_workspace_focus_default_window (screen->active_workspace,
- NULL,
- timestamp);
-}
-
-void
-meta_screen_workspace_switched (MetaScreen *screen,
- int from,
- int to,
- MetaMotionDirection direction)
-{
- g_signal_emit (screen, screen_signals[WORKSPACE_SWITCHED], 0,
- from, to, direction);
-}
-
-void
-meta_screen_set_active_workspace_hint (MetaScreen *screen)
-{
- MetaX11Display *x11_display = screen->display->x11_display;
-
- unsigned long data[1];
-
- /* this is because we destroy the spaces in order,
- * so we always end up setting a current desktop of
- * 0 when closing a screen, so lose the current desktop
- * on restart. By doing this we keep the current
- * desktop on restart.
- */
- if (screen->closing > 0)
- return;
-
- data[0] = meta_workspace_index (screen->active_workspace);
-
- meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
-
- meta_error_trap_push (x11_display);
- XChangeProperty (x11_display->xdisplay,
- x11_display->xroot,
- x11_display->atom__NET_CURRENT_DESKTOP,
- XA_CARDINAL,
- 32, PropModeReplace, (guchar*) data, 1);
- meta_error_trap_pop (x11_display);
-}
diff --git a/src/core/stack.c b/src/core/stack.c
index a9cd9aa32..2e64698db 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -117,7 +117,7 @@ meta_stack_add (MetaStack *stack,
window->desc, window->stack_position);
stack_sync_to_xserver (stack);
- meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
+ meta_stack_update_window_tile_matches (stack, window->display->active_workspace);
}
void
@@ -153,7 +153,7 @@ meta_stack_remove (MetaStack *stack,
}
stack_sync_to_xserver (stack);
- meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
+ meta_stack_update_window_tile_matches (stack, window->display->active_workspace);
}
void
@@ -163,7 +163,7 @@ meta_stack_update_layer (MetaStack *stack,
stack->need_relayer = TRUE;
stack_sync_to_xserver (stack);
- meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
+ meta_stack_update_window_tile_matches (stack, window->display->active_workspace);
}
void
@@ -173,7 +173,7 @@ meta_stack_update_transient (MetaStack *stack,
stack->need_constrain = TRUE;
stack_sync_to_xserver (stack);
- meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
+ meta_stack_update_window_tile_matches (stack, window->display->active_workspace);
}
/* raise/lower within a layer */
@@ -202,7 +202,7 @@ meta_stack_raise (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, max_stack_position);
stack_sync_to_xserver (stack);
- meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
+ meta_stack_update_window_tile_matches (stack, window->display->active_workspace);
}
void
@@ -230,7 +230,7 @@ meta_stack_lower (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, min_stack_position);
stack_sync_to_xserver (stack);
- meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
+ meta_stack_update_window_tile_matches (stack, window->display->active_workspace);
}
void
@@ -1465,5 +1465,5 @@ meta_window_set_stack_position (MetaWindow *window,
meta_window_set_stack_position_no_sync (window, position);
stack_sync_to_xserver (window->display->stack);
meta_stack_update_window_tile_matches (window->display->stack,
- window->screen->active_workspace);
+ window->display->active_workspace);
}
diff --git a/src/core/window.c b/src/core/window.c
index 97a78601d..2a1c20d3c 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -689,7 +689,7 @@ maybe_leave_show_desktop_mode (MetaWindow *window)
{
gboolean is_desktop_or_dock;
- if (!window->screen->active_workspace->showing_desktop)
+ if (!window->display->active_workspace->showing_desktop)
return;
/* If the window is a transient for the dock or desktop, don't
@@ -706,9 +706,9 @@ maybe_leave_show_desktop_mode (MetaWindow *window)
if (!is_desktop_or_dock)
{
- meta_screen_minimize_all_on_active_workspace_except (window->screen,
- window);
- meta_screen_unshow_desktop (window->screen);
+ meta_display_minimize_all_on_active_workspace_except (window->display,
+ window);
+ meta_display_unshow_desktop (window->display);
}
}
@@ -1244,8 +1244,8 @@ _meta_window_shared_new (MetaDisplay *display,
"Window %s is initially on space %d\n",
window->desc, window->initial_workspace);
- workspace = meta_screen_get_workspace_by_index (window->screen,
- window->initial_workspace);
+ workspace = meta_display_get_workspace_by_index (window->display,
+ window->initial_workspace);
}
set_workspace_state (window, on_all_workspaces, workspace);
@@ -1284,7 +1284,7 @@ _meta_window_shared_new (MetaDisplay *display,
"Putting window %s on active workspace\n",
window->desc);
- set_workspace_state (window, FALSE, window->screen->active_workspace);
+ set_workspace_state (window, FALSE, window->display->active_workspace);
}
meta_window_update_struts (window);
@@ -1470,7 +1470,7 @@ meta_window_unmanage (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"Focusing default window since we're unmanaging %s\n",
window->desc);
- meta_workspace_focus_default_window (window->screen->active_workspace, NULL, timestamp);
+ meta_workspace_focus_default_window (window->display->active_workspace, NULL, timestamp);
}
else
{
@@ -1516,7 +1516,7 @@ meta_window_unmanage (MetaWindow *window,
g_assert (window->workspace == NULL);
#ifndef G_DISABLE_CHECKS
- tmp = window->screen->workspaces;
+ tmp = window->display->workspaces;
while (tmp != NULL)
{
MetaWorkspace *workspace = tmp->data;
@@ -1647,7 +1647,7 @@ meta_window_showing_on_its_workspace (MetaWindow *window)
&is_desktop_or_dock);
if (window->on_all_workspaces)
- workspace_of_window = window->screen->active_workspace;
+ workspace_of_window = window->display->active_workspace;
else if (window->workspace)
workspace_of_window = window->workspace;
else /* This only seems to be needed for startup */
@@ -1687,7 +1687,7 @@ meta_window_should_be_showing (MetaWindow *window)
/* Windows should be showing if they're located on the
* active workspace and they're showing on their own workspace. */
- return (meta_window_located_on_workspace (window, window->screen->active_workspace) &&
+ return (meta_window_located_on_workspace (window, window->display->active_workspace) &&
meta_window_showing_on_its_workspace (window));
}
@@ -2630,11 +2630,11 @@ meta_window_hide (MetaWindow *window)
* We also pass in NULL if we are in the process of hiding all non-desktop
* windows to avoid unexpected changes to the stacking order.
*/
- if (my_workspace == window->screen->active_workspace &&
+ if (my_workspace == window->display->active_workspace &&
!my_workspace->showing_desktop)
not_this_one = window;
- meta_workspace_focus_default_window (window->screen->active_workspace,
+ meta_workspace_focus_default_window (window->display->active_workspace,
not_this_one,
timestamp);
}
@@ -3641,7 +3641,7 @@ meta_window_activate_full (MetaWindow *window,
/* Get window on current or given workspace */
if (workspace == NULL)
- workspace = window->screen->active_workspace;
+ workspace = window->display->active_workspace;
/* For non-transient windows, we just set up a pulsing indicator,
rather than move windows or workspaces.
@@ -3869,8 +3869,8 @@ meta_window_update_monitor (MetaWindow *window,
*/
if (meta_prefs_get_workspaces_only_on_primary () && user_op &&
meta_window_is_on_primary_monitor (window) &&
- window->screen->active_workspace != window->workspace)
- meta_window_change_workspace (window, window->screen->active_workspace);
+ window->display->active_workspace != window->workspace)
+ meta_window_change_workspace (window, window->display->active_workspace);
meta_window_main_monitor_changed (window, old);
@@ -4036,7 +4036,7 @@ meta_window_move_resize_internal (MetaWindow *window,
meta_window_foreach_transient (window, maybe_move_attached_dialog, NULL);
meta_stack_update_window_tile_matches (window->display->stack,
- window->screen->active_workspace);
+ window->display->active_workspace);
}
/**
@@ -4642,8 +4642,8 @@ meta_window_focus (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"%s has %s as a modal transient, so focusing it instead.\n",
window->desc, modal_transient->desc);
- if (!meta_window_located_on_workspace (modal_transient, window->screen->active_workspace))
- meta_window_change_workspace (modal_transient, window->screen->active_workspace);
+ if (!meta_window_located_on_workspace (modal_transient, window->display->active_workspace))
+ meta_window_change_workspace (modal_transient, window->display->active_workspace);
window = modal_transient;
}
@@ -4714,7 +4714,7 @@ set_workspace_state (MetaWindow *window,
else if (window->on_all_workspaces)
{
GList *l;
- for (l = window->screen->workspaces; l != NULL; l = l->next)
+ for (l = window->display->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *ws = l->data;
meta_workspace_remove_window (ws, window);
@@ -4729,7 +4729,7 @@ set_workspace_state (MetaWindow *window,
else if (window->on_all_workspaces)
{
GList *l;
- for (l = window->screen->workspaces; l != NULL; l = l->next)
+ for (l = window->display->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *ws = l->data;
meta_workspace_add_window (ws, window);
@@ -4786,7 +4786,7 @@ meta_window_on_all_workspaces_changed (MetaWindow *window)
{
/* We're coming out of the sticky state. Put the window on
* the currently active workspace. */
- workspace = window->screen->active_workspace;
+ workspace = window->display->active_workspace;
}
set_workspace_state (window, on_all_workspaces, workspace);
@@ -5010,7 +5010,7 @@ meta_window_change_workspace_by_index (MetaWindow *window,
gboolean append)
{
MetaWorkspace *workspace;
- MetaScreen *screen;
+ MetaDisplay *display;
g_return_if_fail (!window->override_redirect);
@@ -5020,13 +5020,13 @@ meta_window_change_workspace_by_index (MetaWindow *window,
return;
}
- screen = window->screen;
+ display = window->display;
workspace =
- meta_screen_get_workspace_by_index (screen, space_index);
+ meta_display_get_workspace_by_index (display, space_index);
if (!workspace && append)
- workspace = meta_screen_append_new_workspace (screen, FALSE, CurrentTime);
+ workspace = meta_display_append_new_workspace (display, FALSE, CurrentTime);
if (workspace)
meta_window_change_workspace (window, workspace);
@@ -5140,22 +5140,22 @@ meta_window_set_focused_internal (MetaWindow *window,
* list only if the window is actually on the active
* workspace.
*/
- if (window->screen->active_workspace &&
+ if (window->display->active_workspace &&
meta_window_located_on_workspace (window,
- window->screen->active_workspace))
+ window->display->active_workspace))
{
GList* link;
- link = g_list_find (window->screen->active_workspace->mru_list,
+ link = g_list_find (window->display->active_workspace->mru_list,
window);
g_assert (link);
- window->screen->active_workspace->mru_list =
- g_list_remove_link (window->screen->active_workspace->mru_list,
+ window->display->active_workspace->mru_list =
+ g_list_remove_link (window->display->active_workspace->mru_list,
link);
g_list_free (link);
- window->screen->active_workspace->mru_list =
- g_list_prepend (window->screen->active_workspace->mru_list,
+ window->display->active_workspace->mru_list =
+ g_list_prepend (window->display->active_workspace->mru_list,
window);
}
@@ -5399,7 +5399,7 @@ GList*
meta_window_get_workspaces (MetaWindow *window)
{
if (window->on_all_workspaces)
- return window->screen->workspaces;
+ return window->display->workspaces;
else if (window->workspace != NULL)
return window->workspace->list_containing_self;
else if (window->constructing)
@@ -5764,7 +5764,7 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window)
/* Get the basic info we need */
meta_window_get_frame_rect (window, &frame_rect);
- onscreen_region = window->screen->active_workspace->screen_region;
+ onscreen_region = window->display->active_workspace->screen_region;
/* Extend the region (just in case the window is too big to fit on the
* screen), then shove the window on screen, then return the region to
@@ -5816,7 +5816,7 @@ meta_window_titlebar_is_onscreen (MetaWindow *window)
* them overlaps with the titlebar sufficiently to consider it onscreen.
*/
is_onscreen = FALSE;
- onscreen_region = window->screen->active_workspace->screen_region;
+ onscreen_region = window->display->active_workspace->screen_region;
while (onscreen_region)
{
MetaRectangle *spanning_rect = onscreen_region->data;
@@ -6885,7 +6885,7 @@ ensure_mru_position_after (MetaWindow *window,
GList* window_position;
GList* after_this_one_position;
- active_mru_list = window->screen->active_workspace->mru_list;
+ active_mru_list = window->display->active_workspace->mru_list;
window_position = g_list_find (active_mru_list, window);
after_this_one_position = g_list_find (active_mru_list, after_this_one);
@@ -6898,12 +6898,12 @@ ensure_mru_position_after (MetaWindow *window,
if (g_list_length (window_position) > g_list_length (after_this_one_position))
{
- window->screen->active_workspace->mru_list =
- g_list_delete_link (window->screen->active_workspace->mru_list,
+ window->display->active_workspace->mru_list =
+ g_list_delete_link (window->display->active_workspace->mru_list,
window_position);
- window->screen->active_workspace->mru_list =
- g_list_insert_before (window->screen->active_workspace->mru_list,
+ window->display->active_workspace->mru_list =
+ g_list_insert_before (window->display->active_workspace->mru_list,
after_this_one_position->next,
window);
}
@@ -7056,7 +7056,7 @@ meta_window_set_demands_attention (MetaWindow *window)
MetaWindow *other_window;
gboolean obscured = FALSE;
- MetaWorkspace *workspace = window->screen->active_workspace;
+ MetaWorkspace *workspace = window->display->active_workspace;
if (window->wm_state_demands_attention)
return;
@@ -7257,7 +7257,7 @@ MetaWorkspace *
meta_window_get_workspace (MetaWindow *window)
{
if (window->on_all_workspaces)
- return window->screen->active_workspace;
+ return window->display->active_workspace;
else
return window->workspace;
}
diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h
index 54d9db01f..f63be9550 100644
--- a/src/core/workspace-private.h
+++ b/src/core/workspace-private.h
@@ -37,7 +37,7 @@
struct _MetaWorkspace
{
GObject parent_instance;
- MetaScreen *screen;
+ MetaDisplay *display;
GList *windows;
@@ -72,7 +72,7 @@ struct _MetaWorkspaceClass
GObjectClass parent_class;
};
-MetaWorkspace* meta_workspace_new (MetaScreen *screen);
+MetaWorkspace* meta_workspace_new (MetaDisplay *display);
void meta_workspace_remove (MetaWorkspace *workspace);
void meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window);
diff --git a/src/core/workspace.c b/src/core/workspace.c
index ea036bdc9..adb926081 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -34,7 +34,7 @@
#include <config.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
-#include "screen-private.h"
+#include "x11/meta-x11-display-private.h"
#include <meta/workspace.h>
#include "workspace-private.h"
#include "boxes-private.h"
@@ -223,16 +223,16 @@ meta_workspace_init (MetaWorkspace *workspace)
}
MetaWorkspace*
-meta_workspace_new (MetaScreen *screen)
+meta_workspace_new (MetaDisplay *display)
{
MetaWorkspace *workspace;
GSList *windows, *l;
workspace = g_object_new (META_TYPE_WORKSPACE, NULL);
- workspace->screen = screen;
- workspace->screen->workspaces =
- g_list_append (workspace->screen->workspaces, workspace);
+ workspace->display = display;
+ workspace->display->workspaces =
+ g_list_append (workspace->display->workspaces, workspace);
workspace->windows = NULL;
workspace->mru_list = NULL;
@@ -253,7 +253,7 @@ meta_workspace_new (MetaScreen *screen)
workspace->showing_desktop = FALSE;
/* make sure sticky windows are in our mru_list */
- windows = meta_display_list_windows (screen->display, META_LIST_SORTED);
+ windows = meta_display_list_windows (display, META_LIST_SORTED);
for (l = windows; l; l = l->next)
if (meta_window_located_on_workspace (l->data, workspace))
meta_workspace_add_window (workspace, l->data);
@@ -319,12 +319,12 @@ assert_workspace_empty (MetaWorkspace *workspace)
void
meta_workspace_remove (MetaWorkspace *workspace)
{
- g_return_if_fail (workspace != workspace->screen->active_workspace);
+ g_return_if_fail (workspace != workspace->display->active_workspace);
assert_workspace_empty (workspace);
- workspace->screen->workspaces =
- g_list_remove (workspace->screen->workspaces, workspace);
+ workspace->display->workspaces =
+ g_list_remove (workspace->display->workspaces, workspace);
meta_workspace_clear_logical_monitor_data (workspace);
@@ -439,14 +439,14 @@ workspace_switch_sound(MetaWorkspace *from,
int i, nw, x, y, fi, ti;
const char *e;
- nw = meta_screen_get_n_workspaces(from->screen);
+ nw = meta_display_get_n_workspaces(from->display);
fi = meta_workspace_index(from);
ti = meta_workspace_index(to);
- meta_screen_calc_workspace_layout(from->screen,
- nw,
- fi,
- &layout);
+ meta_display_calc_workspace_layout(from->display,
+ nw,
+ fi,
+ &layout);
for (i = 0; i < nw; i++)
if (layout.grid[i] == ti)
@@ -489,7 +489,7 @@ workspace_switch_sound(MetaWorkspace *from,
NULL);
finish:
- meta_screen_free_workspace_layout (&layout);
+ meta_display_free_workspace_layout (&layout);
#endif /* HAVE_LIBCANBERRA */
}
@@ -519,7 +519,6 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
{
MetaWorkspace *old;
MetaWindow *move_window;
- MetaScreen *screen;
MetaDisplay *display;
MetaCompositor *comp;
MetaWorkspaceLayout layout1, layout2;
@@ -529,36 +528,36 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
meta_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace));
- if (workspace->screen->active_workspace == workspace)
+ if (workspace->display->active_workspace == workspace)
return;
/* Free any cached pointers to the workspaces's edges from
* a current resize or move operation */
- meta_display_cleanup_edges (workspace->screen->display);
+ meta_display_cleanup_edges (workspace->display);
- if (workspace->screen->active_workspace)
- workspace_switch_sound (workspace->screen->active_workspace, workspace);
+ if (workspace->display->active_workspace)
+ workspace_switch_sound (workspace->display->active_workspace, workspace);
/* Note that old can be NULL; e.g. when starting up */
- old = workspace->screen->active_workspace;
+ old = workspace->display->active_workspace;
- workspace->screen->active_workspace = workspace;
+ workspace->display->active_workspace = workspace;
- meta_screen_set_active_workspace_hint (workspace->screen);
+ meta_x11_display_set_active_workspace_hint (workspace->display->x11_display);
/* If the "show desktop" mode is active for either the old workspace
* or the new one *but not both*, then update the
* _net_showing_desktop hint
*/
if (old && (old->showing_desktop != workspace->showing_desktop))
- meta_screen_update_showing_desktop_hint (workspace->screen);
+ meta_x11_display_update_showing_desktop_hint (workspace->display->x11_display);
if (old == NULL)
return;
move_window = NULL;
- if (meta_grab_op_is_moving (workspace->screen->display->grab_op))
- move_window = workspace->screen->display->grab_window;
+ if (meta_grab_op_is_moving (workspace->display->grab_op))
+ move_window = workspace->display->grab_window;
if (move_window != NULL)
{
@@ -579,19 +578,18 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/*
* Notify the compositor that the active workspace is changing.
*/
- screen = workspace->screen;
- display = meta_screen_get_display (screen);
+ display = workspace->display;
comp = meta_display_get_compositor (display);
direction = 0;
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
- num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
- meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
- current_space, &layout1);
+ num_workspaces = meta_display_get_n_workspaces (workspace->display);
+ meta_display_calc_workspace_layout (workspace->display, num_workspaces,
+ current_space, &layout1);
- meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
- new_space, &layout2);
+ meta_display_calc_workspace_layout (workspace->display, num_workspaces,
+ new_space, &layout2);
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
{
@@ -628,8 +626,8 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
direction = META_MOTION_UP_LEFT;
}
- meta_screen_free_workspace_layout (&layout1);
- meta_screen_free_workspace_layout (&layout2);
+ meta_display_free_workspace_layout (&layout1);
+ meta_display_free_workspace_layout (&layout2);
meta_compositor_switch_workspace (comp, old, workspace, direction);
@@ -653,7 +651,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
}
/* Emit switched signal from screen.c */
- meta_screen_workspace_switched (screen, current_space, new_space, direction);
+ meta_display_workspace_switched (display, current_space, new_space, direction);
}
void
@@ -668,7 +666,7 @@ meta_workspace_index (MetaWorkspace *workspace)
{
int ret;
- ret = g_list_index (workspace->screen->workspaces, workspace);
+ ret = g_list_index (workspace->display->workspaces, workspace);
if (ret < 0)
meta_bug ("Workspace does not exist to index!\n");
@@ -704,7 +702,7 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
GSList *display_windows, *l;
GList *workspace_windows;
- display_windows = meta_display_list_windows (workspace->screen->display,
+ display_windows = meta_display_list_windows (workspace->display,
META_LIST_DEFAULT);
workspace_windows = NULL;
@@ -741,8 +739,8 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
/* If we are in the middle of a resize or move operation, we
* might have cached pointers to the workspace's edges */
- if (workspace == workspace->screen->active_workspace)
- meta_display_cleanup_edges (workspace->screen->display);
+ if (workspace == workspace->display->active_workspace)
+ meta_display_cleanup_edges (workspace->display);
meta_workspace_clear_logical_monitor_data (workspace);
@@ -768,7 +766,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
g_list_free (windows);
- meta_display_queue_workarea_recalc (workspace->screen->display);
+ meta_display_queue_workarea_recalc (workspace->display);
}
static MetaStrut *
@@ -849,13 +847,13 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
workspace->screen_region =
meta_rectangle_get_minimal_spanning_set_for_region (
- &workspace->screen->display->rect,
+ &workspace->display->rect,
workspace->all_struts);
/* STEP 3: Get the work areas (region-to-maximize-to) for the screen and
* monitors.
*/
- work_area = workspace->screen->display->rect; /* start with the screen */
+ work_area = workspace->display->rect; /* start with the screen */
if (workspace->screen_region == NULL)
work_area = meta_rect (0, 0, -1, -1);
else
@@ -872,7 +870,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
work_area.width, MIN_SANE_AREA);
if (work_area.width < 1)
{
- work_area.x = (workspace->screen->display->rect.width - MIN_SANE_AREA)/2;
+ work_area.x = (workspace->display->rect.width - MIN_SANE_AREA)/2;
work_area.width = MIN_SANE_AREA;
}
else
@@ -889,7 +887,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
work_area.height, MIN_SANE_AREA);
if (work_area.height < 1)
{
- work_area.y = (workspace->screen->display->rect.height - MIN_SANE_AREA)/2;
+ work_area.y = (workspace->display->rect.height - MIN_SANE_AREA)/2;
work_area.height = MIN_SANE_AREA;
}
else
@@ -956,7 +954,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
g_assert (workspace->screen_edges == NULL);
g_assert (workspace->monitor_edges == NULL);
workspace->screen_edges =
- meta_rectangle_find_onscreen_edges (&workspace->screen->display->rect,
+ meta_rectangle_find_onscreen_edges (&workspace->display->rect,
workspace->all_struts);
tmp = NULL;
for (l = logical_monitors; l; l = l->next)
@@ -1007,7 +1005,7 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
- MetaScreen *screen = workspace->screen;
+ MetaDisplay *display = workspace->display;
GSList *l;
for (l = struts; l; l = l->next)
@@ -1036,7 +1034,7 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
META_DISPLAY_DOWN))
continue;
- strut->rect.height = screen->display->rect.height - strut->rect.y;
+ strut->rect.height = display->rect.height - strut->rect.y;
break;
case META_SIDE_LEFT:
if (meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
@@ -1053,7 +1051,7 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
META_DISPLAY_RIGHT))
continue;
- strut->rect.width = screen->display->rect.width - strut->rect.x;
+ strut->rect.width = display->rect.width - strut->rect.x;
break;
}
}
@@ -1199,9 +1197,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
gboolean ltr;
current_space = meta_workspace_index (workspace);
- num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
- meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
- current_space, &layout);
+ num_workspaces = meta_display_get_n_workspaces (workspace->display);
+ meta_display_calc_workspace_layout (workspace->display, num_workspaces,
+ current_space, &layout);
meta_verbose ("Getting neighbor of %d in direction %s\n",
current_space, meta_motion_direction_to_string (direction));
@@ -1246,9 +1244,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
meta_verbose ("Neighbor workspace is %d at row %d col %d\n",
i, layout.current_row, layout.current_col);
- meta_screen_free_workspace_layout (&layout);
+ meta_display_free_workspace_layout (&layout);
- return meta_screen_get_workspace_by_index (workspace->screen, i);
+ return meta_display_get_workspace_by_index (workspace->display, i);
}
const char*
@@ -1262,19 +1260,17 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
MetaWindow *not_this_one,
guint32 timestamp)
{
- MetaDisplay *display = workspace->screen->display;
-
if (timestamp == CurrentTime)
meta_warning ("CurrentTime used to choose focus window; "
"focus window may not be correct.\n");
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
- !workspace->screen->display->mouse_mode)
+ !workspace->display->mouse_mode)
focus_ancestor_or_top_window (workspace, not_this_one, timestamp);
else
{
MetaWindow * window;
- window = meta_display_get_pointer_window (workspace->screen->display, not_this_one);
+ window = meta_display_get_pointer_window (workspace->display, not_this_one);
if (window &&
window->type != META_WINDOW_DOCK &&
window->type != META_WINDOW_DESKTOP)
@@ -1299,10 +1295,10 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
meta_window_focus (window, timestamp);
}
- if (workspace->screen->display->autoraise_window != window &&
+ if (workspace->display->autoraise_window != window &&
meta_prefs_get_auto_raise ())
{
- meta_display_queue_autoraise_callback (display, window);
+ meta_display_queue_autoraise_callback (workspace->display, window);
}
}
else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_SLOPPY)
@@ -1312,7 +1308,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
meta_topic (META_DEBUG_FOCUS,
"Setting focus to no_focus_window, since no valid "
"window to focus found.\n");
- meta_x11_display_focus_the_no_focus_window (display->x11_display,
+ meta_x11_display_focus_the_no_focus_window (workspace->display->x11_display,
timestamp);
}
}
@@ -1334,7 +1330,6 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
MetaWindow *not_this_one,
guint32 timestamp)
{
- MetaDisplay *display = workspace->screen->display;
MetaWindow *window = NULL;
if (not_this_one)
@@ -1368,7 +1363,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
}
}
- window = meta_stack_get_default_focus_window (display->stack,
+ window = meta_stack_get_default_focus_window (workspace->display->stack,
workspace,
not_this_one);
@@ -1386,22 +1381,21 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
else
{
meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n");
- meta_x11_display_focus_the_no_focus_window (display->x11_display,
+ meta_x11_display_focus_the_no_focus_window (workspace->display->x11_display,
timestamp);
}
}
/**
- * meta_workspace_get_screen:
+ * meta_workspace_get_display:
* @workspace: a #MetaWorkspace
*
- * Gets the #MetaScreen that the workspace is part of.
+ * Gets the #MetaDisplay that the workspace is part of.
*
- * Return value: (transfer none): the #MetaScreen for the workspace
+ * Return value: (transfer none): the #MetaDisplay for the workspace
*/
-MetaScreen *
-meta_workspace_get_screen (MetaWorkspace *workspace)
+MetaDisplay *
+meta_workspace_get_display (MetaWorkspace *workspace)
{
- return workspace->screen;
+ return workspace->display;
}
-
diff --git a/src/meta/display.h b/src/meta/display.h
index 50366cbff..aa263066f 100644
--- a/src/meta/display.h
+++ b/src/meta/display.h
@@ -208,4 +208,46 @@ int meta_display_get_monitor_neighbor_index (MetaDisplay *display,
int which_monitor,
MetaDisplayDirection dir);
+GList *meta_display_get_workspaces (MetaDisplay *display);
+
+int meta_display_get_n_workspaces (MetaDisplay *display);
+
+MetaWorkspace* meta_display_get_workspace_by_index (MetaDisplay *display,
+ int index);
+void meta_display_remove_workspace (MetaDisplay *display,
+ MetaWorkspace *workspace,
+ guint32 timestamp);
+
+MetaWorkspace *meta_display_append_new_workspace (MetaDisplay *display,
+ gboolean activate,
+ guint32 timestamp);
+
+int meta_display_get_active_workspace_index (MetaDisplay *display);
+
+MetaWorkspace *meta_display_get_active_workspace (MetaDisplay *display);
+
+void meta_display_focus_default_window (MetaDisplay *display,
+ guint32 timestamp);
+
+/**
+ * MetaDisplayCorner:
+ * @META_DISPLAY_TOPLEFT: top-left corner
+ * @META_DISPLAY_TOPRIGHT: top-right corner
+ * @META_DISPLAY_BOTTOMLEFT: bottom-left corner
+ * @META_DISPLAY_BOTTOMRIGHT: bottom-right corner
+ */
+typedef enum
+{
+ META_DISPLAY_TOPLEFT,
+ META_DISPLAY_TOPRIGHT,
+ META_DISPLAY_BOTTOMLEFT,
+ META_DISPLAY_BOTTOMRIGHT
+} MetaDisplayCorner;
+
+void meta_display_override_workspace_layout (MetaDisplay *display,
+ MetaDisplayCorner starting_corner,
+ gboolean vertical_layout,
+ int n_rows,
+ int n_columns);
+
#endif
diff --git a/src/meta/screen.h b/src/meta/screen.h
index 57f3b60fd..ec9162efd 100644
--- a/src/meta/screen.h
+++ b/src/meta/screen.h
@@ -38,46 +38,4 @@ GType meta_screen_get_type (void);
MetaDisplay *meta_screen_get_display (MetaScreen *screen);
-GList *meta_screen_get_workspaces (MetaScreen *screen);
-
-int meta_screen_get_n_workspaces (MetaScreen *screen);
-
-MetaWorkspace* meta_screen_get_workspace_by_index (MetaScreen *screen,
- int index);
-void meta_screen_remove_workspace (MetaScreen *screen,
- MetaWorkspace *workspace,
- guint32 timestamp);
-
-MetaWorkspace *meta_screen_append_new_workspace (MetaScreen *screen,
- gboolean activate,
- guint32 timestamp);
-
-int meta_screen_get_active_workspace_index (MetaScreen *screen);
-
-MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen);
-
-void meta_screen_focus_default_window (MetaScreen *screen,
- guint32 timestamp);
-
-/**
- * MetaScreenCorner:
- * @META_SCREEN_TOPLEFT: top-left corner
- * @META_SCREEN_TOPRIGHT: top-right corner
- * @META_SCREEN_BOTTOMLEFT: bottom-left corner
- * @META_SCREEN_BOTTOMRIGHT: bottom-right corner
- */
-typedef enum
-{
- META_SCREEN_TOPLEFT,
- META_SCREEN_TOPRIGHT,
- META_SCREEN_BOTTOMLEFT,
- META_SCREEN_BOTTOMRIGHT
-} MetaScreenCorner;
-
-void meta_screen_override_workspace_layout (MetaScreen *screen,
- MetaScreenCorner starting_corner,
- gboolean vertical_layout,
- int n_rows,
- int n_columns);
-
#endif
diff --git a/src/meta/workspace.h b/src/meta/workspace.h
index 005e9c9af..d83a3891f 100644
--- a/src/meta/workspace.h
+++ b/src/meta/workspace.h
@@ -37,7 +37,7 @@ typedef struct _MetaWorkspaceClass MetaWorkspaceClass;
GType meta_workspace_get_type (void);
int meta_workspace_index (MetaWorkspace *workspace);
-MetaScreen *meta_workspace_get_screen (MetaWorkspace *workspace);
+MetaDisplay *meta_workspace_get_display (MetaWorkspace *workspace);
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
void meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace,
int which_monitor,
diff --git a/src/x11/events.c b/src/x11/events.c
index e4fa77801..375d72f08 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -843,7 +843,6 @@ handle_input_xevent (MetaX11Display *x11_display,
Window modified;
MetaWindow *window;
MetaDisplay *display = x11_display->display;
- MetaScreen *screen = display->screen;
if (input_event == NULL)
return FALSE;
@@ -912,7 +911,7 @@ handle_input_xevent (MetaX11Display *x11_display,
"Focus got set to None, probably due to "
"brain-damage in the X protocol (see bug "
"125492). Setting the default focus window.\n");
- meta_workspace_focus_default_window (screen->active_workspace,
+ meta_workspace_focus_default_window (display->active_workspace,
NULL,
meta_x11_display_get_current_time_roundtrip
(x11_display));
}
@@ -924,7 +923,7 @@ handle_input_xevent (MetaX11Display *x11_display,
"Focus got set to root window, probably due to "
"gnome-session logout dialog usage (see bug "
"153220). Setting the default focus window.\n");
- meta_workspace_focus_default_window (screen->active_workspace,
+ meta_workspace_focus_default_window (display->active_workspace,
NULL,
meta_x11_display_get_current_time_roundtrip
(x11_display));
}
@@ -1398,12 +1397,12 @@ handle_other_xevent (MetaX11Display *x11_display,
if (window->minimized)
{
meta_window_unminimize (window);
- if (window->workspace != window->screen->active_workspace)
+ if (window->workspace != window->display->active_workspace)
{
meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n",
window->mapped, window->minimized);
meta_window_change_workspace (window,
- window->screen->active_workspace);
+ window->display->active_workspace);
}
}
break;
@@ -1488,10 +1487,10 @@ handle_other_xevent (MetaX11Display *x11_display,
{
if (event->xproperty.atom ==
x11_display->atom__NET_DESKTOP_LAYOUT)
- meta_screen_update_workspace_layout (display->screen);
+ meta_display_update_workspace_layout (display);
else if (event->xproperty.atom ==
x11_display->atom__NET_DESKTOP_NAMES)
- meta_screen_update_workspace_names (display->screen);
+ meta_x11_display_update_workspace_names (x11_display);
/* we just use this property as a sentinel to avoid
* certain race conditions. See the comment for the
@@ -1552,7 +1551,7 @@ handle_other_xevent (MetaX11Display *x11_display,
"specified timestamp of %u\n",
space, time);
- workspace = meta_screen_get_workspace_by_index (display->screen, space);
+ workspace = meta_display_get_workspace_by_index (display, space);
/* Handle clients using the older version of the spec... */
if (time == 0 && workspace)
@@ -1593,11 +1592,11 @@ handle_other_xevent (MetaX11Display *x11_display,
showing_desktop ? "show" : "hide");
if (showing_desktop)
- meta_screen_show_desktop (display->screen, timestamp);
+ meta_display_show_desktop (display, timestamp);
else
{
- meta_screen_unshow_desktop (display->screen);
- meta_workspace_focus_default_window (display->screen->active_workspace, NULL,
timestamp);
+ meta_display_unshow_desktop (display);
+ meta_workspace_focus_default_window (display->active_workspace, NULL, timestamp);
}
}
else if (event->xclient.message_type ==
diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h
index 72e68d544..09bf2a082 100644
--- a/src/x11/meta-x11-display-private.h
+++ b/src/x11/meta-x11-display-private.h
@@ -202,4 +202,12 @@ int meta_x11_display_logical_monitor_to_xinerama_index (MetaX11Display *x11_
MetaLogicalMonitor *meta_x11_display_xinerama_index_to_logical_monitor (MetaX11Display *x11_display,
int xinerama_index);
+/* Update whether the destkop is being shown for the current active_workspace */
+void meta_x11_display_update_showing_desktop_hint (MetaX11Display *x11_display);
+void meta_x11_display_update_workspace_names (MetaX11Display *x11_display);
+
+void meta_x11_display_set_active_workspace_hint (MetaX11Display *x11_display);
+void meta_x11_display_set_number_of_spaces_hint (MetaX11Display *x11_display,
+ int n_spaces);
+
#endif /* META_X11_DISPLAY_PRIVATE_H */
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 7460873d5..64a0d0fc5 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -53,6 +53,7 @@
#include "backends/x11/meta-backend-x11.h"
#include "core/frame.h"
#include "core/util-private.h"
+#include "core/workspace-private.h"
#include "meta/errors.h"
#include "meta/main.h"
@@ -1562,3 +1563,108 @@ meta_x11_display_xinerama_index_to_logical_monitor (MetaX11Display *x11_display,
return NULL;
}
+
+void
+meta_x11_display_update_showing_desktop_hint (MetaX11Display *x11_display)
+{
+ MetaDisplay *display = x11_display->display;
+ unsigned long data[1];
+
+ data[0] = display->active_workspace->showing_desktop ? 1 : 0;
+
+ meta_error_trap_push (x11_display);
+ XChangeProperty (x11_display->xdisplay,
+ x11_display->xroot,
+ x11_display->atom__NET_SHOWING_DESKTOP,
+ XA_CARDINAL,
+ 32, PropModeReplace, (guchar*) data, 1);
+ meta_error_trap_pop (x11_display);
+}
+
+void
+meta_x11_display_update_workspace_names (MetaX11Display *x11_display)
+{
+ char **names;
+ int n_names;
+ int i;
+
+ /* this updates names in prefs when the root window property changes,
+ * iff the new property contents don't match what's already in prefs
+ */
+
+ names = NULL;
+ n_names = 0;
+ if (!meta_prop_get_utf8_list (x11_display,
+ x11_display->xroot,
+ x11_display->atom__NET_DESKTOP_NAMES,
+ &names, &n_names))
+ {
+ meta_verbose ("Failed to get workspace names from root window\n");
+ return;
+ }
+
+ i = 0;
+ while (i < n_names)
+ {
+ meta_topic (META_DEBUG_PREFS,
+ "Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n",
+ i, names[i] ? names[i] : "null");
+ meta_prefs_change_workspace_name (i, names[i]);
+
+ ++i;
+ }
+
+ g_strfreev (names);
+}
+
+
+void
+meta_x11_display_set_active_workspace_hint (MetaX11Display *x11_display)
+{
+ MetaDisplay *display = x11_display->display;
+
+ unsigned long data[1];
+
+ /* this is because we destroy the spaces in order,
+ * so we always end up setting a current desktop of
+ * 0 when closing a screen, so lose the current desktop
+ * on restart. By doing this we keep the current
+ * desktop on restart.
+ */
+ if (display->closing > 0)
+ return;
+
+ data[0] = meta_workspace_index (display->active_workspace);
+
+ meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
+
+ meta_error_trap_push (x11_display);
+ XChangeProperty (x11_display->xdisplay,
+ x11_display->xroot,
+ x11_display->atom__NET_CURRENT_DESKTOP,
+ XA_CARDINAL,
+ 32, PropModeReplace, (guchar*) data, 1);
+ meta_error_trap_pop (x11_display);
+}
+
+void
+meta_x11_display_set_number_of_spaces_hint (MetaX11Display *x11_display,
+ int n_spaces)
+{
+ unsigned long data[1];
+
+ if (x11_display->display->closing > 0)
+ return;
+
+ data[0] = n_spaces;
+
+ meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]);
+
+ meta_error_trap_push (x11_display);
+ XChangeProperty (x11_display->xdisplay,
+ x11_display->xroot,
+ x11_display->atom__NET_NUMBER_OF_DESKTOPS,
+ XA_CARDINAL,
+ 32, PropModeReplace, (guchar*) data, 1);
+ meta_error_trap_pop (x11_display);
+}
diff --git a/src/x11/window-props.c b/src/x11/window-props.c
index 1461f999b..5f8ee647c 100644
--- a/src/x11/window-props.c
+++ b/src/x11/window-props.c
@@ -1049,7 +1049,7 @@ reload_net_startup_id (MetaWindow *window,
if (window->initial_timestamp_set)
timestamp = window->initial_timestamp;
if (window->initial_workspace_set)
- workspace = meta_screen_get_workspace_by_index (window->screen, window->initial_workspace);
+ workspace = meta_display_get_workspace_by_index (window->display, window->initial_workspace);
meta_window_activate_with_workspace (window, timestamp, workspace);
}
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index d297b554d..6b070cedb 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -445,8 +445,8 @@ meta_window_apply_session_info (MetaWindow *window,
MetaWorkspace *space;
space =
- meta_screen_get_workspace_by_index (window->screen,
- GPOINTER_TO_INT (tmp->data));
+ meta_display_get_workspace_by_index (window->display,
+ GPOINTER_TO_INT (tmp->data));
if (space)
spaces = g_slist_prepend (spaces, space);
@@ -2409,8 +2409,8 @@ meta_window_x11_client_message (MetaWindow *window,
window->desc, space);
workspace =
- meta_screen_get_workspace_by_index (window->screen,
- space);
+ meta_display_get_workspace_by_index (window->display,
+ space);
if (workspace)
meta_window_change_workspace (window, workspace);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]