[gtk+/drop-gail: 1/24] First cut at moving GailWidget -> GtkWidgetAccessible
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/drop-gail: 1/24] First cut at moving GailWidget -> GtkWidgetAccessible
- Date: Sun, 15 May 2011 02:12:11 +0000 (UTC)
commit 08f329c6bc69a67c71e98da941ab3174145c8399
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Feb 21 01:00:07 2011 -0500
First cut at moving GailWidget -> GtkWidgetAccessible
gtk/gtkwidget.c | 822 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 806 insertions(+), 16 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index cece4de..b38f072 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -11935,23 +11935,18 @@ gtk_widget_real_get_accessible (GtkWidget *widget)
{
AtkObject* accessible;
- accessible = g_object_get_qdata (G_OBJECT (widget),
- quark_accessible_object);
+ accessible = g_object_get_qdata (G_OBJECT (widget), quark_accessible_object);
if (!accessible)
- {
- AtkObjectFactory *factory;
- AtkRegistry *default_registry;
-
- default_registry = atk_get_default_registry ();
- factory = atk_registry_get_factory (default_registry,
- G_TYPE_FROM_INSTANCE (widget));
- accessible =
- atk_object_factory_create_accessible (factory,
- G_OBJECT (widget));
- g_object_set_qdata (G_OBJECT (widget),
- quark_accessible_object,
- accessible);
- }
+ {
+ AtkObjectFactory *factory;
+ AtkRegistry *default_registry;
+
+ default_registry = atk_get_default_registry ();
+ factory = atk_registry_get_factory (default_registry, G_TYPE_FROM_INSTANCE (widget));
+ accessible = atk_object_factory_create_accessible (factory, G_OBJECT (widget));
+ g_object_set_qdata (G_OBJECT (widget), quark_accessible_object, accessible);
+ }
+
return accessible;
}
@@ -14365,3 +14360,798 @@ gtk_widget_get_style_context (GtkWidget *widget)
return widget->priv->context;
}
+
+/* --- Accessibility --- */
+
+#define GTK_TYPE_WIDGET_ACCESSIBLE (gtk_widget_accessible_get_type ())
+#define GTK_WIDGET_ACCESSIBLE(obj)(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WIDGET_ACCESSIBLE, GtkWidgetAccessible))
+#define GTK_WIDGET_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WIDGET_ACCESSIBLE, GtkWidgetAccessibleClass))
+
+typedef struct _GtkWidgetAccessible GtkWidgetAccessible;
+typedef struct _GtkWidgetAccessibleClass GtkWidgetAccessibleClass;
+
+struct _GtkWidgetAccessible
+{
+ GtkAccessible parent;
+};
+
+struct _GtkWidgetAccessibleClass
+{
+ GtkAccessibleClass parent_class;
+
+ /* FIXME: drop these */
+ void (*notify_gtk) (GObject *object,
+ GParamSpec *pspec);
+ gboolean (*focus_gtk) (GtkWidget *widget,
+ GdkEventFocus *event);
+};
+
+static void atk_component_interface_init (AtkComponentIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkWidgetAccessible, gtk_widget_accessible, GTK_TYPE_ACCESSIBLE,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
+
+static void
+gtk_widget_accessible_init (GtkWidgetAccessible *accessible)
+{
+}
+
+static gboolean
+gtk_widget_accessible_focus_cb (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ GtkWidgetAccessible *accessible;
+
+ accessible = GTK_WIDGET_ACCESSIBLE (gtk_widget_get_accessible (widget));
+
+ return GTK_WIDGET_ACCESSIBLE_GET_CLASS (accessible)->focus_gtk (widget, event);
+}
+
+static gboolean
+gtk_widget_accessible_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ AtkObject* accessible;
+ gboolean return_val;
+ return_val = FALSE;
+
+ accessible = gtk_widget_get_accessible (widget);
+ g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val);
+ return FALSE;
+}
+
+static void
+gtk_widget_accessible_notify_cb (GObject *object,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget;
+ GtkWidgetAccessible *accessible;
+
+ widget = GTK_WIDGET (object);
+ accessible = GTK_WIDGET_ACCESSIBLE (gtk_widget_get_accessible (widget));
+
+ GTK_WIDGET_ACCESSIBLE_GET_CLASS (accessible)->notify_gtk (object, pspec);
+}
+
+static void
+gtk_widget_accessible_notify_gtk (GObject *object,
+ GParamSpec *pspec)
+{
+ GtkWidget* widget = GTK_WIDGET (object);
+ AtkObject* atk_obj = gtk_widget_get_accessible (widget);
+ AtkState state;
+ gboolean value;
+
+ if (strcmp (pspec->name, "visible") == 0)
+ {
+ state = ATK_STATE_VISIBLE;
+ value = gtk_widget_get_visible (widget);
+ }
+ else if (strcmp (pspec->name, "sensitive") == 0)
+ {
+ state = ATK_STATE_SENSITIVE;
+ value = gtk_widget_get_sensitive (widget);
+ }
+ else if (strcmp (pspec->name, "orientation") == 0)
+ {
+ GtkOrientable *orientable;
+
+ orientable = GTK_ORIENTABLE (widget);
+
+ state = ATK_STATE_HORIZONTAL;
+ value = (gtk_orientable_get_orientation (orientable) == GTK_ORIENTATION_HORIZONTAL);
+ }
+ else
+ return;
+
+ atk_object_notify_state_change (atk_obj, state, value);
+ if (state == ATK_STATE_SENSITIVE)
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, value);
+
+ if (state == ATK_STATE_HORIZONTAL)
+ atk_object_notify_state_change (atk_obj, ATK_STATE_VERTICAL, !value);
+}
+
+static void
+gtk_widget_accessible_size_allocate_cb (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ AtkObject* accessible;
+ AtkRectangle rect;
+
+ accessible = gtk_widget_get_accessible (widget);
+
+ rect.x = allocation->x;
+ rect.y = allocation->y;
+ rect.width = allocation->width;
+ rect.height = allocation->height;
+
+ g_signal_emit_by_name (accessible, "bounds_changed", &rect);
+}
+
+static void
+gtk_widget_accessible_focus_event (AtkObject *obj,
+ gboolean focus_in)
+{
+ AtkObject *focus_obj;
+
+ /* FIXME: focus tracking in gail is totally insane */
+ focus_obj = g_object_get_data (G_OBJECT (obj), "gail-focus-object");
+ if (focus_obj == NULL)
+ focus_obj = obj;
+ atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in);
+}
+
+static void
+gtk_widget_accessible_map_cb (GtkWidget *widget)
+{
+ AtkObject* accessible;
+
+ accessible = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (accessible, ATK_STATE_SHOWING,
+ gtk_widget_get_mapped (widget));
+}
+
+static void
+gtk_widget_accessible_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkAccessible *accessible;
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (data);
+
+ accessible = GTK_ACCESSIBLE (obj);
+ atk_object_set_role (ATK_OBJECT (accessible), ATK_ROLE_UNKNOWN);
+
+ gtk_accessible_set_widget (accessible, widget);
+ gtk_accessible_connect_widget_destroyed (accessible);
+
+ /* FIXME: move all this into the class handlers
+ * and get rid of the duplicated signals on GtkWidgetAccessible
+ */
+ g_signal_connect_after (widget, "focus-in-event",
+ G_CALLBACK (gtk_widget_accessible_focus_cb), NULL);
+ g_signal_connect_after (widget, "focus-out-event",
+ G_CALLBACK (gtk_widget_accessible_focus_cb), NULL);
+ g_signal_connect (widget, "notify",
+ G_CALLBACK (gtk_widget_accessible_notify_cb), NULL);
+ g_signal_connect (widget, "size_allocate",
+ G_CALLBACK (gtk_widget_accessible_size_allocate_cb), NULL);
+
+ atk_component_add_focus_handler (ATK_COMPONENT (accessible),
+ gtk_widget_accessible_focus_event);
+
+ g_signal_connect (widget, "map",
+ G_CALLBACK (gtk_widget_accessible_map_cb), NULL);
+ g_signal_connect (widget, "unmap",
+ G_CALLBACK (gtk_widget_accessible_map_cb), NULL);
+}
+
+static G_CONST_RETURN gchar*
+gtk_widget_accessible_get_description (AtkObject *accessible)
+{
+ GtkWidget *widget;
+
+ if (accessible->description)
+ return accessible->description;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return NULL;
+
+ /* FIXME: memory leak */
+ return gtk_widget_get_tooltip_text (widget);
+}
+
+static AtkObject *
+gtk_widget_accessible_get_parent (AtkObject *accessible)
+{
+ GtkWidget *widget, *parent_widget;
+
+ if (accessible->accessible_parent)
+ return accessible->accessible_parent;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return NULL;
+
+ parent_widget = gtk_widget_get_parent (widget);
+ if (parent_widget == NULL)
+ return NULL;
+
+ /* FIXME: turn this into a get_parent_for_child vfunc */
+ if (GTK_IS_NOTEBOOK (parent_widget))
+ {
+ gint page_num;
+ GtkWidget *child;
+ GtkNotebook *notebook;
+ AtkObject *parent;
+
+ page_num = 0;
+ notebook = GTK_NOTEBOOK (parent_widget);
+ while (TRUE)
+ {
+ child = gtk_notebook_get_nth_page (notebook, page_num);
+ if (!child)
+ break;
+ if (child == widget)
+ {
+ parent = (AtkObject *)gtk_widget_get_accessible (parent_widget);
+ parent = atk_object_ref_accessible_child (parent, page_num);
+ g_object_unref (parent);
+ return parent;
+ }
+ page_num++;
+ }
+ }
+
+ return gtk_widget_get_accessible (parent_widget);
+}
+
+static gint
+gtk_widget_accessible_get_index_in_parent (AtkObject *accessible)
+{
+ GtkWidget *widget;
+ AtkObject *parent;
+ GtkWidget *parent_widget;
+ gint index;
+ GList *children;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return -1;
+
+ parent = accessible->accessible_parent;
+ if (parent)
+ {
+#if 0
+ /* FIXME: turn this into a vfunc on the parent */
+ if (GAIL_IS_NOTEBOOK_PAGE (parent))
+ return 0;
+ else
+ {
+ gint n_children, i;
+ gboolean found = FALSE;
+
+ n_children = atk_object_get_n_accessible_children (parent);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (parent, i);
+ if (child == accessible)
+ found = TRUE;
+
+ g_object_unref (child);
+ if (found)
+ return i;
+ }
+ }
+#endif
+ }
+
+ parent_widget = gtk_widget_get_parent (widget);
+ if (parent_widget == NULL)
+ return -1;
+
+ children = gtk_container_get_children (GTK_CONTAINER (parent_widget));
+
+ index = g_list_index (children, widget);
+ g_list_free (children);
+
+ return index;
+}
+
+static void
+gtk_widget_accessible_widget_destroyed (GtkWidget *widget,
+ GtkAccessible *accessible)
+{
+ atk_object_notify_state_change (ATK_OBJECT (accessible), ATK_STATE_DEFUNCT,
+ TRUE);
+}
+
+/* FIXME: Should just have a GtkAccessible::widget property */
+static void
+gtk_widget_accessible_connect_widget_destroyed (GtkAccessible *accessible)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget)
+ g_signal_connect_after (widget, "destroy",
+ G_CALLBACK (gtk_widget_accessible_widget_destroyed),
+ accessible);
+}
+
+static GtkWidget*
+find_label (GtkWidget *widget)
+{
+ GList *labels;
+ GtkWidget *label;
+
+ labels = gtk_widget_list_mnemonic_labels (widget);
+ label = NULL;
+ if (labels)
+ {
+ if (labels->next)
+ g_warning ("Widget (%s) has more than one label", G_OBJECT_TYPE_NAME (widget));
+ label = labels->data;
+ }
+ g_list_free (labels);
+
+ /* Ignore a label within a button; bug #136602 */
+ if (label &&
+ GTK_IS_BUTTON (widget) &&
+ gtk_widget_is_ancestor (label, widget))
+ {
+ label = NULL;
+ }
+
+ return label;
+}
+
+static AtkRelationSet*
+gtk_widget_accessible_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ GtkWidget *label;
+ AtkObject *array[1];
+ AtkRelation* relation;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ relation_set = ATK_OBJECT_CLASS (gtk_widget_accessible_parent_class)->ref_relation_set (obj);
+
+ if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
+ {
+ label = find_label (widget);
+
+ if (label)
+ {
+ array[0] = gtk_widget_get_accessible (label);
+
+ relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
+ atk_relation_set_add (relation_set, relation);
+ g_object_unref (relation);
+ }
+ }
+
+ return relation_set;
+}
+
+/*
+ * This function checks whether the widget has an antecedent which is
+ * a GtkViewport and, if so, whether any part of the widget intersects
+ * the visible rectangle of the GtkViewport.
+ *
+ * FIXME: this does not work for child widgets in scrollable containers
+ * like gtktextview or gtkiconview. Needs to be a container vfunc, probably
+ */
+static gboolean
+gtk_widget_on_screen (GtkWidget *widget)
+{
+ GtkAllocation allocation;
+ GtkWidget *viewport;
+ gboolean return_value;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ viewport = gtk_widget_get_ancestor (widget, GTK_TYPE_VIEWPORT);
+ if (viewport)
+ {
+ GtkAllocation viewport_allocation;
+ GtkAdjustment *adjustment;
+ GdkRectangle visible_rect;
+
+ gtk_widget_get_allocation (viewport, &viewport_allocation);
+ adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (viewport));
+ visible_rect.y = gtk_adjustment_get_value (adjustment);
+ adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (viewport));
+ visible_rect.x = gtk_adjustment_get_value (adjustment);
+ visible_rect.width = viewport_allocation.width;
+ visible_rect.height = viewport_allocation.height;
+
+ if (((allocation.x + allocation.width) < visible_rect.x) ||
+ ((allocation.y + allocation.height) < visible_rect.y) ||
+ (allocation.x > (visible_rect.x + visible_rect.width)) ||
+ (allocation.y > (visible_rect.y + visible_rect.height)))
+ return_value = FALSE;
+ else
+ return_value = TRUE;
+ }
+ else
+ {
+ /*
+ * Check whether the widget has been placed of the screen.
+ * The widget may be MAPPED as when toolbar items do not fit
+ * on the toolbar.
+ */
+ if (allocation.x + allocation.width <= 0 &&
+ allocation.y + allocation.height <= 0)
+ return_value = FALSE;
+ else
+ return_value = TRUE;
+ }
+
+ return return_value;
+}
+
+static AtkStateSet*
+gtk_widget_accessible_ref_state_set (AtkObject *accessible)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ AtkStateSet *state_set;
+
+ state_set = ATK_OBJECT_CLASS (gtk_widget_accessible_parent_class)->ref_state_set (accessible);
+
+ if (widget == NULL)
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
+ }
+ else
+ {
+ if (gtk_widget_is_sensitive (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ }
+
+ if (gtk_widget_get_can_focus (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
+ }
+
+ if (gtk_widget_get_visible (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
+ if (gtk_widget_get_mapped (widget) &&
+ gtk_widget_on_screen (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+ }
+ }
+
+ if (gtk_widget_has_focus (widget))
+ {
+ AtkObject *focus_obj;
+
+ focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
+ if (focus_obj == NULL)
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
+ }
+
+ if (gtk_widget_has_default (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
+ }
+
+ if (GTK_IS_ORIENTABLE(widget))
+ switch (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)))
+ {
+ case GTK_ORIENTATION_HORIZONTAL:
+ atk_state_set_add_state (state_set, ATK_STATE_HORIZONTAL);
+ break;
+
+ case GTK_ORIENTATION_VERTICAL:
+ atk_state_set_add_state (state_set, ATK_STATE_VERTICAL);
+ break;
+ }
+ }
+
+ return state_set;
+}
+
+static AtkAttributeSet *
+gtk_widget_accessible_get_attributes (AtkObject *obj)
+{
+ AtkAttributeSet *attributes;
+ AtkAttribute *attribute;
+
+ attribute = g_new (AtkAttribute, 1);
+
+ attribute->name = g_strdup ("toolkit");
+ attribute->value = g_strdup( "gtk");
+
+ attributes = g_slist_append (NULL, attribute);
+
+ return attributes;
+}
+
+static void
+gtk_widget_accessible_class_init (GtkWidgetAccessibleClass *klass)
+{
+ AtkObjectClass *atkobject_class = ATK_OBJECT_CLASS (klass);
+ GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
+
+ atkobject_class->initialize = gtk_widget_accessible_initialize;
+ atkobject_class->get_description = gtk_widget_accessible_get_description;
+ atkobject_class->get_parent = gtk_widget_accessible_get_parent;
+ atkobject_class->get_index_in_parent = gtk_widget_accessible_get_index_in_parent;
+ atkobject_class->ref_relation_set = gtk_widget_accessible_ref_relation_set;
+ atkobject_class->ref_state_set = gtk_widget_accessible_ref_state_set;
+ atkobject_class->get_attributes = gtk_widget_accessible_get_attributes;
+
+ accessible_class->connect_widget_destroyed = gtk_widget_accessible_connect_widget_destroyed;
+
+ klass->focus_gtk = gtk_widget_accessible_focus_gtk;
+ klass->notify_gtk = gtk_widget_accessible_notify_gtk;
+}
+
+static guint
+gtk_widget_accessible_add_focus_handler (AtkComponent *component,
+ AtkFocusHandler handler)
+{
+ guint signal_id;
+
+ signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
+
+ if (g_signal_handler_find (component,
+ G_SIGNAL_MATCH_ID|G_SIGNAL_MATCH_FUNC,
+ signal_id,
+ 0, NULL, (gpointer) handler, NULL))
+ return 0;
+
+ return g_signal_connect_closure_by_id (component,
+ signal_id, 0,
+ g_cclosure_new (G_CALLBACK (handler), NULL,
+ (GClosureNotify) NULL),
+ FALSE);
+}
+
+static void
+gtk_widget_accessible_remove_focus_handler (AtkComponent *component,
+ guint handler_id)
+{
+ g_signal_handler_disconnect (component, handler_id);
+}
+
+static void
+gtk_widget_accessible_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GtkAllocation allocation;
+ GdkWindow *window;
+ gint x_window, y_window;
+ gint x_toplevel, y_toplevel;
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ return;
+
+ gtk_widget_get_allocation (widget, &allocation);
+ *width = allocation.width;
+ *height = allocation.height;
+
+ if (!gtk_widget_on_screen (widget) || !gtk_widget_is_drawable (widget))
+ {
+ *x = G_MININT;
+ *y = G_MININT;
+
+ return;
+ }
+
+ if (gtk_widget_get_parent (widget))
+ {
+ *x = allocation.x;
+ *y = allocation.y;
+ window = gtk_widget_get_parent_window (widget);
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ window = gtk_widget_get_window (widget);
+ }
+
+ gdk_window_get_origin (window, &x_window, &y_window);
+ *x += x_window;
+ *y += y_window;
+
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
+ gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
+
+ *x -= x_toplevel;
+ *y -= y_toplevel;
+ }
+}
+
+/* FIXME: move to GtkWindow */
+static gboolean
+gtk_widget_accessible_set_extents (AtkComponent *component,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ return FALSE;
+
+ if (!gtk_widget_is_toplevel (widget))
+ return FALSE;
+
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ gint x_current, y_current;
+ GdkWindow *window;
+
+ window = gtk_widget_get_window (widget);
+ gdk_window_get_origin (window, &x_current, &y_current);
+ x_current += x;
+ y_current += y;
+ if (x_current < 0 || y_current < 0)
+ return FALSE;
+ else
+ {
+ gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
+ gtk_widget_set_size_request (widget, width, height);
+ return TRUE;
+ }
+ }
+ else if (coord_type == ATK_XY_SCREEN)
+ {
+ gtk_window_move (GTK_WINDOW (widget), x, y);
+ gtk_widget_set_size_request (widget, width, height);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* FIXME: move to GtkWindow */
+static gboolean
+gtk_widget_accessible_set_position (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ return FALSE;
+
+ if (!gtk_widget_is_toplevel (widget))
+ return FALSE;
+
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ gint x_current, y_current;
+ GdkWindow *window;
+
+ window = gtk_widget_get_window (widget);
+ gdk_window_get_origin (window, &x_current, &y_current);
+ x_current += x;
+ y_current += y;
+ if (x_current < 0 || y_current < 0)
+ return FALSE;
+ else
+ {
+ gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
+ return TRUE;
+ }
+ }
+ else if (coord_type == ATK_XY_SCREEN)
+ {
+ gtk_window_move (GTK_WINDOW (widget), x, y);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+gtk_widget_accessible_get_size (AtkComponent *component,
+ gint *width,
+ gint *height)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ return;
+
+ *width = gtk_widget_get_allocated_width (widget);
+ *height = gtk_widget_get_allocated_height (widget);
+}
+
+/* FIXME: move to GtkWindow */
+static gboolean
+gtk_widget_accessible_set_size (AtkComponent *component,
+ gint width,
+ gint height)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ return FALSE;
+
+ if (!gtk_widget_is_toplevel (widget))
+ return FALSE;
+
+ gtk_widget_set_size_request (widget, width, height);
+
+ return TRUE;
+}
+
+static AtkLayer
+gtk_widget_accessible_get_layer (AtkComponent *component)
+{
+ return ATK_LAYER_WIDGET;
+}
+
+static gboolean
+gtk_widget_accessible_grab_focus (AtkComponent *component)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ GtkWidget *toplevel;
+
+ if (widget == NULL)
+ return FALSE;
+
+ if (!gtk_widget_get_can_focus (widget))
+ return FALSE;
+
+ gtk_widget_grab_focus (widget);
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (gtk_widget_is_toplevel (toplevel))
+ {
+ guint32 timestamp;
+
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_WINDOW (gtk_widget_get_window (widget)))
+ timestamp = gdk_x11_get_server_time (gtk_widget_get_window (widget));
+ else
+#endif
+ timestamp = GDK_CURRENT_TIME;
+
+ gtk_window_present_with_time (GTK_WINDOW (toplevel), timestamp);
+ }
+
+ return TRUE;
+}
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ iface->add_focus_handler = gtk_widget_accessible_add_focus_handler;
+ iface->remove_focus_handler = gtk_widget_accessible_remove_focus_handler;
+ iface->get_extents = gtk_widget_accessible_get_extents;
+ iface->set_extents = gtk_widget_accessible_set_extents;
+ iface->set_position = gtk_widget_accessible_set_position;
+ iface->get_size = gtk_widget_accessible_get_size;
+ iface->set_size = gtk_widget_accessible_set_size;
+ iface->get_layer = gtk_widget_accessible_get_layer;
+ iface->grab_focus = gtk_widget_accessible_grab_focus;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]