mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-11 05:00:07 +00:00
Tightly integrate tree updates with surface rendering, so there's always at least one tree update before each surface commit, as required by Newton, without the AccessKit context having to do extra surface commits itself. This should also prevent multiple tree updates per frame across platforms.
This commit is contained in:
parent
9131b28834
commit
be7a23fa5e
@ -449,6 +449,14 @@ gdk_wayland_surface_commit (GdkSurface *surface)
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_force_next_commit (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
impl->has_pending_subsurface_commits = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_notify_committed (GdkSurface *surface)
|
||||
{
|
||||
|
@ -43,5 +43,8 @@ GType gdk_wayland_surface_get_type (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
struct wl_surface *gdk_wayland_surface_get_wl_surface (GdkSurface *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_surface_force_next_commit (GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -1853,3 +1853,12 @@ gtk_accesskit_context_add_to_update (GtkAccessKitContext *self,
|
||||
accesskit_tree_update_push_node (update, self->id,
|
||||
accesskit_node_builder_build (builder));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_accesskit_context_update_tree (GtkAccessKitContext *self)
|
||||
{
|
||||
if (!gtk_at_context_is_realized (GTK_AT_CONTEXT (self)))
|
||||
return;
|
||||
|
||||
gtk_accesskit_root_update_tree (self->root);
|
||||
}
|
||||
|
@ -42,4 +42,7 @@ void
|
||||
gtk_accesskit_context_add_to_update (GtkAccessKitContext *self,
|
||||
accesskit_tree_update *update);
|
||||
|
||||
void
|
||||
gtk_accesskit_context_update_tree (GtkAccessKitContext *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -44,7 +44,7 @@ struct _GtkAccessKitRoot
|
||||
GHashTable *contexts;
|
||||
GArray *update_queue;
|
||||
gboolean did_initial_update;
|
||||
gint update_id;
|
||||
gboolean requested_initial_tree;
|
||||
|
||||
#if defined(GDK_WINDOWING_WIN32)
|
||||
accesskit_windows_subclassing_adapter *adapter;
|
||||
@ -72,7 +72,6 @@ gtk_accesskit_root_finalize (GObject *gobject)
|
||||
|
||||
g_clear_pointer (&self->contexts, g_hash_table_destroy);
|
||||
g_clear_pointer (&self->update_queue, g_array_unref);
|
||||
g_clear_handle_id (&self->update_id, g_source_remove);
|
||||
|
||||
#if defined(GDK_WINDOWING_WIN32)
|
||||
g_clear_pointer (&self->adapter, accesskit_windows_subclassing_adapter_free);
|
||||
@ -223,6 +222,7 @@ request_initial_tree_main_thread (void *data)
|
||||
{
|
||||
GtkAccessKitRoot *self = data;
|
||||
accesskit_tree_update *update = build_full_update (self);
|
||||
self->requested_initial_tree = TRUE;
|
||||
self->did_initial_update = TRUE;
|
||||
return update;
|
||||
}
|
||||
@ -237,35 +237,21 @@ update_if_active (GtkAccessKitRoot *self, accesskit_tree_update_factory factory)
|
||||
if (events)
|
||||
accesskit_windows_queued_events_raise (events);
|
||||
#elif defined(GDK_WINDOWING_WAYLAND)
|
||||
/* TBD: Newton treats accessibility tree updates as double-buffered state,
|
||||
meaning the surface has to be committed after the update is sent.
|
||||
Can we more tightly integrate accessibility updates with rendering,
|
||||
so everything happens atomically as intended, rather than queuing
|
||||
an idle callback for the accessibility update, then committing
|
||||
the surface? */
|
||||
GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (self->root_widget));
|
||||
struct wl_surface *wl_surface = gdk_wayland_surface_get_wl_surface (surface);
|
||||
|
||||
gdk_wayland_surface_force_next_commit (surface);
|
||||
accesskit_newton_adapter_update_if_active (self->adapter, factory, self);
|
||||
wl_surface_commit (wl_surface);
|
||||
/* TODO: other platforms */
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
initial_update (gpointer data)
|
||||
static void
|
||||
queue_tree_update (GtkAccessKitRoot *self)
|
||||
{
|
||||
GtkAccessKitRoot *self = data;
|
||||
if (!gtk_widget_get_mapped (GTK_WIDGET (self->root_widget)))
|
||||
return;
|
||||
|
||||
self->update_id = 0;
|
||||
|
||||
if (gtk_widget_get_mapped (GTK_WIDGET (self->root_widget)))
|
||||
{
|
||||
update_if_active (self, build_full_update);
|
||||
self->did_initial_update = TRUE;
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (self->root_widget));
|
||||
gdk_surface_queue_render (surface);
|
||||
}
|
||||
|
||||
static accesskit_tree_update *
|
||||
@ -273,8 +259,8 @@ request_initial_tree_other_thread (void *data)
|
||||
{
|
||||
GtkAccessKitRoot *self = data;
|
||||
|
||||
if (!self->update_id)
|
||||
self->update_id = g_idle_add (initial_update, self);
|
||||
queue_tree_update (self);
|
||||
self->requested_initial_tree = TRUE;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -292,8 +278,8 @@ deactivate_accessibility (void *data)
|
||||
|
||||
/* TODO: Unrealize AT contexts. Which ones? */
|
||||
g_clear_pointer (&self->update_queue, g_array_unref);
|
||||
g_clear_handle_id (&self->update_id, g_source_remove);
|
||||
self->did_initial_update = FALSE;
|
||||
self->requested_initial_tree = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -485,19 +471,6 @@ build_incremental_update (void *data)
|
||||
return update;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
incremental_update (gpointer data)
|
||||
{
|
||||
GtkAccessKitRoot *self = data;
|
||||
|
||||
self->update_id = 0;
|
||||
|
||||
if (gtk_widget_get_mapped (GTK_WIDGET (self->root_widget)))
|
||||
update_if_active (self, build_incremental_update);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_accesskit_root_queue_update (GtkAccessKitRoot *self,
|
||||
guint32 id,
|
||||
@ -508,6 +481,17 @@ gtk_accesskit_root_queue_update (GtkAccessKitRoot *self,
|
||||
|
||||
add_to_update_queue (self, id, force_to_end);
|
||||
|
||||
if (!self->update_id)
|
||||
self->update_id = g_idle_add (incremental_update, self);
|
||||
queue_tree_update (self);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_accesskit_root_update_tree (GtkAccessKitRoot *self)
|
||||
{
|
||||
if (self->did_initial_update && self->update_queue)
|
||||
update_if_active (self, build_incremental_update);
|
||||
else if (self->requested_initial_tree)
|
||||
{
|
||||
update_if_active (self, build_full_update);
|
||||
self->did_initial_update = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -49,4 +49,7 @@ gtk_accesskit_root_queue_update (GtkAccessKitRoot *self,
|
||||
guint32 id,
|
||||
gboolean force_to_end);
|
||||
|
||||
void
|
||||
gtk_accesskit_root_update_tree (GtkAccessKitRoot *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -71,6 +71,7 @@
|
||||
#include "gtktestatcontextprivate.h"
|
||||
|
||||
#include "inspector/window.h"
|
||||
#include "a11y/gtkaccesskitcontextprivate.h"
|
||||
|
||||
#include "gdk/gdkeventsprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
@ -12077,6 +12078,7 @@ gtk_widget_render (GtkWidget *widget,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GtkATContext *at_ctx;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *root;
|
||||
@ -12090,6 +12092,11 @@ gtk_widget_render (GtkWidget *widget,
|
||||
if (!GTK_IS_NATIVE (widget))
|
||||
return;
|
||||
|
||||
at_ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
|
||||
if (GTK_IS_ACCESSKIT_CONTEXT (at_ctx))
|
||||
gtk_accesskit_context_update_tree (GTK_ACCESSKIT_CONTEXT (at_ctx));
|
||||
g_object_unref (at_ctx);
|
||||
|
||||
renderer = gtk_native_get_renderer (GTK_NATIVE (widget));
|
||||
if (renderer == NULL)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user