]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.4817: Win32 GUI: modifiers are not always used v8.2.4817
authorLemonBoy <thatlemon@gmail.com>
Sun, 24 Apr 2022 14:46:42 +0000 (15:46 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 24 Apr 2022 14:46:42 +0000 (15:46 +0100)
Problem:    Win32 GUI: modifiers are not always used.
Solution:   Handle more modifiers. (closes #10269)

src/gui_w32.c
src/version.c

index 7c2c7fce33f427d88f1878d852f8060386d1de1d..9308e47852df9e90013a485c8aa04df129aa1263 100644 (file)
@@ -818,6 +818,26 @@ char_to_string(int ch, char_u *string, int slen, int had_alt)
     return len;
 }
 
+    static int
+get_active_modifiers(void)
+{
+    int modifiers = 0;
+
+    if (GetKeyState(VK_CONTROL) & 0x8000)
+       modifiers |= MOD_MASK_CTRL;
+    if (GetKeyState(VK_SHIFT) & 0x8000)
+       modifiers |= MOD_MASK_SHIFT;
+    if (GetKeyState(VK_MENU) & 0x8000)
+       modifiers |= MOD_MASK_ALT;
+    // Windows handles Ctrl + Alt as AltGr, in that case no modifier is actually
+    // pressed.
+    if ((modifiers & (MOD_MASK_CTRL | MOD_MASK_ALT)) ==
+           (MOD_MASK_CTRL | MOD_MASK_ALT))
+       modifiers &= ~(MOD_MASK_CTRL | MOD_MASK_ALT);
+
+    return modifiers;
+}
+
 /*
  * Key hit, add it to the input buffer.
  */
@@ -829,15 +849,12 @@ _OnChar(
 {
     char_u     string[40];
     int                len = 0;
-    int                modifiers = 0;
+    int                modifiers;
     int                ch = cch;   // special keys are negative
 
     dead_key = 0;
 
-    if (GetKeyState(VK_SHIFT) & 0x8000)
-       modifiers |= MOD_MASK_SHIFT;
-    if (GetKeyState(VK_CONTROL) & 0x8000)
-       modifiers |= MOD_MASK_CTRL;
+    modifiers = get_active_modifiers();
 
     ch = simplify_key(ch, &modifiers);
     // remove the SHIFT modifier for keys where it's already included, e.g.,
@@ -887,12 +904,7 @@ _OnSysChar(
     // ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note
     // that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless
     // CAPSLOCK is pressed) at this point.
-    modifiers = MOD_MASK_ALT;
-    if (GetKeyState(VK_SHIFT) & 0x8000)
-       modifiers |= MOD_MASK_SHIFT;
-    if (GetKeyState(VK_CONTROL) & 0x8000)
-       modifiers |= MOD_MASK_CTRL;
-
+    modifiers = get_active_modifiers();
     ch = simplify_key(ch, &modifiers);
     // remove the SHIFT modifier for keys where it's already included, e.g.,
     // '(' and '*'
@@ -1917,10 +1929,18 @@ process_message(void)
             * VK_BACK, or VK_ESCAPE it means that he actually wants to deal
             * with the dead char now, so do nothing special and let Windows
             * handle it.
+            *
+            * Note that VK_SPACE combines with the dead_key's character and
+            * only one WM_CHAR will be generated by TranslateMessage(), in
+            * the two other cases two WM_CHAR will be generated: the dead
+            * char and VK_BACK or VK_ESCAPE. That is most likely what the
+            * user expects.
             */
            if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
            {
                dead_key = 0;
+               TranslateMessage(&msg);
+               return;
            }
            // In modes where we are not typing, dead keys should behave
            // normally
@@ -1976,21 +1996,7 @@ process_message(void)
                                                          NULL, NULL) == NULL)
                    break;
 #endif
-               if (GetKeyState(VK_SHIFT) & 0x8000)
-                   modifiers |= MOD_MASK_SHIFT;
-               /*
-                * Don't use caps-lock as shift, because these are special keys
-                * being considered here, and we only want letters to get
-                * shifted -- webb
-                */
-               /*
-               if (GetKeyState(VK_CAPITAL) & 0x0001)
-                   modifiers ^= MOD_MASK_SHIFT;
-               */
-               if (GetKeyState(VK_CONTROL) & 0x8000)
-                   modifiers |= MOD_MASK_CTRL;
-               if (GetKeyState(VK_MENU) & 0x8000)
-                   modifiers |= MOD_MASK_ALT;
+               modifiers = get_active_modifiers();
 
                if (special_keys[i].vim_code1 == NUL)
                    key = special_keys[i].vim_code0;
@@ -2036,13 +2042,6 @@ process_message(void)
            int         i;
            UINT        scan_code;
 
-           if (GetKeyState(VK_SHIFT) & 0x8000)
-               modifiers |= MOD_MASK_SHIFT;
-           if (GetKeyState(VK_CONTROL) & 0x8000)
-               modifiers |= MOD_MASK_CTRL;
-           if (GetKeyState(VK_LMENU) & 0x8000)
-               modifiers |= MOD_MASK_ALT;
-
            // Construct the state table with only a few modifiers, we don't
            // really care about the presence of Ctrl/Alt as those modifiers are
            // handled by Vim separately.
@@ -2051,7 +2050,9 @@ process_message(void)
                keyboard_state[VK_SHIFT] = 0x80;
            if (GetKeyState(VK_CAPITAL) & 0x0001)
                keyboard_state[VK_CAPITAL] = 0x01;
-           if (GetKeyState(VK_RMENU) & 0x8000)
+           // Alt-Gr is synthesized as Alt + Ctrl.
+           if ((GetKeyState(VK_MENU) & 0x8000) &&
+                   (GetKeyState(VK_CONTROL) & 0x8000))
            {
                keyboard_state[VK_MENU] = 0x80;
                keyboard_state[VK_CONTROL] = 0x80;
@@ -3795,11 +3796,13 @@ _OnDropFiles(
 
     if (fnames != NULL)
     {
-       if ((GetKeyState(VK_SHIFT) & 0x8000) != 0)
+       int kbd_modifiers = get_active_modifiers();
+
+       if ((kbd_modifiers & MOD_MASK_SHIFT) != 0)
            modifiers |= MOUSE_SHIFT;
-       if ((GetKeyState(VK_CONTROL) & 0x8000) != 0)
+       if ((kbd_modifiers & MOD_MASK_CTRL) != 0)
            modifiers |= MOUSE_CTRL;
-       if ((GetKeyState(VK_MENU) & 0x8000) != 0)
+       if ((kbd_modifiers & MOD_MASK_ALT) != 0)
            modifiers |= MOUSE_ALT;
 
        gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
index 57f2e8d6948a07bae3c5377eb346916999a22557..e46816eddd1cc46954e7c449dd5beb70274d78e1 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4817,
 /**/
     4816,
 /**/