[mutter] Send _NET_WM_FRAME_DRAWN messages
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] Send _NET_WM_FRAME_DRAWN messages
- Date: Wed, 13 Feb 2013 14:50:15 +0000 (UTC)
commit fbfab93c63b3931cef0d11b7a559f210f8c649e6
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Mon Jun 13 18:09:59 2011 -0400
Send _NET_WM_FRAME_DRAWN messages
When the application provides the extended second counter for
_NET_WM_SYNC_REQUEST, send a client message with completion
information after the next redraw after each counter update
by the application.
https://bugzilla.gnome.org/show_bug.cgi?id=685463
src/compositor/compositor.c | 12 ++++++++
src/compositor/meta-window-actor-private.h | 1 +
src/compositor/meta-window-actor.c | 41 ++++++++++++++++++++++++++++
src/core/window-private.h | 4 +++
src/core/window.c | 3 ++
src/meta/atomnames.h | 1 +
6 files changed, 62 insertions(+), 0 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 87cd289..a1b361b 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -470,6 +470,16 @@ meta_check_end_modal (MetaScreen *screen)
}
}
+static void
+after_stage_paint (ClutterActor *stage,
+ MetaCompScreen *info)
+{
+ GList *l;
+
+ for (l = info->windows; l; l = l->next)
+ meta_window_actor_post_paint (l->data);
+}
+
void
meta_compositor_manage_screen (MetaCompositor *compositor,
MetaScreen *screen)
@@ -539,6 +549,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
meta_screen_set_cm_selection (screen);
info->stage = clutter_stage_new ();
+ g_signal_connect_after (info->stage, "paint",
+ G_CALLBACK (after_stage_paint), info);
meta_screen_get_size (screen, &width, &height);
clutter_actor_realize (info->stage);
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 0d653ec..01f7aaa 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -28,6 +28,7 @@ void meta_window_actor_process_damage (MetaWindowActor *self,
XDamageNotifyEvent *event);
void meta_window_actor_pre_paint (MetaWindowActor *self);
+void meta_window_actor_post_paint (MetaWindowActor *self);
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 6c147af..5c5c53b 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -97,6 +97,10 @@ struct _MetaWindowActorPrivate
gint map_in_progress;
gint destroy_in_progress;
+ /* If non-zero, the client needs to be sent a _NET_WM_FRAME_DRAWN
+ * client message with this value */
+ gint64 frame_drawn_serial;
+
guint visible : 1;
guint mapped : 1;
guint argb32 : 1;
@@ -2307,6 +2311,43 @@ meta_window_actor_pre_paint (MetaWindowActor *self)
check_needs_pixmap (self);
check_needs_reshape (self);
check_needs_shadow (self);
+
+ if (priv->window->needs_frame_drawn)
+ {
+ priv->frame_drawn_serial = priv->window->sync_request_serial;
+ priv->window->needs_frame_drawn = FALSE;
+ }
+}
+
+void
+meta_window_actor_post_paint (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv = self->priv;
+
+ if (priv->frame_drawn_serial != 0)
+ {
+ MetaScreen *screen = priv->screen;
+ MetaDisplay *display = meta_screen_get_display (screen);
+ Display *xdisplay = meta_display_get_xdisplay (display);
+
+ XClientMessageEvent ev;
+
+ ev.type = ClientMessage;
+ ev.window = meta_window_get_xwindow (priv->window);
+ ev.message_type = display->atom_WM_PROTOCOLS;
+ ev.format = 32;
+ ev.data.l[0] = display->atom__NET_WM_FRAME_DRAWN;
+ ev.data.l[1] = 0; /* timestamp */
+ ev.data.l[2] = priv->frame_drawn_serial & G_GUINT64_CONSTANT(0xffffffff);
+ ev.data.l[3] = priv->frame_drawn_serial >> 32;
+ ev.data.l[4] = 0; /* vblank estimate */
+
+ meta_error_trap_push (display);
+ XSendEvent (xdisplay, ev.window, False, 0, (XEvent*) &ev);
+ meta_error_trap_pop (display);
+
+ priv->frame_drawn_serial = 0;
+ }
}
void
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 04ee110..97b06ac 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -356,6 +356,10 @@ struct _MetaWindow
* also handles application frames */
guint extended_sync_request_counter : 1;
+ /* if TRUE, we still need to send a _NET_WM_FRAME_DRAWN message for the
+ * last update the sync request counter */
+ guint needs_frame_drawn : 1;
+
/* Note: can be NULL */
GSList *struts;
diff --git a/src/core/window.c b/src/core/window.c
index 5bf8f05..a4838d2 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -9493,6 +9493,9 @@ void
meta_window_update_sync_request_counter (MetaWindow *window,
gint64 new_counter_value)
{
+ if (window->extended_sync_request_counter)
+ window->needs_frame_drawn = TRUE;
+
window->sync_request_serial = new_counter_value;
meta_compositor_set_updates_frozen (window->display->compositor, window,
meta_window_updates_are_frozen (window));
diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h
index ca0520f..2b10fe2 100644
--- a/src/meta/atomnames.h
+++ b/src/meta/atomnames.h
@@ -174,6 +174,7 @@ item(_NET_WM_FULLSCREEN_MONITORS)
item(_NET_WM_STATE_FOCUSED)
item(_NET_WM_BYPASS_COMPOSITOR)
item(_NET_WM_OPAQUE_REGION)
+item(_NET_WM_FRAME_DRAWN)
#if 0
/* We apparently never use: */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]