Make workspace management work without X11
https://bugzilla.gnome.org/show_bug.cgi?id=759538
This commit is contained in:
parent
14d8aec4b8
commit
8adab02757
@ -444,7 +444,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;
|
||||
|
||||
@ -477,4 +481,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
|
||||
|
@ -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,
|
||||
@ -174,10 +176,6 @@ 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);
|
||||
|
||||
@ -488,6 +486,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),
|
||||
@ -495,6 +501,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),
|
||||
@ -790,6 +804,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;
|
||||
@ -800,15 +834,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;
|
||||
@ -825,8 +850,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)
|
||||
@ -2559,11 +2582,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3717,36 +3737,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");
|
||||
num = meta_prefs_get_num_workspaces ();
|
||||
|
||||
update_num_workspaces (display, timestamp);
|
||||
meta_display_update_num_workspaces (display, META_CURRENT_TIME, num);
|
||||
|
||||
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);
|
||||
meta_workspace_activate (display->workspaces->data, META_CURRENT_TIME);
|
||||
}
|
||||
|
||||
int
|
||||
@ -3816,15 +3820,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; l = l->next)
|
||||
{
|
||||
@ -3871,8 +3873,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);
|
||||
|
||||
@ -3885,51 +3885,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;
|
||||
@ -3951,7 +3923,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;
|
||||
@ -3978,8 +3949,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++)
|
||||
@ -3988,100 +3957,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,
|
||||
@ -4110,64 +4003,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
|
||||
@ -4527,7 +4369,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
|
||||
@ -4540,7 +4382,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -543,17 +543,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))
|
||||
@ -650,7 +650,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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
@ -683,6 +688,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
|
||||
@ -736,6 +848,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[] = {
|
||||
@ -927,6 +1041,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;
|
||||
}
|
||||
|
||||
@ -1564,23 +1742,6 @@ 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)
|
||||
{
|
||||
@ -1617,54 +1778,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;
|
||||
}
|
||||
|
||||
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)
|
||||
n_rows = rows;
|
||||
else
|
||||
n_rows = -1;
|
||||
|
||||
if (cols > 0)
|
||||
n_columns = cols;
|
||||
else
|
||||
n_columns = -1;
|
||||
}
|
||||
|
||||
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_XFree (list);
|
||||
|
||||
meta_display_update_workspace_layout (x11_display->display,
|
||||
starting_corner,
|
||||
vertical_layout,
|
||||
n_rows,
|
||||
n_columns);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_x11_display_set_number_of_spaces_hint (MetaX11Display *x11_display,
|
||||
int n_spaces)
|
||||
static void
|
||||
prefs_changed_callback (MetaPreference pref,
|
||||
void *data)
|
||||
{
|
||||
unsigned long data[1];
|
||||
MetaX11Display *x11_display = data;
|
||||
|
||||
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);
|
||||
if (pref == META_PREF_WORKSPACE_NAMES)
|
||||
{
|
||||
set_workspace_names (x11_display);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user