[mutter] Make handling of windows that don't respond to _NET_WM_SYNC_REQUEST reliable
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] Make handling of windows that don't respond to _NET_WM_SYNC_REQUEST reliable
- Date: Thu, 14 Mar 2013 12:01:55 +0000 (UTC)
commit 97a4cc8c9bfd2dc023cc259ab1f2ec24238c8770
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Mar 13 15:31:11 2013 -0400
Make handling of windows that don't respond to _NET_WM_SYNC_REQUEST reliable
Previously, we were handling failure to respond to _NET_WM_SYNC_REQUEST
in the code path for throttling motion events. But this meant that
if a window didn't respond to _NET_WM_SYNC_REQUEST and there were no
motion events - for a keyboard resize, or after the end of the grab
operation - it would end up in a stuck state.
Use a separate per-window timeout to reliably catch the failure to respond
to _NET_WM_SYNC_REQUEST.
https://bugzilla.gnome.org/show_bug.cgi?id=694046
src/core/display.c | 2 -
src/core/window-private.h | 2 +-
src/core/window.c | 139 +++++++++++++++++++++++----------------------
3 files changed, 71 insertions(+), 72 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index 2c53355..2747304 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -3962,8 +3962,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_window->sync_request_counter != None)
{
meta_window_create_sync_request_alarm (display->grab_window);
- window->sync_request_time.tv_sec = 0;
- window->sync_request_time.tv_usec = 0;
}
#endif
}
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 60e64bd..e9f935f 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -364,7 +364,7 @@ struct _MetaWindow
XSyncCounter sync_request_counter;
gint64 sync_request_serial;
gint64 sync_request_wait_serial;
- GTimeVal sync_request_time;
+ guint sync_request_timeout_id;
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
XSyncAlarm sync_request_alarm;
#endif
diff --git a/src/core/window.c b/src/core/window.c
index 1947d35..46e276d 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1020,8 +1020,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
#ifdef HAVE_XSYNC
window->sync_request_counter = None;
window->sync_request_serial = 0;
- window->sync_request_time.tv_sec = 0;
- window->sync_request_time.tv_usec = 0;
+ window->sync_request_timeout_id = 0;
window->sync_request_alarm = None;
#endif
@@ -1774,6 +1773,12 @@ meta_window_unmanage (MetaWindow *window,
invalidate_work_areas (window);
}
+ if (window->sync_request_timeout_id)
+ {
+ g_source_remove (window->sync_request_timeout_id);
+ window->sync_request_timeout_id = 0;
+ }
+
if (window->display->grab_window == window)
meta_display_end_grab_op (window->display, timestamp);
@@ -4616,6 +4621,38 @@ meta_window_destroy_sync_request_alarm (MetaWindow *window)
}
#ifdef HAVE_XSYNC
+static gboolean
+sync_request_timeout (gpointer data)
+{
+ MetaWindow *window = data;
+
+ window->sync_request_timeout_id = 0;
+
+ /* We have now waited for more than a second for the
+ * application to respond to the sync request
+ */
+ window->disable_sync = TRUE;
+
+ /* Reset the wait serial, so we don't continue freezing
+ * window updates
+ */
+ window->sync_request_wait_serial = 0;
+ meta_compositor_set_updates_frozen (window->display->compositor, window,
+ meta_window_updates_are_frozen (window));
+
+ if (window == window->display->grab_window &&
+ meta_grab_op_is_resizing (window->display->grab_op))
+ {
+ update_resize (window,
+ window->display->grab_last_user_action_was_snap,
+ window->display->grab_latest_motion_x,
+ window->display->grab_latest_motion_y,
+ TRUE);
+ }
+
+ return FALSE;
+}
+
static void
send_sync_request (MetaWindow *window)
{
@@ -4654,7 +4691,13 @@ send_sync_request (MetaWindow *window)
XSendEvent (window->display->xdisplay,
window->xwindow, False, 0, (XEvent*) &ev);
- g_get_current_time (&window->sync_request_time);
+ /* 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);
meta_compositor_set_updates_frozen (window->display->compositor, window,
meta_window_updates_are_frozen (window));
@@ -5206,8 +5249,7 @@ meta_window_move_resize_internal (MetaWindow *window,
!window->disable_sync &&
window->sync_request_counter != None &&
window->sync_request_alarm != None &&
- window->sync_request_time.tv_usec == 0 &&
- window->sync_request_time.tv_sec == 0)
+ window->sync_request_timeout_id == 0)
{
send_sync_request (window);
}
@@ -8821,81 +8863,39 @@ check_moveresize_frequency (MetaWindow *window,
gdouble *remaining)
{
GTimeVal current_time;
+ const double max_resizes_per_second = 25.0;
+ const double ms_between_resizes = 1000.0 / max_resizes_per_second;
+ double elapsed;
g_get_current_time (¤t_time);
#ifdef HAVE_XSYNC
+ /* If we are throttling via _NET_WM_SYNC_REQUEST, we don't need
+ * an artificial timeout-based throttled */
if (!window->disable_sync &&
window->sync_request_alarm != None)
- {
- if (window->sync_request_time.tv_sec != 0 ||
- window->sync_request_time.tv_usec != 0)
- {
- double elapsed =
- time_diff (¤t_time, &window->sync_request_time);
-
- if (elapsed < 1000.0)
- {
- /* We want to be sure that the timeout happens at
- * a time where elapsed will definitely be
- * greater than 1000, so we can disable sync
- */
- if (remaining)
- *remaining = 1000.0 - elapsed + 100;
-
- return FALSE;
- }
- else
- {
- /* We have now waited for more than a second for the
- * application to respond to the sync request
- */
- window->disable_sync = TRUE;
-
- /* Reset the wait serial, so we don't continue freezing
- * window updates
- */
- window->sync_request_wait_serial = 0;
- meta_compositor_set_updates_frozen (window->display->compositor, window,
- meta_window_updates_are_frozen (window));
-
- return TRUE;
- }
- }
- else
- {
- /* No outstanding sync requests. Go ahead and resize
- */
- return TRUE;
- }
- }
- else
+ return TRUE;
#endif /* HAVE_XSYNC */
- {
- const double max_resizes_per_second = 25.0;
- const double ms_between_resizes = 1000.0 / max_resizes_per_second;
- double elapsed;
- elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_time);
+ elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_time);
- if (elapsed >= 0.0 && elapsed < ms_between_resizes)
- {
- meta_topic (META_DEBUG_RESIZING,
- "Delaying move/resize as only %g of %g ms elapsed\n",
- elapsed, ms_between_resizes);
+ if (elapsed >= 0.0 && elapsed < ms_between_resizes)
+ {
+ meta_topic (META_DEBUG_RESIZING,
+ "Delaying move/resize as only %g of %g ms elapsed\n",
+ elapsed, ms_between_resizes);
- if (remaining)
- *remaining = (ms_between_resizes - elapsed);
+ if (remaining)
+ *remaining = (ms_between_resizes - elapsed);
- return FALSE;
- }
+ return FALSE;
+ }
- meta_topic (META_DEBUG_RESIZING,
- " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
- elapsed / 1000.0, 1.0 / max_resizes_per_second);
+ meta_topic (META_DEBUG_RESIZING,
+ " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
+ elapsed / 1000.0, 1.0 / max_resizes_per_second);
- return TRUE;
- }
+ return TRUE;
}
static gboolean
@@ -9625,8 +9625,9 @@ meta_window_update_sync_request_counter (MetaWindow *window,
* busy with a pagefault or a long computation).
*/
window->disable_sync = FALSE;
- window->sync_request_time.tv_sec = 0;
- window->sync_request_time.tv_usec = 0;
+
+ g_source_remove (window->sync_request_timeout_id);
+ window->sync_request_timeout_id = 0;
/* This means we are ready for another configure;
* no pointer round trip here, to keep in sync */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]