mirror of
https://github.com/brl/mutter.git
synced 2025-02-23 08:24:09 +00:00
screen: Behave better about CM selections
This commit is contained in:
parent
41303101e5
commit
fa97364fa8
@ -100,8 +100,6 @@ struct _MetaScreen
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Window wm_cm_selection_window;
|
Window wm_cm_selection_window;
|
||||||
guint32 wm_cm_timestamp;
|
|
||||||
|
|
||||||
guint work_area_later;
|
guint work_area_later;
|
||||||
guint check_fullscreen_later;
|
guint check_fullscreen_later;
|
||||||
|
|
||||||
|
@ -496,6 +496,81 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
|||||||
return guard_window;
|
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*
|
MetaScreen*
|
||||||
meta_screen_new (MetaDisplay *display,
|
meta_screen_new (MetaDisplay *display,
|
||||||
int number,
|
int number,
|
||||||
@ -505,11 +580,9 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
Window xroot;
|
Window xroot;
|
||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
Window new_wm_sn_owner;
|
Window new_wm_sn_owner;
|
||||||
Window current_wm_sn_owner;
|
|
||||||
gboolean replace_current_wm;
|
gboolean replace_current_wm;
|
||||||
Atom wm_sn_atom;
|
Atom wm_sn_atom;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
guint32 manager_timestamp;
|
|
||||||
MetaMonitorManager *manager;
|
MetaMonitorManager *manager;
|
||||||
|
|
||||||
replace_current_wm = meta_get_replace_current_wm ();
|
replace_current_wm = meta_get_replace_current_wm ();
|
||||||
@ -537,83 +610,11 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf (buf, "WM_S%d", number);
|
sprintf (buf, "WM_S%d", number);
|
||||||
|
|
||||||
wm_sn_atom = XInternAtom (xdisplay, buf, False);
|
wm_sn_atom = XInternAtom (xdisplay, buf, False);
|
||||||
|
new_wm_sn_owner = take_manager_selection (display, xroot, wm_sn_atom, timestamp, replace_current_wm);
|
||||||
current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
|
if (new_wm_sn_owner == None)
|
||||||
|
return NULL;
|
||||||
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);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
long event_mask;
|
long event_mask;
|
||||||
@ -638,16 +639,6 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
XSelectInput (xdisplay, xroot, event_mask);
|
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. */
|
/* Select for cursor changes so the cursor tracker is up to date. */
|
||||||
XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask);
|
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_selection_window = new_wm_sn_owner;
|
||||||
screen->wm_sn_atom = wm_sn_atom;
|
screen->wm_sn_atom = wm_sn_atom;
|
||||||
screen->wm_sn_timestamp = manager_timestamp;
|
screen->wm_sn_timestamp = timestamp;
|
||||||
|
|
||||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
|
||||||
xroot,
|
|
||||||
NoEventMask);
|
|
||||||
screen->work_area_later = 0;
|
screen->work_area_later = 0;
|
||||||
screen->check_fullscreen_later = 0;
|
screen->check_fullscreen_later = 0;
|
||||||
|
|
||||||
@ -2898,27 +2885,12 @@ meta_screen_set_cm_selection (MetaScreen *screen)
|
|||||||
{
|
{
|
||||||
char selection[32];
|
char selection[32];
|
||||||
Atom a;
|
Atom a;
|
||||||
|
guint32 timestamp;
|
||||||
|
|
||||||
screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip (
|
timestamp = meta_display_get_current_time_roundtrip (screen->display);
|
||||||
screen->display);
|
g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", screen->number);
|
||||||
|
a = XInternAtom (xdisplay, selection, False);
|
||||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
screen->wm_cm_selection_window = take_manager_selection (screen->display, screen->xroot, a, timestamp, TRUE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,6 @@ void meta_screen_get_size (MetaScreen *screen,
|
|||||||
int *height);
|
int *height);
|
||||||
|
|
||||||
void meta_screen_set_cm_selection (MetaScreen *screen);
|
void meta_screen_set_cm_selection (MetaScreen *screen);
|
||||||
void meta_screen_unset_cm_selection (MetaScreen *screen);
|
|
||||||
|
|
||||||
GSList *meta_screen_get_startup_sequences (MetaScreen *screen);
|
GSList *meta_screen_get_startup_sequences (MetaScreen *screen);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user