Patch 9.0.1169
Problem:    Some key+modifier tests fail on some AppVeyor images.
Solution:   Adjust the tests for key movements and fix the revealed bugs.
            (Christopher Plewright, closes #11798)
Files:      src/os_win32.c, src/testdir/test_gui.vim,
            src/testdir/test_mswin_event.vim


*** ../vim-9.0.1168/src/os_win32.c      2023-01-04 18:05:55.408803650 +0000
--- src/os_win32.c      2023-01-10 13:41:03.137935193 +0000
***************
*** 1043,1049 ****
      }
  
      // check if it already has a valid unicode character.
!     if (pker->uChar.UnicodeChar > 0 && pker->uChar.UnicodeChar < 0xFFFD)
        return 1;
  
      CLEAR_FIELD(abKeystate);
--- 1043,1049 ----
      }
  
      // check if it already has a valid unicode character.
!     if (pker->uChar.UnicodeChar != 0)
        return 1;
  
      CLEAR_FIELD(abKeystate);
***************
*** 1154,1165 ****
                        else if (pker->wVirtualKeyCode >= VK_END
                                && pker->wVirtualKeyCode <= VK_DOWN)
                        {
!                           // VK_END   0x23
!                           // VK_HOME  0x24
!                           // VK_LEFT  0x25
!                           // VK_UP    0x26
!                           // VK_RIGHT 0x27
!                           // VK_DOWN  0x28
                            *pmodifiers = 0;
                            *pch2 = VirtKeyMap[i].chAlone;
                            if ((nModifs & SHIFT) != 0
--- 1154,1162 ----
                        else if (pker->wVirtualKeyCode >= VK_END
                                && pker->wVirtualKeyCode <= VK_DOWN)
                        {
!                           // (0x23 - 0x28): VK_END, VK_HOME,
!                           // VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN
! 
                            *pmodifiers = 0;
                            *pch2 = VirtKeyMap[i].chAlone;
                            if ((nModifs & SHIFT) != 0
***************
*** 1167,1173 ****
                            {
                                *pch2 = VirtKeyMap[i].chShift;
                            }
!                           else if ((nModifs & CTRL) != 0
                                                     && (nModifs & ~CTRL) == 0)
                            {
                                *pch2 = VirtKeyMap[i].chCtrl;
--- 1164,1170 ----
                            {
                                *pch2 = VirtKeyMap[i].chShift;
                            }
!                           if ((nModifs & CTRL) != 0
                                                     && (nModifs & ~CTRL) == 0)
                            {
                                *pch2 = VirtKeyMap[i].chCtrl;
***************
*** 1178,1194 ****
                                    *pch2 = VirtKeyMap[i].chAlone;
                                }
                            }
!                           else if ((nModifs & ALT) != 0
!                                                     && (nModifs & ~ALT) == 0)
!                           {
!                               *pch2 = VirtKeyMap[i].chAlt;
!                           }
!                           else if ((nModifs & SHIFT) != 0
                                                      && (nModifs & CTRL) != 0)
                            {
                                *pmodifiers |= MOD_MASK_CTRL;
                                *pch2 = VirtKeyMap[i].chShift;
                            }
                        }
                        else
                        {
--- 1175,1212 ----
                                    *pch2 = VirtKeyMap[i].chAlone;
                                }
                            }
!                           if ((nModifs & SHIFT) != 0
                                                      && (nModifs & CTRL) != 0)
                            {
                                *pmodifiers |= MOD_MASK_CTRL;
                                *pch2 = VirtKeyMap[i].chShift;
                            }
+                           if ((nModifs & ALT) != 0)
+                           {
+                               *pch2 = VirtKeyMap[i].chAlt;
+                               *pmodifiers |= MOD_MASK_ALT;
+                               if ((nModifs & ~ALT) == 0)
+                               {
+                                   *pch2 = VirtKeyMap[i].chAlone;
+                               }
+                               else if ((nModifs & SHIFT) != 0)
+                               {
+                                   *pch2 = VirtKeyMap[i].chShift;
+                               }
+                               else if ((nModifs & CTRL) != 0)
+                               {
+                                   if (pker->wVirtualKeyCode == VK_UP
+                                       || pker->wVirtualKeyCode == VK_DOWN)
+                                   {
+                                       *pmodifiers |= MOD_MASK_CTRL;
+                                       *pch2 = VirtKeyMap[i].chAlone;
+                                   }
+                                   else
+                                   {
+                                       *pch2 = VirtKeyMap[i].chCtrl;
+                                   }
+                               }
+                           }
                        }
                        else
                        {
***************
*** 1319,1325 ****
        }
        ker.dwControlKeyState |= s_dwMods;
        ker.wVirtualKeyCode = vkCode;
!       ker.uChar.UnicodeChar = 0xFFFD;  // UNICODE REPLACEMENT CHARACTER
        ir->Event.KeyEvent = ker;
        vim_free(action);
      }
