mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
[DSC] Implement Microsoft.PowerToys.Configure DSCResource & winget support (#30918)
* [DSC] Microsoft.PowerToys.Configure module + winget configuration file support
* f: fix for an incorrect directory id reference
* f: update comment
* f: address review comments
* f: file locksmith bug fix
* f: add explorer preview switches in samples
* f: remove debug
* Sign DSC files
* f: implement docs/samples generator
* [ci]Sign FancyZonesEditorCommon.dll
* Sign DSC files in the Generated folder
* f: address review comments
* f: update usable options
* f: add autogenerated sample
* [Installer] Don't use same GUID for different components
* [Installer]Don't remove folders shared by other modules
* Allow configuring PTRun MaximumNumberOfResults
* Remove all settings DSC sample. Just random data
* Allow configuring Hosts Run as Administrator
* Revert "[Installer]Don't remove folders shared by other modules"
This reverts commit 6da3d6cfd5.
* Add all PTRun plugins and Global and keyboard to DSC sample
* Fix issues with context menu modules not disabling
* Fix default enabled values when setting with DSC
* Fix tests regarding default modules in Settings
* Fix merge error
* Restart PowerToys process if we stopped it
---------
Co-authored-by: Andrey Nekrasov <1828123+yuyoyuppe@users.noreply.github.com>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
// 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;
|
||||
|
||||
namespace Settings.UI.Library.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// Adding this attribute to a property makes it not configurable from the command line.
|
||||
/// Typical use cases:
|
||||
/// - Property represents internal module state.
|
||||
/// - Property has a type that is unwieldy to type as a command line string.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class CmdConfigureIgnoreAttribute : Attribute;
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -36,6 +37,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public DateTimeOffset ExpirationDateTime { get; set; }
|
||||
|
||||
[JsonPropertyName("customTrayTimes")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public Dictionary<string, int> CustomTrayTimes { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class BoolProperty
|
||||
public record BoolProperty : ICmdLineRepresentable
|
||||
{
|
||||
public BoolProperty()
|
||||
{
|
||||
@@ -22,9 +22,28 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("value")]
|
||||
public bool Value { get; set; }
|
||||
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (!bool.TryParse(cmd, out bool value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = new BoolProperty { Value = value };
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
result = Value.ToString();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,13 @@ using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Enumerations;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class ColorPickerProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x43);
|
||||
|
||||
public ColorPickerProperties()
|
||||
@@ -43,6 +45,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
[JsonPropertyName("changecursor")]
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool ChangeCursor { get; set; }
|
||||
|
||||
[JsonPropertyName("copiedcolorrepresentation")]
|
||||
@@ -53,12 +56,15 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
// Property ColorHistory is not used, the color history is saved separately in the colorHistory.json file
|
||||
[JsonPropertyName("colorhistory")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public List<string> ColorHistory { get; set; }
|
||||
|
||||
[JsonPropertyName("colorhistorylimit")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public int ColorHistoryLimit { get; set; }
|
||||
|
||||
[JsonPropertyName("visiblecolorformats")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public Dictionary<string, KeyValuePair<bool, string>> VisibleColorFormats { get; set; }
|
||||
|
||||
[JsonPropertyName("showcolorname")]
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
private Action notifyEnabledChangedAction;
|
||||
|
||||
// Default values for enabled modules should match their expected "enabled by default" values.
|
||||
// Otherwise, a run of DSC on clean settings will not match the expected default result.
|
||||
public EnabledModules()
|
||||
{
|
||||
}
|
||||
@@ -55,7 +57,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
private bool fileExplorerPreview = true;
|
||||
|
||||
[JsonPropertyName("File Explorer Preview")]
|
||||
public bool FileExplorerPreview
|
||||
public bool PowerPreview
|
||||
{
|
||||
get => fileExplorerPreview;
|
||||
set
|
||||
@@ -116,7 +118,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool keyboardManager = true;
|
||||
private bool keyboardManager; // defaulting to off
|
||||
|
||||
[JsonPropertyName("Keyboard Manager")]
|
||||
public bool KeyboardManager
|
||||
@@ -183,7 +185,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool awake;
|
||||
private bool awake = true;
|
||||
|
||||
[JsonPropertyName("Awake")]
|
||||
public bool Awake
|
||||
@@ -199,7 +201,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool mouseWithoutBorders = true;
|
||||
private bool mouseWithoutBorders; // defaulting to off
|
||||
|
||||
[JsonPropertyName("MouseWithoutBorders")]
|
||||
public bool MouseWithoutBorders
|
||||
@@ -247,7 +249,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool mouseJump = true;
|
||||
private bool mouseJump; // defaulting to off
|
||||
|
||||
[JsonPropertyName("MouseJump")]
|
||||
public bool MouseJump
|
||||
@@ -279,7 +281,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool mousePointerCrosshairs = true;
|
||||
private bool mousePointerCrosshairs; // defaulting to off
|
||||
|
||||
[JsonPropertyName("MousePointerCrosshairs")]
|
||||
public bool MousePointerCrosshairs
|
||||
@@ -295,7 +297,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool powerAccent;
|
||||
private bool powerAccent; // defaulting to off
|
||||
|
||||
[JsonPropertyName("QuickAccent")]
|
||||
public bool PowerAccent
|
||||
@@ -311,10 +313,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool powerOCR = true;
|
||||
private bool powerOCR; // defaulting to off
|
||||
|
||||
[JsonPropertyName("TextExtractor")]
|
||||
public bool PowerOCR
|
||||
public bool PowerOcr
|
||||
{
|
||||
get => powerOCR;
|
||||
set
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -110,6 +111,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public BoolProperty FancyzonesMakeDraggedWindowTransparent { get; set; }
|
||||
|
||||
[JsonPropertyName("fancyzones_allowPopupWindowSnap")]
|
||||
[CmdConfigureIgnore]
|
||||
public BoolProperty FancyzonesAllowPopupWindowSnap { get; set; }
|
||||
|
||||
[JsonPropertyName("fancyzones_allowChildWindowSnap")]
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// 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 FindMyMouseProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x46);
|
||||
|
||||
[JsonPropertyName("activation_method")]
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Text.Json.Serialization;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -18,15 +19,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public bool Startup { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether the powertoy elevated.
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
[JsonPropertyName("is_elevated")]
|
||||
public bool IsElevated { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether powertoys should run elevated.
|
||||
[JsonPropertyName("run_elevated")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool RunElevated { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether is admin.
|
||||
[JsonPropertyName("is_admin")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool IsAdmin { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether is warnings of elevated apps enabled.
|
||||
@@ -39,16 +43,20 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
// Gets or sets system theme name.
|
||||
[JsonPropertyName("system_theme")]
|
||||
[CmdConfigureIgnore]
|
||||
public string SystemTheme { get; set; }
|
||||
|
||||
// Gets or sets powertoys version number.
|
||||
[JsonPropertyName("powertoys_version")]
|
||||
[CmdConfigureIgnore]
|
||||
public string PowertoysVersion { get; set; }
|
||||
|
||||
[JsonPropertyName("action_name")]
|
||||
[CmdConfigureIgnore]
|
||||
public string CustomActionName { get; set; }
|
||||
|
||||
[JsonPropertyName("enabled")]
|
||||
[CmdConfigureIgnore]
|
||||
public EnabledModules Enabled { get; set; }
|
||||
|
||||
[JsonPropertyName("show_new_updates_toast_notification")]
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class GenericProperty<T>
|
||||
public class GenericProperty<T> : ICmdLineRepresentable
|
||||
{
|
||||
[JsonPropertyName("value")]
|
||||
public T Value { get; set; }
|
||||
@@ -20,5 +21,25 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public GenericProperty()
|
||||
{
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Adding ICmdLineRepresentable support")]
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (ICmdLineRepresentable.TryParseFromCmdFor(typeof(T), cmd, out var value))
|
||||
{
|
||||
result = new GenericProperty<T> { Value = (T)value };
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
result = Value.ToString();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
using Settings.UI.Library.Enumerations;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class HotkeySettings
|
||||
public record HotkeySettings : ICmdLineRepresentable
|
||||
{
|
||||
private const int VKTAB = 0x09;
|
||||
|
||||
@@ -39,11 +41,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
Code = code;
|
||||
}
|
||||
|
||||
public HotkeySettings Clone()
|
||||
{
|
||||
return new HotkeySettings(Win, Ctrl, Alt, Shift, Code);
|
||||
}
|
||||
|
||||
[JsonPropertyName("win")]
|
||||
public bool Win { get; set; }
|
||||
|
||||
@@ -176,5 +173,72 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
bool win = false, ctrl = false, alt = false, shift = false;
|
||||
int code = 0;
|
||||
|
||||
var parts = cmd.Split('+');
|
||||
foreach (var part in parts)
|
||||
{
|
||||
switch (part.Trim().ToLower(CultureInfo.InvariantCulture))
|
||||
{
|
||||
case "win":
|
||||
win = true;
|
||||
break;
|
||||
case "ctrl":
|
||||
ctrl = true;
|
||||
break;
|
||||
case "alt":
|
||||
alt = true;
|
||||
break;
|
||||
case "shift":
|
||||
shift = true;
|
||||
break;
|
||||
default:
|
||||
if (!TryParseKeyCode(part, out code))
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = new HotkeySettings(win, ctrl, alt, shift, code);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryParseKeyCode(string key, out int keyCode)
|
||||
{
|
||||
// ASCII symbol
|
||||
if (key.Length == 1 && char.IsLetterOrDigit(key[0]))
|
||||
{
|
||||
keyCode = char.ToUpper(key[0], CultureInfo.InvariantCulture);
|
||||
return true;
|
||||
}
|
||||
|
||||
// VK code
|
||||
else if (key.Length == 4 && key.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return int.TryParse(key.AsSpan(2), NumberStyles.HexNumber, null, out keyCode);
|
||||
}
|
||||
|
||||
// Alias
|
||||
else
|
||||
{
|
||||
keyCode = (int)Utilities.Helper.GetKeyValue(key);
|
||||
return keyCode != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
result = ToString();
|
||||
result = result.Replace(" ", null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -69,6 +70,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public StringProperty ImageresizerFileName { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_sizes")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public ImageResizerSizes ImageresizerSizes { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_keepDateModified")]
|
||||
@@ -78,6 +80,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public StringProperty ImageresizerFallbackEncoder { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_customSize")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public ImageResizerCustomSizeProperty ImageresizerCustomSize { get; set; }
|
||||
|
||||
public string ToJsonString()
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
// Represents the configuration property of the settings that store Integer type.
|
||||
public class IntProperty
|
||||
public record IntProperty : ICmdLineRepresentable
|
||||
{
|
||||
public IntProperty()
|
||||
{
|
||||
@@ -25,6 +26,19 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("value")]
|
||||
public int Value { get; set; }
|
||||
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (!int.TryParse(cmd, out var value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = new IntProperty { Value = value };
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns a JSON version of the class settings configuration class.
|
||||
public override string ToString()
|
||||
{
|
||||
@@ -40,5 +54,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
result = Value.ToString(CultureInfo.InvariantCulture);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
// 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;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
/// <summary>
|
||||
/// A helper interface to allow parsing property values from their command line representation.
|
||||
/// </summary>
|
||||
public interface ICmdLineRepresentable
|
||||
{
|
||||
public static abstract bool TryParseFromCmd(string cmd, out object result);
|
||||
|
||||
public abstract bool TryToCmdRepresentable(out string result);
|
||||
|
||||
public static sealed bool TryToCmdRepresentableFor(Type type, object value, out string result)
|
||||
{
|
||||
result = null;
|
||||
if (!typeof(ICmdLineRepresentable).IsAssignableFrom(type))
|
||||
{
|
||||
throw new ArgumentException($"{type} doesn't implement {nameof(ICmdLineRepresentable)}");
|
||||
}
|
||||
|
||||
var method = type.GetMethod(nameof(TryToCmdRepresentable));
|
||||
var parameters = new object[] { result };
|
||||
if ((bool)method.Invoke(value, parameters))
|
||||
{
|
||||
result = (string)parameters[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static sealed bool TryParseFromCmdFor(Type type, string cmd, out object result)
|
||||
{
|
||||
result = null;
|
||||
if (!typeof(ICmdLineRepresentable).IsAssignableFrom(type))
|
||||
{
|
||||
throw new ArgumentException($"{type} doesn't implement {nameof(ICmdLineRepresentable)}");
|
||||
}
|
||||
|
||||
var method = type.GetMethod(nameof(TryParseFromCmd), BindingFlags.Static | BindingFlags.Public);
|
||||
var parameters = new object[] { cmd, null };
|
||||
if ((bool)method.Invoke(null, parameters))
|
||||
{
|
||||
result = parameters[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static sealed object ParseFor(Type type, string cmdRepr)
|
||||
{
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return Enum.Parse(type, cmdRepr);
|
||||
}
|
||||
else if (type.IsPrimitive)
|
||||
{
|
||||
if (type == typeof(bool))
|
||||
{
|
||||
return bool.Parse(cmdRepr.ToLowerInvariant());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Converts numeric types like Uint32
|
||||
return Convert.ChangeType(cmdRepr, type, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
else if (type.IsValueType && type == typeof(DateTimeOffset))
|
||||
{
|
||||
if (DateTimeOffset.TryParse(cmdRepr, out var structResult))
|
||||
{
|
||||
return structResult;
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid DateTimeOffset format '{cmdRepr}'");
|
||||
}
|
||||
else if (type.IsClass)
|
||||
{
|
||||
if (type == typeof(string))
|
||||
{
|
||||
return cmdRepr;
|
||||
}
|
||||
else
|
||||
{
|
||||
TryParseFromCmdFor(type, cmdRepr, out var classResult);
|
||||
return classResult;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"Parsing type {type} is not supported yet");
|
||||
}
|
||||
|
||||
public static string ToCmdRepr(Type type, object value)
|
||||
{
|
||||
if (type.IsEnum || type.IsPrimitive)
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
else if (type.IsValueType && type == typeof(DateTimeOffset))
|
||||
{
|
||||
return ((DateTimeOffset)value).ToString("o");
|
||||
}
|
||||
else if (type.IsClass)
|
||||
{
|
||||
if (type == typeof(string))
|
||||
{
|
||||
return (string)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
TryToCmdRepresentableFor(type, value, out var result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"CmdRepr of {type} is not supported yet");
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,12 @@
|
||||
// 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.Globalization;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class KeyboardKeysProperty
|
||||
public record KeyboardKeysProperty : ICmdLineRepresentable
|
||||
{
|
||||
public KeyboardKeysProperty()
|
||||
{
|
||||
@@ -20,5 +21,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
[JsonPropertyName("value")]
|
||||
public HotkeySettings Value { get; set; }
|
||||
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
if (!HotkeySettings.TryParseFromCmd(cmd, out var hotkey))
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new KeyboardKeysProperty { Value = (HotkeySettings)hotkey };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
return Value.TryToCmdRepresentable(out result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class KeyboardManagerProperties
|
||||
{
|
||||
[JsonPropertyName("activeConfiguration")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public GenericProperty<string> ActiveConfiguration { get; set; }
|
||||
|
||||
// List of all Keyboard Configurations.
|
||||
[JsonPropertyName("keyboardConfigurations")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public GenericProperty<List<string>> KeyboardConfigurations { get; set; }
|
||||
|
||||
public KeyboardManagerProperties()
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
using Settings.UI.Library.Enumerations;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class MeasureToolProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x4D);
|
||||
|
||||
public MeasureToolProperties()
|
||||
@@ -35,6 +37,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool PerColorChannelEdgeDetection { get; set; }
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
public IntProperty UnitsOfMeasure { get; set; }
|
||||
|
||||
public IntProperty PixelTolerance { get; set; }
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// 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 MouseHighlighterProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x48);
|
||||
|
||||
[JsonPropertyName("activation_shortcut")]
|
||||
@@ -20,6 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public StringProperty RightButtonClickColor { get; set; }
|
||||
|
||||
[JsonPropertyName("highlight_opacity")]
|
||||
[CmdConfigureIgnore]
|
||||
public IntProperty HighlightOpacity { get; set; }
|
||||
|
||||
[JsonPropertyName("always_color")]
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// 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 MouseJumpProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x44);
|
||||
|
||||
[JsonPropertyName("activation_shortcut")]
|
||||
|
||||
@@ -9,7 +9,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class MouseJumpThumbnailSize : INotifyPropertyChanged
|
||||
public record MouseJumpThumbnailSize : INotifyPropertyChanged, ICmdLineRepresentable
|
||||
{
|
||||
private int _width;
|
||||
private int _height;
|
||||
@@ -64,5 +64,30 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
var parts = cmd.Split('x');
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (int.TryParse(parts[0], out int width) && int.TryParse(parts[1], out int height))
|
||||
{
|
||||
result = new MouseJumpThumbnailSize { Width = width, Height = height };
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
result = $"{Width}x{Height}";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// 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 MousePointerCrosshairsProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, true, false, 0x50); // Win + Alt + P
|
||||
|
||||
[JsonPropertyName("activation_shortcut")]
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -23,16 +24,22 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
public class MouseWithoutBordersProperties : ICloneable
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public static HotkeySettings DefaultHotKeySwitch2AllPC => new HotkeySettings();
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
public static HotkeySettings DefaultHotKeyLockMachine => new HotkeySettings(true, true, true, false, 0x4C);
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
public static HotkeySettings DefaultHotKeyReconnect => new HotkeySettings(true, true, true, false, 0x52);
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
public static HotkeySettings DefaultHotKeyToggleEasyMouse => new HotkeySettings(true, true, true, false, 0x45);
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
public StringProperty SecurityKey { get; set; }
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool UseService { get; set; }
|
||||
|
||||
@@ -72,42 +79,54 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool ShowClipboardAndNetworkStatusMessages { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public List<string> MachineMatrixString { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public StringProperty MachinePool { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool MatrixOneRow { get; set; }
|
||||
|
||||
public IntProperty EasyMouse { get; set; }
|
||||
|
||||
[CmdConfigureIgnore]
|
||||
public IntProperty MachineID { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty LastX { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty LastY { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty PackageID { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool FirstRun { get; set; }
|
||||
|
||||
public IntProperty HotKeySwitchMachine { get; set; }
|
||||
|
||||
[ObsoleteAttribute("Use ToggleEasyMouseShortcut instead", false)]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty HotKeyToggleEasyMouse { get; set; }
|
||||
|
||||
[ObsoleteAttribute("Use LockMachineShortcut instead", false)]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty HotKeyLockMachine { get; set; }
|
||||
|
||||
[ObsoleteAttribute("Use ReconnectShortcut instead", false)]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty HotKeyReconnect { get; set; }
|
||||
|
||||
[ObsoleteAttribute("Use Switch2AllPCShortcut instead", false)]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty HotKeySwitch2AllPC { get; set; }
|
||||
|
||||
public HotkeySettings ToggleEasyMouseShortcut { get; set; }
|
||||
@@ -118,6 +137,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
public HotkeySettings Switch2AllPCShortcut { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public IntProperty TCPPort { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
@@ -126,8 +146,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public StringProperty Name2IP { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool FirstCtrlShiftS { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public StringProperty DeviceID { get; set; }
|
||||
|
||||
public MouseWithoutBordersProperties()
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PastePlainProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, true, true, false, 0x56); // Ctrl+Win+Alt+V
|
||||
|
||||
public PastePlainProperties()
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PeekProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(false, true, false, false, 0x20);
|
||||
|
||||
public PeekProperties()
|
||||
|
||||
@@ -4,15 +4,18 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using ManagedCommon;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PowerLauncherProperties
|
||||
{
|
||||
[JsonPropertyName("search_result_preference")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public string SearchResultPreference { get; set; }
|
||||
|
||||
[JsonPropertyName("search_type_preference")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public string SearchTypePreference { get; set; }
|
||||
|
||||
[JsonPropertyName("maximum_number_of_results")]
|
||||
@@ -22,18 +25,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public HotkeySettings OpenPowerLauncher { get; set; }
|
||||
|
||||
[JsonPropertyName("open_file_location")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings OpenFileLocation { get; set; }
|
||||
|
||||
[JsonPropertyName("copy_path_location")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings CopyPathLocation { get; set; }
|
||||
|
||||
[JsonPropertyName("open_console")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings OpenConsole { get; set; }
|
||||
|
||||
[JsonPropertyName("override_win_r_key")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool OverrideWinkeyR { get; set; }
|
||||
|
||||
[JsonPropertyName("override_win_s_key")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public bool OverrideWinkeyS { get; set; }
|
||||
|
||||
[JsonPropertyName("ignore_hotkeys_in_fullscreen")]
|
||||
@@ -49,6 +57,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public Theme Theme { get; set; }
|
||||
|
||||
[JsonPropertyName("show_plugins_overview")]
|
||||
[CmdConfigureIgnore]
|
||||
public int ShowPluginsOverview { get; set; }
|
||||
|
||||
[JsonPropertyName("title_fontsize")]
|
||||
@@ -84,10 +93,13 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("generate_thumbnails_from_files")]
|
||||
public bool GenerateThumbnailsFromFiles { get; set; }
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultOpenPowerLauncher => new HotkeySettings(false, false, true, false, 32);
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultOpenFileLocation => new HotkeySettings();
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultCopyPathLocation => new HotkeySettings();
|
||||
|
||||
public PowerLauncherProperties()
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PowerOcrProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x54); // Win+Shift+T
|
||||
|
||||
public PowerOcrProperties()
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// 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;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -16,12 +18,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
ShowIcon = new BoolProperty();
|
||||
ExtendedContextMenuOnly = new BoolProperty();
|
||||
UseBoostLib = new BoolProperty();
|
||||
Enabled = new BoolProperty();
|
||||
}
|
||||
|
||||
[ObsoleteAttribute("Now controlled from the general settings", false)]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public BoolProperty Enabled { get; set; }
|
||||
|
||||
[JsonPropertyName("bool_persist_input")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public BoolProperty PersistState { get; set; }
|
||||
|
||||
[JsonPropertyName("bool_mru_enabled")]
|
||||
@@ -31,6 +35,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public IntProperty MaxMRUSize { get; set; }
|
||||
|
||||
[JsonPropertyName("bool_show_icon_on_menu")]
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public BoolProperty ShowIcon { get; set; }
|
||||
|
||||
[JsonPropertyName("bool_show_extended_menu")]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\Version.props" />
|
||||
<Import Project="..\..\Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0-windows</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Version>$(Version).0</Version>
|
||||
<Authors>Microsoft Corporation</Authors>
|
||||
@@ -20,42 +22,42 @@
|
||||
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="backup_restore_settings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<None Include="backup_restore_settings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Abstractions" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Abstractions" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Resources\Resources.Designer.cs">
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Resources\Resources.Designer.cs">
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\Resources.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\Resources.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// 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 ShortcutGuideProperties
|
||||
{
|
||||
[CmdConfigureIgnore]
|
||||
public HotkeySettings DefaultOpenShortcutGuide => new HotkeySettings(true, false, false, true, 0xBF);
|
||||
|
||||
public ShortcutGuideProperties()
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Text.Json.Serialization;
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
// Represents the configuration property of the settings that store string type.
|
||||
public class StringProperty
|
||||
public record StringProperty : ICmdLineRepresentable
|
||||
{
|
||||
public StringProperty()
|
||||
{
|
||||
@@ -35,6 +35,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
return new StringProperty(v);
|
||||
}
|
||||
|
||||
public static bool TryParseFromCmd(string cmd, out object result)
|
||||
{
|
||||
result = new StringProperty(cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryToCmdRepresentable(out string result)
|
||||
{
|
||||
result = Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static implicit operator StringProperty(string v)
|
||||
{
|
||||
return new StringProperty(v);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// 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;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
public class CommandLineUtils
|
||||
{
|
||||
private static Type GetSettingsConfigType(string moduleName, Assembly settingsLibraryAssembly)
|
||||
{
|
||||
var settingsClassName = moduleName == "GeneralSettings" ? moduleName : moduleName + "Settings";
|
||||
return settingsLibraryAssembly.GetType(typeof(CommandLineUtils).Namespace + "." + settingsClassName);
|
||||
}
|
||||
|
||||
public static ISettingsConfig GetSettingsConfigFor(string moduleName, ISettingsUtils settingsUtils, Assembly settingsLibraryAssembly)
|
||||
{
|
||||
return GetSettingsConfigFor(GetSettingsConfigType(moduleName, settingsLibraryAssembly), settingsUtils);
|
||||
}
|
||||
|
||||
/// Executes SettingsRepository<moduleSettingsType>.GetInstance(settingsUtils).SettingsConfig
|
||||
public static ISettingsConfig GetSettingsConfigFor(Type moduleSettingsType, ISettingsUtils settingsUtils)
|
||||
{
|
||||
var genericSettingsRepositoryType = typeof(SettingsRepository<>);
|
||||
var moduleSettingsRepositoryType = genericSettingsRepositoryType.MakeGenericType(moduleSettingsType);
|
||||
|
||||
// Note: GeneralSettings is only used here only to satisfy nameof constrains, i.e. the choice of this particular type doesn't have any special significance.
|
||||
var getInstanceInfo = moduleSettingsRepositoryType.GetMethod(nameof(SettingsRepository<GeneralSettings>.GetInstance));
|
||||
var settingsRepository = getInstanceInfo.Invoke(null, new object[] { settingsUtils });
|
||||
var settingsConfigProperty = getInstanceInfo.ReturnType.GetProperty(nameof(SettingsRepository<GeneralSettings>.SettingsConfig));
|
||||
return settingsConfigProperty.GetValue(settingsRepository) as ISettingsConfig;
|
||||
}
|
||||
|
||||
public static Assembly GetSettingsAssembly()
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies()
|
||||
.FirstOrDefault(a => a.GetName().Name == "PowerToys.Settings.UI.Lib");
|
||||
}
|
||||
|
||||
public static object GetPropertyValue(string propertyName, ISettingsConfig settingsConfig)
|
||||
{
|
||||
var (settingInfo, properties) = LocateSetting(propertyName, settingsConfig);
|
||||
return settingInfo.GetValue(properties);
|
||||
}
|
||||
|
||||
public static object GetProperties(ISettingsConfig settingsConfig)
|
||||
{
|
||||
var settingsType = settingsConfig.GetType();
|
||||
if (settingsType == typeof(GeneralSettings))
|
||||
{
|
||||
return settingsConfig;
|
||||
}
|
||||
|
||||
var settingsConfigInfo = settingsType.GetProperty("Properties");
|
||||
return settingsConfigInfo.GetValue(settingsConfig);
|
||||
}
|
||||
|
||||
public static (PropertyInfo SettingInfo, object Properties) LocateSetting(string propertyName, ISettingsConfig settingsConfig)
|
||||
{
|
||||
var properties = GetProperties(settingsConfig);
|
||||
var propertiesType = properties.GetType();
|
||||
if (propertiesType == typeof(GeneralSettings) && propertyName.StartsWith("Enabled.", StringComparison.InvariantCulture))
|
||||
{
|
||||
var moduleNameToToggle = propertyName.Replace("Enabled.", string.Empty);
|
||||
properties = propertiesType.GetProperty("Enabled").GetValue(properties);
|
||||
propertiesType = properties.GetType();
|
||||
propertyName = moduleNameToToggle;
|
||||
}
|
||||
|
||||
return (propertiesType.GetProperty(propertyName), properties);
|
||||
}
|
||||
|
||||
public static PropertyInfo GetSettingPropertyInfo(string propertyName, ISettingsConfig settingsConfig)
|
||||
{
|
||||
return LocateSetting(propertyName, settingsConfig).SettingInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Xml;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
/// <summary>
|
||||
/// This user flow allows DSC resources to use PowerToys.Settings executable to get settings values by querying them from command line using the following syntax:
|
||||
/// PowerToys.Settings.exe get <path to a json file containing a list of modules and their corresponding properties>
|
||||
///
|
||||
/// Example: PowerToys.Settings.exe get %TEMP%\properties.json
|
||||
/// `properties.json` file contents:
|
||||
/// {
|
||||
/// "AlwaysOnTop": ["FrameEnabled", "FrameAccentColor"],
|
||||
/// "FancyZones": ["FancyzonesShiftDrag", "FancyzonesShowOnAllMonitors"]
|
||||
/// }
|
||||
///
|
||||
/// Upon PowerToys.Settings.exe completion, it'll update `properties.json` file to contain something like this:
|
||||
/// {
|
||||
/// "AlwaysOnTop": {
|
||||
/// "FrameEnabled": true,
|
||||
/// "FrameAccentColor": "#0099cc"
|
||||
/// },
|
||||
/// "FancyZones": {
|
||||
/// "FancyzonesShiftDrag": true,
|
||||
/// "FancyzonesShowOnAllMonitors": false
|
||||
/// }
|
||||
/// }
|
||||
/// </summary>
|
||||
public sealed class GetSettingCommandLineCommand
|
||||
{
|
||||
private static JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
};
|
||||
|
||||
public static string Execute(Dictionary<string, List<string>> settingNamesForModules)
|
||||
{
|
||||
var modulesSettings = new Dictionary<string, Dictionary<string, object>>();
|
||||
|
||||
var settingsAssembly = CommandLineUtils.GetSettingsAssembly();
|
||||
var settingsUtils = new SettingsUtils();
|
||||
|
||||
var enabledModules = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Enabled;
|
||||
|
||||
foreach (var (moduleName, settings) in settingNamesForModules)
|
||||
{
|
||||
var moduleSettings = new Dictionary<string, object>();
|
||||
if (moduleName != nameof(GeneralSettings))
|
||||
{
|
||||
moduleSettings.Add("Enabled", typeof(EnabledModules).GetProperty(moduleName).GetValue(enabledModules));
|
||||
}
|
||||
|
||||
var settingsConfig = CommandLineUtils.GetSettingsConfigFor(moduleName, settingsUtils, settingsAssembly);
|
||||
foreach (var settingName in settings)
|
||||
{
|
||||
var value = CommandLineUtils.GetPropertyValue(settingName, settingsConfig);
|
||||
if (value != null)
|
||||
{
|
||||
var cmdReprValue = ICmdLineRepresentable.ToCmdRepr(value.GetType(), value);
|
||||
moduleSettings.Add(settingName, cmdReprValue);
|
||||
}
|
||||
}
|
||||
|
||||
modulesSettings.Add(moduleName, moduleSettings);
|
||||
}
|
||||
|
||||
return JsonSerializer.Serialize(modulesSettings, _serializerOptions);
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
return LayoutMap.GetKeyName(key);
|
||||
}
|
||||
|
||||
public static uint GetKeyValue(string key)
|
||||
{
|
||||
return LayoutMap.GetKeyValue(key);
|
||||
}
|
||||
|
||||
public static string GetProductVersion()
|
||||
{
|
||||
return interop.CommonManaged.GetProductVersion();
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
/// <summary>
|
||||
/// This user flow allows DSC resources to use PowerToys.Settings executable to set custom settings values by suppling them from command line using the following syntax:
|
||||
/// PowerToys.Settings.exe setAdditional <module struct name> <path to a json file containing the properties>
|
||||
/// </summary>
|
||||
public sealed class SetAdditionalSettingsCommandLineCommand
|
||||
{
|
||||
private static readonly string KeyPropertyName = "Name";
|
||||
|
||||
private static JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
};
|
||||
|
||||
private struct AdditionalPropertyInfo
|
||||
{
|
||||
public string RootPropertyName;
|
||||
public JsonValueKind RootObjectType;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, AdditionalPropertyInfo> SupportedAdditionalPropertiesInfoForModules = new Dictionary<string, AdditionalPropertyInfo> { { "PowerLauncher", new AdditionalPropertyInfo { RootPropertyName = "Plugins", RootObjectType = JsonValueKind.Array } } };
|
||||
|
||||
private static void ExecuteRootArray(JsonElement.ArrayEnumerator properties, IEnumerable<object> currentPropertyValuesArray)
|
||||
{
|
||||
// In case it's an array of object -> combine the existing values with the provided
|
||||
var currentPropertyValueType = currentPropertyValuesArray.FirstOrDefault()?.GetType();
|
||||
|
||||
object matchedElement = null;
|
||||
foreach (var arrayElement in properties)
|
||||
{
|
||||
var newElementPropertyValues = new Dictionary<string, object>();
|
||||
foreach (var elementProperty in arrayElement.EnumerateObject())
|
||||
{
|
||||
var elementPropertyName = elementProperty.Name;
|
||||
var elementPropertyType = currentPropertyValueType.GetProperty(elementPropertyName).PropertyType;
|
||||
var elemePropertyValue = ICmdLineRepresentable.ParseFor(elementPropertyType, elementProperty.Value.ToString());
|
||||
if (elementPropertyName == KeyPropertyName)
|
||||
{
|
||||
foreach (var currentElementValue in currentPropertyValuesArray)
|
||||
{
|
||||
var currentElementType = currentElementValue.GetType();
|
||||
var keyPropertyNameInfo = currentElementType.GetProperty(KeyPropertyName);
|
||||
var keyPropertyValue = keyPropertyNameInfo.GetValue(currentElementValue);
|
||||
if (string.Equals(keyPropertyValue, elemePropertyValue))
|
||||
{
|
||||
matchedElement = currentElementValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newElementPropertyValues.Add(elementPropertyName, elemePropertyValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (matchedElement != null)
|
||||
{
|
||||
foreach (var overriddenProperty in newElementPropertyValues)
|
||||
{
|
||||
var propertyInfo = currentPropertyValueType.GetProperty(overriddenProperty.Key);
|
||||
propertyInfo.SetValue(matchedElement, overriddenProperty.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Execute(string moduleName, JsonDocument settings, ISettingsUtils settingsUtils)
|
||||
{
|
||||
Assembly settingsLibraryAssembly = CommandLineUtils.GetSettingsAssembly();
|
||||
|
||||
var settingsConfig = CommandLineUtils.GetSettingsConfigFor(moduleName, settingsUtils, settingsLibraryAssembly);
|
||||
var settingsConfigType = settingsConfig.GetType();
|
||||
|
||||
if (!SupportedAdditionalPropertiesInfoForModules.TryGetValue(moduleName, out var additionalPropertiesInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var propertyValueInfo = settingsConfigType.GetProperty(additionalPropertiesInfo.RootPropertyName);
|
||||
var currentPropertyValue = propertyValueInfo.GetValue(settingsConfig);
|
||||
|
||||
// For now, only a certain data shapes are supported
|
||||
switch (additionalPropertiesInfo.RootObjectType)
|
||||
{
|
||||
case JsonValueKind.Array:
|
||||
ExecuteRootArray(settings.RootElement.EnumerateArray(), currentPropertyValue as IEnumerable<object>);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
settingsUtils.SaveSettings(settingsConfig.ToJsonString(), settingsConfig.GetModuleName());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
using System.Reflection;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
/// <summary>
|
||||
/// This user flow allows DSC resources to use PowerToys.Settings executable to set settings values by suppling them from command line using the following syntax:
|
||||
/// PowerToys.Settings.exe set <module struct name>.<field name> <field_value>
|
||||
///
|
||||
/// Example: PowerToys.Settings.exe set MeasureTool.MeasureCrossColor "#00FF00"
|
||||
/// </summary>
|
||||
public sealed class SetSettingCommandLineCommand
|
||||
{
|
||||
private static readonly char[] SettingNameSeparator = { '.' };
|
||||
|
||||
private static (string ModuleName, string PropertyName) ParseSettingName(string settingName)
|
||||
{
|
||||
var parts = settingName.Split(SettingNameSeparator, 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
return (parts[0], parts[1]);
|
||||
}
|
||||
|
||||
public static void Execute(string settingName, string settingValue, ISettingsUtils settingsUtils)
|
||||
{
|
||||
Assembly settingsLibraryAssembly = CommandLineUtils.GetSettingsAssembly();
|
||||
|
||||
var (moduleName, propertyName) = ParseSettingName(settingName);
|
||||
|
||||
var settingsConfig = CommandLineUtils.GetSettingsConfigFor(moduleName, settingsUtils, settingsLibraryAssembly);
|
||||
|
||||
var propertyInfo = CommandLineUtils.GetSettingPropertyInfo(propertyName, settingsConfig);
|
||||
if (propertyInfo == null)
|
||||
{
|
||||
throw new ArgumentException($"Property '{propertyName}' wasn't found");
|
||||
}
|
||||
|
||||
if (propertyInfo.PropertyType.GetCustomAttribute<CmdConfigureIgnoreAttribute>() != null)
|
||||
{
|
||||
throw new ArgumentException($"Property '{propertyName}' is explicitly ignored");
|
||||
}
|
||||
|
||||
// Execute settingsConfig.Properties.<propertyName> = settingValue
|
||||
var propertyValue = ICmdLineRepresentable.ParseFor(propertyInfo.PropertyType, settingValue);
|
||||
var (settingInfo, properties) = CommandLineUtils.LocateSetting(propertyName, settingsConfig);
|
||||
settingInfo.SetValue(properties, propertyValue);
|
||||
|
||||
settingsUtils.SaveSettings(settingsConfig.ToJsonString(), settingsConfig.GetModuleName());
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Settings.UI.Library.Attributes;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class VideoConferenceConfigProperties
|
||||
{
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultMuteCameraAndMicrophoneHotkey => new HotkeySettings()
|
||||
{
|
||||
Win = true,
|
||||
@@ -19,6 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
Code = 81,
|
||||
};
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultMuteMicrophoneHotkey => new HotkeySettings()
|
||||
{
|
||||
Win = true,
|
||||
@@ -29,6 +32,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
Code = 65,
|
||||
};
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultPushToTalkMicrophoneHotkey => new HotkeySettings()
|
||||
{
|
||||
Win = true,
|
||||
@@ -39,6 +43,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
Code = 73,
|
||||
};
|
||||
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
public HotkeySettings DefaultMuteCameraHotkey => new HotkeySettings()
|
||||
{
|
||||
Win = true,
|
||||
|
||||
@@ -9,10 +9,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class VideoConferenceSettings : BasePTModuleSettings, ISettingsConfig
|
||||
{
|
||||
public const string ModuleName = "Video Conference";
|
||||
|
||||
public VideoConferenceSettings()
|
||||
{
|
||||
Version = "1";
|
||||
Name = "Video Conference";
|
||||
Name = ModuleName;
|
||||
Properties = new VideoConferenceConfigProperties();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Settings.UI.UnitTests.Settings;
|
||||
|
||||
[TestClass]
|
||||
public class ICmdReprParsableTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void KeyboardKeysPropertyParsing()
|
||||
{
|
||||
{
|
||||
Assert.IsTrue(KeyboardKeysProperty.TryParseFromCmd("win+ctrl+Alt+sHifT+Q", out var hotkey));
|
||||
|
||||
Assert.AreEqual(new KeyboardKeysProperty { Value = new HotkeySettings(true, true, true, true, 0x51) }, hotkey);
|
||||
}
|
||||
|
||||
{
|
||||
Assert.IsTrue(KeyboardKeysProperty.TryParseFromCmd("CTRL+z", out var hotkey));
|
||||
Assert.AreEqual(new KeyboardKeysProperty { Value = new HotkeySettings(false, true, false, false, 0x5A) }, hotkey);
|
||||
}
|
||||
|
||||
{
|
||||
Assert.IsTrue(KeyboardKeysProperty.TryParseFromCmd("shift+ALT+0x59", out var hotkey));
|
||||
Assert.AreEqual(new KeyboardKeysProperty { Value = new HotkeySettings(false, false, true, true, 0x59) }, hotkey);
|
||||
}
|
||||
|
||||
{
|
||||
Assert.IsTrue(KeyboardKeysProperty.TryParseFromCmd("alt+Space", out var hotkey));
|
||||
Assert.AreEqual(new KeyboardKeysProperty { Value = new HotkeySettings(false, false, true, false, 0x20) }, hotkey);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BoolPropertyParsing()
|
||||
{
|
||||
{
|
||||
Assert.IsTrue(BoolProperty.TryParseFromCmd("True", out var result));
|
||||
Assert.AreEqual(new BoolProperty(true), result);
|
||||
}
|
||||
|
||||
{
|
||||
Assert.IsTrue(BoolProperty.TryParseFromCmd("false", out var result));
|
||||
Assert.AreEqual(new BoolProperty(false), result);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntPropertyParsing()
|
||||
{
|
||||
{
|
||||
Assert.IsTrue(IntProperty.TryParseFromCmd("123", out var result));
|
||||
Assert.AreEqual(new IntProperty(123), result);
|
||||
}
|
||||
|
||||
{
|
||||
Assert.IsTrue(IntProperty.TryParseFromCmd("1500", out var result));
|
||||
Assert.AreEqual(new IntProperty(1500), result);
|
||||
Assert.AreNotEqual(new IntProperty(15), result);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MouseJumpThumbnailSizeParsing()
|
||||
{
|
||||
{
|
||||
Assert.IsTrue(MouseJumpThumbnailSize.TryParseFromCmd("1920x1080", out var result));
|
||||
Assert.AreEqual(new MouseJumpThumbnailSize { Width = 1920, Height = 1080 }, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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;
|
||||
using System.IO.Abstractions.TestingHelpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using static Microsoft.PowerToys.Settings.UI.Library.SetSettingCommandLineCommand;
|
||||
|
||||
namespace Settings.UI.UnitTests.Cmd;
|
||||
|
||||
[TestClass]
|
||||
public class SetSettingCommandTests
|
||||
{
|
||||
private SettingsUtils settingsUtils;
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
settingsUtils = new SettingsUtils(new MockFileSystem());
|
||||
}
|
||||
|
||||
private void SetSetting(Type moduleSettingsType, string settingName, string newValueStr)
|
||||
{
|
||||
var settings = CommandLineUtils.GetSettingsConfigFor(moduleSettingsType, settingsUtils);
|
||||
var defaultValue = CommandLineUtils.GetPropertyValue(settingName, settings);
|
||||
var qualifiedName = moduleSettingsType.Name.Replace("Settings", string.Empty) + "." + settingName;
|
||||
var type = CommandLineUtils.GetSettingPropertyInfo(settingName, settings).PropertyType;
|
||||
var newValue = ICmdLineRepresentable.ParseFor(type, newValueStr);
|
||||
|
||||
Execute(qualifiedName, newValueStr, settingsUtils);
|
||||
|
||||
Assert.AreNotEqual(defaultValue, newValue);
|
||||
Assert.AreEqual(newValue, CommandLineUtils.GetPropertyValue(settingName, settings));
|
||||
}
|
||||
|
||||
// Each setting has a different type.
|
||||
[TestMethod]
|
||||
[DataRow(typeof(PowerRenameSettings), nameof(PowerRenameProperties.MaxMRUSize), "123")]
|
||||
[DataRow(typeof(FancyZonesSettings), nameof(FZConfigProperties.FancyzonesBorderColor), "#00FF00")]
|
||||
[DataRow(typeof(MeasureToolSettings), nameof(MeasureToolProperties.ActivationShortcut), "Ctrl+Alt+Delete")]
|
||||
[DataRow(typeof(AlwaysOnTopSettings), nameof(AlwaysOnTopProperties.SoundEnabled), "False")]
|
||||
[DataRow(typeof(PowerAccentSettings), nameof(PowerAccentProperties.ShowUnicodeDescription), "true")]
|
||||
[DataRow(typeof(AwakeSettings), nameof(AwakeProperties.Mode), "EXPIRABLE")]
|
||||
[DataRow(typeof(AwakeSettings), nameof(AwakeProperties.ExpirationDateTime), "March 31, 2020 15:00 +00:00")]
|
||||
[DataRow(typeof(PowerLauncherSettings), nameof(PowerLauncherProperties.MaximumNumberOfResults), "322")]
|
||||
|
||||
[DataRow(typeof(ColorPickerSettings), nameof(ColorPickerProperties.CopiedColorRepresentation), "RGB")]
|
||||
public void SetModuleSetting(Type moduleSettingsType, string settingName, string newValueStr)
|
||||
{
|
||||
SetSetting(moduleSettingsType, settingName, newValueStr);
|
||||
}
|
||||
|
||||
[DataRow(typeof(GeneralSettings), "Enabled.MouseWithoutBorders", "true")]
|
||||
[DataRow(typeof(GeneralSettings), nameof(GeneralSettings.AutoDownloadUpdates), "true")]
|
||||
[TestMethod]
|
||||
public void SetGeneralSetting(Type moduleSettingsType, string settingName, string newValueStr)
|
||||
{
|
||||
SetSetting(moduleSettingsType, settingName, newValueStr);
|
||||
}
|
||||
}
|
||||
@@ -237,10 +237,9 @@ namespace ViewModelTests
|
||||
// Assert
|
||||
Assert.IsTrue(modules.FancyZones);
|
||||
Assert.IsTrue(modules.ImageResizer);
|
||||
Assert.IsTrue(modules.FileExplorerPreview);
|
||||
Assert.IsTrue(modules.PowerPreview);
|
||||
Assert.IsTrue(modules.ShortcutGuide);
|
||||
Assert.IsTrue(modules.PowerRename);
|
||||
Assert.IsTrue(modules.KeyboardManager);
|
||||
Assert.IsTrue(modules.PowerLauncher);
|
||||
Assert.IsTrue(modules.ColorPicker);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
case ModuleType.RegistryPreview: return generalSettingsConfig.Enabled.RegistryPreview;
|
||||
case ModuleType.MeasureTool: return generalSettingsConfig.Enabled.MeasureTool;
|
||||
case ModuleType.ShortcutGuide: return generalSettingsConfig.Enabled.ShortcutGuide;
|
||||
case ModuleType.PowerOCR: return generalSettingsConfig.Enabled.PowerOCR;
|
||||
case ModuleType.PowerOCR: return generalSettingsConfig.Enabled.PowerOcr;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
case ModuleType.RegistryPreview: generalSettingsConfig.Enabled.RegistryPreview = isEnabled; break;
|
||||
case ModuleType.MeasureTool: generalSettingsConfig.Enabled.MeasureTool = isEnabled; break;
|
||||
case ModuleType.ShortcutGuide: generalSettingsConfig.Enabled.ShortcutGuide = isEnabled; break;
|
||||
case ModuleType.PowerOCR: generalSettingsConfig.Enabled.PowerOCR = isEnabled; break;
|
||||
case ModuleType.PowerOCR: generalSettingsConfig.Enabled.PowerOcr = isEnabled; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,15 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Json;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Common.UI;
|
||||
using interop;
|
||||
@@ -42,8 +48,11 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
ContainsFlyoutPosition,
|
||||
}
|
||||
|
||||
// Quantity of arguments
|
||||
private const int RequiredArgumentsQty = 12;
|
||||
private const int RequiredArgumentsSetSettingQty = 4;
|
||||
private const int RequiredArgumentsSetAdditionalSettingsQty = 4;
|
||||
private const int RequiredArgumentsGetSettingQty = 3;
|
||||
|
||||
private const int RequiredArgumentsLaunchedFromRunnerQty = 12;
|
||||
|
||||
// Create an instance of the IPC wrapper.
|
||||
private static TwoWayPipeMessageIPCManaged ipcmanager;
|
||||
@@ -100,6 +109,171 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLaunchedToSetSetting(string[] cmdArgs)
|
||||
{
|
||||
var settingName = cmdArgs[2];
|
||||
var settingValue = cmdArgs[3];
|
||||
try
|
||||
{
|
||||
SetSettingCommandLineCommand.Execute(settingName, settingValue, new SettingsUtils());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"SetSettingCommandLineCommand exception: '{settingName}' setting couldn't be set to {settingValue}", ex);
|
||||
}
|
||||
|
||||
Exit();
|
||||
}
|
||||
|
||||
private void OnLaunchedToSetAdditionalSetting(string[] cmdArgs)
|
||||
{
|
||||
var moduleName = cmdArgs[2];
|
||||
var ipcFileName = cmdArgs[3];
|
||||
try
|
||||
{
|
||||
using (var settings = JsonDocument.Parse(File.ReadAllText(ipcFileName)))
|
||||
{
|
||||
SetAdditionalSettingsCommandLineCommand.Execute(moduleName, settings, new SettingsUtils());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"SetAdditionalSettingsCommandLineCommand exception: couldn't set additional settings for '{moduleName}'", ex);
|
||||
}
|
||||
|
||||
Exit();
|
||||
}
|
||||
|
||||
private void OnLaunchedToGetSetting(string[] cmdArgs)
|
||||
{
|
||||
var ipcFileName = cmdArgs[2];
|
||||
|
||||
try
|
||||
{
|
||||
var requestedSettings = JsonSerializer.Deserialize<Dictionary<string, List<string>>>(File.ReadAllText(ipcFileName));
|
||||
File.WriteAllText(ipcFileName, GetSettingCommandLineCommand.Execute(requestedSettings));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"GetSettingCommandLineCommand exception", ex);
|
||||
}
|
||||
|
||||
Exit();
|
||||
}
|
||||
|
||||
private void OnLaunchedFromRunner(string[] cmdArgs)
|
||||
{
|
||||
// Skip the first argument which is prepended when launched by explorer
|
||||
if (cmdArgs[0].EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) && cmdArgs[1].EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) && (cmdArgs.Length >= RequiredArgumentsLaunchedFromRunnerQty + 1))
|
||||
{
|
||||
cmdArgs = cmdArgs.Skip(1).ToArray();
|
||||
}
|
||||
|
||||
_ = int.TryParse(cmdArgs[(int)Arguments.PTPid], out int powerToysPID);
|
||||
PowerToysPID = powerToysPID;
|
||||
|
||||
IsElevated = cmdArgs[(int)Arguments.ElevatedStatus] == "true";
|
||||
IsUserAnAdmin = cmdArgs[(int)Arguments.IsUserAdmin] == "true";
|
||||
ShowOobe = cmdArgs[(int)Arguments.ShowOobeWindow] == "true";
|
||||
ShowScoobe = cmdArgs[(int)Arguments.ShowScoobeWindow] == "true";
|
||||
ShowFlyout = cmdArgs[(int)Arguments.ShowFlyout] == "true";
|
||||
bool containsSettingsWindow = cmdArgs[(int)Arguments.ContainsSettingsWindow] == "true";
|
||||
bool containsFlyoutPosition = cmdArgs[(int)Arguments.ContainsFlyoutPosition] == "true";
|
||||
|
||||
// To keep track of variable arguments
|
||||
int currentArgumentIndex = RequiredArgumentsLaunchedFromRunnerQty;
|
||||
|
||||
if (containsSettingsWindow)
|
||||
{
|
||||
// Open specific window
|
||||
StartupPage = GetPage(cmdArgs[currentArgumentIndex]);
|
||||
|
||||
currentArgumentIndex++;
|
||||
}
|
||||
|
||||
int flyout_x = 0;
|
||||
int flyout_y = 0;
|
||||
if (containsFlyoutPosition)
|
||||
{
|
||||
// get the flyout position arguments
|
||||
_ = int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_x);
|
||||
_ = int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_y);
|
||||
}
|
||||
|
||||
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
||||
{
|
||||
Environment.Exit(0);
|
||||
});
|
||||
|
||||
ipcmanager = new TwoWayPipeMessageIPCManaged(cmdArgs[(int)Arguments.SettingsPipeName], cmdArgs[(int)Arguments.PTPipeName], (string message) =>
|
||||
{
|
||||
if (IPCMessageReceivedCallback != null && message.Length > 0)
|
||||
{
|
||||
IPCMessageReceivedCallback(message);
|
||||
}
|
||||
});
|
||||
ipcmanager.Start();
|
||||
|
||||
if (!ShowOobe && !ShowScoobe && !ShowFlyout)
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow.Activate();
|
||||
settingsWindow.ExtendsContentIntoTitleBar = true;
|
||||
settingsWindow.NavigateToSection(StartupPage);
|
||||
|
||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
||||
// Need to call SetForegroundWindow to actually gain focus.
|
||||
WindowHelpers.BringToForeground(settingsWindow.GetWindowHandle());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the Settings window hidden so that it's fully initialized and
|
||||
// it will be ready to receive the notification if the user opens
|
||||
// the Settings from the tray icon.
|
||||
settingsWindow = new MainWindow(true);
|
||||
|
||||
if (ShowOobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
|
||||
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview);
|
||||
oobeWindow.Activate();
|
||||
oobeWindow.ExtendsContentIntoTitleBar = true;
|
||||
SetOobeWindow(oobeWindow);
|
||||
}
|
||||
else if (ShowScoobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
|
||||
OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew);
|
||||
scoobeWindow.Activate();
|
||||
scoobeWindow.ExtendsContentIntoTitleBar = true;
|
||||
SetOobeWindow(scoobeWindow);
|
||||
}
|
||||
else if (ShowFlyout)
|
||||
{
|
||||
POINT? p = null;
|
||||
if (containsFlyoutPosition)
|
||||
{
|
||||
p = new POINT(flyout_x, flyout_y);
|
||||
}
|
||||
|
||||
ShellPage.OpenFlyoutCallback(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedTheme() == ElementTheme.Default)
|
||||
{
|
||||
try
|
||||
{
|
||||
themeListener = new ThemeListener();
|
||||
themeListener.ThemeChanged += (_) => HandleThemeChange();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"HandleThemeChange exception. Please install .NET 4.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
@@ -109,117 +283,21 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
var cmdArgs = Environment.GetCommandLineArgs();
|
||||
|
||||
if (cmdArgs != null && cmdArgs.Length >= RequiredArgumentsQty)
|
||||
if (cmdArgs?.Length >= RequiredArgumentsLaunchedFromRunnerQty)
|
||||
{
|
||||
// Skip the first argument which is prepended when launched by explorer
|
||||
if (cmdArgs[0].EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) && cmdArgs[1].EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) && (cmdArgs.Length >= RequiredArgumentsQty + 1))
|
||||
{
|
||||
cmdArgs = cmdArgs.Skip(1).ToArray();
|
||||
}
|
||||
|
||||
_ = int.TryParse(cmdArgs[(int)Arguments.PTPid], out int powerToysPID);
|
||||
PowerToysPID = powerToysPID;
|
||||
|
||||
IsElevated = cmdArgs[(int)Arguments.ElevatedStatus] == "true";
|
||||
IsUserAnAdmin = cmdArgs[(int)Arguments.IsUserAdmin] == "true";
|
||||
ShowOobe = cmdArgs[(int)Arguments.ShowOobeWindow] == "true";
|
||||
ShowScoobe = cmdArgs[(int)Arguments.ShowScoobeWindow] == "true";
|
||||
ShowFlyout = cmdArgs[(int)Arguments.ShowFlyout] == "true";
|
||||
bool containsSettingsWindow = cmdArgs[(int)Arguments.ContainsSettingsWindow] == "true";
|
||||
bool containsFlyoutPosition = cmdArgs[(int)Arguments.ContainsFlyoutPosition] == "true";
|
||||
|
||||
// To keep track of variable arguments
|
||||
int currentArgumentIndex = RequiredArgumentsQty;
|
||||
|
||||
if (containsSettingsWindow)
|
||||
{
|
||||
// Open specific window
|
||||
StartupPage = GetPage(cmdArgs[currentArgumentIndex]);
|
||||
|
||||
currentArgumentIndex++;
|
||||
}
|
||||
|
||||
int flyout_x = 0;
|
||||
int flyout_y = 0;
|
||||
if (containsFlyoutPosition)
|
||||
{
|
||||
// get the flyout position arguments
|
||||
_ = int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_x);
|
||||
_ = int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_y);
|
||||
}
|
||||
|
||||
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
||||
{
|
||||
Environment.Exit(0);
|
||||
});
|
||||
|
||||
ipcmanager = new TwoWayPipeMessageIPCManaged(cmdArgs[(int)Arguments.SettingsPipeName], cmdArgs[(int)Arguments.PTPipeName], (string message) =>
|
||||
{
|
||||
if (IPCMessageReceivedCallback != null && message.Length > 0)
|
||||
{
|
||||
IPCMessageReceivedCallback(message);
|
||||
}
|
||||
});
|
||||
ipcmanager.Start();
|
||||
|
||||
if (!ShowOobe && !ShowScoobe && !ShowFlyout)
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow.Activate();
|
||||
settingsWindow.ExtendsContentIntoTitleBar = true;
|
||||
settingsWindow.NavigateToSection(StartupPage);
|
||||
|
||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
||||
// Need to call SetForegroundWindow to actually gain focus.
|
||||
WindowHelpers.BringToForeground(settingsWindow.GetWindowHandle());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the Settings window hidden so that it's fully initialized and
|
||||
// it will be ready to receive the notification if the user opens
|
||||
// the Settings from the tray icon.
|
||||
settingsWindow = new MainWindow(true);
|
||||
|
||||
if (ShowOobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
|
||||
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview);
|
||||
oobeWindow.Activate();
|
||||
oobeWindow.ExtendsContentIntoTitleBar = true;
|
||||
SetOobeWindow(oobeWindow);
|
||||
}
|
||||
else if (ShowScoobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
|
||||
OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew);
|
||||
scoobeWindow.Activate();
|
||||
scoobeWindow.ExtendsContentIntoTitleBar = true;
|
||||
SetOobeWindow(scoobeWindow);
|
||||
}
|
||||
else if (ShowFlyout)
|
||||
{
|
||||
POINT? p = null;
|
||||
if (containsFlyoutPosition)
|
||||
{
|
||||
p = new POINT(flyout_x, flyout_y);
|
||||
}
|
||||
|
||||
ShellPage.OpenFlyoutCallback(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedTheme() == ElementTheme.Default)
|
||||
{
|
||||
try
|
||||
{
|
||||
themeListener = new ThemeListener();
|
||||
themeListener.ThemeChanged += (_) => HandleThemeChange();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"HandleThemeChange exception. Please install .NET 4.", ex);
|
||||
}
|
||||
}
|
||||
OnLaunchedFromRunner(cmdArgs);
|
||||
}
|
||||
else if (cmdArgs?.Length == RequiredArgumentsSetSettingQty && cmdArgs[1] == "set")
|
||||
{
|
||||
OnLaunchedToSetSetting(cmdArgs);
|
||||
}
|
||||
else if (cmdArgs?.Length == RequiredArgumentsSetAdditionalSettingsQty && cmdArgs[1] == "setAdditional")
|
||||
{
|
||||
OnLaunchedToSetAdditionalSetting(cmdArgs);
|
||||
}
|
||||
else if (cmdArgs?.Length == RequiredArgumentsGetSettingQty && cmdArgs[1] == "get")
|
||||
{
|
||||
OnLaunchedToGetSetting(cmdArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -417,7 +495,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
case "QuickAccent": return typeof(PowerAccentPage);
|
||||
case "FileExplorer": return typeof(PowerPreviewPage);
|
||||
case "ShortcutGuide": return typeof(ShortcutGuidePage);
|
||||
case "PowerOCR": return typeof(PowerOcrPage);
|
||||
case "PowerOcr": return typeof(PowerOcrPage);
|
||||
case "VideoConference": return typeof(VideoConferencePage);
|
||||
case "MeasureTool": return typeof(MeasureToolPage);
|
||||
case "Hosts": return typeof(HostsPage);
|
||||
|
||||
@@ -321,7 +321,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
// Tab and Shift+Tab are accessible keys and should not be displayed in the hotkey control.
|
||||
if (internalSettings.Code > 0 && !internalSettings.IsAccessibleShortcut())
|
||||
{
|
||||
lastValidSettings = internalSettings.Clone();
|
||||
lastValidSettings = internalSettings with { };
|
||||
|
||||
if (!ComboIsValid(lastValidSettings))
|
||||
{
|
||||
@@ -436,7 +436,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
{
|
||||
if (ComboIsValid(lastValidSettings))
|
||||
{
|
||||
HotkeySettings = lastValidSettings.Clone();
|
||||
HotkeySettings = lastValidSettings with { };
|
||||
}
|
||||
|
||||
PreviewKeysControl.ItemsSource = hotkeySettings.GetKeysList();
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
_isEnabled = GeneralSettingsConfig.Enabled.PowerOCR;
|
||||
_isEnabled = GeneralSettingsConfig.Enabled.PowerOcr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,8 +129,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_isEnabled = value;
|
||||
OnPropertyChanged(nameof(IsEnabled));
|
||||
|
||||
// Set the status of PowerOCR in the general settings
|
||||
GeneralSettingsConfig.Enabled.PowerOCR = value;
|
||||
// Set the status of PowerOcr in the general settings
|
||||
GeneralSettingsConfig.Enabled.PowerOcr = value;
|
||||
var outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
||||
|
||||
SendConfigMSG(outgoing.ToString());
|
||||
|
||||
Reference in New Issue
Block a user