generic-poky/openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtkcontainer.c.diff

285 lines
9.0 KiB
Diff

--- gtk+-2.6.4/gtk/gtkcontainer.c 2005-03-01 08:28:55.000000000 +0200
+++ gtk+-2.6.4/gtk/gtkcontainer.c 2005-04-06 16:19:36.410003200 +0300
@@ -37,10 +37,13 @@
#include "gtkwindow.h"
#include "gtkintl.h"
#include "gtktoolbar.h"
+#include "gtkmenu.h"
+#include "gtkentry.h"
+#include "gtktextview.h"
+#include "gtkwidget.h"
#include <gobject/gobjectnotifyqueue.c>
#include <gobject/gvaluecollector.h>
-
enum {
ADD,
REMOVE,
@@ -56,6 +59,19 @@
PROP_CHILD
};
+enum {
+ FOCUS_MOVE_OK,
+ FOCUS_MOVE_OK_NO_MOVE,
+ FOCUS_MOVE_FAIL_NO_TEXT
+};
+
+typedef struct
+{
+ GtkWidget *menu;
+ void *func;
+ GtkWidgetTapAndHoldFlags flags;
+} GtkContainerTAH;
+
#define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
#define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
@@ -87,6 +103,9 @@
static gboolean gtk_container_focus_move (GtkContainer *container,
GList *children,
GtkDirectionType direction);
+static gint gtk_container_focus_move_with_tab (GtkContainer *container,
+ GtkDirectionType direction,
+ GtkWidget **fallback);
static void gtk_container_children_callback (GtkWidget *widget,
gpointer client_data);
static void gtk_container_show_all (GtkWidget *widget);
@@ -95,10 +114,14 @@
GdkEventExpose *event);
static void gtk_container_map (GtkWidget *widget);
static void gtk_container_unmap (GtkWidget *widget);
-
+static void gtk_container_tap_and_hold_setup (GtkWidget *widget,
+ GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags);
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
GtkWidget *child);
+static void gtk_container_tap_and_hold_setup_forall( GtkWidget *widget,
+ GtkContainerTAH *tah );
+static void gtk_container_grab_focus( GtkWidget *focus_widget );
/* --- variables --- */
static const gchar vadjustment_key[] = "gtk-vadjustment";
@@ -190,7 +213,9 @@
widget_class->map = gtk_container_map;
widget_class->unmap = gtk_container_unmap;
widget_class->focus = gtk_container_focus;
-
+ widget_class->tap_and_hold_setup = gtk_container_tap_and_hold_setup;
+ widget_class->grab_focus = gtk_container_grab_focus;
+
class->add = gtk_container_add_unimplemented;
class->remove = gtk_container_remove_unimplemented;
class->check_resize = gtk_container_real_check_resize;
@@ -2011,6 +2036,24 @@
GtkWidget *focus_child;
GtkWidget *child;
+ /*
+ * If there's an item focus already and tab was pressed, only go thru
+ * GtkEntries and GtkTextviews. Do _not_ jump from last widget to the first
+ * one and vice verca.
+ */
+ if ((direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD) &&
+ container->focus_child != NULL)
+ {
+ GtkWidget *fallback;
+ fallback = NULL;
+ if (gtk_container_focus_move_with_tab (container, direction, &fallback)
+ != FOCUS_MOVE_FAIL_NO_TEXT)
+ return TRUE;
+
+ if (fallback && gtk_widget_child_focus (fallback, direction))
+ return TRUE;
+ }
+
focus_child = container->focus_child;
while (children)
@@ -2019,7 +2062,7 @@
children = children->next;
if (!child)
- continue;
+ continue;
if (focus_child)
{
@@ -2027,8 +2070,8 @@
{
focus_child = NULL;
- if (gtk_widget_child_focus (child, direction))
- return TRUE;
+ if (gtk_widget_child_focus (child, direction))
+ return TRUE;
}
}
else if (GTK_WIDGET_DRAWABLE (child) &&
@@ -2042,6 +2085,105 @@
return FALSE;
}
+static gint
+gtk_container_focus_move_with_tab (GtkContainer *container,
+ GtkDirectionType direction,
+ GtkWidget **fallback)
+{
+ GList *children, *sorted_children;
+ GtkWidget *child;
+ GtkWidget *focus_child;
+ gboolean found_text;
+ gint ret;
+
+ found_text = FALSE;
+ focus_child = container->focus_child;
+
+ /* This part is copied from gtk_container_focus() */
+ if (container->has_focus_chain)
+ children = g_list_copy (get_focus_chain (container));
+ else
+ children = gtk_container_get_all_children (container);
+
+ if (container->has_focus_chain &&
+ (direction == GTK_DIR_TAB_FORWARD ||
+ direction == GTK_DIR_TAB_BACKWARD))
+ {
+ sorted_children = g_list_copy (children);
+
+ if (direction == GTK_DIR_TAB_BACKWARD)
+ sorted_children = g_list_reverse (sorted_children);
+ }
+ else
+ sorted_children = _gtk_container_focus_sort (container, children,
+ direction, NULL);
+ g_list_free(children);
+ children = sorted_children;
+
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ if (!child)
+ continue;
+
+ if (GTK_IS_ENTRY (child) || GTK_IS_TEXT_VIEW (child))
+ found_text = TRUE;
+
+ if (focus_child)
+ {
+ if (child == focus_child)
+ {
+ focus_child = NULL;
+ if (GTK_IS_CONTAINER (child))
+ {
+ ret = gtk_container_focus_move_with_tab (GTK_CONTAINER (child),
+ direction,
+ fallback);
+ if (ret == FOCUS_MOVE_OK)
+ {
+ g_list_free (sorted_children);
+ return FOCUS_MOVE_OK;
+ }
+ else if (ret == FOCUS_MOVE_OK_NO_MOVE)
+ found_text = TRUE;
+ }
+ }
+ }
+ else if (GTK_WIDGET_DRAWABLE (child) &&
+ gtk_widget_is_ancestor (child, GTK_WIDGET (container)))
+ {
+ if (GTK_IS_ENTRY (child) || GTK_IS_TEXT_VIEW (child))
+ {
+ if (gtk_widget_child_focus (child, direction))
+ {
+ g_list_free (sorted_children);
+ return FOCUS_MOVE_OK;
+ }
+ }
+ else if (GTK_IS_CONTAINER (child))
+ {
+ ret = gtk_container_focus_move_with_tab (GTK_CONTAINER (child),
+ direction,
+ fallback);
+ if (ret == FOCUS_MOVE_OK)
+ {
+ g_list_free (sorted_children);
+ return FOCUS_MOVE_OK;
+ }
+ else if (ret == FOCUS_MOVE_OK_NO_MOVE)
+ found_text = TRUE;
+ }
+ if (GTK_WIDGET_CAN_FOCUS (child) && *fallback == NULL)
+ *fallback = child;
+ }
+ }
+
+ g_list_free (sorted_children);
+
+ return found_text ? FOCUS_MOVE_OK_NO_MOVE : FOCUS_MOVE_FAIL_NO_TEXT;
+}
static void
gtk_container_children_callback (GtkWidget *widget,
@@ -2463,3 +2605,58 @@
gdk_event_free (child_event);
}
}
+
+static void gtk_container_tap_and_hold_setup_forall( GtkWidget *widget,
+ GtkContainerTAH *tah )
+{
+ gtk_widget_tap_and_hold_setup( widget, tah->menu, tah->func,
+ tah->flags );
+}
+
+static void gtk_container_tap_and_hold_setup( GtkWidget *widget,
+ GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags )
+{
+ GtkContainerTAH tah;
+ g_return_if_fail( GTK_IS_WIDGET(widget));
+ g_return_if_fail( menu == NULL || GTK_IS_MENU(menu) );
+ tah.menu = menu;
+ tah.func = func;
+ tah.flags = flags;
+ if (flags & GTK_TAP_AND_HOLD_NO_INTERNALS)
+ gtk_container_foreach( GTK_CONTAINER(widget),
+ (GtkCallback)gtk_container_tap_and_hold_setup_forall, &tah );
+ else
+ gtk_container_forall( GTK_CONTAINER(widget),
+ (GtkCallback)gtk_container_tap_and_hold_setup_forall, &tah );
+ parent_class->tap_and_hold_setup (widget, menu, func, flags);
+}
+
+static void gtk_container_grab_focus( GtkWidget *focus_widget )
+{
+ if( GTK_WIDGET_CAN_FOCUS(focus_widget) )
+ parent_class->grab_focus( focus_widget );
+ else
+ {
+ GList *first = NULL;
+ GList *children = NULL;
+ GtkWidget *old_focus = NULL;
+ GtkWidget *toplevel = NULL;
+
+ toplevel = gtk_widget_get_toplevel( focus_widget );
+ if( !GTK_IS_WINDOW(toplevel) )
+ return;
+
+ old_focus = GTK_WINDOW(toplevel)->focus_widget;
+ first = gtk_container_get_all_children(
+ GTK_CONTAINER(focus_widget) );
+ children = g_list_last( first );
+
+ while( children && GTK_WINDOW(toplevel)->focus_widget == old_focus )
+ {
+ gtk_widget_grab_focus( GTK_WIDGET(children->data) );
+ children = children->prev;
+ }
+ g_list_free( first );
+ }
+}
+