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);
110 G_DEFINE_TYPE_WITH_CODE (GailWidget, gail_widget, GTK_TYPE_ACCESSIBLE,
111 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
114 gail_widget_class_init (GailWidgetClass *klass)
116 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
117 GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
119 klass->notify_gtk = gail_widget_real_notify_gtk;
120 klass->focus_gtk = gail_widget_real_focus_gtk;
122 accessible_class->connect_widget_destroyed = gail_widget_connect_widget_destroyed;
124 class->get_description = gail_widget_get_description;
125 class->get_parent = gail_widget_get_parent;
126 class->ref_relation_set = gail_widget_ref_relation_set;
127 class->ref_state_set = gail_widget_ref_state_set;
128 class->get_index_in_parent = gail_widget_get_index_in_parent;
129 class->initialize = gail_widget_real_initialize;
133 gail_widget_init (GailWidget *accessible)
138 * This function specifies the GtkWidget for which the GailWidget was created
139 * and specifies a handler to be called when the GtkWidget is destroyed.
142 gail_widget_real_initialize (AtkObject *obj,
145 GtkAccessible *accessible;
148 g_return_if_fail (GTK_IS_WIDGET (data));
150 widget = GTK_WIDGET (data);
152 accessible = GTK_ACCESSIBLE (obj);
153 accessible->widget = widget;
154 gtk_accessible_connect_widget_destroyed (accessible);
155 g_signal_connect_after (widget,
157 G_CALLBACK (gail_widget_focus_gtk),
159 g_signal_connect_after (widget,
161 G_CALLBACK (gail_widget_focus_gtk),
163 g_signal_connect (widget,
165 G_CALLBACK (gail_widget_notify_gtk),
167 g_signal_connect (widget,
169 G_CALLBACK (gail_widget_size_allocate_gtk),
171 atk_component_add_focus_handler (ATK_COMPONENT (accessible),
172 gail_widget_focus_event);
174 * Add signal handlers for GTK signals required to support property changes
176 g_signal_connect (widget,
178 G_CALLBACK (gail_widget_map_gtk),
180 g_signal_connect (widget,
182 G_CALLBACK (gail_widget_map_gtk),
184 g_object_set_data (G_OBJECT (obj), "atk-component-layer",
185 GINT_TO_POINTER (ATK_LAYER_WIDGET));
187 obj->role = ATK_ROLE_UNKNOWN;
191 gail_widget_new (GtkWidget *widget)
194 AtkObject *accessible;
196 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
198 object = g_object_new (GAIL_TYPE_WIDGET, NULL);
200 accessible = ATK_OBJECT (object);
201 atk_object_initialize (accessible, widget);
207 * This function specifies the function to be called when the widget
211 gail_widget_connect_widget_destroyed (GtkAccessible *accessible)
213 if (accessible->widget)
215 g_signal_connect_after (accessible->widget,
217 G_CALLBACK (gail_widget_destroyed),
223 * This function is called when the widget is destroyed.
224 * It sets the widget field in the GtkAccessible structure to NULL
225 * and emits a state-change signal for the state ATK_STATE_DEFUNCT
228 gail_widget_destroyed (GtkWidget *widget,
229 GtkAccessible *accessible)
231 accessible->widget = NULL;
232 atk_object_notify_state_change (ATK_OBJECT (accessible), ATK_STATE_DEFUNCT,
236 static G_CONST_RETURN gchar*
237 gail_widget_get_description (AtkObject *accessible)
239 if (accessible->description)
240 return accessible->description;
243 /* Get the tooltip from the widget */
244 GtkAccessible *obj = GTK_ACCESSIBLE (accessible);
245 GtkTooltipsData *data;
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 data = gtk_tooltips_data_get (obj->widget);
261 return data->tip_text;
266 gail_widget_get_parent (AtkObject *accessible)
270 parent = accessible->accessible_parent;
273 g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
276 GtkWidget *widget, *parent_widget;
278 widget = GTK_ACCESSIBLE (accessible)->widget;
284 gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
286 parent_widget = widget->parent;
287 if (parent_widget == NULL)
291 * For a widget whose parent is a GtkNoteBook, we return the
292 * accessible object corresponding the GtkNotebookPage containing
293 * the widget as the accessible parent.
295 if (GTK_IS_NOTEBOOK (parent_widget))
299 GtkNotebook *notebook;
302 notebook = GTK_NOTEBOOK (parent_widget);
305 child = gtk_notebook_get_nth_page (notebook, page_num);
310 parent = gtk_widget_get_accessible (parent_widget);
311 parent = atk_object_ref_accessible_child (parent, page_num);
312 g_object_unref (parent);
319 parent = gtk_widget_get_accessible (parent_widget);
325 find_label (GtkWidget *widget)
329 GtkWidget *temp_widget;
331 labels = gtk_widget_list_mnemonic_labels (widget);
339 g_warning ("Widget (%s) has more than one label", G_OBJECT_TYPE_NAME (widget));
344 label = labels->data;
347 g_list_free (labels);
351 * Ignore a label within a button; bug #136602
353 if (label && GTK_IS_BUTTON (widget))
358 if (temp_widget == widget)
363 temp_widget = gtk_widget_get_parent (temp_widget);
369 static AtkRelationSet*
370 gail_widget_ref_relation_set (AtkObject *obj)
373 AtkRelationSet *relation_set;
376 AtkRelation* relation;
378 gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
380 widget = GTK_ACCESSIBLE (obj)->widget;
387 relation_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_relation_set (obj);
389 if (GTK_IS_BOX (widget) && !GTK_IS_COMBO (widget))
391 * Do not report labelled-by for a GtkBox which could be a
396 if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
398 label = find_label (widget);
401 if (GTK_IS_BUTTON (widget))
403 * Handle the case where GnomeIconEntry is the mnemonic widget.
404 * The GtkButton which is a grandchild of the GnomeIconEntry
405 * should really be the mnemonic widget. See bug #133967.
408 GtkWidget *temp_widget;
410 temp_widget = gtk_widget_get_parent (widget);
412 if (GTK_IS_ALIGNMENT (temp_widget))
414 temp_widget = gtk_widget_get_parent (temp_widget);
415 if (GTK_IS_BOX (temp_widget))
417 label = find_label (temp_widget);
420 label = find_label (gtk_widget_get_parent (temp_widget));
424 else if (GTK_IS_COMBO (widget))
426 * Handle the case when GnomeFileEntry is the mnemonic widget.
427 * The GnomeEntry which is a grandchild of the GnomeFileEntry
428 * should be the mnemonic widget. See bug #137584.
431 GtkWidget *temp_widget;
433 temp_widget = gtk_widget_get_parent (widget);
435 if (GTK_IS_HBOX (temp_widget))
437 temp_widget = gtk_widget_get_parent (temp_widget);
438 if (GTK_IS_BOX (temp_widget))
440 label = find_label (temp_widget);
444 else if (GTK_IS_COMBO_BOX (widget))
446 * Handle the case when GtkFileChooserButton is the mnemonic
447 * widget. The GtkComboBox which is a child of the
448 * GtkFileChooserButton should be the mnemonic widget.
452 GtkWidget *temp_widget;
454 temp_widget = gtk_widget_get_parent (widget);
455 if (GTK_IS_HBOX (temp_widget))
457 label = find_label (temp_widget);
464 array [0] = gtk_widget_get_accessible (label);
466 relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
467 atk_relation_set_add (relation_set, relation);
468 g_object_unref (relation);
476 gail_widget_ref_state_set (AtkObject *accessible)
478 GtkWidget *widget = GTK_ACCESSIBLE (accessible)->widget;
479 AtkStateSet *state_set;
481 state_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_state_set (accessible);
485 atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
489 if (GTK_WIDGET_IS_SENSITIVE (widget))
491 atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
492 atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
495 if (GTK_WIDGET_CAN_FOCUS (widget))
497 atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
500 * We do not currently generate notifications when an ATK object
501 * corresponding to a GtkWidget changes visibility by being scrolled
502 * on or off the screen. The testcase for this is the main window
503 * of the testgtk application in which a set of buttons in a GtkVBox
504 * is in a scrooled window with a viewport.
506 * To generate the notifications we would need to do the following:
507 * 1) Find the GtkViewPort among the antecendents of the objects
508 * 2) Create an accesible for the GtkViewPort
509 * 3) Connect to the value-changed signal on the viewport
510 * 4) When the signal is received we need to traverse the children
511 * of the viewport and check whether the children are visible or not
512 * visible; we may want to restrict this to the widgets for which
513 * accessible objects have been created.
514 * 5) We probably need to store a variable on_screen in the
515 * GailWidget data structure so we can determine whether the value has
518 if (GTK_WIDGET_VISIBLE (widget))
520 atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
521 if (gail_widget_on_screen (widget) &&
522 GTK_WIDGET_MAPPED (widget))
524 atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
528 if (GTK_WIDGET_HAS_FOCUS (widget) && (widget == focus_widget))
530 AtkObject *focus_obj;
532 focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
533 if (focus_obj == NULL)
534 atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
536 if (GTK_WIDGET_HAS_DEFAULT(widget))
538 atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
545 gail_widget_get_index_in_parent (AtkObject *accessible)
548 GtkWidget *parent_widget;
553 type = g_type_from_name ("GailCanvasWidget");
554 widget = GTK_ACCESSIBLE (accessible)->widget;
562 if (accessible->accessible_parent)
566 parent = accessible->accessible_parent;
568 if (GAIL_IS_NOTEBOOK_PAGE (parent) ||
569 G_TYPE_CHECK_INSTANCE_TYPE ((parent), type))
574 gboolean found = FALSE;
576 n_children = atk_object_get_n_accessible_children (parent);
577 for (i = 0; i < n_children; i++)
581 child = atk_object_ref_accessible_child (parent, i);
582 if (child == accessible)
585 g_object_unref (child);
592 gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
593 parent_widget = widget->parent;
594 if (parent_widget == NULL)
596 gail_return_val_if_fail (GTK_IS_CONTAINER (parent_widget), -1);
598 children = gtk_container_get_children (GTK_CONTAINER (parent_widget));
600 index = g_list_index (children, widget);
601 g_list_free (children);
606 atk_component_interface_init (AtkComponentIface *iface)
609 * Use default implementation for contains and get_position
611 iface->add_focus_handler = gail_widget_add_focus_handler;
612 iface->get_extents = gail_widget_get_extents;
613 iface->get_size = gail_widget_get_size;
614 iface->get_layer = gail_widget_get_layer;
615 iface->grab_focus = gail_widget_grab_focus;
616 iface->remove_focus_handler = gail_widget_remove_focus_handler;
617 iface->set_extents = gail_widget_set_extents;
618 iface->set_position = gail_widget_set_position;
619 iface->set_size = gail_widget_set_size;
623 gail_widget_add_focus_handler (AtkComponent *component,
624 AtkFocusHandler handler)
626 GSignalMatchType match_type;
630 match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
631 signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
633 ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL,
634 (gpointer) handler, NULL);
637 return g_signal_connect_closure_by_id (component,
640 G_CALLBACK (handler), NULL,
641 (GClosureNotify) NULL),
651 gail_widget_get_extents (AtkComponent *component,
656 AtkCoordType coord_type)
659 gint x_window, y_window;
660 gint x_toplevel, y_toplevel;
661 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
669 gail_return_if_fail (GTK_IS_WIDGET (widget));
671 *width = widget->allocation.width;
672 *height = widget->allocation.height;
673 if (!gail_widget_on_screen (widget) || (!GTK_WIDGET_DRAWABLE (widget)))
682 *x = widget->allocation.x;
683 *y = widget->allocation.y;
684 window = gtk_widget_get_parent_window (widget);
690 window = widget->window;
692 gdk_window_get_origin (window, &x_window, &y_window);
697 if (coord_type == ATK_XY_WINDOW)
699 window = gdk_window_get_toplevel (widget->window);
700 gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
708 gail_widget_get_size (AtkComponent *component,
712 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
720 gail_return_if_fail (GTK_IS_WIDGET (widget));
722 *width = widget->allocation.width;
723 *height = widget->allocation.height;
727 gail_widget_get_layer (AtkComponent *component)
730 layer = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (component), "atk-component-layer"));
732 return (AtkLayer) layer;
736 gail_widget_grab_focus (AtkComponent *component)
738 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
741 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
742 if (GTK_WIDGET_CAN_FOCUS (widget))
744 gtk_widget_grab_focus (widget);
745 toplevel = gtk_widget_get_toplevel (widget);
746 if (GTK_WIDGET_TOPLEVEL (toplevel))
748 #ifdef GDK_WINDOWING_X11
749 gtk_window_present_with_time (GTK_WINDOW (toplevel), gdk_x11_get_server_time (widget->window));
751 gtk_window_present (GTK_WINDOW (toplevel));
761 gail_widget_remove_focus_handler (AtkComponent *component,
764 g_signal_handler_disconnect (component, handler_id);
768 gail_widget_set_extents (AtkComponent *component,
773 AtkCoordType coord_type)
775 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
782 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
784 if (GTK_WIDGET_TOPLEVEL (widget))
786 if (coord_type == ATK_XY_WINDOW)
788 gint x_current, y_current;
789 GdkWindow *window = widget->window;
791 gdk_window_get_origin (window, &x_current, &y_current);
794 if (x_current < 0 || y_current < 0)
798 gtk_widget_set_uposition (widget, x_current, y_current);
799 gtk_widget_set_size_request (widget, width, height);
803 else if (coord_type == ATK_XY_SCREEN)
805 gtk_widget_set_uposition (widget, x, y);
806 gtk_widget_set_size_request (widget, width, height);
814 gail_widget_set_position (AtkComponent *component,
817 AtkCoordType coord_type)
819 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
826 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
828 if (GTK_WIDGET_TOPLEVEL (widget))
830 if (coord_type == ATK_XY_WINDOW)
832 gint x_current, y_current;
833 GdkWindow *window = widget->window;
835 gdk_window_get_origin (window, &x_current, &y_current);
838 if (x_current < 0 || y_current < 0)
842 gtk_widget_set_uposition (widget, x_current, y_current);
846 else if (coord_type == ATK_XY_SCREEN)
848 gtk_widget_set_uposition (widget, x, y);
856 gail_widget_set_size (AtkComponent *component,
860 GtkWidget *widget = GTK_ACCESSIBLE (component)->widget;
867 gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
869 if (GTK_WIDGET_TOPLEVEL (widget))
871 gtk_widget_set_size_request (widget, width, height);
879 * This function is a signal handler for notify_in_event and focus_out_event
880 * signal which gets emitted on a GtkWidget.
883 gail_widget_focus_gtk (GtkWidget *widget,
884 GdkEventFocus *event)
886 GailWidget *gail_widget;
887 GailWidgetClass *klass;
889 gail_widget = GAIL_WIDGET (gtk_widget_get_accessible (widget));
890 klass = GAIL_WIDGET_GET_CLASS (gail_widget);
891 if (klass->focus_gtk)
892 return klass->focus_gtk (widget, event);
898 * This function is the signal handler defined for focus_in_event and
899 * focus_out_event got GailWidget.
901 * It emits a focus-event signal on the GailWidget.
904 gail_widget_real_focus_gtk (GtkWidget *widget,
905 GdkEventFocus *event)
907 AtkObject* accessible;
911 accessible = gtk_widget_get_accessible (widget);
912 g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val);
917 gail_widget_size_allocate_gtk (GtkWidget *widget,
918 GtkAllocation *allocation)
920 AtkObject* accessible;
923 accessible = gtk_widget_get_accessible (widget);
924 if (ATK_IS_COMPONENT (accessible))
926 rect.x = allocation->x;
927 rect.y = allocation->y;
928 rect.width = allocation->width;
929 rect.height = allocation->height;
930 g_signal_emit_by_name (accessible, "bounds_changed", &rect);
935 * This function is the signal handler defined for map and unmap signals.
938 gail_widget_map_gtk (GtkWidget *widget)
940 AtkObject* accessible;
942 accessible = gtk_widget_get_accessible (widget);
943 atk_object_notify_state_change (accessible, ATK_STATE_SHOWING,
944 GTK_WIDGET_MAPPED (widget));
949 * This function is a signal handler for notify signal which gets emitted
950 * when a property changes value on the GtkWidget associated with the object.
952 * It calls a function for the GailWidget type
955 gail_widget_notify_gtk (GObject *obj,
959 GailWidgetClass *klass;
961 widget = GAIL_WIDGET (gtk_widget_get_accessible (GTK_WIDGET (obj)));
962 klass = GAIL_WIDGET_GET_CLASS (widget);
963 if (klass->notify_gtk)
964 klass->notify_gtk (obj, pspec);
968 * This function is a signal handler for notify signal which gets emitted
969 * when a property changes value on the GtkWidget associated with a GailWidget.
971 * It constructs an AtkPropertyValues structure and emits a "property_changed"
972 * signal which causes the user specified AtkPropertyChangeHandler
976 gail_widget_real_notify_gtk (GObject *obj,
979 GtkWidget* widget = GTK_WIDGET (obj);
980 AtkObject* atk_obj = gtk_widget_get_accessible (widget);
984 if (strcmp (pspec->name, "has-focus") == 0)
986 * We use focus-in-event and focus-out-event signals to catch
987 * focus changes so we ignore this.
990 else if (strcmp (pspec->name, "visible") == 0)
992 state = ATK_STATE_VISIBLE;
993 value = GTK_WIDGET_VISIBLE (widget);
995 else if (strcmp (pspec->name, "sensitive") == 0)
997 state = ATK_STATE_SENSITIVE;
998 value = GTK_WIDGET_SENSITIVE (widget);
1003 atk_object_notify_state_change (atk_obj, state, value);
1007 gail_widget_focus_event (AtkObject *obj,
1010 AtkObject *focus_obj;
1012 focus_obj = g_object_get_data (G_OBJECT (obj), "gail-focus-object");
1013 if (focus_obj == NULL)
1015 atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in);
1019 gail_widget_find_viewport (GtkWidget *widget)
1022 * Find an antecedent which is a GtkViewPort
1026 parent = widget->parent;
1027 while (parent != NULL)
1029 if (GTK_IS_VIEWPORT (parent))
1031 parent = parent->parent;
1037 * This function checks whether the widget has an antecedent which is
1038 * a GtkViewport and, if so, whether any part of the widget intersects
1039 * the visible rectangle of the GtkViewport.
1041 static gboolean gail_widget_on_screen (GtkWidget *widget)
1043 GtkWidget *viewport;
1044 gboolean return_value;
1046 viewport = gail_widget_find_viewport (widget);
1049 GtkAdjustment *adjustment;
1050 GdkRectangle visible_rect;
1052 adjustment = gtk_viewport_get_vadjustment (GTK_VIEWPORT (viewport));
1053 visible_rect.y = adjustment->value;
1054 adjustment = gtk_viewport_get_hadjustment (GTK_VIEWPORT (viewport));
1055 visible_rect.x = adjustment->value;
1056 visible_rect.width = viewport->allocation.width;
1057 visible_rect.height = viewport->allocation.height;
1059 if (((widget->allocation.x + widget->allocation.width) < visible_rect.x) ||
1060 ((widget->allocation.y + widget->allocation.height) < visible_rect.y) ||
1061 (widget->allocation.x > (visible_rect.x + visible_rect.width)) ||
1062 (widget->allocation.y > (visible_rect.y + visible_rect.height)))
1063 return_value = FALSE;
1065 return_value = TRUE;
1070 * Check whether the widget has been placed of the screen. The
1071 * widget may be MAPPED as when toolbar items do not fit on the toolbar.
1073 if (widget->allocation.x + widget->allocation.width <= 0 &&
1074 widget->allocation.y + widget->allocation.height <= 0)
1075 return_value = FALSE;
1077 return_value = TRUE;
1080 return return_value;