[PATCH v3 0/2] MR4399: win32u: Support key message repeat for winewayland.
-- v3: win32u: Implement opt-in auto-repeat for WM_(SYS)KEYDOWN messages. winewayland.drv: Configure win32u keyboard repeat delay and speed. https://gitlab.winehq.org/wine/wine/-/merge_requests/4399
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/message.c | 8 ++++++++ dlls/win32u/ntuser_private.h | 3 +++ dlls/win32u/sysparams.c | 3 +++ dlls/winewayland.drv/wayland_keyboard.c | 16 +++++++++++++++- include/ntuser.h | 1 + 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d2909339983..e897ead329e 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -288,6 +288,7 @@ struct send_message_info }; static const INPUT_MESSAGE_SOURCE msg_source_unavailable = { IMDT_UNAVAILABLE, IMO_UNAVAILABLE }; +static BOOL keyboard_auto_repeat_enabled; /* flag for messages that contain pointers */ /* 32 messages per entry, messages 0..31 map to bits 0..31 */ @@ -508,6 +509,13 @@ static inline BOOL check_hwnd_filter( const MSG *msg, HWND hwnd_filter ) return (msg->hwnd == hwnd_filter || is_child( hwnd_filter, msg->hwnd )); } +BOOL set_keyboard_auto_repeat( BOOL enable ) +{ + BOOL enabled = keyboard_auto_repeat_enabled; + keyboard_auto_repeat_enabled = enable; + return enabled; +} + /*********************************************************************** * unpack_message * diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index b39e38db5d6..915aeb50bdc 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -242,6 +242,9 @@ HICON alloc_cursoricon_handle( BOOL is_icon ) DECLSPEC_HIDDEN; extern void free_dce( struct dce *dce, HWND hwnd ) DECLSPEC_HIDDEN; extern void invalidate_dce( WND *win, const RECT *extra_rect ) DECLSPEC_HIDDEN; +/* message.c */ +extern BOOL set_keyboard_auto_repeat( BOOL enable ) DECLSPEC_HIDDEN; + /* window.c */ HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN; void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index b134c5af680..dd409fe992f 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -6320,6 +6320,9 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) process_layout = arg; return TRUE; + case NtUserCallOneParam_SetKeyboardAutoRepeat: + return set_keyboard_auto_repeat( arg ); + /* temporary exports */ case NtUserGetDeskPattern: return get_entry( &entry_DESKPATTERN, 256, (WCHAR *)arg ); diff --git a/dlls/winewayland.drv/wayland_keyboard.c b/dlls/winewayland.drv/wayland_keyboard.c index 741dbfe1157..e3bcce443a8 100644 --- a/dlls/winewayland.drv/wayland_keyboard.c +++ b/dlls/winewayland.drv/wayland_keyboard.c @@ -219,7 +219,20 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int rate, int delay) { - FIXME("rate=%d delay=%d stub!\n", rate, delay); + UINT speed; + + TRACE("rate=%d delay=%d\n", rate, delay); + + /* Handle non-negative rate values, ignore invalid (negative) values. A + * rate of 0 disables repeat. */ + if (rate >= 80) speed = 31; + else if (rate >= 5) speed = rate * 400 / 1000 - 1; + else speed = 0; + + delay = max(0, min(3, round(delay / 250.0) - 1)); + NtUserSystemParametersInfo(SPI_SETKEYBOARDSPEED, speed, NULL, 0); + NtUserSystemParametersInfo(SPI_SETKEYBOARDDELAY, delay, NULL, 0); + NtUserCallOneParam(rate > 0, NtUserCallOneParam_SetKeyboardAutoRepeat); } static const struct wl_keyboard_listener keyboard_listener = { @@ -245,6 +258,7 @@ void wayland_keyboard_init(struct wl_keyboard *wl_keyboard) return; } + NtUserCallOneParam(TRUE, NtUserCallOneParam_SetKeyboardAutoRepeat); pthread_mutex_lock(&keyboard->mutex); keyboard->wl_keyboard = wl_keyboard; keyboard->xkb_context = xkb_context; diff --git a/include/ntuser.h b/include/ntuser.h index def89a82aff..b62c2e60538 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -878,6 +878,7 @@ enum NtUserCallOneParam_ReplyMessage, NtUserCallOneParam_SetCaretBlinkTime, NtUserCallOneParam_SetProcessDefaultLayout, + NtUserCallOneParam_SetKeyboardAutoRepeat, /* temporary exports */ NtUserGetDeskPattern, }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4399
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/message.c | 47 ++++++++++++++++++++++++++++++++++++ dlls/win32u/ntuser_private.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index e897ead329e..3c59eb8ee1d 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2292,6 +2292,22 @@ static void send_parent_notify( HWND hwnd, WORD event, WORD idChild, POINT pt ) } } + +static void handle_keyboard_repeat_message( HWND hwnd ) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + MSG *msg = &thread_info->key_repeat_msg; + UINT speed; + + msg->lParam = (msg->lParam & ~(LPARAM)0xffff) + ((msg->lParam + 1) & 0xffff); + + if (NtUserSystemParametersInfo( SPI_GETKEYBOARDSPEED, 0, &speed, 0 )) + NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_KEY_REPEAT, 400 / (speed + 1) ); + + NtUserPostMessage( hwnd, msg->message, msg->wParam, msg->lParam ); +} + + /*********************************************************************** * process_keyboard_message * @@ -2371,6 +2387,33 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter, if (ImmProcessKey( msg->hwnd, NtUserGetKeyboardLayout(0), msg->wParam, msg->lParam, 0 )) msg->wParam = VK_PROCESSKEY; + /* set/kill timers for key auto-repeat */ + if (remove && keyboard_auto_repeat_enabled) + { + struct user_thread_info *thread_info = get_user_thread_info(); + + switch (msg->message) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + UINT delay; + + if (msg->wParam == VK_PROCESSKEY) break; + + thread_info->key_repeat_msg = *msg; + if (NtUserSystemParametersInfo( SPI_GETKEYBOARDDELAY, 0, &delay, 0 )) + NtUserSetSystemTimer( msg->hwnd, SYSTEM_TIMER_KEY_REPEAT, (delay + 1) * 250 ); + break; + } + + case WM_KEYUP: + case WM_SYSKEYUP: + kill_system_timer( thread_info->key_repeat_msg.hwnd, SYSTEM_TIMER_KEY_REPEAT ); + break; + } + } + return TRUE; } @@ -3565,6 +3608,10 @@ LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ) case SYSTEM_TIMER_TRACK_MOUSE: update_mouse_tracking_info( msg->hwnd ); return 0; + + case SYSTEM_TIMER_KEY_REPEAT: + handle_keyboard_repeat_message( msg->hwnd ); + return 0; } } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 915aeb50bdc..72a2f24bc49 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -32,6 +32,9 @@ enum system_timer_id { SYSTEM_TIMER_TRACK_MOUSE = 0xfffa, SYSTEM_TIMER_CARET = 0xffff, + + /* not compatible with native */ + SYSTEM_TIMER_KEY_REPEAT = 0xfff0, }; struct rawinput_thread_data @@ -126,6 +129,7 @@ struct user_thread_info struct received_message_info *receive_info; /* Message being currently received */ struct user_key_state_info *key_state; /* Cache of global key state */ struct imm_thread_data *imm_thread_data; /* IMM thread data */ + MSG key_repeat_msg; /* Last WM_KEYDOWN message to repeat */ HKL kbd_layout; /* Current keyboard layout */ UINT kbd_layout_id; /* Current keyboard layout ID */ struct rawinput_thread_data *rawinput; /* RawInput thread local data / buffer */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4399
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=140115 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/win32u/ntuser_private.h:242 Task: Patch failed to apply === debian11b (build log) === error: patch failed: dlls/win32u/ntuser_private.h:242 Task: Patch failed to apply
Fwiw @afrantzis, unless ofc if you don't think you have time for it, it'd be nice if you could request access to the project (on the https://gitlab.winehq.org/wine/wine page), so that you can be added as reviewer and approve winewayland merge requests. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4399#note_53114
On Wed Nov 22 07:43:44 2023 +0000, Rémi Bernon wrote:
Fwiw @afrantzis, unless ofc if you don't think you have time for it, it'd be nice if you could request access to the project (on the https://gitlab.winehq.org/wine/wine page), so that you can be added as reviewer and approve winewayland merge requests. Thanks, I have requested access.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/4399#note_53270
This merge request was approved by Alexandros Frantzis. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4399
participants (3)
-
Alexandros Frantzis (@afrantzis) -
Marvin -
Rémi Bernon