Skip to content

Commit

Permalink
patch 9.0.1112: test_mswin_event() can hang
Browse files Browse the repository at this point in the history
Problem:    test_mswin_event() can hang.
Solution:   Add the "execute" argument to process events right away.
            (Christopher Plewright, closes #11760)
  • Loading branch information
zewpo authored and brammool committed Dec 30, 2022
1 parent 96dd34e commit 7b0afc1
Show file tree
Hide file tree
Showing 6 changed files with 592 additions and 252 deletions.
13 changes: 9 additions & 4 deletions runtime/doc/testing.txt
Expand Up @@ -274,17 +274,22 @@ test_mswin_event({event}, {args}) *test_mswin_event()*
event: The supported string values are:
keyup generate a keyup event
keydown generate a keydown event
keycode: Keycode to use for a keyup or a keydown event.
keycode: Keycode to use for a keyup or a keydown event.
modifiers: Optional; key modifiers.
The supported values are:
2 shift is pressed
4 ctrl is pressed
8 alt is pressed
Note: These values are different from the
mouse modifiers.
*E1291*
Returns TRUE if the event is successfully added, FALSE if
there is a failure.
execute: Optional. Similar to |feedkeys()| mode x.
When this is included and set to true
(non-zero) then Vim will process any buffered
unprocessed key events. All other {args}
items are optional when this is set and true.

Returns TRUE if the event is successfully added or executed,
FALSE if there is a failure.

Can also be used as a |method|: >
GetEvent()->test_mswin_event({args})
Expand Down
6 changes: 6 additions & 0 deletions src/gui_w32.c
Expand Up @@ -888,6 +888,12 @@ _OnChar(
modifiers = get_active_modifiers();

ch = simplify_key(ch, &modifiers);

// Some keys need adjustment when the Ctrl modifier is used.
++no_reduce_keys;
ch = may_adjust_key_for_ctrl(modifiers, ch);
--no_reduce_keys;

// remove the SHIFT modifier for keys where it's already included, e.g.,
// '(' and '*'
modifiers = may_remove_shift_modifier(modifiers, ch);
Expand Down
73 changes: 44 additions & 29 deletions src/os_win32.c
Expand Up @@ -1106,31 +1106,6 @@ decode_key_event(
break;
}

// special cases
if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0
&& (pker->uChar.UnicodeChar == NUL
|| pker->uChar.UnicodeChar == 0xfffd))
{
// Ctrl-6 is Ctrl-^
if (pker->wVirtualKeyCode == '6')
{
*pch = Ctrl_HAT;
return TRUE;
}
// Ctrl-2 is Ctrl-@
else if (pker->wVirtualKeyCode == '2')
{
*pch = NUL;
return TRUE;
}
// Ctrl-- is Ctrl-_
else if (pker->wVirtualKeyCode == 0xBD)
{
*pch = Ctrl__;
return TRUE;
}
}

// Shift-TAB
if (pker->wVirtualKeyCode == VK_TAB && (nModifs & SHIFT_PRESSED))
{
Expand Down Expand Up @@ -1277,13 +1252,23 @@ encode_key_event(dict_T *args, INPUT_RECORD *ir)
ker.wVirtualKeyCode = vkCode;
win32_kbd_patch_key(&ker);

for (int i = ARRAY_LENGTH(VirtKeyMap);
--i >= 0 && !ker.uChar.UnicodeChar; )
for (int i = ARRAY_LENGTH(VirtKeyMap); i >= 0; --i)
{
if (VirtKeyMap[i].wVirtKey == vkCode)
{
ker.uChar.UnicodeChar = 0xfffd; // REPLACEMENT CHARACTER
break;
}
}

// The following are treated specially in Vim.
// Ctrl-6 is Ctrl-^
// Ctrl-2 is Ctrl-@
// Ctrl-- is Ctrl-_
if ((vkCode == 0xBD || vkCode == '2' || vkCode == '6')
&& (ker.dwControlKeyState & CTRL))
ker.uChar.UnicodeChar = 0xfffd; // REPLACEMENT CHARACTER

ir->Event.KeyEvent = ker;
vim_free(event);
}
Expand Down Expand Up @@ -1919,10 +1904,23 @@ test_mswin_event(char_u *event, dict_T *args)

INPUT_RECORD ir;
BOOL input_encoded = FALSE;
BOOL execute = FALSE;
if (STRCMP(event, "key") == 0)
input_encoded = encode_key_event(args, &ir);
{
execute = dict_get_bool(args, "execute", FALSE);
if (dict_has_key(args, "event"))
input_encoded = encode_key_event(args, &ir);
else if (!execute)
{
semsg(_(e_missing_argument_str), "event");
return FALSE;
}
}
else if (STRCMP(event, "mouse") == 0)
{
execute = TRUE;
input_encoded = encode_mouse_event(args, &ir);
}
else
{
semsg(_(e_invalid_value_for_argument_str_str), "event", event);
Expand All @@ -1935,8 +1933,16 @@ test_mswin_event(char_u *event, dict_T *args)
if (input_encoded)
lpEventsWritten = write_input_record_buffer(&ir, 1);

if (STRCMP(event, "mouse") == 0)
// Set flags to execute the event, ie. like feedkeys mode X.
if (execute)
{
int save_msg_scroll = msg_scroll;
// Avoid a 1 second delay when the keys start Insert mode.
msg_scroll = FALSE;
ch_log(NULL, "test_mswin_event() executing");
exec_normal(TRUE, TRUE, TRUE);
msg_scroll |= save_msg_scroll;
}

# endif
return lpEventsWritten;
Expand Down Expand Up @@ -2426,6 +2432,15 @@ mch_inchar(

c = tgetch(&modifiers, &ch2);

// Some chars need adjustment when the Ctrl modifier is used.
++no_reduce_keys;
c = may_adjust_key_for_ctrl(modifiers, c);
--no_reduce_keys;

// remove the SHIFT modifier for keys where it's already included,
// e.g., '(' and '*'
modifiers = may_remove_shift_modifier(modifiers, c);

if (typebuf_changed(tb_change_cnt))
{
// "buf" may be invalid now if a client put something in the
Expand Down
3 changes: 2 additions & 1 deletion src/testdir/test_gui.vim
Expand Up @@ -1694,7 +1694,7 @@ func Test_gui_lowlevel_keyevent()
\ [[0x11, 0x10, 0x28], "C-S-Down", 4],
\ [[0x11, 0x30], "C-0", 4],
\ [[0x11, 0x31], "C-1", 4],
\ [[0x11, 0x32], "C-2", 4],
\ [[0x11, 0x32], "C-@", 0],
\ [[0x11, 0x33], "C-3", 4],
\ [[0x11, 0x34], "C-4", 4],
\ [[0x11, 0x35], "C-5", 4],
Expand All @@ -1715,6 +1715,7 @@ func Test_gui_lowlevel_keyevent()
\ [[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],
Expand Down

0 comments on commit 7b0afc1

Please sign in to comment.