]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkimmulticontext.c
filechooserbutton: Update the combo box even after the dialog is cancelled
[~andy/gtk] / gtk / gtkimmulticontext.c
index a8357babfe5ad187401120997a5911eba8ebd3e2..712d5ca8736d83396e7295ca70b4f49796efd579 100644 (file)
@@ -12,9 +12,7 @@
  * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
 #include <locale.h>
 
 #include "gtkimmulticontext.h"
-#include "gtkimmodule.h"
+#include "gtkimmoduleprivate.h"
+#include "gtkintl.h"
+#include "gtklabel.h"
 #include "gtkmain.h"
+#include "gtkprivate.h"
 #include "gtkradiomenuitem.h"
-#include "gtkintl.h"
-#include "gtkprivate.h" /* To get redefinition of GTK_LOCALE_DIR on Win32 */
+#include "gtkseparatormenuitem.h"
+#include "gtksettings.h"
 
 
 /**
@@ -54,6 +55,8 @@ struct _GtkIMMulticontextPrivate
   guint                  focus_in             : 1;
 };
 
+static void     gtk_im_multicontext_notify             (GObject                 *object,
+                                                        GParamSpec              *pspec);
 static void     gtk_im_multicontext_finalize           (GObject                 *object);
 
 static void     gtk_im_multicontext_set_slave          (GtkIMMulticontext       *multicontext,
@@ -99,6 +102,8 @@ static gboolean gtk_im_multicontext_delete_surrounding_cb   (GtkIMContext      *
                                                             gint               n_chars,
                                                             GtkIMMulticontext *multicontext);
 
+static void propagate_purpose (GtkIMMulticontext *context);
+
 static const gchar *global_context_id = NULL;
 
 G_DEFINE_TYPE (GtkIMMulticontext, gtk_im_multicontext, GTK_TYPE_IM_CONTEXT)
@@ -108,7 +113,9 @@ gtk_im_multicontext_class_init (GtkIMMulticontextClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
   GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
-  
+
+  gobject_class->notify = gtk_im_multicontext_notify;
+
   im_context_class->set_client_window = gtk_im_multicontext_set_client_window;
   im_context_class->get_preedit_string = gtk_im_multicontext_get_preedit_string;
   im_context_class->filter_keypress = gtk_im_multicontext_filter_keypress;
@@ -197,13 +204,15 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
       if (!finalizing)
        need_preedit_changed = TRUE;
     }
-  
+
   priv->slave = slave;
 
   if (priv->slave)
     {
       g_object_ref (priv->slave);
 
+      propagate_purpose (multicontext);
+
       g_signal_connect (priv->slave, "preedit-start",
                        G_CALLBACK (gtk_im_multicontext_preedit_start_cb),
                        multicontext);
@@ -222,7 +231,7 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
       g_signal_connect (priv->slave, "delete-surrounding",
                        G_CALLBACK (gtk_im_multicontext_delete_surrounding_cb),
                        multicontext);
-      
+
       if (!priv->use_preedit)  /* Default is TRUE */
        gtk_im_context_set_use_preedit (slave, FALSE);
       if (priv->client_window)
