CVS2003-05-29 Rob Adams <robadams@ucla.edu>

CVS2003-05-29  Rob Adams  <robadams@ucla.edu>

	Use a new property _METACITY_SENTINEL to eliminate a race
	condition that causes focus to behave badly with sloppy/mouse
	focus when lots of windows are mapped/unmapped, such as with a
	workspace switch.  The EnterNotify events on a display are ignored
	until the PropertyNotify sent after all the window maps is
	received.  This is a fix for #110970.

	* src/display.[ch]: New _METACITY_SENTINEL atom.
	(event_callback): ignore EnterNotify if the sentinel isn't clear,
	and decrement the sentinel counter when the PropertyNotify is
	received.
	(meta_display_increment_focus_sentinel): new function.  Increments
	the sentinel counter and updates the property on a root window on
	this display.
	(meta_display_decrement_focus_sentinel): Decrement the sentinel
	counter.
	(meta_display_focus_sentinel_clear): returns whether the sentinel
	counter is zero.

	* src/window.c (idle_calc_showing): after showing windows, call
	meta_display_increment_focus_sentinel on each display for windows
	to be shown.

	* src/workspace.[ch] (meta_workspace_activate_with_focus): new
	function activates a workspace and focuses a particular window
	after the workspace is activated.
	(meta_workspace_activate): now just a wrapper for
	meta_workspace_activate_with_focus

	* src/keybindings.c: use new meta_workspace_activate_with_focus
	function to ensure that focus will follow the focused window
	through the workspace switch.

: ----------------------------------------------------------------------
This commit is contained in:
Rob Adams
2003-05-30 20:24:00 +00:00
parent 903f3d7e6e
commit 3edad8599c
7 changed files with 140 additions and 9 deletions

View File

@ -1338,6 +1338,7 @@ idle_calc_showing (gpointer data)
GSList *should_show;
GSList *should_hide;
GSList *unplaced;
GSList *displays;
meta_topic (META_DEBUG_WINDOW_STATE,
"Clearing the calc_showing queue\n");
@ -1361,7 +1362,8 @@ idle_calc_showing (gpointer data)
should_show = NULL;
should_hide = NULL;
unplaced = NULL;
displays = NULL;
tmp = copy;
while (tmp != NULL)
{
@ -1438,12 +1440,31 @@ idle_calc_showing (gpointer data)
tmp = tmp->next;
}
/* for all displays used in the queue, set a sentinel property on
* the root window so that we can ignore EnterNotify events that
* occur before the window maps occur. This avoids a race
* condition. */
tmp = should_show;
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
if (g_slist_find (displays, window->display) == NULL)
{
displays = g_slist_prepend (displays, window->display);
meta_display_increment_focus_sentinel (window->display);
}
tmp = tmp->next;
}
g_slist_free (copy);
g_slist_free (unplaced);
g_slist_free (should_show);
g_slist_free (should_hide);
g_slist_free (displays);
destroying_windows_disallowed -= 1;