mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 04:37:30 +02:00
Merge branch 'dev/build-features' into users/niels9001/settingsV2UXtweaks
This commit is contained in:
@@ -59,7 +59,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
|||||||
this.AutoDownloadUpdates = false;
|
this.AutoDownloadUpdates = false;
|
||||||
this.Theme = "system";
|
this.Theme = "system";
|
||||||
this.SystemTheme = "light";
|
this.SystemTheme = "light";
|
||||||
this.PowertoysVersion = interop.CommonManaged.GetProductVersion();
|
try
|
||||||
|
{
|
||||||
|
this.PowertoysVersion = DefaultPowertoysVersion();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
this.PowertoysVersion = "v0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
this.Enabled = new EnabledModules();
|
this.Enabled = new EnabledModules();
|
||||||
this.CustomActionName = string.Empty;
|
this.CustomActionName = string.Empty;
|
||||||
}
|
}
|
||||||
@@ -69,5 +77,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
|||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(this);
|
return JsonSerializer.Serialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string DefaultPowertoysVersion()
|
||||||
|
{
|
||||||
|
return interop.CommonManaged.GetProductVersion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
|||||||
MaxMRUSize = new IntProperty();
|
MaxMRUSize = new IntProperty();
|
||||||
ShowIcon = new BoolProperty();
|
ShowIcon = new BoolProperty();
|
||||||
ExtendedContextMenuOnly = new BoolProperty();
|
ExtendedContextMenuOnly = new BoolProperty();
|
||||||
|
Enabled = new BoolProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BoolProperty Enabled { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("bool_persist_input")]
|
[JsonPropertyName("bool_persist_input")]
|
||||||
public BoolProperty PersistState { get; set; }
|
public BoolProperty PersistState { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||||
|
{
|
||||||
|
public class PowerRenameSettingsIPCMessage
|
||||||
|
{
|
||||||
|
[JsonPropertyName("powertoys")]
|
||||||
|
public SndPowerRenameSettings Powertoys { get; set; }
|
||||||
|
|
||||||
|
public PowerRenameSettingsIPCMessage()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PowerRenameSettingsIPCMessage(SndPowerRenameSettings settings)
|
||||||
|
{
|
||||||
|
this.Powertoys = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToJsonString()
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
|||||||
[JsonPropertyName("PowerRename")]
|
[JsonPropertyName("PowerRename")]
|
||||||
public PowerRenameSettings PowerRename { get; set; }
|
public PowerRenameSettings PowerRename { get; set; }
|
||||||
|
|
||||||
|
public SndPowerRenameSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public SndPowerRenameSettings(PowerRenameSettings settings)
|
public SndPowerRenameSettings(PowerRenameSettings settings)
|
||||||
{
|
{
|
||||||
PowerRename = settings;
|
PowerRename = settings;
|
||||||
|
|||||||
@@ -369,16 +369,16 @@
|
|||||||
<value>Choose Settings color</value>
|
<value>Choose Settings color</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PowerRename_Toggle_EnableOnContextMenu.Header" xml:space="preserve">
|
<data name="PowerRename_Toggle_EnableOnContextMenu.Header" xml:space="preserve">
|
||||||
<value>Show on default context menu</value>
|
<value>Show icon on context menu</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PowerRename_Toggle_EnableOnExtendedContextMenu.Header" xml:space="preserve">
|
<data name="PowerRename_Toggle_EnableOnExtendedContextMenu.Header" xml:space="preserve">
|
||||||
<value>Only show on extended context menu (Shift + Right-click)</value>
|
<value>Only show the PowerRename menu item on the extended context menu (Shift + Right-click).</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PowerRename_Toggle_MaxDispListNum.Text" xml:space="preserve">
|
<data name="PowerRename_Toggle_MaxDispListNum.Text" xml:space="preserve">
|
||||||
<value>Maximum numbers of items to show in recently used list</value>
|
<value>Maximum numbers of items to show in recently used list for autocomplete dropdown.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PowerRename_Toggle_RestoreFlagsOnLaunch.Header" xml:space="preserve">
|
<data name="PowerRename_Toggle_RestoreFlagsOnLaunch.Header" xml:space="preserve">
|
||||||
<value>Restore search, replace and flags values on launch from previous run</value>
|
<value>Restore search, replace and flags values on launch from previous run.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FileEplorerPreview_ToggleSwitch_Preview_MD.Header" xml:space="preserve">
|
<data name="FileEplorerPreview_ToggleSwitch_Preview_MD.Header" xml:space="preserve">
|
||||||
<value>Markdown Preview Handler</value>
|
<value>Markdown Preview Handler</value>
|
||||||
@@ -396,7 +396,7 @@
|
|||||||
<value>Open-source notice</value>
|
<value>Open-source notice</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PowerRename_Toggle_AutoComplete.Header" xml:space="preserve">
|
<data name="PowerRename_Toggle_AutoComplete.Header" xml:space="preserve">
|
||||||
<value>Enable Auto Complete</value>
|
<value>Enable autocomplete and autosuggest of recently used list for autocomplete dropdown.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FancyZones_BorderColor.Text" xml:space="preserve">
|
<data name="FancyZones_BorderColor.Text" xml:space="preserve">
|
||||||
<value>Zone border color (Default #FFFFFF)</value>
|
<value>Zone border color (Default #FFFFFF)</value>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
ShellPage.DefaultSndMSGCallback(snd.ToString());
|
ShellPage.DefaultSndMSGCallback(snd.ToString());
|
||||||
|
|
||||||
_powerRenameEnabled = value;
|
_powerRenameEnabled = value;
|
||||||
RaisePropertyChanged();
|
OnPropertyChanged("IsEnabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,12 @@
|
|||||||
<TextBlock x:Uid="PowerRename_ShellIntergration"
|
<TextBlock x:Uid="PowerRename_ShellIntergration"
|
||||||
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
||||||
|
|
||||||
|
<ToggleSwitch x:Uid="PowerRename_Toggle_AutoComplete"
|
||||||
|
Margin="{StaticResource SmallTopMargin}"
|
||||||
|
IsOn="{Binding Mode=TwoWay, Path=MRUEnabled}"
|
||||||
|
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled}"
|
||||||
|
/>
|
||||||
|
|
||||||
<ToggleSwitch x:Uid="PowerRename_Toggle_EnableOnContextMenu"
|
<ToggleSwitch x:Uid="PowerRename_Toggle_EnableOnContextMenu"
|
||||||
Margin="{StaticResource SmallTopMargin}"
|
Margin="{StaticResource SmallTopMargin}"
|
||||||
IsOn="{Binding Mode=TwoWay, Path=EnabledOnContextMenu}"
|
IsOn="{Binding Mode=TwoWay, Path=EnabledOnContextMenu}"
|
||||||
|
|||||||
@@ -129,6 +129,7 @@
|
|||||||
<Compile Include="UnitTestApp.xaml.cs">
|
<Compile Include="UnitTestApp.xaml.cs">
|
||||||
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ViewModelTests\PowerRename.cs" />
|
||||||
<Compile Include="ViewModelTests\PowerPreview.cs" />
|
<Compile Include="ViewModelTests\PowerPreview.cs" />
|
||||||
<Compile Include="ViewModelTests\ShortcutGuide.cs" />
|
<Compile Include="ViewModelTests\ShortcutGuide.cs" />
|
||||||
<Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" />
|
<Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Views;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ViewModelTests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class PowerRename
|
||||||
|
{
|
||||||
|
public const string ModuleName = "PowerRename";
|
||||||
|
public string schemaText = null;
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
// initialize creation of test settings file.
|
||||||
|
GeneralSettings generalSettings = new GeneralSettings();
|
||||||
|
PowerRenameSettings powerRename = new PowerRenameSettings();
|
||||||
|
|
||||||
|
SettingsUtils.SaveSettings(generalSettings.ToJsonString());
|
||||||
|
SettingsUtils.SaveSettings(powerRename.ToJsonString(), powerRename.name, "power-rename-settings.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCleanup]
|
||||||
|
public void CleanUp()
|
||||||
|
{
|
||||||
|
// delete folder created.
|
||||||
|
string generalSettings_file_name = string.Empty;
|
||||||
|
if (SettingsUtils.SettingsFolderExists(generalSettings_file_name))
|
||||||
|
{
|
||||||
|
DeleteFolder(generalSettings_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete folder created.
|
||||||
|
if (SettingsUtils.SettingsFolderExists(ModuleName))
|
||||||
|
{
|
||||||
|
DeleteFolder(ModuleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEnabled_ShouldEnableModule_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerRenameViewModel viewModel = new PowerRenameViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||||
|
Assert.IsTrue(snd.GeneralSettings.Enabled.PowerRename);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.IsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MRUEnabled_ShouldSetValue2True_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerRenameViewModel viewModel = new PowerRenameViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
PowerRenameSettingsIPCMessage snd = JsonSerializer.Deserialize<PowerRenameSettingsIPCMessage>(msg);
|
||||||
|
Assert.IsTrue(snd.Powertoys.PowerRename.properties.MRUEnabled.Value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.MRUEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void EnabledOnContextMenu_ShouldSetValue2True_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerRenameViewModel viewModel = new PowerRenameViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
PowerRenameSettingsIPCMessage snd = JsonSerializer.Deserialize<PowerRenameSettingsIPCMessage>(msg);
|
||||||
|
Assert.IsTrue(snd.Powertoys.PowerRename.properties.ShowIcon.Value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.EnabledOnContextMenu = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void EnabledOnContextExtendedMenu_ShouldSetValue2True_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerRenameViewModel viewModel = new PowerRenameViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
PowerRenameSettingsIPCMessage snd = JsonSerializer.Deserialize<PowerRenameSettingsIPCMessage>(msg);
|
||||||
|
Assert.IsTrue(snd.Powertoys.PowerRename.properties.ShowIcon.Value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.EnabledOnContextMenu = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RestoreFlagsOnLaunch_ShouldSetValue2True_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerRenameViewModel viewModel = new PowerRenameViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
PowerRenameSettingsIPCMessage snd = JsonSerializer.Deserialize<PowerRenameSettingsIPCMessage>(msg);
|
||||||
|
Assert.IsTrue(snd.Powertoys.PowerRename.properties.PersistState.Value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.RestoreFlagsOnLaunch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MaxDispListNum_ShouldSetMaxSuggListTo20_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerRenameViewModel viewModel = new PowerRenameViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
PowerRenameSettingsIPCMessage snd = JsonSerializer.Deserialize<PowerRenameSettingsIPCMessage>(msg);
|
||||||
|
Assert.AreEqual(20,snd.Powertoys.PowerRename.properties.MaxMRUSize.Value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.MaxDispListNum = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteFolder(string powertoy)
|
||||||
|
{
|
||||||
|
Directory.Delete(Path.Combine(SettingsUtils.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="RemapShortcut.cpp" />
|
<ClCompile Include="RemapShortcut.cpp" />
|
||||||
<ClCompile Include="Shortcut.cpp" />
|
<ClCompile Include="Shortcut.cpp" />
|
||||||
|
<ClCompile Include="trace.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Helpers.h" />
|
<ClInclude Include="Helpers.h" />
|
||||||
@@ -109,6 +110,7 @@
|
|||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="RemapShortcut.h" />
|
<ClInclude Include="RemapShortcut.h" />
|
||||||
<ClInclude Include="Shortcut.h" />
|
<ClInclude Include="Shortcut.h" />
|
||||||
|
<ClInclude Include="trace.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\common\common.vcxproj">
|
<ProjectReference Include="..\..\..\common\common.vcxproj">
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
<ClCompile Include="KeyDelay.cpp">
|
<ClCompile Include="KeyDelay.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Trace.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="KeyboardManagerState.h">
|
<ClInclude Include="KeyboardManagerState.h">
|
||||||
@@ -56,5 +59,8 @@
|
|||||||
<ClInclude Include="KeyboardManagerConstants.h">
|
<ClInclude Include="KeyboardManagerConstants.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Trace.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "winrt/Windows.UI.Text.h"
|
#include "winrt/Windows.UI.Text.h"
|
||||||
#include "winrt/Windows.UI.Core.h"
|
#include "winrt/Windows.UI.Core.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <ProjectTelemetry.h>
|
||||||
|
|
||||||
using namespace winrt;
|
using namespace winrt;
|
||||||
using namespace Windows::UI;
|
using namespace Windows::UI;
|
||||||
|
|||||||
52
src/modules/keyboardmanager/common/trace.cpp
Normal file
52
src/modules/keyboardmanager/common/trace.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
TRACELOGGING_DEFINE_PROVIDER(
|
||||||
|
g_hProvider,
|
||||||
|
"Microsoft.PowerToys",
|
||||||
|
// {38e8889b-9731-53f5-e901-e8a7c1753074}
|
||||||
|
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
|
||||||
|
TraceLoggingOptionProjectTelemetry());
|
||||||
|
|
||||||
|
void Trace::RegisterProvider() noexcept
|
||||||
|
{
|
||||||
|
TraceLoggingRegister(g_hProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Trace::UnregisterProvider() noexcept
|
||||||
|
{
|
||||||
|
TraceLoggingUnregister(g_hProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log if the user has KBM enabled or disabled - Can also be used to see how often users have to restart the keyboard hook
|
||||||
|
void Trace::EnableKeyboardManager(const bool enabled) noexcept
|
||||||
|
{
|
||||||
|
TraceLoggingWrite(
|
||||||
|
g_hProvider,
|
||||||
|
"KeyboardManager_EnableKeyboardManager",
|
||||||
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
|
||||||
|
TraceLoggingBoolean(enabled, "Enabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log number of key remaps when the user uses Edit Keyboard and saves settings
|
||||||
|
void Trace::KeyRemapCount(const DWORD count) noexcept
|
||||||
|
{
|
||||||
|
TraceLoggingWrite(
|
||||||
|
g_hProvider,
|
||||||
|
"KeyboardManager_KeyRemapCount",
|
||||||
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
|
||||||
|
TraceLoggingValue(count, "KeyRemapCount"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log number of os level shortcut remaps when the user uses Edit Shortcuts and saves settings
|
||||||
|
void Trace::OSLevelShortcutRemapCount(const DWORD count) noexcept
|
||||||
|
{
|
||||||
|
TraceLoggingWrite(
|
||||||
|
g_hProvider,
|
||||||
|
"KeyboardManager_OSLevelShortcutRemapCount",
|
||||||
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
|
||||||
|
TraceLoggingValue(count, "OSLevelShortcutRemapCount"));
|
||||||
|
}
|
||||||
17
src/modules/keyboardmanager/common/trace.h
Normal file
17
src/modules/keyboardmanager/common/trace.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Trace
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void RegisterProvider() noexcept;
|
||||||
|
static void UnregisterProvider() noexcept;
|
||||||
|
|
||||||
|
// Log if the user has KBM enabled or disabled - Can also be used to see how often users have to restart the keyboard hook
|
||||||
|
static void EnableKeyboardManager(const bool enabled) noexcept;
|
||||||
|
|
||||||
|
// Log number of key remaps when the user uses Edit Keyboard and saves settings
|
||||||
|
static void KeyRemapCount(const DWORD count) noexcept;
|
||||||
|
|
||||||
|
// Log number of os level shortcut remaps when the user uses Edit Shortcuts and saves settings
|
||||||
|
static void OSLevelShortcutRemapCount(const DWORD count) noexcept;
|
||||||
|
};
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
STRINGTABLE
|
STRINGTABLE
|
||||||
BEGIN
|
BEGIN
|
||||||
IDS_SETTINGS_DESCRIPTION L"Customize your experience by remapping keys or creating new shortcuts!"
|
IDS_SETTINGS_DESCRIPTION L"This feature requires Windows 10, May 2019 Update"
|
||||||
IDS_KEYBOARDMANAGER L"Keyboard Manager"
|
IDS_KEYBOARDMANAGER L"Keyboard Manager"
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="trace.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="dllmain.cpp" />
|
<ClCompile Include="dllmain.cpp" />
|
||||||
@@ -118,7 +117,6 @@
|
|||||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
|
||||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="trace.cpp" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="$(SolutionDir)src\common\common.vcxproj">
|
<ProjectReference Include="$(SolutionDir)src\common\common.vcxproj">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <interface/win_hook_event_data.h>
|
#include <interface/win_hook_event_data.h>
|
||||||
#include <common/settings_objects.h>
|
#include <common/settings_objects.h>
|
||||||
#include <common/shared_constants.h>
|
#include <common/shared_constants.h>
|
||||||
#include "trace.h"
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include <keyboardmanager/ui/EditKeyboardWindow.h>
|
#include <keyboardmanager/ui/EditKeyboardWindow.h>
|
||||||
#include <keyboardmanager/ui/EditShortcutsWindow.h>
|
#include <keyboardmanager/ui/EditShortcutsWindow.h>
|
||||||
@@ -12,7 +11,8 @@
|
|||||||
#include <keyboardmanager/common/Shortcut.h>
|
#include <keyboardmanager/common/Shortcut.h>
|
||||||
#include <keyboardmanager/common/RemapShortcut.h>
|
#include <keyboardmanager/common/RemapShortcut.h>
|
||||||
#include <keyboardmanager/common/KeyboardManagerConstants.h>
|
#include <keyboardmanager/common/KeyboardManagerConstants.h>
|
||||||
#include <common\settings_helpers.h>
|
#include <common/settings_helpers.h>
|
||||||
|
#include <keyboardmanager/common/trace.h>
|
||||||
|
|
||||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
@@ -267,6 +267,9 @@ public:
|
|||||||
virtual void enable()
|
virtual void enable()
|
||||||
{
|
{
|
||||||
m_enabled = true;
|
m_enabled = true;
|
||||||
|
// Log telemetry
|
||||||
|
Trace::EnableKeyboardManager(true);
|
||||||
|
// Start keyboard hook
|
||||||
start_lowlevel_keyboard_hook();
|
start_lowlevel_keyboard_hook();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +277,9 @@ public:
|
|||||||
virtual void disable()
|
virtual void disable()
|
||||||
{
|
{
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
|
// Log telemetry
|
||||||
|
Trace::EnableKeyboardManager(false);
|
||||||
|
// Stop keyboard hook
|
||||||
stop_lowlevel_keyboard_hook();
|
stop_lowlevel_keyboard_hook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "trace.h"
|
|
||||||
|
|
||||||
TRACELOGGING_DEFINE_PROVIDER(
|
|
||||||
g_hProvider,
|
|
||||||
"Microsoft.PowerToys",
|
|
||||||
// {38e8889b-9731-53f5-e901-e8a7c1753074}
|
|
||||||
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
|
|
||||||
TraceLoggingOptionProjectTelemetry());
|
|
||||||
|
|
||||||
void Trace::RegisterProvider()
|
|
||||||
{
|
|
||||||
TraceLoggingRegister(g_hProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Trace::UnregisterProvider()
|
|
||||||
{
|
|
||||||
TraceLoggingUnregister(g_hProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Trace::MyEvent()
|
|
||||||
{
|
|
||||||
TraceLoggingWrite(
|
|
||||||
g_hProvider,
|
|
||||||
"PowerToyName_MyEvent",
|
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
class Trace
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void RegisterProvider();
|
|
||||||
static void UnregisterProvider();
|
|
||||||
static void MyEvent();
|
|
||||||
};
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "SingleKeyRemapControl.h"
|
#include "SingleKeyRemapControl.h"
|
||||||
#include "KeyDropDownControl.h"
|
#include "KeyDropDownControl.h"
|
||||||
#include "XamlBridge.h"
|
#include "XamlBridge.h"
|
||||||
|
#include <keyboardmanager/common/trace.h>
|
||||||
|
|
||||||
LRESULT CALLBACK EditKeyboardWindowProc(HWND, UINT, WPARAM, LPARAM);
|
LRESULT CALLBACK EditKeyboardWindowProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
@@ -215,7 +216,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
|||||||
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
|
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
|
||||||
// Clear existing Key Remaps
|
// Clear existing Key Remaps
|
||||||
keyboardManagerState.ClearSingleKeyRemaps();
|
keyboardManagerState.ClearSingleKeyRemaps();
|
||||||
|
DWORD successfulRemapCount = 0;
|
||||||
for (int i = 0; i < SingleKeyRemapControl::singleKeyRemapBuffer.size(); i++)
|
for (int i = 0; i < SingleKeyRemapControl::singleKeyRemapBuffer.size(); i++)
|
||||||
{
|
{
|
||||||
DWORD originalKey = SingleKeyRemapControl::singleKeyRemapBuffer[i][0];
|
DWORD originalKey = SingleKeyRemapControl::singleKeyRemapBuffer[i][0];
|
||||||
@@ -257,6 +258,10 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
|||||||
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
||||||
// Tooltip is already shown for this row
|
// Tooltip is already shown for this row
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
successfulRemapCount += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -278,6 +283,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
|||||||
{
|
{
|
||||||
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
|
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
|
||||||
}
|
}
|
||||||
|
Trace::KeyRemapCount(successfulRemapCount);
|
||||||
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
|
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "ShortcutControl.h"
|
#include "ShortcutControl.h"
|
||||||
#include "KeyDropDownControl.h"
|
#include "KeyDropDownControl.h"
|
||||||
#include "XamlBridge.h"
|
#include "XamlBridge.h"
|
||||||
|
#include <keyboardmanager/common/trace.h>
|
||||||
|
|
||||||
LRESULT CALLBACK EditShortcutsWindowProc(HWND, UINT, WPARAM, LPARAM);
|
LRESULT CALLBACK EditShortcutsWindowProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
@@ -167,7 +168,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
|||||||
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
|
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
|
||||||
// Clear existing shortcuts
|
// Clear existing shortcuts
|
||||||
keyboardManagerState.ClearOSLevelShortcuts();
|
keyboardManagerState.ClearOSLevelShortcuts();
|
||||||
|
DWORD successfulRemapCount = 0;
|
||||||
// Save the shortcuts that are valid and report if any of them were invalid
|
// Save the shortcuts that are valid and report if any of them were invalid
|
||||||
for (int i = 0; i < ShortcutControl::shortcutRemapBuffer.size(); i++)
|
for (int i = 0; i < ShortcutControl::shortcutRemapBuffer.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -182,6 +183,10 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
|||||||
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
||||||
// Tooltip is already shown for this row
|
// Tooltip is already shown for this row
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
successfulRemapCount += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -203,6 +208,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
|||||||
{
|
{
|
||||||
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
|
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
|
||||||
}
|
}
|
||||||
|
Trace::OSLevelShortcutRemapCount(successfulRemapCount);
|
||||||
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
|
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -12,6 +12,8 @@ using Microsoft.Plugin.Indexer.SearchHelper;
|
|||||||
using Microsoft.Search.Interop;
|
using Microsoft.Search.Interop;
|
||||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using Wox.Infrastructure.Logger;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Microsoft.Plugin.Indexer
|
namespace Microsoft.Plugin.Indexer
|
||||||
{
|
{
|
||||||
@@ -30,6 +32,9 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
// To access Windows Search functionalities
|
// To access Windows Search functionalities
|
||||||
private readonly WindowsSearchAPI _api = new WindowsSearchAPI();
|
private readonly WindowsSearchAPI _api = new WindowsSearchAPI();
|
||||||
|
|
||||||
|
// Reserved keywords in oleDB
|
||||||
|
private string ReservedStringPattern = @"^[\/\\\$\%]+$";
|
||||||
|
|
||||||
private IContextMenu _contextMenuLoader;
|
private IContextMenu _contextMenuLoader;
|
||||||
|
|
||||||
// To save the configurations of plugins
|
// To save the configurations of plugins
|
||||||
@@ -50,66 +55,67 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
_settings.MaxSearchCount = 50;
|
_settings.MaxSearchCount = 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
var regexMatch = Regex.Match(searchQuery, ReservedStringPattern);
|
||||||
|
|
||||||
|
if (!regexMatch.Success)
|
||||||
{
|
{
|
||||||
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
|
try
|
||||||
foreach (var searchResult in searchResultsList)
|
|
||||||
{
|
{
|
||||||
var path = searchResult.Path;
|
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
|
||||||
|
foreach (var searchResult in searchResultsList)
|
||||||
string workingDir = null;
|
|
||||||
if (_settings.UseLocationAsWorkingDir)
|
|
||||||
workingDir = Path.GetDirectoryName(path);
|
|
||||||
|
|
||||||
Result r = new Result();
|
|
||||||
r.Title = searchResult.Title;
|
|
||||||
r.SubTitle = "Search: " + path;
|
|
||||||
r.IcoPath = path;
|
|
||||||
r.Action = c =>
|
|
||||||
{
|
{
|
||||||
bool hide;
|
var path = searchResult.Path;
|
||||||
try
|
|
||||||
|
string workingDir = null;
|
||||||
|
if (_settings.UseLocationAsWorkingDir)
|
||||||
|
workingDir = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
|
Result r = new Result();
|
||||||
|
r.Title = searchResult.Title;
|
||||||
|
r.SubTitle = "Search: " + path;
|
||||||
|
r.IcoPath = path;
|
||||||
|
r.Action = c =>
|
||||||
{
|
{
|
||||||
Process.Start(new ProcessStartInfo
|
bool hide;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
FileName = path,
|
Process.Start(new ProcessStartInfo
|
||||||
UseShellExecute = true,
|
{
|
||||||
WorkingDirectory = workingDir
|
FileName = path,
|
||||||
});
|
UseShellExecute = true,
|
||||||
hide = true;
|
WorkingDirectory = workingDir
|
||||||
}
|
});
|
||||||
catch (Win32Exception)
|
hide = true;
|
||||||
|
}
|
||||||
|
catch (Win32Exception)
|
||||||
|
{
|
||||||
|
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
||||||
|
var msg = "Can't Open this file";
|
||||||
|
_context.API.ShowMsg(name, msg, string.Empty);
|
||||||
|
hide = false;
|
||||||
|
}
|
||||||
|
return hide;
|
||||||
|
};
|
||||||
|
r.ContextData = searchResult;
|
||||||
|
|
||||||
|
//If the result is a directory, then it's display should show a directory.
|
||||||
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
r.QueryTextDisplay = path;
|
||||||
var msg = "Can't Open this file";
|
|
||||||
_context.API.ShowMsg(name, msg, string.Empty);
|
|
||||||
hide = false;
|
|
||||||
}
|
}
|
||||||
return hide;
|
|
||||||
};
|
|
||||||
r.ContextData = searchResult;
|
|
||||||
|
|
||||||
//If the result is a directory, then it's display should show a directory.
|
results.Add(r);
|
||||||
if(Directory.Exists(path))
|
|
||||||
{
|
|
||||||
r.QueryTextDisplay = path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
results.Add(r);
|
|
||||||
}
|
}
|
||||||
}
|
catch (InvalidOperationException)
|
||||||
catch(InvalidOperationException)
|
|
||||||
{
|
|
||||||
//The connection has closed, internal error of ExecuteReader()
|
|
||||||
//Not showing this exception to the users
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
results.Add(new Result
|
|
||||||
{
|
{
|
||||||
Title = ex.ToString(),
|
//The connection has closed, internal error of ExecuteReader()
|
||||||
IcoPath = "Images\\WindowsIndexerImg.bmp"
|
//Not showing this exception to the users
|
||||||
});
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Info(ex.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,4 +27,5 @@
|
|||||||
#include <winrt/Windows.ApplicationModel.h>
|
#include <winrt/Windows.ApplicationModel.h>
|
||||||
#include <winrt/Windows.Storage.h>
|
#include <winrt/Windows.Storage.h>
|
||||||
|
|
||||||
|
#include <winrt/Windows.Foundation.Metadata.h>
|
||||||
#include <wil/resource.h>
|
#include <wil/resource.h>
|
||||||
@@ -207,6 +207,41 @@ BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args,
|
|||||||
return process_created;
|
return process_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following three helper functions determine if the user has a build version higher than or equal to 19h1, as that is a requirement for xaml islands
|
||||||
|
// Source : Microsoft-ui-xaml github
|
||||||
|
// Link: https://github.com/microsoft/microsoft-ui-xaml/blob/c045cde57c5c754683d674634a0baccda34d58c4/dev/dll/SharedHelpers.cpp
|
||||||
|
template<uint16_t APIVersion> bool IsAPIContractVxAvailable()
|
||||||
|
{
|
||||||
|
static bool isAPIContractVxAvailableInitialized = false;
|
||||||
|
static bool isAPIContractVxAvailable = false;
|
||||||
|
if (!isAPIContractVxAvailableInitialized)
|
||||||
|
{
|
||||||
|
isAPIContractVxAvailableInitialized = true;
|
||||||
|
isAPIContractVxAvailable = winrt::Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", APIVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAPIContractVxAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsAPIContractV8Available()
|
||||||
|
{
|
||||||
|
return IsAPIContractVxAvailable<8>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Is19H1OrHigher()
|
||||||
|
{
|
||||||
|
return IsAPIContractV8Available();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function returns true if the build is 19h1 or higher, so that we deploy the new settings.
|
||||||
|
// It returns false otherwise.
|
||||||
|
bool use_new_settings()
|
||||||
|
{
|
||||||
|
return Is19H1OrHigher();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DWORD g_settings_process_id = 0;
|
DWORD g_settings_process_id = 0;
|
||||||
|
|
||||||
void run_settings_window()
|
void run_settings_window()
|
||||||
@@ -223,7 +258,15 @@ void run_settings_window()
|
|||||||
|
|
||||||
// Arg 1: executable path.
|
// Arg 1: executable path.
|
||||||
std::wstring executable_path = get_module_folderpath();
|
std::wstring executable_path = get_module_folderpath();
|
||||||
executable_path.append(L"\\SettingsUIRunner\\Microsoft.PowerToys.Settings.UI.Runner.exe");
|
|
||||||
|
if (use_new_settings())
|
||||||
|
{
|
||||||
|
executable_path.append(L"\\SettingsUIRunner\\Microsoft.PowerToys.Settings.UI.Runner.exe");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
executable_path.append(L"\\PowerToysSettings.exe");
|
||||||
|
}
|
||||||
|
|
||||||
// Arg 2: pipe server. Generate unique names for the pipes, if getting a UUID is possible.
|
// Arg 2: pipe server. Generate unique names for the pipes, if getting a UUID is possible.
|
||||||
std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_");
|
std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_");
|
||||||
@@ -245,7 +288,7 @@ void run_settings_window()
|
|||||||
|
|
||||||
// Arg 4: settings theme.
|
// Arg 4: settings theme.
|
||||||
const std::wstring settings_theme_setting{ get_general_settings().theme };
|
const std::wstring settings_theme_setting{ get_general_settings().theme };
|
||||||
std::wstring settings_theme;
|
std::wstring settings_theme = L"system";
|
||||||
if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode()))
|
if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode()))
|
||||||
{
|
{
|
||||||
settings_theme = L"dark";
|
settings_theme = L"dark";
|
||||||
@@ -350,15 +393,27 @@ LExit:
|
|||||||
g_settings_process_id = 0;
|
g_settings_process_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_TITLE_LENGTH 100
|
||||||
void bring_settings_to_front()
|
void bring_settings_to_front()
|
||||||
{
|
{
|
||||||
auto callback = [](HWND hwnd, LPARAM data) -> BOOL {
|
auto callback = [](HWND hwnd, LPARAM data) -> BOOL {
|
||||||
DWORD processId;
|
DWORD processId;
|
||||||
if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id)
|
if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id)
|
||||||
{
|
{
|
||||||
ShowWindow(hwnd, SW_NORMAL);
|
std::wstring windowTitle = L"PowerToys Settings";
|
||||||
SetForegroundWindow(hwnd);
|
|
||||||
return FALSE;
|
WCHAR title[MAX_TITLE_LENGTH];
|
||||||
|
int len = GetWindowTextW(hwnd, title, MAX_TITLE_LENGTH);
|
||||||
|
if (len <= 0)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (wcsncmp(title, windowTitle.c_str(), len) == 0)
|
||||||
|
{
|
||||||
|
ShowWindow(hwnd, SW_RESTORE);
|
||||||
|
SetForegroundWindow(hwnd);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -378,3 +433,15 @@ void open_settings_window()
|
|||||||
std::thread(run_settings_window).detach();
|
std::thread(run_settings_window).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close_settings_window()
|
||||||
|
{
|
||||||
|
if (g_settings_process_id != 0)
|
||||||
|
{
|
||||||
|
HANDLE proc = OpenProcess(PROCESS_TERMINATE, false, g_settings_process_id);
|
||||||
|
if (proc != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
TerminateProcess(proc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
void open_settings_window();
|
void open_settings_window();
|
||||||
|
void close_settings_window();
|
||||||
@@ -67,6 +67,7 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
|
|||||||
Shell_NotifyIcon(NIM_DELETE, &tray_icon_data);
|
Shell_NotifyIcon(NIM_DELETE, &tray_icon_data);
|
||||||
tray_icon_created = false;
|
tray_icon_created = false;
|
||||||
}
|
}
|
||||||
|
close_settings_window();
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
|
|||||||
Reference in New Issue
Block a user