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
This commit is contained in:
parent
70c0d39fa7
commit
fbfab93c63
@ -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
|
void
|
||||||
meta_compositor_manage_screen (MetaCompositor *compositor,
|
meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||||
MetaScreen *screen)
|
MetaScreen *screen)
|
||||||
@ -539,6 +549,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
|||||||
meta_screen_set_cm_selection (screen);
|
meta_screen_set_cm_selection (screen);
|
||||||
|
|
||||||
info->stage = clutter_stage_new ();
|
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);
|
meta_screen_get_size (screen, &width, &height);
|
||||||
clutter_actor_realize (info->stage);
|
clutter_actor_realize (info->stage);
|
||||||
|
@ -28,6 +28,7 @@ void meta_window_actor_process_damage (MetaWindowActor *self,
|
|||||||
XDamageNotifyEvent *event);
|
XDamageNotifyEvent *event);
|
||||||
|
|
||||||
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
||||||
|
void meta_window_actor_post_paint (MetaWindowActor *self);
|
||||||
|
|
||||||
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
||||||
|
|
||||||
|
@ -97,6 +97,10 @@ struct _MetaWindowActorPrivate
|
|||||||
gint map_in_progress;
|
gint map_in_progress;
|
||||||
gint destroy_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 visible : 1;
|
||||||
guint mapped : 1;
|
guint mapped : 1;
|
||||||
guint argb32 : 1;
|
guint argb32 : 1;
|
||||||
@ -2307,6 +2311,43 @@ meta_window_actor_pre_paint (MetaWindowActor *self)
|
|||||||
check_needs_pixmap (self);
|
check_needs_pixmap (self);
|
||||||
check_needs_reshape (self);
|
check_needs_reshape (self);
|
||||||
check_needs_shadow (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
|
void
|
||||||
|
@ -356,6 +356,10 @@ struct _MetaWindow
|
|||||||
* also handles application frames */
|
* also handles application frames */
|
||||||
guint extended_sync_request_counter : 1;
|
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 */
|
/* Note: can be NULL */
|
||||||
GSList *struts;
|
GSList *struts;
|
||||||
|
|
||||||
|
@ -9493,6 +9493,9 @@ void
|
|||||||
meta_window_update_sync_request_counter (MetaWindow *window,
|
meta_window_update_sync_request_counter (MetaWindow *window,
|
||||||
gint64 new_counter_value)
|
gint64 new_counter_value)
|
||||||
{
|
{
|
||||||
|
if (window->extended_sync_request_counter)
|
||||||
|
window->needs_frame_drawn = TRUE;
|
||||||
|
|
||||||
window->sync_request_serial = new_counter_value;
|
window->sync_request_serial = new_counter_value;
|
||||||
meta_compositor_set_updates_frozen (window->display->compositor, window,
|
meta_compositor_set_updates_frozen (window->display->compositor, window,
|
||||||
meta_window_updates_are_frozen (window));
|
meta_window_updates_are_frozen (window));
|
||||||
|
@ -174,6 +174,7 @@ item(_NET_WM_FULLSCREEN_MONITORS)
|
|||||||
item(_NET_WM_STATE_FOCUSED)
|
item(_NET_WM_STATE_FOCUSED)
|
||||||
item(_NET_WM_BYPASS_COMPOSITOR)
|
item(_NET_WM_BYPASS_COMPOSITOR)
|
||||||
item(_NET_WM_OPAQUE_REGION)
|
item(_NET_WM_OPAQUE_REGION)
|
||||||
|
item(_NET_WM_FRAME_DRAWN)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* We apparently never use: */
|
/* We apparently never use: */
|
||||||
|
Loading…
Reference in New Issue
Block a user