[PATCH 0/2] MR3624: win32u: Implement cross-process scrollbar queries.
From: Esme Povirk <esme(a)codeweavers.com> --- dlls/win32u/message.c | 11 +++++++++++ dlls/win32u/scroll.c | 5 ++++- dlls/win32u/win32u_private.h | 1 + include/ntuser.h | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d15f9af3f9f..e2a1a2870df 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -721,6 +721,7 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa if (!get_buffer_space( buffer, sizeof(SCROLLINFO), size )) return FALSE; break; case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO: if (!get_buffer_space( buffer, sizeof(SCROLLBARINFO), size )) return FALSE; break; case EM_GETSEL: @@ -1121,6 +1122,7 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara push_data( data, (SCROLLINFO *)lparam, sizeof(SCROLLINFO) ); return sizeof(SCROLLINFO); case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO: { const SCROLLBARINFO *info = (const SCROLLBARINFO *)lparam; size_t size = min( info->cbSize, sizeof(SCROLLBARINFO) ); @@ -1357,6 +1359,10 @@ static void pack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, case SBM_GETSCROLLINFO: push_data( data, (SCROLLINFO *)lparam, sizeof(SCROLLINFO) ); break; + case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO: + push_data( data, (SCROLLBARINFO *)lparam, sizeof(SCROLLBARINFO) ); + break; case EM_GETRECT: case LB_GETITEMRECT: case CB_GETDROPPEDCONTROLRECT: @@ -1498,6 +1504,7 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, memcpy( (SCROLLINFO *)lparam, buffer, min( sizeof(SCROLLINFO), size )); break; case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO: memcpy( (SCROLLBARINFO *)lparam, buffer, min( sizeof(SCROLLBARINFO), size )); break; case EM_GETRECT: @@ -1698,6 +1705,7 @@ size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, size = sizeof(SCROLLINFO); break; case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO: size = sizeof(SCROLLBARINFO); break; case EM_GETSEL: @@ -1932,6 +1940,7 @@ static void copy_user_result( void *buffer, size_t size, LRESULT result, UINT me copy_size = sizeof(SCROLLINFO); break; case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO: copy_size = sizeof(SCROLLBARINFO); break; case EM_GETSEL: @@ -2102,6 +2111,8 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR case WM_WINE_UPDATEWINDOWSTATE: update_window_state( hwnd ); return 0; + case WM_WINE_GETSCROLLBARINFO: + return get_scroll_bar_info( hwnd, (LONG)wparam, (SCROLLBARINFO *)lparam ); default: if (msg >= WM_WINE_FIRST_DRIVER_MSG && msg <= WM_WINE_LAST_DRIVER_MSG) return user_driver->pWindowMessage( hwnd, msg, wparam, lparam ); diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index 19a9a1379f4..65491f25c5b 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -1048,7 +1048,7 @@ done: return ret; /* Return current position */ } -static BOOL get_scroll_bar_info( HWND hwnd, LONG id, SCROLLBARINFO *info ) +BOOL get_scroll_bar_info( HWND hwnd, LONG id, SCROLLBARINFO *info ) { struct scroll_info *scroll; int bar, dummy; @@ -1067,6 +1067,9 @@ static BOOL get_scroll_bar_info( HWND hwnd, LONG id, SCROLLBARINFO *info ) /* handle invalid data structure */ if (info->cbSize != sizeof(*info)) return FALSE; + if (bar != SB_CTL && !is_current_thread_window( hwnd )) + return send_message( hwnd, WM_WINE_GETSCROLLBARINFO, (WPARAM)id, (LPARAM)info ); + get_scroll_bar_rect( hwnd, bar, &info->rcScrollBar, &dummy, &info->dxyLineButton, &info->xyThumbTop ); /* rcScrollBar needs to be in screen coordinates */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 6380a0808c8..447b2a85b8e 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -151,6 +151,7 @@ extern BOOL rawinput_device_get_usages( HANDLE handle, USHORT *usage_page, USHOR /* scroll.c */ extern void draw_nc_scrollbar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ) DECLSPEC_HIDDEN; +extern BOOL get_scroll_bar_info( HWND hwnd, LONG id, SCROLLBARINFO *info ) DECLSPEC_HIDDEN; extern BOOL get_scroll_info( HWND hwnd, INT bar, SCROLLINFO *info ) DECLSPEC_HIDDEN; extern void handle_scroll_event( HWND hwnd, INT bar, UINT msg, POINT pt ) DECLSPEC_HIDDEN; extern LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, diff --git a/include/ntuser.h b/include/ntuser.h index b873512dbd1..b5ceadb4e54 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -480,6 +480,7 @@ enum wine_internal_message WM_WINE_CLIPCURSOR, WM_WINE_SETCURSOR, WM_WINE_UPDATEWINDOWSTATE, + WM_WINE_GETSCROLLBARINFO, WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */ WM_WINE_LAST_DRIVER_MSG = 0x80001fff }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3624
From: Esme Povirk <esme(a)codeweavers.com> --- dlls/win32u/message.c | 8 ++++++++ dlls/win32u/scroll.c | 8 +++++++- include/ntuser.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index e2a1a2870df..3958afcfebe 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -718,6 +718,7 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa minsize = sizeof(SCROLLINFO); break; case SBM_GETSCROLLINFO: + case WM_WINE_GETSCROLLINFO: if (!get_buffer_space( buffer, sizeof(SCROLLINFO), size )) return FALSE; break; case SBM_GETSCROLLBARINFO: @@ -1119,6 +1120,7 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara push_data( data, (SCROLLINFO *)lparam, sizeof(SCROLLINFO) ); return 0; case SBM_GETSCROLLINFO: + case WM_WINE_GETSCROLLINFO: push_data( data, (SCROLLINFO *)lparam, sizeof(SCROLLINFO) ); return sizeof(SCROLLINFO); case SBM_GETSCROLLBARINFO: @@ -1357,6 +1359,7 @@ static void pack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, break; } case SBM_GETSCROLLINFO: + case WM_WINE_GETSCROLLINFO: push_data( data, (SCROLLINFO *)lparam, sizeof(SCROLLINFO) ); break; case SBM_GETSCROLLBARINFO: @@ -1501,6 +1504,7 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, } break; case SBM_GETSCROLLINFO: + case WM_WINE_GETSCROLLINFO: memcpy( (SCROLLINFO *)lparam, buffer, min( sizeof(SCROLLINFO), size )); break; case SBM_GETSCROLLBARINFO: @@ -1702,6 +1706,7 @@ size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, break; case SBM_SETSCROLLINFO: case SBM_GETSCROLLINFO: + case WM_WINE_GETSCROLLINFO: size = sizeof(SCROLLINFO); break; case SBM_GETSCROLLBARINFO: @@ -1937,6 +1942,7 @@ static void copy_user_result( void *buffer, size_t size, LRESULT result, UINT me break; case SBM_SETSCROLLINFO: case SBM_GETSCROLLINFO: + case WM_WINE_GETSCROLLINFO: copy_size = sizeof(SCROLLINFO); break; case SBM_GETSCROLLBARINFO: @@ -2113,6 +2119,8 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return 0; case WM_WINE_GETSCROLLBARINFO: return get_scroll_bar_info( hwnd, (LONG)wparam, (SCROLLBARINFO *)lparam ); + case WM_WINE_GETSCROLLINFO: + return get_scroll_info( hwnd, (int)wparam, (SCROLLINFO *)lparam ); default: if (msg >= WM_WINE_FIRST_DRIVER_MSG && msg <= WM_WINE_LAST_DRIVER_MSG) return user_driver->pWindowMessage( hwnd, msg, wparam, lparam ); diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index 65491f25c5b..e3ed1350b09 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -892,7 +892,13 @@ BOOL get_scroll_info( HWND hwnd, int bar, SCROLLINFO *info ) struct scroll_info *scroll; /* handle invalid data structure */ - if (!validate_scroll_info( info ) || !(scroll = get_scroll_info_ptr( hwnd, bar, FALSE ))) + if (!validate_scroll_info( info )) + return FALSE; + + if (bar != SB_CTL && !is_current_thread_window( hwnd )) + return send_message( hwnd, WM_WINE_GETSCROLLINFO, (WPARAM)bar, (LPARAM)info ); + + if (!(scroll = get_scroll_info_ptr( hwnd, bar, FALSE ))) return FALSE; /* fill in the desired scroll info structure */ diff --git a/include/ntuser.h b/include/ntuser.h index b5ceadb4e54..4aa35e62d0e 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -481,6 +481,7 @@ enum wine_internal_message WM_WINE_SETCURSOR, WM_WINE_UPDATEWINDOWSTATE, WM_WINE_GETSCROLLBARINFO, + WM_WINE_GETSCROLLINFO, WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */ WM_WINE_LAST_DRIVER_MSG = 0x80001fff }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3624
Jacek Caban (@jacek) commented about dlls/win32u/message.c:
case SBM_GETSCROLLINFO: push_data( data, (SCROLLINFO *)lparam, sizeof(SCROLLINFO) ); break; + case SBM_GETSCROLLBARINFO:
This is a separated change. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43004
Jacek Caban (@jacek) commented about dlls/win32u/message.c:
size = sizeof(SCROLLINFO); break; case SBM_GETSCROLLBARINFO: + case WM_WINE_GETSCROLLBARINFO:
You don't need user message packing for internal messages, they should never be dispatched to client. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43005
I wonder if we should scroll info to server instead of using internal messages. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43006
On Tue Aug 22 14:28:18 2023 +0000, Jacek Caban wrote:
I wonder if we should scroll info to server instead of using internal messages. Possibly. In my testing, SetScrollInfo doesn't seem to work cross-process on Windows, so the information could probably just be mirrored on the server.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43035
On Tue Aug 22 09:30:44 2023 +0000, Jacek Caban wrote:
You don't need user message packing for internal messages, they should never be dispatched to client. How would you suggest getting the information to the internal message handler?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43036
On Tue Aug 22 14:29:45 2023 +0000, Esme Povirk wrote:
How would you suggest getting the information to the internal message handler? I'm not sure what you mean, do you somehow see `user_message_size` and `pack_user_message` used for those messages? For internal messages `pack_message` and `unpack_message` should be enough.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43041
On Tue Aug 22 14:56:39 2023 +0000, Jacek Caban wrote:
I'm not sure what you mean, do you somehow see `user_message_size` and `pack_user_message` used for those messages? For internal messages `pack_message` and `unpack_message` should be enough. I may be confused about the distinction between these functions.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43042
On Tue Aug 22 14:28:18 2023 +0000, Esme Povirk wrote:
Possibly. In my testing, SetScrollInfo doesn't seem to work cross-process on Windows, so the information could probably just be mirrored on the server. I can test whether it's possible to query this on Windows when the other thread isn't pumping messages.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43046
On Tue Aug 22 16:18:04 2023 +0000, Esme Povirk wrote:
I can test whether it's possible to query this on Windows when the other thread isn't pumping messages. Testing showed that GetScrollBarInfo, at least, does not require a message pump on Windows.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3624#note_43059
participants (3)
-
Esme Povirk -
Esme Povirk (@madewokherd) -
Jacek Caban (@jacek)