2025-11-05 03:28:25 -08:00
|
|
|
// Copyright (c) Microsoft Corporation
|
|
|
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text.Json.Serialization;
|
|
|
|
|
using ManagedCommon;
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.PowerToys.Settings.UI.Library
|
|
|
|
|
{
|
|
|
|
|
public class CursorWrapSettings : BasePTModuleSettings, ISettingsConfig, IHotkeyConfig
|
|
|
|
|
{
|
|
|
|
|
public const string ModuleName = "CursorWrap";
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("properties")]
|
|
|
|
|
public CursorWrapProperties Properties { get; set; }
|
|
|
|
|
|
|
|
|
|
public CursorWrapSettings()
|
|
|
|
|
{
|
|
|
|
|
Name = ModuleName;
|
|
|
|
|
Properties = new CursorWrapProperties();
|
|
|
|
|
Version = "1.0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string GetModuleName()
|
|
|
|
|
{
|
|
|
|
|
return Name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ModuleType GetModuleType() => ModuleType.CursorWrap;
|
|
|
|
|
|
|
|
|
|
public HotkeyAccessor[] GetAllHotkeyAccessors()
|
|
|
|
|
{
|
|
|
|
|
var hotkeyAccessors = new List<HotkeyAccessor>
|
|
|
|
|
{
|
|
|
|
|
new HotkeyAccessor(
|
|
|
|
|
() => Properties.ActivationShortcut,
|
|
|
|
|
value => Properties.ActivationShortcut = value ?? Properties.DefaultActivationShortcut,
|
|
|
|
|
"MouseUtils_CursorWrap_ActivationShortcut"),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return hotkeyAccessors.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This can be utilized in the future if the settings.json file is to be modified/deleted.
|
|
|
|
|
public bool UpgradeSettingsConfiguration()
|
|
|
|
|
{
|
2026-01-27 05:27:11 +00:00
|
|
|
bool settingsUpgraded = false;
|
|
|
|
|
|
|
|
|
|
// Add WrapMode property if it doesn't exist (for users upgrading from older versions)
|
|
|
|
|
if (Properties.WrapMode == null)
|
|
|
|
|
{
|
|
|
|
|
Properties.WrapMode = new IntProperty(0); // Default to Both
|
|
|
|
|
settingsUpgraded = true;
|
|
|
|
|
}
|
|
|
|
|
|
[Cursor Wrap] Update edge wrap model, update simulator, add cursor logging, add settings support to ModuleLoader (#45915)
This PR adds new options for disabling wrap, updates the wrapping model,
extends the simulator and cursor logging.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #45116
- [ ] Closes: #44955
- [ ] Closes: #44827
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **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
The PR adds a new option for disabling cursor wrapping, exposing three
options: None - wrapping is not disabled, Ctrl key - if this is pressed
then wrapping is disabled, Shift key - if this is pressed then wrapping
is disabled, this would enable a user to temporarily disable wrapping if
they wanted to get close to a monitor edge without wrapping (auto-hide
status bar for example).
The cursor wrap edge model has been updated to mirror Windows
monitor-to-monitor cursor movement, this should ensure there aren't any
non-wrappable edges.
A new test tool has been added 'CursorLog' this is a monitor aware,
dpi/scaling aware Win32 application that captures mouse movement across
monitors to a log file, the log contains one line per mouse movement
which includes: Monitor, x, y, scale, dpi.
The wrapping simulator has been updated to include the new wrapping
model and support mouse cursor log playback.
## Validation Steps Performed
The updated CursorWrap has been tested on a single monitor (laptop) and
multi-monitor desktop PC with monitors being offset to test
edge/wrapping behavior.
---------
Co-authored-by: Mike Hall <mikehall@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: vanzue <vanzue@outlook.com>
2026-03-04 14:56:32 +01:00
|
|
|
// Add ActivationMode property if it doesn't exist (for users upgrading from older versions)
|
|
|
|
|
if (Properties.ActivationMode == null)
|
|
|
|
|
{
|
|
|
|
|
Properties.ActivationMode = new IntProperty(0); // Default to Always (0=Always, 1=HoldingCtrl, 2=HoldingShift)
|
|
|
|
|
settingsUpgraded = true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-05 10:37:10 +00:00
|
|
|
// Add DisableCursorWrapOnSingleMonitor property if it doesn't exist (for users upgrading from older versions)
|
|
|
|
|
if (Properties.DisableCursorWrapOnSingleMonitor == null)
|
|
|
|
|
{
|
|
|
|
|
Properties.DisableCursorWrapOnSingleMonitor = new BoolProperty(false); // Default to false
|
|
|
|
|
settingsUpgraded = true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-27 05:27:11 +00:00
|
|
|
return settingsUpgraded;
|
2025-11-05 03:28:25 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|