Big patch to cover about 6 different issues in order to correct rare

2005-02-20  Elijah Newren  <newren@gmail.com>

	Big patch to cover about 6 different issues in order to correct
	rare problems with timestamps (make sure window selected in
	tasklist actually gets focus, sanity check timestamps to avoid
	rogue apps hosing the system, correct the updating of
	net_wm_user_time, correctly handle timestamps of 0 when comparing
	xserver timestamps for those who have had their systems up for
	over 25 days or so, add some debugging information to verbose
	logs, some code cleanups).  Fixes all issues listed in #167358.

	* src/display.h: (struct _MetaDisplay): clarify comment on
	last_focus_time, introduce a new variable--last_user_time,
	(XSERVER_TIME_IS_BEFORE macro): put this functionality into a
	separate macro and then introduce a new macro with this name that
	uses the old one but adds additional special-case checks for
	timestamps that are 0, (comment to
	meta_display_set_input_focus_window): add information about how
	last_user_time should be used in this function

	* src/display.c (santiy_check_timestamps): new function,
	(meta_display_open): intialize display->last_user_time,
	(meta_display_get_current_time_roundtrip): use the timestamp,
	which is known to be good, in order to sanity_check_timestamps,
	(event_callback): use the new meta_window_ste_user_time() function
	in order to correct problems, use the timestamp of KeyPress and
	ButtonPress events, which are known to be good, in order to
	sanity_check_timestamps, (timestamp_too_old): new function for
	common behavior of meta_display_focus_the_no_focus_window and
	meta_display_set_input_focus_window, with added checking for
	display->last_user_time in addition to display->last_focus_time,
	(meta_display_set_input_focus_window): replace some of the code
	with a call to timestamp_too_old(),
	(meta_display_focus_the_no_focus_window): replace some of th ecode
	with a call to timestamp_too_old()

	* src/window.h: (meta_window_set_user_time): new function to
	abstract the many things that need to be done when updating the
	net_wm_user_time of any window

	* src/window.c: (meta_window_activate): add debugging spew, make
	sure the comparison is made with last_user_time NOT
	last_focus_time, use meta_window_set_user_time() function in order
	to correct problems, (meta_window_client_message): add a newline
	to a debugging message to make them easier to read,
	(meta_window_set_user_time): new function

	* src/window-props.c (reload_net_wm_user_time): use the new
	meta_window_ste_user_time() function in order to correct problems
This commit is contained in:
Elijah Newren
2005-02-20 17:14:16 +00:00
committed by Elijah Newren
parent 11508ce27e
commit 50312dd0e8
6 changed files with 229 additions and 44 deletions

View File

