]> Pileus Git - ~andy/gtk/commitdiff
Bug 145058 - Inputting "^^" requires four keystrokes on Win32, differs
authorTor Lillqvist <tml@novell.com>
Thu, 29 Jan 2009 13:43:42 +0000 (13:43 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Thu, 29 Jan 2009 13:43:42 +0000 (13:43 +0000)
2009-01-29  Tor Lillqvist  <tml@novell.com>

Bug 145058 - Inputting "^^" requires four keystrokes on Win32,
differs from platform default behaviour

* gtk/gtkimcontextsimple.c
(check_win32_special_case_after_compact_match): New
function. Called from check_compact_table() after a table-based
match has committed a character. In case there was two identical
dead accents in the input, another copy of the spacing accent that
was already committed is committed. This fixes #145058.

(check_win32_special_cases): New function. Called first from
gtk_im_context_simple_filter_keypress(). This fixes another
problem: a dead accent followed by a space should commit the
corresponding spacing accent. The compose tables from X commit
another character in two cases and we want to override that on
Windows.

Add GTK_NOTE (MISC) debugging output to this code.

svn path=/trunk/; revision=22253

ChangeLog
gtk/gtkimcontextsimple.c

index f7c68196ac7e60645d63dbf0b7575162e5896b3c..2979cca025299e0ad6cf6431e68db064f34eddc8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2009-01-29  Tor Lillqvist  <tml@novell.com>
+
+       Bug 145058 - Inputting "^^" requires four keystrokes on Win32,
+       differs from platform default behaviour
+
+       * gtk/gtkimcontextsimple.c
+       (check_win32_special_case_after_compact_match): New
+       function. Called from check_compact_table() after a table-based
+       match has committed a character. In case there was two identical
+       dead accents in the input, another copy of the spacing accent that
+       was already committed is committed. This fixes #145058.
+
+       (check_win32_special_cases): New function. Called first from
+       gtk_im_context_simple_filter_keypress(). This fixes another
+       problem: a dead accent followed by a space should commit the
+       corresponding spacing accent. The compose tables from X commit
+       another character in two cases and we want to override that on
+       Windows.
+
+       Add GTK_NOTE (MISC) debugging output to this code.
+
 2009-01-29  Claudio Saavedra  <csaavedra@igalia.com>
 
        Bug 569435 – make maintainer-clean removes non-generated sources
index 532ddefb7f3dbe9ae4e5622a5b76f575b6a89878..62bab7c0c92137715ac525db43a5f601cfe9caba 100644 (file)
@@ -270,6 +270,72 @@ check_table (GtkIMContextSimple    *context_simple,
   return FALSE;
 }
 
+/* Checks if a keysym is a dead key. Dead key keysym values are defined in
+ * ../gdk/gdkkeysyms.h and the first is GDK_dead_grave. As X.Org is updated,
+ * more dead keys are added and we need to update the upper limit.
+ * Currently, the upper limit is GDK_dead_dasia+1. The +1 has to do with 
+ * a temporary issue in the X.Org header files. 
+ * In future versions it will be just the keysym (no +1).
+ */
+#define IS_DEAD_KEY(k) \
+    ((k) >= GDK_dead_grave && (k) <= (GDK_dead_dasia+1))
+
+#ifdef GDK_WINDOWING_WIN32
+
+/* On Windows, user expectation is that typing a dead accent followed
+ * by space will input the corresponding spacing character. The X
+ * compose tables are different for dead acute and diaeresis, which
+ * when followed by space produce a plain ASCII apostrophe and double
+ * quote respectively. So special-case those.
+ */
+
+static gboolean
+check_win32_special_cases (GtkIMContextSimple    *context_simple,
+                          gint                   n_compose)
+{
+  if (n_compose == 2 &&
+      context_simple->compose_buffer[1] == GDK_space)
+    {
+      gunichar value = 0;
+
+      switch (context_simple->compose_buffer[0])
+       {
+       case GDK_dead_acute:
+         value = 0x00B4; break;
+       case GDK_dead_diaeresis:
+         value = 0x00A8; break;
+       }
+      if (value > 0)
+       {
+         gtk_im_context_simple_commit_char (GTK_IM_CONTEXT (context_simple), value);
+         context_simple->compose_buffer[0] = 0;
+
+         GTK_NOTE (MISC, g_print ("win32: U+%04X\n", value));
+         return TRUE;
+       }
+    }
+  return FALSE;
+}
+
+static void
+check_win32_special_case_after_compact_match (GtkIMContextSimple    *context_simple,
+                                             gint                   n_compose,
+                                             guint                  value)
+{
+  /* On Windows user expectation is that typing two dead accents will input
+   * two corresponding spacing accents.
+   */
+  if (n_compose == 2 &&
+      context_simple->compose_buffer[0] == context_simple->compose_buffer[1] &&
+      IS_DEAD_KEY (context_simple->compose_buffer[0]))
+    {
+      gtk_im_context_simple_commit_char (GTK_IM_CONTEXT (context_simple), value);
+      GTK_NOTE (MISC, g_print ("win32: U+%04X ", value));
+    }
+}
+
+#endif
+
 static gboolean
 check_compact_table (GtkIMContextSimple    *context_simple,
             const GtkComposeTableCompact *table,
@@ -292,11 +358,18 @@ check_compact_table (GtkIMContextSimple    *context_simple,
                 compare_seq_index);
 
   if (!seq_index)
-    return FALSE;
+    {
+      GTK_NOTE (MISC, g_print ("compact: no\n"));
+      return FALSE;
+    }
 
   if (seq_index && n_compose == 1)
-    return TRUE;
+    {
+      GTK_NOTE (MISC, g_print ("compact: yes\n"));
+      return TRUE;
+    }
 
+  GTK_NOTE (MISC, g_print ("compact: %d ", *seq_index));
   seq = NULL;
 
   for (i = n_compose-1; i < table->max_seq_len; i++)
@@ -317,6 +390,8 @@ check_compact_table (GtkIMContextSimple    *context_simple,
               else
                 {
                   g_signal_emit_by_name (context_simple, "preedit-changed");
+
+                 GTK_NOTE (MISC, g_print ("yes\n"));
                  return TRUE;
                 }
              }
@@ -324,19 +399,27 @@ check_compact_table (GtkIMContextSimple    *context_simple,
     }
 
   if (!seq)
-    return FALSE;
+    {
+      GTK_NOTE (MISC, g_print ("no\n"));
+      return FALSE;
+    }
   else
     {
       gunichar value;
 
       value = seq[row_stride - 1];
-         
+
       gtk_im_context_simple_commit_char (GTK_IM_CONTEXT (context_simple), value);
+#ifdef G_OS_WIN32
+      check_win32_special_case_after_compact_match (context_simple, n_compose, value);
+#endif
       context_simple->compose_buffer[0] = 0;
 
+      GTK_NOTE (MISC, g_print ("U+%04X\n", value));
       return TRUE;
     }
 
+  GTK_NOTE (MISC, g_print ("no\n"));
   return FALSE;
 }
 
@@ -407,16 +490,6 @@ check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
   return FALSE;
 }
 
