a11y: Implement atspi.Text.GetCharacterExtents for GtkTextView
authorEmmanuele Bassi <ebassi@gnome.org>
Mon, 23 May 2022 14:54:13 +0000 (15:54 +0100)
committerEmmanuele Bassi <ebassi@gnome.org>
Mon, 23 May 2022 14:54:13 +0000 (15:54 +0100)
Retrieve the location of a given offset in window-relative coordinate
space.

gtk/a11y/gtkatspitext.c

index 338357f6d344a6013121328106c900bcffe02920..5bac320813ba84c85004181b246722d057aaa88b 100644 (file)
@@ -1098,7 +1098,40 @@ text_view_handle_method (GDBusConnection       *connection,
     }
   else if (g_strcmp0 (method_name, "GetCharacterExtents") == 0)
     {
-      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
+      int offset = 0;
+      guint coords_type;
+
+      g_variant_get (parameters, "(iu)", &offset, &coords_type);
+
+      if (coords_type != ATSPI_COORD_TYPE_WINDOW)
+        {
+          g_dbus_method_invocation_return_error_literal (invocation,
+                                                         G_DBUS_ERROR,
+                                                         G_DBUS_ERROR_NOT_SUPPORTED,
+                                                         "Unsupported coordinate space");
+          return;
+        }
+
+      GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+
+      GtkTextIter iter;
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+
+      GdkRectangle rect = { 0, };
+      gtk_text_view_get_iter_location (GTK_TEXT_VIEW (widget), &iter, &rect);
+
+      int x, y;
+      gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (widget),
+                                             GTK_TEXT_WINDOW_WIDGET,
+                                             rect.x, rect.y,
+                                             &x, &y);
+
+      g_dbus_method_invocation_return_value (invocation,
+                                             g_variant_new ("(iiii)",
+                                                            x,
+                                                            y,
+                                                            rect.width,
+                                                            rect.height));
     }
   else if (g_strcmp0 (method_name, "GetRangeExtents") == 0)
     {