mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 14:10:30 +00:00
wayland: Request frame callbacks on subsurfaces
We need this for the case when the subsurface completely covers up the main surface. Without it, we just stop updating.
This commit is contained in:
parent
59dbfb0843
commit
ca054bfdc9
@ -25,6 +25,8 @@ struct _GdkWaylandSubsurface
|
||||
|
||||
struct wl_region *opaque_region;
|
||||
|
||||
struct wl_callback *frame_callback;
|
||||
|
||||
gboolean above_parent;
|
||||
};
|
||||
|
||||
@ -34,3 +36,6 @@ struct _GdkWaylandSubsurfaceClass
|
||||
};
|
||||
|
||||
GType gdk_wayland_subsurface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gdk_wayland_subsurface_request_frame (GdkSubsurface *subsurface);
|
||||
void gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *subsurface);
|
||||
|
@ -41,6 +41,7 @@ gdk_wayland_subsurface_finalize (GObject *object)
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (object);
|
||||
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
|
||||
g_clear_pointer (&self->opaque_region, wl_region_destroy);
|
||||
g_clear_pointer (&self->viewport, wp_viewport_destroy);
|
||||
g_clear_pointer (&self->subsurface, wl_subsurface_destroy);
|
||||
@ -337,3 +338,39 @@ gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
|
||||
subsurface_class->place_below = gdk_wayland_subsurface_place_below;
|
||||
subsurface_class->is_above_parent = gdk_wayland_subsurface_is_above_parent;
|
||||
};
|
||||
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkSubsurface *sub = data;
|
||||
|
||||
g_assert (((GdkWaylandSubsurface *)sub)->frame_callback == callback);
|
||||
g_assert (!GDK_SURFACE_DESTROYED (sub->parent));
|
||||
|
||||
gdk_wayland_surface_frame_callback (sub->parent, time);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
frame_callback
|
||||
};
|
||||
|
||||
void
|
||||
gdk_wayland_subsurface_request_frame (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
|
||||
|
||||
self->frame_callback = wl_surface_frame (self->surface);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) self->frame_callback, NULL);
|
||||
wl_callback_add_listener (self->frame_callback, &frame_listener, self);
|
||||
wl_surface_commit (self->surface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
|
||||
|
||||
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
|
||||
}
|
||||
|
@ -123,6 +123,9 @@ void gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
|
||||
void gdk_wayland_surface_freeze_state (GdkSurface *surface);
|
||||
void gdk_wayland_surface_thaw_state (GdkSurface *surface);
|
||||
|
||||
void gdk_wayland_surface_frame_callback (GdkSurface *surface,
|
||||
uint32_t time);
|
||||
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DRAG_SURFACE (gdk_wayland_drag_surface_get_type ())
|
||||
GType gdk_wayland_drag_surface_get_type (void) G_GNUC_CONST;
|
||||
|
@ -264,12 +264,10 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
void
|
||||
gdk_wayland_surface_frame_callback (GdkSurface *surface,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkSurface *surface = data;
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
@ -279,11 +277,14 @@ frame_callback (void *data,
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "frame event");
|
||||
GDK_DISPLAY_DEBUG (GDK_DISPLAY (display_wayland), EVENTS, "frame %p", surface);
|
||||
|
||||
g_assert (impl->frame_callback == callback);
|
||||
g_assert (!GDK_SURFACE_DESTROYED (surface));
|
||||
|
||||
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
|
||||
|
||||
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
|
||||
{
|
||||
GdkSubsurface *subsurface = gdk_surface_get_subsurface (surface, i);
|
||||
gdk_wayland_subsurface_clear_frame_callback (subsurface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->handle_frame (impl);
|
||||
|
||||
if (impl->awaiting_frame_frozen)
|
||||
@ -321,6 +322,19 @@ frame_callback (void *data,
|
||||
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkSurface *surface = data;
|
||||
|
||||
g_assert (GDK_WAYLAND_SURFACE (surface)->frame_callback == callback);
|
||||
g_assert (!GDK_SURFACE_DESTROYED (surface));
|
||||
|
||||
gdk_wayland_surface_frame_callback (surface, time);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
frame_callback
|
||||
};
|
||||
@ -382,6 +396,13 @@ gdk_wayland_surface_request_frame (GdkSurface *surface)
|
||||
self->frame_callback = wl_surface_frame (self->display_server.wl_surface);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) self->frame_callback, NULL);
|
||||
wl_callback_add_listener (self->frame_callback, &frame_listener, surface);
|
||||
|
||||
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
|
||||
{
|
||||
GdkSubsurface *subsurface = gdk_surface_get_subsurface (surface, i);
|
||||
gdk_wayland_subsurface_request_frame (subsurface);
|
||||
}
|
||||
|
||||
self->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user