--- 1337,1343 ----
        }
        ker.dwControlKeyState |= s_dwMods;
        ker.wVirtualKeyCode = vkCode;
!       ker.uChar.UnicodeChar = 0;
        ir->Event.KeyEvent = ker;
        vim_free(action);
      }
*** ../vim-9.0.1168/src/testdir/test_gui.vim    2022-12-30 16:54:53.456987927 
+0000
--- src/testdir/test_gui.vim    2023-01-10 13:37:34.665439089 +0000
***************
*** 1656,1749 ****
      call assert_equal(nr2char(kc - 64), ch)
    endfor
  
!   " Test for the various Ctrl and Shift key combinations.
!   " Refer to the following page for the virtual key codes:
!   " https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
!   let keytests = [
!     \ [[0x10, 0x21], "S-Pageup", 2],
!     \ [[0xA0, 0x21], "S-Pageup", 2],
!     \ [[0xA1, 0x21], "S-Pageup", 2],
!     \ [[0x11, 0x21], "C-Pageup", 4],
!     \ [[0xA2, 0x21], "C-Pageup", 4],
!     \ [[0xA3, 0x21], "C-Pageup", 4],
!     \ [[0x11, 0x10, 0x21], "C-S-Pageup", 6],
!     \ [[0x10, 0x22], "S-PageDown", 2],
!     \ [[0xA0, 0x22], "S-PageDown", 2],
!     \ [[0xA1, 0x22], "S-PageDown", 2],
!     \ [[0x11, 0x22], "C-PageDown", 4],
!     \ [[0xA2, 0x22], "C-PageDown", 4],
!     \ [[0xA3, 0x22], "C-PageDown", 4],
!     \ [[0x11, 0x10, 0x22], "C-S-PageDown", 6],
!     \ [[0x10, 0x23], "S-End", 0],
!     \ [[0x11, 0x23], "C-End", 0],
!     \ [[0x11, 0x10, 0x23], "C-S-End", 4],
!     \ [[0x10, 0x24], "S-Home", 0],
!     \ [[0x11, 0x24], "C-Home", 0],
!     \ [[0x11, 0x10, 0x24], "C-S-Home", 4],
!     \ [[0x10, 0x25], "S-Left", 0],
!     \ [[0x11, 0x25], "C-Left", 0],
!     \ [[0x11, 0x10, 0x25], "C-S-Left", 4],
!     \ [[0x10, 0x26], "S-Up", 0],
!     \ [[0x11, 0x26], "C-Up", 4],
!     \ [[0x11, 0x10, 0x26], "C-S-Up", 4],
!     \ [[0x10, 0x27], "S-Right", 0],
!     \ [[0x11, 0x27], "C-Right", 0],
!     \ [[0x11, 0x10, 0x27], "C-S-Right", 4],
!     \ [[0x10, 0x28], "S-Down", 0],
!     \ [[0x11, 0x28], "C-Down", 4],
!     \ [[0x11, 0x10, 0x28], "C-S-Down", 4],
!     \ [[0x11, 0x30], "C-0", 4],
!     \ [[0x11, 0x31], "C-1", 4],
!     \ [[0x11, 0x32], "C-@", 0],
!     \ [[0x11, 0x33], "C-3", 4],
!     \ [[0x11, 0x34], "C-4", 4],
!     \ [[0x11, 0x35], "C-5", 4],
!     \ [[0x11, 0x36], "C-^", 0],
!     \ [[0x11, 0x37], "C-7", 4],
!     \ [[0x11, 0x38], "C-8", 4],
!     \ [[0x11, 0x39], "C-9", 4],
!     \ [[0x11, 0x60], "C-0", 4],
!     \ [[0x11, 0x61], "C-1", 4],
!     \ [[0x11, 0x62], "C-2", 4],
!     \ [[0x11, 0x63], "C-3", 4],
!     \ [[0x11, 0x64], "C-4", 4],
!     \ [[0x11, 0x65], "C-5", 4],
!     \ [[0x11, 0x66], "C-6", 4],
!     \ [[0x11, 0x67], "C-7", 4],
!     \ [[0x11, 0x68], "C-8", 4],
!     \ [[0x11, 0x69], "C-9", 4],
!     \ [[0x11, 0x6A], "C-*", 4],
!     \ [[0x11, 0x6B], "C-+", 4],
!     \ [[0x11, 0x6D], "C--", 4],
!     \ [[0x11, 0xBD], "C-_", 0],
!     \ [[0x11, 0x70], "C-F1", 4],
!     \ [[0x11, 0x10, 0x70], "C-S-F1", 4],
!     \ [[0x11, 0x71], "C-F2", 4],
!     \ [[0x11, 0x10, 0x71], "C-S-F2", 4],
!     \ [[0x11, 0x72], "C-F3", 4],
!     \ [[0x11, 0x10, 0x72], "C-S-F3", 4],
!     \ [[0x11, 0x73], "C-F4", 4],
!     \ [[0x11, 0x10, 0x73], "C-S-F4", 4],
!     \ [[0x11, 0x74], "C-F5", 4],
!     \ [[0x11, 0x10, 0x74], "C-S-F5", 4],
!     \ [[0x11, 0x75], "C-F6", 4],
!     \ [[0x11, 0x10, 0x75], "C-S-F6", 4],
!     \ [[0x11, 0x76], "C-F7", 4],
!     \ [[0x11, 0x10, 0x76], "C-S-F7", 4],
!     \ [[0x11, 0x77], "C-F8", 4],
!     \ [[0x11, 0x10, 0x77], "C-S-F8", 4],
!     \ [[0x11, 0x78], "C-F9", 4],
!     \ [[0x11, 0x10, 0x78], "C-S-F9", 4],
!     \ ]
! 
!   for [kcodes, kstr, kmod] in keytests
!     call SendKeys(kcodes)
!     let ch = getcharstr()
!     let mod = getcharmod()
!     let keycode = eval('"\<' .. kstr .. '>"')
!     call assert_equal(keycode, ch, $"key = {kstr}")
!     call assert_equal(kmod, mod, $"key = {kstr}")
!   endfor
  
    bw!
  endfunc
