It's not completely clear what exactly it was doing differently from win32u, but keeping the captions within the work area is probably fine for win32u, and de-duplicating this code is probably a good thing and makes later changes for DPI-based virtual display settings easier.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/defwnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index c8b9897644c..f21dd079fe8 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -822,7 +822,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) HMONITOR newmon; MONITORINFO info;
- if ((newmon = monitor_from_point( pt, MONITOR_DEFAULTTONULL, get_thread_dpi() ))) + if ((newmon = monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ))) mon = newmon;
info.cbSize = sizeof(info);
From: Rémi Bernon rbernon@codeweavers.com
So the constraints apply to the resize tracking point, not to the cursor itself. This makes the constraints easier to follow: regardless of where the cursor is, we keep the resized point within the maximum window size rect and within the monitor work area. --- dlls/win32u/defwnd.c | 46 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index f21dd079fe8..f7cf910ca3d 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -668,7 +668,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) UINT hittest = wparam & 0x0f; UINT syscommand = wparam & 0xfff0; UINT style = get_window_long( hwnd, GWL_STYLE ); - POINT capture_point, pt; + POINT capture_point, pt, offset = {0}; MINMAXINFO minmax; HMONITOR mon = 0; HWND parent; @@ -729,34 +729,35 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam )
if (on_left_border( hittest )) { - mouse_rect.left = max( mouse_rect.left, - sizing_rect.right - minmax.ptMaxTrackSize.x + capture_point.x - sizing_rect.left ); - mouse_rect.right = min( mouse_rect.right, - sizing_rect.right - minmax.ptMinTrackSize.x + capture_point.x - sizing_rect.left ); + offset.x = capture_point.x - sizing_rect.left; + mouse_rect.left = max( mouse_rect.left, sizing_rect.right - minmax.ptMaxTrackSize.x ); + mouse_rect.right = min( mouse_rect.right, sizing_rect.right - minmax.ptMinTrackSize.x ); } else if (on_right_border( hittest )) { - mouse_rect.left = max( mouse_rect.left, - sizing_rect.left + minmax.ptMinTrackSize.x + capture_point.x - sizing_rect.right ); - mouse_rect.right = min( mouse_rect.right, - sizing_rect.left + minmax.ptMaxTrackSize.x + capture_point.x - sizing_rect.right ); + offset.x = capture_point.x - sizing_rect.right; + mouse_rect.left = max( mouse_rect.left, sizing_rect.left + minmax.ptMinTrackSize.x ); + mouse_rect.right = min( mouse_rect.right, sizing_rect.left + minmax.ptMaxTrackSize.x ); }
if (on_top_border( hittest )) { - mouse_rect.top = max( mouse_rect.top, - sizing_rect.bottom - minmax.ptMaxTrackSize.y + capture_point.y - sizing_rect.top ); - mouse_rect.bottom = min( mouse_rect.bottom, - sizing_rect.bottom - minmax.ptMinTrackSize.y + capture_point.y - sizing_rect.top ); + offset.y = capture_point.y - sizing_rect.top; + mouse_rect.top = max( mouse_rect.top, sizing_rect.bottom - minmax.ptMaxTrackSize.y ); + mouse_rect.bottom = min( mouse_rect.bottom, sizing_rect.bottom - minmax.ptMinTrackSize.y ); } else if (on_bottom_border( hittest )) { - mouse_rect.top = max( mouse_rect.top, - sizing_rect.top + minmax.ptMinTrackSize.y + capture_point.y - sizing_rect.bottom ); - mouse_rect.bottom = min( mouse_rect.bottom, - sizing_rect.top + minmax.ptMaxTrackSize.y + capture_point.y - sizing_rect.bottom ); + offset.y = capture_point.y - sizing_rect.bottom; + mouse_rect.top = max( mouse_rect.top, sizing_rect.top + minmax.ptMinTrackSize.y ); + mouse_rect.bottom = min( mouse_rect.bottom, sizing_rect.top + minmax.ptMaxTrackSize.y ); }
+ capture_point.x -= offset.x; + capture_point.y -= offset.y; + pt.x -= offset.x; + pt.y -= offset.y; + /* Retrieve a default cache DC (without using the window style) */ hdc = NtUserGetDCEx( parent, 0, DCX_CACHE );
@@ -791,15 +792,16 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) if (!(NtUserGetKeyState( VK_LBUTTON ) & 0x8000)) { DWORD last_pos = NtUserGetThreadInfo()->message_pos; - pt.x = ((int)(short)LOWORD( last_pos )); - pt.y = ((int)(short)HIWORD( last_pos )); + pt.x = ((int)(short)LOWORD( last_pos )) - offset.x; + pt.y = ((int)(short)HIWORD( last_pos )) - offset.y; break; }
continue; /* We are not interested in other messages */ }
- pt = msg.pt; + pt.x = msg.pt.x - offset.x; + pt.y = msg.pt.y - offset.y;
if (msg.message == WM_KEYDOWN) { @@ -847,7 +849,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) draw_moving_frame( parent, hdc, &sizing_rect, thickframe ); }
- if (msg.message == WM_KEYDOWN) NtUserSetCursorPos( pt.x, pt.y ); + if (msg.message == WM_KEYDOWN) NtUserSetCursorPos( offset.x + pt.x, offset.x + pt.y ); else { if (!drag_full_windows) draw_moving_frame( parent, hdc, &sizing_rect, thickframe ); @@ -926,7 +928,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) if (is_iconic(hwnd) && !moved && (style & WS_SYSMENU)) { /* Single click brings up the system menu when iconized */ - send_message( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x, pt.y) ); + send_message( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, MAKELONG(offset.x + pt.x, offset.y + pt.y) ); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/defwnd.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index f7cf910ca3d..44d7d4138d3 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -667,12 +667,12 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) RECT sizing_rect, mouse_rect, orig_rect; UINT hittest = wparam & 0x0f; UINT syscommand = wparam & 0xfff0; - UINT style = get_window_long( hwnd, GWL_STYLE ); + UINT style = get_window_long( hwnd, GWL_STYLE ), ex_style = get_window_long( hwnd, GWL_EXSTYLE ); POINT capture_point, pt, offset = {0}; + LONG caption_height = 0; MINMAXINFO minmax; HMONITOR mon = 0; HWND parent; - UINT dpi; HDC hdc; MSG msg;
@@ -709,22 +709,25 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) } }
+ SetRect( &sizing_rect, 0, 0, 0, 0 ); + if (adjust_window_rect( &sizing_rect, style, FALSE, ex_style, get_thread_dpi() )) caption_height = -sizing_rect.top; + if (on_bottom_border( hittest )) caption_height = 0; + minmax = get_min_max_info( hwnd ); - dpi = get_thread_dpi(); - get_window_rect_rel( hwnd, COORDS_PARENT, &sizing_rect, dpi ); + get_window_rect_rel( hwnd, COORDS_PARENT, &sizing_rect, get_thread_dpi() ); orig_rect = sizing_rect; if (style & WS_CHILD) { parent = get_parent( hwnd ); get_client_rect( parent, &mouse_rect, get_thread_dpi() ); - map_window_points( parent, 0, (POINT *)&mouse_rect, 2, dpi ); - map_window_points( parent, 0, (POINT *)&sizing_rect, 2, dpi ); + map_window_points( parent, 0, (POINT *)&mouse_rect, 2, get_thread_dpi() ); + map_window_points( parent, 0, (POINT *)&sizing_rect, 2, get_thread_dpi() ); } else { parent = 0; mouse_rect = get_virtual_screen_rect( get_thread_dpi() ); - mon = monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, dpi ); + mon = monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); }
if (on_left_border( hittest )) @@ -752,6 +755,10 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) mouse_rect.top = max( mouse_rect.top, sizing_rect.top + minmax.ptMinTrackSize.y ); mouse_rect.bottom = min( mouse_rect.bottom, sizing_rect.top + minmax.ptMaxTrackSize.y ); } + else + { + offset.y = capture_point.y - sizing_rect.top; + }
capture_point.x -= offset.x; capture_point.y -= offset.y; @@ -817,7 +824,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) pt.x = max( pt.x, mouse_rect.left ); pt.x = min( pt.x, mouse_rect.right - 1 ); pt.y = max( pt.y, mouse_rect.top ); - pt.y = min( pt.y, mouse_rect.bottom - 1 ); + pt.y = min( pt.y, mouse_rect.bottom - 1 - caption_height );
if (!parent) { @@ -833,7 +840,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) pt.x = max( pt.x, info.rcWork.left ); pt.x = min( pt.x, info.rcWork.right - 1 ); pt.y = max( pt.y, info.rcWork.top ); - pt.y = min( pt.y, info.rcWork.bottom - 1 ); + pt.y = min( pt.y, info.rcWork.bottom - 1 - caption_height ); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/window.c | 230 -------------------------------------- 1 file changed, 230 deletions(-)
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 824475a9b34..693dfc50220 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1094,230 +1094,6 @@ static void set_app_icon(void) }
-/********************************************************************** - * set_capture_window_for_move - */ -static BOOL set_capture_window_for_move(HWND hwnd) -{ - HWND previous = 0; - BOOL ret; - - SERVER_START_REQ(set_capture_window) - { - req->handle = wine_server_user_handle(hwnd); - req->flags = CAPTURE_MOVESIZE; - if ((ret = !wine_server_call_err(req))) - { - previous = wine_server_ptr_handle(reply->previous); - hwnd = wine_server_ptr_handle(reply->full_handle); - } - } - SERVER_END_REQ; - - if (ret) - { - macdrv_SetCapture(hwnd, GUI_INMOVESIZE); - - if (previous && previous != hwnd) - send_message(previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd); - } - return ret; -} - - -static HMONITOR monitor_from_point(POINT pt, UINT flags) -{ - RECT rect; - - SetRect(&rect, pt.x, pt.y, pt.x + 1, pt.y + 1); - return NtUserMonitorFromRect(&rect, flags); -} - - -/*********************************************************************** - * move_window - * - * Based on user32's WINPOS_SysCommandSizeMove() specialized just for - * moving top-level windows and enforcing Mac-style constraints like - * keeping the top of the window within the work area. - */ -static LRESULT move_window(HWND hwnd, WPARAM wparam) -{ - UINT dpi = get_win_monitor_dpi(hwnd); - MSG msg; - RECT origRect, movedRect, desktopRect; - int hittest = (int)(wparam & 0x0f); - POINT capturePoint; - LONG style = NtUserGetWindowLongW(hwnd, GWL_STYLE); - BOOL moved = FALSE; - DWORD dwPoint = NtUserGetThreadInfo()->message_pos; - INT captionHeight; - HMONITOR mon = 0; - MONITORINFO info; - - if ((style & (WS_MINIMIZE | WS_MAXIMIZE)) || !IsWindowVisible(hwnd)) return -1; - if (hittest && hittest != HTCAPTION) return -1; - - capturePoint.x = (short)LOWORD(dwPoint); - capturePoint.y = (short)HIWORD(dwPoint); - NtUserClipCursor(NULL); - - TRACE("hwnd %p hittest %d, pos %d,%d\n", hwnd, hittest, (int)capturePoint.x, (int)capturePoint.y); - - origRect.left = origRect.right = origRect.top = origRect.bottom = 0; - if (NtUserAdjustWindowRect(&origRect, style, FALSE, NtUserGetWindowLongW(hwnd, GWL_EXSTYLE), dpi)) - captionHeight = -origRect.top; - else - captionHeight = 0; - - NtUserGetWindowRect(hwnd, &origRect, get_win_monitor_dpi(hwnd)); - movedRect = origRect; - - if (!hittest) - { - /* Move pointer to the center of the caption */ - RECT rect = origRect; - - /* Note: to be exactly centered we should take the different types - * of border into account, but it shouldn't make more than a few pixels - * of difference so let's not bother with that */ - rect.top += NtUserGetSystemMetrics(SM_CYBORDER); - if (style & WS_SYSMENU) - rect.left += NtUserGetSystemMetrics(SM_CXSIZE) + 1; - if (style & WS_MINIMIZEBOX) - rect.right -= NtUserGetSystemMetrics(SM_CXSIZE) + 1; - if (style & WS_MAXIMIZEBOX) - rect.right -= NtUserGetSystemMetrics(SM_CXSIZE) + 1; - capturePoint.x = (rect.right + rect.left) / 2; - capturePoint.y = rect.top + NtUserGetSystemMetrics(SM_CYSIZE)/2; - - NtUserSetCursorPos(capturePoint.x, capturePoint.y); - send_message(hwnd, WM_SETCURSOR, (WPARAM)hwnd, MAKELONG(HTCAPTION, WM_MOUSEMOVE)); - } - - desktopRect = rect_from_cgrect(macdrv_get_desktop_rect()); - mon = monitor_from_point(capturePoint, MONITOR_DEFAULTTONEAREST); - info.cbSize = sizeof(info); - if (mon && !NtUserGetMonitorInfo(mon, &info)) - mon = 0; - - /* repaint the window before moving it around */ - NtUserRedrawWindow(hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN); - - send_message(hwnd, WM_ENTERSIZEMOVE, 0, 0); - set_capture_window_for_move(hwnd); - - while(1) - { - POINT pt; - int dx = 0, dy = 0; - HMONITOR newmon; - - if (!NtUserGetMessage(&msg, 0, 0, 0)) break; - if (NtUserCallMsgFilter(&msg, MSGF_SIZE)) continue; - - /* Exit on button-up, Return, or Esc */ - if (msg.message == WM_LBUTTONUP || - (msg.message == WM_KEYDOWN && (msg.wParam == VK_RETURN || msg.wParam == VK_ESCAPE))) - break; - - if (msg.message != WM_KEYDOWN && msg.message != WM_MOUSEMOVE) - { - NtUserTranslateMessage(&msg, 0); - NtUserDispatchMessage(&msg); - continue; /* We are not interested in other messages */ - } - - pt = msg.pt; - - if (msg.message == WM_KEYDOWN) switch(msg.wParam) - { - case VK_UP: pt.y -= 8; break; - case VK_DOWN: pt.y += 8; break; - case VK_LEFT: pt.x -= 8; break; - case VK_RIGHT: pt.x += 8; break; - } - - pt.x = max(pt.x, desktopRect.left); - pt.x = min(pt.x, desktopRect.right - 1); - pt.y = max(pt.y, desktopRect.top); - pt.y = min(pt.y, desktopRect.bottom - 1); - - if ((newmon = monitor_from_point(pt, MONITOR_DEFAULTTONULL)) && newmon != mon) - { - if (NtUserGetMonitorInfo(newmon, &info)) - mon = newmon; - else - mon = 0; - } - - if (mon) - { - /* wineserver clips the cursor position to the virtual desktop rect but, - if the display configuration is non-rectangular, that could still - leave the logical cursor position outside of any display. The window - could keep moving as you push the cursor against a display edge, even - though the visible cursor doesn't keep moving. The following keeps - the window movement in sync with the visible cursor. */ - pt.x = max(pt.x, info.rcMonitor.left); - pt.x = min(pt.x, info.rcMonitor.right - 1); - pt.y = max(pt.y, info.rcMonitor.top); - pt.y = min(pt.y, info.rcMonitor.bottom - 1); - - /* Assuming that dx will be calculated below as pt.x - capturePoint.x, - dy will be pt.y - capturePoint.y, and movedRect will be offset by those, - we want to enforce these constraints: - movedRect.left + dx < info.rcWork.right - movedRect.right + dx > info.rcWork.left - movedRect.top + captionHeight + dy < info.rcWork.bottom - movedRect.bottom + dy > info.rcWork.top - movedRect.top + dy >= info.rcWork.top - The first four keep at least one edge barely in the work area. - The last keeps the top (i.e. the title bar) in the work area. - The fourth is redundant with the last, so can be ignored. - - Substituting for dx and dy and rearranging gives us... - */ - pt.x = min(pt.x, info.rcWork.right - 1 + capturePoint.x - movedRect.left); - pt.x = max(pt.x, info.rcWork.left + 1 + capturePoint.x - movedRect.right); - pt.y = min(pt.y, info.rcWork.bottom - 1 + capturePoint.y - movedRect.top - captionHeight); - pt.y = max(pt.y, info.rcWork.top + capturePoint.y - movedRect.top); - } - - dx = pt.x - capturePoint.x; - dy = pt.y - capturePoint.y; - - if (dx || dy) - { - moved = TRUE; - - if (msg.message == WM_KEYDOWN) NtUserSetCursorPos(pt.x, pt.y); - else - { - OffsetRect(&movedRect, dx, dy); - capturePoint = pt; - - send_message(hwnd, WM_MOVING, 0, (LPARAM)&movedRect); - set_window_pos(hwnd, 0, movedRect.left, movedRect.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); - } - } - } - - set_capture_window_for_move(0); - - send_message(hwnd, WM_EXITSIZEMOVE, 0, 0); - send_message(hwnd, WM_SETVISIBLE, TRUE, 0L); - - /* if the move is canceled, restore the previous position */ - if (moved && msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) - { - set_window_pos(hwnd, 0, origRect.left, origRect.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); - } - - return 0; -} - - /*********************************************************************** * perform_window_command */ @@ -1677,12 +1453,6 @@ LRESULT macdrv_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) ret = 0; }
- if (command == SC_MOVE) - { - release_win_data(data); - return move_window(hwnd, wparam); - } - done: release_win_data(data); return ret;
Fwiw as far as I can tell this code was even only used for non-decorated windows. Windows with host window manager frame are moved/resized by the host, as on Linux.