]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Work around OS X GTK treating Option as an AltGr key.
authorSimon Tatham <anakin@pobox.com>
Tue, 1 Sep 2015 18:10:29 +0000 (19:10 +0100)
committerSimon Tatham <anakin@pobox.com>
Tue, 1 Sep 2015 18:13:55 +0000 (19:13 +0100)
If I'm using Option as the Meta key, I want to suppress OS X GTK's
default behaviour of treating it as an AltGr-oid which changes the
keyval and Unicode translation of alphabetic keys. So on OS X I enable
a somewhat bodgy workaround which retranslates from the hardware
keycode as if the Option modifier had not been active at the time, and
use that as the character to prefix Esc to.

This is a bit nasty because I have to hardwire group = 0 in the call
to gdk_keymap_translate_keyboard_state(), whereas in principle what I
wanted was group = (whatever would have resulted from everything else
in the key event other than MOD1). However, in practice, they seem to
be the same, so this will do for the moment.

unix/gtkwin.c
unix/unix.h

index 8e8090540b4fe3c856855bf8f025d2f747d4b140..e75afb755a1f602908da54b45dae1f0325f2ae60 100644 (file)
@@ -996,8 +996,19 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
                     event->keyval == GDK_KEY_KP_Page_Up)) {
             /* nethack mode; do nothing */
         } else {
-            if (gtk_im_context_filter_keypress(inst->imc, event))
-                return TRUE;
+#ifdef META_MANUAL_MASK
+            if (event->state & META_MANUAL_MASK & inst->meta_mod_mask) {
+                /*
+                 * If this key event had a Meta modifier bit set which
+                 * is also in META_MANUAL_MASK, that means passing
+                 * such an event to the GtkIMContext will be unhelpful
+                 * (it will eat the keystroke and turn it into
+                 * something not what we wanted).
+                 */
+            } else
+#endif
+                if (gtk_im_context_filter_keypress(inst->imc, event))
+                    return TRUE;
         }
 
        /*
@@ -1043,6 +1054,33 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
        if (event->state & inst->meta_mod_mask) {
            start = 0;
            if (end == 1) end = 0;
+
+#ifdef META_MANUAL_MASK
+            if (event->state & META_MANUAL_MASK) {
+                /*
+                 * Key events which have a META_MANUAL_MASK meta bit
+                 * set may have a keyval reflecting that, e.g. on OS X
+                 * the Option key acts as an AltGr-like modifier and
+                 * causes different Unicode characters to be output.
+                 *
+                 * To work around this, we clear the dangerous
+                 * modifier bit and retranslate from the hardware
+                 * keycode as if the key had been pressed without that
+                 * modifier. Then we prefix Esc to *that*.
+                 */
+                guint new_keyval;
+                GdkModifierType consumed;
+                if (gdk_keymap_translate_keyboard_state
+                    (gdk_keymap_get_for_display(gdk_display_get_default()),
+                     event->hardware_keycode, event->state & ~META_MANUAL_MASK,
+                     0, &new_keyval, NULL, NULL, &consumed)) {
+                    ucsoutput[0] = '\033';
+                    ucsoutput[1] = gdk_keyval_to_unicode(new_keyval);
+                    use_ucsoutput = TRUE;
+                    end = 2;
+                }
+            }
+#endif
        } else
            start = 1;
 
index 3fe7d7f6626970471988c5499b9f7a7d5ba427b8..1c8f2e8db6837dd1d6f0c04f6cd5b5dc4a01f928 100644 (file)
@@ -25,6 +25,8 @@
 #define NO_PTY_PRE_INIT /* OS X gets very huffy if we try to set[ug]id */
 #define SET_NONBLOCK_VIA_OPENPT /* work around missing fcntl functionality */
 #define OSX_META_KEY_CONFIG /* two possible Meta keys to choose from */
+/* this potential one of the Meta keys needs manual handling */
+#define META_MANUAL_MASK (GDK_MOD1_MASK)
 #endif
 
 struct Filename {