Merge branch 'dev/build-features' into users/niels9001/settingsV2UXtweaks

This commit is contained in:
Clint Rutkas 2020-05-05 21:28:44 -07:00 committed by GitHub
commit 98ede836d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 473 additions and 130 deletions

View File

@ -59,7 +59,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
this.AutoDownloadUpdates = false;
this.Theme = "system";
this.SystemTheme = "light";
this.PowertoysVersion = interop.CommonManaged.GetProductVersion();
try
{
this.PowertoysVersion = DefaultPowertoysVersion();
}
catch
{
this.PowertoysVersion = "v0.0.0";
}
this.Enabled = new EnabledModules();
this.CustomActionName = string.Empty;
}
@ -69,5 +77,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
return JsonSerializer.Serialize(this);
}
private string DefaultPowertoysVersion()
{
return interop.CommonManaged.GetProductVersion();
}
}
}

View File

@ -15,8 +15,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
MaxMRUSize = new IntProperty();
ShowIcon = new BoolProperty();
ExtendedContextMenuOnly = new BoolProperty();
Enabled = new BoolProperty();
}
public BoolProperty Enabled { get; set; }
[JsonPropertyName("bool_persist_input")]
public BoolProperty PersistState { get; set; }

View File

@ -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);
}
}
}

View File

@ -81,4 +81,4 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
}
}
}
}

View File

@ -12,6 +12,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
[JsonPropertyName("PowerRename")]
public PowerRenameSettings PowerRename { get; set; }
public SndPowerRenameSettings()
{
}
public SndPowerRenameSettings(PowerRenameSettings settings)
{
PowerRename = settings;

View File

@ -369,16 +369,16 @@
<value>Choose Settings color</value>
</data>
<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 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 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 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 name="FileEplorerPreview_ToggleSwitch_Preview_MD.Header" xml:space="preserve">
<value>Markdown Preview Handler</value>
@ -396,7 +396,7 @@
<value>Open-source notice</value>
</data>
<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 name="FancyZones_BorderColor.Text" xml:space="preserve">
<value>Zone border color (Default #FFFFFF)</value>

View File

@ -75,7 +75,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
ShellPage.DefaultSndMSGCallback(snd.ToString());
_powerRenameEnabled = value;
RaisePropertyChanged();
OnPropertyChanged("IsEnabled");
}
}
}

View File

@ -53,6 +53,12 @@
<TextBlock x:Uid="PowerRename_ShellIntergration"
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"
Margin="{StaticResource SmallTopMargin}"
IsOn="{Binding Mode=TwoWay, Path=EnabledOnContextMenu}"

View File

@ -129,6 +129,7 @@
<Compile Include="UnitTestApp.xaml.cs">
<DependentUpon>UnitTestApp.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModelTests\PowerRename.cs" />
<Compile Include="ViewModelTests\PowerPreview.cs" />
<Compile Include="ViewModelTests\ShortcutGuide.cs" />
<Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" />

View File

@ -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);
}
}
}

View File

@ -100,6 +100,7 @@
</ClCompile>
<ClCompile Include="RemapShortcut.cpp" />
<ClCompile Include="Shortcut.cpp" />
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Helpers.h" />
@ -109,6 +110,7 @@
<ClInclude Include="pch.h" />
<ClInclude Include="RemapShortcut.h" />
<ClInclude Include="Shortcut.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\common.vcxproj">

View File

@ -33,6 +33,9 @@
<ClCompile Include="KeyDelay.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Trace.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="KeyboardManagerState.h">
@ -56,5 +59,8 @@
<ClInclude Include="KeyboardManagerConstants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Trace.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -13,6 +13,7 @@
#include "winrt/Windows.UI.Text.h"
#include "winrt/Windows.UI.Core.h"
#include <stdlib.h>
#include <ProjectTelemetry.h>
using namespace winrt;
using namespace Windows::UI;

View 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"));
}

View 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;
};

View File

@ -5,7 +5,7 @@
STRINGTABLE
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"
END

View File

@ -108,7 +108,6 @@
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
@ -118,7 +117,6 @@
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)src\common\common.vcxproj">

View File

