# HG changeset patch # User Bram Moolenaar # Date 1589631305 -7200 # Node ID 8590a462ad4670e98c9e9546de37c672cc66460f # Parent e5482a10499c7c8b20284bdfa43a876edae55247 patch 8.2.0765: In the GUI can't use all the modifiers. Commit: https://github.com/vim/vim/commit/fd615a3c901f59abddca27c6a09940be552c0f4d Author: Bram Moolenaar Date: Sat May 16 14:01:51 2020 +0200 patch 8.2.0765: In the GUI can't use all the modifiers. Problem: In the GUI can't use all the modifiers. (Andri M?ll) Solution: Do not apply Alt/Meta early, do it later like with the terminal. Avoid the Motif test from crashing. diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -1212,39 +1212,9 @@ key_press_event(GtkWidget *widget UNUSED return FALSE; #endif - // Check for Alt/Meta key (Mod1Mask), but not for a BS, DEL or character - // that already has the 8th bit set. - // Don't do this for , that should become K_S_TAB with ALT. - // Don't do this for double-byte encodings, it turns the char into a lead - // byte. - if (len == 1 - && ((state & GDK_MOD1_MASK) -#if GTK_CHECK_VERSION(2,10,0) - || (state & GDK_SUPER_MASK) -#endif - ) - && !(key_sym == GDK_BackSpace || key_sym == GDK_Delete) - && (string[0] & 0x80) == 0 - && !(key_sym == GDK_Tab && (state & GDK_SHIFT_MASK)) - && !enc_dbcs - ) - { - string[0] |= 0x80; - state &= ~GDK_MOD1_MASK; // don't use it again - if (enc_utf8) // convert to utf-8 - { - string[1] = string[0] & 0xbf; - string[0] = ((unsigned)string[0] >> 6) + 0xc0; - if (string[1] == CSI) - { - string[2] = KS_EXTRA; - string[3] = (int)KE_CSI; - len = 4; - } - else - len = 2; - } - } + // We used to apply Alt/Meta to the key here (Mod1Mask), but that is now + // done later, the same as it happens for the terminal. Hopefully that + // works for everybody... // Check for special keys. Also do this when len == 1 (key has an ASCII // value) to detect backspace, delete and keypad keys. @@ -1266,52 +1236,37 @@ key_press_event(GtkWidget *widget UNUSED if (len == 0) // Unrecognized key return TRUE; - // Special keys (and a few others) may have modifiers. Also when using a - // double-byte encoding (can't set the 8th bit). - if (len == -3 || key_sym == GDK_space || key_sym == GDK_Tab - || key_sym == GDK_Return || key_sym == GDK_Linefeed - || key_sym == GDK_Escape || key_sym == GDK_KP_Tab - || key_sym == GDK_ISO_Enter || key_sym == GDK_3270_Enter - || (enc_dbcs && len == 1 && ((state & GDK_MOD1_MASK) -#if GTK_CHECK_VERSION(2,10,0) - || (state & GDK_SUPER_MASK) -#endif - ))) - { - modifiers = modifiers_gdk2vim(state); - - /* - * For some keys a shift modifier is translated into another key - * code. - */ - if (len == -3) - key = TO_SPECIAL(string[1], string[2]); - else - key = string[0]; - - key = simplify_key(key, &modifiers); - if (key == CSI) - key = K_CSI; - if (IS_SPECIAL(key)) - { - string[0] = CSI; - string[1] = K_SECOND(key); - string[2] = K_THIRD(key); - len = 3; - } - else - { - string[0] = key; - len = 1; - } - - if (modifiers != 0) - { - string2[0] = CSI; - string2[1] = KS_MODIFIER; - string2[2] = modifiers; - add_to_input_buf(string2, 3); - } + // Handle modifiers. + modifiers = modifiers_gdk2vim(state); + + // For some keys a shift modifier is translated into another key code. + if (len == -3) + key = TO_SPECIAL(string[1], string[2]); + else + key = string[0]; + + key = simplify_key(key, &modifiers); + if (key == CSI) + key = K_CSI; + if (IS_SPECIAL(key)) + { + string[0] = CSI; + string[1] = K_SECOND(key); + string[2] = K_THIRD(key); + len = 3; + } + else + { + string[0] = key; + len = 1; + } + + if (modifiers != 0) + { + string2[0] = CSI; + string2[1] = KS_MODIFIER; + string2[2] = modifiers; + add_to_input_buf(string2, 3); } if (len == 1 && ((string[0] == Ctrl_C && ctrl_c_interrupts) diff --git a/src/gui_mac.c b/src/gui_mac.c --- a/src/gui_mac.c +++ b/src/gui_mac.c @@ -2168,9 +2168,9 @@ gui_mac_unicode_key_event( // taken liberally from gui_w48.c key_char = simplify_key(key_char, (int *)&vimModifiers); - // Interpret META, include SHIFT, etc. + // Unify modifiers somewhat. No longer use ALT to set the 8th bit. key_char = extract_modifiers(key_char, (int *)&vimModifiers, - TRUE, NULL); + FALSE, NULL); if (key_char == CSI) key_char = K_CSI; diff --git a/src/gui_motif.c b/src/gui_motif.c --- a/src/gui_motif.c +++ b/src/gui_motif.c @@ -1238,8 +1238,11 @@ add_pixmap_args(vimmenu_T *menu, Arg *ar } else { +# if 0 // DISABLED - this causes a crash when running "make test_gui" in + // Test_colorscheme() if (menu->xpm_fname != NULL) XtSetArg(args[n], XmNpixmapFile, menu->xpm_fname); n++; +# endif XtSetArg(args[n], XmNpixmapData, menu->xpm); n++; XtSetArg(args[n], XmNlabelLocation, XmBOTTOM); n++; } diff --git a/src/gui_w32.c b/src/gui_w32.c --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -847,8 +847,8 @@ char_to_string(int ch, char_u *string, i if (ch < 0x100 && !isalpha(ch) && isprint(ch)) modifiers &= ~MOD_MASK_SHIFT; - // Interpret the ALT key as making the key META, include SHIFT, etc. - ch = extract_modifiers(ch, &modifiers, TRUE, NULL); + // Unify modifiers somewhat. No longer use ALT to set the 8th bit. + ch = extract_modifiers(ch, &modifiers, FALSE, NULL); if (ch == CSI) ch = K_CSI; diff --git a/src/gui_x11.c b/src/gui_x11.c --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -771,8 +771,8 @@ gui_x11_key_hit_cb( #else char_u string[4], string2[3]; #endif - KeySym key_sym, key_sym2; - int len, len2; + KeySym key_sym; + int len; int i; int modifiers; int key; @@ -883,57 +883,9 @@ gui_x11_key_hit_cb( } #endif - // Check for Alt/Meta key (Mod1Mask), but not for a BS, DEL or character - // that already has the 8th bit set. And not when using a double-byte - // encoding, setting the 8th bit may make it the lead byte of a - // double-byte character. - if (len == 1 - && (ev_press->state & Mod1Mask) - && !(key_sym == XK_BackSpace || key_sym == XK_Delete) - && (string[0] & 0x80) == 0 - && !enc_dbcs) - { -#if defined(FEAT_MENU) && defined(FEAT_GUI_MOTIF) - // Ignore ALT keys when they are used for the menu only - if (gui.menu_is_active - && (p_wak[0] == 'y' - || (p_wak[0] == 'm' && gui_is_menu_shortcut(string[0])))) - goto theend; -#endif - /* - * Before we set the 8th bit, check to make sure the user doesn't - * already have a mapping defined for this sequence. We determine this - * by checking to see if the input would be the same without the - * Alt/Meta key. - * Don't do this for , that should become K_S_TAB with ALT. - */ - ev_press->state &= ~Mod1Mask; - len2 = XLookupString(ev_press, (char *)string2, sizeof(string2), - &key_sym2, NULL); - if (key_sym2 == XK_space) - string2[0] = ' '; // Otherwise Meta-Ctrl-Space doesn't work - if ( len2 == 1 - && string[0] == string2[0] - && !(key_sym == XK_Tab && (ev_press->state & ShiftMask))) - { - string[0] |= 0x80; - if (enc_utf8) // convert to utf-8 - { - string[1] = string[0] & 0xbf; - string[0] = ((unsigned)string[0] >> 6) + 0xc0; - if (string[1] == CSI) - { - string[2] = KS_EXTRA; - string[3] = (int)KE_CSI; - len = 4; - } - else - len = 2; - } - } - else - ev_press->state |= Mod1Mask; - } + // We used to apply Alt/Meta to the key here (Mod1Mask), but that is now + // done later, the same as it happens for the terminal. Hopefully that + // works for everybody... if (len == 1 && string[0] == CSI) { @@ -963,54 +915,47 @@ gui_x11_key_hit_cb( if (len == 0) goto theend; - // Special keys (and a few others) may have modifiers. Also when using a - // double-byte encoding (can't set the 8th bit). - if (len == -3 || key_sym == XK_space || key_sym == XK_Tab - || key_sym == XK_Return || key_sym == XK_Linefeed - || key_sym == XK_Escape - || (enc_dbcs && len == 1 && (ev_press->state & Mod1Mask))) + // Handle modifiers. + modifiers = 0; + if (ev_press->state & ShiftMask) + modifiers |= MOD_MASK_SHIFT; + if (ev_press->state & ControlMask) + modifiers |= MOD_MASK_CTRL; + if (ev_press->state & Mod1Mask) + modifiers |= MOD_MASK_ALT; + if (ev_press->state & Mod4Mask) + modifiers |= MOD_MASK_META; + + /* + * For some keys a shift modifier is translated into another key + * code. + */ + if (len == -3) + key = TO_SPECIAL(string[1], string[2]); + else + key = string[0]; + key = simplify_key(key, &modifiers); + if (key == CSI) + key = K_CSI; + if (IS_SPECIAL(key)) { - modifiers = 0; - if (ev_press->state & ShiftMask) - modifiers |= MOD_MASK_SHIFT; - if (ev_press->state & ControlMask) - modifiers |= MOD_MASK_CTRL; - if (ev_press->state & Mod1Mask) - modifiers |= MOD_MASK_ALT; - if (ev_press->state & Mod4Mask) - modifiers |= MOD_MASK_META; - - /* - * For some keys a shift modifier is translated into another key - * code. - */ - if (len == -3) - key = TO_SPECIAL(string[1], string[2]); - else - key = string[0]; - key = simplify_key(key, &modifiers); - if (key == CSI) - key = K_CSI; - if (IS_SPECIAL(key)) - { - string[0] = CSI; - string[1] = K_SECOND(key); - string[2] = K_THIRD(key); - len = 3; - } - else - { - string[0] = key; - len = 1; - } - - if (modifiers != 0) - { - string2[0] = CSI; - string2[1] = KS_MODIFIER; - string2[2] = modifiers; - add_to_input_buf(string2, 3); - } + string[0] = CSI; + string[1] = K_SECOND(key); + string[2] = K_THIRD(key); + len = 3; + } + else + { + string[0] = key; + len = 1; + } + + if (modifiers != 0) + { + string2[0] = CSI; + string2[1] = KS_MODIFIER; + string2[2] = modifiers; + add_to_input_buf(string2, 3); } if (len == 1 && ((string[0] == Ctrl_C && ctrl_c_interrupts) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 765, +/**/ 764, /**/ 763,