From 0aca7c292c63ae525d1e92faefd9b2436dc6021b Mon Sep 17 00:00:00 2001
From: Kai Tao <69313318+vanzue@users.noreply.github.com>
Date: Mon, 9 Mar 2026 19:21:24 +0800
Subject: [PATCH] Cursor Wrap: Reverse the wrap mode (hold ctrl or shift) to
wrap (#46009)
## Summary of the Pull Request
Currently, hold ctrl or shift to disable wrap, which is inverse with
existing similar thing in mouse without borders,
reverse the behavior, so we hold ctrl or shift to wrap.
## PR Checklist
- [ ] Closes: #46005
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
Verified locally, everything works as expected, hold ctrl and shift will
trigger the wrap, other wise not if select the corresponding option
---
src/modules/MouseUtils/CursorWrap/dllmain.cpp | 20 +++++++++----------
.../Settings.UI/Strings/en-us/Resources.resw | 4 ++--
.../ViewModels/MouseUtilsViewModel.cs | 2 +-
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/modules/MouseUtils/CursorWrap/dllmain.cpp b/src/modules/MouseUtils/CursorWrap/dllmain.cpp
index 451c4e99bd..c270703743 100644
--- a/src/modules/MouseUtils/CursorWrap/dllmain.cpp
+++ b/src/modules/MouseUtils/CursorWrap/dllmain.cpp
@@ -84,7 +84,7 @@ private:
bool m_disableWrapDuringDrag = true; // Default to true to prevent wrap during drag
bool m_disableOnSingleMonitor = false; // Default to false
int m_wrapMode = 0; // 0=Both (default), 1=VerticalOnly, 2=HorizontalOnly
- int m_activationMode = 0; // 0=Always (default), 1=HoldingCtrl (disables wrap), 2=HoldingShift (disables wrap)
+ int m_activationMode = 0; // 0=Always (default), 1=HoldingCtrl (wraps only while held), 2=HoldingShift (wraps only while held)
// Mouse hook
HHOOK m_mouseHook = nullptr;
@@ -689,23 +689,23 @@ private:
if (g_cursorWrapInstance && g_cursorWrapInstance->m_hookActive)
{
- // Check activation mode to determine if wrapping should be disabled
- // 0=Always, 1=HoldingCtrl (disables wrap when Ctrl held), 2=HoldingShift (disables wrap when Shift held)
+ // Check activation mode to determine if wrapping should happen.
+ // 0=Always, 1=HoldingCtrl (wraps only when Ctrl held), 2=HoldingShift (wraps only when Shift held)
int activationMode = g_cursorWrapInstance->m_activationMode;
- bool disableByKey = false;
+ bool shouldWrap = true;
- if (activationMode == 1) // HoldingCtrl - disable wrap when Ctrl is held
+ if (activationMode == 1) // HoldingCtrl - wrap only when Ctrl is held
{
- disableByKey = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0;
+ shouldWrap = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0;
}
- else if (activationMode == 2) // HoldingShift - disable wrap when Shift is held
+ else if (activationMode == 2) // HoldingShift - wrap only when Shift is held
{
- disableByKey = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0;
+ shouldWrap = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0;
}
- if (disableByKey)
+ if (!shouldWrap)
{
- // Key is held, do not wrap - let normal behavior happen
+ // Activation key is not held, do not wrap - let normal behavior happen.
return CallNextHookEx(nullptr, nCode, wParam, lParam);
}
diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
index f2efe864b4..4b885e4e0f 100644
--- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
+++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
@@ -2554,11 +2554,11 @@ From there, simply click on one of the supported files in the File Explorer and
Holding Ctrl
- CursorWrap: Activation mode - disable wrap when Ctrl held
+ CursorWrap: Activation mode - wrap only when Ctrl held
Holding Shift
- CursorWrap: Activation mode - disable wrap when Shift held
+ CursorWrap: Activation mode - wrap only when Shift held
Mouse Pointer Crosshairs
diff --git a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs
index cc54869100..853b77d336 100644
--- a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs
+++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs
@@ -1241,7 +1241,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private bool _cursorWrapAutoActivate;
private bool _cursorWrapDisableWrapDuringDrag; // Will be initialized in constructor from settings
private int _cursorWrapWrapMode; // 0=Both, 1=VerticalOnly, 2=HorizontalOnly
- private int _cursorWrapActivationMode; // 0=Always, 1=HoldingCtrl (disables wrap), 2=HoldingShift (disables wrap)
+ private int _cursorWrapActivationMode; // 0=Always, 1=HoldingCtrl (wraps only while held), 2=HoldingShift (wraps only while held)
private bool _cursorWrapDisableOnSingleMonitor; // Disable cursor wrap when only one monitor is connected
}
}