don't die on bad atom name
2002-06-08 Havoc Pennington <hp@pobox.com> * src/xprops.c (meta_prop_get_utf8_string): don't die on bad atom name * src/display.c (meta_display_close): don't unmanage windows here, do it in screen_free and then closing the display unmanages windows as a side effect of unmanaging the screen (meta_display_unmanage_screen): new function (process_selection_clear, process_selection_request): handle selection stuff (meta_spew_event): don't crash on client message containing invalid atom (meta_spew_event): don't crash on property notify with invalid atom * src/main.c (main): add --replace option to replace existing window manager. * src/screen.c: implement holding manager selection. * src/display.c (meta_display_open): add new selection-related atoms.
This commit is contained in:
parent
538a06fd55
commit
31b211550f
24
ChangeLog
24
ChangeLog
@ -1,3 +1,27 @@
|
|||||||
|
2002-06-08 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* src/xprops.c (meta_prop_get_utf8_string): don't die on bad atom
|
||||||
|
name
|
||||||
|
|
||||||
|
* src/display.c (meta_display_close): don't unmanage windows here,
|
||||||
|
do it in screen_free and then closing the display unmanages
|
||||||
|
windows as a side effect of unmanaging the screen
|
||||||
|
(meta_display_unmanage_screen): new function
|
||||||
|
(process_selection_clear, process_selection_request): handle
|
||||||
|
selection stuff
|
||||||
|
(meta_spew_event): don't crash on client message containing
|
||||||
|
invalid atom
|
||||||
|
(meta_spew_event): don't crash on property notify with invalid
|
||||||
|
atom
|
||||||
|
|
||||||
|
* src/main.c (main): add --replace option to replace existing
|
||||||
|
window manager.
|
||||||
|
|
||||||
|
* src/screen.c: implement holding manager selection.
|
||||||
|
|
||||||
|
* src/display.c (meta_display_open): add new selection-related
|
||||||
|
atoms.
|
||||||
|
|
||||||
2002-06-08 Havoc Pennington <hp@pobox.com>
|
2002-06-08 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
* src/screen.c (meta_screen_new): select keypress/keyrelease
|
* src/screen.c (meta_screen_new): select keypress/keyrelease
|
||||||
|
294
src/display.c
294
src/display.c
@ -71,7 +71,10 @@ static guint32 event_get_time (MetaDisplay *display,
|
|||||||
XEvent *event);
|
XEvent *event);
|
||||||
static void process_pong_message (MetaDisplay *display,
|
static void process_pong_message (MetaDisplay *display,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
static void process_selection_request (MetaDisplay *display,
|
||||||
|
XEvent *event);
|
||||||
|
static void process_selection_clear (MetaDisplay *display,
|
||||||
|
XEvent *event);
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
unsigned_long_equal (gconstpointer v1,
|
unsigned_long_equal (gconstpointer v1,
|
||||||
@ -217,7 +220,13 @@ meta_display_open (const char *name)
|
|||||||
"WM_CLIENT_MACHINE",
|
"WM_CLIENT_MACHINE",
|
||||||
"_NET_WM_WORKAREA",
|
"_NET_WM_WORKAREA",
|
||||||
"_NET_SHOW_DESKTOP",
|
"_NET_SHOW_DESKTOP",
|
||||||
"_NET_DESKTOP_LAYOUT"
|
"_NET_DESKTOP_LAYOUT",
|
||||||
|
"MANAGER",
|
||||||
|
"TARGETS",
|
||||||
|
"MULTIPLE",
|
||||||
|
"TIMESTAMP",
|
||||||
|
"VERSION",
|
||||||
|
"ATOM_PAIR"
|
||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
@ -340,6 +349,12 @@ meta_display_open (const char *name)
|
|||||||
display->atom_net_wm_workarea = atoms[56];
|
display->atom_net_wm_workarea = atoms[56];
|
||||||
display->atom_net_show_desktop = atoms[57];
|
display->atom_net_show_desktop = atoms[57];
|
||||||
display->atom_net_desktop_layout = atoms[58];
|
display->atom_net_desktop_layout = atoms[58];
|
||||||
|
display->atom_manager = atoms[59];
|
||||||
|
display->atom_targets = atoms[60];
|
||||||
|
display->atom_multiple = atoms[61];
|
||||||
|
display->atom_timestamp = atoms[62];
|
||||||
|
display->atom_version = atoms[63];
|
||||||
|
display->atom_atom_pair = atoms[64];
|
||||||
|
|
||||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||||
* created in screen_new
|
* created in screen_new
|
||||||
@ -529,26 +544,11 @@ meta_display_list_windows (MetaDisplay *display)
|
|||||||
void
|
void
|
||||||
meta_display_close (MetaDisplay *display)
|
meta_display_close (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
GSList *winlist;
|
|
||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
|
|
||||||
if (display->error_traps > 0)
|
if (display->error_traps > 0)
|
||||||
meta_bug ("Display closed with error traps pending\n");
|
meta_bug ("Display closed with error traps pending\n");
|
||||||
|
|
||||||
winlist = meta_display_list_windows (display);
|
|
||||||
|
|
||||||
/* Unmanage all windows */
|
|
||||||
meta_display_grab (display);
|
|
||||||
tmp = winlist;
|
|
||||||
while (tmp != NULL)
|
|
||||||
{
|
|
||||||
meta_window_free (tmp->data);
|
|
||||||
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
g_slist_free (winlist);
|
|
||||||
meta_display_ungrab (display);
|
|
||||||
|
|
||||||
if (display->autoraise_timeout_id != 0)
|
if (display->autoraise_timeout_id != 0)
|
||||||
{
|
{
|
||||||
g_source_remove (display->autoraise_timeout_id);
|
g_source_remove (display->autoraise_timeout_id);
|
||||||
@ -1373,8 +1373,18 @@ event_callback (XEvent *event,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SelectionClear:
|
case SelectionClear:
|
||||||
|
/* do this here instead of at end of function
|
||||||
|
* so we can return
|
||||||
|
*/
|
||||||
|
display->current_time = CurrentTime;
|
||||||
|
process_selection_clear (display, event);
|
||||||
|
/* Note that processing that may have resulted in
|
||||||
|
* closing the display... so return right away.
|
||||||
|
*/
|
||||||
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
case SelectionRequest:
|
case SelectionRequest:
|
||||||
|
process_selection_request (display, event);
|
||||||
break;
|
break;
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
break;
|
break;
|
||||||
@ -1899,7 +1909,7 @@ meta_spew_event (MetaDisplay *display,
|
|||||||
extra = g_strdup_printf ("atom: %s state: %s",
|
extra = g_strdup_printf ("atom: %s state: %s",
|
||||||
str ? str : "(unknown atom)",
|
str ? str : "(unknown atom)",
|
||||||
state);
|
state);
|
||||||
XFree (str);
|
meta_XFree (str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SelectionClear:
|
case SelectionClear:
|
||||||
@ -1925,7 +1935,7 @@ meta_spew_event (MetaDisplay *display,
|
|||||||
extra = g_strdup_printf ("type: %s format: %d\n",
|
extra = g_strdup_printf ("type: %s format: %d\n",
|
||||||
str ? str : "(unknown atom)",
|
str ? str : "(unknown atom)",
|
||||||
event->xclient.format);
|
event->xclient.format);
|
||||||
XFree (str);
|
meta_XFree (str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MappingNotify:
|
case MappingNotify:
|
||||||
@ -2989,3 +2999,249 @@ meta_rectangle_intersect (MetaRectangle *src1,
|
|||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaScreen*
|
||||||
|
find_screen_for_selection (MetaDisplay *display,
|
||||||
|
Window owner,
|
||||||
|
Atom selection)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
tmp = display->screens;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaScreen *screen = tmp->data;
|
||||||
|
|
||||||
|
if (screen->wm_sn_selection_window == owner &&
|
||||||
|
screen->wm_sn_atom == selection)
|
||||||
|
return screen;
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from fvwm2, Copyright Dominik Vogt I assume, but it
|
||||||
|
* was unmarked.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
convert_property (MetaDisplay *display,
|
||||||
|
MetaScreen *screen,
|
||||||
|
Window w,
|
||||||
|
Atom target,
|
||||||
|
Atom property)
|
||||||
|
{
|
||||||
|
#define N_TARGETS 4
|
||||||
|
Atom conversion_targets[N_TARGETS];
|
||||||
|
long icccm_version[] = { 2, 0 };
|
||||||
|
|
||||||
|
conversion_targets[0] = display->atom_targets;
|
||||||
|
conversion_targets[1] = display->atom_multiple;
|
||||||
|
conversion_targets[2] = display->atom_timestamp;
|
||||||
|
conversion_targets[3] = display->atom_version;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
if (target == display->atom_targets)
|
||||||
|
XChangeProperty (display->xdisplay, w, property,
|
||||||
|
XA_ATOM, 32, PropModeReplace,
|
||||||
|
(unsigned char *)conversion_targets, N_TARGETS);
|
||||||
|
else if (target == display->atom_timestamp)
|
||||||
|
XChangeProperty (display->xdisplay, w, property,
|
||||||
|
XA_INTEGER, 32, PropModeReplace,
|
||||||
|
(unsigned char *)&screen->wm_sn_timestamp, 1);
|
||||||
|
else if (target == display->atom_version)
|
||||||
|
XChangeProperty (display->xdisplay, w, property,
|
||||||
|
XA_INTEGER, 32, PropModeReplace,
|
||||||
|
(unsigned char *)icccm_version, 2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta_error_trap_pop (display) != Success)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Be sure the PropertyNotify has arrived so we
|
||||||
|
* can send SelectionNotify
|
||||||
|
*/
|
||||||
|
XSync (display->xdisplay, False);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from fvwm2, Copyright Dominik Vogt I assume, but it
|
||||||
|
* was unmarked.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
process_selection_request (MetaDisplay *display,
|
||||||
|
XEvent *event)
|
||||||
|
{
|
||||||
|
XSelectionEvent reply;
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
screen = find_screen_for_selection (display,
|
||||||
|
event->xselectionrequest.owner,
|
||||||
|
event->xselectionrequest.selection);
|
||||||
|
|
||||||
|
if (screen == NULL)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
str = XGetAtomName (display->xdisplay,
|
||||||
|
event->xselectionrequest.selection);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
|
meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n",
|
||||||
|
str ? str : "(bad atom)", event->xselectionrequest.owner);
|
||||||
|
|
||||||
|
meta_XFree (str);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.type = SelectionNotify;
|
||||||
|
reply.display = display->xdisplay;
|
||||||
|
reply.requestor = event->xselectionrequest.requestor;
|
||||||
|
reply.selection = event->xselectionrequest.selection;
|
||||||
|
reply.target = event->xselectionrequest.target;
|
||||||
|
reply.property = None;
|
||||||
|
reply.time = event->xselectionrequest.time;
|
||||||
|
|
||||||
|
if (event->xselectionrequest.target == display->atom_multiple)
|
||||||
|
{
|
||||||
|
if (event->xselectionrequest.property != None)
|
||||||
|
{
|
||||||
|
Atom type, *adata;
|
||||||
|
int i, format;
|
||||||
|
unsigned long num, rest;
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XGetWindowProperty (display->xdisplay,
|
||||||
|
event->xselectionrequest.requestor,
|
||||||
|
event->xselectionrequest.property, 0, 256, False,
|
||||||
|
display->atom_atom_pair,
|
||||||
|
&type, &format, &num, &rest, &data);
|
||||||
|
if (meta_error_trap_pop (display) == Success)
|
||||||
|
{
|
||||||
|
/* FIXME: to be 100% correct, should deal with rest > 0,
|
||||||
|
* but since we have 4 possible targets, we will hardly ever
|
||||||
|
* meet multiple requests with a length > 8
|
||||||
|
*/
|
||||||
|
adata = (Atom*)data;
|
||||||
|
i = 0;
|
||||||
|
while (i < (int) num)
|
||||||
|
{
|
||||||
|
if (!convert_property (display, screen,
|
||||||
|
event->xselectionrequest.requestor,
|
||||||
|
adata[i], adata[i+1]))
|
||||||
|
adata[i+1] = None;
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XChangeProperty (display->xdisplay,
|
||||||
|
event->xselectionrequest.requestor,
|
||||||
|
event->xselectionrequest.property,
|
||||||
|
display->atom_atom_pair,
|
||||||
|
32, PropModeReplace, data, num);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
meta_XFree (data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (event->xselectionrequest.property == None)
|
||||||
|
event->xselectionrequest.property = event->xselectionrequest.target;
|
||||||
|
|
||||||
|
if (convert_property (display, screen,
|
||||||
|
event->xselectionrequest.requestor,
|
||||||
|
event->xselectionrequest.target,
|
||||||
|
event->xselectionrequest.property))
|
||||||
|
reply.property = event->xselectionrequest.property;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSendEvent (display->xdisplay,
|
||||||
|
event->xselectionrequest.requestor,
|
||||||
|
False, 0L, (XEvent*)&reply);
|
||||||
|
|
||||||
|
meta_verbose ("Handled selection request\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_selection_clear (MetaDisplay *display,
|
||||||
|
XEvent *event)
|
||||||
|
{
|
||||||
|
/* We need to unmanage the screen on which we lost the selection */
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
screen = find_screen_for_selection (display,
|
||||||
|
event->xselectionclear.window,
|
||||||
|
event->xselectionclear.selection);
|
||||||
|
|
||||||
|
|
||||||
|
if (screen != NULL)
|
||||||
|
{
|
||||||
|
meta_verbose ("Got selection clear for screen %d on display %s\n",
|
||||||
|
screen->number, display->name);
|
||||||
|
|
||||||
|
meta_display_unmanage_screen (display, screen);
|
||||||
|
|
||||||
|
/* display and screen may both be invalid memory... */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
str = XGetAtomName (display->xdisplay,
|
||||||
|
event->xselectionclear.selection);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
|
meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n",
|
||||||
|
str ? str : "(bad atom)", event->xselectionclear.window);
|
||||||
|
|
||||||
|
meta_XFree (str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_unmanage_screen (MetaDisplay *display,
|
||||||
|
MetaScreen *screen)
|
||||||
|
{
|
||||||
|
meta_verbose ("Unmanaging screen %d on display %s\n",
|
||||||
|
screen->number, display->name);
|
||||||
|
|
||||||
|
g_return_if_fail (g_slist_find (display->screens, screen) != NULL);
|
||||||
|
|
||||||
|
meta_screen_free (screen);
|
||||||
|
display->screens = g_slist_remove (display->screens, screen);
|
||||||
|
|
||||||
|
if (display->screens == NULL)
|
||||||
|
meta_display_close (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||||
|
MetaScreen *screen)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
GSList *winlist;
|
||||||
|
|
||||||
|
winlist = meta_display_list_windows (display);
|
||||||
|
|
||||||
|
/* Unmanage all windows */
|
||||||
|
tmp = winlist;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
meta_window_free (tmp->data);
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
g_slist_free (winlist);
|
||||||
|
}
|
||||||
|
@ -131,6 +131,12 @@ struct _MetaDisplay
|
|||||||
Atom atom_net_wm_workarea;
|
Atom atom_net_wm_workarea;
|
||||||
Atom atom_net_show_desktop;
|
Atom atom_net_show_desktop;
|
||||||
Atom atom_net_desktop_layout;
|
Atom atom_net_desktop_layout;
|
||||||
|
Atom atom_manager;
|
||||||
|
Atom atom_targets;
|
||||||
|
Atom atom_multiple;
|
||||||
|
Atom atom_timestamp;
|
||||||
|
Atom atom_version;
|
||||||
|
Atom atom_atom_pair;
|
||||||
|
|
||||||
/* This is the actual window from focus events,
|
/* This is the actual window from focus events,
|
||||||
* not the one we last set
|
* not the one we last set
|
||||||
@ -225,6 +231,12 @@ void meta_display_grab (MetaDisplay *display);
|
|||||||
void meta_display_ungrab (MetaDisplay *display);
|
void meta_display_ungrab (MetaDisplay *display);
|
||||||
gboolean meta_display_is_double_click (MetaDisplay *display);
|
gboolean meta_display_is_double_click (MetaDisplay *display);
|
||||||
|
|
||||||
|
void meta_display_unmanage_screen (MetaDisplay *display,
|
||||||
|
MetaScreen *screen);
|
||||||
|
|
||||||
|
void meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||||
|
MetaScreen *screen);
|
||||||
|
|
||||||
/* A given MetaWindow may have various X windows that "belong"
|
/* A given MetaWindow may have various X windows that "belong"
|
||||||
* to it, such as the frame window.
|
* to it, such as the frame window.
|
||||||
*/
|
*/
|
||||||
|
@ -128,6 +128,8 @@ main (int argc, char **argv)
|
|||||||
usage ();
|
usage ();
|
||||||
else if (strcmp (arg, "--sm-disable") == 0)
|
else if (strcmp (arg, "--sm-disable") == 0)
|
||||||
disable_sm = TRUE;
|
disable_sm = TRUE;
|
||||||
|
else if (strcmp (arg, "--replace") == 0)
|
||||||
|
meta_set_replace_current_wm (TRUE);
|
||||||
else if (strstr (arg, "--display=") == arg)
|
else if (strstr (arg, "--display=") == arg)
|
||||||
{
|
{
|
||||||
const char *disp;
|
const char *disp;
|
||||||
|
131
src/screen.c
131
src/screen.c
@ -1,7 +1,10 @@
|
|||||||
/* Metacity X screen handler */
|
/* Metacity X screen handler */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Havoc Pennington
|
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||||
|
* Copyright (C) 2002 Red Hat Inc.
|
||||||
|
* Some ICCCM manager selection code derived from fvwm2,
|
||||||
|
* Copyright (C) 2001 Dominik Vogt and fvwm2 team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -38,6 +41,7 @@
|
|||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
static char* get_screen_name (MetaDisplay *display,
|
static char* get_screen_name (MetaDisplay *display,
|
||||||
int number);
|
int number);
|
||||||
@ -168,6 +172,14 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
Window xroot;
|
Window xroot;
|
||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
|
Window new_wm_sn_owner;
|
||||||
|
Window current_wm_sn_owner;
|
||||||
|
gboolean replace_current_wm;
|
||||||
|
Atom wm_sn_atom;
|
||||||
|
char buf[128];
|
||||||
|
Time manager_timestamp;
|
||||||
|
|
||||||
|
replace_current_wm = meta_get_replace_current_wm ();
|
||||||
|
|
||||||
/* Only display->name, display->xdisplay, and display->error_traps
|
/* Only display->name, display->xdisplay, and display->error_traps
|
||||||
* can really be used in this function, since normally screens are
|
* can really be used in this function, since normally screens are
|
||||||
@ -191,7 +203,98 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select our root window events */
|
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 override 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 (display) != Success)
|
||||||
|
current_wm_sn_owner = None; /* don't wait for it to die later on */
|
||||||
|
}
|
||||||
|
|
||||||
|
new_wm_sn_owner = XCreateSimpleWindow (xdisplay, xroot,
|
||||||
|
-100, -100, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Generate a timestamp */
|
||||||
|
XSetWindowAttributes attrs;
|
||||||
|
XEvent event;
|
||||||
|
|
||||||
|
attrs.event_mask = PropertyChangeMask;
|
||||||
|
XChangeWindowAttributes (xdisplay, new_wm_sn_owner, CWEventMask, &attrs);
|
||||||
|
|
||||||
|
XChangeProperty (xdisplay,
|
||||||
|
new_wm_sn_owner, XA_WM_CLASS, XA_STRING, 8,
|
||||||
|
PropModeAppend, NULL, 0);
|
||||||
|
XWindowEvent (xdisplay, new_wm_sn_owner, PropertyChangeMask, &event);
|
||||||
|
attrs.event_mask = NoEventMask;
|
||||||
|
XChangeWindowAttributes (display->xdisplay,
|
||||||
|
new_wm_sn_owner, CWEventMask, &attrs);
|
||||||
|
|
||||||
|
manager_timestamp = event.xproperty.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
meta_error_trap_push (display);
|
||||||
|
|
||||||
/* We need to or with the existing event mask since
|
/* We need to or with the existing event mask since
|
||||||
@ -208,8 +311,11 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
FocusChangeMask | attr.your_event_mask);
|
FocusChangeMask | attr.your_event_mask);
|
||||||
if (meta_error_trap_pop (display) != Success)
|
if (meta_error_trap_pop (display) != Success)
|
||||||
{
|
{
|
||||||
meta_warning (_("Screen %d on display '%s' already has a window manager\n"),
|
meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
|
||||||
number, display->name);
|
number, display->name);
|
||||||
|
|
||||||
|
XDestroyWindow (xdisplay, new_wm_sn_owner);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +332,10 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
|
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
|
||||||
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
|
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
|
||||||
|
|
||||||
|
screen->wm_sn_selection_window = new_wm_sn_owner;
|
||||||
|
screen->wm_sn_atom = wm_sn_atom;
|
||||||
|
screen->wm_sn_timestamp = manager_timestamp;
|
||||||
|
|
||||||
screen->work_area_idle = 0;
|
screen->work_area_idle = 0;
|
||||||
|
|
||||||
screen->rows_of_workspaces = 1;
|
screen->rows_of_workspaces = 1;
|
||||||
@ -386,6 +496,14 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
void
|
void
|
||||||
meta_screen_free (MetaScreen *screen)
|
meta_screen_free (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
|
MetaDisplay *display;
|
||||||
|
|
||||||
|
display = screen->display;
|
||||||
|
|
||||||
|
meta_display_grab (display);
|
||||||
|
|
||||||
|
meta_display_unmanage_windows_for_screen (display, screen);
|
||||||
|
|
||||||
meta_prefs_remove_listener (prefs_changed_callback, screen);
|
meta_prefs_remove_listener (prefs_changed_callback, screen);
|
||||||
|
|
||||||
meta_screen_ungrab_keys (screen);
|
meta_screen_ungrab_keys (screen);
|
||||||
@ -397,14 +515,19 @@ meta_screen_free (MetaScreen *screen)
|
|||||||
meta_error_trap_push (screen->display);
|
meta_error_trap_push (screen->display);
|
||||||
XSelectInput (screen->display->xdisplay, screen->xroot, 0);
|
XSelectInput (screen->display->xdisplay, screen->xroot, 0);
|
||||||
if (meta_error_trap_pop (screen->display) != Success)
|
if (meta_error_trap_pop (screen->display) != Success)
|
||||||
meta_warning (_("Could not release screen %d on display '%s'\n"),
|
meta_warning (_("Could not release screen %d on display \"%s\"\n"),
|
||||||
screen->number, screen->display->name);
|
screen->number, screen->display->name);
|
||||||
|
|
||||||
|
XDestroyWindow (screen->display->xdisplay,
|
||||||
|
screen->wm_sn_selection_window);
|
||||||
|
|
||||||
if (screen->work_area_idle != 0)
|
if (screen->work_area_idle != 0)
|
||||||
g_source_remove (screen->work_area_idle);
|
g_source_remove (screen->work_area_idle);
|
||||||
|
|
||||||
g_free (screen->screen_name);
|
g_free (screen->screen_name);
|
||||||
g_free (screen);
|
g_free (screen);
|
||||||
|
|
||||||
|
meta_display_ungrab (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -60,6 +60,10 @@ struct _MetaScreen
|
|||||||
|
|
||||||
MetaCursor current_cursor;
|
MetaCursor current_cursor;
|
||||||
|
|
||||||
|
Window wm_sn_selection_window;
|
||||||
|
Atom wm_sn_atom;
|
||||||
|
Time wm_sn_timestamp;
|
||||||
|
|
||||||
MetaXineramaScreenInfo *xinerama_infos;
|
MetaXineramaScreenInfo *xinerama_infos;
|
||||||
int n_xinerama_infos;
|
int n_xinerama_infos;
|
||||||
|
|
||||||
|
13
src/util.c
13
src/util.c
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
static gboolean is_verbose = FALSE;
|
static gboolean is_verbose = FALSE;
|
||||||
static gboolean is_debugging = FALSE;
|
static gboolean is_debugging = FALSE;
|
||||||
|
static gboolean replace_current = FALSE;
|
||||||
static int no_prefix = 0;
|
static int no_prefix = 0;
|
||||||
static FILE* logfile = NULL;
|
static FILE* logfile = NULL;
|
||||||
|
|
||||||
@ -109,6 +110,18 @@ meta_set_debugging (gboolean setting)
|
|||||||
is_debugging = setting;
|
is_debugging = setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_get_replace_current_wm (void)
|
||||||
|
{
|
||||||
|
return replace_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_set_replace_current_wm (gboolean setting)
|
||||||
|
{
|
||||||
|
replace_current = setting;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_debug_spew (const char *format, ...)
|
meta_debug_spew (const char *format, ...)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,8 @@ gboolean meta_is_debugging (void);
|
|||||||
void meta_set_debugging (gboolean setting);
|
void meta_set_debugging (gboolean setting);
|
||||||
gboolean meta_is_syncing (void);
|
gboolean meta_is_syncing (void);
|
||||||
void meta_set_syncing (gboolean setting);
|
void meta_set_syncing (gboolean setting);
|
||||||
|
gboolean meta_get_replace_current_wm (void);
|
||||||
|
void meta_set_replace_current_wm (gboolean setting);
|
||||||
|
|
||||||
void meta_debug_spew (const char *format,
|
void meta_debug_spew (const char *format,
|
||||||
...) G_GNUC_PRINTF (1, 2);
|
...) G_GNUC_PRINTF (1, 2);
|
||||||
|
@ -280,7 +280,7 @@ meta_prop_get_utf8_string (MetaDisplay *display,
|
|||||||
name = XGetAtomName (display->xdisplay, xatom);
|
name = XGetAtomName (display->xdisplay, xatom);
|
||||||
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n"),
|
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n"),
|
||||||
name, xwindow);
|
name, xwindow);
|
||||||
XFree (name);
|
meta_XFree (name);
|
||||||
XFree (str);
|
XFree (str);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user