0
0
mirror of https://github.com/vim/vim.git synced 2025-08-27 20:13:38 -04:00

patch 9.0.0058: Win32: cannot test low level events

Problem:    Win32: cannot test low level events.
Solution:   Add "sendevent" to test_gui_event(). (Yegappan Lakshmanan,
            closes #10679)
This commit is contained in:
Yegappan Lakshmanan 2022-07-23 05:04:16 +01:00 committed by Bram Moolenaar
parent 5154a88800
commit 81a3ff97e2
7 changed files with 148 additions and 0 deletions

View File

@ -94,6 +94,7 @@ test_gui_event({event}, {args})
"findrepl" search and replace text. "findrepl" search and replace text.
"mouse" mouse button click event. "mouse" mouse button click event.
"scrollbar" move or drag the scrollbar. "scrollbar" move or drag the scrollbar.
"sendevent" send a low-level GUI event.
"tabline" select a tab page by mouse click. "tabline" select a tab page by mouse click.
"tabmenu" select a tabline menu entry. "tabmenu" select a tabline menu entry.
@ -177,6 +178,15 @@ test_gui_event({event}, {args})
dragging: 1 to drag the scrollbar and 0 to click in the dragging: 1 to drag the scrollbar and 0 to click in the
scrollbar. scrollbar.
"sendevent":
Send a low-level GUI event (e.g. key-up or down).
Currently only supported on MS-Windows.
The supported items in {args} are:
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.
"tabline": "tabline":
Inject a mouse click event on the tabline to select a Inject a mouse click event on the tabline to select a
tabpage. The supported items in {args} are: tabpage. The supported items in {args} are:

View File

@ -3303,4 +3303,6 @@ EXTERN char e_could_not_check_for_pending_sigalrm_str[]
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
EXTERN char e_substitute_nesting_too_deep[] EXTERN char e_substitute_nesting_too_deep[]
INIT(= N_("E1290: substitute nesting too deep")); INIT(= N_("E1290: substitute nesting too deep"));
EXTERN char e_invalid_argument_nr[]
INIT(= N_("E1291: Invalid argument: %ld"));
#endif #endif

View File

@ -8541,3 +8541,42 @@ netbeans_draw_multisign_indicator(int row)
SetPixel(s_hdc, x+2, y, gui.currFgColor); SetPixel(s_hdc, x+2, y, gui.currFgColor);
} }
#endif #endif
#if defined(FEAT_EVAL) || defined(PROTO)
int
test_gui_w32_sendevent(dict_T *args)
{
char_u *event;
INPUT inputs[1];
event = dict_get_string(args, "event", TRUE);
if (event == NULL)
return FALSE;
ZeroMemory(inputs, sizeof(inputs));
if (STRICMP(event, "keydown") == 0 || STRICMP(event, "keyup") == 0)
{
WORD vkCode;
vkCode = dict_get_number_def(args, "keycode", 0);
if (vkCode <= 0 || vkCode >= 0xFF)
{
semsg(_(e_invalid_argument_nr), (long)vkCode);
return FALSE;
}
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = vkCode;
if (STRICMP(event, "keyup") == 0)
inputs[0].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
}
else
semsg(_(e_invalid_argument_str), event);
vim_free(event);
return TRUE;
}
#endif

View File

