mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
Add Cursor Wrap functionality to Powertoys Mouse Utils (#41826)
## Summary of the Pull Request Cursor Wrap makes it simple to move the mouse from one edge of a display (or set of displays) to the opposite edge of the display stack - on a single display Cursor Wrap will wrap top/bottom and left/right edges. https://github.com/user-attachments/assets/3feb606c-142b-4dab-9824-7597833d3ba4 ## PR Checklist - [x] Closes: CursorWrap #41759 - [x] **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 - [x] **New binaries:** Added on the required places - [x] [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 PR adds a new mouse utils module, this is 'Cursor Wrap' - Cursor Wrap works with 1-9 monitors based on the logical monitor layout of the PC - for a single monitor device the cursor is wrapped for the top/bottom and left/right edges of the display - for a multi-monitor setup the cursor is wrapped on the top/bottom left/right of the displays in the logical display layout. ## Validation Steps Performed Validation has been performed on a Surface Laptop 7 Pro (Intel) with a single display and with an HDMI USB-C second display configured to be a second monitor in top/left/right/bottom configuration - there are also tests that run as part of the build to validate logical monitor layout and cursor positioning. --------- Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Kai Tao (from Dev Box) <kaitao@microsoft.com> Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
This commit is contained in:
32
src/settings-ui/Settings.UI.Library/CursorWrapProperties.cs
Normal file
32
src/settings-ui/Settings.UI.Library/CursorWrapProperties.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class CursorWrapProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, true, false, 0x55); // Win + Alt + U
|
||||
|
||||
[JsonPropertyName("activation_shortcut")]
|
||||
public HotkeySettings ActivationShortcut { get; set; }
|
||||
|
||||
[JsonPropertyName("auto_activate")]
|
||||
public BoolProperty AutoActivate { get; set; }
|
||||
|
||||
[JsonPropertyName("disable_wrap_during_drag")]
|
||||
public BoolProperty DisableWrapDuringDrag { get; set; }
|
||||
|
||||
public CursorWrapProperties()
|
||||
{
|
||||
ActivationShortcut = DefaultActivationShortcut;
|
||||
AutoActivate = new BoolProperty(false);
|
||||
DisableWrapDuringDrag = new BoolProperty(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/settings-ui/Settings.UI.Library/CursorWrapSettings.cs
Normal file
53
src/settings-ui/Settings.UI.Library/CursorWrapSettings.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -513,6 +513,22 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool cursorWrap; // defaulting to off
|
||||
|
||||
[JsonPropertyName("CursorWrap")]
|
||||
public bool CursorWrap
|
||||
{
|
||||
get => cursorWrap;
|
||||
set
|
||||
{
|
||||
if (cursorWrap != value)
|
||||
{
|
||||
LogTelemetryEvent(value);
|
||||
cursorWrap = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool lightSwitch;
|
||||
|
||||
[JsonPropertyName("LightSwitch")]
|
||||
|
||||
29
src/settings-ui/Settings.UI.Library/SndCursorWrapSettings.cs
Normal file
29
src/settings-ui/Settings.UI.Library/SndCursorWrapSettings.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class SndCursorWrapSettings
|
||||
{
|
||||
[JsonPropertyName("CursorWrap")]
|
||||
public CursorWrapSettings CursorWrap { get; set; }
|
||||
|
||||
public SndCursorWrapSettings()
|
||||
{
|
||||
}
|
||||
|
||||
public SndCursorWrapSettings(CursorWrapSettings settings)
|
||||
{
|
||||
CursorWrap = settings;
|
||||
}
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/settings-ui/Settings.UI/Assets/Settings/Icons/CursorWrap.png
Normal file
BIN
src/settings-ui/Settings.UI/Assets/Settings/Icons/CursorWrap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -22,7 +22,8 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
case ModuleType.FindMyMouse:
|
||||
case ModuleType.MouseHighlighter:
|
||||
case ModuleType.MouseJump:
|
||||
case ModuleType.MousePointerCrosshairs: return $"MouseUtils_{moduleType}/Header";
|
||||
case ModuleType.MousePointerCrosshairs:
|
||||
case ModuleType.CursorWrap: return $"MouseUtils_{moduleType}/Header";
|
||||
default: return $"{moduleType}/ModuleTitle";
|
||||
}
|
||||
}
|
||||
@@ -52,6 +53,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
case ModuleType.CmdPal: return generalSettingsConfig.Enabled.CmdPal;
|
||||
case ModuleType.ColorPicker: return generalSettingsConfig.Enabled.ColorPicker;
|
||||
case ModuleType.CropAndLock: return generalSettingsConfig.Enabled.CropAndLock;
|
||||
case ModuleType.CursorWrap: return generalSettingsConfig.Enabled.CursorWrap;
|
||||
case ModuleType.LightSwitch: return generalSettingsConfig.Enabled.LightSwitch;
|
||||
case ModuleType.EnvironmentVariables: return generalSettingsConfig.Enabled.EnvironmentVariables;
|
||||
case ModuleType.FancyZones: return generalSettingsConfig.Enabled.FancyZones;
|
||||
@@ -89,6 +91,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
case ModuleType.CmdPal: generalSettingsConfig.Enabled.CmdPal = isEnabled; break;
|
||||
case ModuleType.ColorPicker: generalSettingsConfig.Enabled.ColorPicker = isEnabled; break;
|
||||
case ModuleType.CropAndLock: generalSettingsConfig.Enabled.CropAndLock = isEnabled; break;
|
||||
case ModuleType.CursorWrap: generalSettingsConfig.Enabled.CursorWrap = isEnabled; break;
|
||||
case ModuleType.LightSwitch: generalSettingsConfig.Enabled.LightSwitch = isEnabled; break;
|
||||
case ModuleType.EnvironmentVariables: generalSettingsConfig.Enabled.EnvironmentVariables = isEnabled; break;
|
||||
case ModuleType.FancyZones: generalSettingsConfig.Enabled.FancyZones = isEnabled; break;
|
||||
@@ -125,6 +128,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
case ModuleType.CmdPal: return GPOWrapper.GetConfiguredCmdPalEnabledValue();
|
||||
case ModuleType.ColorPicker: return GPOWrapper.GetConfiguredColorPickerEnabledValue();
|
||||
case ModuleType.CropAndLock: return GPOWrapper.GetConfiguredCropAndLockEnabledValue();
|
||||
case ModuleType.CursorWrap: return GPOWrapper.GetConfiguredCursorWrapEnabledValue();
|
||||
case ModuleType.EnvironmentVariables: return GPOWrapper.GetConfiguredEnvironmentVariablesEnabledValue();
|
||||
case ModuleType.FancyZones: return GPOWrapper.GetConfiguredFancyZonesEnabledValue();
|
||||
case ModuleType.FileLocksmith: return GPOWrapper.GetConfiguredFileLocksmithEnabledValue();
|
||||
@@ -161,6 +165,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
ModuleType.CmdPal => typeof(CmdPalPage),
|
||||
ModuleType.ColorPicker => typeof(ColorPickerPage),
|
||||
ModuleType.CropAndLock => typeof(CropAndLockPage),
|
||||
ModuleType.CursorWrap => typeof(MouseUtilsPage),
|
||||
ModuleType.LightSwitch => typeof(LightSwitchPage),
|
||||
ModuleType.EnvironmentVariables => typeof(EnvironmentVariablesPage),
|
||||
ModuleType.FancyZones => typeof(FancyZonesPage),
|
||||
|
||||
@@ -273,6 +273,44 @@
|
||||
|
||||
<panels:MouseJumpPanel x:Name="MouseUtils_MouseJump_Panel" x:Uid="MouseUtils_MouseJump_Panel" />
|
||||
|
||||
<controls:SettingsGroup x:Uid="MouseUtils_CursorWrap" AutomationProperties.AutomationId="MouseUtils_CursorWrapTestId">
|
||||
<controls:GPOInfoControl ShowWarning="{x:Bind ViewModel.IsCursorWrapEnabledGpoConfigured, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="MouseUtilsEnableCursorWrap"
|
||||
x:Uid="MouseUtils_Enable_CursorWrap"
|
||||
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CursorWrap.png}"
|
||||
IsEnabled="{x:Bind ViewModel.IsCursorWrapEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
|
||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.IsCursorWrapEnabled, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</controls:GPOInfoControl>
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="MouseUtilsCursorWrapSettingsExpander"
|
||||
x:Uid="MouseUtils_CursorWrap_ActivationShortcut"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.IsCursorWrapEnabled, Mode=OneWay}"
|
||||
IsExpanded="True">
|
||||
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.CursorWrapActivationShortcut, Mode=TwoWay}" />
|
||||
<tkcontrols:SettingsExpander.Items>
|
||||
<tkcontrols:SettingsCard ContentAlignment="Left">
|
||||
<CheckBox x:Uid="MouseUtils_AutoActivate" IsChecked="{x:Bind ViewModel.CursorWrapAutoActivate, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.Items>
|
||||
</tkcontrols:SettingsExpander>
|
||||
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="CursorWrapAppearanceBehavior"
|
||||
x:Uid="Appearance_Behavior"
|
||||
AutomationProperties.AutomationId="MouseUtils_CursorWrapAppearanceBehaviorId"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.IsCursorWrapEnabled, Mode=OneWay}"
|
||||
IsExpanded="False">
|
||||
<tkcontrols:SettingsExpander.Items>
|
||||
<tkcontrols:SettingsCard ContentAlignment="Left">
|
||||
<CheckBox x:Uid="MouseUtils_CursorWrap_DisableWrapDuringDrag" IsChecked="{x:Bind ViewModel.CursorWrapDisableWrapDuringDrag, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.Items>
|
||||
</tkcontrols:SettingsExpander>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="MouseUtils_MousePointerCrosshairs" AutomationProperties.AutomationId="MouseUtils_MousePointerCrosshairsTestId">
|
||||
<controls:GPOInfoControl ShowWarning="{x:Bind ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
@@ -285,7 +323,6 @@
|
||||
IsOn="{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</controls:GPOInfoControl>
|
||||
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="MouseUtilsMousePointerCrosshairsActivationShortcut"
|
||||
x:Uid="MouseUtils_MousePointerCrosshairs_ActivationShortcut"
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
SettingsRepository<MouseHighlighterSettings>.GetInstance(settingsUtils),
|
||||
SettingsRepository<MouseJumpSettings>.GetInstance(settingsUtils),
|
||||
SettingsRepository<MousePointerCrosshairsSettings>.GetInstance(settingsUtils),
|
||||
SettingsRepository<CursorWrapSettings>.GetInstance(settingsUtils),
|
||||
ShellPage.SendDefaultIPCMessage);
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
@@ -2695,12 +2695,47 @@ From there, simply click on one of the supported files in the File Explorer and
|
||||
<data name="Oobe_MouseUtils_MouseHighlighter_Description.Text" xml:space="preserve">
|
||||
<value>Use a keyboard shortcut to highlight left and right mouse clicks.</value>
|
||||
<comment>Mouse as in the hardware peripheral.</comment>
|
||||
</data>
|
||||
|
||||
<!-- CursorWrap Module -->
|
||||
<data name="MouseUtils_Enable_CursorWrap.Header" xml:space="preserve">
|
||||
<value>Enable CursorWrap</value>
|
||||
</data>
|
||||
<data name="MouseUtils_CursorWrap.Header" xml:space="preserve">
|
||||
<value>CursorWrap</value>
|
||||
</data>
|
||||
<data name="MouseUtils_CursorWrap.Description" xml:space="preserve">
|
||||
<value>Wrap the mouse cursor between monitor edges</value>
|
||||
</data>
|
||||
|
||||
<!-- Activation Shortcut -->
|
||||
<data name="MouseUtils_CursorWrap_ActivationShortcut.Header" xml:space="preserve">
|
||||
<value>Activation shortcut</value>
|
||||
</data>
|
||||
<data name="MouseUtils_CursorWrap_ActivationShortcut_Description.Text" xml:space="preserve">
|
||||
<value>Hotkey to toggle cursor wrapping on/off</value>
|
||||
</data>
|
||||
<data name="MouseUtils_CursorWrap_ActivationShortcut_Button.Content" xml:space="preserve">
|
||||
<value>Set shortcut</value>
|
||||
</data>
|
||||
|
||||
<data name="MouseUtils_CursorWrap_DisableWrapDuringDrag.Content" xml:space="preserve">
|
||||
<value>Disable wrapping while dragging</value>
|
||||
</data>
|
||||
|
||||
<!-- Auto-activate -->
|
||||
<data name="MouseUtils_CursorWrap_AutoActivate.Header" xml:space="preserve">
|
||||
<value>Auto-activate on startup</value>
|
||||
</data>
|
||||
<data name="MouseUtils_CursorWrap_AutoActivate.Content" xml:space="preserve">
|
||||
<value>Automatically activate on utility startup</value>
|
||||
</data>
|
||||
|
||||
<data name="Oobe_MouseUtils_MousePointerCrosshairs.Text" xml:space="preserve">
|
||||
<value>Mouse Pointer Crosshairs</value>
|
||||
<comment>Mouse as in the hardware peripheral.</comment>
|
||||
</data>
|
||||
<data name="Oobe_MouseUtils_MousePointerCrosshairs_Description.Text" xml:space="preserve">
|
||||
<data name="Oobe_MouseUtils_MousePointerCrosshairs.Description" xml:space="preserve">
|
||||
<value>Draw crosshairs centered around the mouse pointer.</value>
|
||||
<comment>Mouse as in the hardware peripheral.</comment>
|
||||
</data>
|
||||
|
||||
@@ -29,7 +29,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
private MousePointerCrosshairsSettings MousePointerCrosshairsSettingsConfig { get; set; }
|
||||
|
||||
public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FindMyMouseSettings> findMyMouseSettingsRepository, ISettingsRepository<MouseHighlighterSettings> mouseHighlighterSettingsRepository, ISettingsRepository<MouseJumpSettings> mouseJumpSettingsRepository, ISettingsRepository<MousePointerCrosshairsSettings> mousePointerCrosshairsSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
|
||||
private CursorWrapSettings CursorWrapSettingsConfig { get; set; }
|
||||
|
||||
public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FindMyMouseSettings> findMyMouseSettingsRepository, ISettingsRepository<MouseHighlighterSettings> mouseHighlighterSettingsRepository, ISettingsRepository<MouseJumpSettings> mouseJumpSettingsRepository, ISettingsRepository<MousePointerCrosshairsSettings> mousePointerCrosshairsSettingsRepository, ISettingsRepository<CursorWrapSettings> cursorWrapSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
|
||||
{
|
||||
SettingsUtils = settingsUtils;
|
||||
|
||||
@@ -103,6 +105,14 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_mousePointerCrosshairsOrientation = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value;
|
||||
_mousePointerCrosshairsAutoActivate = MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value;
|
||||
|
||||
ArgumentNullException.ThrowIfNull(cursorWrapSettingsRepository);
|
||||
|
||||
CursorWrapSettingsConfig = cursorWrapSettingsRepository.SettingsConfig;
|
||||
_cursorWrapAutoActivate = CursorWrapSettingsConfig.Properties.AutoActivate.Value;
|
||||
|
||||
// Null-safe access in case property wasn't upgraded yet - default to TRUE
|
||||
_cursorWrapDisableWrapDuringDrag = CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag?.Value ?? true;
|
||||
|
||||
int isEnabled = 0;
|
||||
|
||||
Utilities.NativeMethods.SystemParametersInfo(Utilities.NativeMethods.SPI_GETCLIENTAREAANIMATION, 0, ref isEnabled, 0);
|
||||
@@ -144,13 +154,25 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
if (_mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||
{
|
||||
// Get the enabled state from GPO.
|
||||
_mousePointerCrosshairsEnabledStateIsGPOConfigured = true;
|
||||
_mousePointerCrosshairsEnabledStateGPOConfigured = true;
|
||||
_isMousePointerCrosshairsEnabled = _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isMousePointerCrosshairsEnabled = GeneralSettingsConfig.Enabled.MousePointerCrosshairs;
|
||||
}
|
||||
|
||||
_cursorWrapEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredCursorWrapEnabledValue();
|
||||
if (_cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||
{
|
||||
// Get the enabled state from GPO.
|
||||
_cursorWrapEnabledStateIsGPOConfigured = true;
|
||||
_isCursorWrapEnabled = _cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isCursorWrapEnabled = GeneralSettingsConfig.Enabled.CursorWrap;
|
||||
}
|
||||
}
|
||||
|
||||
public override Dictionary<string, HotkeySettings[]> GetAllHotkeySettings()
|
||||
@@ -163,6 +185,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
MousePointerCrosshairsActivationShortcut,
|
||||
GlidingCursorActivationShortcut],
|
||||
[MouseJumpSettings.ModuleName] = [MouseJumpActivationShortcut],
|
||||
[CursorWrapSettings.ModuleName] = [CursorWrapActivationShortcut],
|
||||
};
|
||||
|
||||
return hotkeysDict;
|
||||
@@ -663,7 +686,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
get => _isMousePointerCrosshairsEnabled;
|
||||
set
|
||||
{
|
||||
if (_mousePointerCrosshairsEnabledStateIsGPOConfigured)
|
||||
if (_mousePointerCrosshairsEnabledStateGPOConfigured)
|
||||
{
|
||||
// If it's GPO configured, shouldn't be able to change this state.
|
||||
return;
|
||||
@@ -686,7 +709,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
public bool IsMousePointerCrosshairsEnabledGpoConfigured
|
||||
{
|
||||
get => _mousePointerCrosshairsEnabledStateIsGPOConfigured;
|
||||
get => _mousePointerCrosshairsEnabledStateGPOConfigured;
|
||||
}
|
||||
|
||||
public HotkeySettings MousePointerCrosshairsActivationShortcut
|
||||
@@ -959,6 +982,110 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
SettingsUtils.SaveSettings(MousePointerCrosshairsSettingsConfig.ToJsonString(), MousePointerCrosshairsSettings.ModuleName);
|
||||
}
|
||||
|
||||
public bool IsCursorWrapEnabled
|
||||
{
|
||||
get => _isCursorWrapEnabled;
|
||||
set
|
||||
{
|
||||
if (_cursorWrapEnabledStateIsGPOConfigured)
|
||||
{
|
||||
// If it's GPO configured, shouldn't be able to change this state.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isCursorWrapEnabled != value)
|
||||
{
|
||||
_isCursorWrapEnabled = value;
|
||||
|
||||
GeneralSettingsConfig.Enabled.CursorWrap = value;
|
||||
OnPropertyChanged(nameof(IsCursorWrapEnabled));
|
||||
|
||||
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
||||
SendConfigMSG(outgoing.ToString());
|
||||
|
||||
NotifyCursorWrapPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCursorWrapEnabledGpoConfigured
|
||||
{
|
||||
get => _cursorWrapEnabledStateIsGPOConfigured;
|
||||
}
|
||||
|
||||
public HotkeySettings CursorWrapActivationShortcut
|
||||
{
|
||||
get
|
||||
{
|
||||
return CursorWrapSettingsConfig.Properties.ActivationShortcut;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (CursorWrapSettingsConfig.Properties.ActivationShortcut != value)
|
||||
{
|
||||
CursorWrapSettingsConfig.Properties.ActivationShortcut = value ?? CursorWrapSettingsConfig.Properties.DefaultActivationShortcut;
|
||||
NotifyCursorWrapPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CursorWrapAutoActivate
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cursorWrapAutoActivate;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _cursorWrapAutoActivate)
|
||||
{
|
||||
_cursorWrapAutoActivate = value;
|
||||
CursorWrapSettingsConfig.Properties.AutoActivate.Value = value;
|
||||
NotifyCursorWrapPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CursorWrapDisableWrapDuringDrag
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cursorWrapDisableWrapDuringDrag;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _cursorWrapDisableWrapDuringDrag)
|
||||
{
|
||||
_cursorWrapDisableWrapDuringDrag = value;
|
||||
|
||||
// Ensure the property exists before setting value
|
||||
if (CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag == null)
|
||||
{
|
||||
CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag = new BoolProperty(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag.Value = value;
|
||||
}
|
||||
|
||||
NotifyCursorWrapPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyCursorWrapPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
OnPropertyChanged(propertyName);
|
||||
|
||||
SndCursorWrapSettings outsettings = new SndCursorWrapSettings(CursorWrapSettingsConfig);
|
||||
SndModuleSettings<SndCursorWrapSettings> ipcMessage = new SndModuleSettings<SndCursorWrapSettings>(outsettings);
|
||||
SendConfigMSG(ipcMessage.ToJsonString());
|
||||
SettingsUtils.SaveSettings(CursorWrapSettingsConfig.ToJsonString(), CursorWrapSettings.ModuleName);
|
||||
}
|
||||
|
||||
public void RefreshEnabledState()
|
||||
{
|
||||
InitializeEnabledValues();
|
||||
@@ -966,6 +1093,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
OnPropertyChanged(nameof(IsMouseHighlighterEnabled));
|
||||
OnPropertyChanged(nameof(IsMouseJumpEnabled));
|
||||
OnPropertyChanged(nameof(IsMousePointerCrosshairsEnabled));
|
||||
OnPropertyChanged(nameof(IsCursorWrapEnabled));
|
||||
}
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
@@ -999,7 +1127,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private bool _highlighterAutoActivate;
|
||||
|
||||
private GpoRuleConfigured _mousePointerCrosshairsEnabledGpoRuleConfiguration;
|
||||
private bool _mousePointerCrosshairsEnabledStateIsGPOConfigured;
|
||||
private bool _mousePointerCrosshairsEnabledStateGPOConfigured;
|
||||
private bool _isMousePointerCrosshairsEnabled;
|
||||
private string _mousePointerCrosshairsColor;
|
||||
private int _mousePointerCrosshairsOpacity;
|
||||
@@ -1013,5 +1141,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private int _mousePointerCrosshairsOrientation;
|
||||
private bool _mousePointerCrosshairsAutoActivate;
|
||||
private bool _isAnimationEnabledBySystem;
|
||||
|
||||
private GpoRuleConfigured _cursorWrapEnabledGpoRuleConfiguration;
|
||||
private bool _cursorWrapEnabledStateIsGPOConfigured;
|
||||
private bool _isCursorWrapEnabled;
|
||||
private bool _cursorWrapAutoActivate;
|
||||
private bool _cursorWrapDisableWrapDuringDrag; // Will be initialized in constructor from settings
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user