@ -4,7 +4,6 @@
#include <interface/win_hook_event_data.h>
#include <common/settings_objects.h>
#include <common/shared_constants.h>
#include "trace.h"
#include "resource.h"
#include <keyboardmanager/ui/EditKeyboardWindow.h>
#include <keyboardmanager/ui/EditShortcutsWindow.h>
@ -12,7 +11,8 @@
#include <keyboardmanager/common/Shortcut.h>
#include <keyboardmanager/common/RemapShortcut.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;
@ -267,6 +267,9 @@ public:
virtual void enable()
{
m_enabled = true;
// Log telemetry
Trace::EnableKeyboardManager(true);
// Start keyboard hook
start_lowlevel_keyboard_hook();
}
@ -274,6 +277,9 @@ public:
virtual void disable()
{
m_enabled = false;
// Log telemetry
Trace::EnableKeyboardManager(false);
// Stop keyboard hook
stop_lowlevel_keyboard_hook();
}

View File

@ -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));
}

View File

@ -1,9 +0,0 @@
#pragma once
class Trace
{
public:
static void RegisterProvider();
static void UnregisterProvider();
static void MyEvent();
};

View File

@ -3,6 +3,7 @@
#include "SingleKeyRemapControl.h"
#include "KeyDropDownControl.h"
#include "XamlBridge.h"
#include <keyboardmanager/common/trace.h>
LRESULT CALLBACK EditKeyboardWindowProc(HWND, UINT, WPARAM, LPARAM);
@ -215,7 +216,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
// Clear existing Key Remaps
keyboardManagerState.ClearSingleKeyRemaps();
DWORD successfulRemapCount = 0;
for (int i = 0; i < SingleKeyRemapControl::singleKeyRemapBuffer.size(); i++)
{
DWORD originalKey = SingleKeyRemapControl::singleKeyRemapBuffer[i][0];
@ -257,6 +258,10 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
// Tooltip is already shown for this row
}
else
{
successfulRemapCount += 1;
}
}
else
{
@ -278,6 +283,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
{
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
}
Trace::KeyRemapCount(successfulRemapCount);
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
});

View File

@ -3,6 +3,7 @@
#include "ShortcutControl.h"
#include "KeyDropDownControl.h"
#include "XamlBridge.h"
#include <keyboardmanager/common/trace.h>
LRESULT CALLBACK EditShortcutsWindowProc(HWND, UINT, WPARAM, LPARAM);
@ -167,7 +168,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
// Clear existing shortcuts
keyboardManagerState.ClearOSLevelShortcuts();
DWORD successfulRemapCount = 0;
// Save the shortcuts that are valid and report if any of them were invalid
for (int i = 0; i < ShortcutControl::shortcutRemapBuffer.size(); i++)
{
@ -182,6 +183,10 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
// Tooltip is already shown for this row
}
else
{
successfulRemapCount += 1;
}
}
else
{
@ -203,6 +208,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
{
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
}
Trace::OSLevelShortcutRemapCount(successfulRemapCount);
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
});

View File

@ -1,15 +1,14 @@
#include "resource.h"
#include "../../../common/version.h"
<EFBFBD>
匀吀刀䤀一䜀吀䄀䈀䰀䔀ഀ<EFBFBD>
䈀䔀䜀䤀一ഀ<EFBFBD>
IDS_LAUNCHER_NAME L"Run"
IDS_LAUNCHER_SETTINGS_DESC L"<No description>"
IDS_LAUNCHER_NAME L"Launcher"
IDS_LAUNCHER_SETTINGS_DESC L"This feature requires Windows 10, May 2019 Update"
䔀一䐀ഀ<EFBFBD>
<EFBFBD>
 嘀䔀刀匀䤀伀一䤀一䘀伀ഀ<EFBFBD>
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEVERSION 0,1,0,0
PRODUCTVERSION 0,1,0,0
 䘀䤀䰀䔀䘀䰀䄀䜀匀䴀䄀匀䬀  砀㌀昀䰀ഀ<EFBFBD>
⌀椀昀搀攀昀 开䐀䔀䈀唀䜀ഀ<EFBFBD>
 䘀䤀䰀䔀䘀䰀䄀䜀匀  砀㄀䰀ഀ<EFBFBD>
