Compare commits

..

8 Commits

Author SHA1 Message Date
Jaime Bernardo
8981e1a825 GPO line in General instead 2024-10-01 15:47:35 +01:00
Jaime Bernardo
e0c1a1d32b Fix spellcheck 2024-10-01 14:05:47 +01:00
Jaime Bernardo
3d413eff80 Update binary hashes 2024-10-01 13:59:34 +01:00
Jaime Bernardo
2720368d22 Update with latest repo changes 2024-10-01 13:57:57 +01:00
Jaime Bernardo
b0e4336c36 Address PR feedback 2024-09-30 11:35:56 +01:00
Jaime Bernardo
bd867c03fe Update README.md
Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
2024-09-30 11:32:39 +01:00
Jaime Bernardo
24d7e60d55 Mention ZoomIt 2024-09-27 17:12:07 +01:00
Jaime Bernardo
a0088b6335 0.85 changelog 2024-09-27 15:07:37 +01:00
36 changed files with 265 additions and 297 deletions

View File

@@ -1590,7 +1590,7 @@ SYSKEYUP
SYSLIB
SYSMENU
SYSTEMAPPS
SYSTEMSETTINGS
systemsettings
SYSTEMTIME
SYSTEMWOW
tapp

View File

@@ -32,7 +32,7 @@ parameters:
- name: enableMsBuildCaching
type: boolean
displayName: "Enable MSBuild Caching"
default: false
default: true
- name: runTests
type: boolean
displayName: "Run Tests"

View File

@@ -6,14 +6,14 @@
<PackageVersion Include="Appium.WebDriver" Version="4.4.5" />
<PackageVersion Include="Azure.AI.OpenAI" Version="1.0.0-beta.12" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.1.240821" />
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.Markdown" Version="7.1.2" />
<PackageVersion Include="ControlzEx" Version="6.0.0" />

View File

@@ -1299,14 +1299,14 @@ EXHIBIT A -Mozilla Public License.
- Appium.WebDriver 4.4.5
- Azure.AI.OpenAI 1.0.0-beta.12
- CommunityToolkit.Mvvm 8.2.2
- CommunityToolkit.WinUI.Animations 8.0.240109
- CommunityToolkit.WinUI.Collections 8.0.240109
- CommunityToolkit.WinUI.Controls.Primitives 8.0.240109
- CommunityToolkit.WinUI.Controls.Segmented 8.0.240109
- CommunityToolkit.WinUI.Controls.SettingsControls 8.0.240109
- CommunityToolkit.WinUI.Controls.Sizers 8.0.240109
- CommunityToolkit.WinUI.Converters 8.0.240109
- CommunityToolkit.WinUI.Extensions 8.0.240109
- CommunityToolkit.WinUI.Animations 8.1.240821
- CommunityToolkit.WinUI.Collections 8.1.240821
- CommunityToolkit.WinUI.Controls.Primitives 8.1.240821
- CommunityToolkit.WinUI.Controls.Segmented 8.1.240821
- CommunityToolkit.WinUI.Controls.SettingsControls 8.1.240821
- CommunityToolkit.WinUI.Controls.Sizers 8.1.240821
- CommunityToolkit.WinUI.Converters 8.1.240821
- CommunityToolkit.WinUI.Extensions 8.1.240821
- CommunityToolkit.WinUI.UI.Controls.DataGrid 7.1.2
- CommunityToolkit.WinUI.UI.Controls.Markdown 7.1.2
- ControlzEx 6.0.0

View File

