2008-04-15 13:21:13 <timj@imendio.com>
[hildon] / src / hildon-private.c
index ebec6ba..e91d9d9 100644 (file)
@@ -8,7 +8,7 @@
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; version 2.1 of
- * the License.
+ * the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * regardless of where the focus is coming from.
  */
 gboolean G_GNUC_INTERNAL
-hildon_private_composite_focus                  (GtkWidget *widget, 
-                                                 GtkDirectionType direction)
+hildon_private_composite_focus                  (GtkWidget *widget,
+                                                 GtkDirectionType direction,
+                                                 GtkDirectionType *effective_direction)
 {
-    GtkWidget *toplevel = NULL;
-    GtkWidget *focus_widget = NULL;
+  GtkWidget *toplevel = NULL;
+  GtkWidget *focus_widget = NULL;
+  gboolean coming_from_outside = FALSE;
 
-    /* Get the topmost parent widget */  
-    toplevel = gtk_widget_get_toplevel (widget);
+  toplevel = gtk_widget_get_toplevel (widget);
 
-    if (! GTK_IS_WINDOW (toplevel))
-        return GTK_WIDGET_CLASS (g_type_class_peek_parent (
-                    GTK_WIDGET_GET_CLASS (widget)))->focus (widget, direction);
-    /* Get focus widget in the topmost parent widget */
-    focus_widget = GTK_WINDOW (toplevel)->focus_widget;
+  focus_widget = GTK_WINDOW (toplevel)->focus_widget;
 
-    if (! GTK_IS_WIDGET (focus_widget))
-        return TRUE;
-
-    if (! gtk_widget_is_ancestor (focus_widget, widget))
+  if (focus_widget == NULL || gtk_widget_is_ancestor (focus_widget, widget) == FALSE)
     {
-        gtk_widget_grab_focus (widget);
+      /* When coming from outside we want to give focus to the first
+         item in the widgets */
+      *effective_direction = GTK_DIR_TAB_FORWARD;
+      coming_from_outside = TRUE;
     }
-    else
-    {
-        /* Containers grab_focus grabs the focus to the correct widget */
-        switch (direction) {
-            case GTK_DIR_UP:
-            case GTK_DIR_DOWN:
-                if (HILDON_IS_DATE_EDITOR (widget) || HILDON_IS_TIME_EDITOR(widget))
-                    return FALSE;
-                else
-                    return GTK_WIDGET_CLASS (g_type_class_peek_parent
-                            (GTK_WIDGET_GET_CLASS(widget)))->focus (widget, direction);
-                break;
+  else
+    *effective_direction = direction;
 
-            default:
-                return GTK_WIDGET_CLASS (g_type_class_peek_parent
-                        (GTK_WIDGET_GET_CLASS(widget)))->focus (widget, direction);
-                break;
-        }
-    }
+  switch (direction) {
+      case GTK_DIR_UP:
+      case GTK_DIR_DOWN:
+      case GTK_DIR_TAB_FORWARD:
+      case GTK_DIR_TAB_BACKWARD:
+        if ((HILDON_IS_DATE_EDITOR (widget) || HILDON_IS_TIME_EDITOR(widget)) &&
+            !coming_from_outside)
+            return FALSE;
+        /* fall through */
+      default:
+        return TRUE;
+  }
 
-    return TRUE;
+  g_assert_not_reached ();
+  return TRUE;
 }