[NTUSER][PSDK] Implement Snap DockMoving setting (#8020)

SPI_SETDOCKMOVING allows you to turn off window snapping when moving a window with the mouse. The Win keys can still snap unless you turn everything off with SPI_SETWINARRANGING.
This commit is contained in:
Whindmar Saksit 2025-05-23 13:45:25 +02:00 committed by GitHub
parent e326b06983
commit 5299f047e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 15 deletions

View file

@ -1494,6 +1494,14 @@ extern "C" {
#define SPI_GETSCREENSAVESECURE 0x0076
#define SPI_SETSCREENSAVESECURE 0x0077
#endif
#if(_WIN32_WINNT >= 0x0601) || defined(__REACTOS__)
#define SPI_GETWINARRANGING 0x0082
#define SPI_SETWINARRANGING 0x0083
#define SPI_GETDRAGFROMMAXIMIZE 0x008C
#define SPI_SETDRAGFROMMAXIMIZE 0x008D
#define SPI_GETDOCKMOVING 0x0090
#define SPI_SETDOCKMOVING 0x0091
#endif
#if(WINVER >= 0x0500)
#define SPI_GETACTIVEWINDOWTRACKING 0x1000
#define SPI_SETACTIVEWINDOWTRACKING 0x1001

View file

@ -139,7 +139,10 @@ NC_GetSysPopupPos(PWND Wnd, RECT *Rect)
static UINT
GetSnapActivationPoint(PWND Wnd, POINT pt)
{
// TODO: SPI_GETMOUSEDOCKTHRESHOLD
RECT wa;
if (!GetSnapSetting(bDockMoving))
return HTNOWHERE;
UserSystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0); /* FIXME: MultiMon of PWND */
if (pt.x <= wa.left) return HTLEFT;

View file

@ -79,6 +79,8 @@ static const WCHAR* VAL_CARETWIDTH = L"CaretWidth";
static const WCHAR* VAL_SCRLLCHARS = L"WheelScrollChars";
#endif
static const WCHAR* VAL_USERPREFMASK = L"UserPreferencesMask";
static const WCHAR* VAL_SNAP_ENABLED = L"WindowArrangementActive";
static const WCHAR* VAL_SNAP_DOCKMOVING = L"DockMoving";
static const WCHAR* KEY_MDALIGN = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
static const WCHAR* VAL_MDALIGN = L"MenuDropAlignment";
@ -219,19 +221,6 @@ SpiFixupValues(VOID)
}
/* Is Window Snap enabled? */
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
VOID
SpiUpdatePerUserSystemParameters(VOID)
@ -351,6 +340,9 @@ SpiUpdatePerUserSystemParameters(VOID)
gspv.highcontrast.cbSize = sizeof(HIGHCONTRASTW);
gspv.animationinfo.cbSize = sizeof(ANIMATIONINFO);
g_bWindowSnapEnabled = SpiLoadInt(KEY_DESKTOP, VAL_SNAP_ENABLED, TRUE);
gspv.bDockMoving = SpiLoadInt(KEY_DESKTOP, VAL_SNAP_DOCKMOVING, TRUE);
/* Make sure we don't use broken values */
SpiFixupValues();
@ -366,8 +358,6 @@ SpiUpdatePerUserSystemParameters(VOID)
}
gdwLanguageToggleKey = UserGetLanguageToggle(L"Language Hotkey", 1);
gdwLayoutToggleKey = UserGetLanguageToggle(L"Layout Hotkey", 2);
g_bWindowSnapEnabled = IntIsWindowSnapEnabled();
}
BOOL
@ -1804,6 +1794,16 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
case SPI_SETFONTSMOOTHINGORIENTATION:
return SpiSetDWord(&gspv.uiFontSmoothingOrientation, PtrToUlong(pvParam), KEY_DESKTOP, VAL_FONTSMOOTHINGORIENTATION, fl);
case SPI_GETWINARRANGING:
return SpiGetInt(pvParam, &g_bWindowSnapEnabled, fl);
case SPI_SETWINARRANGING:
return SpiSetInt(&g_bWindowSnapEnabled, uiParam, KEY_DESKTOP, VAL_SNAP_ENABLED, fl);
case SPI_GETDOCKMOVING:
return SpiGetInt(pvParam, &gspv.bDockMoving, fl);
case SPI_SETDOCKMOVING:
return SpiSetInt(&gspv.bDockMoving, uiParam, KEY_DESKTOP, VAL_SNAP_DOCKMOVING, fl);
/* The following are undocumented, but valid SPI values */
case 0x1010:
case 0x1011:

View file

@ -157,6 +157,12 @@ typedef struct _SPIVALUES
DWORD dwForegroundFlashCount;
DWORD dwCaretWidth;
/* Snap */
// BOOL bWinArranging; (g_bWindowSnapEnabled)
BOOL bDockMoving;
// BOOL bSnapSizing;
// BOOL bDragFromMaximize;
// SPI_LANGDRIVER
// SPI_SETDESKPATTERN
// SPI_SETPENWINDOWS

View file

@ -77,6 +77,13 @@ VOID FASTCALL co_IntCalculateSnapPosition(PWND Wnd, UINT Edge, OUT RECT *Pos);
VOID FASTCALL co_IntSnapWindow(PWND Wnd, UINT Edge);
VOID FASTCALL IntSetSnapEdge(PWND Wnd, UINT Edge);
VOID FASTCALL IntSetSnapInfo(PWND Wnd, UINT Edge, IN const RECT *Pos OPTIONAL);
#define GetSnapSetting(gspvmember) (IsSnapEnabled() ? (gspv.gspvmember) : 0)
FORCEINLINE BOOL
IsSnapEnabled(VOID)
{
return g_bWindowSnapEnabled;
}
FORCEINLINE VOID
co_IntUnsnapWindow(PWND Wnd)