[maemo-commits] [maemo-commits] r13692 - in projects/haf/trunk/hildon-input-method-framework: . src

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Mon Sep 10 13:08:39 EEST 2007
Author: tjunnone
Date: 2007-09-10 13:08:37 +0300 (Mon, 10 Sep 2007)
New Revision: 13692

Added:
   projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.c
   projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.h
Modified:
   projects/haf/trunk/hildon-input-method-framework/ChangeLog
   projects/haf/trunk/hildon-input-method-framework/src/Makefile.am
   projects/haf/trunk/hildon-input-method-framework/src/hildon-im-context.c
Log:
* src/hildon-im-context.c, +src/hildon-im-gtk[c,h], src/Makefile.am:
  - Introduce Hildon platform behavior previously contained in Maemo
    branch of GTK:
     - Pressing tab in a text widget focuses the next text widget
     - Pressing enter in a text widget without a default action simulates tab
  Fixes NB#58192, NB#64072.


Modified: projects/haf/trunk/hildon-input-method-framework/ChangeLog
===================================================================
--- projects/haf/trunk/hildon-input-method-framework/ChangeLog	2007-09-10 09:46:43 UTC (rev 13691)
+++ projects/haf/trunk/hildon-input-method-framework/ChangeLog	2007-09-10 10:08:37 UTC (rev 13692)
@@ -1,3 +1,12 @@
+2007-09-10  Tomas Junnonen  <tomas.junnonen at nokia.com>
+
+	* src/hildon-im-context.c, +src/hildon-im-gtk[c,h], src/Makefile.am:
+	- Introduce Hildon platform behavior previously contained in Maemo
+	  branch of GTK:
+	  - Pressing tab in a text widget focuses the next text widget
+	  - Pressing enter in a text widget without a default action simulates tab
+	Fixes NB#58192, NB#64072.
+
 2007-09-05  Tomas Junnonen  <tomas.junnonen at nokia.com>
 
 	* src/hildon-im-context.c:

Modified: projects/haf/trunk/hildon-input-method-framework/src/Makefile.am
===================================================================
--- projects/haf/trunk/hildon-input-method-framework/src/Makefile.am	2007-09-10 09:46:43 UTC (rev 13691)
+++ projects/haf/trunk/hildon-input-method-framework/src/Makefile.am	2007-09-10 10:08:37 UTC (rev 13692)
@@ -32,7 +32,9 @@
 hildon_im_module_la_SOURCES = \
 	hildon-im-context.h \
 	hildon-im-context.c \
-	hildon-im-module.c
+	hildon-im-module.c \
+	hildon-im-gtk.h \
+	hildon-im-gtk.c
 hildon_im_module_la_LIBADD = \
 	$(GTK_LIBS) $(XTST_LIBS) \
 	-lhildon_im_common

Modified: projects/haf/trunk/hildon-input-method-framework/src/hildon-im-context.c
===================================================================
--- projects/haf/trunk/hildon-input-method-framework/src/hildon-im-context.c	2007-09-10 09:46:43 UTC (rev 13691)
+++ projects/haf/trunk/hildon-input-method-framework/src/hildon-im-context.c	2007-09-10 10:08:37 UTC (rev 13692)
@@ -26,6 +26,7 @@
  */
 
 #include "hildon-im-context.h"
+#include "hildon-im-gtk.h"
 #include "hildon-im-common.h"
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdkx.h>
@@ -1425,12 +1426,39 @@
 
   /* The IM determines the action for the return and enter keys */
   if (event->keyval == GDK_Return ||
+      event->keyval == GDK_KP_Enter ||
       event->keyval == GDK_ISO_Enter)
   {
+    /* If the client widget doesn't activate, enter acts as tab */
+    if (event->type == GDK_KEY_PRESS &&
+        GTK_IS_ENTRY(self->client_gtk_widget) &&
+        !gtk_entry_get_activates_default(GTK_ENTRY(self->client_gtk_widget)))
+    {
+      hildon_im_gtk_focus_next_text_widget(self->client_gtk_widget,
+                                           GTK_DIR_TAB_FORWARD);
+      return TRUE;
+    }
+
+    if (event->keyval == GDK_KP_Enter)
+      return FALSE;
+
     hildon_im_context_send_key_event(self, event->type, event->state, event->keyval, event->hardware_keycode);
     /* Stop both press and release events so they aren't sent to the application. */
     return TRUE;
   }
+  else if (event->keyval == GDK_Tab)
+  {
+    if (event->type == GDK_KEY_PRESS)
+    {
+      if ((event->state & GDK_CONTROL_MASK) == 0)
+        hildon_im_gtk_focus_next_text_widget(self->client_gtk_widget,
+                                             GTK_DIR_TAB_FORWARD);
+      else
+        hildon_im_gtk_focus_next_text_widget(self->client_gtk_widget,
+                                             GTK_DIR_TAB_BACKWARD);
+    }
+    return TRUE;
+  }
 
 #ifdef MAEMO_CHANGES
   g_object_get(self, "hildon-input-mode", &input_mode, NULL);