@@ -256,6 +265,9 @@ gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext)
 {
   GtkIMMulticontextPrivate *priv = multicontext->priv;
 
+  if (g_strcmp0 (priv->context_id, get_effective_context_id (multicontext)) != 0)
+    gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
+
   if (!priv->slave)
     {
       GtkIMContext *slave;
@@ -289,7 +301,8 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
 {
   GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
   GtkIMMulticontextPrivate *priv = multicontext->priv;
-  GdkScreen *screen; 
+  GtkIMContext *slave;
+  GdkScreen *screen;
   GtkSettings *settings;
   gboolean connected;
 
@@ -297,7 +310,7 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
 
   if (window)
     {
-      screen = gdk_window_get_screen (GDK_DRAWABLE (window));
+      screen = gdk_window_get_screen (window);
       settings = gtk_settings_get_for_screen (screen);
 
       connected = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (settings),
@@ -313,11 +326,9 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
         }
     }
 
-  if (g_strcmp0 (priv->context_id, get_effective_context_id (multicontext)) != 0)
-    gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
-
-  if (priv->slave)
-    gtk_im_context_set_client_window (priv->slave, window);
+  slave = gtk_im_multicontext_get_slave (multicontext);
+  if (slave)
+    gtk_im_context_set_client_window (slave, window);
 }
 
 static void
@@ -348,24 +359,38 @@ gtk_im_multicontext_filter_keypress (GtkIMContext *context,
   GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
 
   if (slave)
-    return gtk_im_context_filter_keypress (slave, event);
-  else if (event->type == GDK_KEY_PRESS &&
-           (event->state & (GDK_MOD1_MASK | GDK_CONTROL_MASK)) == 0)
     {
-      gunichar ch;
+      return gtk_im_context_filter_keypress (slave, event);
+    }
+  else
+    {
+      GdkDisplay *display;
+      GdkModifierType no_text_input_mask;
+
+      display = gdk_window_get_display (event->window);
+
+      no_text_input_mask =
+        gdk_keymap_get_modifier_mask (gdk_keymap_get_for_display (display),
+                                      GDK_MODIFIER_INTENT_NO_TEXT_INPUT);
 
-      ch = gdk_keyval_to_unicode (event->keyval);
-      if (ch != 0)
+      if (event->type == GDK_KEY_PRESS &&
+          (event->state & no_text_input_mask) == 0)
         {
-          gint len;
-          gchar buf[10];
+          gunichar ch;
 
-          len = g_unichar_to_utf8 (ch, buf);
-          buf[len] = '\0';
+          ch = gdk_keyval_to_unicode (event->keyval);
+          if (ch != 0 && !g_unichar_iscntrl (ch))
+            {
+              gint len;
+              gchar buf[10];
 
-          g_signal_emit_by_name (multicontext, "commit", buf);
+              len = g_unichar_to_utf8 (ch, buf);
+              buf[len] = '\0';
 
-          return TRUE;
+              g_signal_emit_by_name (multicontext, "commit", buf);
+
+              return TRUE;
+            }
         }
     }
 
@@ -377,12 +402,7 @@ gtk_im_multicontext_focus_in (GtkIMContext   *context)
 {
   GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
   GtkIMMulticontextPrivate *priv = multicontext->priv;
-  GtkIMContext *slave;
-
-  if (g_strcmp0 (priv->context_id, get_effective_context_id (multicontext)) != 0)
-    gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
-
-  slave = gtk_im_multicontext_get_slave (multicontext);
+  GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
 
   priv->focus_in = TRUE;
 
@@ -620,7 +640,7 @@ gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
            {
              /* Same translation domain as GTK+ */
              if (!(contexts[i]->domain_dirname && contexts[i]->domain_dirname[0]) ||
-                 pathnamecmp (contexts[i]->domain_dirname, GTK_LOCALEDIR) == 0)
+                 pathnamecmp (contexts[i]->domain_dirname, _gtk_get_localedir ()) == 0)
                {
                  /* Empty or NULL, domain directory, or same as
                   * GTK+. Input method may have a name in the GTK+
@@ -742,3 +762,26 @@ gtk_im_multicontext_set_context_id (GtkIMMulticontext *context,
   priv->context_id_aux = g_strdup (context_id);
   gtk_im_multicontext_set_slave (context, NULL, FALSE);
 }
+
+static void
+propagate_purpose (GtkIMMulticontext *context)
+{
+  GtkInputPurpose purpose;
+  GtkInputHints hints;
+
+  if (context->priv->slave == NULL)
+    return;
+
+  g_object_get (context, "input-purpose", &purpose, NULL);
+  g_object_set (context->priv->slave, "input-purpose", purpose, NULL);
+
+  g_object_get (context, "input-hints", &hints, NULL);
+  g_object_set (context->priv->slave, "input-hints", hints, NULL);
+}
+
+static void
+gtk_im_multicontext_notify (GObject      *object,
+                            GParamSpec   *pspec)
+{
+  propagate_purpose (GTK_IM_MULTICONTEXT (object));
+}