Starting to manage an X window is racy
I'm trying to resurrect the patch from https://bugzilla.gnome.org/show_bug.cgi?id=769387 - attached for reference.
This patch happened after the work to reduce the number of server grabs, but before the refactorings around moving X11 code from core/ to x11/ (05899596 and 86de79cf are particularly relevant).
The summary of this patch is that it wants meta_window_x11_manage()
to happen under an X server grab, so that window properties can be read without a chance of the application interfering. To do that, it re-introduces the recursive grab mechanism that was removed in #721345 (basically a display->server_grab_count
and associated meta_display_grab()/ungrab()
functions).
There are two icky parts to the patch, as far as I can tell:
-
It makes the following functions return immediately if the server is grabbed:
meta_display_grab_window_buttons
,meta_display_ungrab_window_buttons
,meta_display_grab_focus_window_button
,meta_display_ungrab_focus_window_button
,meta_window_grab_keys
,meta_window_ungrab_keys
. I don't know why they wouldn't work with a server grab in place; I haven't looked very closely. -
At the end of
meta_window_x11_manage()
, after it has ungrabbed the server, it callsmeta_display_grab_window_buttons
andmeta_window_grab_keys
so that they can do their work without the grab. I'm not sure why that is needed, since the only place where meta_window_x11_manage() is called is through this call chain:
meta_window_x11_new
_meta_window_shared_new
meta_window_manage
meta_window_x11_manage
And meta_window_x11_new() does the same calls to grab_window_buttons/etc. after shared_new/manage have been called.
Doing a server grab while managing a single window seems necessary to avoid race conditions. However, I am aware that doing individual server grabs during meta_display_manage_all_xwindows() sounds suboptimal. Maybe things need to be done in two stages at startup? with_server_grabbed(Get all the windows, manage them), then do things that can't be done inside the grab in a second pass?