mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 15:14:17 +00:00
a11y: Translate GtkAccessibleText to AT-SPI
Handle GtkAccessibleText in our translation layer, as far as possible.
This commit is contained in:
parent
610a5d6c0d
commit
10c782b106
@ -41,6 +41,7 @@
|
||||
#include "gtkspinbuttonprivate.h"
|
||||
#include "gtktextbufferprivate.h"
|
||||
#include "gtktextviewprivate.h"
|
||||
#include "gtkaccessibletext-private.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
@ -64,6 +65,283 @@ atspi_granularity_to_gtk (AtspiTextGranularity granularity)
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ GtkAccessibleText */
|
||||
|
||||
static void
|
||||
accessible_text_handle_method (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *method_name,
|
||||
GVariant *parameters,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkATContext *self = user_data;
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
|
||||
GtkAccessibleText *accessible_text = GTK_ACCESSIBLE_TEXT (accessible);
|
||||
|
||||
if (g_strcmp0 (method_name, "GetCaretOffset") == 0)
|
||||
{
|
||||
guint offset;
|
||||
|
||||
offset = gtk_accessible_text_get_caret_position (accessible_text);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", (int)offset));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SetCaretOffset") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetText") == 0)
|
||||
{
|
||||
int start, end;
|
||||
GBytes *contents;
|
||||
|
||||
g_variant_get (parameters, "(ii)", &start, &end);
|
||||
|
||||
contents = gtk_accessible_text_get_contents (accessible_text, start, end < 0 ? G_MAXUINT : end);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", g_bytes_get_data (contents, NULL)));
|
||||
|
||||
g_bytes_unref (contents);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetTextBeforeOffset") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "This method is deprecated in favor of GetStringAtOffset");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetTextAtOffset") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "This method is deprecated in favor of GetStringAtOffset");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetTextAfterOffset") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "This method is deprecated in favor of GetStringAtOffset");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetCharacterAtOffset") == 0)
|
||||
{
|
||||
int offset;
|
||||
gunichar ch = 0;
|
||||
|
||||
g_variant_get (parameters, "(i)", &offset);
|
||||
|
||||
GBytes *text = gtk_accessible_text_get_contents (accessible_text, offset, offset + 1);
|
||||
|
||||
if (text != NULL)
|
||||
{
|
||||
const char *str = g_bytes_get_data (text, NULL);
|
||||
|
||||
if (0 <= offset && offset < g_utf8_strlen (str, -1))
|
||||
ch = g_utf8_get_char (g_utf8_offset_to_pointer (str, offset));
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", ch));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetStringAtOffset") == 0)
|
||||
{
|
||||
unsigned int start, end;
|
||||
int offset;
|
||||
AtspiTextGranularity granularity;
|
||||
GBytes *bytes;
|
||||
|
||||
g_variant_get (parameters, "(iu)", &offset, &granularity);
|
||||
|
||||
bytes = gtk_accessible_text_get_contents_at (accessible_text, offset,
|
||||
atspi_granularity_to_gtk (granularity),
|
||||
&start, &end);
|
||||
|
||||
if (bytes == NULL)
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", "", -1, -1));
|
||||
else
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", g_bytes_get_data (bytes, NULL), start, end));
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetAttributes") == 0)
|
||||
{
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
gsize n_attrs = 0;
|
||||
GtkAccessibleTextRange *ranges = NULL;
|
||||
int start, end;
|
||||
char **attr_names = NULL;
|
||||
char **attr_values = NULL;
|
||||
|
||||
g_variant_get (parameters, "(i)", &offset);
|
||||
|
||||
gtk_accessible_text_get_attributes (accessible_text,
|
||||
offset,
|
||||
&n_attrs,
|
||||
&ranges,
|
||||
&attr_names,
|
||||
&attr_values);
|
||||
|
||||
start = 0;
|
||||
end = G_MAXINT;
|
||||
|
||||
for (int i = 0; i < n_attrs; i++)
|
||||
{
|
||||
g_variant_builder_add (&builder, "{ss}", attr_names[i], attr_values[i]);
|
||||
start = MAX (start, ranges[i].start);
|
||||
end = MIN (end, start + ranges[i].length);
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
|
||||
|
||||
g_clear_pointer (&ranges, g_free);
|
||||
g_strfreev (attr_names);
|
||||
g_strfreev (attr_values);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetAttributeValue") == 0)
|
||||
{
|
||||
int offset;
|
||||
const char *name;
|
||||
const char *val = "";
|
||||
char **names, **values;
|
||||
GtkAccessibleTextRange *ranges;
|
||||
gsize n_ranges;
|
||||
|
||||
g_variant_get (parameters, "(i&s)", &offset, &name);
|
||||
|
||||
gtk_accessible_text_get_attributes (accessible_text, offset,
|
||||
&n_ranges, &ranges,
|
||||
&names, &values);
|
||||
|
||||
for (unsigned i = 0; names[i] != NULL; i++)
|
||||
{
|
||||
if (g_strcmp0 (names[i], name) == 0)
|
||||
{
|
||||
val = values[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", val));
|
||||
|
||||
g_strfreev (names);
|
||||
g_strfreev (values);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetAttributeRun") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetDefaultAttributes") == 0 ||
|
||||
g_strcmp0 (method_name, "GetDefaultAttributeSet") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetNSelections") == 0)
|
||||
{
|
||||
gsize n_ranges;
|
||||
GtkAccessibleTextRange *ranges = NULL;
|
||||
|
||||
gtk_accessible_text_get_selection (accessible_text, &n_ranges, &ranges);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", (int)n_ranges));
|
||||
|
||||
g_clear_pointer (&ranges, g_free);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetSelection") == 0)
|
||||
{
|
||||
int num;
|
||||
gsize n_ranges;
|
||||
GtkAccessibleTextRange *ranges = NULL;
|
||||
|
||||
g_variant_get (parameters, "(i)", &num);
|
||||
|
||||
gtk_accessible_text_get_selection (accessible_text, &n_ranges, &ranges);
|
||||
|
||||
if (num < 0 || num >= n_ranges)
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Not a valid selection: %d", num);
|
||||
else
|
||||
{
|
||||
int start = ranges[num].start;
|
||||
int end = start + ranges[num].length;
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", start, end));
|
||||
}
|
||||
|
||||
g_clear_pointer (&ranges, g_free);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "AddSelection") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "RemoveSelection") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SetSelection") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetCharacterExtents") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetRangeExtents") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetBoundedRanges") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "ScrollSubstringTo") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "ScrollSubstringToPoint") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
}
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
accessible_text_get_property (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *property_name,
|
||||
GError **error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkATContext *self = user_data;
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
|
||||
GtkAccessibleText *accessible_text = GTK_ACCESSIBLE_TEXT (accessible);
|
||||
|
||||
if (g_strcmp0 (property_name, "CharacterCount") == 0)
|
||||
{
|
||||
GBytes *contents;
|
||||
const char *str;
|
||||
gsize len;
|
||||
|
||||
contents = gtk_accessible_text_get_contents (accessible_text, 0, G_MAXUINT);
|
||||
str = g_bytes_get_data (contents, NULL);
|
||||
len = g_utf8_strlen (str, -1);
|
||||
g_bytes_unref (contents);
|
||||
|
||||
return g_variant_new_int32 ((int) len);
|
||||
}
|
||||
else if (g_strcmp0 (property_name, "CaretOffset") == 0)
|
||||
{
|
||||
guint offset;
|
||||
|
||||
offset = gtk_accessible_text_get_caret_position (accessible_text);
|
||||
|
||||
return g_variant_new_int32 ((int) offset);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const GDBusInterfaceVTable accessible_text_vtable = {
|
||||
accessible_text_handle_method,
|
||||
accessible_text_get_property,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GtkLabel */
|
||||
|
||||
static void
|
||||
@ -195,7 +473,7 @@ label_handle_method (GDBusConnection *connection,
|
||||
int offset;
|
||||
AtspiTextGranularity granularity;
|
||||
char *string;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
|
||||
g_variant_get (parameters, "(iu)", &offset, &granularity);
|
||||
|
||||
@ -211,7 +489,7 @@ label_handle_method (GDBusConnection *connection,
|
||||
PangoLayout *layout = gtk_label_get_layout (GTK_LABEL (widget));
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
char **names, **values;
|
||||
|
||||
g_variant_get (parameters, "(i)", &offset);
|
||||
@ -231,7 +509,7 @@ label_handle_method (GDBusConnection *connection,
|
||||
PangoLayout *layout = gtk_label_get_layout (GTK_LABEL (widget));
|
||||
int offset;
|
||||
const char *name;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
const char *val = "";
|
||||
char **names, **values;
|
||||
|
||||
@ -259,7 +537,7 @@ label_handle_method (GDBusConnection *connection,
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
gboolean include_defaults;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
char **names, **values;
|
||||
|
||||
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
|
||||
@ -585,7 +863,7 @@ inscription_handle_method (GDBusConnection *connection,
|
||||
int offset;
|
||||
AtspiTextGranularity granularity;
|
||||
char *string;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
|
||||
g_variant_get (parameters, "(iu)", &offset, &granularity);
|
||||
|
||||
@ -601,7 +879,7 @@ inscription_handle_method (GDBusConnection *connection,
|
||||
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
char **names, **values;
|
||||
|
||||
g_variant_get (parameters, "(i)", &offset);
|
||||
@ -621,7 +899,7 @@ inscription_handle_method (GDBusConnection *connection,
|
||||
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
|
||||
int offset;
|
||||
const char *name;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
const char *val = "";
|
||||
char **names, **values;
|
||||
|
||||
@ -649,7 +927,7 @@ inscription_handle_method (GDBusConnection *connection,
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
gboolean include_defaults;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
char **names, **values;
|
||||
|
||||
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
|
||||
@ -921,7 +1199,7 @@ editable_handle_method (GDBusConnection *connection,
|
||||
int offset;
|
||||
AtspiTextGranularity granularity;
|
||||
char *string;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
|
||||
g_variant_get (parameters, "(iu)", &offset, &granularity);
|
||||
|
||||
@ -937,7 +1215,7 @@ editable_handle_method (GDBusConnection *connection,
|
||||
PangoLayout *layout = gtk_text_get_layout (text_widget);
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
char **names, **values;
|
||||
|
||||
g_variant_get (parameters, "(i)", &offset);
|
||||
@ -957,7 +1235,7 @@ editable_handle_method (GDBusConnection *connection,
|
||||
PangoLayout *layout = gtk_text_get_layout (text_widget);
|
||||
int offset;
|
||||
const char *name;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
const char *val = "";
|
||||
char **names, **values;
|
||||
|
||||
@ -985,7 +1263,7 @@ editable_handle_method (GDBusConnection *connection,
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int offset;
|
||||
gboolean include_defaults;
|
||||
int start, end;
|
||||
unsigned int start, end;
|
||||
char **names, **values;
|
||||
|
||||
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
|
||||
@ -1707,7 +1985,9 @@ static const GDBusInterfaceVTable text_view_vtable = {
|
||||
const GDBusInterfaceVTable *
|
||||
gtk_atspi_get_text_vtable (GtkAccessible *accessible)
|
||||
{
|
||||
if (GTK_IS_LABEL (accessible))
|
||||
if (GTK_IS_ACCESSIBLE_TEXT (accessible))
|
||||
return &accessible_text_vtable;
|
||||
else if (GTK_IS_LABEL (accessible))
|
||||
return &label_vtable;
|
||||
else if (GTK_IS_INSCRIPTION (accessible))
|
||||
return &inscription_vtable;
|
||||
|
Loading…
Reference in New Issue
Block a user