diff --git a/ChangeLog b/ChangeLog index 78279422d..5e128c963 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,25 @@ +2007-03-31 Elijah Newren + + Clean up event mask handling and meta_create_offscreen_window, to + prevent nasty metacity/gdk interactions causing hangs. See #354213. + + * src/screen.[ch] (meta_create_offscreen_window): + * src/display.c (meta_display_open): + * src/screen.c (meta_screen_new): + Add a valuemask parameter to meta_create_offscreen_window + + * src/display.c (meta_display_open): + make it explicit that we can't rely on PropertyNotify events for + the leader_window due to nasty metacity/gdk interaction + + * src/session.c (warn_about_lame_clients_and_finish_interact): + remove cut-and-paste code for timestamp pinging and just call + meta_display_get_current_time_roundtrip + 2007-03-30 Elijah Newren Add support for _NET_WM_USER_TIME_WINDOW in order to cut down on - context switches. + context switches. Fixes #354213. * src/display.c (meta_display_open): * src/display.h (struct _MetaDisplay): diff --git a/src/display.c b/src/display.c index ca8e82f57..22619616e 100644 --- a/src/display.c +++ b/src/display.c @@ -660,8 +660,15 @@ meta_display_open (void) gulong data[1]; XEvent event; - display->leader_window = meta_create_offscreen_window (display->xdisplay, - DefaultRootWindow (display->xdisplay)); + /* We only care about the PropertyChangeMask in the next 30 or so lines of + * code. Note that gdk will at some point unset the PropertyChangeMask for + * this window, so we can't rely on it still being set later. See bug + * 354213 for details. + */ + display->leader_window = + meta_create_offscreen_window (display->xdisplay, + DefaultRootWindow (display->xdisplay), + PropertyChangeMask); meta_prop_set_utf8_string_hint (display, display->leader_window, @@ -686,6 +693,13 @@ meta_display_open (void) &event); timestamp = event.xproperty.time; + + /* Make it painfully clear that we can't rely on PropertyNotify events on + * this window, as per bug 354213. + */ + XSelectInput(display->xdisplay, + display->leader_window, + NoEventMask); } /* Make a little window used only for pinging the server for timestamps; note @@ -693,7 +707,8 @@ meta_display_open (void) */ display->timestamp_pinging_window = meta_create_offscreen_window (display->xdisplay, - DefaultRootWindow (display->xdisplay)); + DefaultRootWindow (display->xdisplay), + PropertyChangeMask); display->last_focus_time = timestamp; display->last_user_time = timestamp; diff --git a/src/screen.c b/src/screen.c index 3cd4cb7ce..96db5659f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -435,7 +435,10 @@ meta_screen_new (MetaDisplay *display, current_wm_sn_owner = None; /* don't wait for it to die later on */ } - new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot); + /* 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; @@ -578,10 +581,10 @@ meta_screen_new (MetaDisplay *display, meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); /* Handle creating a no_focus_window for this screen */ - screen->no_focus_window = meta_create_offscreen_window (display->xdisplay, - screen->xroot); - XSelectInput (display->xdisplay, screen->no_focus_window, - FocusChangeMask | KeyPressMask | KeyReleaseMask); + screen->no_focus_window = + meta_create_offscreen_window (display->xdisplay, + screen->xroot, + FocusChangeMask|KeyPressMask|KeyReleaseMask); XMapWindow (display->xdisplay, screen->no_focus_window); /* Done with no_focus_window stuff */ @@ -1816,7 +1819,8 @@ meta_screen_update_workspace_names (MetaScreen *screen) Window meta_create_offscreen_window (Display *xdisplay, - Window parent) + Window parent, + long valuemask) { XSetWindowAttributes attrs; @@ -1825,7 +1829,7 @@ meta_create_offscreen_window (Display *xdisplay, * (but on a display we are managing at least one screen for) */ attrs.override_redirect = True; - attrs.event_mask = PropertyChangeMask; + attrs.event_mask = valuemask; return XCreateWindow (xdisplay, parent, diff --git a/src/screen.h b/src/screen.h index 009e22fd3..b4ad219fb 100644 --- a/src/screen.h +++ b/src/screen.h @@ -171,7 +171,8 @@ void meta_screen_update_workspace_names (MetaScreen *scree void meta_screen_queue_workarea_recalc (MetaScreen *screen); Window meta_create_offscreen_window (Display *xdisplay, - Window parent); + Window parent, + long valuemask); typedef struct MetaWorkspaceLayout MetaWorkspaceLayout; diff --git a/src/session.c b/src/session.c index ee93bfa53..dc2d6fd5c 100644 --- a/src/session.c +++ b/src/session.c @@ -82,7 +82,6 @@ static void save_state (void); static char* load_state (const char *previous_save_file); static void regenerate_save_file (void); static const char* full_save_file (void); -static const char* base_save_file (void); static void warn_about_lame_clients_and_finish_interact (gboolean shutdown); /* This is called when data is available on an ICE connection. */ @@ -1835,27 +1834,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown) lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title); - - { - XEvent property_event; - MetaDisplay *display; - - display = meta_displays_list ()->data; - - /* Using the property XA_PRIMARY because it's safe; nothing - * would use it as a property. The type doesn't matter. - */ - XChangeProperty (display->xdisplay, - display->leader_window, - XA_PRIMARY, XA_STRING, 8, - PropModeAppend, NULL, 0); - XWindowEvent (display->xdisplay, - display->leader_window, - PropertyChangeMask, - &property_event); - - timestamp = property_event.xproperty.time; - } + timestamp = meta_display_get_current_time_roundtrip (displays->data); sprintf (timestampbuf, "%u", timestamp); len = g_slist_length (lame);