--- 1656,1663 ----
      call assert_equal(nr2char(kc - 64), ch)
    endfor
  
!   " Testing more extensive windows keyboard handling
!   " is covered in test_mswin_event.vim
  
    bw!
  endfunc
*** ../vim-9.0.1168/src/testdir/test_mswin_event.vim    2023-01-04 
18:05:55.408803650 +0000
--- src/testdir/test_mswin_event.vim    2023-01-10 13:37:34.669439101 +0000
***************
*** 155,173 ****
      \ 'ESCAPE'     : 0x1B
      \ }
  
!   let s:vim_MOD_MASK_SHIFT = 0x02
!   let s:vim_MOD_MASK_CTRL  = 0x04
!   let s:vim_MOD_MASK_ALT   = 0x08
    
    let s:vim_key_modifiers = [
      \ ["",       0,   []],
!     \ ["S-",     2,   [s:VK.SHIFT]],
!     \ ["C-",     4,   [s:VK.CONTROL]],
!     \ ["C-S-",   6,   [s:VK.CONTROL, s:VK.SHIFT]],
!     \ ["A-",     8,   [s:VK.MENU]],
!     \ ["A-S-",   10,  [s:VK.MENU, s:VK.SHIFT]],
!     \ ["A-C-",   12,  [s:VK.MENU, s:VK.CONTROL]],
!     \ ["A-C-S-", 14,  [s:VK.MENU, s:VK.CONTROL, s:VK.SHIFT]],
      \]
  
    " Assuming Standard US PC Keyboard layout
--- 155,173 ----
      \ 'ESCAPE'     : 0x1B
      \ }
  
!   let s:MOD_MASK_SHIFT = 0x02
!   let s:MOD_MASK_CTRL  = 0x04
!   let s:MOD_MASK_ALT   = 0x08
    
    let s:vim_key_modifiers = [
      \ ["",       0,   []],
!     \ ["S-",     2,   [s:VK.LSHIFT]],
!     \ ["C-",     4,   [s:VK.LCONTROL]],
!     \ ["C-S-",   6,   [s:VK.LCONTROL, s:VK.LSHIFT]],
!     \ ["A-",     8,   [s:VK.LMENU]],
!     \ ["A-S-",   10,  [s:VK.LMENU, s:VK.LSHIFT]],
!     \ ["A-C-",   12,  [s:VK.LMENU, s:VK.LCONTROL]],
!     \ ["A-C-S-", 14,  [s:VK.LMENU, s:VK.LCONTROL, s:VK.LSHIFT]],
      \]
  
    " Assuming Standard US PC Keyboard layout
***************
*** 340,346 ****
      \ ]
  
  func s:LoopTestKeyArray(arr)
!   " flush out anything in the typeahead buffer
    while getchar(0)
    endwhile
  
--- 340,346 ----
      \ ]
  
  func s:LoopTestKeyArray(arr)
!   " flush out the typeahead buffer
    while getchar(0)
    endwhile
  
***************
*** 364,376 ****
      let key = kcodes[0]
      for key in kcodes
        if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], key) >= 0
!         let modifiers = modifiers + s:vim_MOD_MASK_SHIFT
        endif
        if index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], key) >= 0
!         let modifiers = modifiers + s:vim_MOD_MASK_CTRL
        endif
        if index([s:VK.ALT, s:VK.LALT, s:VK.RALT], key) >= 0
!         let modifiers = modifiers + s:vim_MOD_MASK_ALT
        endif
      endfor
      call SendKeyWithModifiers(key, modifiers)
--- 364,376 ----
      let key = kcodes[0]
      for key in kcodes
        if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], key) >= 0
!         let modifiers = modifiers + s:MOD_MASK_SHIFT
        endif
        if index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], key) >= 0
!         let modifiers = modifiers + s:MOD_MASK_CTRL
        endif
        if index([s:VK.ALT, s:VK.LALT, s:VK.RALT], key) >= 0
!         let modifiers = modifiers + s:MOD_MASK_ALT
        endif
      endfor
      call SendKeyWithModifiers(key, modifiers)
***************
*** 387,400 ****
      call assert_equal(0, mod_mask, $"key = {kstr}")
    endfor
  
!   " flush out anything in the typeahead buffer
    while getchar(0)
    endwhile
  
  endfunc
  
  " Test MS-Windows key events
! func Test_mswin_key_event()
    CheckMSWindows
    new
  
--- 387,400 ----
      call assert_equal(0, mod_mask, $"key = {kstr}")
    endfor
  
!   " flush out the typeahead buffer
    while getchar(0)
    endwhile
  
  endfunc
  
  " Test MS-Windows key events
! func Test_mswin_event_character_keys()
    CheckMSWindows
    new
  
***************
*** 422,428 ****
        call SendKeyGroup([modkey, kc])
        let ch = getchar(0)
        call assert_equal(kc+128, ch)
!       call SendKeyWithModifiers(kc, s:vim_MOD_MASK_ALT)
        let ch = getchar(0)
        call assert_equal(kc+128, ch)
      endfor
--- 422,428 ----
        call SendKeyGroup([modkey, kc])
        let ch = getchar(0)
        call assert_equal(kc+128, ch)
!       call SendKeyWithModifiers(kc, s:MOD_MASK_ALT)
        let ch = getchar(0)
        call assert_equal(kc+128, ch)
      endfor
***************
*** 451,457 ****
        call SendKeyGroup([modkey, kc])
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc), ch)
!       call SendKeyWithModifiers(kc, s:vim_MOD_MASK_SHIFT)
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc), ch)
      endfor
--- 451,457 ----
        call SendKeyGroup([modkey, kc])
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc), ch)
!       call SendKeyWithModifiers(kc, s:MOD_MASK_SHIFT)
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc), ch)
      endfor
***************
*** 464,470 ****
        call SendKeyGroup([modkey, kc])
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc - 64), ch)
!       call SendKeyWithModifiers(kc, s:vim_MOD_MASK_CTRL)
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc - 64), ch)
      endfor
--- 464,470 ----
        call SendKeyGroup([modkey, kc])
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc - 64), ch)
!       call SendKeyWithModifiers(kc, s:MOD_MASK_CTRL)
        let ch = getcharstr(0)
        call assert_equal(nr2char(kc - 64), ch)
      endfor
***************
*** 480,588 ****
          call SendKeyGroup([modkey, kc])
          let ch = getchar(0)
          call assert_equal(kc+160, ch)
!         call SendKeyWithModifiers(kc, s:vim_MOD_MASK_ALT)
          let ch = getchar(0)
          call assert_equal(kc+160, ch)
        endfor
      endfor
    endif
  
    " Test for Function Keys 'F1' to 'F12'
    " VK codes 112(0x70) - 123(0x7B)
    " Also with ALL permutatios of modifiers; Shift, Ctrl & Alt
!   " NOTE: Windows intercepts some of these keys in the GUI
!   if !has("gui_running")
!     for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers
!       for n in range(1, 12)
!         let kstr = $"{mod_str}F{n}"
          let keycode = eval('"\<' .. kstr .. '>"')
!         " flush out anything in the typeahead buffer
          while getchar(0)
          endwhile
-         " call SendKeyGroup(mod_keycodes + [111+n])
          call SendKeyWithModifiers(111+n, vim_mod_mask)
          let ch = getcharstr(0)
          let mod_mask = getcharmod()
          call assert_equal(keycode, $"{ch}", $"key = {kstr}")
!         " workaround for the virtual termcap maps changing the character 
instead
!         " of sending Shift
          for mod_key in mod_keycodes
            if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], mod_key) >= 0
!             let mod_mask = mod_mask + s:vim_MOD_MASK_SHIFT
            endif
          endfor
