x11: Cut some slack to clients doing slow draws/resizes

The timer to blacklist the window from frame sync is set at the time of
issuing the sync request, but not removed until the client replies to
the most recent wait serial.

This means that if the client is slowly catching up, the timeout would
fire up regardless of the client slowly updating the alarm to older
values.

Fix this by ensuring the timeout is reset everytime the sync request
counter is updated, to acknowledge the client is not irresponsive,
just slow.

https://bugzilla.gnome.org/show_bug.cgi?id=740424
This commit is contained in:
Carlos Garnacho 2015-02-27 17:00:43 +01:00
parent d3988c04d6
commit 94c3c8f412

View File

@ -949,6 +949,23 @@ sync_request_timeout (gpointer data)
return FALSE;
}
static void
reset_sync_request_timeout (MetaWindow *window)
{
if (window->sync_request_timeout_id != 0)
g_source_remove (window->sync_request_timeout_id);
/* We give the window 1 sec to respond to _NET_WM_SYNC_REQUEST;
* if this time expires, we consider the window unresponsive
* and resize it unsynchonized.
*/
window->sync_request_timeout_id = g_timeout_add (1000,
sync_request_timeout,
window);
g_source_set_name_by_id (window->sync_request_timeout_id,
"[mutter] sync_request_timeout");
}
static void
send_sync_request (MetaWindow *window)
{
@ -987,15 +1004,7 @@ send_sync_request (MetaWindow *window)
XSendEvent (window->display->xdisplay,
window->xwindow, False, 0, (XEvent*) &ev);
/* We give the window 1 sec to respond to _NET_WM_SYNC_REQUEST;
* if this time expires, we consider the window unresponsive
* and resize it unsynchonized.
*/
window->sync_request_timeout_id = g_timeout_add (1000,
sync_request_timeout,
window);
g_source_set_name_by_id (window->sync_request_timeout_id,
"[mutter] sync_request_timeout");
reset_sync_request_timeout (window);
meta_compositor_sync_updates_frozen (window->display->compositor, window);
}
@ -3338,27 +3347,34 @@ meta_window_x11_update_sync_request_counter (MetaWindow *window,
window->sync_request_serial = new_counter_value;
meta_compositor_sync_updates_frozen (window->display->compositor, window);
if (window == window->display->grab_window &&
meta_grab_op_is_resizing (window->display->grab_op) &&
new_counter_value >= window->sync_request_wait_serial &&
(!window->extended_sync_request_counter || new_counter_value % 2 == 0) &&
window->sync_request_timeout_id)
if (window->sync_request_timeout_id)
{
meta_topic (META_DEBUG_RESIZING,
"Alarm event received last motion x = %d y = %d\n",
window->display->grab_latest_motion_x,
window->display->grab_latest_motion_y);
if (new_counter_value < window->sync_request_wait_serial)
{
reset_sync_request_timeout (window);
}
else if (!window->extended_sync_request_counter || new_counter_value % 2 == 0)
{
g_source_remove (window->sync_request_timeout_id);
window->sync_request_timeout_id = 0;
g_source_remove (window->sync_request_timeout_id);
window->sync_request_timeout_id = 0;
if (window == window->display->grab_window &&
meta_grab_op_is_resizing (window->display->grab_op))
{
meta_topic (META_DEBUG_RESIZING,
"Alarm event received last motion x = %d y = %d\n",
window->display->grab_latest_motion_x,
window->display->grab_latest_motion_y);
/* This means we are ready for another configure;
* no pointer round trip here, to keep in sync */
meta_window_update_resize (window,
window->display->grab_last_user_action_was_snap,
window->display->grab_latest_motion_x,
window->display->grab_latest_motion_y,
TRUE);
/* This means we are ready for another configure;
* no pointer round trip here, to keep in sync */
meta_window_update_resize (window,
window->display->grab_last_user_action_was_snap,
window->display->grab_latest_motion_x,
window->display->grab_latest_motion_y,
TRUE);
}
}
}
/* If sync was previously disabled, turn it back on and hope