@@ -115,6 +115,9 @@ static void update_window_grab_modifiers (MetaDisplay *display);
static void prefs_changed_callback (MetaPreference pref,
void *data);
static void sanity_check_timestamps (MetaDisplay *display,
Time known_good_timestamp);
static void
set_utf8_string_hint (MetaDisplay *display,
Window xwindow,
@@ -645,6 +648,7 @@ meta_display_open (const char *name)
}
display->last_focus_time = timestamp;
display->last_user_time = timestamp;
display->compositor = meta_compositor_new (display);
screens = NULL;
@@ -1146,6 +1150,8 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display)
timestamp = property_event.xproperty.time;
}
sanity_check_timestamps (display, timestamp);
return timestamp;
}
@@ -1563,11 +1569,8 @@ event_callback (XEvent *event,
if (window && ((event->type == KeyPress) || (event->type == ButtonPress)))
{
g_assert (CurrentTime != display->current_time);
meta_topic (META_DEBUG_WINDOW_STATE,
"Metacity set %s's net_wm_user_time to %lu.\n",
window->desc, display->current_time);
window->net_wm_user_time_set = TRUE;
window->net_wm_user_time = display->current_time;
meta_window_set_user_time (window, display->current_time);
sanity_check_timestamps (display, display->current_time);
}
switch (event->type)
@@ -4648,21 +4651,114 @@ meta_display_focus_sentinel_clear (MetaDisplay *display)
return (display->sentinel_counter == 0);
}
static void
sanity_check_timestamps (MetaDisplay *display,
Time timestamp)
{
if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time))
{
meta_warning ("last_focus_time (%lu) is greater than comparison "
"timestamp (%lu). This most likely represents a buggy "
"client sending inaccurate timestamps in messages such as "
"_NET_ACTIVE_WINDOW. Trying to work around...\n",
display->last_focus_time, (unsigned long)timestamp);
display->last_focus_time = timestamp;
}
if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_user_time))
{
GSList *windows;
GSList *tmp;
meta_warning ("last_user_time (%lu) is greater than comparison "
"timestamp (%lu). This most likely represents a buggy "
"client sending inaccurate timestamps in messages such as "
"_NET_ACTIVE_WINDOW. Trying to work around...\n",
display->last_user_time, (unsigned long)timestamp);
display->last_user_time = timestamp;
windows = meta_display_list_windows (display);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
{
meta_warning ("%s appears to be one of the offending windows "
"with a timestamp of %lu. Working around...\n",
window->desc, window->net_wm_user_time);
window->net_wm_user_time = timestamp;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
}
static gboolean
timestamp_too_old (MetaDisplay *display,
MetaWindow *window,
Time *timestamp)
{
/* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow
* us to sanity check the timestamp here and ensure it doesn't correspond to
* a future time (though we would want to rename to
* timestamp_too_old_or_in_future).
*/
MetaWindow *focus_window;
focus_window = display->focus_window;
if (*timestamp == CurrentTime)
{
meta_warning ("Got a request to focus %s with a timestamp of 0. This "
"shouldn't happen!\n",
window ? window->desc : "the no_focus_window");
meta_print_backtrace ();
*timestamp = meta_display_get_current_time_roundtrip (display);
return FALSE;
}
else if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_focus_time))
{
if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_user_time))
{
meta_topic (META_DEBUG_FOCUS,
"Ignoring focus request for %s since %lu "
"is less than %lu and %lu.\n",
window ? window->desc : "the no_focus_window",
*timestamp,
(unsigned long) display->last_user_time,
(unsigned long) display->last_focus_time);
return TRUE;
}
else
{
meta_topic (META_DEBUG_FOCUS,
"Received focus request for %s which is newer than most "
"recent user_time, but less recent than "
"last_focus_time (%lu < %lu < %lu); adjusting "
"accordingly. (See bug 167358)\n",
window ? window->desc : "the no_focus_window",
display->last_user_time,
*timestamp,
display->last_focus_time);
*timestamp = display->last_focus_time;
return FALSE;
}
}
return FALSE;
}
void
meta_display_set_input_focus_window (MetaDisplay *display,
MetaWindow *window,
gboolean focus_frame,
Time timestamp)
{
if (timestamp == CurrentTime)
{
meta_warning ("meta_display_set_input_focus_window called with a "
"timestamp of 0 for window %s. This shouldn't happen!\n",
window->desc);
meta_print_backtrace ();
timestamp = meta_display_get_current_time_roundtrip (display);
}
else if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time))
if (timestamp_too_old (display, window, &timestamp))
return;
XSetInputFocus (display->xdisplay,
@@ -4680,18 +4776,8 @@ void
meta_display_focus_the_no_focus_window (MetaDisplay *display,
Time timestamp)
{
if (timestamp == CurrentTime)
{
meta_warning ("meta_display_focus_the_no_focus_window called with a "
"timestamp of 0. This shouldn't happen!\n");
meta_print_backtrace ();
timestamp = meta_display_get_current_time_roundtrip (display);
}
else if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time))
{
meta_warning ("Ignoring focus request for no_focus_window since %lu is less than %lu.\n", timestamp, display->last_focus_time);
if (timestamp_too_old (display, NULL, &timestamp))
return;
}
XSetInputFocus (display->xdisplay,
display->no_focus_window,