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.
24 #include "gtkwindowaccessible.h"
25 #include "gtktoplevelaccessible.h"
43 static void gtk_window_accessible_get_extents (AtkComponent *component,
48 AtkCoordType coord_type);
49 static void gtk_window_accessible_get_size (AtkComponent *component,
53 static guint gtk_window_accessible_signals [LAST_SIGNAL] = { 0, };
55 static void atk_component_interface_init (AtkComponentIface *iface);
57 G_DEFINE_TYPE_WITH_CODE (GtkWindowAccessible, _gtk_window_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
58 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
62 gtk_window_accessible_focus_gtk (GtkWidget *widget,
67 obj = gtk_widget_get_accessible (widget);
68 atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in);
74 gtk_window_accessible_notify_gtk (GObject *obj,
77 GtkWidget *widget = GTK_WIDGET (obj);
78 AtkObject* atk_obj = gtk_widget_get_accessible (widget);
80 if (g_strcmp0 (pspec->name, "title") == 0)
82 g_object_notify (G_OBJECT (atk_obj), "accessible-name");
83 g_signal_emit_by_name (atk_obj, "visible-data-changed");
86 GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_window_accessible_parent_class)->notify_gtk (obj, pspec);
90 window_state_event_cb (GtkWidget *widget,
91 GdkEventWindowState *event)
95 obj = gtk_widget_get_accessible (widget);
96 atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED,
97 (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
103 gtk_window_accessible_initialize (AtkObject *obj,
106 GtkWidget *widget = GTK_WIDGET (data);
108 /* A GtkWindowAccessible can be created for a GtkHandleBox or a GtkWindow */
109 if (!GTK_IS_WINDOW (widget) && !GTK_IS_HANDLE_BOX (widget))
112 ATK_OBJECT_CLASS (_gtk_window_accessible_parent_class)->initialize (obj, data);
114 g_signal_connect (data, "window-state-event", G_CALLBACK (window_state_event_cb), NULL);
115 _gtk_widget_accessible_set_layer (GTK_WIDGET_ACCESSIBLE (obj), ATK_LAYER_WINDOW);
117 if (GTK_IS_FILE_CHOOSER_DIALOG (widget))
118 obj->role = ATK_ROLE_FILE_CHOOSER;
119 else if (GTK_IS_COLOR_SELECTION_DIALOG (widget))
120 obj->role = ATK_ROLE_COLOR_CHOOSER;
121 else if (GTK_IS_FONT_SELECTION_DIALOG (widget))
122 obj->role = ATK_ROLE_FONT_CHOOSER;
123 else if (GTK_IS_MESSAGE_DIALOG (widget))
124 obj->role = ATK_ROLE_ALERT;
125 else if (GTK_IS_DIALOG (widget))
126 obj->role = ATK_ROLE_DIALOG;
131 name = gtk_widget_get_name (widget);
133 if (!g_strcmp0 (name, "gtk-tooltip"))
134 obj->role = ATK_ROLE_TOOL_TIP;
135 #ifdef GDK_WINDOWING_X11
136 else if (GTK_IS_PLUG (widget))
137 obj->role = ATK_ROLE_PANEL;
139 else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP)
140 obj->role = ATK_ROLE_WINDOW;
142 obj->role = ATK_ROLE_FRAME;
145 /* Notify that tooltip is showing */
146 if (obj->role == ATK_ROLE_TOOL_TIP && gtk_widget_get_mapped (widget))
147 atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1);
151 find_label_child (GtkContainer *container)
153 GList *children, *tmp_list;
156 children = gtk_container_get_children (container);
159 for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
161 if (GTK_IS_LABEL (tmp_list->data))
163 child = GTK_WIDGET (tmp_list->data);
166 else if (GTK_IS_CONTAINER (tmp_list->data))
168 child = find_label_child (GTK_CONTAINER (tmp_list->data));
173 g_list_free (children);
178 gtk_window_accessible_get_name (AtkObject *accessible)
183 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
187 name = ATK_OBJECT_CLASS (_gtk_window_accessible_parent_class)->get_name (accessible);
191 if (GTK_IS_WINDOW (widget))
193 GtkWindow *window = GTK_WINDOW (widget);
195 name = gtk_window_get_title (window);
196 if (name == NULL && accessible->role == ATK_ROLE_TOOL_TIP)
200 child = find_label_child (GTK_CONTAINER (window));
201 if (GTK_IS_LABEL (child))
202 name = gtk_label_get_text (GTK_LABEL (child));
209 gtk_window_accessible_get_index_in_parent (AtkObject *accessible)
215 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
219 index = ATK_OBJECT_CLASS (_gtk_window_accessible_parent_class)->get_index_in_parent (accessible);
223 atk_obj = atk_get_root ();
225 if (GTK_IS_WINDOW (widget))
227 GtkWindow *window = GTK_WINDOW (widget);
228 if (GTK_IS_TOPLEVEL_ACCESSIBLE (atk_obj))
230 GtkToplevelAccessible *toplevel = GTK_TOPLEVEL_ACCESSIBLE (atk_obj);
231 index = g_list_index (toplevel->window_list, window);
235 gint i, sibling_count;
237 sibling_count = atk_object_get_n_accessible_children (atk_obj);
238 for (i = 0; i < sibling_count && index == -1; ++i)
240 AtkObject *child = atk_object_ref_accessible_child (atk_obj, i);
241 if (accessible == child)
243 g_object_unref (G_OBJECT (child));
250 static AtkRelationSet *
251 gtk_window_accessible_ref_relation_set (AtkObject *obj)
254 AtkRelationSet *relation_set;
256 AtkRelation* relation;
257 GtkWidget *current_widget;
259 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
263 relation_set = ATK_OBJECT_CLASS (_gtk_window_accessible_parent_class)->ref_relation_set (obj);
265 if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP)
267 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR);
269 atk_relation_set_remove (relation_set, relation);
271 if (0) /* FIXME need a way to go from tooltip window to widget */
273 array[0] = gtk_widget_get_accessible (current_widget);
274 relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR);
275 atk_relation_set_add (relation_set, relation);
276 g_object_unref (relation);
283 gtk_window_accessible_ref_state_set (AtkObject *accessible)
285 AtkStateSet *state_set;
288 GdkWindow *gdk_window;
289 GdkWindowState state;
291 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
295 state_set = ATK_OBJECT_CLASS (_gtk_window_accessible_parent_class)->ref_state_set (accessible);
297 window = GTK_WINDOW (widget);
299 if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window))
300 atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
302 gdk_window = gtk_widget_get_window (widget);
305 state = gdk_window_get_state (gdk_window);
306 if (state & GDK_WINDOW_STATE_ICONIFIED)
307 atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED);
309 if (gtk_window_get_modal (window))
310 atk_state_set_add_state (state_set, ATK_STATE_MODAL);
312 if (gtk_window_get_resizable (window))
313 atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE);
319 _gtk_window_accessible_class_init (GtkWindowAccessibleClass *klass)
321 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
322 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
324 widget_class->focus_gtk = gtk_window_accessible_focus_gtk;
325 widget_class->notify_gtk = gtk_window_accessible_notify_gtk;
327 class->get_name = gtk_window_accessible_get_name;
328 class->get_index_in_parent = gtk_window_accessible_get_index_in_parent;
329 class->ref_relation_set = gtk_window_accessible_ref_relation_set;
330 class->ref_state_set = gtk_window_accessible_ref_state_set;
331 class->initialize = gtk_window_accessible_initialize;
333 gtk_window_accessible_signals [ACTIVATE] =
334 g_signal_new ("activate",
335 G_TYPE_FROM_CLASS (klass),
339 g_cclosure_marshal_VOID__VOID,
341 gtk_window_accessible_signals [CREATE] =
342 g_signal_new ("create",
343 G_TYPE_FROM_CLASS (klass),
347 g_cclosure_marshal_VOID__VOID,
349 gtk_window_accessible_signals [DEACTIVATE] =
350 g_signal_new ("deactivate",
351 G_TYPE_FROM_CLASS (klass),
355 g_cclosure_marshal_VOID__VOID,
357 gtk_window_accessible_signals [DESTROY] =
358 g_signal_new ("destroy",
359 G_TYPE_FROM_CLASS (klass),
363 g_cclosure_marshal_VOID__VOID,
365 gtk_window_accessible_signals [MAXIMIZE] =
366 g_signal_new ("maximize",
367 G_TYPE_FROM_CLASS (klass),
371 g_cclosure_marshal_VOID__VOID,
373 gtk_window_accessible_signals [MINIMIZE] =
374 g_signal_new ("minimize",
375 G_TYPE_FROM_CLASS (klass),
379 g_cclosure_marshal_VOID__VOID,
381 gtk_window_accessible_signals [MOVE] =
382 g_signal_new ("move",
383 G_TYPE_FROM_CLASS (klass),
387 g_cclosure_marshal_VOID__VOID,
389 gtk_window_accessible_signals [RESIZE] =
390 g_signal_new ("resize",
391 G_TYPE_FROM_CLASS (klass),
395 g_cclosure_marshal_VOID__VOID,
397 gtk_window_accessible_signals [RESTORE] =
398 g_signal_new ("restore",
399 G_TYPE_FROM_CLASS (klass),
403 g_cclosure_marshal_VOID__VOID,
408 _gtk_window_accessible_init (GtkWindowAccessible *accessible)
413 gtk_window_accessible_get_extents (AtkComponent *component,
418 AtkCoordType coord_type)
422 gint x_toplevel, y_toplevel;
424 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
428 if (!gtk_widget_is_toplevel (widget))
430 AtkComponentIface *parent_iface;
432 parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
433 parent_iface->get_extents (component, x, y, width, height, coord_type);
437 gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
440 *height = rect.height;
441 if (!gtk_widget_is_drawable (widget))
450 if (coord_type == ATK_XY_WINDOW)
452 gdk_window_get_origin (gtk_widget_get_window (widget),
453 &x_toplevel, &y_toplevel);
460 gtk_window_accessible_get_size (AtkComponent *component,
467 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
471 if (!gtk_widget_is_toplevel (widget))
473 AtkComponentIface *parent_iface;
475 parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
476 parent_iface->get_size (component, width, height);
480 gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
483 *height = rect.height;
487 atk_component_interface_init (AtkComponentIface *iface)
489 iface->get_extents = gtk_window_accessible_get_extents;
490 iface->get_size = gtk_window_accessible_get_size;