[gtk/wip/otte/inscription: 1/2] inscription: Add a11y support for text interface
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/inscription: 1/2] inscription: Add a11y support for text interface
- Date: Thu, 9 Jun 2022 05:43:52 +0000 (UTC)
commit 4a211bb858cfd34399f0b646ef240f0adea20f42
Author: Benjamin Otte <otte redhat com>
Date: Thu Jun 9 07:14:30 2022 +0200
inscription: Add a11y support for text interface
This is entirely untested.
gtk/a11y/gtkatspitext.c | 271 ++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkinscription.c | 11 +-
gtk/gtkinscriptionprivate.h | 33 ++++++
3 files changed, 314 insertions(+), 1 deletion(-)
---
diff --git a/gtk/a11y/gtkatspitext.c b/gtk/a11y/gtkatspitext.c
index e4a6140298..e7bd9275be 100644
--- a/gtk/a11y/gtkatspitext.c
+++ b/gtk/a11y/gtkatspitext.c
@@ -32,6 +32,7 @@
#include "gtkatcontextprivate.h"
#include "gtkdebug.h"
#include "gtkeditable.h"
+#include "gtkinscriptionprivate.h"
#include "gtklabelprivate.h"
#include "gtkentryprivate.h"
#include "gtksearchentryprivate.h"
@@ -406,6 +407,274 @@ static const GDBusInterfaceVTable label_vtable = {
NULL,
};
+/* }}} */
+/* {{{ GtkInscription */
+
+static void
+inscription_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);
+ GtkWidget *widget = GTK_WIDGET (accessible);
+
+ if (g_strcmp0 (method_name, "GetCaretOffset") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", 0));
+ }
+ else if (g_strcmp0 (method_name, "SetCaretOffset") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
+ }
+ else if (g_strcmp0 (method_name, "GetText") == 0)
+ {
+ int start, end;
+ const char *text;
+ int len;
+ char *string;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
+ len = g_utf8_strlen (text, -1);
+
+ start = CLAMP (start, 0, len);
+ end = CLAMP (end, 0, len);
+
+ if (end <= start)
+ string = g_strdup ("");
+ else
+ {
+ const char *p, *q;
+ p = g_utf8_offset_to_pointer (text, start);
+ q = g_utf8_offset_to_pointer (text, end);
+ string = g_strndup (p, q - p);
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", string));
+ g_free (string);
+ }
+ else if (g_strcmp0 (method_name, "GetTextBeforeOffset") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ int offset;
+ AtspiTextBoundaryType boundary_type;
+ char *string;
+ int start, end;
+
+ g_variant_get (parameters, "(iu)", &offset, &boundary_type);
+
+ string = gtk_pango_get_text_before (layout, offset, boundary_type, &start, &end);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
+ g_free (string);
+ }
+ else if (g_strcmp0 (method_name, "GetTextAtOffset") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ int offset;
+ AtspiTextBoundaryType boundary_type;
+ char *string;
+ int start, end;
+
+ g_variant_get (parameters, "(iu)", &offset, &boundary_type);
+
+ string = gtk_pango_get_text_at (layout, offset, boundary_type, &start, &end);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
+ g_free (string);
+ }
+ else if (g_strcmp0 (method_name, "GetTextAfterOffset") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ int offset;
+ AtspiTextBoundaryType boundary_type;
+ char *string;
+ int start, end;
+
+ g_variant_get (parameters, "(iu)", &offset, &boundary_type);
+
+ string = gtk_pango_get_text_after (layout, offset, boundary_type, &start, &end);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
+ g_free (string);
+ }
+ else if (g_strcmp0 (method_name, "GetCharacterAtOffset") == 0)
+ {
+ int offset;
+ const char *text;
+ gunichar ch = 0;
+
+ g_variant_get (parameters, "(i)", &offset);
+
+ text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
+
+ if (0 <= offset && offset < g_utf8_strlen (text, -1))
+ ch = g_utf8_get_char (g_utf8_offset_to_pointer (text, offset));
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", ch));
+ }
+ else if (g_strcmp0 (method_name, "GetStringAtOffset") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ int offset;
+ AtspiTextGranularity granularity;
+ char *string;
+ int start, end;
+
+ g_variant_get (parameters, "(iu)", &offset, &granularity);
+
+ string = gtk_pango_get_string_at (layout, offset, granularity, &start, &end);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
+ g_free (string);
+ }
+ else if (g_strcmp0 (method_name, "GetAttributes") == 0)
+ {
+ 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;
+
+ g_variant_get (parameters, "(i)", &offset);
+
+ gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
+ }
+ else if (g_strcmp0 (method_name, "GetAttributeValue") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
+ int offset;
+ const char *name;
+ int start, end;
+ GVariant *attrs;
+ const char *val;
+
+ g_variant_get (parameters, "(i&s)", &offset, &name);
+
+ gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
+
+ attrs = g_variant_builder_end (&builder);
+ if (!g_variant_lookup (attrs, name, "&s", &val))
+ val = "";
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", val));
+ g_variant_unref (attrs);
+ }
+ else if (g_strcmp0 (method_name, "GetAttributeRun") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
+ int offset;
+ gboolean include_defaults;
+ int start, end;
+
+ g_variant_get (parameters, "(ib)", &offset, &include_defaults);
+
+ if (include_defaults)
+ gtk_pango_get_default_attributes (layout, &builder);
+
+ gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
+ }
+ else if (g_strcmp0 (method_name, "GetDefaultAttributes") == 0 ||
+ g_strcmp0 (method_name, "GetDefaultAttributeSet") == 0)
+ {
+ PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
+ GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
+
+ gtk_pango_get_default_attributes (layout, &builder);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss})", &builder));
+ }
+ else if (g_strcmp0 (method_name, "GetNSelections") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", 0));
+ }
+ else if (g_strcmp0 (method_name, "GetSelection") == 0)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No
selections available");
+ }
+ else if (g_strcmp0 (method_name, "AddSelection") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
+ }
+ else if (g_strcmp0 (method_name, "RemoveSelection") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
+ }
+ else if (g_strcmp0 (method_name, "SetSelection") == 0)
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
+ }
+ 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 *
+inscription_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);
+ GtkWidget *widget = GTK_WIDGET (accessible);
+
+ if (g_strcmp0 (property_name, "CharacterCount") == 0)
+ {
+ const char *text;
+ int len;
+
+ text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
+ len = g_utf8_strlen (text, -1);
+
+ return g_variant_new_int32 (len);
+ }
+ else if (g_strcmp0 (property_name, "CaretOffset") == 0)
+ {
+ return g_variant_new_int32 (0);
+ }
+
+ return NULL;
+}
+
+static const GDBusInterfaceVTable inscription_vtable = {
+ inscription_handle_method,
+ inscription_get_property,
+ NULL,
+};
+
/* }}} */
/* {{{ GtkEditable */
@@ -1301,6 +1570,8 @@ gtk_atspi_get_text_vtable (GtkAccessible *accessible)
{
if (GTK_IS_LABEL (accessible))
return &label_vtable;
+ else if (GTK_IS_INSCRIPTION (accessible))
+ return &inscription_vtable;
else if (GTK_IS_EDITABLE (accessible) &&
GTK_IS_TEXT (gtk_editable_get_delegate (GTK_EDITABLE (accessible))))
return &editable_vtable;
diff --git a/gtk/gtkinscription.c b/gtk/gtkinscription.c
index c290415cea..7bc0d81529 100644
--- a/gtk/gtkinscription.c
+++ b/gtk/gtkinscription.c
@@ -19,7 +19,7 @@
#include "config.h"
-#include "gtkinscription.h"
+#include "gtkinscriptionprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssstylechangeprivate.h"
@@ -664,6 +664,8 @@ gtk_inscription_class_init (GtkInscriptionClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
+
+ gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_LABEL);
}
static void
@@ -680,6 +682,13 @@ gtk_inscription_init (GtkInscription *self)
pango_layout_set_wrap (self->layout, PANGO_WRAP_WORD_CHAR);
}
+/* for a11y */
+PangoLayout *
+gtk_inscription_get_layout (GtkInscription *self)
+{
+ return self->layout;
+}
+
/**
* gtk_inscription_new:
* @text: (nullable): The text to display.
diff --git a/gtk/gtkinscriptionprivate.h b/gtk/gtkinscriptionprivate.h
new file mode 100644
index 0000000000..97de354e27
--- /dev/null
+++ b/gtk/gtkinscriptionprivate.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2022 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_INSCRIPTION_PRIVATE_H__
+#define __GTK_INSCRIPTION_PRIVATE_H__
+
+
+#include <gtk/gtkinscription.h>
+
+
+G_BEGIN_DECLS
+
+PangoLayout * gtk_inscription_get_layout (GtkInscription *self);
+
+G_END_DECLS
+
+#endif /* __GTK_INSCRIPTION_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]