@ -96,4 +96,5 @@ void gui_mch_post_balloon(BalloonEval *beval, char_u *mesg);
BalloonEval *gui_mch_create_beval_area(void *target, char_u *mesg, void (*mesgCB)(BalloonEval *, int), void *clientData); BalloonEval *gui_mch_create_beval_area(void *target, char_u *mesg, void (*mesgCB)(BalloonEval *, int), void *clientData);
void gui_mch_destroy_beval_area(BalloonEval *beval); void gui_mch_destroy_beval_area(BalloonEval *beval);
void netbeans_draw_multisign_indicator(int row); void netbeans_draw_multisign_indicator(int row);
int test_gui_w32_sendevent(dict_T *args);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@ -1606,4 +1606,88 @@ func Test_gui_dialog_file()
call delete('Xlines') call delete('Xlines')
endfunc endfunc
" Test for sending low level key presses
func SendKeys(keylist)
for k in a:keylist
call test_gui_event("sendevent", #{event: "keydown", keycode: k})
endfor
for k in reverse(a:keylist)
call test_gui_event("sendevent", #{event: "keyup", keycode: k})
endfor
endfunc
func Test_gui_lowlevel_keyevent()
CheckMSWindows
new
" Test for <Ctrl-A> to <Ctrl-Z> keys
for kc in range(65, 90)
call SendKeys([0x11, kc])
let ch = getcharstr()
call assert_equal(nr2char(kc - 64), ch)
endfor
" Test for the various Ctrl and Shift key combinations.
let keytests = [
\ [[0x10, 0x21], "\<S-Pageup>", 2],
\ [[0x11, 0x21], "\<C-Pageup>", 4],
\ [[0x10, 0x22], "\<S-PageDown>", 2],
\ [[0x11, 0x22], "\<C-PageDown>", 4],
\ [[0x10, 0x23], "\<S-End>", 0],
\ [[0x11, 0x23], "\<C-End>", 0],
\ [[0x10, 0x24], "\<S-Home>", 0],
\ [[0x11, 0x24], "\<C-Home>", 0],
\ [[0x10, 0x25], "\<S-Left>", 0],
\ [[0x11, 0x25], "\<C-Left>", 0],
\ [[0x10, 0x26], "\<S-Up>", 0],
\ [[0x11, 0x26], "\<C-Up>", 4],
\ [[0x10, 0x27], "\<S-Right>", 0],
\ [[0x11, 0x27], "\<C-Right>", 0],
\ [[0x10, 0x28], "\<S-Down>", 0],
\ [[0x11, 0x28], "\<C-Down>", 4],
\ [[0x11, 0x30], "\<C-0>", 4],
\ [[0x11, 0x31], "\<C-1>", 4],
\ [[0x11, 0x32], "\<C-2>", 4],
\ [[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, 0x70], "\<C-F1>", 4],
\ [[0x11, 0x71], "\<C-F2>", 4],
\ [[0x11, 0x72], "\<C-F3>", 4],
\ [[0x11, 0x73], "\<C-F4>", 4],
\ [[0x11, 0x74], "\<C-F5>", 4],
\ [[0x11, 0x75], "\<C-F6>", 4],
\ [[0x11, 0x76], "\<C-F7>", 4],
\ [[0x11, 0x77], "\<C-F8>", 4],
\ [[0x11, 0x78], "\<C-F9>", 4],
\ ]
for [kcodes, kstr, kmod] in keytests
call SendKeys(kcodes)
let ch = getcharstr()
let mod = getcharmod()
call assert_equal(kstr, ch, $"key = {kstr}")
call assert_equal(kmod, mod)
endfor
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -1500,6 +1500,12 @@ f_test_gui_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
rettv->v_type = VAR_BOOL; rettv->v_type = VAR_BOOL;
rettv->vval.v_number = FALSE; rettv->vval.v_number = FALSE;
if (sandbox != 0)
{
emsg(_(e_not_allowed_in_sandbox));
return;
}
if (check_for_string_arg(argvars, 0) == FAIL if (check_for_string_arg(argvars, 0) == FAIL
|| check_for_dict_arg(argvars, 1) == FAIL || check_for_dict_arg(argvars, 1) == FAIL
|| argvars[1].vval.v_dict == NULL) || argvars[1].vval.v_dict == NULL)
@ -1520,6 +1526,10 @@ f_test_gui_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict); rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict);
else if (STRCMP(event, "tabmenu") == 0) else if (STRCMP(event, "tabmenu") == 0)
rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict); rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict);
# ifdef FEAT_GUI_MSWIN
else if (STRCMP(event, "sendevent") == 0)
rettv->vval.v_number = test_gui_w32_sendevent(argvars[1].vval.v_dict);
# endif
else else
{ {
semsg(_(e_invalid_argument_str), event); semsg(_(e_invalid_argument_str), event);

View File

@ -735,6 +735,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 */
/**/
58,
/**/ /**/
57, 57,
/**/ /**/