[mutter/wip/xwayland-on-demand: 20/32] Make workspace management work without X11
- From: Jonas Ã…dahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/xwayland-on-demand: 20/32] Make workspace management work without X11
- Date: Mon, 28 Aug 2017 02:53:22 +0000 (UTC)
commit c0e61281821894547f288fef50ea8396d41b0b47
Author: Armin Krezović <krezovic armin gmail com>
Date: Sat Aug 26 22:29:10 2017 +0200
Make workspace management work without X11
src/core/display-private.h | 10 +-
src/core/display.c | 312 +++++++++-------------------------
src/core/workspace.c | 13 +-
src/x11/events.c | 2 +-
src/x11/meta-x11-display-private.h | 9 +-
src/x11/meta-x11-display.c | 333 ++++++++++++++++++++++++++++++------
6 files changed, 374 insertions(+), 305 deletions(-)
---
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 25c341d..31a6965 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -443,7 +443,11 @@ 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);
+void meta_display_update_workspace_layout (MetaDisplay *display,
+ MetaDisplayCorner starting_corner,
+ gboolean vertical_layout,
+ int n_rows,
+ int n_columns);
typedef struct MetaWorkspaceLayout MetaWorkspaceLayout;
@@ -476,4 +480,8 @@ void meta_display_workspace_switched (MetaDisplay *display,
int to,
MetaMotionDirection direction);
+void meta_display_update_num_workspaces (MetaDisplay *display,
+ guint32 timestamp,
+ int new_num);
+
#endif
diff --git a/src/core/display.c b/src/core/display.c
index 0f25e93..2547c4b 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -140,7 +140,9 @@ enum
WORKSPACE_ADDED,
WORKSPACE_REMOVED,
WORKSPACE_SWITCHED,
+ ACTIVE_WORKSPACE_CHANGED,
IN_FULLSCREEN_CHANGED,
+ SHOWING_DESKTOP_CHANGED,
STARTUP_SEQUENCE_CHANGED,
MONITORS_CHANGED,
RESTACKED,
@@ -171,10 +173,6 @@ static void on_monitors_changed (MetaMonitorManager *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);
@@ -485,6 +483,14 @@ meta_display_class_init (MetaDisplayClass *klass)
G_TYPE_INT,
META_TYPE_MOTION_DIRECTION);
+ display_signals[ACTIVE_WORKSPACE_CHANGED] =
+ g_signal_new ("active-workspace-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+
display_signals[IN_FULLSCREEN_CHANGED] =
g_signal_new ("in-fullscreen-changed",
G_TYPE_FROM_CLASS (klass),
@@ -492,6 +498,14 @@ meta_display_class_init (MetaDisplayClass *klass)
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
+ display_signals[SHOWING_DESKTOP_CHANGED] =
+ g_signal_new ("showing-desktop-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+
display_signals[STARTUP_SEQUENCE_CHANGED] =
g_signal_new ("startup-sequence-changed",
G_TYPE_FROM_CLASS (klass),
@@ -784,6 +798,26 @@ meta_display_open (void)
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
+
+ /* This is the default layout extracted from default
+ * variable values in update_num_workspaces ()
+ * This can be overriden using _NET_DESKTOP_LAYOUT in
+ * meta_x11_display_new (), if it's specified */
+ meta_display_update_workspace_layout (display,
+ META_DISPLAY_TOPLEFT,
+ FALSE,
+ -1,
+ 1);
+
+ /* There must be at least one workspace at all times,
+ * so create that required workspace.
+ */
+ meta_workspace_new (display);
+
+ meta_display_init_workspaces (display);
+
+ reload_logical_monitors (display);
+
x11_display = meta_x11_display_new (display, &error);
g_assert (x11_display != NULL); /* Required, for now */
display->x11_display = x11_display;
@@ -794,15 +828,6 @@ 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;
@@ -819,8 +844,6 @@ meta_display_open (void)
g_signal_connect (display->startup_notification, "changed",
G_CALLBACK (on_startup_notification_changed), display);
- meta_display_init_workspaces (display);
-
enable_compositor (display);
if (display->x11_display)
@@ -2549,11 +2572,8 @@ prefs_changed_callback (MetaPreference pref,
*/
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);
+ int new_num = meta_prefs_get_num_workspaces ();
+ meta_display_update_num_workspaces (display, timestamp, new_num);
}
}
@@ -3697,36 +3717,20 @@ meta_display_get_pointer_window (MetaDisplay *display,
void
meta_display_init_workspaces (MetaDisplay *display)
{
- MetaWorkspace *current_workspace;
- uint32_t current_workspace_index = 0;
- guint32 timestamp;
+ int num;
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);
+ if (meta_prefs_get_dynamic_workspaces ())
+ /* This will be properly updated using _NET_NUMBER_OF_DESKTOPS
+ * (if set) in meta_x11_display_new () */
+ num = 1;
else
- meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
-
- update_num_workspaces (display, timestamp);
+ num = meta_prefs_get_num_workspaces ();
- set_workspace_names (display);
+ meta_display_update_num_workspaces (display, META_CURRENT_TIME, num);
- /* 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);
+ meta_workspace_activate (display->workspaces->data, META_CURRENT_TIME);
}
int
@@ -3796,15 +3800,13 @@ meta_display_remove_workspace (MetaDisplay *display,
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);
+ g_signal_emit (display, display_signals[ACTIVE_WORKSPACE_CHANGED], 0, NULL);
for (l = next; l != NULL; l = l->next)
{
@@ -3850,8 +3852,6 @@ meta_display_append_new_workspace (MetaDisplay *display,
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);
@@ -3864,51 +3864,23 @@ meta_display_append_new_workspace (MetaDisplay *display,
return w;
}
-static void
-update_num_workspaces (MetaDisplay *display,
- guint32 timestamp)
+void
+meta_display_update_num_workspaces (MetaDisplay *display,
+ guint32 timestamp,
+ int new_num)
{
- int new_num, old_num;
+ int 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 ();
- }
+ int i = 0;
+ GList *extras = NULL;
+ MetaWorkspace *last_remaining = NULL;
+ gboolean need_change_space = FALSE;
g_assert (new_num > 0);
if (g_list_length (display->workspaces) == (guint) new_num)
return;
- last_remaining = NULL;
- extras = NULL;
- i = 0;
for (l = display->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *w = l->data;
@@ -3930,7 +3902,6 @@ update_num_workspaces (MetaDisplay *display,
* 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;
@@ -3957,8 +3928,6 @@ update_num_workspaces (MetaDisplay *display,
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++)
@@ -3967,100 +3936,24 @@ update_num_workspaces (MetaDisplay *display,
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)
+meta_display_update_workspace_layout (MetaDisplay *display,
+ MetaDisplayCorner starting_corner,
+ gboolean vertical_layout,
+ int n_rows,
+ int n_columns)
{
- uint32_t *list;
- int n_items;
+ g_return_if_fail (META_IS_DISPLAY (display));
+ g_return_if_fail (n_rows > 0 || n_columns > 0);
+ g_return_if_fail (n_rows != 0 && n_columns != 0);
if (display->workspace_layout_overridden)
return;
- 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);
- }
+ display->vertical_workspaces = vertical_layout != FALSE;
+ display->starting_corner = starting_corner;
+ display->rows_of_workspaces = n_rows;
+ display->columns_of_workspaces = n_columns;
meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n",
display->rows_of_workspaces,
@@ -4089,64 +3982,13 @@ meta_display_override_workspace_layout (MetaDisplay *display,
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);
+ meta_display_update_workspace_layout (display,
+ starting_corner,
+ vertical_layout,
+ n_rows,
+ n_columns);
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
@@ -4506,7 +4348,7 @@ meta_display_show_desktop (MetaDisplay *display,
}
}
- meta_x11_display_update_showing_desktop_hint (display->x11_display);
+ g_signal_emit (display, display_signals[SHOWING_DESKTOP_CHANGED], 0, NULL);
}
void
@@ -4519,7 +4361,7 @@ meta_display_unshow_desktop (MetaDisplay *display)
queue_windows_showing (display);
- meta_x11_display_update_showing_desktop_hint (display->x11_display);
+ g_signal_emit (display, display_signals[SHOWING_DESKTOP_CHANGED], 0, NULL);
}
/**
diff --git a/src/core/workspace.c b/src/core/workspace.c
index d0380e1..2984a2f 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -542,17 +542,17 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
workspace->display->active_workspace = workspace;
- meta_x11_display_set_active_workspace_hint (workspace->display->x11_display);
+ g_signal_emit_by_name (workspace->display, "active-workspace-changed");
+
+ if (old == NULL)
+ return;
/* 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_x11_display_update_showing_desktop_hint (workspace->display->x11_display);
-
- if (old == NULL)
- return;
+ if (old->showing_desktop != workspace->showing_desktop)
+ g_signal_emit_by_name (workspace->display, "showing-desktop-changed");
move_window = NULL;
if (meta_grab_op_is_moving (workspace->display->grab_op))
@@ -649,7 +649,6 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
meta_workspace_focus_default_window (workspace, NULL, timestamp);
}
- /* Emit switched signal from screen.c */
meta_display_workspace_switched (display, current_space, new_space, direction);
}
diff --git a/src/x11/events.c b/src/x11/events.c
index 0cf03c4..249edd7 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -1486,7 +1486,7 @@ handle_other_xevent (MetaX11Display *x11_display,
{
if (event->xproperty.atom ==
x11_display->atom__NET_DESKTOP_LAYOUT)
- meta_display_update_workspace_layout (display);
+ meta_x11_display_update_workspace_layout (x11_display);
else if (event->xproperty.atom ==
x11_display->atom__NET_DESKTOP_NAMES)
meta_x11_display_update_workspace_names (x11_display);
diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h
index 09bf2a0..a4af63e 100644
--- a/src/x11/meta-x11-display-private.h
+++ b/src/x11/meta-x11-display-private.h
@@ -202,12 +202,7 @@ 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);
+void meta_x11_display_update_workspace_layout (MetaX11Display *x11_display);
+void meta_x11_display_update_workspace_names (MetaX11Display *x11_display);
#endif /* META_X11_DISPLAY_PRIVATE_H */
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 1357981..8f193d3 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -87,11 +87,16 @@ static void on_monitors_changed (MetaDisplay *display,
static void update_cursor_theme (MetaX11Display *x11_display);
static void unset_wm_check_hint (MetaX11Display *x11_display);
+static void prefs_changed_callback (MetaPreference pref,
+ void *data);
+
static void
meta_x11_display_dispose (GObject *object)
{
MetaX11Display *x11_display = META_X11_DISPLAY (object);
+ meta_prefs_remove_listener (prefs_changed_callback, x11_display);
+
meta_x11_display_ungrab_keys (x11_display);
if (x11_display->ui)
@@ -677,6 +682,113 @@ init_event_masks (MetaX11Display *x11_display)
XSelectInput (x11_display->xdisplay, x11_display->xroot, event_mask);
}
+static void
+set_active_workspace_hint (MetaDisplay *display,
+ MetaX11Display *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 (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);
+}
+
+static void
+set_number_of_spaces_hint (MetaDisplay *display,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ MetaX11Display *x11_display = user_data;
+ unsigned long data[1];
+
+ if (display->closing > 0)
+ return;
+
+ data[0] = meta_display_get_n_workspaces (display);
+
+ 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);
+}
+
+static void
+set_showing_desktop_hint (MetaDisplay *display,
+ MetaX11Display *x11_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);
+}
+
+static void
+set_workspace_names (MetaX11Display *x11_display)
+{
+ GString *flattened;
+ int i;
+ int n_spaces;
+
+ /* flatten to nul-separated list */
+ n_spaces = meta_display_get_n_workspaces (x11_display->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);
+}
+
/**
* meta_set_wm_name: (skip)
* @wm_name: value for _NET_WM_NAME
@@ -730,6 +842,8 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
Atom wm_sn_atom;
char buf[128];
guint32 timestamp;
+ MetaWorkspace *current_workspace;
+ uint32_t current_workspace_index = 0;
/* A list of all atom names, so that we can intern them in one go. */
const char *atom_names[] = {
@@ -921,6 +1035,70 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
x11_display->keys_grabbed = FALSE;
meta_x11_display_grab_keys (x11_display);
+ meta_x11_display_update_workspace_layout (x11_display);
+
+ /* Get current workspace */
+ if (meta_prop_get_cardinal (x11_display,
+ x11_display->xroot,
+ x11_display->atom__NET_CURRENT_DESKTOP,
+ ¤t_workspace_index))
+ {
+ meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n",
+ (int) current_workspace_index);
+
+ /* 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_verbose ("No _NET_CURRENT_DESKTOP present\n");
+ }
+
+ if (meta_prefs_get_dynamic_workspaces ())
+ {
+ int num = 0;
+ int n_items = 0;
+ uint32_t *list = NULL;
+
+ if (meta_prop_get_cardinal_list (x11_display,
+ x11_display->xroot,
+ x11_display->atom__NET_NUMBER_OF_DESKTOPS,
+ &list, &n_items))
+ {
+ num = list[0];
+ meta_XFree (list);
+ }
+
+ if (num > meta_display_get_n_workspaces (display))
+ meta_display_update_num_workspaces (display, timestamp, num);
+ }
+
+ set_active_workspace_hint (display, x11_display);
+
+ g_signal_connect_object (display, "active-workspace-changed",
+ G_CALLBACK (set_active_workspace_hint),
+ x11_display, 0);
+
+ set_number_of_spaces_hint (display, NULL, x11_display);
+
+ g_signal_connect_object (display, "notify::n-workspaces",
+ G_CALLBACK (set_number_of_spaces_hint),
+ x11_display, 0);
+
+ set_showing_desktop_hint (display, x11_display);
+
+ g_signal_connect_object (display, "showing-desktop-changed",
+ G_CALLBACK (set_showing_desktop_hint),
+ x11_display, 0);
+
+ set_workspace_names (x11_display);
+
+ meta_prefs_add_listener (prefs_changed_callback, x11_display);
+
return x11_display;
}
@@ -1560,23 +1738,6 @@ meta_x11_display_xinerama_index_to_logical_monitor (MetaX11Display *x11_display,
}
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;
@@ -1612,54 +1773,118 @@ meta_x11_display_update_workspace_names (MetaX11Display *x11_display)
g_strfreev (names);
}
+#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_x11_display_set_active_workspace_hint (MetaX11Display *x11_display)
+meta_x11_display_update_workspace_layout (MetaX11Display *x11_display)
{
- MetaDisplay *display = x11_display->display;
+ gboolean vertical_layout = FALSE;
+ int n_rows = -1;
+ int n_columns = 1;
+ MetaDisplayCorner starting_corner = META_DISPLAY_TOPLEFT;
+ uint32_t *list;
+ int n_items;
- 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)
+ if (x11_display->display->workspace_layout_overridden)
return;
- data[0] = meta_workspace_index (display->active_workspace);
+ list = NULL;
+ n_items = 0;
- meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
+ if (meta_prop_get_cardinal_list (x11_display,
+ x11_display->xroot,
+ x11_display->atom__NET_DESKTOP_LAYOUT,
+ &list, &n_items))
+ {
+ if (n_items == 3 || n_items == 4)
+ {
+ int cols, rows;
- 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);
-}
+ switch (list[0])
+ {
+ case _NET_WM_ORIENTATION_HORZ:
+ vertical_layout = FALSE;
+ break;
+ case _NET_WM_ORIENTATION_VERT:
+ vertical_layout = TRUE;
+ break;
+ default:
+ meta_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n");
+ break;
+ }
-void
-meta_x11_display_set_number_of_spaces_hint (MetaX11Display *x11_display,
- int n_spaces)
-{
- unsigned long data[1];
+ cols = list[1];
+ rows = list[2];
- if (x11_display->display->closing > 0)
- return;
+ 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)
+ n_rows = rows;
+ else
+ n_rows = -1;
+
+ if (cols > 0)
+ n_columns = cols;
+ else
+ n_columns = -1;
+ }
- data[0] = n_spaces;
+ if (n_items == 4)
+ {
+ switch (list[3])
+ {
+ case _NET_WM_TOPLEFT:
+ starting_corner = META_DISPLAY_TOPLEFT;
+ break;
+ case _NET_WM_TOPRIGHT:
+ starting_corner = META_DISPLAY_TOPRIGHT;
+ break;
+ case _NET_WM_BOTTOMRIGHT:
+ starting_corner = META_DISPLAY_BOTTOMRIGHT;
+ break;
+ case _NET_WM_BOTTOMLEFT:
+ starting_corner = META_DISPLAY_BOTTOMLEFT;
+ break;
+ default:
+ meta_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n");
+ break;
+ }
+ }
+ }
+ else
+ {
+ meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 "
+ "(3 is accepted for backwards compat)\n", n_items);
+ }
- meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]);
+ meta_XFree (list);
- 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);
+ meta_display_update_workspace_layout (x11_display->display,
+ starting_corner,
+ vertical_layout,
+ n_rows,
+ n_columns);
+ }
+}
+
+static void
+prefs_changed_callback (MetaPreference pref,
+ void *data)
+{
+ MetaX11Display *x11_display = data;
+
+ if (pref == META_PREF_WORKSPACE_NAMES)
+ {
+ set_workspace_names (x11_display);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]