Make the bounds calculation part of the accessible interface.
Bounds are used by ATs like Orca to implement features like Flat Review:
https://help.gnome.org/users/orca/stable/howto_flat_review.html.en
Or to determine the area of a non-presentational widget.
{
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (ctx);
GtkAccessible *accessible = gtk_at_context_get_accessible (ctx);
- GtkWidget *widget;
- GtkWidget *parent;
- double x, y;
- int width, height;
-
- if (!GTK_IS_WIDGET (accessible))
- return;
-
- widget = GTK_WIDGET (accessible);
- if (!gtk_widget_get_realized (widget))
- return;
-
- parent = gtk_widget_get_parent (widget);
-
- if (parent)
- gtk_widget_translate_coordinates (widget, parent, 0., 0., &x, &y);
- else
- x = y = 0.;
-
- width = gtk_widget_get_width (widget);
- height = gtk_widget_get_height (widget);
-
- emit_bounds_changed (self, (int)x, (int)y, width, height);
+ int x, y, width, height;
+ if (gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
+ emit_bounds_changed (self, x, y, width, height);
}
static void
gtk_at_context_bounds_changed (context);
}
+/*
+ * gtk_accessible_get_bounds:
+ * @self: a `GtkAccessible`
+ * @x: the x coordinate of the top left corner of the accessible
+ * @y: the y coordinate of the top left corner of the widget
+ * @width: the width of the widget
+ * @height: the height of the widget
+ *
+ * Query the coordinates and dimensions of this accessible
+ *
+ * See gtk_accessible_bounds_changed().
+ *
+ * This functionality can be overridden by `GtkAccessible`
+ * implementations, e.g. to get the bounds from an ignored
+ * child widget.
+ *
+ * Returns: whether the bounds should be considered valid
+ */
+gboolean
+gtk_accessible_get_bounds (GtkAccessible *self,
+ int *x, int *y, int *width, int *height)
+{
+ return GTK_ACCESSIBLE_GET_IFACE (self)->get_bounds (self, x, y, width, height);
+}
+
/*<private>
* gtk_accessible_should_present:
* @self: a `GtkAccessible`
GtkAccessible * (* get_parent) (GtkAccessible *self);
GtkAccessible * (* get_child_at_index) (GtkAccessible *self, guint index);
+
+ gboolean (* get_bounds) (GtkAccessible *self, int *x, int *y,
+ int *width, int *height);
};
GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self);
GtkAccessible * gtk_accessible_get_child_at_index(GtkAccessible *self, guint index);
+gboolean gtk_accessible_get_bounds (GtkAccessible *self, int *x, int *y, int *width, int *height);
+
void gtk_accessible_bounds_changed (GtkAccessible *self);
void gtk_accessible_update_children (GtkAccessible *self,
return NULL;
}
+static gboolean
+gtk_widget_accessible_get_bounds (GtkAccessible *self, int *x, int *y, int *width, int *height) {
+ GtkWidget *widget;
+ GtkWidget *parent;
+ double translated_x, translated_y;
+
+ widget = GTK_WIDGET (self);
+ if (!gtk_widget_get_realized (widget))
+ return false;
+
+ parent = gtk_widget_get_parent (widget);
+
+ if (parent)
+ {
+ gtk_widget_translate_coordinates (widget, parent, 0., 0., &translated_x, &translated_y);
+ *x = (int)translated_x;
+ *y = (int)translated_y;
+ }
+ else
+ *x = *y = 0;
+
+ *width = gtk_widget_get_width (widget);
+ *height = gtk_widget_get_height (widget);
+
+ return true;
+}
+
static void
gtk_widget_accessible_interface_init (GtkAccessibleInterface *iface)
{
iface->get_platform_state = gtk_widget_accessible_get_platform_state;
iface->get_parent = gtk_widget_accessible_get_parent;
iface->get_child_at_index = gtk_widget_accessible_get_child_at_index;
+ iface->get_bounds = gtk_widget_accessible_get_bounds;
}
static void