[New Utility]Mouse Jump(#23566)

* #23216 - initial MouseJump commit

* #23216 - Mouse Jump - fix spelling, removing Interop folder

* #23216 - Mouse Jump - removed orphaned project guids from PowerToys.sln

* #23216 - Mouse Jump - removed orphaned project guids from PowerToys.sln

* #23216 - Mouse Jump - switch MS Logger to NLog for nuget package allow-listing

* #23216 added MouseJumpUI.UnitTests.dll to "MS Tests" step in build-powertoys-steps.yml

* [MouseJump] fixed screenshot coords (x & y were transposed) (#23216)

* [MouseJump] close form rather than hide on deactivate (#23216)

* [MouseJump] added UI dll for signing (#23216)

* [MouseJump] close form rather than hide on deactivate (#23216)

* [MouseJump] removed redundant line

* [MouseJump] configure dpi awareness, add NLog.config (microsoft#23216)

* [MouseJump] fix spellchecker errors (microsoft#23216)

* [MouseJump] fixing comment style warning (microsoft#23216)

* [MouseJump] simplified dpi config (microsoft#23216)

* [MouseJump] fixed edge case issue with moving cursor (microsoft#23216)

* [MouseJump] fixed typo (microsoft#23216)

* [MouseJump] added attribution (microsoft#23216)

* [Mouse Jump] fix attribution link and spelling (microsoft#23216)

* Add MouseJump to installer

* Fix centralized version control

* Add Quick Access enable/disable entry

* Fix analyzer error in GPO

* Fix botched merge

* Disabled by default and remove boilerplate code

* Add GPO definitions

* Add GPO implications when starting standalone

* Update hotkey when it's changed in Settings

* Use standard Logger

* Add OOBE strings for Mouse Jump

* Add telemetry

* Update installer

* Add signing

* Add to bug report tool

* Address PR feedback
This commit is contained in:
Michael Clayton
2023-02-24 13:30:30 +00:00
committed by GitHub
parent a2e29c8c3a
commit 0524a4bddd
51 changed files with 2455 additions and 5 deletions

View File

@@ -214,6 +214,22 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool mouseJump = true;
[JsonPropertyName("MouseJump")]
public bool MouseJump
{
get => mouseJump;
set
{
if (mouseJump != value)
{
LogTelemetryEvent(value);
mouseJump = value;
}
}
}
private bool alwaysOnTop = true;
[JsonPropertyName("AlwaysOnTop")]

View File

@@ -0,0 +1,19 @@
// 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;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MouseJumpProperties
{
[JsonPropertyName("activation_shortcut")]
public HotkeySettings ActivationShortcut { get; set; }
public MouseJumpProperties()
{
ActivationShortcut = new HotkeySettings(true, false, false, true, 0x44);
}
}
}

View File

@@ -0,0 +1,35 @@
// 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 Microsoft.PowerToys.Settings.UI.Library.Interfaces;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MouseJumpSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "MouseJump";
[JsonPropertyName("properties")]
public MouseJumpProperties Properties { get; set; }
public MouseJumpSettings()
{
Name = ModuleName;
Properties = new MouseJumpProperties();
Version = "1.0";
}
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View 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 SndMouseJumpSettings
{
[JsonPropertyName("MouseJump")]
public MouseJumpSettings MouseJump { get; set; }
public SndMouseJumpSettings()
{
}
public SndMouseJumpSettings(MouseJumpSettings settings)
{
MouseJump = settings;
}
public string ToJsonString()
{
return JsonSerializer.Serialize(this);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -120,6 +120,9 @@ namespace Microsoft.PowerToys.Settings.UI
case "MouseHighlighter":
needToUpdate = generalSettingsConfig.Enabled.MouseHighlighter != isEnabled;
generalSettingsConfig.Enabled.MouseHighlighter = isEnabled; break;
case "MouseJump":
needToUpdate = generalSettingsConfig.Enabled.MouseJump != isEnabled;
generalSettingsConfig.Enabled.MouseJump = isEnabled; break;
case "MousePointerCrosshairs":
needToUpdate = generalSettingsConfig.Enabled.MousePointerCrosshairs != isEnabled;
generalSettingsConfig.Enabled.MousePointerCrosshairs = isEnabled; break;

View File

@@ -35,6 +35,13 @@
x:Uid="Oobe_MouseUtils_MousePointerCrosshairs_Description"
Background="Transparent" />
<TextBlock
x:Uid="Oobe_MouseUtils_MouseJump"
Style="{ThemeResource OobeSubtitleStyle}" />
<toolkitcontrols:MarkdownTextBlock
x:Uid="Oobe_MouseUtils_MouseJump_Description"
Background="Transparent" />
<StackPanel
Margin="0,24,0,0"
Orientation="Horizontal"

View File

@@ -2030,6 +2030,14 @@ From there, simply click on one of the supported files in the File Explorer and
<value>Draw crosshairs centered around the mouse pointer.</value>
<comment>Mouse as in the hardware peripheral.</comment>
</data>
<data name="Oobe_MouseUtils_MouseJump.Text" xml:space="preserve">
<value>Mouse Jump</value>
<comment>Mouse as in the hardware peripheral.</comment>
</data>
<data name="Oobe_MouseUtils_MouseJump_Description.Text" xml:space="preserve">
<value>Jump the mouse pointer quickly to anywhere on your desktop.</value>
<comment>Mouse as in the hardware peripheral.</comment>
</data>
<data name="Launch_Run.Content" xml:space="preserve">
<value>Launch PowerToys Run</value>
</data>
@@ -3014,4 +3022,22 @@ Activate by holding the key for the character you want to add an accent to, then
<value>The maximum size, in kilobytes, for files to be displayed. This is a safety mechanism to prevent loading large files into RAM.</value>
<comment>"RAM" refers to random access memory; "size" refers to disk space; "bytes" refer to the measurement unit</comment>
</data>
<data name="MouseUtils_MouseJump.Description" xml:space="preserve">
<value>Quickly move the mouse pointer long distances.</value>
<comment>"Mouse Jump" is the name of the utility. Mouse is the hardware mouse.</comment>
</data>
<data name="MouseUtils_MouseJump.Header" xml:space="preserve">
<value>Mouse Jump</value>
<comment>Refers to the utility name</comment>
</data>
<data name="MouseUtils_MouseJump_ActivationShortcut.Description" xml:space="preserve">
<value>Customize the shortcut to turn on or off this mode</value>
</data>
<data name="MouseUtils_MouseJump_ActivationShortcut.Header" xml:space="preserve">
<value>Activation shortcut</value>
</data>
<data name="MouseUtils_Enable_MouseJump.Header" xml:space="preserve">
<value>Enable Mouse Jump</value>
<comment>"Mouse Jump" is the name of the utility.</comment>
</data>
</root>

View File

@@ -83,6 +83,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("MouseUtils_MouseHighlighter/Header"), IsEnabled = generalSettingsConfig.Enabled.MouseHighlighter, Tag = "MouseHighlighter", Icon = "ms-appx:///Assets/FluentIcons/FluentIconsMouseHighlighter.png", EnabledChangedCallback = EnabledChangedOnUI });
}
if ((gpo = GPOWrapper.GetConfiguredMouseJumpEnabledValue()) != GpoRuleConfigured.Disabled && gpo != GpoRuleConfigured.Enabled)
{
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("MouseUtils_MouseJump/Header"), IsEnabled = generalSettingsConfig.Enabled.MouseJump, Tag = "MouseJump", Icon = "ms-appx:///Assets/FluentIcons/FluentIconsMouseJump.png", EnabledChangedCallback = EnabledChangedOnUI });
}
if ((gpo = GPOWrapper.GetConfiguredMousePointerCrosshairsEnabledValue()) != GpoRuleConfigured.Disabled && gpo != GpoRuleConfigured.Enabled)
{
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("MouseUtils_MousePointerCrosshairs/Header"), IsEnabled = generalSettingsConfig.Enabled.MousePointerCrosshairs, Tag = "MousePointerCrosshairs", Icon = "ms-appx:///Assets/FluentIcons/FluentIconsMouseCrosshairs.png", EnabledChangedCallback = EnabledChangedOnUI });
@@ -153,6 +158,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
case "ImageResizer": item.IsEnabled = generalSettingsConfig.Enabled.ImageResizer; break;
case "KeyboardManager": item.IsEnabled = generalSettingsConfig.Enabled.KeyboardManager; break;
case "MouseHighlighter": item.IsEnabled = generalSettingsConfig.Enabled.MouseHighlighter; break;
case "MouseJump": item.IsEnabled = generalSettingsConfig.Enabled.MouseJump; break;
case "MousePointerCrosshairs": item.IsEnabled = generalSettingsConfig.Enabled.MousePointerCrosshairs; break;
case "PastePlain": item.IsEnabled = generalSettingsConfig.Enabled.PastePlain; break;
case "PowerRename": item.IsEnabled = generalSettingsConfig.Enabled.PowerRename; break;

View File

@@ -21,9 +21,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private MouseHighlighterSettings MouseHighlighterSettingsConfig { get; set; }
private MouseJumpSettings MouseJumpSettingsConfig { get; set; }
private MousePointerCrosshairsSettings MousePointerCrosshairsSettingsConfig { get; set; }
public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FindMyMouseSettings> findMyMouseSettingsRepository, ISettingsRepository<MouseHighlighterSettings> mouseHighlighterSettingsRepository, ISettingsRepository<MousePointerCrosshairsSettings> mousePointerCrosshairsSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
public MouseUtilsViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FindMyMouseSettings> findMyMouseSettingsRepository, ISettingsRepository<MouseHighlighterSettings> mouseHighlighterSettingsRepository, ISettingsRepository<MouseJumpSettings> mouseJumpSettingsRepository, ISettingsRepository<MousePointerCrosshairsSettings> mousePointerCrosshairsSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
{
SettingsUtils = settingsUtils;
@@ -78,6 +80,13 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
_highlightFadeDelayMs = MouseHighlighterSettingsConfig.Properties.HighlightFadeDelayMs.Value;
_highlightFadeDurationMs = MouseHighlighterSettingsConfig.Properties.HighlightFadeDurationMs.Value;
if (mouseJumpSettingsRepository == null)
{
throw new ArgumentNullException(nameof(mouseJumpSettingsRepository));
}
MouseJumpSettingsConfig = mouseJumpSettingsRepository.SettingsConfig;
if (mousePointerCrosshairsSettingsRepository == null)
{
throw new ArgumentNullException(nameof(mousePointerCrosshairsSettingsRepository));
@@ -126,6 +135,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
_isMouseHighlighterEnabled = GeneralSettingsConfig.Enabled.MouseHighlighter;
}
_jumpEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMouseJumpEnabledValue();
if (_jumpEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _jumpEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
{
// Get the enabled state from GPO.
_jumpEnabledStateIsGPOConfigured = true;
_isMouseJumpEnabled = _jumpEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
}
else
{
_isMouseJumpEnabled = GeneralSettingsConfig.Enabled.MouseJump;
}
_mousePointerCrosshairsEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMousePointerCrosshairsEnabledValue();
if (_mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
{
@@ -530,6 +551,64 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
SettingsUtils.SaveSettings(MouseHighlighterSettingsConfig.ToJsonString(), MouseHighlighterSettings.ModuleName);
}
public bool IsMouseJumpEnabled
{
get => _isMouseJumpEnabled;
set
{
if (_jumpEnabledStateIsGPOConfigured)
{
// If it's GPO configured, shouldn't be able to change this state.
return;
}
if (_isMouseJumpEnabled != value)
{
_isMouseJumpEnabled = value;
GeneralSettingsConfig.Enabled.MouseJump = value;
OnPropertyChanged(nameof(_isMouseJumpEnabled));
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(outgoing.ToString());
NotifyMouseJumpPropertyChanged();
}
}
}
public bool IsJumpEnabledGpoConfigured
{
get => _jumpEnabledStateIsGPOConfigured;
}
public HotkeySettings MouseJumpActivationShortcut
{
get
{
return MouseJumpSettingsConfig.Properties.ActivationShortcut;
}
set
{
if (MouseJumpSettingsConfig.Properties.ActivationShortcut != value)
{
MouseJumpSettingsConfig.Properties.ActivationShortcut = value;
NotifyMouseJumpPropertyChanged();
}
}
}
public void NotifyMouseJumpPropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(propertyName);
SndMouseJumpSettings outsettings = new SndMouseJumpSettings(MouseJumpSettingsConfig);
SndModuleSettings<SndMouseJumpSettings> ipcMessage = new SndModuleSettings<SndMouseJumpSettings>(outsettings);
SendConfigMSG(ipcMessage.ToJsonString());
SettingsUtils.SaveSettings(MouseJumpSettingsConfig.ToJsonString(), MouseJumpSettings.ModuleName);
}
public bool IsMousePointerCrosshairsEnabled
{
get => _isMousePointerCrosshairsEnabled;
@@ -703,6 +782,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
InitializeEnabledValues();
OnPropertyChanged(nameof(IsFindMyMouseEnabled));
OnPropertyChanged(nameof(IsMouseHighlighterEnabled));
OnPropertyChanged(nameof(IsMouseJumpEnabled));
OnPropertyChanged(nameof(IsMousePointerCrosshairsEnabled));
}
@@ -732,6 +812,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private int _highlightFadeDelayMs;
private int _highlightFadeDurationMs;
private GpoRuleConfigured _jumpEnabledGpoRuleConfiguration;
private bool _jumpEnabledStateIsGPOConfigured;
private bool _isMouseJumpEnabled;
private GpoRuleConfigured _mousePointerCrosshairsEnabledGpoRuleConfiguration;
private bool _mousePointerCrosshairsEnabledStateIsGPOConfigured;
private bool _isMousePointerCrosshairsEnabled;

View File

@@ -206,6 +206,31 @@
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseUtils_MouseJump">
<labs:SettingsCard
x:Uid="MouseUtils_Enable_MouseJump"
HeaderIcon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsMouseJump.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsJumpEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsMouseJumpEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsJumpEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsJumpEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="MouseUtils_MouseJump_ActivationShortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}"
IsEnabled="{x:Bind ViewModel.IsMouseJumpEnabled, Mode=OneWay}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.MouseJumpActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseUtils_MousePointerCrosshairs">
<labs:SettingsCard
x:Uid="MouseUtils_Enable_MousePointerCrosshairs"
@@ -296,6 +321,9 @@
<controls:PageLink
Link="https://devblogs.microsoft.com/oldnewthing/author/oldnewthing"
Text="Raymond Chen's Find My Mouse" />
<controls:PageLink
Link="https://michael-clayton.com/projects/fancymouse"
Text="Michael Clayton's Mouse Jump (FancyMouse)" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -37,6 +37,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<FindMyMouseSettings>.GetInstance(settingsUtils),
SettingsRepository<MouseHighlighterSettings>.GetInstance(settingsUtils),
SettingsRepository<MouseJumpSettings>.GetInstance(settingsUtils),
SettingsRepository<MousePointerCrosshairsSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage);