blob: e2add3b2c228e8f8e9e235c92c6cab22a45aca32 [file] [log] [blame]
Christopher Plewright7b0afc12022-12-30 16:54:58 +00001" Test MS-Windows input event handling.
2" Most of this works the same in Windows GUI as well as Windows console.
Christopher Plewright20b795e2022-12-20 20:01:58 +00003
4source check.vim
5CheckMSWindows
Christopher Plewright20b795e2022-12-20 20:01:58 +00006source mouse.vim
7
Christopher Plewright7b0afc12022-12-30 16:54:58 +00008" Helper function for sending a grouped sequence of low level key presses
9" The modifer key(s) can be included as VK Key Codes in the sequence
10" Keydown events will be sent, to to the end of the group, then keyup events
11" will be sent in reverse order to release the keys.
12func SendKeyGroup(keygroup)
13 for k in a:keygroup
14 call test_mswin_event("key", {'event': "keydown", 'keycode': k})
Christopher Plewright20b795e2022-12-20 20:01:58 +000015 endfor
Christopher Plewright7b0afc12022-12-30 16:54:58 +000016 for k in reverse(copy(a:keygroup))
17 call test_mswin_event("key", {'event': "keyup", 'keycode': k})
Christopher Plewright20b795e2022-12-20 20:01:58 +000018 endfor
19endfunc
20
Christopher Plewright7b0afc12022-12-30 16:54:58 +000021" Send individual key press and release events.
Christopher Plewright20b795e2022-12-20 20:01:58 +000022" the modifers for the key press can be specified in the modifiers arg.
Christopher Plewright7b0afc12022-12-30 16:54:58 +000023func SendKeyWithModifiers(key, modifiers)
Christopher Plewright20b795e2022-12-20 20:01:58 +000024 let args = { }
25 let args.keycode = a:key
26 let args.modifiers = a:modifiers
27 let args.event = "keydown"
28 call test_mswin_event("key", args)
29 let args.event = "keyup"
30 call test_mswin_event("key", args)
31 unlet args
32endfunc
33
Christopher Plewright7b0afc12022-12-30 16:54:58 +000034" Send an individual key press, without modifiers.
35func SendKey(key)
36 call SendKeyWithModifiers(a:key, 0)
37endfunc
38
39" Send a string of individual key-press events, without modifiers.
40func SendKeyStr(keystring)
41 for k in a:keystring
42 call SendKey(k)
43 endfor
44endfunc
45
Bram Moolenaar94722c52023-01-28 19:19:03 +000046" This tells Vim to execute the buffered keys as user commands,
Christopher Plewright7b0afc12022-12-30 16:54:58 +000047" ie. same as feekdeys with mode X would do.
48func ExecuteBufferedKeys()
49 if has('gui_running')
50 call feedkeys("\<Esc>", 'Lx!')
51 else
52 call test_mswin_event("key", {'execute': v:true})
53 endif
54endfunc
55
Christopher Plewrightc8b20492023-01-04 18:06:00 +000056" Refer to the following page for the virtual key codes:
57" https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Christopher Plewright7b0afc12022-12-30 16:54:58 +000058let s:VK = {
59 \ 'ENTER' : 0x0D,
60 \ 'SPACE' : 0x20,
61 \ 'SHIFT' : 0x10,
62 \ 'LSHIFT' : 0xA0,
63 \ 'RSHIFT' : 0xA1,
64 \ 'CONTROL' : 0x11,
65 \ 'LCONTROL' : 0xA2,
66 \ 'RCONTROL' : 0xA3,
67 \ 'MENU' : 0x12,
68 \ 'ALT' : 0x12,
69 \ 'LMENU' : 0xA4,
70 \ 'LALT' : 0xA4,
71 \ 'RMENU' : 0xA5,
72 \ 'RALT' : 0xA5,
73 \ 'OEM_1' : 0xBA,
74 \ 'OEM_2' : 0xBF,
75 \ 'OEM_3' : 0xC0,
76 \ 'OEM_4' : 0xDB,
77 \ 'OEM_5' : 0xDC,
78 \ 'OEM_6' : 0xDD,
79 \ 'OEM_7' : 0xDE,
80 \ 'OEM_PLUS' : 0xBB,
81 \ 'OEM_COMMA' : 0xBC,
82 \ 'OEM_MINUS' : 0xBD,
83 \ 'OEM_PERIOD' : 0xBE,
84 \ 'PRIOR' : 0x21,
85 \ 'NEXT' : 0x22,
86 \ 'END' : 0x23,
87 \ 'HOME' : 0x24,
88 \ 'LEFT' : 0x25,
89 \ 'UP' : 0x26,
90 \ 'RIGHT' : 0x27,
91 \ 'DOWN' : 0x28,
92 \ 'KEY_0' : 0x30,
93 \ 'KEY_1' : 0x31,
94 \ 'KEY_2' : 0x32,
95 \ 'KEY_3' : 0x33,
96 \ 'KEY_4' : 0x34,
97 \ 'KEY_5' : 0x35,
98 \ 'KEY_6' : 0x36,
99 \ 'KEY_7' : 0x37,
100 \ 'KEY_8' : 0x38,
101 \ 'KEY_9' : 0x39,
102 \ 'KEY_A' : 0x41,
103 \ 'KEY_B' : 0x42,
104 \ 'KEY_C' : 0x43,
105 \ 'KEY_D' : 0x44,
106 \ 'KEY_E' : 0x45,
107 \ 'KEY_F' : 0x46,
108 \ 'KEY_G' : 0x47,
109 \ 'KEY_H' : 0x48,
110 \ 'KEY_I' : 0x49,
111 \ 'KEY_J' : 0x4A,
112 \ 'KEY_K' : 0x4B,
113 \ 'KEY_L' : 0x4C,
114 \ 'KEY_M' : 0x4D,
115 \ 'KEY_N' : 0x4E,
116 \ 'KEY_O' : 0x4F,
117 \ 'KEY_P' : 0x50,
118 \ 'KEY_Q' : 0x51,
119 \ 'KEY_R' : 0x52,
120 \ 'KEY_S' : 0x53,
121 \ 'KEY_T' : 0x54,
122 \ 'KEY_U' : 0x55,
123 \ 'KEY_V' : 0x56,
124 \ 'KEY_W' : 0x57,
125 \ 'KEY_X' : 0x58,
126 \ 'KEY_Y' : 0x59,
127 \ 'KEY_Z' : 0x5A,
128 \ 'NUMPAD0' : 0x60,
129 \ 'NUMPAD1' : 0x61,
130 \ 'NUMPAD2' : 0x62,
131 \ 'NUMPAD3' : 0x63,
132 \ 'NUMPAD4' : 0x64,
133 \ 'NUMPAD5' : 0x65,
134 \ 'NUMPAD6' : 0x66,
135 \ 'NUMPAD7' : 0x67,
136 \ 'NUMPAD8' : 0x68,
137 \ 'NUMPAD9' : 0x69,
138 \ 'MULTIPLY' : 0x6A,
139 \ 'ADD' : 0x6B,
140 \ 'SUBTRACT' : 0x6D,
141 \ 'F1' : 0x70,
142 \ 'F2' : 0x71,
143 \ 'F3' : 0x72,
144 \ 'F4' : 0x73,
145 \ 'F5' : 0x74,
146 \ 'F6' : 0x75,
147 \ 'F7' : 0x76,
148 \ 'F8' : 0x77,
149 \ 'F9' : 0x78,
150 \ 'F10' : 0x79,
151 \ 'F11' : 0x7A,
152 \ 'F12' : 0x7B,
153 \ 'DELETE' : 0x2E,
154 \ 'BACK' : 0x08,
155 \ 'ESCAPE' : 0x1B
156 \ }
157
Christopher Plewright566f76e2023-01-10 13:43:04 +0000158 let s:MOD_MASK_SHIFT = 0x02
159 let s:MOD_MASK_CTRL = 0x04
160 let s:MOD_MASK_ALT = 0x08
Bram Moolenaar94722c52023-01-28 19:19:03 +0000161
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000162 let s:vim_key_modifiers = [
163 \ ["", 0, []],
Christopher Plewright566f76e2023-01-10 13:43:04 +0000164 \ ["S-", 2, [s:VK.LSHIFT]],
165 \ ["C-", 4, [s:VK.LCONTROL]],
166 \ ["C-S-", 6, [s:VK.LCONTROL, s:VK.LSHIFT]],
167 \ ["A-", 8, [s:VK.LMENU]],
168 \ ["A-S-", 10, [s:VK.LMENU, s:VK.LSHIFT]],
169 \ ["A-C-", 12, [s:VK.LMENU, s:VK.LCONTROL]],
170 \ ["A-C-S-", 14, [s:VK.LMENU, s:VK.LCONTROL, s:VK.LSHIFT]],
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000171 \]
172
173 " Assuming Standard US PC Keyboard layout
174 let s:test_ascii_key_chars = [
175 \ [[s:VK.SPACE], ' '],
176 \ [[s:VK.OEM_1], ';'],
177 \ [[s:VK.OEM_2], '/'],
178 \ [[s:VK.OEM_3], '`'],
179 \ [[s:VK.OEM_4], '['],
180 \ [[s:VK.OEM_5], '\'],
181 \ [[s:VK.OEM_6], ']'],
182 \ [[s:VK.OEM_7], ''''],
183 \ [[s:VK.OEM_PLUS], '='],
184 \ [[s:VK.OEM_COMMA], ','],
185 \ [[s:VK.OEM_MINUS], '-'],
186 \ [[s:VK.OEM_PERIOD], '.'],
187 \ [[s:VK.SHIFT, s:VK.OEM_1], ':'],
188 \ [[s:VK.SHIFT, s:VK.OEM_2], '?'],
189 \ [[s:VK.SHIFT, s:VK.OEM_3], '~'],
190 \ [[s:VK.SHIFT, s:VK.OEM_4], '{'],
191 \ [[s:VK.SHIFT, s:VK.OEM_5], '|'],
192 \ [[s:VK.SHIFT, s:VK.OEM_6], '}'],
193 \ [[s:VK.SHIFT, s:VK.OEM_7], '"'],
194 \ [[s:VK.SHIFT, s:VK.OEM_PLUS], '+'],
195 \ [[s:VK.SHIFT, s:VK.OEM_COMMA], '<'],
196 \ [[s:VK.SHIFT, s:VK.OEM_MINUS], '_'],
197 \ [[s:VK.SHIFT, s:VK.OEM_PERIOD], '>'],
198 \ [[s:VK.KEY_1], '1'],
199 \ [[s:VK.KEY_2], '2'],
200 \ [[s:VK.KEY_3], '3'],
201 \ [[s:VK.KEY_4], '4'],
202 \ [[s:VK.KEY_5], '5'],
203 \ [[s:VK.KEY_6], '6'],
204 \ [[s:VK.KEY_7], '7'],
205 \ [[s:VK.KEY_8], '8'],
206 \ [[s:VK.KEY_9], '9'],
207 \ [[s:VK.KEY_0], '0'],
208 \ [[s:VK.SHIFT, s:VK.KEY_1], '!'],
209 \ [[s:VK.SHIFT, s:VK.KEY_2], '@'],
210 \ [[s:VK.SHIFT, s:VK.KEY_3], '#'],
211 \ [[s:VK.SHIFT, s:VK.KEY_4], '$'],
212 \ [[s:VK.SHIFT, s:VK.KEY_5], '%'],
213 \ [[s:VK.SHIFT, s:VK.KEY_6], '^'],
214 \ [[s:VK.SHIFT, s:VK.KEY_7], '&'],
215 \ [[s:VK.SHIFT, s:VK.KEY_8], '*'],
216 \ [[s:VK.SHIFT, s:VK.KEY_9], '('],
217 \ [[s:VK.SHIFT, s:VK.KEY_0], ')'],
218 \ [[s:VK.KEY_A], 'a'],
219 \ [[s:VK.KEY_B], 'b'],
220 \ [[s:VK.KEY_C], 'c'],
221 \ [[s:VK.KEY_D], 'd'],
222 \ [[s:VK.KEY_E], 'e'],
223 \ [[s:VK.KEY_F], 'f'],
224 \ [[s:VK.KEY_G], 'g'],
225 \ [[s:VK.KEY_H], 'h'],
226 \ [[s:VK.KEY_I], 'i'],
227 \ [[s:VK.KEY_J], 'j'],
228 \ [[s:VK.KEY_K], 'k'],
229 \ [[s:VK.KEY_L], 'l'],
230 \ [[s:VK.KEY_M], 'm'],
231 \ [[s:VK.KEY_N], 'n'],
232 \ [[s:VK.KEY_O], 'o'],
233 \ [[s:VK.KEY_P], 'p'],
234 \ [[s:VK.KEY_Q], 'q'],
235 \ [[s:VK.KEY_R], 'r'],
236 \ [[s:VK.KEY_S], 's'],
237 \ [[s:VK.KEY_T], 't'],
238 \ [[s:VK.KEY_U], 'u'],
239 \ [[s:VK.KEY_V], 'v'],
240 \ [[s:VK.KEY_W], 'w'],
241 \ [[s:VK.KEY_X], 'x'],
242 \ [[s:VK.KEY_Y], 'y'],
243 \ [[s:VK.KEY_Z], 'z'],
244 \ [[s:VK.SHIFT, s:VK.KEY_A], 'A'],
245 \ [[s:VK.SHIFT, s:VK.KEY_B], 'B'],
246 \ [[s:VK.SHIFT, s:VK.KEY_C], 'C'],
247 \ [[s:VK.SHIFT, s:VK.KEY_D], 'D'],
248 \ [[s:VK.SHIFT, s:VK.KEY_E], 'E'],
249 \ [[s:VK.SHIFT, s:VK.KEY_F], 'F'],
250 \ [[s:VK.SHIFT, s:VK.KEY_G], 'G'],
251 \ [[s:VK.SHIFT, s:VK.KEY_H], 'H'],
252 \ [[s:VK.SHIFT, s:VK.KEY_I], 'I'],
253 \ [[s:VK.SHIFT, s:VK.KEY_J], 'J'],
254 \ [[s:VK.SHIFT, s:VK.KEY_K], 'K'],
255 \ [[s:VK.SHIFT, s:VK.KEY_L], 'L'],
256 \ [[s:VK.SHIFT, s:VK.KEY_M], 'M'],
257 \ [[s:VK.SHIFT, s:VK.KEY_N], 'N'],
258 \ [[s:VK.SHIFT, s:VK.KEY_O], 'O'],
259 \ [[s:VK.SHIFT, s:VK.KEY_P], 'P'],
260 \ [[s:VK.SHIFT, s:VK.KEY_Q], 'Q'],
261 \ [[s:VK.SHIFT, s:VK.KEY_R], 'R'],
262 \ [[s:VK.SHIFT, s:VK.KEY_S], 'S'],
263 \ [[s:VK.SHIFT, s:VK.KEY_T], 'T'],
264 \ [[s:VK.SHIFT, s:VK.KEY_U], 'U'],
265 \ [[s:VK.SHIFT, s:VK.KEY_V], 'V'],
266 \ [[s:VK.SHIFT, s:VK.KEY_W], 'W'],
267 \ [[s:VK.SHIFT, s:VK.KEY_X], 'X'],
268 \ [[s:VK.SHIFT, s:VK.KEY_Y], 'Y'],
269 \ [[s:VK.SHIFT, s:VK.KEY_Z], 'Z'],
270 \ [[s:VK.CONTROL, s:VK.KEY_A], 0x01],
271 \ [[s:VK.CONTROL, s:VK.KEY_B], 0x02],
272 \ [[s:VK.CONTROL, s:VK.KEY_C], 0x03],
273 \ [[s:VK.CONTROL, s:VK.KEY_D], 0x04],
274 \ [[s:VK.CONTROL, s:VK.KEY_E], 0x05],
275 \ [[s:VK.CONTROL, s:VK.KEY_F], 0x06],
276 \ [[s:VK.CONTROL, s:VK.KEY_G], 0x07],
277 \ [[s:VK.CONTROL, s:VK.KEY_H], 0x08],
278 \ [[s:VK.CONTROL, s:VK.KEY_I], 0x09],
279 \ [[s:VK.CONTROL, s:VK.KEY_J], 0x0A],
280 \ [[s:VK.CONTROL, s:VK.KEY_K], 0x0B],
281 \ [[s:VK.CONTROL, s:VK.KEY_L], 0x0C],
282 \ [[s:VK.CONTROL, s:VK.KEY_M], 0x0D],
283 \ [[s:VK.CONTROL, s:VK.KEY_N], 0x0E],
284 \ [[s:VK.CONTROL, s:VK.KEY_O], 0x0F],
285 \ [[s:VK.CONTROL, s:VK.KEY_P], 0x10],
286 \ [[s:VK.CONTROL, s:VK.KEY_Q], 0x11],
287 \ [[s:VK.CONTROL, s:VK.KEY_R], 0x12],
288 \ [[s:VK.CONTROL, s:VK.KEY_S], 0x13],
289 \ [[s:VK.CONTROL, s:VK.KEY_T], 0x14],
290 \ [[s:VK.CONTROL, s:VK.KEY_U], 0x15],
291 \ [[s:VK.CONTROL, s:VK.KEY_V], 0x16],
292 \ [[s:VK.CONTROL, s:VK.KEY_W], 0x17],
293 \ [[s:VK.CONTROL, s:VK.KEY_X], 0x18],
294 \ [[s:VK.CONTROL, s:VK.KEY_Y], 0x19],
295 \ [[s:VK.CONTROL, s:VK.KEY_Z], 0x1A],
296 \ [[s:VK.CONTROL, s:VK.OEM_4], 0x1B],
297 \ [[s:VK.CONTROL, s:VK.OEM_5], 0x1C],
298 \ [[s:VK.CONTROL, s:VK.OEM_6], 0x1D],
Christopher Plewrightc8b20492023-01-04 18:06:00 +0000299 \ [[s:VK.CONTROL, s:VK.KEY_6], 0x1E],
300 \ [[s:VK.CONTROL, s:VK.OEM_MINUS], 0x1F],
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000301 \ ]
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000302
303let s:test_extra_key_chars = [
304 \ [[s:VK.ALT, s:VK.KEY_1], '±'],
305 \ [[s:VK.ALT, s:VK.KEY_2], '²'],
306 \ [[s:VK.ALT, s:VK.KEY_3], '³'],
307 \ [[s:VK.ALT, s:VK.KEY_4], '´'],
308 \ [[s:VK.ALT, s:VK.KEY_5], 'µ'],
309 \ [[s:VK.ALT, s:VK.KEY_6], '¶'],
310 \ [[s:VK.ALT, s:VK.KEY_7], '·'],
311 \ [[s:VK.ALT, s:VK.KEY_8], '¸'],
312 \ [[s:VK.ALT, s:VK.KEY_9], '¹'],
313 \ [[s:VK.ALT, s:VK.KEY_0], '°'],
314 \ [[s:VK.ALT, s:VK.KEY_A], 'á'],
315 \ [[s:VK.ALT, s:VK.KEY_B], 'â'],
316 \ [[s:VK.ALT, s:VK.KEY_C], 'ã'],
317 \ [[s:VK.ALT, s:VK.KEY_D], 'ä'],
318 \ [[s:VK.ALT, s:VK.KEY_E], 'Ã¥'],
319 \ [[s:VK.ALT, s:VK.KEY_F], 'æ'],
320 \ [[s:VK.ALT, s:VK.KEY_G], 'ç'],
321 \ [[s:VK.ALT, s:VK.KEY_H], 'è'],
322 \ [[s:VK.ALT, s:VK.KEY_I], 'é'],
323 \ [[s:VK.ALT, s:VK.KEY_J], 'ê'],
324 \ [[s:VK.ALT, s:VK.KEY_K], 'ë'],
325 \ [[s:VK.ALT, s:VK.KEY_L], 'ì'],
326 \ [[s:VK.ALT, s:VK.KEY_M], 'í'],
327 \ [[s:VK.ALT, s:VK.KEY_N], 'î'],
328 \ [[s:VK.ALT, s:VK.KEY_O], 'ï'],
329 \ [[s:VK.ALT, s:VK.KEY_P], 'ð'],
330 \ [[s:VK.ALT, s:VK.KEY_Q], 'ñ'],
331 \ [[s:VK.ALT, s:VK.KEY_R], 'ò'],
332 \ [[s:VK.ALT, s:VK.KEY_S], 'ó'],
333 \ [[s:VK.ALT, s:VK.KEY_T], 'ô'],
334 \ [[s:VK.ALT, s:VK.KEY_U], 'õ'],
335 \ [[s:VK.ALT, s:VK.KEY_V], 'ö'],
336 \ [[s:VK.ALT, s:VK.KEY_W], '÷'],
337 \ [[s:VK.ALT, s:VK.KEY_X], 'ø'],
338 \ [[s:VK.ALT, s:VK.KEY_Y], 'ù'],
339 \ [[s:VK.ALT, s:VK.KEY_Z], 'ú'],
340 \ ]
341
342func s:LoopTestKeyArray(arr)
Christopher Plewright566f76e2023-01-10 13:43:04 +0000343 " flush out the typeahead buffer
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000344 while getchar(0)
345 endwhile
346
347 for [kcodes, kstr] in a:arr
348 " Send as a sequence of key presses.
349 call SendKeyGroup(kcodes)
350 let ch = getcharstr(0)
351 " need to deal a bit differently with the non-printable ascii chars < 0x20
Christopher Plewrightc8b20492023-01-04 18:06:00 +0000352 if kstr < 0x20 && index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], kcodes[0]) >= 0
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000353 call assert_equal(nr2char(kstr), $"{ch}")
354 else
355 call assert_equal(kstr, $"{ch}")
356 endif
357 let mod_mask = getcharmod()
358 " the mod_mask is zero when no modifiers are used
359 " and when the virtual termcap maps the character
360 call assert_equal(0, mod_mask, $"key = {kstr}")
361
362 " Send as a single key press with a modifers mask.
363 let modifiers = 0
364 let key = kcodes[0]
365 for key in kcodes
366 if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], key) >= 0
Christopher Plewright566f76e2023-01-10 13:43:04 +0000367 let modifiers = modifiers + s:MOD_MASK_SHIFT
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000368 endif
369 if index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], key) >= 0
Christopher Plewright566f76e2023-01-10 13:43:04 +0000370 let modifiers = modifiers + s:MOD_MASK_CTRL
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000371 endif
372 if index([s:VK.ALT, s:VK.LALT, s:VK.RALT], key) >= 0
Christopher Plewright566f76e2023-01-10 13:43:04 +0000373 let modifiers = modifiers + s:MOD_MASK_ALT
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000374 endif
375 endfor
376 call SendKeyWithModifiers(key, modifiers)
377 let ch = getcharstr(0)
378 " need to deal a bit differently with the non-printable ascii chars < 0x20
379 if kstr < 0x20 && index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], kcodes[0]) >= 0
380 call assert_equal(nr2char(kstr), $"{ch}")
381 else
382 call assert_equal(kstr, $"{ch}")
383 endif
384 let mod_mask = getcharmod()
385 " the mod_mask is zero when no modifiers are used
386 " and when the virtual termcap maps the character
387 call assert_equal(0, mod_mask, $"key = {kstr}")
388 endfor
389
Christopher Plewright566f76e2023-01-10 13:43:04 +0000390 " flush out the typeahead buffer
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000391 while getchar(0)
392 endwhile
393
394endfunc
395
396" Test MS-Windows key events
Christopher Plewright566f76e2023-01-10 13:43:04 +0000397func Test_mswin_event_character_keys()
Christopher Plewright20b795e2022-12-20 20:01:58 +0000398 CheckMSWindows
399 new
400
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000401 call s:LoopTestKeyArray(s:test_ascii_key_chars)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000402
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000403 if !has('gui_running')
404 call s:LoopTestKeyArray(s:test_extra_key_chars)
405 endif
Christopher Plewright20b795e2022-12-20 20:01:58 +0000406
407" Test keyboard codes for digits
408" (0x30 - 0x39) : VK_0 - VK_9 are the same as ASCII '0' - '9'
409 for kc in range(48, 57)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000410 call SendKey(kc)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000411 let ch = getcharstr(0)
412 call assert_equal(nr2char(kc), ch)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000413 call SendKeyWithModifiers(kc, 0)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000414 let ch = getcharstr(0)
415 call assert_equal(nr2char(kc), ch)
416 endfor
417
418" Test keyboard codes for Alt-0 to Alt-9
419" Expect +128 from the digit char codes
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000420 for modkey in [s:VK.ALT, s:VK.LALT, s:VK.RALT]
Christopher Plewright20b795e2022-12-20 20:01:58 +0000421 for kc in range(48, 57)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000422 call SendKeyGroup([modkey, kc])
Christopher Plewright20b795e2022-12-20 20:01:58 +0000423 let ch = getchar(0)
424 call assert_equal(kc+128, ch)
Christopher Plewright566f76e2023-01-10 13:43:04 +0000425 call SendKeyWithModifiers(kc, s:MOD_MASK_ALT)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000426 let ch = getchar(0)
427 call assert_equal(kc+128, ch)
428 endfor
429 endfor
430
431" Test for lowercase 'a' to 'z', VK codes 65(0x41) - 90(0x5A)
432" Note: VK_A-VK_Z virtual key codes coincide with uppercase ASCII codes A-Z.
433" eg VK_A is 65, and the ASCII character code for uppercase 'A' is also 65.
Bram Moolenaar94722c52023-01-28 19:19:03 +0000434" Caution: these are interpreted as lowercase when Shift is NOT pressed.
Christopher Plewright20b795e2022-12-20 20:01:58 +0000435" eg, sending VK_A (65) 'A' Key code without shift modifier, will produce ASCII
436" char 'a' (91) as the output. The ASCII codes for the lowercase letters are
437" numbered 32 higher than their uppercase versions.
438 for kc in range(65, 90)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000439 call SendKey(kc)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000440 let ch = getcharstr(0)
441 call assert_equal(nr2char(kc + 32), ch)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000442 call SendKeyWithModifiers(kc, 0)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000443 let ch = getcharstr(0)
444 call assert_equal(nr2char(kc + 32), ch)
445 endfor
446
447" Test for Uppercase 'A' - 'Z' keys
448" ie. with VK_SHIFT, expect the keycode = character code.
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000449 for modkey in [s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT]
450 for kc in range(65, 90)
451 call SendKeyGroup([modkey, kc])
452 let ch = getcharstr(0)
453 call assert_equal(nr2char(kc), ch)
Christopher Plewright566f76e2023-01-10 13:43:04 +0000454 call SendKeyWithModifiers(kc, s:MOD_MASK_SHIFT)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000455 let ch = getcharstr(0)
456 call assert_equal(nr2char(kc), ch)
457 endfor
Christopher Plewright20b795e2022-12-20 20:01:58 +0000458 endfor
459
460 " Test for <Ctrl-A> to <Ctrl-Z> keys
Christopher Plewright20b795e2022-12-20 20:01:58 +0000461 " Expect the unicode characters 0x01 to 0x1A
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000462 for modkey in [s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL]
Christopher Plewright20b795e2022-12-20 20:01:58 +0000463 for kc in range(65, 90)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000464 call SendKeyGroup([modkey, kc])
Christopher Plewright20b795e2022-12-20 20:01:58 +0000465 let ch = getcharstr(0)
466 call assert_equal(nr2char(kc - 64), ch)
Christopher Plewright566f76e2023-01-10 13:43:04 +0000467 call SendKeyWithModifiers(kc, s:MOD_MASK_CTRL)
Christopher Plewright20b795e2022-12-20 20:01:58 +0000468 let ch = getcharstr(0)
469 call assert_equal(nr2char(kc - 64), ch)
470 endfor
471 endfor
472
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000473 " Windows intercepts some of these keys in the GUI.
Christopher Plewright20b795e2022-12-20 20:01:58 +0000474 if !has("gui_running")
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000475 " Test for <Alt-A> to <Alt-Z> keys
Christopher Plewright20b795e2022-12-20 20:01:58 +0000476 " Expect the unicode characters 0xE1 to 0xFA
477 " ie. 160 higher than the lowercase equivalent
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000478 for modkey in [s:VK.ALT, s:VK.LALT, s:VK.RALT]
479 for kc in range(65, 90)
480 call SendKeyGroup([modkey, kc])
481 let ch = getchar(0)
482 call assert_equal(kc+160, ch)
Christopher Plewright566f76e2023-01-10 13:43:04 +0000483 call SendKeyWithModifiers(kc, s:MOD_MASK_ALT)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000484 let ch = getchar(0)
485 call assert_equal(kc+160, ch)
486 endfor
Christopher Plewright20b795e2022-12-20 20:01:58 +0000487 endfor
488 endif
489
Christopher Plewright566f76e2023-01-10 13:43:04 +0000490endfun
491
Christopher Plewrightc8b20492023-01-04 18:06:00 +0000492 " Test for Function Keys 'F1' to 'F12'
493 " VK codes 112(0x70) - 123(0x7B)
494 " Also with ALL permutatios of modifiers; Shift, Ctrl & Alt
Christopher Plewright566f76e2023-01-10 13:43:04 +0000495func Test_mswin_event_function_keys()
496
497 if has('gui_running')
498 let g:test_is_flaky = 1
499 endif
500
501 " NOTE: Windows intercepts these combinations in the GUI
502 let gui_nogo = ["A-F1", "A-F2", "A-F3", "A-F4", "A-S-F4", "A-C-S-F4",
503 \ "A-F5", "A-F6", "A-F7", "A-F8", "A-C-F8", "A-F9",
504 \ "A-F10", "A-F11" , "A-C-F11", "A-C-F12"]
505
506 " flush out the typeahead buffer
507 while getchar(0)
508 endwhile
509
510 for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers
511 for n in range(1, 12)
512 let expected_mod_mask = vim_mod_mask
513 let kstr = $"{mod_str}F{n}"
514 if !has('gui_running') || (has('gui_running') && n != 10
515 \ && index(gui_nogo, kstr) == -1)
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000516 let keycode = eval('"\<' .. kstr .. '>"')
Christopher Plewright566f76e2023-01-10 13:43:04 +0000517 " flush out the typeahead buffer
Christopher Plewrightc8b20492023-01-04 18:06:00 +0000518 while getchar(0)
519 endwhile
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000520 call SendKeyWithModifiers(111+n, vim_mod_mask)
521 let ch = getcharstr(0)
522 let mod_mask = getcharmod()
Christopher Plewrightc8b20492023-01-04 18:06:00 +0000523 call assert_equal(keycode, $"{ch}", $"key = {kstr}")
Christopher Plewright566f76e2023-01-10 13:43:04 +0000524 " workaround for the virtual termcap maps changing the character
525 "instead of sending Shift
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000526 for mod_key in mod_keycodes
527 if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], mod_key) >= 0
Christopher Plewright566f76e2023-01-10 13:43:04 +0000528 let expected_mod_mask -= s:MOD_MASK_SHIFT
529 break
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000530 endif
531 endfor
Christopher Plewright566f76e2023-01-10 13:43:04 +0000532 call assert_equal(expected_mod_mask, mod_mask, $"mod = {expected_mod_mask} for key = {kstr}")
533 endif
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000534 endfor
Christopher Plewright566f76e2023-01-10 13:43:04 +0000535 endfor
536endfunc
537
538func ExtractModifiers(mod_keycodes)
539 let has_shift = 0
540 let has_ctrl = 0
541 let has_alt = 0
542 for mod_key in a:mod_keycodes
543 if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], mod_key) >= 0
544 let has_shift = 1
545 endif
546 if index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], mod_key) >= 0
547 let has_ctrl = 1
548 endif
549 if index([s:VK.MENU, s:VK.LMENU, s:VK.RMENU], mod_key) >= 0
550 let has_alt = 1
551 endif
552 endfor
553 return [has_shift, has_ctrl, has_alt]
554endfunc
555
556 " Test for Movement Keys;
557 " VK_PRIOR 0x21, VK_NEXT 0x22,
558 " VK_END 0x23, VK_HOME 0x24,
559 " VK_LEFT 0x25, VK_UP 0x26,
560 " VK_RIGHT 0x27, VK_DOWN 0x28
561 " With ALL permutations of modifiers; none, Shift, Ctrl & Alt
562func Test_mswin_event_movement_keys()
563
564 if has('gui_running')
565 let g:test_is_flaky = 1
Christopher Plewright20b795e2022-12-20 20:01:58 +0000566 endif
567
Christopher Plewright566f76e2023-01-10 13:43:04 +0000568 let movement_keys = [
569 \ [s:VK.PRIOR, "PageUp"],
570 \ [s:VK.NEXT, "PageDown"],
571 \ [s:VK.END, "End"],
572 \ [s:VK.HOME, "Home"],
573 \ [s:VK.LEFT, "Left"],
574 \ [s:VK.UP, "Up"],
575 \ [s:VK.RIGHT, "Right"],
576 \ [s:VK.DOWN, "Down"],
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000577 \ ]
578
Christopher Plewright566f76e2023-01-10 13:43:04 +0000579 " flush out the typeahead buffer
580 while getchar(0)
581 endwhile
582
583 for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers
584 for [kcode, kname] in movement_keys
585 let exp_mod_mask = vim_mod_mask
586 let kstr = $"{mod_str}{kname}"
587 let chstr_eval = eval('"\<' .. kstr .. '>"')
588
589 " flush out the typeahead buffer
590 while getchar(0)
591 endwhile
592 execute 'call feedkeys("\<' .. kstr .. '>")'
593 let chstr_fk = getcharstr(0)
594 call assert_equal(chstr_eval, chstr_fk, $"feedkeys = <{kstr}>")
595
596 " flush out the typeahead buffer
597 while getchar(0)
598 endwhile
599 call SendKey(kcode)
600 let chstr_alone = getcharstr(0)
601 let chstr_alone_end = chstr_alone[len(chstr_alone)-2:len(chstr_alone)-1]
602
603 " flush out the typeahead buffer
604 while getchar(0)
605 endwhile
606 call SendKeyGroup(mod_keycodes + [kcode])
607 let chstr_mswin = getcharstr(0)
608 let chstr_mswin_end = chstr_mswin[len(chstr_mswin)-2:len(chstr_mswin)-1]
609 let mod_mask = getcharmod()
610
611 " The virtual termcap maps may** change the character and either;
612 " - remove the Shift modifier, or
613 " - remove the Ctrl modifier if the Shift modifier was not removed.
614 let [has_shift, has_ctrl, has_alt] = ExtractModifiers(mod_keycodes)
615 if chstr_alone_end != chstr_mswin_end
616 if has_shift != 0
617 let exp_mod_mask -= s:MOD_MASK_SHIFT
618 elseif has_ctrl != 0
619 let exp_mod_mask -= s:MOD_MASK_CTRL
620 endif
621 endif
622 " **Note: The appveyor Windows GUI test environments, from VS2017 on,
623 " consistently intercepts the Shift modifier WITHOUT changing the
624 " MOVEMENT character. This issue does not happen in any github actions
625 " CI Windows test environments. Attempted to reproduce this manually
626 " on Windows versions; 7, 8.1, 10, 11, Server 2019 and Server 2022, but
627 " the issue did not occur on any of those environments.
628 " Below is a workaround for the issue.
629 if has('gui_running') && has_shift != 0
630 if exp_mod_mask != mod_mask && chstr_eval != chstr_mswin
631 let kstr_sub = substitute(kstr, "S-", "", "")
632 let chstr_eval = eval('"\<' .. kstr_sub .. '>"')
633 if exp_mod_mask - s:MOD_MASK_SHIFT == mod_mask
634 let exp_mod_mask -= s:MOD_MASK_SHIFT
635 elseif has_ctrl != 0 && exp_mod_mask - s:MOD_MASK_CTRL == mod_mask
636 let exp_mod_mask -= s:MOD_MASK_CTRL
637 endif
638 endif
639 endif
640 call assert_equal(chstr_eval, chstr_mswin, $"key = {kstr}")
641 call assert_equal(exp_mod_mask, mod_mask, $"mod_mask for key = {kstr}")
642 endfor
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000643 endfor
644
Christopher Plewright20b795e2022-12-20 20:01:58 +0000645 bw!
646endfunc
647
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000648
649" Test for QWERTY Ctrl+- which should result in ^_
650" issue #10817
651func Test_QWERTY_Ctrl_minus()
652 CheckMSWindows
653 new
654
655 call SendKeyGroup([s:VK.CONTROL, s:VK.OEM_MINUS])
656 let ch = getcharstr(0)
657 call assert_equal(nr2char(0x1f),ch)
658
659 call SendKey(s:VK.KEY_I)
660 call SendKeyGroup([s:VK.CONTROL, s:VK.SUBTRACT])
661 call SendKey(s:VK.ESCAPE)
662 call ExecuteBufferedKeys()
663 call assert_equal('-', getline('$'))
664
665 %d _
666 imapclear
667 imap <C-_> BINGO
668 call SendKey(s:VK.KEY_I)
669 call SendKeyGroup([s:VK.CONTROL, s:VK.OEM_MINUS])
670 call SendKey(s:VK.ESCAPE)
671 call ExecuteBufferedKeys()
672 call assert_equal('BINGO', getline('$'))
673
674 %d _
675 imapclear
676 exec "imap \x1f BILBO"
677 call SendKey(s:VK.KEY_I)
678 call SendKeyGroup([s:VK.CONTROL, s:VK.OEM_MINUS])
679 call SendKey(s:VK.ESCAPE)
680 call ExecuteBufferedKeys()
681 call assert_equal('BILBO', getline('$'))
682
Christopher Plewright7b0afc12022-12-30 16:54:58 +0000683 imapclear
684 bw!
685endfunc
686
687" Test MS-Windows mouse events
Christopher Plewright566f76e2023-01-10 13:43:04 +0000688func Test_mswin_event_mouse()
Christopher Plewright20b795e2022-12-20 20:01:58 +0000689 CheckMSWindows
690 new
691
692 set mousemodel=extend
693 call test_override('no_query_mouse', 1)
694 call WaitForResponses()
695
696 let msg = ''
697
698 call setline(1, ['one two three', 'four five six'])
699
700 " Test mouse movement
701 " by default, no mouse move events are generated
702 " this setting enables it to generate move events
703 set mousemev
704
705 if !has('gui_running')
706 " console version needs a button pressed,
707 " otherwise it ignores mouse movements.
708 call MouseLeftClick(2, 3)
709 endif
710 call MSWinMouseEvent(0x700, 8, 13, 0, 0, 0)
711 if has('gui_running')
712 call feedkeys("\<Esc>", 'Lx!')
713 endif
714 let pos = getmousepos()
715 call assert_equal(8, pos.screenrow)
716 call assert_equal(13, pos.screencol)
717
718 if !has('gui_running')
719 call MouseLeftClick(2, 3)
720 call MSWinMouseEvent(0x700, 6, 4, 1, 0, 0)
721 let pos = getmousepos()
722 call assert_equal(6, pos.screenrow)
723 call assert_equal(4, pos.screencol)
724 endif
725
726 " test cells vs pixels
727 if has('gui_running')
728 let args = { }
729 let args.row = 9
730 let args.col = 7
731 let args.move = 1
732 let args.cell = 1
733 call test_mswin_event("mouse", args)
734 call feedkeys("\<Esc>", 'Lx!')
735 let pos = getmousepos()
736 call assert_equal(9, pos.screenrow)
737 call assert_equal(7, pos.screencol)
738
739 let args.cell = 0
740 call test_mswin_event("mouse", args)
741 call feedkeys("\<Esc>", 'Lx!')
742 let pos = getmousepos()
743 call assert_equal(1, pos.screenrow)
744 call assert_equal(1, pos.screencol)
745
746 unlet args
747 endif
748
749 " finish testing mouse movement
750 set mousemev&
751
752 " place the cursor using left click and release in normal mode
753 call MouseLeftClick(2, 4)
754 call MouseLeftRelease(2, 4)
755 if has('gui_running')
756 call feedkeys("\<Esc>", 'Lx!')
757 endif
758 call assert_equal([0, 2, 4, 0], getpos('.'))
759
760 " select and yank a word
761 let @" = ''
762 call MouseLeftClick(1, 9)
763 let args = #{button: 0, row: 1, col: 9, multiclick: 1, modifiers: 0}
764 call test_mswin_event('mouse', args)
765 call MouseLeftRelease(1, 9)
766 call feedkeys("y", 'Lx!')
767 call assert_equal('three', @")
768
769 " create visual selection using right click
770 let @" = ''
771
772 call MouseLeftClick(2 ,6)
773 call MouseLeftRelease(2, 6)
774 call MouseRightClick(2, 13)
775 call MouseRightRelease(2, 13)
776 call feedkeys("y", 'Lx!')
777 call assert_equal('five six', @")
778
779 " paste using middle mouse button
780 let @* = 'abc '
781 call feedkeys('""', 'Lx!')
782 call MouseMiddleClick(1, 9)
783 call MouseMiddleRelease(1, 9)
784 if has('gui_running')
785 call feedkeys("\<Esc>", 'Lx!')
786 endif
787 call assert_equal(['one two abc three', 'four five six'], getline(1, '$'))
788
789 " test mouse scrolling (aka touchpad scrolling.)
790 %d _
791 set scrolloff=0
792 call setline(1, range(1, 100))
793
794 " Scroll Down
795 call MouseWheelDown(2, 1)
796 call MouseWheelDown(2, 1)
797 call MouseWheelDown(2, 1)
798 call feedkeys("H", 'Lx!')
799 call assert_equal(10, line('.'))
800
801 " Scroll Up
802 call MouseWheelUp(2, 1)
803 call MouseWheelUp(2, 1)
804 call feedkeys("H", 'Lx!')
805 call assert_equal(4, line('.'))
806
807 " Shift Scroll Down
808 call MouseShiftWheelDown(2, 1)
809 call feedkeys("H", 'Lx!')
810 " should scroll from where it is (4) + visible buffer height - cmdheight
Bram Moolenaar94722c52023-01-28 19:19:03 +0000811 let shift_scroll_height = line('w$') - line('w0') - &cmdheight
Christopher Plewright20b795e2022-12-20 20:01:58 +0000812 call assert_equal(4 + shift_scroll_height, line('.'))
813
814 " Shift Scroll Up
815 call MouseShiftWheelUp(2, 1)
816 call feedkeys("H", 'Lx!')
817 call assert_equal(4, line('.'))
818
819 if !has('gui_running')
820 " Shift Scroll Down (using MOD)
821 call MSWinMouseEvent(0x100, 2, 1, 0, 0, 0x04)
822 call feedkeys("H", 'Lx!')
823 " should scroll from where it is (4) + visible buffer height - cmdheight
Bram Moolenaar94722c52023-01-28 19:19:03 +0000824 let shift_scroll_height = line('w$') - line('w0') - &cmdheight
Christopher Plewright20b795e2022-12-20 20:01:58 +0000825 call assert_equal(4 + shift_scroll_height, line('.'))
826
827 " Shift Scroll Up (using MOD)
828 call MSWinMouseEvent(0x200, 2, 1, 0, 0, 0x04)
829 call feedkeys("H", 'Lx!')
830 call assert_equal(4, line('.'))
831 endif
832
833 set scrolloff&
834
835 %d _
836 set nowrap
837 " make the buffer 500 wide.
838 call setline(1, range(10)->join('')->repeat(50))
839 " Scroll Right
840 call MouseWheelRight(1, 5)
841 call MouseWheelRight(1, 10)
842 call MouseWheelRight(1, 15)
843 call feedkeys('g0', 'Lx!')
844 call assert_equal(19, col('.'))
845
846 " Scroll Left
847 call MouseWheelLeft(1, 15)
848 call MouseWheelLeft(1, 10)
849 call feedkeys('g0', 'Lx!')
850 call assert_equal(7, col('.'))
851
852 " Shift Scroll Right
853 call MouseShiftWheelRight(1, 10)
854 call feedkeys('g0', 'Lx!')
855 " should scroll from where it is (7) + window width
856 call assert_equal(7 + winwidth(0), col('.'))
Bram Moolenaar94722c52023-01-28 19:19:03 +0000857
Christopher Plewright20b795e2022-12-20 20:01:58 +0000858 " Shift Scroll Left
859 call MouseShiftWheelLeft(1, 50)
860 call feedkeys('g0', 'Lx!')
861 call assert_equal(7, col('.'))
862 set wrap&
863
864 %d _
865 call setline(1, repeat([repeat('a', 60)], 10))
866
867 " record various mouse events
868 let mouseEventNames = [
869 \ 'LeftMouse', 'LeftRelease', '2-LeftMouse', '3-LeftMouse',
870 \ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse',
871 \ 'MiddleRelease', '2-MiddleMouse', '3-MiddleMouse',
872 \ 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
873 \ 'RightMouse', 'RightRelease', '2-RightMouse',
874 \ '3-RightMouse', 'S-RightMouse', 'A-RightMouse', 'C-RightMouse',
875 \ ]
876 let mouseEventCodes = map(copy(mouseEventNames), "'<' .. v:val .. '>'")
877 let g:events = []
878 for e in mouseEventCodes
879 exe 'nnoremap ' .. e .. ' <Cmd>call add(g:events, "' ..
880 \ substitute(e, '[<>]', '', 'g') .. '")<CR>'
881 endfor
882
Bram Moolenaar94722c52023-01-28 19:19:03 +0000883 " Test various mouse buttons
884 "(0 - Left, 1 - Middle, 2 - Right,
Christopher Plewright20b795e2022-12-20 20:01:58 +0000885 " 0x300 - MOUSE_X1/FROM_LEFT_3RD_BUTTON,
886 " 0x400 - MOUSE_X2/FROM_LEFT_4TH_BUTTON)
887 for button in [0, 1, 2, 0x300, 0x400]
888 " Single click
889 let args = #{button: button, row: 2, col: 5, multiclick: 0, modifiers: 0}
890 call test_mswin_event('mouse', args)
891 let args.button = 3
892 call test_mswin_event('mouse', args)
893
894 " Double Click
895 let args.button = button
896 call test_mswin_event('mouse', args)
897 let args.multiclick = 1
898 call test_mswin_event('mouse', args)
899 let args.button = 3
900 let args.multiclick = 0
901 call test_mswin_event('mouse', args)
902
903 " Triple Click
904 let args.button = button
905 call test_mswin_event('mouse', args)
906 let args.multiclick = 1
907 call test_mswin_event('mouse', args)
908 call test_mswin_event('mouse', args)
909 let args.button = 3
910 let args.multiclick = 0
911 call test_mswin_event('mouse', args)
912
913 " Shift click
914 let args = #{button: button, row: 3, col: 7, multiclick: 0, modifiers: 4}
915 call test_mswin_event('mouse', args)
916 let args.button = 3
917 call test_mswin_event('mouse', args)
918
919 " Alt click
920 let args.button = button
921 let args.modifiers = 8
922 call test_mswin_event('mouse', args)
923 let args.button = 3
924 call test_mswin_event('mouse', args)
925
926 " Ctrl click
927 let args.button = button
928 let args.modifiers = 16
929 call test_mswin_event('mouse', args)
930 let args.button = 3
931 call test_mswin_event('mouse', args)
932
933 call feedkeys("\<Esc>", 'Lx!')
934 endfor
935
936 if has('gui_running')
937 call assert_equal(['LeftMouse', 'LeftRelease', 'LeftMouse',
938 \ '2-LeftMouse', 'LeftMouse', '2-LeftMouse', '3-LeftMouse',
939 \ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse',
940 \ 'MiddleRelease', 'MiddleMouse', '2-MiddleMouse', 'MiddleMouse',
941 \ '2-MiddleMouse', '3-MiddleMouse', 'S-MiddleMouse', 'A-MiddleMouse',
942 \ 'C-MiddleMouse', 'RightMouse', 'RightRelease', 'RightMouse',
943 \ '2-RightMouse', 'RightMouse', '2-RightMouse', '3-RightMouse',
944 \ 'S-RightMouse', 'A-RightMouse', 'C-RightMouse'],
945 \ g:events)
946 else
947 call assert_equal(['MiddleRelease', 'LeftMouse', '2-LeftMouse',
948 \ '3-LeftMouse', 'S-LeftMouse', 'MiddleMouse', '2-MiddleMouse',
949 \ '3-MiddleMouse', 'MiddleMouse', 'S-MiddleMouse', 'RightMouse',
950 \ '2-RightMouse', '3-RightMouse'],
951 \ g:events)
952 endif
953
954 for e in mouseEventCodes
955 exe 'nunmap ' .. e
956 endfor
957
958 bw!
959 call test_override('no_query_mouse', 0)
960 set mousemodel&
961endfunc
962
963
964" Test MS-Windows test_mswin_event error handling
965func Test_mswin_event_error_handling()
966
967 let args = #{button: 0xfff, row: 2, col: 4, move: 0, multiclick: 0, modifiers: 0}
968 if !has('gui_running')
969 call assert_fails("call test_mswin_event('mouse', args)",'E475:')
970 endif
971 let args = #{button: 0, row: 2, col: 4, move: 0, multiclick: 0, modifiers: 0}
972 call assert_fails("call test_mswin_event('a1b2c3', args)", 'E475:')
973 call assert_fails("call test_mswin_event(test_null_string(), {})", 'E475:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000974
Christopher Plewright20b795e2022-12-20 20:01:58 +0000975 call assert_fails("call test_mswin_event([], args)", 'E1174:')
976 call assert_fails("call test_mswin_event('abc', [])", 'E1206:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000977
Christopher Plewright20b795e2022-12-20 20:01:58 +0000978 call assert_false(test_mswin_event('mouse', test_null_dict()))
979 let args = #{row: 2, col: 4, multiclick: 0, modifiers: 0}
980 call assert_false(test_mswin_event('mouse', args))
981 let args = #{button: 0, col: 4, multiclick: 0, modifiers: 0}
982 call assert_false(test_mswin_event('mouse', args))
983 let args = #{button: 0, row: 2, multiclick: 0, modifiers: 0}
984 call assert_false(test_mswin_event('mouse', args))
985 let args = #{button: 0, row: 2, col: 4, modifiers: 0}
986 call assert_false(test_mswin_event('mouse', args))
987 let args = #{button: 0, row: 2, col: 4, multiclick: 0}
988 call assert_false(test_mswin_event('mouse', args))
989
990 call assert_false(test_mswin_event('key', test_null_dict()))
991 call assert_fails("call test_mswin_event('key', [])", 'E1206:')
992 call assert_fails("call test_mswin_event('key', {'event': 'keydown', 'keycode': 0x0})", 'E1291:')
993 call assert_fails("call test_mswin_event('key', {'event': 'keydown', 'keycode': [15]})", 'E745:')
994 call assert_fails("call test_mswin_event('key', {'event': 'keys', 'keycode': 0x41})", 'E475:')
995 call assert_fails("call test_mswin_event('key', {'keycode': 0x41})", 'E417:')
996 call assert_fails("call test_mswin_event('key', {'event': 'keydown'})", 'E1291:')
997
998 call assert_fails("sandbox call test_mswin_event('key', {'event': 'keydown', 'keycode': 61 })", 'E48:')
999
Christopher Plewright566f76e2023-01-10 13:43:04 +00001000 " flush out the typeahead buffer
Christopher Plewright20b795e2022-12-20 20:01:58 +00001001 while getchar(0)
1002 endwhile
1003endfunc
1004
1005
1006" vim: shiftwidth=2 sts=2 expandtab