!         call assert_equal(vim_mod_mask, mod_mask, $"mod = {vim_mod_mask} for 
key = {kstr}")
!       endfor
      endfor
    endif
  
!   " Test for the various Ctrl and Shift key combinations.
!   let keytests = [
!     \ [[s:VK.SHIFT,    s:VK.PRIOR], "S-Pageup", 2],
!     \ [[s:VK.LSHIFT,   s:VK.PRIOR], "S-Pageup", 2],
!     \ [[s:VK.RSHIFT,   s:VK.PRIOR], "S-Pageup", 2],
!     \ [[s:VK.CONTROL,  s:VK.PRIOR], "C-Pageup", 4],
!     \ [[s:VK.LCONTROL, s:VK.PRIOR], "C-Pageup", 4],
!     \ [[s:VK.RCONTROL, s:VK.PRIOR], "C-Pageup", 4],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.PRIOR], "C-S-Pageup", 6],
!     \ [[s:VK.SHIFT,    s:VK.NEXT], "S-PageDown", 2],
!     \ [[s:VK.LSHIFT,   s:VK.NEXT], "S-PageDown", 2],
!     \ [[s:VK.RSHIFT,   s:VK.NEXT], "S-PageDown", 2],
!     \ [[s:VK.CONTROL,  s:VK.NEXT], "C-PageDown", 4],
!     \ [[s:VK.LCONTROL, s:VK.NEXT], "C-PageDown", 4],
!     \ [[s:VK.RCONTROL, s:VK.NEXT], "C-PageDown", 4],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.NEXT], "C-S-PageDown", 6],
!     \ [[s:VK.SHIFT,    s:VK.END], "S-End", 0],
!     \ [[s:VK.CONTROL,  s:VK.END], "C-End", 0],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.END], "C-S-End", 4],
!     \ [[s:VK.SHIFT,    s:VK.HOME], "S-Home", 0],
!     \ [[s:VK.CONTROL,  s:VK.HOME], "C-Home", 0],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.HOME], "C-S-Home", 4],
!     \ [[s:VK.SHIFT,    s:VK.LEFT], "S-Left", 0],
!     \ [[s:VK.CONTROL,  s:VK.LEFT], "C-Left", 0],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.LEFT], "C-S-Left", 4],
!     \ [[s:VK.SHIFT,    s:VK.UP], "S-Up", 0],
!     \ [[s:VK.CONTROL,  s:VK.UP], "C-Up", 4],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.UP], "C-S-Up", 4],
!     \ [[s:VK.SHIFT,    s:VK.RIGHT], "S-Right", 0],
!     \ [[s:VK.CONTROL,  s:VK.RIGHT], "C-Right", 0],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.RIGHT], "C-S-Right", 4],
!     \ [[s:VK.SHIFT,    s:VK.DOWN], "S-Down", 0],
!     \ [[s:VK.CONTROL,  s:VK.DOWN], "C-Down", 4],
!     \ [[s:VK.CONTROL,  s:VK.SHIFT, s:VK.DOWN], "C-S-Down", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_0], "C-0", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_1], "C-1", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_2], "C-@", 0],
!     \ [[s:VK.CONTROL,  s:VK.KEY_3], "C-3", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_4], "C-4", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_5], "C-5", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_6], "C-^", 0],
!     \ [[s:VK.CONTROL,  s:VK.KEY_7], "C-7", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_8], "C-8", 4],
!     \ [[s:VK.CONTROL,  s:VK.KEY_9], "C-9", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD0], "C-0", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD1], "C-1", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD2], "C-2", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD3], "C-3", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD4], "C-4", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD5], "C-5", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD6], "C-6", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD7], "C-7", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD8], "C-8", 4],
!     \ [[s:VK.CONTROL,  s:VK.NUMPAD9], "C-9", 4],
!     \ [[s:VK.CONTROL,  s:VK.MULTIPLY], "C-*", 4],
!     \ [[s:VK.CONTROL,  s:VK.ADD], "C-+", 4],
!     \ [[s:VK.CONTROL,  s:VK.SUBTRACT], "C--", 4],
!     \ [[s:VK.CONTROL,  s:VK.OEM_MINUS], "C-_", 0]
      \ ]
  
!   for [kcodes, kstr, kmod] in keytests
!     call SendKeyGroup(kcodes)
!     let ch = getcharstr(0)
!     let mod = getcharmod()
!     let keycode = eval('"\<' .. kstr .. '>"')
!     call assert_equal(keycode, ch, $"key = {kstr}")
!     call assert_equal(kmod, mod, $"mod = {kmod} key = {kstr}")
    endfor
  
    bw!
--- 480,645 ----
          call SendKeyGroup([modkey, kc])
          let ch = getchar(0)
          call assert_equal(kc+160, ch)
!         call SendKeyWithModifiers(kc, s:MOD_MASK_ALT)
          let ch = getchar(0)
          call assert_equal(kc+160, ch)
        endfor
      endfor
    endif
  
