[mutter/wip/ssd-black-borders-fix: 21/22] window: ensure window titlebars are drawn in sync during resize
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/ssd-black-borders-fix: 21/22] window: ensure window titlebars are drawn in sync during resize
- Date: Thu, 29 Mar 2018 14:38:34 +0000 (UTC)
commit 7f4f5f5c4c4d52183a6b3113901c3fcfbdd9e824
Author: Ray Strode <rstrode redhat com>
Date: Thu Mar 15 18:14:43 2018 -0400
window: ensure window titlebars are drawn in sync during resize
mutter synchronizes drawing and resizes with Xwayland applications using
XSYNC counters, but it doesn't synchronize drawing and resizes with its
own titlebar painting code.
This commit makes mutter wait until the titlebar finishes drawing before
it unfreezes the corresponding window actor. This ensures the titlebar
and client area don't get out of sync with each other.
src/core/window-private.h | 6 ++++++
src/core/window.c | 12 ++++++++++++
src/ui/frames.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index afaa499e5..9964c8595 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -410,6 +410,9 @@ struct _MetaWindow
/* if TRUE, the X server hasn't yet committed a new buffer following resize of the frame/client window */
guint resize_pending : 1;
+ /* if TRUE, the window frame has a redraw queued */
+ guint frame_redraw_pending : 1;
+
/* if non-NULL, the bounds of the window frame */
cairo_region_t *frame_bounds;
@@ -788,6 +791,9 @@ void meta_window_set_resize_pending (MetaWindow *window,
gboolean is_resize_pending);
gboolean meta_window_resize_is_pending (MetaWindow *window);
+void meta_window_set_frame_redraw_pending (MetaWindow *window,
+ gboolean is_frame_redraw_pending);
+
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
diff --git a/src/core/window.c b/src/core/window.c
index 34f48712f..eaab29d2e 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3730,6 +3730,9 @@ meta_window_updates_are_frozen (MetaWindow *window)
if (window->sync_request_serial < window->sync_request_wait_serial)
return TRUE;
+ if (window->frame_redraw_pending)
+ return TRUE;
+
return FALSE;
}
@@ -6324,6 +6327,15 @@ meta_window_resize_is_pending (MetaWindow *window)
return window->resize_pending;
}
+void
+meta_window_set_frame_redraw_pending (MetaWindow *window,
+ gboolean is_frame_redraw_pending)
+{
+ window->frame_redraw_pending = is_frame_redraw_pending;
+
+ meta_compositor_sync_updates_frozen (window->display->compositor, window);
+}
+
static void
end_grab_op (MetaWindow *window,
const ClutterEvent *event)
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 129a9e59b..471bfa0c7 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -149,6 +149,7 @@ static void
invalidate_whole_window (MetaUIFrame *frame)
{
gdk_window_invalidate_rect (frame->window, NULL, FALSE);
+ meta_window_set_frame_redraw_pending (frame->meta_window, TRUE);
}
static MetaStyleInfo *
@@ -484,6 +485,27 @@ meta_ui_frame_attach_style (MetaUIFrame *frame)
variant));
}
+static void
+after_paint (GdkFrameClock *frame_clock,
+ MetaUIFrame *frame)
+{
+ MetaFrames *frames = frame->frames;
+ MetaWindow *window = frame->meta_window;
+
+ /* Make sure the damage is posted to the X server before
+ * we mark the frame redraw finished and unfreeze, so there's
+ * a wayland surface commit waiting for us at unfreeze time
+ */
+ if (meta_is_wayland_compositor ())
+ gdk_display_sync (gtk_widget_get_display (GTK_WIDGET (frames)));
+
+ meta_window_set_frame_redraw_pending (window, FALSE);
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (gdk_window_get_frame_clock (frame->window)),
+ G_CALLBACK (after_paint),
+ frame);
+}
+
MetaUIFrame *
meta_frames_manage_window (MetaFrames *frames,
MetaWindow *meta_window,
@@ -531,6 +553,10 @@ meta_ui_frame_unmanage (MetaUIFrame *frame)
frame->xwindow,
META_CURSOR_DEFAULT);
+ g_signal_handlers_disconnect_by_func (G_OBJECT (gdk_window_get_frame_clock (frame->window)),
+ G_CALLBACK (after_paint),
+ frame);
+
gdk_window_set_user_data (frame->window, NULL);
g_hash_table_remove (frames->frames, &frame->xwindow);
@@ -1396,6 +1422,11 @@ meta_frames_draw (GtkWidget *widget,
meta_ui_frame_paint (frame, cr);
cairo_region_destroy (region);
+ g_signal_connect (G_OBJECT (gdk_window_get_frame_clock (frame->window)),
+ "after-paint",
+ G_CALLBACK (after_paint),
+ frame);
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]