[client] Fix keyboard input

properly pass key repeat events to the server.
This commit is contained in:
Armin Novak 2022-12-12 10:42:40 +01:00 committed by David Fort
parent 7fd6278bc6
commit 2b49047c34
3 changed files with 43 additions and 14 deletions

View File

@ -340,7 +340,7 @@ BOOL wlf_handle_key(freerdp* instance, const UwacKeyEvent* ev)
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
return TRUE;
return freerdp_input_send_keyboard_event_ex(input, ev->pressed, rdp_scancode);
return freerdp_input_send_keyboard_event_ex(input, ev->pressed, ev->repeated, rdp_scancode);
}
BOOL wlf_handle_ungrab_key(freerdp* instance, const UwacKeyEvent* ev)

View File

@ -64,8 +64,11 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
wfContext* wfc = NULL;
DWORD rdp_scancode;
BOOL keystate;
rdpInput* input;
PKBDLLHOOKSTRUCT p;
static BOOL keystates[256] = { 0 };
DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X", g_focus_hWnd, nCode, wParam);
if (g_flipping_in)
@ -110,6 +113,20 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
input = wfc->common.context.input;
rdp_scancode = MAKE_RDP_SCANCODE((BYTE)p->scanCode, p->flags & LLKHF_EXTENDED);
keystate = keystates[p->scanCode & 0xFF];
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
keystates[p->scanCode & 0xFF] = TRUE;
break;
case WM_KEYUP:
case WM_SYSKEYUP:
default:
keystates[p->scanCode & 0xFF] = FALSE;
break;
}
DEBUG_KBD("keydown %d scanCode 0x%08lX flags 0x%08lX vkCode 0x%08lX",
(wParam == WM_KEYDOWN), p->scanCode, p->flags, p->vkCode);
@ -138,10 +155,14 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
if (wParam == WM_KEYDOWN)
{
DEBUG_KBD("Pause, sent as Ctrl+NumLock");
freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_LCONTROL);
freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_NUMLOCK);
freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_LCONTROL);
freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_NUMLOCK);
freerdp_input_send_keyboard_event_ex(input, TRUE, FALSE,
RDP_SCANCODE_LCONTROL);
freerdp_input_send_keyboard_event_ex(input, TRUE, FALSE,
RDP_SCANCODE_NUMLOCK);
freerdp_input_send_keyboard_event_ex(input, FALSE, FALSE,
RDP_SCANCODE_LCONTROL);
freerdp_input_send_keyboard_event_ex(input, FALSE, FALSE,
RDP_SCANCODE_NUMLOCK);
}
else
{
@ -156,7 +177,8 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
rdp_scancode = RDP_SCANCODE_RSHIFT;
}
freerdp_input_send_keyboard_event_ex(input, !(p->flags & LLKHF_UP), rdp_scancode);
freerdp_input_send_keyboard_event_ex(input, !(p->flags & LLKHF_UP), keystate,
rdp_scancode);
if (p->vkCode == VK_NUMLOCK || p->vkCode == VK_CAPITAL || p->vkCode == VK_SCROLL ||
p->vkCode == VK_KANA)
@ -165,6 +187,8 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
else
return 1;
break;
default:
break;
}
}

View File

@ -62,7 +62,7 @@ BOOL xf_keyboard_update_modifier_map(xfContext* xfc)
return xfc->modifierMap != NULL;
}
static void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* ev);
static void xf_keyboard_send_key(xfContext* xfc, BOOL down, BOOL repeat, const XKeyEvent* ev);
static BOOL xf_sync_kbd_state(xfContext* xfc)
{
@ -175,18 +175,21 @@ void xf_keyboard_free(xfContext* xfc)
void xf_keyboard_key_press(xfContext* xfc, const XKeyEvent* event, KeySym keysym)
{
BOOL last;
WINPR_ASSERT(xfc);
WINPR_ASSERT(event);
if (event->keycode < 8)
return;
last = xfc->KeyboardState[event->keycode];
xfc->KeyboardState[event->keycode] = TRUE;
if (xf_keyboard_handle_special_keys(xfc, keysym))
return;
xf_keyboard_send_key(xfc, TRUE, event);
xf_keyboard_send_key(xfc, TRUE, last, event);
}
void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keysym)
@ -197,9 +200,10 @@ void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keys
if (event->keycode < 8)
return;
BOOL last = xfc->KeyboardState[event->keycode];
xfc->KeyboardState[event->keycode] = FALSE;
xf_keyboard_handle_special_keys_release(xfc, keysym);
xf_keyboard_send_key(xfc, FALSE, event);
xf_keyboard_send_key(xfc, FALSE, last, event);
}
void xf_keyboard_release_all_keypress(xfContext* xfc)
@ -218,10 +222,11 @@ void xf_keyboard_release_all_keypress(xfContext* xfc)
// release tab before releasing the windows key.
// this stops the start menu from opening on unfocus event.
if (rdp_scancode == RDP_SCANCODE_LWIN)
freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE,
freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, FALSE,
RDP_SCANCODE_TAB);
freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, rdp_scancode);
freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, FALSE,
rdp_scancode);
xfc->KeyboardState[keycode] = FALSE;
}
}
@ -234,7 +239,7 @@ BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym)
return xfc->KeyboardState[keycode];
}
void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event)
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BOOL repeat, const XKeyEvent* event)
{
DWORD rdp_scancode;
rdpInput* input;
@ -290,7 +295,7 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event)
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", event->keycode);
else
freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode);
freerdp_input_send_keyboard_event_ex(input, down, repeat, rdp_scancode);
}
else
freerdp_input_send_unicode_keyboard_event(input, down ? KBD_FLAGS_RELEASE : 0,
@ -299,7 +304,7 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event)
else if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", event->keycode);
else
freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode);
freerdp_input_send_keyboard_event_ex(input, down, repeat, rdp_scancode);
if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE))
{