+ endfun
+ 
    " Test for Function Keys 'F1' to 'F12'
    " VK codes 112(0x70) - 123(0x7B)
    " Also with ALL permutatios of modifiers; Shift, Ctrl & Alt
! func Test_mswin_event_function_keys()
! 
!   if has('gui_running')
!     let g:test_is_flaky = 1
!   endif
! 
!   " NOTE: Windows intercepts these combinations in the GUI
!   let gui_nogo = ["A-F1", "A-F2", "A-F3", "A-F4", "A-S-F4", "A-C-S-F4",
!             \ "A-F5", "A-F6", "A-F7", "A-F8", "A-C-F8", "A-F9",
!           \ "A-F10", "A-F11" , "A-C-F11", "A-C-F12"]
! 
!   " flush out the typeahead buffer
!   while getchar(0)
!   endwhile
! 
!   for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers
!     for n in range(1, 12)
!       let expected_mod_mask = vim_mod_mask
!       let kstr = $"{mod_str}F{n}"
!       if !has('gui_running') || (has('gui_running') && n != 10
!                                              \  && index(gui_nogo, kstr) == 
-1)
          let keycode = eval('"\<' .. kstr .. '>"')
!         " flush out the typeahead buffer
          while getchar(0)
          endwhile
          call SendKeyWithModifiers(111+n, vim_mod_mask)
          let ch = getcharstr(0)
          let mod_mask = getcharmod()
          call assert_equal(keycode, $"{ch}", $"key = {kstr}")
!         " workaround for the virtual termcap maps changing the character
!         "instead of sending Shift
          for mod_key in mod_keycodes
            if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], mod_key) >= 0
!             let expected_mod_mask -= s:MOD_MASK_SHIFT
!             break
            endif
          endfor
!         call assert_equal(expected_mod_mask, mod_mask, $"mod = 
{expected_mod_mask} for key = {kstr}")
!       endif
      endfor
+   endfor
+ endfunc
+ 
+ func ExtractModifiers(mod_keycodes)
+   let has_shift = 0
+   let has_ctrl = 0
+   let has_alt = 0
+   for mod_key in a:mod_keycodes
+     if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], mod_key) >= 0
+       let has_shift = 1
+     endif
+     if index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], mod_key) >= 0
+       let has_ctrl = 1
+     endif
+     if index([s:VK.MENU, s:VK.LMENU, s:VK.RMENU], mod_key) >= 0
+       let has_alt = 1
+     endif
+   endfor
+   return [has_shift, has_ctrl, has_alt]
+ endfunc
+ 
+   " Test for Movement Keys;
+   "    VK_PRIOR 0x21,   VK_NEXT  0x22,
+   "    VK_END   0x23,   VK_HOME  0x24,
+   "    VK_LEFT  0x25,   VK_UP    0x26,
+   "    VK_RIGHT 0x27,   VK_DOWN  0x28
+   " With ALL permutations of modifiers; none, Shift, Ctrl & Alt
+ func Test_mswin_event_movement_keys()
+ 
+   if has('gui_running')
+     let g:test_is_flaky = 1
    endif
  
!   let movement_keys = [
!     \ [s:VK.PRIOR, "PageUp"],
!     \ [s:VK.NEXT,  "PageDown"],
!     \ [s:VK.END,   "End"],
!     \ [s:VK.HOME,  "Home"],
!     \ [s:VK.LEFT,  "Left"],
!     \ [s:VK.UP,    "Up"],
!     \ [s:VK.RIGHT, "Right"],
!     \ [s:VK.DOWN,  "Down"],
      \ ]
  
