forked from aniani/vim
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.
This commit is contained in:
@@ -1212,39 +1212,9 @@ key_press_event(GtkWidget *widget UNUSED,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check for Alt/Meta key (Mod1Mask), but not for a BS, DEL or character
|
// We used to apply Alt/Meta to the key here (Mod1Mask), but that is now
|
||||||
// that already has the 8th bit set.
|
// done later, the same as it happens for the terminal. Hopefully that
|
||||||
// Don't do this for <S-M-Tab>, that should become K_S_TAB with ALT.
|
// works for everybody...
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for special keys. Also do this when len == 1 (key has an ASCII
|
// Check for special keys. Also do this when len == 1 (key has an ASCII
|
||||||
// value) to detect backspace, delete and keypad keys.
|
// value) to detect backspace, delete and keypad keys.
|
||||||
@@ -1266,52 +1236,37 @@ key_press_event(GtkWidget *widget UNUSED,
|
|||||||
if (len == 0) // Unrecognized key
|
if (len == 0) // Unrecognized key
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
// Special keys (and a few others) may have modifiers. Also when using a
|
// Handle modifiers.
|
||||||
// double-byte encoding (can't set the 8th bit).
|
modifiers = modifiers_gdk2vim(state);
|
||||||
if (len == -3 || key_sym == GDK_space || key_sym == GDK_Tab
|
|
||||||
|| key_sym == GDK_Return || key_sym == GDK_Linefeed
|
// For some keys a shift modifier is translated into another key code.
|
||||||
|| key_sym == GDK_Escape || key_sym == GDK_KP_Tab
|
if (len == -3)
|
||||||
|| key_sym == GDK_ISO_Enter || key_sym == GDK_3270_Enter
|
key = TO_SPECIAL(string[1], string[2]);
|
||||||
|| (enc_dbcs && len == 1 && ((state & GDK_MOD1_MASK)
|
else
|
||||||
#if GTK_CHECK_VERSION(2,10,0)
|
key = string[0];
|
||||||
|| (state & GDK_SUPER_MASK)
|
|
||||||
#endif
|
key = simplify_key(key, &modifiers);
|
||||||
)))
|
if (key == CSI)
|
||||||
|
key = K_CSI;
|
||||||
|
if (IS_SPECIAL(key))
|
||||||
{
|
{
|
||||||
modifiers = modifiers_gdk2vim(state);
|
string[0] = CSI;
|
||||||
|
string[1] = K_SECOND(key);
|
||||||
|
string[2] = K_THIRD(key);
|
||||||
|
len = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string[0] = key;
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
if (modifiers != 0)
|
||||||
* For some keys a shift modifier is translated into another key
|
{
|
||||||
* code.
|
string2[0] = CSI;
|
||||||
*/
|
string2[1] = KS_MODIFIER;
|
||||||
if (len == -3)
|
string2[2] = modifiers;
|
||||||
key = TO_SPECIAL(string[1], string[2]);
|
add_to_input_buf(string2, 3);
|
||||||
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)
|
if (len == 1 && ((string[0] == Ctrl_C && ctrl_c_interrupts)
|
||||||
|
@@ -2168,9 +2168,9 @@ gui_mac_unicode_key_event(
|
|||||||
// taken liberally from gui_w48.c
|
// taken liberally from gui_w48.c
|
||||||
key_char = simplify_key(key_char, (int *)&vimModifiers);
|
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,
|
key_char = extract_modifiers(key_char, (int *)&vimModifiers,
|
||||||
TRUE, NULL);
|
FALSE, NULL);
|
||||||
if (key_char == CSI)
|
if (key_char == CSI)
|
||||||
key_char = K_CSI;
|
key_char = K_CSI;
|
||||||
|
|
||||||
|
@@ -1238,8 +1238,11 @@ add_pixmap_args(vimmenu_T *menu, Arg *args, int n)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
# if 0 // DISABLED - this causes a crash when running "make test_gui" in
|
||||||
|
// Test_colorscheme()
|
||||||
if (menu->xpm_fname != NULL)
|
if (menu->xpm_fname != NULL)
|
||||||
XtSetArg(args[n], XmNpixmapFile, menu->xpm_fname); n++;
|
XtSetArg(args[n], XmNpixmapFile, menu->xpm_fname); n++;
|
||||||
|
# endif
|
||||||
XtSetArg(args[n], XmNpixmapData, menu->xpm); n++;
|
XtSetArg(args[n], XmNpixmapData, menu->xpm); n++;
|
||||||
XtSetArg(args[n], XmNlabelLocation, XmBOTTOM); n++;
|
XtSetArg(args[n], XmNlabelLocation, XmBOTTOM); n++;
|
||||||
}
|
}
|
||||||
|
@@ -847,8 +847,8 @@ _OnSysChar(
|
|||||||
if (ch < 0x100 && !isalpha(ch) && isprint(ch))
|
if (ch < 0x100 && !isalpha(ch) && isprint(ch))
|
||||||
modifiers &= ~MOD_MASK_SHIFT;
|
modifiers &= ~MOD_MASK_SHIFT;
|
||||||
|
|
||||||
// Interpret the ALT key as making the key META, include SHIFT, etc.
|
// Unify modifiers somewhat. No longer use ALT to set the 8th bit.
|
||||||
ch = extract_modifiers(ch, &modifiers, TRUE, NULL);
|
ch = extract_modifiers(ch, &modifiers, FALSE, NULL);
|
||||||
if (ch == CSI)
|
if (ch == CSI)
|
||||||
ch = K_CSI;
|
ch = K_CSI;
|
||||||
|
|
||||||
|
143
src/gui_x11.c
143
src/gui_x11.c
@@ -771,8 +771,8 @@ gui_x11_key_hit_cb(
|
|||||||
#else
|
#else
|
||||||
char_u string[4], string2[3];
|
char_u string[4], string2[3];
|
||||||
#endif
|
#endif
|
||||||
KeySym key_sym, key_sym2;
|
KeySym key_sym;
|
||||||
int len, len2;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
int modifiers;
|
int modifiers;
|
||||||
int key;
|
int key;
|
||||||
@@ -883,57 +883,9 @@ gui_x11_key_hit_cb(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check for Alt/Meta key (Mod1Mask), but not for a BS, DEL or character
|
// We used to apply Alt/Meta to the key here (Mod1Mask), but that is now
|
||||||
// that already has the 8th bit set. And not when using a double-byte
|
// done later, the same as it happens for the terminal. Hopefully that
|
||||||
// encoding, setting the 8th bit may make it the lead byte of a
|
// works for everybody...
|
||||||
// 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 <S-M-Tab>, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == 1 && string[0] == CSI)
|
if (len == 1 && string[0] == CSI)
|
||||||
{
|
{
|
||||||
@@ -963,54 +915,47 @@ gui_x11_key_hit_cb(
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
goto theend;
|
goto theend;
|
||||||
|
|
||||||
// Special keys (and a few others) may have modifiers. Also when using a
|
// Handle modifiers.
|
||||||
// double-byte encoding (can't set the 8th bit).
|
modifiers = 0;
|
||||||
if (len == -3 || key_sym == XK_space || key_sym == XK_Tab
|
if (ev_press->state & ShiftMask)
|
||||||
|| key_sym == XK_Return || key_sym == XK_Linefeed
|
modifiers |= MOD_MASK_SHIFT;
|
||||||
|| key_sym == XK_Escape
|
if (ev_press->state & ControlMask)
|
||||||
|| (enc_dbcs && len == 1 && (ev_press->state & Mod1Mask)))
|
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;
|
string[0] = CSI;
|
||||||
if (ev_press->state & ShiftMask)
|
string[1] = K_SECOND(key);
|
||||||
modifiers |= MOD_MASK_SHIFT;
|
string[2] = K_THIRD(key);
|
||||||
if (ev_press->state & ControlMask)
|
len = 3;
|
||||||
modifiers |= MOD_MASK_CTRL;
|
}
|
||||||
if (ev_press->state & Mod1Mask)
|
else
|
||||||
modifiers |= MOD_MASK_ALT;
|
{
|
||||||
if (ev_press->state & Mod4Mask)
|
string[0] = key;
|
||||||
modifiers |= MOD_MASK_META;
|
len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
if (modifiers != 0)
|
||||||
* For some keys a shift modifier is translated into another key
|
{
|
||||||
* code.
|
string2[0] = CSI;
|
||||||
*/
|
string2[1] = KS_MODIFIER;
|
||||||
if (len == -3)
|
string2[2] = modifiers;
|
||||||
key = TO_SPECIAL(string[1], string[2]);
|
add_to_input_buf(string2, 3);
|
||||||
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)
|
if (len == 1 && ((string[0] == Ctrl_C && ctrl_c_interrupts)
|
||||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
765,
|
||||||
/**/
|
/**/
|
||||||
764,
|
764,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user