From d04e148d1c49975de0803299055a47eedbc94487 Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Thu, 16 Feb 2023 19:33:37 +0100 Subject: [PATCH] [NTUSER] Optimize Window Snap Disabling (#5061) --- win32ss/user/ntuser/defwnd.c | 48 +++++++++++---------------- win32ss/user/ntuser/nonclient.c | 59 ++++++++++++++------------------- 2 files changed, 44 insertions(+), 63 deletions(-) diff --git a/win32ss/user/ntuser/defwnd.c b/win32ss/user/ntuser/defwnd.c index 05a1db08877..81ece247b78 100644 --- a/win32ss/user/ntuser/defwnd.c +++ b/win32ss/user/ntuser/defwnd.c @@ -404,18 +404,18 @@ UserPaintCaption(PWND pWnd, INT Flags) { if (pWnd->state & WNDS_HASCAPTION && pWnd->head.pti->MessageQueue == gpqForeground) Flags |= DC_ACTIVE; - /* + /* * When themes are not enabled we can go on and paint the non client area. * However if we do that with themes enabled we will draw a classic frame. * This is solved by sending a themes specific message to notify the themes - * engine that the caption needs to be redrawn + * engine that the caption needs to be redrawn. */ if (gpsi->dwSRVIFlags & SRVINFO_APIHOOK) { - /* + /* * This will cause uxtheme to either paint the themed caption or call * RealUserDrawCaption in order to draw the classic caption when themes - * are disabled but the themes service is enabled + * are disabled but the themes service is enabled. */ TRACE("UDCB Flags %08x\n", Flags); co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0); @@ -440,7 +440,7 @@ DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam) HICON hIcon, hIconSmall, hIconOld; if ( wParam > ICON_SMALL2 ) - { + { EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } @@ -544,9 +544,6 @@ IntDefWindowProc( PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); LRESULT lResult = 0; USER_REFERENCE_ENTRY Ref; - BOOL IsTaskBar; - DWORD Style; - DWORD ExStyle; if (Msg > WM_USER) return 0; @@ -792,32 +789,27 @@ IntDefWindowProc( co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1)); } } - if (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN)) + if (g_bWindowSnapEnabled && (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN))) { + BOOL IsTaskBar; + DWORD StyleTB; + DWORD ExStyleTB; HWND hwndTop = UserGetForegroundWindow(); PWND topWnd = UserGetWindowObject(hwndTop); - /* Test for typical TaskBar ExStyle Values */ - ExStyle = (topWnd->ExStyle & WS_EX_TOOLWINDOW); - TRACE("ExStyle is '%x'.\n", ExStyle); + // We want to forbid snapping operations on the TaskBar + // We use a heuristic for detecting the TaskBar Wnd by its typical Style & ExStyle Values + ExStyleTB = (topWnd->ExStyle & WS_EX_TOOLWINDOW); + StyleTB = (topWnd->style & (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); + IsTaskBar = (StyleTB == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)) + && (ExStyleTB == WS_EX_TOOLWINDOW); + TRACE("ExStyle=%x Style=%x IsTaskBar=%d\n", ExStyleTB, StyleTB, IsTaskBar); - /* Test for typical TaskBar Style Values */ - Style = (topWnd->style & (WS_POPUP | WS_VISIBLE | - WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); - TRACE("Style is '%x'.\n", Style); - - /* Test for masked typical TaskBar Style and ExStyles to detect TaskBar */ - IsTaskBar = (Style == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)) - && (ExStyle == WS_EX_TOOLWINDOW); - TRACE("This %s the TaskBar.\n", IsTaskBar ? "is" : "is not"); - - if (topWnd && !IsTaskBar) /* Second test is so we are not touching the Taskbar */ + if (topWnd && !IsTaskBar) { - if ((topWnd->style & WS_THICKFRAME) == 0 || !g_bWindowSnapEnabled) - { + if ((topWnd->style & WS_THICKFRAME) == 0) return 0; - } - + if (wParam == VK_DOWN) { if (topWnd->style & WS_MAXIMIZE) @@ -835,7 +827,7 @@ IntDefWindowProc( else if (wParam == VK_UP) { RECT currentRect; - if ((topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) || + if ((topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) || (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom)) { currentRect = topWnd->rcWindow; diff --git a/win32ss/user/ntuser/nonclient.c b/win32ss/user/ntuser/nonclient.c index ab7d00143b4..69291c50adb 100644 --- a/win32ss/user/ntuser/nonclient.c +++ b/win32ss/user/ntuser/nonclient.c @@ -256,8 +256,6 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) //PMONITOR mon = 0; Don't port sync from wine!!! This breaks explorer task bar sizing!! // The task bar can grow in size and can not reduce due to the change // in the work area. - DWORD ExStyleTB, StyleTB; - BOOL IsTaskBar; Style = pwnd->style; ExStyle = pwnd->ExStyle; @@ -393,35 +391,33 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) break; if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue; - /* Exit on button-up */ - if (msg.message == WM_LBUTTONUP) - { - /* Test for typical TaskBar ExStyle Values */ + if (msg.message == WM_KEYDOWN && (msg.wParam == VK_RETURN || msg.wParam == VK_ESCAPE)) + break; // Exit on Return or Esc + + if (!g_bWindowSnapEnabled && (msg.message == WM_LBUTTONUP)) + { // If no WindowSnapEnabled: Exit on button-up immediately + break; + } + else if (g_bWindowSnapEnabled && msg.message == WM_LBUTTONUP) + { // If WindowSnapEnabled: Decide whether to snap before exiting + DWORD ExStyleTB, StyleTB; + BOOL IsTaskBar; + + // We want to forbid snapping operations on the TaskBar + // We use a heuristic for detecting the TaskBar Wnd by its typical Style & ExStyle Values ExStyleTB = (ExStyle & WS_EX_TOOLWINDOW); - TRACE("ExStyle is '%x'.\n", ExStyleTB); - - /* Test for typical TaskBar Style Values */ - StyleTB = (Style & (WS_POPUP | WS_VISIBLE | - WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); - TRACE("Style is '%x'.\n", StyleTB); - - /* Test for masked typical TaskBar Style and ExStyles to detect TaskBar */ + StyleTB = (Style & (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); IsTaskBar = (StyleTB == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)) && (ExStyleTB == WS_EX_TOOLWINDOW); - TRACE("This %s the TaskBar.\n", IsTaskBar ? "is" : "is not"); + TRACE("ExStyle=%x Style=%x IsTaskBar=%d\n", ExStyleTB, StyleTB, IsTaskBar); // check for snapping if was moved by caption - if (hittest == HTCAPTION && thickframe && (ExStyle & WS_EX_MDICHILD) == 0) + if (!IsTaskBar && hittest == HTCAPTION && thickframe && (ExStyle & WS_EX_MDICHILD) == 0) { RECT snapRect; BOOL doSideSnap = FALSE; UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0); - /* if this is the taskbar, then we want to just exit */ - if (IsTaskBar || !g_bWindowSnapEnabled) - { - break; - } // snap to left if (pt.x <= snapRect.left) { @@ -434,7 +430,7 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) snapRect.left = (snapRect.right - snapRect.left) / 2 + snapRect.left; doSideSnap = TRUE; } - + if (doSideSnap) { co_WinPosSetWindowPos(pwnd, @@ -458,13 +454,6 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) } break; } - - /* Exit on Return or Esc */ - if (msg.message == WM_KEYDOWN && - (msg.wParam == VK_RETURN || msg.wParam == VK_ESCAPE)) - { - break; - } if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE)) { @@ -1285,7 +1274,7 @@ LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect, BOOL Suspende SIZE WindowBorders; RECT OrigRect; LONG Style = Wnd->style; - LONG exStyle = Wnd->ExStyle; + LONG exStyle = Wnd->ExStyle; if (Rect == NULL) { @@ -1662,7 +1651,7 @@ NC_HandleNCLButtonDblClk(PWND pWnd, WPARAM wParam, LPARAM lParam) { PMENU SysMenu = IntGetSystemMenu(pWnd, FALSE); UINT state = IntGetMenuState(SysMenu ? UserHMGetHandle(SysMenu) : NULL, SC_CLOSE, MF_BYCOMMAND); - + /* If the close item of the sysmenu is disabled or not present do nothing */ if ((state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF)) break; @@ -1674,12 +1663,12 @@ NC_HandleNCLButtonDblClk(PWND pWnd, WPARAM wParam, LPARAM lParam) case HTBOTTOM: { RECT sizingRect = pWnd->rcWindow, mouseRect; - + if (pWnd->ExStyle & WS_EX_MDICHILD) break; - + UserSystemParametersInfo(SPI_GETWORKAREA, 0, &mouseRect, 0); - + co_WinPosSetWindowPos(pWnd, NULL, sizingRect.left, @@ -1700,7 +1689,7 @@ NC_HandleNCLButtonDblClk(PWND pWnd, WPARAM wParam, LPARAM lParam) * * Handle a WM_NCRBUTTONDOWN message. Called from DefWindowProc(). */ -LRESULT NC_HandleNCRButtonDown( PWND pwnd, WPARAM wParam, LPARAM lParam ) +LRESULT NC_HandleNCRButtonDown(PWND pwnd, WPARAM wParam, LPARAM lParam) { MSG msg; INT hittest = wParam;