1 --- gtk+-2.6.4/gtk/gtkcontainer.c 2005-03-01 08:28:55.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtkcontainer.c 2005-04-06 16:19:36.410003200 +0300
6 #include "gtktoolbar.h"
9 +#include "gtktextview.h"
10 +#include "gtkwidget.h"
11 #include <gobject/gobjectnotifyqueue.c>
12 #include <gobject/gvaluecollector.h>
24 + FOCUS_MOVE_OK_NO_MOVE,
25 + FOCUS_MOVE_FAIL_NO_TEXT
32 + GtkWidgetTapAndHoldFlags flags;
35 #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
36 #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
39 static gboolean gtk_container_focus_move (GtkContainer *container,
41 GtkDirectionType direction);
42 +static gint gtk_container_focus_move_with_tab (GtkContainer *container,
43 + GtkDirectionType direction,
44 + GtkWidget **fallback);
45 static void gtk_container_children_callback (GtkWidget *widget,
46 gpointer client_data);
47 static void gtk_container_show_all (GtkWidget *widget);
49 GdkEventExpose *event);
50 static void gtk_container_map (GtkWidget *widget);
51 static void gtk_container_unmap (GtkWidget *widget);
53 +static void gtk_container_tap_and_hold_setup (GtkWidget *widget,
54 + GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags);
55 static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
57 +static void gtk_container_tap_and_hold_setup_forall( GtkWidget *widget,
58 + GtkContainerTAH *tah );
60 +static void gtk_container_grab_focus( GtkWidget *focus_widget );
62 /* --- variables --- */
63 static const gchar vadjustment_key[] = "gtk-vadjustment";
65 widget_class->map = gtk_container_map;
66 widget_class->unmap = gtk_container_unmap;
67 widget_class->focus = gtk_container_focus;
69 + widget_class->tap_and_hold_setup = gtk_container_tap_and_hold_setup;
70 + widget_class->grab_focus = gtk_container_grab_focus;
72 class->add = gtk_container_add_unimplemented;
73 class->remove = gtk_container_remove_unimplemented;
74 class->check_resize = gtk_container_real_check_resize;
75 @@ -2011,6 +2036,24 @@
76 GtkWidget *focus_child;
80 + * If there's an item focus already and tab was pressed, only go thru
81 + * GtkEntries and GtkTextviews. Do _not_ jump from last widget to the first
82 + * one and vice verca.
84 + if ((direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD) &&
85 + container->focus_child != NULL)
87 + GtkWidget *fallback;
89 + if (gtk_container_focus_move_with_tab (container, direction, &fallback)
90 + != FOCUS_MOVE_FAIL_NO_TEXT)
93 + if (fallback && gtk_widget_child_focus (fallback, direction))
97 focus_child = container->focus_child;
100 @@ -2019,7 +2062,7 @@
101 children = children->next;
109 @@ -2027,8 +2070,8 @@
113 - if (gtk_widget_child_focus (child, direction))
115 + if (gtk_widget_child_focus (child, direction))
119 else if (GTK_WIDGET_DRAWABLE (child) &&
120 @@ -2042,6 +2085,105 @@
125 +gtk_container_focus_move_with_tab (GtkContainer *container,
126 + GtkDirectionType direction,
127 + GtkWidget **fallback)
129 + GList *children, *sorted_children;
131 + GtkWidget *focus_child;
132 + gboolean found_text;
135 + found_text = FALSE;
136 + focus_child = container->focus_child;
138 + /* This part is copied from gtk_container_focus() */
139 + if (container->has_focus_chain)
140 + children = g_list_copy (get_focus_chain (container));
142 + children = gtk_container_get_all_children (container);
144 + if (container->has_focus_chain &&
145 + (direction == GTK_DIR_TAB_FORWARD ||
146 + direction == GTK_DIR_TAB_BACKWARD))
148 + sorted_children = g_list_copy (children);
150 + if (direction == GTK_DIR_TAB_BACKWARD)
151 + sorted_children = g_list_reverse (sorted_children);
154 + sorted_children = _gtk_container_focus_sort (container, children,
156 + g_list_free(children);
157 + children = sorted_children;
161 + child = children->data;
162 + children = children->next;
167 + if (GTK_IS_ENTRY (child) || GTK_IS_TEXT_VIEW (child))
172 + if (child == focus_child)
174 + focus_child = NULL;
175 + if (GTK_IS_CONTAINER (child))
177 + ret = gtk_container_focus_move_with_tab (GTK_CONTAINER (child),
180 + if (ret == FOCUS_MOVE_OK)
182 + g_list_free (sorted_children);
183 + return FOCUS_MOVE_OK;
185 + else if (ret == FOCUS_MOVE_OK_NO_MOVE)
190 + else if (GTK_WIDGET_DRAWABLE (child) &&
191 + gtk_widget_is_ancestor (child, GTK_WIDGET (container)))
193 + if (GTK_IS_ENTRY (child) || GTK_IS_TEXT_VIEW (child))
195 + if (gtk_widget_child_focus (child, direction))
197 + g_list_free (sorted_children);
198 + return FOCUS_MOVE_OK;
201 + else if (GTK_IS_CONTAINER (child))
203 + ret = gtk_container_focus_move_with_tab (GTK_CONTAINER (child),
206 + if (ret == FOCUS_MOVE_OK)
208 + g_list_free (sorted_children);
209 + return FOCUS_MOVE_OK;
211 + else if (ret == FOCUS_MOVE_OK_NO_MOVE)
214 + if (GTK_WIDGET_CAN_FOCUS (child) && *fallback == NULL)
219 + g_list_free (sorted_children);
221 + return found_text ? FOCUS_MOVE_OK_NO_MOVE : FOCUS_MOVE_FAIL_NO_TEXT;
225 gtk_container_children_callback (GtkWidget *widget,
226 @@ -2463,3 +2605,58 @@
227 gdk_event_free (child_event);
231 +static void gtk_container_tap_and_hold_setup_forall( GtkWidget *widget,
232 + GtkContainerTAH *tah )
234 + gtk_widget_tap_and_hold_setup( widget, tah->menu, tah->func,
238 +static void gtk_container_tap_and_hold_setup( GtkWidget *widget,
239 + GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags )
241 + GtkContainerTAH tah;
242 + g_return_if_fail( GTK_IS_WIDGET(widget));
243 + g_return_if_fail( menu == NULL || GTK_IS_MENU(menu) );
247 + if (flags & GTK_TAP_AND_HOLD_NO_INTERNALS)
248 + gtk_container_foreach( GTK_CONTAINER(widget),
249 + (GtkCallback)gtk_container_tap_and_hold_setup_forall, &tah );
251 + gtk_container_forall( GTK_CONTAINER(widget),
252 + (GtkCallback)gtk_container_tap_and_hold_setup_forall, &tah );
253 + parent_class->tap_and_hold_setup (widget, menu, func, flags);
256 +static void gtk_container_grab_focus( GtkWidget *focus_widget )
258 + if( GTK_WIDGET_CAN_FOCUS(focus_widget) )
259 + parent_class->grab_focus( focus_widget );
262 + GList *first = NULL;
263 + GList *children = NULL;
264 + GtkWidget *old_focus = NULL;
265 + GtkWidget *toplevel = NULL;
267 + toplevel = gtk_widget_get_toplevel( focus_widget );
268 + if( !GTK_IS_WINDOW(toplevel) )
271 + old_focus = GTK_WINDOW(toplevel)->focus_widget;
272 + first = gtk_container_get_all_children(
273 + GTK_CONTAINER(focus_widget) );
274 + children = g_list_last( first );
276 + while( children && GTK_WINDOW(toplevel)->focus_widget == old_focus )
278 + gtk_widget_grab_focus( GTK_WIDGET(children->data) );
279 + children = children->prev;
281 + g_list_free( first );