Added: projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.c
===================================================================
--- projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.c	2007-09-10 09:46:43 UTC (rev 13691)
+++ projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.c	2007-09-10 10:08:37 UTC (rev 13692)
@@ -0,0 +1,187 @@
+/**
+   @file: hildon-im-gtk.c
+
+ */
+/*
+ * This file is part of hildon-input-method-framework
+ *
+ * Copyright (C) 2005-2007 Nokia Corporation.
+ *
+ * Contact: Mohammad Anwari <Mohammad.Anwari at nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "hildon-im-gtk.h"
+
+/* Widget spatial comparison from GtkContainer */
+static gint
+tab_compare(gconstpointer a,
+            gconstpointer b,
+            gpointer      data)
+{
+  const GtkWidget *child1 = a;
+  const GtkWidget *child2 = b;
+  GtkTextDirection text_direction = GPOINTER_TO_INT(data);
+
+  gint y1 = child1->allocation.y + child1->allocation.height / 2;
+  gint y2 = child2->allocation.y + child2->allocation.height / 2;
+
+  if (y1 == y2)
+  {
+    gint x1 = child1->allocation.x + child1->allocation.width / 2;
+    gint x2 = child2->allocation.x + child2->allocation.width / 2;
+      
+    if (text_direction == GTK_TEXT_DIR_RTL) 
+      return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1);
+    else
+      return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1);
+  }
+  else
+    return (y1 < y2) ? -1 : 1;
+}
+
+static GList *
+container_focus_sort(GtkContainer     *container,
+                     GList            *children,
+                     GtkDirectionType  direction)
+{
+  GtkTextDirection text_direction = gtk_widget_get_direction(GTK_WIDGET(container));
+  children = g_list_sort_with_data(children, tab_compare, GINT_TO_POINTER(text_direction));
+
+  if (direction == GTK_DIR_TAB_BACKWARD)
+    children = g_list_reverse(children);
+
+  return children;
+}
+
+static void
+container_children_callback(GtkWidget *widget,
+                            gpointer   client_data)
+{
+  GList **children;
+
+  children = (GList**)client_data;
+  *children = g_list_prepend(*children, widget);
+}
+
+/* same as gtk_container_get_children, except it includes internals */
+static GList *
+container_get_all_children(GtkContainer *container)
+{
+  GList *children = NULL;
+
+  gtk_container_forall(container,
+                       container_children_callback,
+                       &children);
+  return children;
+}
+
+static gboolean
+move_focus(GtkContainer     *container,
+           GtkDirectionType direction,
+           GtkWidget        *old_focus_widget)
+{
+  GList *children, *child;
+  GtkWidget *child_widget;
+  gboolean found = FALSE;
+
+  if (container->has_focus_chain)
+  {
+    children = g_list_copy(g_object_get_data(G_OBJECT(container),
+                                             "gtk-container-focus-chain"));
+
+    if (direction == GTK_DIR_TAB_BACKWARD)
+      children = g_list_reverse(children);
+  }
+  else
+  {
+    children = container_get_all_children(container);
+    children = container_focus_sort(container, children, direction);
+  }
+
+  if (old_focus_widget)
+  {
+    GList *old_widget_location;
+
+    old_widget_location = g_list_find(children, old_focus_widget);
+    if (old_widget_location)
+    {
+      children = old_widget_location->next;
+    }
+  }
+
+  for (child = children; child; child = child->next)
+  {
+    child_widget = child->data;
+
+    if (!child_widget)
+      continue;
+
+    if (GTK_IS_ENTRY(child_widget) || GTK_IS_TEXT_VIEW(child_widget))
+    {
+      if (GTK_WIDGET_CAN_FOCUS(child_widget))
+      {
+        gtk_widget_child_focus(child_widget, direction);
+        found = TRUE;
+        break;
+      }
+    }
+
+    if (GTK_IS_CONTAINER(child_widget))
+    {
+      found = move_focus(GTK_CONTAINER(child_widget),
+                         direction,
+                         child_widget);
+      if (found)
+        break;
+    }
+  }
+
+  g_list_free(children);
+  return found;
+}
+
+void
+hildon_im_gtk_focus_next_text_widget(GtkWidget *current_focus,
+                                     GtkDirectionType direction)
+{
+  GtkWidget *container;
+  GtkWidget *toplevel;
+  GtkWidget *child;
+
+  toplevel = gtk_widget_get_toplevel(current_focus);
+  if (!GTK_WIDGET_TOPLEVEL(toplevel))
+    return;
+
+  container = gtk_widget_get_ancestor(gtk_window_get_focus(GTK_WINDOW(toplevel)),
+                                      GTK_TYPE_CONTAINER);
+
+  child = current_focus;
+  while (container != NULL &&
+         move_focus(GTK_CONTAINER(container),
+                    direction,
+                    child) == FALSE)
+  {
+    GtkWidget *parent = gtk_widget_get_parent(container);
+
+    child = container;
+    if (parent)
+      container = gtk_widget_get_ancestor(parent, GTK_TYPE_CONTAINER);
+    else
+      container = NULL;
+  }
+}

Added: projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.h
===================================================================
--- projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.h	2007-09-10 09:46:43 UTC (rev 13691)
+++ projects/haf/trunk/hildon-input-method-framework/src/hildon-im-gtk.h	2007-09-10 10:08:37 UTC (rev 13692)
@@ -0,0 +1,38 @@
+/**
+   @file: hildon-im-gtk.h
+
+ */
+/*
+ * This file is part of hildon-input-method-framework
+ *
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Mohammad Anwari <Mohammad.Anwari at nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_IM_GTK_H__
+#define __HILDON_IM_GTK_H__
+
+#include <gtk/gtk.h>
+
+void
+hildon_im_gtk_focus_next_text_widget(GtkWidget *current_focus,
+                                     GtkDirectionType direction);
+
+#endif


More information about the maemo-commits mailing list