[mutter] screen: Behave better about CM selections
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] screen: Behave better about CM selections
- Date: Mon, 29 Dec 2014 03:21:24 +0000 (UTC)
commit fa97364fa842b4ef27b7cf442bf97d64303b4171
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sun Dec 28 19:11:45 2014 -0800
screen: Behave better about CM selections
src/core/screen-private.h | 2 -
src/core/screen.c | 198 +++++++++++++++++++--------------------------
src/meta/screen.h | 1 -
3 files changed, 85 insertions(+), 116 deletions(-)
---
diff --git a/src/core/screen-private.h b/src/core/screen-private.h
index c9f4231..9d520e5 100644
--- a/src/core/screen-private.h
+++ b/src/core/screen-private.h
@@ -100,8 +100,6 @@ struct _MetaScreen
#endif
Window wm_cm_selection_window;
- guint32 wm_cm_timestamp;
-
guint work_area_later;
guint check_fullscreen_later;
diff --git a/src/core/screen.c b/src/core/screen.c
index b26137e..496e693 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -496,6 +496,81 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
return guard_window;
}
+static Window
+take_manager_selection (MetaDisplay *display,
+ Window xroot,
+ Atom manager_atom,
+ int timestamp,
+ gboolean should_replace)
+{
+ Display *xdisplay = display->xdisplay;
+ Window current_owner, new_owner;
+
+ current_owner = XGetSelectionOwner (xdisplay, manager_atom);
+ if (current_owner != None)
+ {
+ XSetWindowAttributes attrs;
+
+ if (should_replace)
+ {
+ /* We want to find out when the current selection owner dies */
+ meta_error_trap_push (display);
+ attrs.event_mask = StructureNotifyMask;
+ XChangeWindowAttributes (xdisplay, current_owner, CWEventMask, &attrs);
+ if (meta_error_trap_pop_with_return (display) != Success)
+ current_owner = None; /* don't wait for it to die later on */
+ }
+ else
+ {
+ meta_warning (_("Display \"%s\" already has a window manager; try using the --replace option to
replace the current window manager."),
+ display->name);
+ return None;
+ }
+ }
+
+ /* We need SelectionClear and SelectionRequest events on the new owner,
+ * but those cannot be masked, so we only need NoEventMask.
+ */
+ new_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
+
+ XSetSelectionOwner (xdisplay, manager_atom, new_owner, timestamp);
+
+ if (XGetSelectionOwner (xdisplay, manager_atom) != new_owner)
+ {
+ meta_warning ("Could not acquire selection: %s", XGetAtomName (xdisplay, manager_atom));
+ return None;
+ }
+
+ {
+ /* Send client message indicating that we are now the selection owner */
+ XClientMessageEvent ev;
+
+ ev.type = ClientMessage;
+ ev.window = xroot;
+ ev.message_type = display->atom_MANAGER;
+ ev.format = 32;
+ ev.data.l[0] = timestamp;
+ ev.data.l[1] = manager_atom;
+
+ XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent *) &ev);
+ }
+
+ /* Wait for old window manager to go away */
+ if (current_owner != None)
+ {
+ XEvent event;
+
+ /* We sort of block infinitely here which is probably lame. */
+
+ meta_verbose ("Waiting for old window manager to exit\n");
+ do
+ XWindowEvent (xdisplay, current_owner, StructureNotifyMask, &event);
+ while (event.type != DestroyNotify);
+ }
+
+ return new_owner;
+}
+
MetaScreen*
meta_screen_new (MetaDisplay *display,
int number,
@@ -505,11 +580,9 @@ meta_screen_new (MetaDisplay *display,
Window xroot;
Display *xdisplay;
Window new_wm_sn_owner;
- Window current_wm_sn_owner;
gboolean replace_current_wm;
Atom wm_sn_atom;
char buf[128];
- guint32 manager_timestamp;
MetaMonitorManager *manager;
replace_current_wm = meta_get_replace_current_wm ();
@@ -537,83 +610,11 @@ meta_screen_new (MetaDisplay *display,
}
sprintf (buf, "WM_S%d", number);
- wm_sn_atom = XInternAtom (xdisplay, buf, False);
-
- current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
-
- if (current_wm_sn_owner != None)
- {
- XSetWindowAttributes attrs;
-
- if (!replace_current_wm)
- {
- meta_warning (_("Screen %d on display \"%s\" already has a window manager; try using the --replace
option to replace the current window manager.\n"),
- number, display->name);
-
- return NULL;
- }
-
- /* We want to find out when the current selection owner dies */
- meta_error_trap_push (display);
- attrs.event_mask = StructureNotifyMask;
- XChangeWindowAttributes (xdisplay,
- current_wm_sn_owner, CWEventMask, &attrs);
- if (meta_error_trap_pop_with_return (display) != Success)
- current_wm_sn_owner = None; /* don't wait for it to die later on */
- }
- /* We need SelectionClear and SelectionRequest events on the new_wm_sn_owner,
- * but those cannot be masked, so we only need NoEventMask.
- */
- new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
-
- manager_timestamp = timestamp;
-
- XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner,
- manager_timestamp);
-
- if (XGetSelectionOwner (xdisplay, wm_sn_atom) != new_wm_sn_owner)
- {
- meta_warning ("Could not acquire window manager selection on screen %d display \"%s\"\n",
- number, display->name);
-
- XDestroyWindow (xdisplay, new_wm_sn_owner);
-
- return NULL;
- }
-
- {
- /* Send client message indicating that we are now the WM */
- XClientMessageEvent ev;
-
- ev.type = ClientMessage;
- ev.window = xroot;
- ev.message_type = display->atom_MANAGER;
- ev.format = 32;
- ev.data.l[0] = manager_timestamp;
- ev.data.l[1] = wm_sn_atom;
-
- XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent*)&ev);
- }
-
- /* Wait for old window manager to go away */
- if (current_wm_sn_owner != None)
- {
- XEvent event;
-
- /* We sort of block infinitely here which is probably lame. */
-
- meta_verbose ("Waiting for old window manager to exit\n");
- do
- {
- XWindowEvent (xdisplay, current_wm_sn_owner,
- StructureNotifyMask, &event);
- }
- while (event.type != DestroyNotify);
- }
-
- /* select our root window events */
- meta_error_trap_push (display);
+ wm_sn_atom = XInternAtom (xdisplay, buf, False);
+ new_wm_sn_owner = take_manager_selection (display, xroot, wm_sn_atom, timestamp, replace_current_wm);
+ if (new_wm_sn_owner == None)
+ return NULL;
{
long event_mask;
@@ -638,16 +639,6 @@ meta_screen_new (MetaDisplay *display,
XSelectInput (xdisplay, xroot, event_mask);
}
- if (meta_error_trap_pop_with_return (display) != Success)
- {
- meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
- number, display->name);
-
- XDestroyWindow (xdisplay, new_wm_sn_owner);
-
- return NULL;
- }
-
/* Select for cursor changes so the cursor tracker is up to date. */
XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask);
@@ -675,11 +666,7 @@ meta_screen_new (MetaDisplay *display,
screen->wm_sn_selection_window = new_wm_sn_owner;
screen->wm_sn_atom = wm_sn_atom;
- screen->wm_sn_timestamp = manager_timestamp;
-
- screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
- xroot,
- NoEventMask);
+ screen->wm_sn_timestamp = timestamp;
screen->work_area_later = 0;
screen->check_fullscreen_later = 0;
@@ -2898,27 +2885,12 @@ meta_screen_set_cm_selection (MetaScreen *screen)
{
char selection[32];
Atom a;
+ guint32 timestamp;
- screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip (
- screen->display);
-
- g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
- meta_verbose ("Setting selection: %s\n", selection);
- a = XInternAtom (screen->display->xdisplay, selection, FALSE);
- XSetSelectionOwner (screen->display->xdisplay, a,
- screen->wm_cm_selection_window, screen->wm_cm_timestamp);
-}
-
-void
-meta_screen_unset_cm_selection (MetaScreen *screen)
-{
- char selection[32];
- Atom a;
-
- g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
- a = XInternAtom (screen->display->xdisplay, selection, FALSE);
- XSetSelectionOwner (screen->display->xdisplay, a,
- None, screen->wm_cm_timestamp);
+ timestamp = meta_display_get_current_time_roundtrip (screen->display);
+ g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", screen->number);
+ a = XInternAtom (xdisplay, selection, False);
+ screen->wm_cm_selection_window = take_manager_selection (screen->display, screen->xroot, a, timestamp,
TRUE);
}
/**
diff --git a/src/meta/screen.h b/src/meta/screen.h
index 4c3c52e..500871b 100644
--- a/src/meta/screen.h
+++ b/src/meta/screen.h
@@ -45,7 +45,6 @@ void meta_screen_get_size (MetaScreen *screen,
int *height);
void meta_screen_set_cm_selection (MetaScreen *screen);
-void meta_screen_unset_cm_selection (MetaScreen *screen);
GSList *meta_screen_get_startup_sequences (MetaScreen *screen);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]