@@ -4,6 +4,13 @@
[How to use PowerToys][usingPowerToys-docs-link] | [Downloads & Release notes][github-release-link] | [Contributing to PowerToys](#contributing) | [What's Happening](#whats-happening) | [Roadmap](#powertoys-roadmap)
## Build status
| Architecture | Solution (Main) | Solution (Stable) | Installer (Main) |
|--------------|-----------------|-------------------|------------------|
| x64 | [![Build Status for Main](https://dev.azure.com/shine-oss/PowerToys/_apis/build/status%2FPowerToys%20CI?branchName=main&jobName=Build%20x64%20Release)](https://dev.azure.com/shine-oss/PowerToys/_build/latest?definitionId=3&branchName=main) | [![Build Status for Stable](https://dev.azure.com/shine-oss/PowerToys/_apis/build/status%2FPowerToys%20CI?branchName=stable&jobName=Build%20x64%20Release)](https://dev.azure.com/shine-oss/PowerToys/_build/latest?definitionId=3&branchName=stable) | [![Build Status Installer pipeline](https://dev.azure.com/microsoft/Dart/_apis/build/status/PowerToys/PowerToys%20Signed%20YAML%20Release%20Build?branchName=main&jobName=Build&configuration=Build%20Release_x64)](https://dev.azure.com/microsoft/Dart/_build/latest?definitionId=76541&branchName=main) |
| ARM64 | [![Build Status for Main](https://dev.azure.com/shine-oss/PowerToys/_apis/build/status%2FPowerToys%20CI?branchName=main&jobName=Build%20arm64%20Release)](https://dev.azure.com/shine-oss/PowerToys/_build/latest?definitionId=3&branchName=main) | [![Build Status for Stable](https://dev.azure.com/shine-oss/PowerToys/_apis/build/status%2FPowerToys%20CI?branchName=main&jobName=Build%20arm64%20Release)](https://dev.azure.com/shine-oss/PowerToys/_build/latest?definitionId=3&branchName=main) | [![Build Status Installer pipeline](https://dev.azure.com/microsoft/Dart/_apis/build/status/PowerToys/PowerToys%20Signed%20YAML%20Release%20Build?branchName=main&jobName=Build&configuration=Build%20Release_arm64)](https://dev.azure.com/microsoft/Dart/_build/latest?definitionId=76541&branchName=main) |
## About
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. For more info on [PowerToys overviews and how to use the utilities][usingPowerToys-docs-link], or any other tools and resources for [Windows development environments](https://learn.microsoft.com/windows/dev-environment/overview), head over to [learn.microsoft.com][usingPowerToys-docs-link]!

View File

@@ -54,7 +54,6 @@ call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuil
call move /Y ..\..\..\VideoConference.wxs.bk ..\..\..\VideoConference.wxs
call move /Y ..\..\..\WinAppSDK.wxs.bk ..\..\..\WinAppSDK.wxs
call move /Y ..\..\..\WinUI3Applications.wxs.bk ..\..\..\WinUI3Applications.wxs
call move /Y ..\..\..\Workspaces.wxs.bk ..\..\..\Workspaces.wxs
</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
@@ -126,7 +125,6 @@ call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuil
<Compile Include="Core.wxs" />
<Compile Include="Resources.wxs" />
<Compile Include="WinAppSDK.wxs" />
<Compile Include="Workspaces.wxs" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixFirewallExtension">

View File

@@ -79,7 +79,6 @@
<ComponentGroupRef Id="WindowsAppSDKComponentGroup" />
<ComponentGroupRef Id="ToolComponentGroup" />
<ComponentGroupRef Id="MonacoSRCHeatGenerated" />
<ComponentGroupRef Id="WorkspacesComponentGroup" />
</Feature>
<SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLFOLDER]" After="CostFinalize" />

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" >
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define WorkspacesImagesComponentFiles=?>
<?define WorkspacesImagesComponentFilesPath=$(var.BinDir)Assets\Workspaces\?>
<Fragment>
<!-- Shortcut guide files -->
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="WorkspacesAssetsInstallFolder" Name="Workspaces" />
</DirectoryRef>
<DirectoryRef Id="WorkspacesAssetsInstallFolder" FileSource="$(var.WorkspacesImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WorkspacesImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Workspaces -->
<ComponentGroup Id="WorkspacesComponentGroup" >
<Component Id="RemoveWorkspacesAssetsFolder" Guid="34FC1245-1197-4025-9CF1-A298D509C2CC" Directory="WorkspacesAssetsInstallFolder" >
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveWorkspacesAssetsFolder" Value="" KeyPath="yes"/>
</RegistryKey>
<RemoveFolder Id="RemoveFolderWorkspacesAssetsFolder" Directory="WorkspacesAssetsInstallFolder" On="uninstall"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -317,7 +317,3 @@ Generate-FileComponents -fileListName "SettingsV2AssetsFiles" -wxsFilePath $PSSc
Generate-FileComponents -fileListName "SettingsV2AssetsModulesFiles" -wxsFilePath $PSScriptRoot\Settings.wxs -regroot $registryroot
Generate-FileComponents -fileListName "SettingsV2OOBEAssetsModulesFiles" -wxsFilePath $PSScriptRoot\Settings.wxs -regroot $registryroot
Generate-FileComponents -fileListName "SettingsV2OOBEAssetsFluentIconsFiles" -wxsFilePath $PSScriptRoot\Settings.wxs -regroot $registryroot
#Workspaces
Generate-FileList -fileDepsJson "" -fileListName WorkspacesImagesComponentFiles -wxsFilePath $PSScriptRoot\Workspaces.wxs -depsPath "$PSScriptRoot..\..\..\$platform\Release\Assets\Workspaces\"
Generate-FileComponents -fileListName "WorkspacesImagesComponentFiles" -wxsFilePath $PSScriptRoot\Workspaces.wxs -regroot $registryroot

View File

@@ -76,7 +76,6 @@
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\VideoConference.wxs"" ""$(ProjectDir)..\PowerToysSetup\VideoConference.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\WinAppSDK.wxs"" ""$(ProjectDir)..\PowerToysSetup\WinAppSDK.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\WinUI3Applications.wxs"" ""$(ProjectDir)..\PowerToysSetup\WinUI3Applications.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetup\Workspaces.wxs"" ""$(ProjectDir)..\PowerToysSetup\Workspaces.wxs.bk""""
if not "$(NormalizedPerUserValue)" == "true" call powershell.exe -NonInteractive -executionpolicy Unrestricted -File ..\PowerToysSetup\generateAllFileComponents.ps1 -platform $(Platform)
if "$(NormalizedPerUserValue)" == "true" call powershell.exe -NonInteractive -executionpolicy Unrestricted -File ..\PowerToysSetup\generateAllFileComponents.ps1 -platform $(Platform) -installscopeperuser $(NormalizedPerUserValue)
</Command>

View File

@@ -51,30 +51,21 @@ public:
return true;
}
virtual void set_config(const wchar_t* config) override
virtual void set_config(PCWSTR config) override
{
// The following just checks to see if the Template Location was changed for metrics purposes
// Note: We are not saving the settings here and instead relying on read/write of json in Settings App .cs code paths
try
{
// Parse the input JSON string.
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
json::JsonObject config_as_json = json::JsonValue::Parse(winrt::to_hstring(config)).GetObjectW();
values.save_to_settings_file();
NewSettingsInstance().Load();
const auto latest_location_value = config_as_json.GetNamedString(newplus::constants::non_localizable::settings_json_key_template_location).data();
const auto existing_location_value = NewSettingsInstance().GetTemplateLocation();
auto templateValue = values.get_string_value(newplus::constants::non_localizable::settings_json_key_template_location);
if (templateValue.has_value())
if (!newplus::utilities::wstring_same_when_comparing_ignore_case(latest_location_value, existing_location_value))
{
const auto latest_location_value = templateValue.value();
const auto existing_location_value = NewSettingsInstance().GetTemplateLocation();
if (!newplus::utilities::wstring_same_when_comparing_ignore_case(latest_location_value, existing_location_value))
{
Trace::EventChangedTemplateLocation();
}
Trace::EventChangedTemplateLocation();
}
}
catch (std::exception& e)
{
@@ -91,9 +82,6 @@ public:
{
Logger::info("New+ enabled via Settings UI");
// Log telemetry
Trace::EventToggleOnOff(true);
newplus::utilities::register_msix_package();
powertoy_new_enabled = true;
@@ -102,7 +90,8 @@ public:
virtual void disable() override
{
Logger::info("New+ disabled via Settings UI");
Disable(true);
powertoy_new_enabled = false;
}
virtual bool is_enabled() override
@@ -127,23 +116,12 @@ public:
virtual void destroy() override
{
Disable(false);
delete this;
}
private:
bool powertoy_new_enabled = false;
void Disable(bool const traceEvent)
{
// Log telemetry
if (traceEvent)
{
Trace::EventToggleOnOff(false);
}
powertoy_new_enabled = false;
}
void init_settings()
{
powertoy_new_enabled = NewSettingsInstance().GetEnabled();

View File

@@ -3,7 +3,6 @@
#include <common/utils/gpo.h>
#include <common/utils/json.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/SettingsAPI/settings_objects.h>
#include "settings.h"
#include "constants.h"
@@ -39,13 +38,18 @@ NewSettings::NewSettings()
void NewSettings::Save()
{
PowerToysSettings::PowerToyValues values(newplus::constants::non_localizable::powertoy_key, newplus::constants::non_localizable::powertoy_key);
json::JsonObject new_settings_json_data;
values.add_property(newplus::constants::non_localizable::settings_json_key_hide_file_extension, new_settings.hide_file_extension);
values.add_property(newplus::constants::non_localizable::settings_json_key_hide_starting_digits, new_settings.hide_starting_digits);
values.add_property(newplus::constants::non_localizable::settings_json_key_template_location, new_settings.template_location);
new_settings_json_data.SetNamedValue(newplus::constants::non_localizable::settings_json_key_hide_file_extension,
json::value(new_settings.hide_file_extension));
values.save_to_settings_file();
new_settings_json_data.SetNamedValue(newplus::constants::non_localizable::settings_json_key_hide_starting_digits,
json::value(new_settings.hide_starting_digits));
new_settings_json_data.SetNamedValue(newplus::constants::non_localizable::settings_json_key_template_location,
json::value(new_settings.template_location));
json::to_file(new_settings_json_file_path, new_settings_json_data);
GetSystemTimeAsFileTime(&new_settings_last_loaded_timestamp);
}
@@ -118,27 +122,35 @@ void NewSettings::Reload()
void NewSettings::ParseJson()
{
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(newplus::constants::non_localizable::powertoy_key);
auto templateValue = settings.get_string_value(newplus::constants::non_localizable::settings_json_key_template_location);
if (templateValue.has_value())
auto json = json::from_file(new_settings_json_file_path);
if (json)
{
new_settings.template_location = templateValue.value();
}
try
{
const json::JsonObject& new_settings_json = json.value();
auto hideFileExtensionValue = settings.get_bool_value(newplus::constants::non_localizable::settings_json_key_hide_file_extension);
if (hideFileExtensionValue.has_value())
{
new_settings.hide_file_extension = hideFileExtensionValue.value();
}
if (json::has(new_settings_json, newplus::constants::non_localizable::settings_json_key_hide_file_extension, json::JsonValueType::Boolean))
{
new_settings.hide_file_extension = new_settings_json.GetNamedBoolean(
newplus::constants::non_localizable::settings_json_key_hide_file_extension);
}
auto hideStartingDigitsValue = settings.get_bool_value(newplus::constants::non_localizable::settings_json_key_hide_starting_digits);
if (hideStartingDigitsValue.has_value())
{
new_settings.hide_starting_digits = hideStartingDigitsValue.value();
}
if (json::has(new_settings_json, newplus::constants::non_localizable::settings_json_key_hide_starting_digits, json::JsonValueType::Boolean))
{
new_settings.hide_starting_digits = new_settings_json.GetNamedBoolean(
newplus::constants::non_localizable::settings_json_key_hide_starting_digits);
}
if (json::has(new_settings_json, newplus::constants::non_localizable::settings_json_key_template_location, json::JsonValueType::String))
{
new_settings.template_location = new_settings_json.GetNamedString(
newplus::constants::non_localizable::settings_json_key_template_location);
}
}
catch (const winrt::hresult_error&)
{
}
}
GetSystemTimeAsFileTime(&new_settings_last_loaded_timestamp);
}

View File

Before

Width:  |  Height:  |  Size: 456 KiB

After

Width:  |  Height:  |  Size: 456 KiB

View File

@@ -247,7 +247,7 @@ namespace WorkspacesEditor.Models
{
Logger.LogWarning($"Icon not found on app path: {AppPath}. Using default icon");
IsNotFound = true;
_icon = new Icon(@"Assets\Workspaces\DefaultIcon.ico");
_icon = new Icon(@"images\DefaultIcon.ico");
}
}

View File

@@ -23,12 +23,16 @@
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\Assets\Workspaces\Workspaces.ico</ApplicationIcon>
<ApplicationIcon>images\Workspaces.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AssemblyName>PowerToys.WorkspacesEditor</AssemblyName>
</PropertyGroup>
<ItemGroup>
<None Remove="images\DefaultIcon.ico" />
<None Remove="images\Workspaces.ico" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<WrapperTool>tlbimp</WrapperTool>
@@ -50,10 +54,10 @@
</COMReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\Assets\**\*.*">
<Link>Assets\Workspaces\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Content Include="images\DefaultIcon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="images\Workspaces.ico" />
</ItemGroup>
<ItemGroup>
@@ -96,4 +100,7 @@
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<_DeploymentManifestIconFile Remove="images\Workspaces.ico" />
</ItemGroup>
</Project>

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

View File

@@ -16,7 +16,6 @@
const std::wstring moduleName = L"Workspaces\\WorkspacesLauncher";
const std::wstring internalPath = L"";
const std::wstring instanceMutexName = L"Local\\PowerToys_WorkspacesLauncher_InstanceMutex";
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cmdShow)
{
@@ -29,18 +28,6 @@ int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cm
return 0;
}
auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str());
if (mutex == nullptr)
{
Logger::error(L"Failed to create mutex. {}", get_last_error_or_default(GetLastError()));
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
Logger::warn(L"WorkspacesLauncher instance is already running");
return 0;
}
std::wstring cmdLineStr{ GetCommandLineW() };
auto cmdArgs = split(cmdLineStr, L" ");
if (cmdArgs.workspaceId.empty())

View File

@@ -58,7 +58,7 @@ namespace WorkspacesLauncherUI.Models
{
Logger.LogWarning($"Icon not found on app path: {Application.ApplicationPath}. Using default icon");
IsNotFound = true;
_icon = new Icon(@"Assets\Workspaces\DefaultIcon.ico");
_icon = new Icon(@"images\DefaultIcon.ico");
}
}

View File

@@ -23,20 +23,16 @@
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\Assets\Workspaces\Workspaces.ico</ApplicationIcon>
<ApplicationIcon>images\Workspaces.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AssemblyName>PowerToys.WorkspacesLauncherUI</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Content Include="..\Assets\**\*.*">
<Link>Assets\Workspaces\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Remove="images\DefaultIcon.ico" />
<None Remove="images\Workspaces.ico" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<WrapperTool>tlbimp</WrapperTool>
@@ -57,6 +53,14 @@
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<Content Include="images\DefaultIcon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="images\Workspaces.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

View File

@@ -2,9 +2,8 @@
#include "AppUtils.h"
#include <atlbase.h>
#include <propvarutil.h>
#include <ShlObj.h>
#include <TlHelp32.h>
#include <propvarutil.h>
#include <filesystem>
@@ -29,8 +28,6 @@ namespace Utils
constexpr const wchar_t* PowerToys = L"PowerToys.exe";
constexpr const wchar_t* PowerToysSettingsUpper = L"POWERTOYS.SETTINGS.EXE";
constexpr const wchar_t* PowerToysSettings = L"PowerToys.Settings.exe";
constexpr const wchar_t* ApplicationFrameHost = L"APPLICATIONFRAMEHOST.EXE";
constexpr const wchar_t* Exe = L".EXE";
}
AppList IterateAppsFolder()
@@ -187,39 +184,11 @@ namespace Utils
return IterateAppsFolder();
}
DWORD GetParentPid(DWORD pid)
{
DWORD res = 0;
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(h, &pe))
{
do
{
if (pe.th32ProcessID == pid)
{
res = pe.th32ParentProcessID;
}
} while (Process32Next(h, &pe));
}
CloseHandle(h);
return res;
}
std::optional<AppData> GetApp(const std::wstring& appPath, DWORD pid, const AppList& apps)
std::optional<AppData> GetApp(const std::wstring& appPath, const AppList& apps)
{
std::wstring appPathUpper(appPath);
std::transform(appPathUpper.begin(), appPathUpper.end(), appPathUpper.begin(), towupper);
// filter out ApplicationFrameHost.exe
if (appPathUpper.ends_with(NonLocalizable::ApplicationFrameHost))
{
return std::nullopt;
}
// edge case, "Windows Software Development Kit" has the same app path as "File Explorer"
if (appPathUpper == NonLocalizable::FileExplorerPath)
{
@@ -248,7 +217,6 @@ namespace Utils
}
}
// search in apps list
for (const auto& appData : apps)
{
if (!appData.installPath.empty())
@@ -258,14 +226,6 @@ namespace Utils
if (appPathUpper.contains(installPathUpper))
{
// Update the install path to keep .exe in the path
if (!installPathUpper.ends_with(NonLocalizable::Exe))
{
auto settingsAppData = appData;
settingsAppData.installPath = appPath;
return settingsAppData;
}
return appData;
}
@@ -291,43 +251,11 @@ namespace Utils
if (appNameUpper == exeNameUpper)
{
auto result = appData;
result.installPath = appPath;
return result;
return appData;
}
}
// try with parent process (fix for Steam)
auto parentPid = GetParentPid(pid);
auto parentProcessPath = get_process_path(parentPid);
if (!parentProcessPath.empty())
{
std::wstring parentDirUpper = std::filesystem::path(parentProcessPath).parent_path().c_str();
std::transform(parentDirUpper.begin(), parentDirUpper.end(), parentDirUpper.begin(), towupper);
if (appPathUpper.starts_with(parentDirUpper))
{
Logger::info(L"original process is in the subfolder of the parent process");
for (const auto& appData : apps)
{
if (!appData.installPath.empty())
{
std::wstring installDirUpper = std::filesystem::path(appData.installPath).parent_path().c_str();
std::transform(installDirUpper.begin(), installDirUpper.end(), installDirUpper.begin(), towupper);
if (installDirUpper == parentDirUpper)
{
return appData;
}
}
}
}
}
return AppData{
.name = std::filesystem::path(appPath).stem(),
.installPath = appPath
};
}
@@ -335,11 +263,7 @@ namespace Utils
std::optional<AppData> GetApp(HWND window, const AppList& apps)
{
std::wstring processPath = get_process_path(window);
DWORD pid{};
GetWindowThreadProcessId(window, &pid);
return Utils::Apps::GetApp(processPath, pid, apps);
return Utils::Apps::GetApp(processPath, apps);
}
}
}

View File

@@ -19,7 +19,7 @@ namespace Utils
const std::wstring& GetCurrentFolderUpper();
AppList GetAppsList();
std::optional<AppData> GetApp(const std::wstring& appPath, DWORD pid, const AppList& apps);
std::optional<AppData> GetApp(const std::wstring& appPath, const AppList& apps);
std::optional<AppData> GetApp(HWND window, const AppList& apps);
}
}

View File

@@ -12,12 +12,22 @@
#include <workspaces-common/WindowFilter.h>
#include <WorkspacesLib/AppUtils.h>
#include <TlHelp32.h>
namespace SnapshotUtils
{
namespace NonLocalizable
{
const std::wstring ApplicationFrameHost = L"ApplicationFrameHost.exe";
namespace FileManagers
{
const std::wstring FileExplorer = L"EXPLORER"; // windows explorer
const std::wstring TotalCommander = L"TOTALCMD"; // total commander
const std::wstring DirectoryOpus = L"DOPUS"; // directory opus
const std::wstring QDir = L"Q-DIR"; // Q-Dir
const std::wstring Xplorer2 = L"XPLORER2"; // Xplorer2
}
}
class WbemHelper
@@ -168,6 +178,39 @@ namespace SnapshotUtils
return false;
}
DWORD GetParentPid(DWORD pid)
{
DWORD res = 0;
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(h, &pe))
{
do
{
if (pe.th32ProcessID == pid)
{
res = pe.th32ParentProcessID;
}
} while (Process32Next(h, &pe));
}
CloseHandle(h);
return res;
}
bool IsFileManagerApp(std::wstring processPath)
{
std::wstring appName = std::filesystem::path(processPath).stem();
std::transform(appName.begin(), appName.end(), appName.begin(), towupper);
return ((appName == NonLocalizable::FileManagers::FileExplorer) // windows explorer
|| (appName.starts_with(NonLocalizable::FileManagers::TotalCommander)) // total commander
|| (appName == NonLocalizable::FileManagers::DirectoryOpus) // directory opus
|| (appName == NonLocalizable::FileManagers::QDir) // Q-Dir
|| (appName.starts_with(NonLocalizable::FileManagers::Xplorer2))); // Xplorer2
}
std::vector<WorkspacesData::WorkspacesProject::Application> GetApps(const std::function<unsigned int(HWND)> getMonitorNumberFromWindowHandle)
{
std::vector<WorkspacesData::WorkspacesProject::Application> apps{};
@@ -242,17 +285,83 @@ namespace SnapshotUtils
continue;
}
auto data = Utils::Apps::GetApp(processPath, pid, installedApps);
auto data = Utils::Apps::GetApp(processPath, installedApps);
if (!data.has_value() || data->name.empty())
{
Logger::info(L"Installed app not found: {}", processPath);
continue;
Logger::info(L"Installed app not found: {}, try parent process", processPath);
bool standaloneApp = false;
bool steamLikeApp = false;
// try with parent process (fix for Steam)
auto parentPid = GetParentPid(pid);
auto parentProcessPath = get_process_path(parentPid);
// check if original process is in the subfolder of the parent process which is a sign of an steam-like app
std::wstring processDir = std::filesystem::path(processPath).parent_path().c_str();
std::wstring parentProcessDir = std::filesystem::path(parentProcessPath).parent_path().c_str();
if (parentProcessPath == L"")
{
if (processPath.ends_with(NonLocalizable::ApplicationFrameHost))
{
// filter out ApplicationFrameHost.exe
continue;
}
else
{
Logger::info(L"parent process unknown, the parent app is an already closed file manager app, it is a standalone app");
standaloneApp = true;
}
}
else if (processDir.starts_with(parentProcessDir))
{
Logger::info(L"parent process: {}, original process is in the subfolder of the parent process, it is a steam-like app", parentProcessPath);
steamLikeApp = true;
}
else if (IsFileManagerApp(parentProcessPath))
{
Logger::info(L"parent process: {}, The parent process is a known file manager app, it is a standalone app", parentProcessPath);
standaloneApp = true;
}
else
{
Logger::info(L"parent process: {}, The parent process is NOT a known file manager app, it is a steam-like app", parentProcessPath);
steamLikeApp = true;
}
if (standaloneApp)
{
data = Utils::Apps::AppData{
.name = std::filesystem::path(processPath).stem(),
.installPath = processPath,
};
}
else if (steamLikeApp)
{
if (!parentProcessPath.empty())
{
data = Utils::Apps::GetApp(parentProcessPath, installedApps);
if (!data.has_value() || data->name.empty())
{
Logger::info(L"Installed parent app not found: {}", processPath);
continue;
}
processPath = parentProcessPath;
}
else
{
Logger::info(L"Parent process path not found");
continue;
}
}
}
WorkspacesData::WorkspacesProject::Application app{
.name = data.value().name,
.title = title,
.path = data.value().installPath,
.path = processPath,
.packageFullName = data.value().packageFullName,
.appUserModelId = data.value().appUserModelId,
.commandLineArgs = L"", // GetCommandLineArgs(pid, wbemHelper),

View File

@@ -161,16 +161,19 @@ void WindowArranger::processWindow(HWND window)
return;
}
std::wstring title = WindowUtils::GetWindowTitle(window);
if (title.empty())
{
return;
}
std::wstring processPath = get_process_path(window);
if (processPath.empty())
{
return;
}
DWORD pid{};
GetWindowThreadProcessId(window, &pid);
auto data = Utils::Apps::GetApp(processPath, pid, m_installedApps);
auto data = Utils::Apps::GetApp(processPath, m_installedApps);
if (!data.has_value())
{
return;
@@ -186,6 +189,7 @@ void WindowArranger::processWindow(HWND window)
return;
}
Logger::debug(L"Move {}", title);
iter->second.window = window;
if (moveWindow(window, iter->first))
{

View File

@@ -14,6 +14,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading;
using Awake.Core.Models;
using Awake.Core.Native;
using Awake.Properties;

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Threading;
using ManagedCommon;
namespace Awake.Core.Threading
{
@@ -50,7 +49,7 @@ namespace Awake.Core.Threading
}
catch (Exception e)
{
Logger.LogError("Error during execution of the STS context message loop: " + e.Message);
Console.WriteLine("Error during execution: " + e.Message);
}
}
}
@@ -59,8 +58,7 @@ namespace Awake.Core.Threading
{
lock (queue)
{
// Signal the end of the message loop
queue.Enqueue(null);
queue.Enqueue(null); // Signal the end of the message loop
Monitor.Pulse(queue);
}
}

View File

@@ -15,6 +15,7 @@ using System.Reflection;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Awake.Core;
using Awake.Core.Models;
using Awake.Core.Native;

View File

@@ -1,34 +0,0 @@
// 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;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class NewPlusProperties
{
public const string ModuleName = "NewPlus";
public NewPlusProperties()
{
HideFileExtension = new BoolProperty(true);
HideStartingDigits = new BoolProperty(true);
TemplateLocation = new StringProperty(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "PowerToys", "NewPlus", "Templates"));
}
[JsonPropertyName("HideFileExtension")]
public BoolProperty HideFileExtension { get; set; }
[JsonPropertyName("HideStartingDigits")]
public BoolProperty HideStartingDigits { get; set; }
[JsonPropertyName("TemplateLocation")]
public StringProperty TemplateLocation { get; set; }
public override string ToString() => JsonSerializer.Serialize(this);
}
}

View File

@@ -12,27 +12,34 @@ using Settings.UI.Library.Resources;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class NewPlusSettings : BasePTModuleSettings, ISettingsConfig
public class NewPlusSettings : ISettingsConfig
{
public const string ModuleName = "NewPlus";
public const string ModuleVersion = "1.0";
[JsonPropertyName("properties")]
public NewPlusProperties Properties { get; set; }
public NewPlusSettings()
public void InitializeWithDefaultSettings()
{
Name = ModuleName;
Version = ModuleVersion;
Properties = new NewPlusProperties();
// This code path should never happen
}
public string ToJsonString()
{
return JsonSerializer.Serialize(this);
}
[JsonPropertyName("HideFileExtension")]
public bool HideFileExtension { get; set; }
[JsonPropertyName("HideStartingDigits")]
public bool HideStartingDigits { get; set; }
[JsonPropertyName("TemplateLocation")]
public string TemplateLocation { get; set; }
public string GetModuleName()
{
return Name;
return ModuleName;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;

View File

@@ -130,7 +130,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
var settingsUtils = new SettingsUtils();
var settings = NewPlusViewModel.LoadSettings(settingsUtils);
NewPlusViewModel.CopyTemplateExamples(settings.Properties.TemplateLocation.Value);
NewPlusViewModel.CopyTemplateExamples(settings.TemplateLocation);
}
}

View File

@@ -47,9 +47,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
Settings = LoadSettings(settingsUtils);
// Initialize properties
_hideFileExtension = Settings.Properties.HideFileExtension.Value;
_hideStartingDigits = Settings.Properties.HideStartingDigits.Value;
_templateLocation = Settings.Properties.TemplateLocation.Value;
_hideFileExtension = Settings.HideFileExtension;
_hideStartingDigits = Settings.HideStartingDigits;
_templateLocation = Settings.TemplateLocation;
InitializeEnabledValue();
InitializeGpoValues();
@@ -119,10 +119,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (_templateLocation != value)
{
_templateLocation = value;
Settings.Properties.TemplateLocation.Value = value;
Settings.TemplateLocation = value;
OnPropertyChanged(nameof(TemplateLocation));
NotifySettingsChanged();
SaveSettingsToJson();
}
}
}
@@ -144,10 +146,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (_hideFileExtension != value && !_hideFileExtensionIsGPOConfigured)
{
_hideFileExtension = value;
Settings.Properties.HideFileExtension.Value = value;
Settings.HideFileExtension = value;
OnPropertyChanged(nameof(HideFileExtension));
NotifySettingsChanged();
SaveSettingsToJson();
}
}
}
@@ -164,10 +168,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (_hideStartingDigits != value)
{
_hideStartingDigits = value;
Settings.Properties.HideStartingDigits.Value = value;
Settings.HideStartingDigits = value;
OnPropertyChanged(nameof(HideStartingDigits));
NotifySettingsChanged();
SaveSettingsToJson();
}
}
}
@@ -202,10 +208,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
settings = settingsUtils.GetSettingsOrDefault<NewPlusSettings>(NewPlusSettings.ModuleName);
if (string.IsNullOrEmpty(settings.Properties.TemplateLocation.Value))
if (string.IsNullOrEmpty(settings.TemplateLocation))
{
// This can happen when running the DEBUG Settings application without first letting the runner create the default settings file.
settings.Properties.TemplateLocation.Value = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "PowerToys", "NewPlus", "Templates");
settings.TemplateLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "PowerToys", "NewPlus", "Templates");
}
}
catch (Exception e)
@@ -250,21 +256,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private void OpenNewTemplateFolder()
{
try
var process = new ProcessStartInfo()
{
CopyTemplateExamples(_templateLocation);
var process = new ProcessStartInfo()
{
FileName = _templateLocation,
UseShellExecute = true,
};
Process.Start(process);
}
catch (Exception ex)
{
Logger.LogError("Failed to show NewPlus template folder.", ex);
}
FileName = _templateLocation,
UseShellExecute = true,
};
Process.Start(process);
}
private async void PickNewTemplateFolder()
@@ -281,5 +278,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.GetSettingsWindow());
return await Task.FromResult(GetFolderDialogWithFlags(hwnd, FolderDialogFlags._BIF_NEWDIALOGSTYLE));
}
private void SaveSettingsToJson()
{
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
}
}
}