-/* Checks if a keysym is a dead key. Dead key keysym values are defined in
- * ../gdk/gdkkeysyms.h and the first is GDK_dead_grave. As X.Org is updated,
- * more dead keys are added and we need to update the upper limit.
- * Currently, the upper limit is GDK_dead_dasia+1. The +1 has to do with 
- * a temporary issue in the X.Org header files. 
- * In future versions it will be just the keysym (no +1).
- */
-#define IS_DEAD_KEY(k) \
-    ((k) >= GDK_dead_grave && (k) <= (GDK_dead_dasia+1))
-
 static gboolean
 check_algorithmically (GtkIMContextSimple    *context_simple,
                       gint                   n_compose)
@@ -930,6 +1003,25 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
           tmp_list = tmp_list->next;
         }
 
+      GTK_NOTE (MISC, {
+         g_print ("[ ");
+         for (i = 0; i < n_compose; i++)
+           {
+             const gchar *keyval_name = gdk_keyval_name (context_simple->compose_buffer[i]);
+             
+             if (keyval_name != NULL)
+               g_print ("%s ", keyval_name);
+             else
+               g_print ("%04x ", context_simple->compose_buffer[i]);
+           }
+         g_print ("] ");
+       });
+
+#ifdef GDK_WINDOWING_WIN32
+      if (check_win32_special_cases (context_simple, n_compose))
+       return TRUE;
+#endif
+
       if (check_compact_table (context_simple, &gtk_compose_table_compact, n_compose))
         return TRUE;