]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Handle the Ctrl modifier key ourselves if necessary.
authorSimon Tatham <anakin@pobox.com>
Mon, 31 Aug 2015 12:00:42 +0000 (13:00 +0100)
committerSimon Tatham <anakin@pobox.com>
Mon, 31 Aug 2015 12:21:50 +0000 (13:21 +0100)
The Quartz GDK back end, if you press (say) Ctrl-A, will generate a
GdkKeyEvent with keyval='a' and state=CONTROL, but it'll have a
translated string of "a" where the X back end would have returned
"\001". So we have to do our own translation, which fortunately isn't
hard.

unix/gtkwin.c

index 95f360aa431864074b86d87008ca8a3a293eca5f..f6befeed8462e1bd60127642f722e8662c11fc4c 100644 (file)
@@ -1042,6 +1042,33 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
            end = 2;
        }
 
+        /* Some GTK backends (e.g. Quartz) do not change event->string
+         * in response to the Control modifier. So we do it ourselves
+         * here, if it's not already happened.
+         *
+         * The translations below are in line with X11 policy as far
+         * as I know. */
+        if ((event->state & GDK_CONTROL_MASK) && end == 2) {
+            if (output[1] >= '3' && output[1] <= '7') {
+                /* ^3,...,^7 map to 0x1B,...,0x1F */
+                output[1] += '\x1B' - '3';
+            } else if (output[1] == '2') {
+                /* ^2 is ^@, i.e. \0 */
+                output[1] = '\0';
+            } else if (output[1] == '8') {
+                /* ^8 is DEL */
+                output[1] = '\x7F';
+            } else if (output[1] == '/') {
+                /* ^/ is the same as ^_ */
+                output[1] = '\x1F';
+            } else if (output[1] >= 0x40 && output[1] < 0x7F) {
+                /* Everything anywhere near the alphabetics just gets
+                 * masked. */
+                output[1] &= 0x1F;
+            }
+            /* Anything else, e.g. '0', is unchanged. */
+        }
+
        /* Control-Break sends a Break special to the backend */
        if (event->keyval == GDK_KEY_Break &&
            (event->state & GDK_CONTROL_MASK)) {