@ -24,14 +23,14 @@
    䈀䔀䜀䤀一ഀ<EFBFBD>
        䈀䰀伀䌀䬀    㐀戀 ∀ഀ<EFBFBD>
        䈀䔀䜀䤀一ഀ<EFBFBD>
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", "Microsoft.Launcher Module"
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", "Microsoft.Launcher"
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", "Microsoft.Launcher.dll"
VALUE "ProductName", "Microsoft.Launcher"
VALUE "ProductVersion", PRODUCT_VERSION_STRING
VALUE "CompanyName", "Company Name"
VALUE "FileDescription", "Wox.Launcher Module"
VALUE "FileVersion", "0.1.0.0"
VALUE "InternalName", "Wox.Launcher"
VALUE "LegalCopyright", "Copyright (C) 2019 Company Name"
VALUE "OriginalFilename", "Wox.Launcher.dll"
VALUE "ProductName", "Wox.Launcher"
VALUE "ProductVersion", "0.1.0.0"
        䔀一䐀ഀ<EFBFBD>
    䔀一䐀ഀ<EFBFBD>
    䈀䰀伀䌀䬀 ∀嘀愀爀䘀椀氀攀䤀渀昀漀∀ഀ<EFBFBD>

View File

@ -12,6 +12,8 @@ using Microsoft.Plugin.Indexer.SearchHelper;
using Microsoft.Search.Interop;
using Microsoft.PowerToys.Settings.UI.Lib;
using System.Windows.Controls;
using Wox.Infrastructure.Logger;
using System.Text.RegularExpressions;
namespace Microsoft.Plugin.Indexer
{
@ -30,6 +32,9 @@ namespace Microsoft.Plugin.Indexer
// To access Windows Search functionalities
private readonly WindowsSearchAPI _api = new WindowsSearchAPI();
// Reserved keywords in oleDB
private string ReservedStringPattern = @"^[\/\\\$\%]+$";
private IContextMenu _contextMenuLoader;
// To save the configurations of plugins
@ -50,67 +55,68 @@ namespace Microsoft.Plugin.Indexer
_settings.MaxSearchCount = 50;
}
try
{
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
foreach (var searchResult in searchResultsList)
{
var path = searchResult.Path;
var regexMatch = Regex.Match(searchQuery, ReservedStringPattern);
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;
try
{
Process.Start(new ProcessStartInfo
{
FileName = path,
UseShellExecute = true,
WorkingDirectory = workingDir
});
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))
if (!regexMatch.Success)
{
try
{
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
foreach (var searchResult in searchResultsList)
{
r.QueryTextDisplay = path;
}
results.Add(r);
}
}
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(),
IcoPath = "Images\\WindowsIndexerImg.bmp"
});
}
var path = searchResult.Path;
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;
try
{
Process.Start(new ProcessStartInfo
{
FileName = path,
UseShellExecute = true,
WorkingDirectory = workingDir
});
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))
{
r.QueryTextDisplay = path;
}
results.Add(r);
}
}
catch (InvalidOperationException)
{
//The connection has closed, internal error of ExecuteReader()
//Not showing this exception to the users
}
catch (Exception ex)
{
Log.Info(ex.ToString());
}
}
}
return results;

View File

@ -27,4 +27,5 @@
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Foundation.Metadata.h>
#include <wil/resource.h>

View File

@ -207,6 +207,41 @@ BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args,
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;
void run_settings_window()
@ -223,7 +258,15 @@ void run_settings_window()
// Arg 1: executable path.
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.
std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_");
@ -245,7 +288,7 @@ void run_settings_window()
// Arg 4: 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()))
{
settings_theme = L"dark";
@ -350,15 +393,27 @@ LExit:
g_settings_process_id = 0;
}
#define MAX_TITLE_LENGTH 100
void bring_settings_to_front()
{
auto callback = [](HWND hwnd, LPARAM data) -> BOOL {
DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id)
{
ShowWindow(hwnd, SW_NORMAL);
SetForegroundWindow(hwnd);
return FALSE;
std::wstring windowTitle = L"PowerToys Settings";
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;
@ -378,3 +433,15 @@ void open_settings_window()
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);
}
}
}

View File

@ -1,2 +1,3 @@
#pragma once
void open_settings_window();
void close_settings_window();

View File

@ -67,6 +67,7 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
Shell_NotifyIcon(NIM_DELETE, &tray_icon_data);
tray_icon_created = false;
}
close_settings_window();
PostQuitMessage(0);
break;
case WM_CLOSE: