1 /* GAIL - The GNOME Accessibility Implementation Library
2 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
26 #include "gtkwindowaccessible.h"
27 #include "gailtoplevel.h"
45 static void gtk_window_accessible_get_extents (AtkComponent *component,
50 AtkCoordType coord_type);
51 static void gtk_window_accessible_get_size (AtkComponent *component,
55 static guint gtk_window_accessible_signals [LAST_SIGNAL] = { 0, };
57 static void atk_component_interface_init (AtkComponentIface *iface);
59 G_DEFINE_TYPE_WITH_CODE (GtkWindowAccessible, gtk_window_accessible, GAIL_TYPE_CONTAINER,
60 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
64 gtk_window_accessible_focus_gtk (GtkWidget *widget,
69 obj = gtk_widget_get_accessible (widget);
70 atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in);
76 gtk_window_accessible_notify_gtk (GObject *obj,
79 GtkWidget *widget = GTK_WIDGET (obj);
80 AtkObject* atk_obj = gtk_widget_get_accessible (widget);
82 if (strcmp (pspec->name, "title") == 0)
84 g_object_notify (G_OBJECT (atk_obj), "accessible-name");
85 g_signal_emit_by_name (atk_obj, "visible_data_changed");
88 GAIL_WIDGET_CLASS (gtk_window_accessible_parent_class)->notify_gtk (obj, pspec);
92 window_state_event_cb (GtkWidget *widget,
93 GdkEventWindowState *event)
97 obj = gtk_widget_get_accessible (widget);
98 atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED,
99 (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
105 gtk_window_accessible_initialize (AtkObject *obj,
108 GtkWidget *widget = GTK_WIDGET (data);
110 /* A GtkWindowAccessible can be created for a GtkHandleBox or a GtkWindow */
111 if (!GTK_IS_WINDOW (widget) && !GTK_IS_HANDLE_BOX (widget))
114 ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->initialize (obj, data);
116 g_signal_connect (data, "window_state_event", G_CALLBACK (window_state_event_cb), NULL);
117 g_object_set_data (G_OBJECT (obj), "atk-component-layer", GINT_TO_POINTER (ATK_LAYER_WINDOW));
119 if (GTK_IS_FILE_CHOOSER_DIALOG (widget))
120 obj->role = ATK_ROLE_FILE_CHOOSER;
121 else if (GTK_IS_COLOR_SELECTION_DIALOG (widget))
122 obj->role = ATK_ROLE_COLOR_CHOOSER;
123 else if (GTK_IS_FONT_SELECTION_DIALOG (widget))
124 obj->role = ATK_ROLE_FONT_CHOOSER;
125 else if (GTK_IS_MESSAGE_DIALOG (widget))
126 obj->role = ATK_ROLE_ALERT;
127 else if (GTK_IS_DIALOG (widget))
128 obj->role = ATK_ROLE_DIALOG;
133 name = gtk_widget_get_name (widget);
135 if (!g_strcmp0 (name, "gtk-tooltip"))
136 obj->role = ATK_ROLE_TOOL_TIP;
137 #ifdef GDK_WINDOWING_X11
138 else if (GTK_IS_PLUG (widget))
139 obj->role = ATK_ROLE_PANEL;
141 else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP)
142 obj->role = ATK_ROLE_WINDOW;
144 obj->role = ATK_ROLE_FRAME;
147 /* Notify that tooltip is showing */
148 if (obj->role == ATK_ROLE_TOOL_TIP && gtk_widget_get_mapped (widget))
149 atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1);
153 find_label_child (GtkContainer *container)
155 GList *children, *tmp_list;
158 children = gtk_container_get_children (container);
161 for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
163 if (GTK_IS_LABEL (tmp_list->data))
165 child = GTK_WIDGET (tmp_list->data);
168 else if (GTK_IS_CONTAINER (tmp_list->data))
170 child = find_label_child (GTK_CONTAINER (tmp_list->data));
175 g_list_free (children);
180 gtk_window_accessible_get_name (AtkObject *accessible)
185 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
189 name = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->get_name (accessible);
193 if (GTK_IS_WINDOW (widget))
195 GtkWindow *window = GTK_WINDOW (widget);
197 name = gtk_window_get_title (window);
198 if (name == NULL && accessible->role == ATK_ROLE_TOOL_TIP)
202 child = find_label_child (GTK_CONTAINER (window));
203 if (GTK_IS_LABEL (child))
204 name = gtk_label_get_text (GTK_LABEL (child));
211 gtk_window_accessible_get_index_in_parent (AtkObject *accessible)
217 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
221 index = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->get_index_in_parent (accessible);
225 atk_obj = atk_get_root ();
227 if (GTK_IS_WINDOW (widget))
229 GtkWindow *window = GTK_WINDOW (widget);
230 if (GAIL_IS_TOPLEVEL (atk_obj))
232 GailToplevel* toplevel = GAIL_TOPLEVEL (atk_obj);
233 index = g_list_index (toplevel->window_list, window);
237 gint i, sibling_count;
239 sibling_count = atk_object_get_n_accessible_children (atk_obj);
240 for (i = 0; i < sibling_count && index == -1; ++i)
242 AtkObject *child = atk_object_ref_accessible_child (atk_obj, i);
243 if (accessible == child)
245 g_object_unref (G_OBJECT (child));
252 static AtkRelationSet *
253 gtk_window_accessible_ref_relation_set (AtkObject *obj)
256 AtkRelationSet *relation_set;
258 AtkRelation* relation;
259 GtkWidget *current_widget;
261 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
265 relation_set = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->ref_relation_set (obj);
267 if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP)
269 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR);
271 atk_relation_set_remove (relation_set, relation);
273 if (0) /* FIXME need a way to go from tooltip window to widget */
275 array[0] = gtk_widget_get_accessible (current_widget);
276 relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR);
277 atk_relation_set_add (relation_set, relation);
278 g_object_unref (relation);
285 gtk_window_accessible_ref_state_set (AtkObject *accessible)
287 AtkStateSet *state_set;
290 GdkWindow *gdk_window;
291 GdkWindowState state;
293 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
297 state_set = ATK_OBJECT_CLASS (gtk_window_accessible_parent_class)->ref_state_set (accessible);
299 window = GTK_WINDOW (widget);
301 if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window))
302 atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
304 gdk_window = gtk_widget_get_window (widget);
307 state = gdk_window_get_state (gdk_window);
308 if (state & GDK_WINDOW_STATE_ICONIFIED)
309 atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED);
311 if (gtk_window_get_modal (window))
312 atk_state_set_add_state (state_set, ATK_STATE_MODAL);
314 if (gtk_window_get_resizable (window))
315 atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE);
321 gtk_window_accessible_class_init (GtkWindowAccessibleClass *klass)
323 GailWidgetClass *widget_class = (GailWidgetClass*)klass;
324 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
326 widget_class->focus_gtk = gtk_window_accessible_focus_gtk;
327 widget_class->notify_gtk = gtk_window_accessible_notify_gtk;
329 class->get_name = gtk_window_accessible_get_name;
330 class->get_index_in_parent = gtk_window_accessible_get_index_in_parent;
331 class->ref_relation_set = gtk_window_accessible_ref_relation_set;
332 class->ref_state_set = gtk_window_accessible_ref_state_set;
333 class->initialize = gtk_window_accessible_initialize;
335 gtk_window_accessible_signals [ACTIVATE] =
336 g_signal_new ("activate",
337 G_TYPE_FROM_CLASS (klass),
341 g_cclosure_marshal_VOID__VOID,
343 gtk_window_accessible_signals [CREATE] =
344 g_signal_new ("create",
345 G_TYPE_FROM_CLASS (klass),
349 g_cclosure_marshal_VOID__VOID,
351 gtk_window_accessible_signals [DEACTIVATE] =
352 g_signal_new ("deactivate",
353 G_TYPE_FROM_CLASS (klass),
357 g_cclosure_marshal_VOID__VOID,
359 gtk_window_accessible_signals [DESTROY] =
360 g_signal_new ("destroy",
361 G_TYPE_FROM_CLASS (klass),
365 g_cclosure_marshal_VOID__VOID,
367 gtk_window_accessible_signals [MAXIMIZE] =
368 g_signal_new ("maximize",
369 G_TYPE_FROM_CLASS (klass),
373 g_cclosure_marshal_VOID__VOID,
375 gtk_window_accessible_signals [MINIMIZE] =
376 g_signal_new ("minimize",
377 G_TYPE_FROM_CLASS (klass),
381 g_cclosure_marshal_VOID__VOID,
383 gtk_window_accessible_signals [MOVE] =
384 g_signal_new ("move",
385 G_TYPE_FROM_CLASS (klass),
389 g_cclosure_marshal_VOID__VOID,
391 gtk_window_accessible_signals [RESIZE] =
392 g_signal_new ("resize",
393 G_TYPE_FROM_CLASS (klass),
397 g_cclosure_marshal_VOID__VOID,
399 gtk_window_accessible_signals [RESTORE] =
400 g_signal_new ("restore",
401 G_TYPE_FROM_CLASS (klass),
405 g_cclosure_marshal_VOID__VOID,
410 gtk_window_accessible_init (GtkWindowAccessible *accessible)
415 gtk_window_accessible_get_extents (AtkComponent *component,
420 AtkCoordType coord_type)
424 gint x_toplevel, y_toplevel;
426 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
430 if (!gtk_widget_is_toplevel (widget))
432 AtkComponentIface *parent_iface;
434 parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
435 parent_iface->get_extents (component, x, y, width, height, coord_type);
439 gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
442 *height = rect.height;
443 if (!gtk_widget_is_drawable (widget))
452 if (coord_type == ATK_XY_WINDOW)
454 gdk_window_get_origin (gtk_widget_get_window (widget),
455 &x_toplevel, &y_toplevel);
462 gtk_window_accessible_get_size (AtkComponent *component,
469 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
473 if (!gtk_widget_is_toplevel (widget))
475 AtkComponentIface *parent_iface;
477 parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
478 parent_iface->get_size (component, width, height);
482 gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
485 *height = rect.height;
489 atk_component_interface_init (AtkComponentIface *iface)
491 iface->get_extents = gtk_window_accessible_get_extents;
492 iface->get_size = gtk_window_accessible_get_size;