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 #undef GTK_DISABLE_DEPRECATED
27 #ifdef GDK_WINDOWING_X11
28 #include <gdk/x11/gdkx.h>
30 #include "gailwidget.h"
31 #include "gailnotebookpage.h"
32 #include "gail-private-macros.h"
34 extern GtkWidget *focus_widget;
36 static void gail_widget_class_init (GailWidgetClass *klass);
37 static void gail_widget_init (GailWidget *accessible);
38 static void gail_widget_connect_widget_destroyed (GtkAccessible *accessible);
39 static void gail_widget_destroyed (GtkWidget *widget,
40 GtkAccessible *accessible);
42 static G_CONST_RETURN gchar* gail_widget_get_description (AtkObject *accessible);
43 static AtkObject* gail_widget_get_parent (AtkObject *accessible);
44 static AtkStateSet* gail_widget_ref_state_set (AtkObject *accessible);
45 static AtkRelationSet* gail_widget_ref_relation_set (AtkObject *accessible);
46 static gint gail_widget_get_index_in_parent (AtkObject *accessible);
48 static void atk_component_interface_init (AtkComponentIface *iface);
50 static guint gail_widget_add_focus_handler
51 (AtkComponent *component,
52 AtkFocusHandler handler);
54 static void gail_widget_get_extents (AtkComponent *component,
59 AtkCoordType coord_type);
61 static void gail_widget_get_size (AtkComponent *component,
65 static AtkLayer gail_widget_get_layer (AtkComponent *component);
67 static gboolean gail_widget_grab_focus (AtkComponent *component);
70 static void gail_widget_remove_focus_handler
71 (AtkComponent *component,
74 static gboolean gail_widget_set_extents (AtkComponent *component,
79 AtkCoordType coord_type);
81 static gboolean gail_widget_set_position (AtkComponent *component,
84 AtkCoordType coord_type);
86 static gboolean gail_widget_set_size (AtkComponent *component,
90 static gint gail_widget_map_gtk (GtkWidget *widget);
91 static void gail_widget_real_notify_gtk (GObject *obj,
93 static void gail_widget_notify_gtk (GObject *obj,
95 static gboolean gail_widget_focus_gtk (GtkWidget *widget,
96 GdkEventFocus *event);
97 static gboolean gail_widget_real_focus_gtk (GtkWidget *widget,
98 GdkEventFocus *event);
99 static void gail_widget_size_allocate_gtk (GtkWidget *widget,
100 GtkAllocation *allocation);
102 static void gail_widget_focus_event (AtkObject *obj,
105 static void gail_widget_real_initialize (AtkObject *obj,
107 static GtkWidget* gail_widget_find_viewport (GtkWidget *widget);
108 static gboolean gail_widget_on_screen (GtkWidget *widget);
109 static gboolean gail_widget_all_parents_visible(GtkWidget *widget);
111 G_DEFINE_TYPE_WITH_CODE (GailWidget, gail_widget, GTK_TYPE_ACCESSIBLE,
112 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
115 gail_widget_class_init (GailWidgetClass *klass)
117 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
118 GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
120 klass->notify_gtk = gail_widget_real_notify_gtk;
121 klass->focus_gtk = gail_widget_real_focus_gtk;
123 accessible_class->connect_widget_destroyed = gail_widget_connect_widget_destroyed;
125 class->get_description = gail_widget_get_description;
126 class->get_parent = gail_widget_get_parent;
127 class->ref_relation_set = gail_widget_ref_relation_set;
128 class->ref_state_set = gail_widget_ref_state_set;
129 class->get_index_in_parent = gail_widget_get_index_in_parent;
130 class->initialize = gail_widget_real_initialize;
134 gail_widget_init (GailWidget *accessible)
139 * This function specifies the GtkWidget for which the GailWidget was created
140 * and specifies a handler to be called when the GtkWidget is destroyed.
143 gail_widget_real_initialize (AtkObject *obj,
146 GtkAccessible *accessible;
149 g_return_if_fail (GTK_IS_WIDGET (data));
151 widget = GTK_WIDGET (data);
153 accessible = GTK_ACCESSIBLE (obj);
154 accessible->widget = widget;
155 gtk_accessible_connect_widget_destroyed (accessible);
156 g_signal_connect_after (widget,
158 G_CALLBACK (gail_widget_focus_gtk),
160 g_signal_connect_after (widget,
162 G_CALLBACK (gail_widget_focus_gtk),
164 g_signal_connect (widget,
166 G_CALLBACK (gail_widget_notify_gtk),
168 g_signal_connect (widget,
170 G_CALLBACK (gail_widget_size_allocate_gtk),
172 atk_component_add_focus_handler (ATK_COMPONENT (accessible),
173 gail_widget_focus_event);
175 * Add signal handlers for GTK signals required to support property changes
177 g_signal_connect (widget,
179 G_CALLBACK (gail_widget_map_gtk),
181 g_signal_connect (widget,
183 G_CALLBACK (gail_widget_map_gtk),
185 g_object_set_data (G_OBJECT (obj), "atk-component-layer",
186 GINT_TO_POINTER (ATK_LAYER_WIDGET));
188 obj->role = ATK_ROLE_UNKNOWN;
192 gail_widget_new (GtkWidget *widget)
195 AtkObject *accessible;
197 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
199 object = g_object_new (GAIL_TYPE_WIDGET, NULL);
201 accessible = ATK_OBJECT (object);
202 atk_object_initialize (accessible, widget);
208 * This function specifies the function to be called when the widget
212 gail_widget_connect_widget_destroyed (GtkAccessible *accessible)
214 if (accessible->widget)
216 g_signal_connect_after (accessible->widget,
218 G_CALLBACK (gail_widget_destroyed),
224 * This function is called when the widget is destroyed.
225 * It sets the widget field in the GtkAccessible structure to NULL
226 * and emits a state-change signal for the state ATK_STATE_DEFUNCT
229 gail_widget_destroyed (GtkWidget *widget,
230 GtkAccessible *accessible)
232 accessible->widget = NULL;
233 atk_object_notify_state_change (ATK_OBJECT (accessible), ATK_STATE_DEFUNCT,
237 static G_CONST_RETURN gchar*
238 gail_widget_get_description (AtkObject *accessible)
240 if (accessible->description)
241 return accessible->description;
244 /* Get the tooltip from the widget */
245 GtkAccessible *obj = GTK_ACCESSIBLE (accessible);
247 gail_return_val_if_fail (obj, NULL);
249 if (obj->widget == NULL)
255 gail_return_val_if_fail (GTK_WIDGET (obj->widget), NULL);
257 return gtk_widget_get_tooltip_text (obj->widget);
262 gail_widget_get_parent (AtkObject *accessible)
266 parent = accessible->accessible_parent;
269 g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
272 GtkWidget *widget, *parent_widget;
274 widget = GTK_ACCESSIBLE (accessible)->widget;
280 gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
282 parent_widget = widget->parent;
283 if (parent_widget == NULL)
287 * For a widget whose parent is a GtkNoteBook, we return the
288 * accessible object corresponding the GtkNotebookPage containing
289 * the widget as the accessible parent.
291 if (GTK_IS_NOTEBOOK (parent_widget))
295 GtkNotebook *notebook;
298 notebook = GTK_NOTEBOOK (parent_widget);
301 child = gtk_notebook_get_nth_page (notebook, page_num);
306 parent = gtk_widget_get_accessible (parent_widget);
307 parent = atk_object_ref_accessible_child (parent, page_num);
308 g_object_unref (parent);
315 parent = gtk_widget_get_accessible (parent_widget);
321 find_label (GtkWidget *widget)
325 GtkWidget *temp_widget;
327 labels = gtk_widget_list_mnemonic_labels (widget);
335 g_warning ("Widget (%s) has more than one label", G_OBJECT_TYPE_NAME (widget));
340 label = labels->data;
343 g_list_free (labels);
347 * Ignore a label within a button; bug #136602
349 if (label && GTK_IS_BUTTON (widget))
354 if (temp_widget == widget)
359 temp_widget = gtk_widget_get_parent (temp_widget);
365 static AtkRelationSet*
366 gail_widget_ref_relation_set (AtkObject *obj)
369 AtkRelationSet *relation_set;
372 AtkRelation* relation;
374 gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
376 widget = GTK_ACCESSIBLE (obj)->widget;
383 relation_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_relation_set (obj);
385 if (GTK_IS_BOX (widget) && !GTK_IS_COMBO (widget))
387 * Do not report labelled-by for a GtkBox which could be a
392 if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
394 label = find_label (widget);
397 if (GTK_IS_BUTTON (widget))
399 * Handle the case where GnomeIconEntry is the mnemonic widget.
400 * The GtkButton which is a grandchild of the GnomeIconEntry
401 * should really be the mnemonic widget. See bug #133967.
404 GtkWidget *temp_widget;
406 temp_widget = gtk_widget_get_parent (widget);
408 if (GTK_IS_ALIGNMENT (temp_widget))
410 temp_widget = gtk_widget_get_parent (temp_widget);
411 if (GTK_IS_BOX (temp_widget))
413 label = find_label (temp_widget);
416 label = find_label (gtk_widget_get_parent (temp_widget));
420 else if (GTK_IS_COMBO (widget))
422 * Handle the case when GnomeFileEntry is the mnemonic widget.
423 * The GnomeEntry which is a grandchild of the GnomeFileEntry
424 * should be the mnemonic widget. See bug #137584.
427 GtkWidget *temp_widget;
429 temp_widget = gtk_widget_get_parent (widget);
431 if (GTK_IS_HBOX (temp_widget))
433 temp_widget = gtk_widget_get_parent (temp_widget);
434 if (GTK_IS_BOX (temp_widget))
436 label = find_label (temp_widget);
440 else if (GTK_IS_COMBO_BOX (widget))
442 * Handle the case when GtkFileChooserButton is the mnemonic
443 * widget. The GtkComboBox which is a child of the
444 * GtkFileChooserButton should be the mnemonic widget.
448 GtkWidget *temp_widget;
450 temp_widget = gtk_widget_get_parent (widget);
451 if (GTK_IS_HBOX (temp_widget))
453 label = find_label (temp_widget);
460 array [0] = gtk_widget_get_accessible (label);
462 relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
463 atk_relation_set_add (relation_set, relation);
464 g_object_unref (relation);
472 gail_widget_ref_state_set (AtkObject *accessible)
474 GtkWidget *widget = GTK_ACCESSIBLE (accessible)->widget;
475 AtkStateSet *state_set;
477 state_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_state_set (accessible);
481 atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
485 if (gtk_widget_is_sensitive (widget))
487 atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
488 atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
491 if (gtk_widget_get_can_focus (widget))
493 atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
496 * We do not currently generate notifications when an ATK object
497 * corresponding to a GtkWidget changes visibility by being scrolled
498 * on or off the screen. The testcase for this is the main window
499 * of the testgtk application in which a set of buttons in a GtkVBox
500 * is in a scrooled window with a viewport.
502 * To generate the notifications we would need to do the following:
503 * 1) Find the GtkViewPort among the antecendents of the objects
504 * 2) Create an accesible for the GtkViewPort
505 * 3) Connect to the value-changed signal on the viewport
506 * 4) When the signal is received we need to traverse the children
507 * of the viewport and check whether the children are visible or not
508 * visible; we may want to restrict this to the widgets for which
509 * accessible objects have been created.
510 * 5) We probably need to store a variable on_screen in the
511 * GailWidget data structure so we can determine whether the value has
514 if (gtk_widget_get_visible (widget))
516 atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
517 if (gail_widget_on_screen (widget) && GTK_WIDGET_MAPPED (widget) &&
518 gail_widget_all_parents_visible (widget))
520 atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
524 if (gtk_widget_has_focus (widget) && (widget == focus_widget))
526 AtkObject *focus_obj;
528 focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
529 if (focus_obj == NULL)
530 atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
532 if (gtk_widget_has_default (widget))
534 atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
541 gail_widget_get_index_in_parent (AtkObject *accessible)
544 GtkWidget *parent_widget;
549 type = g_type_from_name ("GailCanvasWidget");
550 widget = GTK_ACCESSIBLE (accessible)->widget;
558 if (accessible->accessible_parent)
562 parent = accessible->accessible_parent;
564 if (GAIL_IS_NOTEBOOK_PAGE (parent) ||
565 G_TYPE_CHECK_INSTANCE_TYPE ((parent), type))
570 gboolean found = FALSE;
572 n_children = atk_object_get_n_accessible_children (parent);
573 for (i = 0; i < n_children; i++)
577 child = atk_object_ref_accessible_child (parent, i);
578 if (child == accessible)
581 g_object_unref (child);
588 gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
589 parent_widget = widget->parent;
590 if (parent_widget == NULL)
592 gail_return_val_if_fail (GTK_IS_CONTAINER (parent_widget), -1);
594 children = gtk_container_get_children (GTK_CONTAINER (parent_widget));
596 index = g_list_index (children, widget);
597 g_list_free (children);
602 atk_component_interface_init (AtkComponentIface *iface)
605 * Use default implementation for contains and get_position
607 iface->add_focus_handler = gail_widget_add_focus_handler;
608 iface->get_extents = gail_widget_get_extents;
609 iface->get_size = gail_widget_get_size;
610 iface->get_layer = gail_widget_get_layer;
611 iface->grab_focus = gail_widget_grab_focus;
612 iface->remove_focus_handler = gail_widget_remove_focus_handler;
613 iface->set_extents = gail_widget_set_extents;
614 iface->set_position = gail_widget_set_position;
615 iface->set_size = gail_widget_set_size;
619 gail_widget_add_focus_handler (AtkComponent *component,
620 AtkFocusHandler handler)
622 GSignalMatchType match_type;
626 match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
627 signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
629 ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL,
630 (gpointer) handler, NULL);
633 return g_signal_connect_closure_by_id (component,
636 G_CALLBACK (handler), NULL,
637 (GClosureNotify) NULL),
647 gail_widget_get_extents (AtkComponent *component,
652 AtkCoordType coord_type)
655 gint x_window, y_window;
656 gint x_toplevel, y_toplevel;
657 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
665 gail_return_if_fail (GTK_IS_WIDGET (widget));
667 *width = widget->allocation.width;
668 *height = widget->allocation.height;
669 if (!gail_widget_on_screen (widget) || (!gtk_widget_is_drawable (widget)))
678 *x = widget->allocation.x;
679 *y = widget->allocation.y;
680 window = gtk_widget_get_parent_window (widget);
686 window = widget->window;
688 gdk_window_get_origin (window, &x_window, &y_window);
693 if (coord_type == ATK_XY_WINDOW)
695 window = gdk_window_get_toplevel (widget->window);
696 gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
704 gail_widget_get_size (AtkComponent *component,
708 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
716 gail_return_if_fail (GTK_IS_WIDGET (widget));
718 *width = widget->allocation.width;
719 *height = widget->allocation.height;
723 gail_widget_get_layer (AtkComponent *component)
726 layer = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (component), "atk-component-layer"));
728 return (AtkLayer) layer;
732 gail_widget_grab_focus (AtkComponent *component)
734 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
737 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
738 if (gtk_widget_get_can_focus (widget))
740 gtk_widget_grab_focus (widget);
741 toplevel = gtk_widget_get_toplevel (widget);
742 if (gtk_widget_is_toplevel (toplevel))
744 #ifdef GDK_WINDOWING_X11
745 gtk_window_present_with_time (GTK_WINDOW (toplevel), gdk_x11_get_server_time (widget->window));
747 gtk_window_present (GTK_WINDOW (toplevel));
757 gail_widget_remove_focus_handler (AtkComponent *component,
760 g_signal_handler_disconnect (component, handler_id);
764 gail_widget_set_extents (AtkComponent *component,
769 AtkCoordType coord_type)
771 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
778 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
780 if (gtk_widget_is_toplevel (widget))
782 if (coord_type == ATK_XY_WINDOW)
784 gint x_current, y_current;
785 GdkWindow *window = widget->window;
787 gdk_window_get_origin (window, &x_current, &y_current);
790 if (x_current < 0 || y_current < 0)
794 gtk_widget_set_uposition (widget, x_current, y_current);
795 gtk_widget_set_size_request (widget, width, height);
799 else if (coord_type == ATK_XY_SCREEN)
801 gtk_widget_set_uposition (widget, x, y);
802 gtk_widget_set_size_request (widget, width, height);
810 gail_widget_set_position (AtkComponent *component,
813 AtkCoordType coord_type)
815 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
822 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
824 if (gtk_widget_is_toplevel (widget))
826 if (coord_type == ATK_XY_WINDOW)
828 gint x_current, y_current;
829 GdkWindow *window = widget->window;
831 gdk_window_get_origin (window, &x_current, &y_current);
834 if (x_current < 0 || y_current < 0)
838 gtk_widget_set_uposition (widget, x_current, y_current);
842 else if (coord_type == ATK_XY_SCREEN)
844 gtk_widget_set_uposition (widget, x, y);
852 gail_widget_set_size (AtkComponent *component,
856 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
863 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
865 if (gtk_widget_is_toplevel (widget))
867 gtk_widget_set_size_request (widget, width, height);
875 * This function is a signal handler for notify_in_event and focus_out_event
876 * signal which gets emitted on a GtkWidget.
879 gail_widget_focus_gtk (GtkWidget *widget,
880 GdkEventFocus *event)
882 GailWidget *gail_widget;
883 GailWidgetClass *klass;
885 gail_widget = GAIL_WIDGET (gtk_widget_get_accessible (widget));
886 klass = GAIL_WIDGET_GET_CLASS (gail_widget);
887 if (klass->focus_gtk)
888 return klass->focus_gtk (widget, event);
894 * This function is the signal handler defined for focus_in_event and
895 * focus_out_event got GailWidget.
897 * It emits a focus-event signal on the GailWidget.
900 gail_widget_real_focus_gtk (GtkWidget *widget,
901 GdkEventFocus *event)
903 AtkObject* accessible;
907 accessible = gtk_widget_get_accessible (widget);
908 g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val);
913 gail_widget_size_allocate_gtk (GtkWidget *widget,
914 GtkAllocation *allocation)
916 AtkObject* accessible;
919 accessible = gtk_widget_get_accessible (widget);
920 if (ATK_IS_COMPONENT (accessible))
922 rect.x = allocation->x;
923 rect.y = allocation->y;
924 rect.width = allocation->width;
925 rect.height = allocation->height;
926 g_signal_emit_by_name (accessible, "bounds_changed", &rect);
931 * This function is the signal handler defined for map and unmap signals.
934 gail_widget_map_gtk (GtkWidget *widget)
936 AtkObject* accessible;
938 accessible = gtk_widget_get_accessible (widget);
939 atk_object_notify_state_change (accessible, ATK_STATE_SHOWING,
940 GTK_WIDGET_MAPPED (widget));
945 * This function is a signal handler for notify signal which gets emitted
946 * when a property changes value on the GtkWidget associated with the object.
948 * It calls a function for the GailWidget type
951 gail_widget_notify_gtk (GObject *obj,
955 GailWidgetClass *klass;
957 widget = GAIL_WIDGET (gtk_widget_get_accessible (GTK_WIDGET (obj)));
958 klass = GAIL_WIDGET_GET_CLASS (widget);
959 if (klass->notify_gtk)
960 klass->notify_gtk (obj, pspec);
964 * This function is a signal handler for notify signal which gets emitted
965 * when a property changes value on the GtkWidget associated with a GailWidget.
967 * It constructs an AtkPropertyValues structure and emits a "property_changed"
968 * signal which causes the user specified AtkPropertyChangeHandler
972 gail_widget_real_notify_gtk (GObject *obj,
975 GtkWidget* widget = GTK_WIDGET (obj);
976 AtkObject* atk_obj = gtk_widget_get_accessible (widget);
980 if (strcmp (pspec->name, "has-focus") == 0)
982 * We use focus-in-event and focus-out-event signals to catch
983 * focus changes so we ignore this.
986 else if (strcmp (pspec->name, "visible") == 0)
988 state = ATK_STATE_VISIBLE;
989 value = gtk_widget_get_visible (widget);
991 else if (strcmp (pspec->name, "sensitive") == 0)
993 state = ATK_STATE_SENSITIVE;
994 value = gtk_widget_get_sensitive (widget);
999 atk_object_notify_state_change (atk_obj, state, value);
1003 gail_widget_focus_event (AtkObject *obj,
1006 AtkObject *focus_obj;
1008 focus_obj = g_object_get_data (G_OBJECT (obj), "gail-focus-object");
1009 if (focus_obj == NULL)
1011 atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in);
1015 gail_widget_find_viewport (GtkWidget *widget)
1018 * Find an antecedent which is a GtkViewPort
1022 parent = widget->parent;
1023 while (parent != NULL)
1025 if (GTK_IS_VIEWPORT (parent))
1027 parent = parent->parent;
1033 * This function checks whether the widget has an antecedent which is
1034 * a GtkViewport and, if so, whether any part of the widget intersects
1035 * the visible rectangle of the GtkViewport.
1037 static gboolean gail_widget_on_screen (GtkWidget *widget)
1039 GtkWidget *viewport;
1040 gboolean return_value;
1042 viewport = gail_widget_find_viewport (widget);
1045 GtkAdjustment *adjustment;
1046 GdkRectangle visible_rect;
1048 adjustment = gtk_viewport_get_vadjustment (GTK_VIEWPORT (viewport));
1049 visible_rect.y = adjustment->value;
1050 adjustment = gtk_viewport_get_hadjustment (GTK_VIEWPORT (viewport));
1051 visible_rect.x = adjustment->value;
1052 visible_rect.width = viewport->allocation.width;
1053 visible_rect.height = viewport->allocation.height;
1055 if (((widget->allocation.x + widget->allocation.width) < visible_rect.x) ||
1056 ((widget->allocation.y + widget->allocation.height) < visible_rect.y) ||
1057 (widget->allocation.x > (visible_rect.x + visible_rect.width)) ||
1058 (widget->allocation.y > (visible_rect.y + visible_rect.height)))
1059 return_value = FALSE;
1061 return_value = TRUE;
1066 * Check whether the widget has been placed of the screen. The
1067 * widget may be MAPPED as when toolbar items do not fit on the toolbar.
1069 if (widget->allocation.x + widget->allocation.width <= 0 &&
1070 widget->allocation.y + widget->allocation.height <= 0)
1071 return_value = FALSE;
1073 return_value = TRUE;
1076 return return_value;
1080 * gail_widget_all_parents_visible:
1081 * @widget: a #GtkWidget
1083 * Checks if all the predecesors (the parent widget, his parent, etc) are visible
1084 * Used to check properly the SHOWING state.
1086 * Return value: TRUE if all the parent hierarchy is visible, FALSE otherwise
1088 static gboolean gail_widget_all_parents_visible (GtkWidget *widget)
1090 GtkWidget *iter_parent = NULL;
1091 gboolean result = TRUE;
1093 for (iter_parent = gtk_widget_get_parent (widget); iter_parent;
1094 iter_parent = gtk_widget_get_parent (iter_parent))
1096 if (!gtk_widget_get_visible (iter_parent))