mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
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.
This commit is contained in:
parent
0d1cee5123
commit
7f4f5f5c4c
@ -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 */
|
/* if TRUE, the X server hasn't yet committed a new buffer following resize of the frame/client window */
|
||||||
guint resize_pending : 1;
|
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 */
|
/* if non-NULL, the bounds of the window frame */
|
||||||
cairo_region_t *frame_bounds;
|
cairo_region_t *frame_bounds;
|
||||||
|
|
||||||
@ -788,6 +791,9 @@ void meta_window_set_resize_pending (MetaWindow *window,
|
|||||||
gboolean is_resize_pending);
|
gboolean is_resize_pending);
|
||||||
gboolean meta_window_resize_is_pending (MetaWindow *window);
|
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_began (MetaWindow *window, MetaGrabOp op);
|
||||||
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
|
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
|
||||||
|
|
||||||
|
@ -3730,6 +3730,9 @@ meta_window_updates_are_frozen (MetaWindow *window)
|
|||||||
if (window->sync_request_serial < window->sync_request_wait_serial)
|
if (window->sync_request_serial < window->sync_request_wait_serial)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
if (window->frame_redraw_pending)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6324,6 +6327,15 @@ meta_window_resize_is_pending (MetaWindow *window)
|
|||||||
return window->resize_pending;
|
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
|
static void
|
||||||
end_grab_op (MetaWindow *window,
|
end_grab_op (MetaWindow *window,
|
||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
|
@ -149,6 +149,7 @@ static void
|
|||||||
invalidate_whole_window (MetaUIFrame *frame)
|
invalidate_whole_window (MetaUIFrame *frame)
|
||||||
{
|
{
|
||||||
gdk_window_invalidate_rect (frame->window, NULL, FALSE);
|
gdk_window_invalidate_rect (frame->window, NULL, FALSE);
|
||||||
|
meta_window_set_frame_redraw_pending (frame->meta_window, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaStyleInfo *
|
static MetaStyleInfo *
|
||||||
@ -484,6 +485,27 @@ meta_ui_frame_attach_style (MetaUIFrame *frame)
|
|||||||
variant));
|
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 *
|
MetaUIFrame *
|
||||||
meta_frames_manage_window (MetaFrames *frames,
|
meta_frames_manage_window (MetaFrames *frames,
|
||||||
MetaWindow *meta_window,
|
MetaWindow *meta_window,
|
||||||
@ -531,6 +553,10 @@ meta_ui_frame_unmanage (MetaUIFrame *frame)
|
|||||||
frame->xwindow,
|
frame->xwindow,
|
||||||
META_CURSOR_DEFAULT);
|
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);
|
gdk_window_set_user_data (frame->window, NULL);
|
||||||
|
|
||||||
g_hash_table_remove (frames->frames, &frame->xwindow);
|
g_hash_table_remove (frames->frames, &frame->xwindow);
|
||||||
@ -1396,6 +1422,11 @@ meta_frames_draw (GtkWidget *widget,
|
|||||||
meta_ui_frame_paint (frame, cr);
|
meta_ui_frame_paint (frame, cr);
|
||||||
cairo_region_destroy (region);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user