285 lines
9.0 KiB
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 );
|
|
+ }
|
|
+}
|
|
+
|