!   " flush out the typeahead buffer
!   while getchar(0)
!   endwhile
! 
!   for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers
!     for [kcode, kname] in movement_keys
!       let exp_mod_mask = vim_mod_mask
!       let kstr = $"{mod_str}{kname}"
!       let chstr_eval = eval('"\<' .. kstr .. '>"')
! 
!       " flush out the typeahead buffer
!       while getchar(0)
!       endwhile
!       execute 'call feedkeys("\<' .. kstr .. '>")'
!       let chstr_fk = getcharstr(0)
!       call assert_equal(chstr_eval, chstr_fk, $"feedkeys = <{kstr}>")
! 
!       " flush out the typeahead buffer
!       while getchar(0)
!       endwhile
!       call SendKey(kcode)
!       let chstr_alone = getcharstr(0)
!       let chstr_alone_end = chstr_alone[len(chstr_alone)-2:len(chstr_alone)-1]
! 
!       " flush out the typeahead buffer
!       while getchar(0)
!       endwhile
!       call SendKeyGroup(mod_keycodes + [kcode])
!       let chstr_mswin = getcharstr(0)
!       let chstr_mswin_end = chstr_mswin[len(chstr_mswin)-2:len(chstr_mswin)-1]
!       let mod_mask = getcharmod()
! 
!       " The virtual termcap maps may** change the character and either;
!       " - remove the Shift modifier, or
!       " - remove the Ctrl modifier if the Shift modifier was not removed.
!       let [has_shift, has_ctrl, has_alt] = ExtractModifiers(mod_keycodes)
!       if chstr_alone_end != chstr_mswin_end
!         if has_shift != 0
!           let exp_mod_mask -= s:MOD_MASK_SHIFT
!         elseif has_ctrl != 0
!         let exp_mod_mask -= s:MOD_MASK_CTRL
!         endif
!       endif
!       " **Note: The appveyor Windows GUI test environments, from VS2017 on,
!       " consistently intercepts the Shift modifier WITHOUT changing the
!       " MOVEMENT character.  This issue does not happen in any github actions
!       " CI Windows test environments.  Attempted to reproduce this manually
!       " on Windows versions;  7, 8.1, 10, 11, Server 2019 and Server 2022, but
!       " the issue did not occur on any of those environments.
!       " Below is a workaround for the issue.
!       if has('gui_running') && has_shift != 0
!         if exp_mod_mask != mod_mask && chstr_eval != chstr_mswin
!           let kstr_sub = substitute(kstr, "S-", "", "")
!           let chstr_eval = eval('"\<' .. kstr_sub .. '>"')
!           if exp_mod_mask - s:MOD_MASK_SHIFT == mod_mask
!             let exp_mod_mask -= s:MOD_MASK_SHIFT
!           elseif has_ctrl != 0 && exp_mod_mask - s:MOD_MASK_CTRL == mod_mask
!             let exp_mod_mask -= s:MOD_MASK_CTRL
!           endif
!         endif
!       endif
!       call assert_equal(chstr_eval, chstr_mswin, $"key = {kstr}")
!       call assert_equal(exp_mod_mask, mod_mask, $"mod_mask for key = {kstr}")
!     endfor
    endfor
  
    bw!
***************
*** 628,634 ****
  endfunc
  
  "  Test MS-Windows mouse events
! func Test_mswin_mouse_event()
    CheckMSWindows
    new
  
--- 685,691 ----
  endfunc
  
  "  Test MS-Windows mouse events
! func Test_mswin_event_mouse()
    CheckMSWindows
    new
  
***************
*** 940,946 ****
  
    call assert_fails("sandbox call test_mswin_event('key', {'event': 
'keydown', 'keycode': 61 })", 'E48:')
  
!   " flush out anything in the typeahead buffer
    while getchar(0)
    endwhile
  endfunc
--- 997,1003 ----
  
    call assert_fails("sandbox call test_mswin_event('key', {'event': 
'keydown', 'keycode': 61 })", 'E48:')
  
!   " flush out the typeahead buffer
    while getchar(0)
    endwhile
  endfunc
*** ../vim-9.0.1168/src/version.c       2023-01-10 12:37:33.253580676 +0000
--- src/version.c       2023-01-10 13:39:55.529798073 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1169,
  /**/

-- 
Your company is doomed if your primary product is overhead transparencies.
                                (Scott Adams - The Dilbert principle)

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230110134336.8919A1C046A%40moolenaar.net.

Reply via email to