forked from AuroraMiddleware/gtk
a11y: Add a display to GtkATContext
Since we need to check at run time what kind of AT context to use, we need a hook into the whole GDK backend machinery. The display connection seems to be the best choice, in this case, as it allows us to determine whether we're running on an X11 or Wayland system, and thus whether we should create a GtkAtSpiContext. This requires some surgery to fix the GtkATContext creation function, in order to include a GdkDisplay instance.
This commit is contained in:
parent
8f19bb0832
commit
8c18480092
@ -22,6 +22,13 @@
|
||||
|
||||
#include "gtkatspicontextprivate.h"
|
||||
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
# include <gdk/wayland/gdkwaylanddisplay.h>
|
||||
#endif
|
||||
#if defined(GDK_WINDOWING_X11)
|
||||
# include <gdk/x11/gdkx11display.h>
|
||||
#endif
|
||||
|
||||
struct _GtkAtSpiContext
|
||||
{
|
||||
GtkATContext parent_instance;
|
||||
@ -62,24 +69,30 @@ gtk_at_spi_context_init (GtkAtSpiContext *self)
|
||||
{
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_at_spi_context_new:
|
||||
* @accessible_role: the accessible role for the AT context
|
||||
* @accessible: the #GtkAccessible instance which owns the context
|
||||
*
|
||||
* Creates a new #GtkAtSpiContext instance for @accessible, using the
|
||||
* given @accessible_role.
|
||||
*
|
||||
* Returns: (transfer full): the newly created #GtkAtSpiContext
|
||||
*/
|
||||
GtkATContext *
|
||||
gtk_at_spi_context_new (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible * accessible)
|
||||
gtk_at_spi_create_context (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible *accessible,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (accessible), NULL);
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_AT_SPI_CONTEXT,
|
||||
"accessible-role", accessible_role,
|
||||
"accessible", accessible,
|
||||
NULL);
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
return g_object_new (GTK_TYPE_AT_SPI_CONTEXT,
|
||||
"accessible-role", accessible_role,
|
||||
"accessible", accessible,
|
||||
"display", display,
|
||||
NULL);
|
||||
#endif
|
||||
#if defined(GDK_WINDOWING_X11)
|
||||
if (GDK_IS_X11_DISPLAY (display))
|
||||
return g_object_new (GTK_TYPE_AT_SPI_CONTEXT,
|
||||
"accessible-role", accessible_role,
|
||||
"accessible", accessible,
|
||||
"display", display,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ G_BEGIN_DECLS
|
||||
G_DECLARE_FINAL_TYPE (GtkAtSpiContext, gtk_at_spi_context, GTK, AT_SPI_CONTEXT, GtkATContext)
|
||||
|
||||
GtkATContext *
|
||||
gtk_at_spi_context_new (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible *accessible);
|
||||
gtk_at_spi_create_context (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible *accessible,
|
||||
GdkDisplay *display);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -50,6 +50,7 @@ enum
|
||||
{
|
||||
PROP_ACCESSIBLE_ROLE = 1,
|
||||
PROP_ACCESSIBLE,
|
||||
PROP_DISPLAY,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@ -95,6 +96,10 @@ gtk_at_context_set_property (GObject *gobject,
|
||||
self->accessible = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
self->display = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
@ -118,6 +123,10 @@ gtk_at_context_get_property (GObject *gobject,
|
||||
g_value_set_object (value, self->accessible);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, self->display);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
@ -177,6 +186,20 @@ gtk_at_context_class_init (GtkATContextClass *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GtkATContext:display:
|
||||
*
|
||||
* The #GdkDisplay for the #GtkATContext.
|
||||
*/
|
||||
obj_props[PROP_DISPLAY] =
|
||||
g_param_spec_object ("display",
|
||||
"Display",
|
||||
"The display connection",
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GtkATContext::state-change:
|
||||
* @self: the #GtkATContext
|
||||
@ -359,16 +382,33 @@ gtk_at_context_get_accessible_role (GtkATContext *self)
|
||||
return self->accessible_role;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_at_context_get_display:
|
||||
* @self: a #GtkATContext
|
||||
*
|
||||
* Retrieves the #GdkDisplay used to create the context.
|
||||
*
|
||||
* Returns: (transfer none): a #GdkDisplay
|
||||
*/
|
||||
GdkDisplay *
|
||||
gtk_at_context_get_display (GtkATContext *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_AT_CONTEXT (self), NULL);
|
||||
|
||||
return self->display;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkATContext * (* create_context) (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible *accessible);
|
||||
GtkAccessible *accessible,
|
||||
GdkDisplay *display);
|
||||
} a11y_backends[] = {
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
{ "AT-SPI", _gtk_at_spi_context_new },
|
||||
{ "AT-SPI (Wayland)", gtk_at_spi_create_context },
|
||||
#endif
|
||||
#if defined(GDK_WINDOWING_X11)
|
||||
{ "AT-SPI", gtk_at_spi_context_new },
|
||||
{ "AT-SPI (X11)", gtk_at_spi_create_context },
|
||||
#endif
|
||||
{ NULL, NULL },
|
||||
};
|
||||
@ -377,9 +417,10 @@ static const struct {
|
||||
* gtk_at_context_create: (constructor)
|
||||
* @accessible_role: the accessible role used by the #GtkATContext
|
||||
* @accessible: the #GtkAccessible implementation using the #GtkATContext
|
||||
* @display: the #GdkDisplay used by the #GtkATContext
|
||||
*
|
||||
* Creates a new #GtkATContext instance for the given accessible role and
|
||||
* accessible instance.
|
||||
* Creates a new #GtkATContext instance for the given accessible role,
|
||||
* accessible instance, and display connection.
|
||||
*
|
||||
* The #GtkATContext implementation being instantiated will depend on the
|
||||
* platform.
|
||||
@ -388,7 +429,8 @@ static const struct {
|
||||
*/
|
||||
GtkATContext *
|
||||
gtk_at_context_create (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible *accessible)
|
||||
GtkAccessible *accessible,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
static const char *gtk_test_accessible;
|
||||
static const char *gtk_no_a11y;
|
||||
@ -424,16 +466,25 @@ gtk_at_context_create (GtkAccessibleRole accessible_role,
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (a11y_backends); i++)
|
||||
{
|
||||
if (a11y_backends[i].name == NULL)
|
||||
break;
|
||||
|
||||
GTK_NOTE (A11Y, g_message ("Trying %s a11y backend", a11y_backends[i].name));
|
||||
if (a11y_backends[i].create_context != NULL)
|
||||
{
|
||||
res = a11y_backends[i].create_context (accessible_role, accessible);
|
||||
break;
|
||||
res = a11y_backends[i].create_context (accessible_role, accessible, display);
|
||||
if (res != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall back to the test context, so we can get debugging data */
|
||||
if (res == NULL)
|
||||
res = gtk_test_at_context_new (accessible_role, accessible);
|
||||
res = g_object_new (GTK_TYPE_TEST_AT_CONTEXT,
|
||||
"accessible_role", accessible_role,
|
||||
"accessible", accessible,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
/* FIXME: Add GIOExtension for AT contexts */
|
||||
return res;
|
||||
|
@ -42,6 +42,7 @@ GtkAccessibleRole gtk_at_context_get_accessible_role (GtkATContext
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkATContext * gtk_at_context_create (GtkAccessibleRole accessible_role,
|
||||
GtkAccessible *accessible);
|
||||
GtkAccessible *accessible,
|
||||
GdkDisplay *display);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -86,6 +86,7 @@ struct _GtkATContext
|
||||
|
||||
GtkAccessibleRole accessible_role;
|
||||
GtkAccessible *accessible;
|
||||
GdkDisplay *display;
|
||||
|
||||
GtkAccessibleAttributeSet *states;
|
||||
GtkAccessibleAttributeSet *properties;
|
||||
@ -109,6 +110,8 @@ struct _GtkATContextClass
|
||||
GtkAccessibleAttributeSet *relations);
|
||||
};
|
||||
|
||||
GdkDisplay * gtk_at_context_get_display (GtkATContext *self);
|
||||
|
||||
void gtk_at_context_update (GtkATContext *self);
|
||||
|
||||
void gtk_at_context_set_accessible_state (GtkATContext *self,
|
||||
|
@ -8095,6 +8095,7 @@ gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self);
|
||||
GtkWidgetClassPrivate *class_priv = widget_class->priv;
|
||||
GdkDisplay *display = _gtk_widget_get_display (self);
|
||||
GtkAccessibleRole role;
|
||||
|
||||
/* Widgets have two options to set the accessible role: either they
|
||||
@ -8111,7 +8112,7 @@ gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
|
||||
role = class_priv->accessible_role;
|
||||
|
||||
priv->accessible_role = role;
|
||||
priv->at_context = gtk_at_context_create (role, accessible);
|
||||
priv->at_context = gtk_at_context_create (role, accessible, display);
|
||||
}
|
||||
|
||||
return priv->at_context;
|
||||
|
@ -29,7 +29,9 @@ test_object_accessible_get_at_context (GtkAccessible *accessible)
|
||||
TestObject *self = (TestObject*)accessible;
|
||||
|
||||
if (self->at_context == NULL)
|
||||
self->at_context = gtk_at_context_create (self->role, accessible);
|
||||
self->at_context = gtk_at_context_create (self->role,
|
||||
accessible,
|
||||
gdk_display_get_default ());
|
||||
|
||||
return self->at_context;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user