[0.4.14][NTUSER] Allow Window Snap to be disabled and optimize

Win+Left, Win+Right, Win+Up, and Win+Down can be disabled by registry value WindowArrangementActive REG_SZ 0 in
HKEY_CURRENT_USER\Control Panel\Desktop
Snapping mouse can be also disabled.

by porting back:
0.4.15-dev-5703-g d04e148d1c Optimize window snap disabling (#5061)
0.4.15-dev-5641-g ea55101aad Allow Window Snap to be disabled (#5014) CORE-16379 (#5014)

Also port back some minor unrelated improvements:
0.4.15-dev-3341-g 4bc95812fd defwnd.c Mark default as unreachable.
0.4.15-dev-316-g 938df97b54 nonclient.c NC_IconForWindow(): Remove redundant if() (#2842)
and:
-defwnd.c: delete a malformed TRACE() which had a format string, but no argument.
This commit is contained in:
Joachim Henze 2023-02-25 03:34:29 +01:00
parent c6a6ee97fc
commit 6247a4509a
4 changed files with 61 additions and 68 deletions

View file

@ -401,20 +401,19 @@ UserPaintCaption(PWND pWnd, INT Flags)
{ {
if (pWnd->state & WNDS_HASCAPTION && pWnd->head.pti->MessageQueue == gpqForeground) if (pWnd->state & WNDS_HASCAPTION && pWnd->head.pti->MessageQueue == gpqForeground)
Flags |= DC_ACTIVE; Flags |= DC_ACTIVE;
/* /*
* When themes are not enabled we can go on and paint the non client area. * 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. * 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 * 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) if (gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
{ {
/* /*
* This will cause uxtheme to either paint the themed caption or call * This will cause uxtheme to either paint the themed caption or call
* RealUserDrawCaption in order to draw the classic caption when themes * 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");
co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0); co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0);
} }
else else
@ -436,7 +435,7 @@ DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
HICON hIcon, hIconSmall, hIconOld; HICON hIcon, hIconSmall, hIconOld;
if ( wParam > ICON_SMALL2 ) if ( wParam > ICON_SMALL2 )
{ {
EngSetLastError(ERROR_INVALID_PARAMETER); EngSetLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@ -486,8 +485,7 @@ DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
case ICON_SMALL2: case ICON_SMALL2:
hIconRet = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE); hIconRet = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
break; break;
default: DEFAULT_UNREACHABLE;
break;
} }
return (LRESULT)hIconRet; return (LRESULT)hIconRet;
} }
@ -539,9 +537,6 @@ IntDefWindowProc(
PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
LRESULT lResult = 0; LRESULT lResult = 0;
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
BOOL IsTaskBar;
DWORD Style;
DWORD ExStyle;
if (Msg > WM_USER) return 0; if (Msg > WM_USER) return 0;
@ -787,32 +782,27 @@ IntDefWindowProc(
co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1)); 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(); HWND hwndTop = UserGetForegroundWindow();
PWND topWnd = UserGetWindowObject(hwndTop); PWND topWnd = UserGetWindowObject(hwndTop);
/* Test for typical TaskBar ExStyle Values */ // We want to forbid snapping operations on the TaskBar
ExStyle = (topWnd->ExStyle & WS_EX_TOOLWINDOW); // We use a heuristic for detecting the TaskBar Wnd by its typical Style & ExStyle Values
TRACE("ExStyle is '%x'.\n", ExStyle); 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 */ if (topWnd && !IsTaskBar)
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->style & WS_THICKFRAME) == 0) if ((topWnd->style & WS_THICKFRAME) == 0)
{
return 0; return 0;
}
if (wParam == VK_DOWN) if (wParam == VK_DOWN)
{ {
if (topWnd->style & WS_MAXIMIZE) if (topWnd->style & WS_MAXIMIZE)
@ -830,7 +820,7 @@ IntDefWindowProc(
else if (wParam == VK_UP) else if (wParam == VK_UP)
{ {
RECT currentRect; 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)) (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom))
{ {
currentRect = topWnd->rcWindow; currentRect = topWnd->rcWindow;

View file

@ -256,8 +256,6 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
//PMONITOR mon = 0; Don't port sync from wine!!! This breaks explorer task bar sizing!! //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 // The task bar can grow in size and can not reduce due to the change
// in the work area. // in the work area.
DWORD ExStyleTB, StyleTB;
BOOL IsTaskBar;
Style = pwnd->style; Style = pwnd->style;
ExStyle = pwnd->ExStyle; ExStyle = pwnd->ExStyle;
@ -393,35 +391,33 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) break; if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) break;
if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue; if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue;
/* Exit on button-up */ if (msg.message == WM_KEYDOWN && (msg.wParam == VK_RETURN || msg.wParam == VK_ESCAPE))
if (msg.message == WM_LBUTTONUP) break; // Exit on Return or Esc
{
/* Test for typical TaskBar ExStyle Values */ 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); ExStyleTB = (ExStyle & WS_EX_TOOLWINDOW);
TRACE("ExStyle is '%x'.\n", ExStyleTB); StyleTB = (Style & (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN));
/* 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 */
IsTaskBar = (StyleTB == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)) IsTaskBar = (StyleTB == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN))
&& (ExStyleTB == WS_EX_TOOLWINDOW); && (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 // 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; RECT snapRect;
BOOL doSideSnap = FALSE; BOOL doSideSnap = FALSE;
UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0); UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0);
/* if this is the taskbar, then we want to just exit */
if (IsTaskBar)
{
break;
}
// snap to left // snap to left
if (pt.x <= snapRect.left) if (pt.x <= snapRect.left)
{ {
@ -434,7 +430,7 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
snapRect.left = (snapRect.right - snapRect.left) / 2 + snapRect.left; snapRect.left = (snapRect.right - snapRect.left) / 2 + snapRect.left;
doSideSnap = TRUE; doSideSnap = TRUE;
} }
if (doSideSnap) if (doSideSnap)
{ {
co_WinPosSetWindowPos(pwnd, co_WinPosSetWindowPos(pwnd,
@ -458,13 +454,6 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
} }
break; 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)) if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
{ {
@ -696,7 +685,7 @@ PCURICON_OBJECT FASTCALL NC_IconForWindow( PWND pWnd )
// it does not use the default icon! And it does not check for DS_MODALFRAME. // it does not use the default icon! And it does not check for DS_MODALFRAME.
if (!hIcon && !(pWnd->ExStyle & WS_EX_DLGMODALFRAME)) if (!hIcon && !(pWnd->ExStyle & WS_EX_DLGMODALFRAME))
{ {
if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size. if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size.
} }
if (hIcon) if (hIcon)
@ -1251,7 +1240,7 @@ LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect, BOOL Suspende
SIZE WindowBorders; SIZE WindowBorders;
RECT OrigRect; RECT OrigRect;
LONG Style = Wnd->style; LONG Style = Wnd->style;
LONG exStyle = Wnd->ExStyle; LONG exStyle = Wnd->ExStyle;
if (Rect == NULL) if (Rect == NULL)
{ {
@ -1628,7 +1617,7 @@ NC_HandleNCLButtonDblClk(PWND pWnd, WPARAM wParam, LPARAM lParam)
{ {
PMENU SysMenu = IntGetSystemMenu(pWnd, FALSE); PMENU SysMenu = IntGetSystemMenu(pWnd, FALSE);
UINT state = IntGetMenuState(SysMenu ? UserHMGetHandle(SysMenu) : NULL, SC_CLOSE, MF_BYCOMMAND); 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 the close item of the sysmenu is disabled or not present do nothing */
if ((state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF)) if ((state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF))
break; break;
@ -1640,12 +1629,12 @@ NC_HandleNCLButtonDblClk(PWND pWnd, WPARAM wParam, LPARAM lParam)
case HTBOTTOM: case HTBOTTOM:
{ {
RECT sizingRect = pWnd->rcWindow, mouseRect; RECT sizingRect = pWnd->rcWindow, mouseRect;
if (pWnd->ExStyle & WS_EX_MDICHILD) if (pWnd->ExStyle & WS_EX_MDICHILD)
break; break;
UserSystemParametersInfo(SPI_GETWORKAREA, 0, &mouseRect, 0); UserSystemParametersInfo(SPI_GETWORKAREA, 0, &mouseRect, 0);
co_WinPosSetWindowPos(pWnd, co_WinPosSetWindowPos(pWnd,
0, 0,
sizingRect.left, sizingRect.left,
@ -1666,7 +1655,7 @@ NC_HandleNCLButtonDblClk(PWND pWnd, WPARAM wParam, LPARAM lParam)
* *
* Handle a WM_NCRBUTTONDOWN message. Called from DefWindowProc(). * 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; MSG msg;
INT hittest = wParam; INT hittest = wParam;

View file

@ -17,6 +17,7 @@ DBG_DEFAULT_CHANNEL(UserSysparams);
SPIVALUES gspv; SPIVALUES gspv;
BOOL gbSpiInitialized = FALSE; BOOL gbSpiInitialized = FALSE;
BOOL g_PaintDesktopVersion = FALSE; BOOL g_PaintDesktopVersion = FALSE;
BOOL g_bWindowSnapEnabled = TRUE;
// HACK! We initialize SPI before we have a proper surface to get this from. // HACK! We initialize SPI before we have a proper surface to get this from.
#define dpi 96 #define dpi 96
@ -99,8 +100,6 @@ static const WCHAR* KEY_KDBPREF = L"Control Panel\\Accessibility\\Keyboard Prefe
static const WCHAR* KEY_SCRREAD = L"Control Panel\\Accessibility\\Blind Access"; static const WCHAR* KEY_SCRREAD = L"Control Panel\\Accessibility\\Blind Access";
static const WCHAR* VAL_ON = L"On"; static const WCHAR* VAL_ON = L"On";
/** Loading the settings ******************************************************/ /** Loading the settings ******************************************************/
static static
@ -214,6 +213,18 @@ SpiFixupValues(VOID)
} }
static BOOL IntIsWindowSnapEnabled(VOID)
{
WCHAR szValue[2];
if (RegReadUserSetting(L"Control Panel\\Desktop", L"WindowArrangementActive",
REG_SZ, szValue, sizeof(szValue)))
{
szValue[RTL_NUMBER_OF(szValue) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
return (_wtoi(szValue) != 0);
}
return TRUE;
}
static static
VOID VOID
SpiUpdatePerUserSystemParameters(VOID) SpiUpdatePerUserSystemParameters(VOID)
@ -342,6 +353,8 @@ SpiUpdatePerUserSystemParameters(VOID)
if (SPITESTPREF(UPM_LISTBOXSMOOTHSCROLLING)) gpsi->PUSIFlags |= PUSIF_LISTBOXSMOOTHSCROLLING; if (SPITESTPREF(UPM_LISTBOXSMOOTHSCROLLING)) gpsi->PUSIFlags |= PUSIF_LISTBOXSMOOTHSCROLLING;
} }
gdwLanguageToggleKey = UserGetLanguageToggle(); gdwLanguageToggleKey = UserGetLanguageToggle();
g_bWindowSnapEnabled = IntIsWindowSnapEnabled();
} }
BOOL BOOL
@ -949,7 +962,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
/* Fixup user's structure size */ /* Fixup user's structure size */
metrics->cbSize = sizeof(NONCLIENTMETRICSW); metrics->cbSize = sizeof(NONCLIENTMETRICSW);
if (!SpiSet(&gspv.ncm, metrics, sizeof(NONCLIENTMETRICSW), fl)) if (!SpiSet(&gspv.ncm, metrics, sizeof(NONCLIENTMETRICSW), fl))
return 0; return 0;

View file

@ -4,6 +4,7 @@ extern ATOM AtomMessage;
extern ATOM AtomWndObj; /* WNDOBJ list */ extern ATOM AtomWndObj; /* WNDOBJ list */
extern ATOM AtomLayer; extern ATOM AtomLayer;
extern ATOM AtomFlashWndState; extern ATOM AtomFlashWndState;
extern BOOL g_bWindowSnapEnabled;
#define HAS_DLGFRAME(Style, ExStyle) \ #define HAS_DLGFRAME(Style, ExStyle) \
(((ExStyle) & WS_EX_DLGMODALFRAME) || \ (((ExStyle) & WS_EX_DLGMODALFRAME) || \