Compare commits
30 Commits
copilot/fi
...
niels9001/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb8197bd5a | ||
|
|
70c4016860 | ||
|
|
fef6921d9b | ||
|
|
ba1eb08c1f | ||
|
|
480049388d | ||
|
|
e505d68b9a | ||
|
|
49a6bdc889 | ||
|
|
a6785ad87c | ||
|
|
bea563474b | ||
|
|
643bba087c | ||
|
|
4375f0439c | ||
|
|
466013dad9 | ||
|
|
f4d3cfb951 | ||
|
|
8ad322dab3 | ||
|
|
d382966150 | ||
|
|
437ca174d4 | ||
|
|
c9642c3c68 | ||
|
|
3eea52d062 | ||
|
|
5bc1644882 | ||
|
|
06ea71b57d | ||
|
|
04c73f6ff1 | ||
|
|
039e3d924c | ||
|
|
280c3642be | ||
|
|
4806b145f0 | ||
|
|
84d492a92e | ||
|
|
1e5fde68a8 | ||
|
|
85d8fbdabd | ||
|
|
eba0b9c619 | ||
|
|
8f029db21e | ||
|
|
9081f98de6 |
1
.github/actions/spell-check/expect.txt
vendored
@@ -27,7 +27,6 @@ admx
|
||||
advancedpaste
|
||||
advancedpasteui
|
||||
advancedpasteuishortcut
|
||||
advapi
|
||||
advfirewall
|
||||
AFeature
|
||||
affordances
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Automatic New Issue Deduplication
|
||||
on:
|
||||
issues:
|
||||
types: [opened, reopened]
|
||||
permissions:
|
||||
models: read
|
||||
issues: write
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.issue.number }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
deduplicate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run Deduplicate Action
|
||||
uses: pelikhan/action-genai-issue-dedup@v0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
label_as_duplicate: true
|
||||
@@ -411,28 +411,9 @@ jobs:
|
||||
!**\obj\**
|
||||
|
||||
- pwsh: |-
|
||||
$Packages = Get-ChildItem -Recurse -Filter "Microsoft.CmdPal.UI_*.msix"
|
||||
Write-Host "Found $($Packages.Count) CmdPal MSIX package(s):"
|
||||
foreach ($pkg in $Packages) {
|
||||
Write-Host " - $($pkg.FullName)"
|
||||
}
|
||||
|
||||
if ($Packages.Count -gt 0) {
|
||||
# Priority: Look for platform-specific MSIX (x64/arm64) first, then fall back to any
|
||||
$PlatformPackage = $Packages | Where-Object { $_.Name -match "Microsoft\.CmdPal\.UI_.*_(x64|arm64)\.msix$" } | Select-Object -First 1
|
||||
if ($PlatformPackage) {
|
||||
$Package = $PlatformPackage
|
||||
Write-Host "Using platform-specific package: $($Package.FullName)"
|
||||
} else {
|
||||
$Package = $Packages | Select-Object -First 1
|
||||
Write-Host "Using first available package: $($Package.FullName)"
|
||||
}
|
||||
|
||||
$PackageFilename = $Package.FullName
|
||||
Write-Host "##vso[task.setvariable variable=CmdPalPackagePath]${PackageFilename}"
|
||||
} else {
|
||||
Write-Warning "No CmdPal MSIX packages found!"
|
||||
}
|
||||
$Package = (Get-ChildItem -Recurse -Filter "Microsoft.CmdPal.UI_*.msix" | Select -First 1)
|
||||
$PackageFilename = $Package.FullName
|
||||
Write-Host "##vso[task.setvariable variable=CmdPalPackagePath]${PackageFilename}"
|
||||
displayName: Locate the CmdPal MSIX
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.Markdown" Version="7.1.2" />
|
||||
<PackageVersion Include="CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock" Version="0.1.250703-build.2173" />
|
||||
<PackageVersion Include="CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock" Version="0.1.250910-build.2249" />
|
||||
<PackageVersion Include="ControlzEx" Version="6.0.0" />
|
||||
<PackageVersion Include="HelixToolkit" Version="2.24.0" />
|
||||
<PackageVersion Include="HelixToolkit.Core.Wpf" Version="2.24.0" />
|
||||
@@ -45,7 +44,7 @@
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.8" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.15.0" />
|
||||
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
|
||||
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.3179.45" />
|
||||
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
|
||||
<!-- Package Microsoft.Win32.SystemEvents added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Drawing.Common but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.8" />
|
||||
<PackageVersion Include="Microsoft.WindowsPackageManager.ComInterop" Version="1.10.340" />
|
||||
@@ -57,8 +56,8 @@
|
||||
This is present due to a bug in CsWinRT where WPF projects cause the analyzer to fail.
|
||||
-->
|
||||
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4948" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.8.250907003" />
|
||||
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.7.250513003" />
|
||||
<PackageVersion Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
|
||||
<PackageVersion Include="ModernWpfUI" Version="0.9.4" />
|
||||
|
||||
@@ -1509,7 +1509,6 @@ SOFTWARE.
|
||||
- CommunityToolkit.WinUI.Converters
|
||||
- CommunityToolkit.WinUI.Extensions
|
||||
- CommunityToolkit.WinUI.UI.Controls.DataGrid
|
||||
- CommunityToolkit.WinUI.UI.Controls.Markdown
|
||||
- ControlzEx
|
||||
- HelixToolkit
|
||||
- HelixToolkit.Core.Wpf
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
<Fragment>
|
||||
<DirectoryRef Id="WinUI3AppsInstallFolder">
|
||||
<Directory Id="CmdPalInstallFolder" Name="CmdPal">
|
||||
<Directory Id="CmdPalDepsInstallFolder" Name="Dependencies">
|
||||
<?if $(sys.BUILDARCH) = x64 ?>
|
||||
<Directory Id="CmdPalDepsX64InstallFolder" Name="x64" />
|
||||
<?else ?>
|
||||
<Directory Id="CmdPalDepsArm64InstallFolder" Name="arm64" />
|
||||
<?endif ?>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</DirectoryRef>
|
||||
|
||||
@@ -26,14 +33,41 @@
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<?if $(sys.BUILDARCH) = x64 ?>
|
||||
<DirectoryRef Id="CmdPalDepsX64InstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\x64">
|
||||
<Component Id="Module_CmdPal_Deps" Win64="yes" Guid="C2790FC4-0665-4462-947A-D942A2AABFF0">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\x64\Microsoft.VCLibs.x64.14.00.Desktop.appx" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?else ?>
|
||||
<DirectoryRef Id="CmdPalDepsArm64InstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\arm64">
|
||||
<Component Id="Module_CmdPal_Deps" Win64="yes" Guid="C2790FC4-0665-4462-947A-D942A2AABFF0">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\arm64\Microsoft.VCLibs.ARM64.14.00.Desktop.appx" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?endif ?>
|
||||
|
||||
<ComponentGroup Id="CmdPalComponentGroup">
|
||||
<Component Id="RemoveCmdPalFolder" Guid="2DF90C08-CC75-4245-A14E-B82904636C53" Directory="INSTALLFOLDER">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="RemoveCmdPalFolder" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<RemoveFolder Id="RemoveCmdPalInstallDirFolder" Directory="CmdPalInstallFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveCmdPalDepsInstallDirFolder" Directory="CmdPalDepsInstallFolder" On="uninstall"/>
|
||||
<?if $(sys.BUILDARCH) = x64 ?>
|
||||
<RemoveFolder Id="RemoveCmdPalDepsX64InstallDirFolder" Directory="CmdPalDepsX64InstallFolder" On="uninstall"/>
|
||||
<?else ?>
|
||||
<RemoveFolder Id="RemoveCmdPalDepsArm64InstallDirFolder" Directory="CmdPalDepsArm64InstallFolder" On="uninstall"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
<ComponentRef Id="Module_CmdPal" />
|
||||
<ComponentRef Id="Module_CmdPal_Deps" />
|
||||
</ComponentGroup>
|
||||
|
||||
</Fragment>
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
<Fragment>
|
||||
<DirectoryRef Id="WinUI3AppsInstallFolder">
|
||||
<Directory Id="CmdPalInstallFolder" Name="CmdPal">
|
||||
<Directory Id="CmdPalDepsInstallFolder" Name="Dependencies">
|
||||
<?if $(sys.BUILDARCH) = x64 ?>
|
||||
<Directory Id="CmdPalDepsX64InstallFolder" Name="x64" />
|
||||
<?else?>
|
||||
<Directory Id="CmdPalDepsArm64InstallFolder" Name="arm64" />
|
||||
<?endif?>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="CmdPalInstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test">
|
||||
@@ -18,14 +25,40 @@
|
||||
<?endif?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?if $(sys.BUILDARCH) = x64 ?>
|
||||
<DirectoryRef Id="CmdPalDepsX64InstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\x64">
|
||||
<Component Id="Module_CmdPal_Deps" Guid="C2790FC4-0665-4462-947A-D942A2AABFF0" Bitness="always64">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes" />
|
||||
</RegistryKey>
|
||||
<File Id="Microsoft.VCLibs.x64.14.00.Desktop.appx" Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\x64\Microsoft.VCLibs.x64.14.00.Desktop.appx" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?else?>
|
||||
<DirectoryRef Id="CmdPalDepsArm64InstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\arm64">
|
||||
<Component Id="Module_CmdPal_Deps" Guid="C2790FC4-0665-4462-947A-D942A2AABFF0" Bitness="always64">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes" />
|
||||
</RegistryKey>
|
||||
<File Id="Microsoft.VCLibs.ARM64.14.00.Desktop.appx" Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\arm64\Microsoft.VCLibs.ARM64.14.00.Desktop.appx" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?endif?>
|
||||
<ComponentGroup Id="CmdPalComponentGroup">
|
||||
<Component Id="RemoveCmdPalFolder" Guid="2DF90C08-CC75-4245-A14E-B82904636C53" Directory="INSTALLFOLDER">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="RemoveCmdPalFolder" Value="" KeyPath="yes" />
|
||||
</RegistryKey>
|
||||
<RemoveFolder Id="RemoveCmdPalInstallDirFolder" Directory="CmdPalInstallFolder" On="uninstall" />
|
||||
<RemoveFolder Id="RemoveCmdPalDepsInstallDirFolder" Directory="CmdPalDepsInstallFolder" On="uninstall" />
|
||||
<?if $(sys.BUILDARCH) = x64 ?>
|
||||
<RemoveFolder Id="RemoveCmdPalDepsX64InstallDirFolder" Directory="CmdPalDepsX64InstallFolder" On="uninstall" />
|
||||
<?else?>
|
||||
<RemoveFolder Id="RemoveCmdPalDepsArm64InstallDirFolder" Directory="CmdPalDepsArm64InstallFolder" On="uninstall" />
|
||||
<?endif?>
|
||||
</Component>
|
||||
<ComponentRef Id="Module_CmdPal" />
|
||||
<ComponentRef Id="Module_CmdPal_Deps" />
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
@@ -147,13 +141,7 @@
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -165,19 +153,7 @@
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -4,14 +4,5 @@
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.26100.4188" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Base" version="1.8.250831001" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Foundation" version="1.8.250906002" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.WinUI" version="1.8.250906003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Runtime" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.DWrite" version="1.8.25090401" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.InteractiveExperiences" version="1.8.250906004" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Widgets" version="1.8.250904007" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.AI" version="1.8.37" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools.MSIX" version="1.7.20250829.1" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.7.250513003" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -33,7 +33,6 @@ namespace
|
||||
const wchar_t JSON_KEY_AUTO_ACTIVATE[] = L"auto_activate";
|
||||
const wchar_t JSON_KEY_GLIDE_TRAVEL_SPEED[] = L"gliding_travel_speed";
|
||||
const wchar_t JSON_KEY_GLIDE_DELAY_SPEED[] = L"gliding_delay_speed";
|
||||
const wchar_t JSON_KEY_GLIDING_CURSOR_ENABLED[] = L"gliding_cursor_enabled";
|
||||
}
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
@@ -107,9 +106,6 @@ private:
|
||||
// Gliding cursor state machine
|
||||
std::atomic<int> m_glideState{ 0 }; // 0..4 like the AHK script
|
||||
|
||||
// Gliding cursor enabled state
|
||||
bool m_glidingCursorEnabled = true;
|
||||
|
||||
// Timer configuration: 10ms tick, speeds are defined per 200ms base window
|
||||
static constexpr int kTimerTickMs = 10;
|
||||
static constexpr int kBaseSpeedTickMs = 200; // mapping period for configured pixel counts
|
||||
@@ -391,11 +387,6 @@ private:
|
||||
|
||||
void HandleGlidingHotkey()
|
||||
{
|
||||
if (!m_glidingCursorEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto s = m_state;
|
||||
if (!s)
|
||||
{
|
||||
@@ -743,17 +734,6 @@ private:
|
||||
m_state->slowVSpeed = 5;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
// Parse Gliding Cursor Enabled
|
||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_GLIDING_CURSOR_ENABLED);
|
||||
m_glidingCursorEnabled = jsonPropertiesObject.GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Logger::info("Failed to initialize gliding cursor enabled from settings. Using default true.");
|
||||
m_glidingCursorEnabled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
1162
src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
|
||||
// <summary>
|
||||
// Initialization and clean up.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
using Microsoft.Win32;
|
||||
using MouseWithoutBorders.Class;
|
||||
using MouseWithoutBorders.Core;
|
||||
using MouseWithoutBorders.Form;
|
||||
using Windows.UI.Input.Preview.Injection;
|
||||
|
||||
using Thread = MouseWithoutBorders.Core.Thread;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal partial class Common
|
||||
{
|
||||
private static bool initDone;
|
||||
internal static int REOPEN_WHEN_WSAECONNRESET = -10054;
|
||||
internal static int REOPEN_WHEN_HOTKEY = -10055;
|
||||
internal static int PleaseReopenSocket;
|
||||
internal static bool ReopenSocketDueToReadError;
|
||||
|
||||
internal static DateTime LastResumeSuspendTime { get; set; } = DateTime.UtcNow;
|
||||
|
||||
internal static bool InitDone
|
||||
{
|
||||
get => Common.initDone;
|
||||
set => Common.initDone = value;
|
||||
}
|
||||
|
||||
internal static void UpdateMachineTimeAndID()
|
||||
{
|
||||
Common.MachineName = Common.MachineName.Trim();
|
||||
_ = MachineStuff.MachinePool.TryUpdateMachineID(Common.MachineName, Common.MachineID, true);
|
||||
}
|
||||
|
||||
private static void InitializeMachinePoolFromSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
MachineInf[] info = MachinePoolHelpers.LoadMachineInfoFromMachinePoolStringSetting(Setting.Values.MachinePoolString);
|
||||
for (int i = 0; i < info.Length; i++)
|
||||
{
|
||||
info[i].Name = info[i].Name.Trim();
|
||||
}
|
||||
|
||||
MachineStuff.MachinePool.Initialize(info);
|
||||
MachineStuff.MachinePool.ResetIPAddressesForDeadMachines(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log(ex);
|
||||
MachineStuff.MachinePool.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SetupMachineNameAndID()
|
||||
{
|
||||
try
|
||||
{
|
||||
GetMachineName();
|
||||
DesMachineID = MachineStuff.NewDesMachineID = MachineID;
|
||||
|
||||
// MessageBox.Show(machineID.ToString(CultureInfo.CurrentCulture)); // For test
|
||||
InitializeMachinePoolFromSettings();
|
||||
|
||||
Common.MachineName = Common.MachineName.Trim();
|
||||
_ = MachineStuff.MachinePool.LearnMachine(Common.MachineName);
|
||||
_ = MachineStuff.MachinePool.TryUpdateMachineID(Common.MachineName, Common.MachineID, true);
|
||||
|
||||
MachineStuff.UpdateMachinePoolStringSetting();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
_ = Helper.GetUserName();
|
||||
Common.GeneratedKey = true;
|
||||
|
||||
try
|
||||
{
|
||||
Common.MyKey = Setting.Values.MyKey;
|
||||
int tmp = Setting.Values.MyKeyDaysToExpire;
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
Common.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
Common.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
InputSimulation.Injector = InputInjector.TryCreate();
|
||||
if (InputSimulation.Injector != null)
|
||||
{
|
||||
InputSimulation.MoveMouseRelative(0, 0);
|
||||
NativeMethods.InjectMouseInputAvailable = true;
|
||||
}
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
NativeMethods.InjectMouseInputAvailable = false;
|
||||
Logger.Log($"{nameof(NativeMethods.InjectMouseInputAvailable)} = false");
|
||||
}
|
||||
|
||||
bool dummy = Setting.Values.DrawMouseEx;
|
||||
Is64bitOS = IntPtr.Size == 8;
|
||||
tcpPort = Setting.Values.TcpPort;
|
||||
GetScreenConfig();
|
||||
PackageSent = new PackageMonitor(0);
|
||||
PackageReceived = new PackageMonitor(0);
|
||||
SetupMachineNameAndID();
|
||||
InitEncryption();
|
||||
CreateHelperThreads();
|
||||
|
||||
SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged);
|
||||
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
|
||||
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
|
||||
PleaseReopenSocket = 9;
|
||||
/* TODO: Telemetry for the matrix? */
|
||||
}
|
||||
|
||||
private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||||
{
|
||||
Helper.WndProcCounter++;
|
||||
|
||||
if (e.Mode is PowerModes.Resume or PowerModes.Suspend)
|
||||
{
|
||||
Logger.TelemetryLogTrace($"{nameof(SystemEvents_PowerModeChanged)}: {e.Mode}", SeverityLevel.Information);
|
||||
LastResumeSuspendTime = DateTime.UtcNow;
|
||||
MachineStuff.SwitchToMultipleMode(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateHelperThreads()
|
||||
{
|
||||
// NOTE(@yuyoyuppe): service crashes while trying to obtain this info, disabling.
|
||||
/*
|
||||
Thread watchDogThread = new(new ThreadStart(WatchDogThread), nameof(WatchDogThread));
|
||||
watchDogThread.Priority = ThreadPriority.Highest;
|
||||
watchDogThread.Start();
|
||||
*/
|
||||
|
||||
helper = new Thread(new ThreadStart(Helper.HelperThread), "Helper Thread");
|
||||
helper.SetApartmentState(ApartmentState.STA);
|
||||
helper.Start();
|
||||
}
|
||||
|
||||
private static void AskHelperThreadsToExit(int waitTime)
|
||||
{
|
||||
Helper.signalHelperToExit = true;
|
||||
Helper.signalWatchDogToExit = true;
|
||||
_ = EvSwitch.Set();
|
||||
|
||||
int c = 0;
|
||||
if (helper != null && c < waitTime)
|
||||
{
|
||||
while (Helper.signalHelperToExit)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
helper = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
SendByeBye();
|
||||
|
||||
// UnhookClipboard();
|
||||
AskHelperThreadsToExit(500);
|
||||
MainForm.NotifyIcon.Visible = false;
|
||||
MainForm.NotifyIcon.Dispose();
|
||||
CloseAllFormsAndHooks();
|
||||
|
||||
DoSomethingInUIThread(() =>
|
||||
{
|
||||
Sk?.Close(true);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static long lastReleaseAllKeysCall;
|
||||
|
||||
internal static void ReleaseAllKeys()
|
||||
{
|
||||
if (Math.Abs(GetTick() - lastReleaseAllKeysCall) < 2000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastReleaseAllKeysCall = GetTick();
|
||||
|
||||
KEYBDDATA kd;
|
||||
kd.dwFlags = (int)LLKHF.UP;
|
||||
|
||||
VK[] keys = new VK[]
|
||||
{
|
||||
VK.LSHIFT, VK.LCONTROL, VK.LMENU, VK.LWIN, VK.RSHIFT,
|
||||
VK.RCONTROL, VK.RMENU, VK.RWIN, VK.SHIFT, VK.MENU, VK.CONTROL,
|
||||
};
|
||||
|
||||
Logger.LogDebug("***** ReleaseAllKeys has been called! *****:");
|
||||
|
||||
foreach (VK vk in keys)
|
||||
{
|
||||
if ((NativeMethods.GetAsyncKeyState((IntPtr)vk) & 0x8000) != 0)
|
||||
{
|
||||
Logger.LogDebug(vk.ToString() + " is down, release it...");
|
||||
Hook?.ResetLastSwitchKeys(); // Sticky key can turn ALL PC mode on (CtrlCtrlCtrl)
|
||||
kd.wVk = (int)vk;
|
||||
InputSimulation.SendKey(kd);
|
||||
Hook?.ResetLastSwitchKeys();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
|
||||
{
|
||||
Logger.LogDebug("NetworkAvailabilityEventArgs.IsAvailable: " + e.IsAvailable.ToString(CultureInfo.InvariantCulture));
|
||||
Helper.WndProcCounter++;
|
||||
ScheduleReopenSocketsDueToNetworkChanges(!e.IsAvailable);
|
||||
}
|
||||
|
||||
private static void ScheduleReopenSocketsDueToNetworkChanges(bool closeSockets = true)
|
||||
{
|
||||
if (closeSockets)
|
||||
{
|
||||
// Slept/hibernated machine may still have the sockets' status as Connected:( (unchanged) so it would not re-connect after a timeout when waking up.
|
||||
// Closing the sockets when it is going to sleep/hibernate will trigger the reconnection faster when it wakes up.
|
||||
DoSomethingInUIThread(
|
||||
() =>
|
||||
{
|
||||
SocketStuff s = Sk;
|
||||
Sk = null;
|
||||
s?.Close(false);
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
if (!Common.IsMyDesktopActive())
|
||||
{
|
||||
PleaseReopenSocket = 0;
|
||||
}
|
||||
else if (PleaseReopenSocket != 10)
|
||||
{
|
||||
PleaseReopenSocket = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static string ActiveDesktop => Common.activeDesktop;
|
||||
|
||||
internal static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
private static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
GetScreenConfig();
|
||||
}
|
||||
@@ -340,7 +340,7 @@ namespace MouseWithoutBorders
|
||||
Setting.Values.LastX = JUST_GOT_BACK_FROM_SCREEN_SAVER;
|
||||
if (cleanupIfExit)
|
||||
{
|
||||
InitAndCleanup.Cleanup();
|
||||
Common.Cleanup();
|
||||
}
|
||||
|
||||
Process.GetCurrentProcess().KillProcess();
|
||||
|
||||
@@ -33,7 +33,6 @@ using MouseWithoutBorders.Class;
|
||||
using MouseWithoutBorders.Core;
|
||||
using MouseWithoutBorders.Exceptions;
|
||||
|
||||
using Clipboard = MouseWithoutBorders.Core.Clipboard;
|
||||
using Thread = MouseWithoutBorders.Core.Thread;
|
||||
|
||||
// Log is enough
|
||||
@@ -91,8 +90,8 @@ namespace MouseWithoutBorders
|
||||
private static FrmMatrix matrixForm;
|
||||
private static FrmInputCallback inputCallbackForm;
|
||||
private static FrmAbout aboutForm;
|
||||
private static Thread helper;
|
||||
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
|
||||
internal static Thread helper;
|
||||
internal static int screenWidth;
|
||||
internal static int screenHeight;
|
||||
#pragma warning restore SA1307
|
||||
@@ -122,9 +121,7 @@ namespace MouseWithoutBorders
|
||||
internal static int switchCount;
|
||||
#pragma warning restore SA1307
|
||||
private static long lastReconnectByHotKeyTime;
|
||||
#pragma warning disable SA1307 // Accessible fields should begin with upper-case names
|
||||
internal static int tcpPort;
|
||||
#pragma warning restore SA1307
|
||||
private static int tcpPort;
|
||||
private static bool secondOpenSocketTry;
|
||||
private static string binaryName;
|
||||
|
||||
@@ -213,7 +210,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static bool Is64bitOS
|
||||
{
|
||||
get; set;
|
||||
get; private set;
|
||||
|
||||
// set { Common.is64bitOS = value; }
|
||||
}
|
||||
@@ -614,7 +611,7 @@ namespace MouseWithoutBorders
|
||||
}
|
||||
* */
|
||||
|
||||
internal static void SendByeBye()
|
||||
private static void SendByeBye()
|
||||
{
|
||||
Logger.LogDebug($"{nameof(SendByeBye)}");
|
||||
SendPackage(ID.ALL, PackageType.ByeBye);
|
||||
@@ -728,7 +725,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static void SendImage(string machine, string file)
|
||||
{
|
||||
Clipboard.LastDragDropFile = file;
|
||||
LastDragDropFile = file;
|
||||
|
||||
// Send ClipboardCapture
|
||||
if (machine.Equals("All", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -747,7 +744,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static void SendImage(ID src, string file)
|
||||
{
|
||||
Clipboard.LastDragDropFile = file;
|
||||
LastDragDropFile = file;
|
||||
|
||||
// Send ClipboardCapture
|
||||
SendPackage(src, PackageType.ClipboardCapture);
|
||||
@@ -1294,7 +1291,7 @@ namespace MouseWithoutBorders
|
||||
});
|
||||
}
|
||||
|
||||
internal static string GetMyStorageDir()
|
||||
private static string GetMyStorageDir()
|
||||
{
|
||||
string st = string.Empty;
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ using MouseWithoutBorders.Core;
|
||||
|
||||
using SystemClipboard = System.Windows.Forms.Clipboard;
|
||||
#if !MM_HELPER
|
||||
using Clipboard = MouseWithoutBorders.Core.Clipboard;
|
||||
using Thread = MouseWithoutBorders.Core.Thread;
|
||||
#endif
|
||||
|
||||
@@ -160,7 +159,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
public void SendClipboardData(ByteArrayOrString data, bool isFilePath)
|
||||
{
|
||||
_ = Clipboard.CheckClipboardEx(data, isFilePath);
|
||||
_ = Common.CheckClipboardEx(data, isFilePath);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -579,7 +579,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
Common.ShowToolTip("Reconnecting...", 2000);
|
||||
Common.LastReconnectByHotKeyTime = Common.GetTick();
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_HOTKEY;
|
||||
Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -632,7 +632,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
// Common.DoSomethingInUIThread(delegate()
|
||||
{
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
}
|
||||
|
||||
// );
|
||||
|
||||
@@ -407,7 +407,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
ResetModifiersState(Setting.Values.HotKeyLockMachine);
|
||||
eatKey = true;
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
_ = NativeMethods.LockWorkStation();
|
||||
}
|
||||
}
|
||||
@@ -439,7 +439,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
ctrlDown = altDown = false;
|
||||
eatKey = true;
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -449,7 +449,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
winDown = false;
|
||||
eatKey = true;
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
uint rv = NativeMethods.LockWorkStation();
|
||||
Logger.LogDebug("LockWorkStation returned " + rv.ToString(CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace MouseWithoutBorders.Class
|
||||
_ = Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
InitAndCleanup.Init();
|
||||
Common.Init();
|
||||
Core.Helper.WndProcCounter++;
|
||||
|
||||
var formScreen = new FrmScreen();
|
||||
@@ -314,7 +314,7 @@ namespace MouseWithoutBorders.Class
|
||||
MachineStuff.UpdateMachinePoolStringSetting();
|
||||
|
||||
SocketStuff.InvalidKeyFound = false;
|
||||
InitAndCleanup.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSockets(true);
|
||||
MachineStuff.SendMachineMatrix();
|
||||
|
||||
@@ -340,7 +340,7 @@ namespace MouseWithoutBorders.Class
|
||||
public void Reconnect()
|
||||
{
|
||||
SocketStuff.InvalidKeyFound = false;
|
||||
InitAndCleanup.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSockets(true);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
@@ -397,7 +397,7 @@ namespace MouseWithoutBorders.Class
|
||||
using var asyncFlowControl = ExecutionContext.SuppressFlow();
|
||||
|
||||
Common.InputCallbackThreadID = Thread.CurrentThread.ManagedThreadId;
|
||||
while (!InitAndCleanup.InitDone)
|
||||
while (!Common.InitDone)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace MouseWithoutBorders.Class
|
||||
if (shouldReopenSockets)
|
||||
{
|
||||
SocketStuff.InvalidKeyFound = false;
|
||||
InitAndCleanup.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSockets(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ using MouseWithoutBorders.Core;
|
||||
// </history>
|
||||
using MouseWithoutBorders.Exceptions;
|
||||
|
||||
using Clipboard = MouseWithoutBorders.Core.Clipboard;
|
||||
using Thread = MouseWithoutBorders.Core.Thread;
|
||||
|
||||
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendData(System.Byte[])", Justification = "Dotnet port with style preservation")]
|
||||
@@ -282,7 +281,7 @@ namespace MouseWithoutBorders.Class
|
||||
* */
|
||||
|
||||
Common.GetMachineName(); // IPs might have been changed
|
||||
InitAndCleanup.UpdateMachineTimeAndID();
|
||||
Common.UpdateMachineTimeAndID();
|
||||
|
||||
Logger.LogDebug("Creating sockets...");
|
||||
|
||||
@@ -309,7 +308,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
Logger.TelemetryLogTrace("Restarting the service dues to WSAEADDRINUSE.", SeverityLevel.Warning);
|
||||
Program.StartService();
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_WSAECONNRESET;
|
||||
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1249,7 +1248,7 @@ namespace MouseWithoutBorders.Class
|
||||
// WSAECONNRESET
|
||||
if (e is ExpectedSocketException se && se.ShouldReconnect)
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_WSAECONNRESET;
|
||||
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
|
||||
Logger.Log($"MainTCPRoutine: {nameof(FlagReopenSocketIfNeeded)}");
|
||||
}
|
||||
}
|
||||
@@ -1307,7 +1306,7 @@ namespace MouseWithoutBorders.Class
|
||||
}
|
||||
catch (ObjectDisposedException e)
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_WSAECONNRESET;
|
||||
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
|
||||
UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);
|
||||
currentSocket.Close();
|
||||
Logger.Log($"{nameof(MainTCPRoutine)}: The socket could have been closed/disposed by other threads: {e.Message}");
|
||||
@@ -1354,10 +1353,10 @@ namespace MouseWithoutBorders.Class
|
||||
* In this case, we should give ONE try to reconnect.
|
||||
*/
|
||||
|
||||
if (InitAndCleanup.ReopenSocketDueToReadError)
|
||||
if (Common.ReopenSocketDueToReadError)
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_WSAECONNRESET;
|
||||
InitAndCleanup.ReopenSocketDueToReadError = false;
|
||||
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
|
||||
Common.ReopenSocketDueToReadError = false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1642,7 +1641,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
bool clientPushData = true;
|
||||
ClipboardPostAction postAction = ClipboardPostAction.Other;
|
||||
bool handShaken = Clipboard.ShakeHand(ref remoteEndPoint, s, out Stream enStream, out Stream deStream, ref clientPushData, ref postAction);
|
||||
bool handShaken = Common.ShakeHand(ref remoteEndPoint, s, out Stream enStream, out Stream deStream, ref clientPushData, ref postAction);
|
||||
|
||||
if (!handShaken)
|
||||
{
|
||||
@@ -1657,7 +1656,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
if (clientPushData)
|
||||
{
|
||||
Clipboard.ReceiveAndProcessClipboardData(remoteEndPoint, s, enStream, deStream, $"{postAction}");
|
||||
Common.ReceiveAndProcessClipboardData(remoteEndPoint, s, enStream, deStream, $"{postAction}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1681,23 +1680,23 @@ namespace MouseWithoutBorders.Class
|
||||
const int CLOSE_TIMEOUT = 10;
|
||||
byte[] header = new byte[1024];
|
||||
string headerString = string.Empty;
|
||||
if (Clipboard.LastDragDropFile != null)
|
||||
if (Common.LastDragDropFile != null)
|
||||
{
|
||||
string fileName = null;
|
||||
|
||||
if (!Launch.ImpersonateLoggedOnUserAndDoSomething(() =>
|
||||
{
|
||||
if (!File.Exists(Clipboard.LastDragDropFile))
|
||||
if (!File.Exists(Common.LastDragDropFile))
|
||||
{
|
||||
headerString = Directory.Exists(Clipboard.LastDragDropFile)
|
||||
? $"{0}*{Clipboard.LastDragDropFile} - Folder is not supported, zip it first!"
|
||||
: Clipboard.LastDragDropFile.Contains("- File too big")
|
||||
? $"{0}*{Clipboard.LastDragDropFile}"
|
||||
: $"{0}*{Clipboard.LastDragDropFile} not found!";
|
||||
headerString = Directory.Exists(Common.LastDragDropFile)
|
||||
? $"{0}*{Common.LastDragDropFile} - Folder is not supported, zip it first!"
|
||||
: Common.LastDragDropFile.Contains("- File too big")
|
||||
? $"{0}*{Common.LastDragDropFile}"
|
||||
: $"{0}*{Common.LastDragDropFile} not found!";
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = Clipboard.LastDragDropFile;
|
||||
fileName = Common.LastDragDropFile;
|
||||
headerString = $"{new FileInfo(fileName).Length}*{fileName}";
|
||||
}
|
||||
}))
|
||||
@@ -1740,11 +1739,11 @@ namespace MouseWithoutBorders.Class
|
||||
Logger.Log(log);
|
||||
}
|
||||
}
|
||||
else if (!Clipboard.IsClipboardDataImage && Clipboard.LastClipboardData != null)
|
||||
else if (!Common.IsClipboardDataImage && Common.LastClipboardData != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] data = Clipboard.LastClipboardData;
|
||||
byte[] data = Common.LastClipboardData;
|
||||
|
||||
headerString = $"{data.Length}*{"text"}";
|
||||
Common.GetBytesU(headerString).CopyTo(header, 0);
|
||||
@@ -1774,9 +1773,9 @@ namespace MouseWithoutBorders.Class
|
||||
Logger.Log(log);
|
||||
}
|
||||
}
|
||||
else if (Clipboard.LastClipboardData != null && Clipboard.LastClipboardData.Length > 0)
|
||||
else if (Common.LastClipboardData != null && Common.LastClipboardData.Length > 0)
|
||||
{
|
||||
byte[] data = Clipboard.LastClipboardData;
|
||||
byte[] data = Common.LastClipboardData;
|
||||
|
||||
headerString = $"{data.Length}*{"image"}";
|
||||
Common.GetBytesU(headerString).CopyTo(header, 0);
|
||||
@@ -1985,8 +1984,8 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
tcp = null;
|
||||
Setting.Values.MachineId = Common.Ran.Next();
|
||||
InitAndCleanup.UpdateMachineTimeAndID();
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_HOTKEY;
|
||||
Common.UpdateMachineTimeAndID();
|
||||
Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;
|
||||
|
||||
Logger.TelemetryLogTrace("MachineID conflict.", SeverityLevel.Information);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ internal static class DragDrop
|
||||
if (wParam == Common.WM_RBUTTONUP && IsDropping)
|
||||
{
|
||||
IsDropping = false;
|
||||
Clipboard.LastIDWithClipboardData = ID.NONE;
|
||||
Common.LastIDWithClipboardData = ID.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ internal static class DragDrop
|
||||
{
|
||||
if (!string.IsNullOrEmpty(dragFileName) && (File.Exists(dragFileName) || Directory.Exists(dragFileName)))
|
||||
{
|
||||
Clipboard.LastDragDropFile = dragFileName;
|
||||
Common.LastDragDropFile = dragFileName;
|
||||
/*
|
||||
* possibleDropMachineID is used as desID sent in DragDropStep06();
|
||||
* */
|
||||
@@ -270,7 +270,7 @@ internal static class DragDrop
|
||||
else
|
||||
{
|
||||
IsDragging = false;
|
||||
Clipboard.LastIDWithClipboardData = ID.NONE;
|
||||
Common.LastIDWithClipboardData = ID.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ internal static class DragDrop
|
||||
Logger.LogDebug("DragDropStep10: Hide the form and get data...");
|
||||
IsDropping = false;
|
||||
IsDragging = false;
|
||||
Clipboard.LastIDWithClipboardData = ID.NONE;
|
||||
Common.LastIDWithClipboardData = ID.NONE;
|
||||
|
||||
Common.DoSomethingInUIThread(() =>
|
||||
{
|
||||
@@ -288,7 +288,7 @@ internal static class DragDrop
|
||||
});
|
||||
|
||||
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersDragAndDropEvent());
|
||||
Clipboard.GetRemoteClipboard("desktop");
|
||||
Common.GetRemoteClipboard("desktop");
|
||||
}
|
||||
|
||||
internal static void DragDropStep11()
|
||||
@@ -298,8 +298,8 @@ internal static class DragDrop
|
||||
IsDropping = false;
|
||||
IsDragging = false;
|
||||
DragMachine = (ID)1;
|
||||
Clipboard.LastIDWithClipboardData = ID.NONE;
|
||||
Clipboard.LastDragDropFile = null;
|
||||
Common.LastIDWithClipboardData = ID.NONE;
|
||||
Common.LastDragDropFile = null;
|
||||
MouseDown = false;
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ internal static class DragDrop
|
||||
{
|
||||
Logger.LogDebug("DragDropStep12: ClipboardDragDropEnd received");
|
||||
IsDropping = false;
|
||||
Clipboard.LastIDWithClipboardData = ID.NONE;
|
||||
Common.LastIDWithClipboardData = ID.NONE;
|
||||
|
||||
Common.DoSomethingInUIThread(() =>
|
||||
{
|
||||
|
||||
@@ -78,7 +78,7 @@ internal static class Event
|
||||
// if they are, check that there is no application running in fullscreen mode before switching.
|
||||
if (!p.IsEmpty && Common.IsEasyMouseSwitchAllowed())
|
||||
{
|
||||
Clipboard.HasSwitchedMachineSinceLastCopy = true;
|
||||
Common.HasSwitchedMachineSinceLastCopy = true;
|
||||
|
||||
Logger.LogDebug(string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
@@ -218,10 +218,10 @@ internal static class Event
|
||||
|
||||
if (MachineStuff.desMachineID == Common.MachineID)
|
||||
{
|
||||
if (Common.GetTick() - Clipboard.clipboardCopiedTime < Clipboard.BIG_CLIPBOARD_DATA_TIMEOUT)
|
||||
if (Common.GetTick() - Common.clipboardCopiedTime < Common.BIG_CLIPBOARD_DATA_TIMEOUT)
|
||||
{
|
||||
Clipboard.clipboardCopiedTime = 0;
|
||||
Clipboard.GetRemoteClipboard("PrepareToSwitchToMachine");
|
||||
Common.clipboardCopiedTime = 0;
|
||||
Common.GetRemoteClipboard("PrepareToSwitchToMachine");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -119,7 +119,7 @@ internal static class Helper
|
||||
|
||||
if (MachineStuff.NewDesMachineID == Common.MachineID)
|
||||
{
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ internal static class Helper
|
||||
Common.GetInputDesktop(),
|
||||
0);
|
||||
|
||||
Clipboard.HasSwitchedMachineSinceLastCopy = true;
|
||||
Common.HasSwitchedMachineSinceLastCopy = true;
|
||||
|
||||
// Common.CreateLowIntegrityProcess("\"" + Path.GetDirectoryName(Application.ExecutablePath) + "\\MouseWithoutBordersHelper.exe\"", string.Empty, 0, false, 0);
|
||||
var processes = Process.GetProcessesByName(HelperProcessName);
|
||||
|
||||
@@ -1,278 +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.Globalization;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
|
||||
using Microsoft.Win32;
|
||||
using MouseWithoutBorders.Class;
|
||||
using Windows.UI.Input.Preview.Injection;
|
||||
|
||||
// <summary>
|
||||
// Initialization and clean up.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal static class InitAndCleanup
|
||||
{
|
||||
private static bool initDone;
|
||||
internal static int REOPEN_WHEN_WSAECONNRESET = -10054;
|
||||
internal static int REOPEN_WHEN_HOTKEY = -10055;
|
||||
internal static int PleaseReopenSocket;
|
||||
internal static bool ReopenSocketDueToReadError;
|
||||
|
||||
private static DateTime LastResumeSuspendTime { get; set; } = DateTime.UtcNow;
|
||||
|
||||
internal static bool InitDone
|
||||
{
|
||||
get => InitAndCleanup.initDone;
|
||||
set => InitAndCleanup.initDone = value;
|
||||
}
|
||||
|
||||
internal static void UpdateMachineTimeAndID()
|
||||
{
|
||||
Common.MachineName = Common.MachineName.Trim();
|
||||
_ = MachineStuff.MachinePool.TryUpdateMachineID(Common.MachineName, Common.MachineID, true);
|
||||
}
|
||||
|
||||
private static void InitializeMachinePoolFromSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
MachineInf[] info = MachinePoolHelpers.LoadMachineInfoFromMachinePoolStringSetting(Setting.Values.MachinePoolString);
|
||||
for (int i = 0; i < info.Length; i++)
|
||||
{
|
||||
info[i].Name = info[i].Name.Trim();
|
||||
}
|
||||
|
||||
MachineStuff.MachinePool.Initialize(info);
|
||||
MachineStuff.MachinePool.ResetIPAddressesForDeadMachines(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log(ex);
|
||||
MachineStuff.MachinePool.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupMachineNameAndID()
|
||||
{
|
||||
try
|
||||
{
|
||||
Common.GetMachineName();
|
||||
Common.DesMachineID = MachineStuff.NewDesMachineID = Common.MachineID;
|
||||
|
||||
// MessageBox.Show(machineID.ToString(CultureInfo.CurrentCulture)); // For test
|
||||
InitializeMachinePoolFromSettings();
|
||||
|
||||
Common.MachineName = Common.MachineName.Trim();
|
||||
_ = MachineStuff.MachinePool.LearnMachine(Common.MachineName);
|
||||
_ = MachineStuff.MachinePool.TryUpdateMachineID(Common.MachineName, Common.MachineID, true);
|
||||
|
||||
MachineStuff.UpdateMachinePoolStringSetting();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
_ = Helper.GetUserName();
|
||||
Common.GeneratedKey = true;
|
||||
|
||||
try
|
||||
{
|
||||
Common.MyKey = Setting.Values.MyKey;
|
||||
int tmp = Setting.Values.MyKeyDaysToExpire;
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
Common.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
Common.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
InputSimulation.Injector = InputInjector.TryCreate();
|
||||
if (InputSimulation.Injector != null)
|
||||
{
|
||||
InputSimulation.MoveMouseRelative(0, 0);
|
||||
NativeMethods.InjectMouseInputAvailable = true;
|
||||
}
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
NativeMethods.InjectMouseInputAvailable = false;
|
||||
Logger.Log($"{nameof(NativeMethods.InjectMouseInputAvailable)} = false");
|
||||
}
|
||||
|
||||
bool dummy = Setting.Values.DrawMouseEx;
|
||||
Common.Is64bitOS = IntPtr.Size == 8;
|
||||
Common.tcpPort = Setting.Values.TcpPort;
|
||||
Common.GetScreenConfig();
|
||||
Common.PackageSent = new PackageMonitor(0);
|
||||
Common.PackageReceived = new PackageMonitor(0);
|
||||
SetupMachineNameAndID();
|
||||
Common.InitEncryption();
|
||||
CreateHelperThreads();
|
||||
|
||||
SystemEvents.DisplaySettingsChanged += new EventHandler(Common.SystemEvents_DisplaySettingsChanged);
|
||||
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
|
||||
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
|
||||
PleaseReopenSocket = 9;
|
||||
/* TODO: Telemetry for the matrix? */
|
||||
}
|
||||
|
||||
private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||||
{
|
||||
Helper.WndProcCounter++;
|
||||
|
||||
if (e.Mode is PowerModes.Resume or PowerModes.Suspend)
|
||||
{
|
||||
Logger.TelemetryLogTrace($"{nameof(SystemEvents_PowerModeChanged)}: {e.Mode}", SeverityLevel.Information);
|
||||
LastResumeSuspendTime = DateTime.UtcNow;
|
||||
MachineStuff.SwitchToMultipleMode(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateHelperThreads()
|
||||
{
|
||||
// NOTE(@yuyoyuppe): service crashes while trying to obtain this info, disabling.
|
||||
/*
|
||||
Thread watchDogThread = new(new ThreadStart(WatchDogThread), nameof(WatchDogThread));
|
||||
watchDogThread.Priority = ThreadPriority.Highest;
|
||||
watchDogThread.Start();
|
||||
*/
|
||||
|
||||
Common.helper = new Thread(new ThreadStart(Helper.HelperThread), "Helper Thread");
|
||||
Common.helper.SetApartmentState(ApartmentState.STA);
|
||||
Common.helper.Start();
|
||||
}
|
||||
|
||||
private static void AskHelperThreadsToExit(int waitTime)
|
||||
{
|
||||
Helper.signalHelperToExit = true;
|
||||
Helper.signalWatchDogToExit = true;
|
||||
_ = Common.EvSwitch.Set();
|
||||
|
||||
int c = 0;
|
||||
if (Common.helper != null && c < waitTime)
|
||||
{
|
||||
while (Helper.signalHelperToExit)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
Common.helper = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
Common.SendByeBye();
|
||||
|
||||
// UnhookClipboard();
|
||||
AskHelperThreadsToExit(500);
|
||||
Common.MainForm.NotifyIcon.Visible = false;
|
||||
Common.MainForm.NotifyIcon.Dispose();
|
||||
Common.CloseAllFormsAndHooks();
|
||||
|
||||
Common.DoSomethingInUIThread(() =>
|
||||
{
|
||||
Common.Sk?.Close(true);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static long lastReleaseAllKeysCall;
|
||||
|
||||
internal static void ReleaseAllKeys()
|
||||
{
|
||||
if (Math.Abs(Common.GetTick() - lastReleaseAllKeysCall) < 2000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastReleaseAllKeysCall = Common.GetTick();
|
||||
|
||||
KEYBDDATA kd;
|
||||
kd.dwFlags = (int)Common.LLKHF.UP;
|
||||
|
||||
VK[] keys = new VK[]
|
||||
{
|
||||
VK.LSHIFT, VK.LCONTROL, VK.LMENU, VK.LWIN, VK.RSHIFT,
|
||||
VK.RCONTROL, VK.RMENU, VK.RWIN, VK.SHIFT, VK.MENU, VK.CONTROL,
|
||||
};
|
||||
|
||||
Logger.LogDebug("***** ReleaseAllKeys has been called! *****:");
|
||||
|
||||
foreach (VK vk in keys)
|
||||
{
|
||||
if ((NativeMethods.GetAsyncKeyState((IntPtr)vk) & 0x8000) != 0)
|
||||
{
|
||||
Logger.LogDebug(vk.ToString() + " is down, release it...");
|
||||
Common.Hook?.ResetLastSwitchKeys(); // Sticky key can turn ALL PC mode on (CtrlCtrlCtrl)
|
||||
kd.wVk = (int)vk;
|
||||
InputSimulation.SendKey(kd);
|
||||
Common.Hook?.ResetLastSwitchKeys();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
|
||||
{
|
||||
Logger.LogDebug("NetworkAvailabilityEventArgs.IsAvailable: " + e.IsAvailable.ToString(CultureInfo.InvariantCulture));
|
||||
Helper.WndProcCounter++;
|
||||
ScheduleReopenSocketsDueToNetworkChanges(!e.IsAvailable);
|
||||
}
|
||||
|
||||
private static void ScheduleReopenSocketsDueToNetworkChanges(bool closeSockets = true)
|
||||
{
|
||||
if (closeSockets)
|
||||
{
|
||||
// Slept/hibernated machine may still have the sockets' status as Connected:( (unchanged) so it would not re-connect after a timeout when waking up.
|
||||
// Closing the sockets when it is going to sleep/hibernate will trigger the reconnection faster when it wakes up.
|
||||
Common.DoSomethingInUIThread(
|
||||
() =>
|
||||
{
|
||||
SocketStuff s = Common.Sk;
|
||||
Common.Sk = null;
|
||||
s?.Close(false);
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
if (!Common.IsMyDesktopActive())
|
||||
{
|
||||
PleaseReopenSocket = 0;
|
||||
}
|
||||
else if (PleaseReopenSocket != 10)
|
||||
{
|
||||
PleaseReopenSocket = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,24 +247,22 @@ internal static class Logger
|
||||
|
||||
internal static void DumpStaticTypes(StringBuilder sb, int level)
|
||||
{
|
||||
var staticTypes = new List<Type>
|
||||
{
|
||||
typeof(Clipboard),
|
||||
typeof(DragDrop),
|
||||
typeof(Event),
|
||||
typeof(InitAndCleanup),
|
||||
typeof(Helper),
|
||||
typeof(Launch),
|
||||
typeof(Logger),
|
||||
typeof(MachineStuff),
|
||||
typeof(Receiver),
|
||||
typeof(Service),
|
||||
};
|
||||
foreach (var staticType in staticTypes)
|
||||
{
|
||||
sb.AppendLine(CultureInfo.InvariantCulture, $"[{staticType.Name}]\r\n===============");
|
||||
Logger.DumpType(sb, staticType, 0, level);
|
||||
}
|
||||
sb.AppendLine($"[{nameof(DragDrop)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(DragDrop), 0, level);
|
||||
sb.AppendLine($"[{nameof(Event)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(Event), 0, level);
|
||||
sb.AppendLine($"[{nameof(Helper)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(Helper), 0, level);
|
||||
sb.AppendLine($"[{nameof(Launch)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(Launch), 0, level);
|
||||
sb.AppendLine($"[{nameof(Logger)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(Logger), 0, level);
|
||||
sb.AppendLine($"[{nameof(MachineStuff)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(MachineStuff), 0, level);
|
||||
sb.AppendLine($"[{nameof(Receiver)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(Receiver), 0, level);
|
||||
sb.AppendLine($"[{nameof(Service)}]\r\n===============");
|
||||
Logger.DumpType(sb, typeof(Service), 0, level);
|
||||
}
|
||||
|
||||
internal static bool PrivateDump(StringBuilder sb, object obj, string objName, int level, int maxLevel, bool stop)
|
||||
|
||||
@@ -992,7 +992,7 @@ internal static class MachineStuff
|
||||
Setting.Values.MatrixOneRow = !((package.Type & PackageType.MatrixTwoRowFlag) == PackageType.MatrixTwoRowFlag);
|
||||
MachineMatrix = MachineMatrix; // Save
|
||||
|
||||
InitAndCleanup.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSocketDueToReadError = true;
|
||||
|
||||
UpdateClientSockets("UpdateMachineMatrix");
|
||||
|
||||
@@ -1044,7 +1044,7 @@ internal static class MachineStuff
|
||||
Common.MoveMouseToCenter();
|
||||
}
|
||||
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
|
||||
Common.UpdateMultipleModeIconAndMenu();
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ internal static class Receiver
|
||||
|
||||
if (!p.IsEmpty)
|
||||
{
|
||||
Clipboard.HasSwitchedMachineSinceLastCopy = true;
|
||||
Common.HasSwitchedMachineSinceLastCopy = true;
|
||||
|
||||
Logger.LogDebug(string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
@@ -274,7 +274,7 @@ internal static class Receiver
|
||||
Common.PackageReceived.Clipboard++;
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
Clipboard.clipboardCopiedTime = Common.GetTick();
|
||||
Common.clipboardCopiedTime = Common.GetTick();
|
||||
GetNameOfMachineWithClipboardData(package);
|
||||
SignalBigClipboardData();
|
||||
}
|
||||
@@ -282,10 +282,10 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.MachineSwitched:
|
||||
if (Common.GetTick() - Clipboard.clipboardCopiedTime < Clipboard.BIG_CLIPBOARD_DATA_TIMEOUT && (package.Des == Common.MachineID))
|
||||
if (Common.GetTick() - Common.clipboardCopiedTime < Common.BIG_CLIPBOARD_DATA_TIMEOUT && (package.Des == Common.MachineID))
|
||||
{
|
||||
Clipboard.clipboardCopiedTime = 0;
|
||||
Clipboard.GetRemoteClipboard("PackageType.MachineSwitched");
|
||||
Common.clipboardCopiedTime = 0;
|
||||
Common.GetRemoteClipboard("PackageType.MachineSwitched");
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -297,7 +297,7 @@ internal static class Receiver
|
||||
if (package.Des == Common.MachineID || package.Des == ID.ALL)
|
||||
{
|
||||
GetNameOfMachineWithClipboardData(package);
|
||||
Clipboard.GetRemoteClipboard("mspaint," + Clipboard.LastMachineWithClipboardData);
|
||||
Common.GetRemoteClipboard("mspaint," + Common.LastMachineWithClipboardData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,10 +326,10 @@ internal static class Receiver
|
||||
Thread.UpdateThreads(thread);
|
||||
|
||||
string remoteMachine = package.MachineName;
|
||||
System.Net.Sockets.TcpClient client = Clipboard.ConnectToRemoteClipboardSocket(remoteMachine);
|
||||
System.Net.Sockets.TcpClient client = Common.ConnectToRemoteClipboardSocket(remoteMachine);
|
||||
bool clientPushData = true;
|
||||
|
||||
if (Clipboard.ShakeHand(ref remoteMachine, client.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref package.PostAction))
|
||||
if (Common.ShakeHand(ref remoteMachine, client.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref package.PostAction))
|
||||
{
|
||||
SocketStuff.SendClipboardData(client.Client, enStream);
|
||||
}
|
||||
@@ -360,7 +360,7 @@ internal static class Receiver
|
||||
|
||||
case PackageType.ClipboardText:
|
||||
case PackageType.ClipboardImage:
|
||||
Clipboard.clipboardCopiedTime = 0;
|
||||
Common.clipboardCopiedTime = 0;
|
||||
if (package.Type == PackageType.ClipboardImage)
|
||||
{
|
||||
Common.PackageReceived.ClipboardImage++;
|
||||
@@ -372,7 +372,7 @@ internal static class Receiver
|
||||
|
||||
if (tcp != null)
|
||||
{
|
||||
Clipboard.ReceiveClipboardDataUsingTCP(
|
||||
Common.ReceiveClipboardDataUsingTCP(
|
||||
package,
|
||||
package.Type == PackageType.ClipboardImage,
|
||||
tcp);
|
||||
@@ -381,10 +381,10 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.HideMouse:
|
||||
Clipboard.HasSwitchedMachineSinceLastCopy = true;
|
||||
Common.HasSwitchedMachineSinceLastCopy = true;
|
||||
Common.HideMouseCursor(true);
|
||||
Helper.MainFormDotEx(false);
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -405,11 +405,11 @@ internal static class Receiver
|
||||
|
||||
internal static void GetNameOfMachineWithClipboardData(DATA package)
|
||||
{
|
||||
Clipboard.LastIDWithClipboardData = package.Src;
|
||||
List<MachineInf> matchingMachines = MachineStuff.MachinePool.TryFindMachineByID(Clipboard.LastIDWithClipboardData);
|
||||
Common.LastIDWithClipboardData = package.Src;
|
||||
List<MachineInf> matchingMachines = MachineStuff.MachinePool.TryFindMachineByID(Common.LastIDWithClipboardData);
|
||||
if (matchingMachines.Count >= 1)
|
||||
{
|
||||
Clipboard.LastMachineWithClipboardData = matchingMachines[0].Name.Trim();
|
||||
Common.LastMachineWithClipboardData = matchingMachines[0].Name.Trim();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace MouseWithoutBorders
|
||||
if ((connectedClientSocket = Common.GetConnectedClientSocket()) != null)
|
||||
{
|
||||
ShowStatus($"Connected from local IP Address: {connectedClientSocket.Address}.");
|
||||
InitAndCleanup.UpdateMachineTimeAndID();
|
||||
Common.UpdateMachineTimeAndID();
|
||||
|
||||
Common.MMSleep(1);
|
||||
connected = true;
|
||||
|
||||
@@ -22,8 +22,6 @@ using Microsoft.PowerToys.Telemetry;
|
||||
// </history>
|
||||
using MouseWithoutBorders.Class;
|
||||
using MouseWithoutBorders.Core;
|
||||
|
||||
using Clipboard = MouseWithoutBorders.Core.Clipboard;
|
||||
using Timer = System.Windows.Forms.Timer;
|
||||
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonOK_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
|
||||
@@ -112,7 +110,7 @@ namespace MouseWithoutBorders
|
||||
{
|
||||
SocketStuff.InvalidKeyFound = false;
|
||||
showInvalidKeyMessage = false;
|
||||
InitAndCleanup.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSocketDueToReadError = true;
|
||||
Common.ReopenSockets(true);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
@@ -782,7 +780,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
ShowUpdateMessage();
|
||||
|
||||
Clipboard.HasSwitchedMachineSinceLastCopy = true;
|
||||
Common.HasSwitchedMachineSinceLastCopy = true;
|
||||
}
|
||||
|
||||
private void CheckBoxDisableCAD_CheckedChanged(object sender, EventArgs e)
|
||||
|
||||
@@ -139,13 +139,13 @@ namespace MouseWithoutBorders
|
||||
{
|
||||
if (cleanup)
|
||||
{
|
||||
InitAndCleanup.Cleanup();
|
||||
Common.Cleanup();
|
||||
}
|
||||
|
||||
Helper.WndProcCounter++;
|
||||
if (!Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
InitAndCleanup.ReleaseAllKeys();
|
||||
Common.ReleaseAllKeys();
|
||||
}
|
||||
|
||||
Helper.RunDDHelper(true);
|
||||
@@ -412,7 +412,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
count = 0;
|
||||
|
||||
InitAndCleanup.InitDone = true;
|
||||
Common.InitDone = true;
|
||||
#if SHOW_ON_WINLOGON
|
||||
if (Common.RunOnLogonDesktop)
|
||||
{
|
||||
@@ -423,39 +423,39 @@ namespace MouseWithoutBorders
|
||||
|
||||
if ((count % 2) == 0)
|
||||
{
|
||||
if (InitAndCleanup.PleaseReopenSocket == 10 || (InitAndCleanup.PleaseReopenSocket > 0 && count > 0 && count % 300 == 0))
|
||||
if (Common.PleaseReopenSocket == 10 || (Common.PleaseReopenSocket > 0 && count > 0 && count % 300 == 0))
|
||||
{
|
||||
if (!Common.AtLeastOneSocketEstablished() || InitAndCleanup.PleaseReopenSocket == 10)
|
||||
if (!Common.AtLeastOneSocketEstablished() || Common.PleaseReopenSocket == 10)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
if (InitAndCleanup.PleaseReopenSocket > 0)
|
||||
if (Common.PleaseReopenSocket > 0)
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket--;
|
||||
Common.PleaseReopenSocket--;
|
||||
}
|
||||
|
||||
// Double check.
|
||||
if (!Common.AtLeastOneSocketEstablished())
|
||||
{
|
||||
Common.GetMachineName();
|
||||
Logger.LogDebug("Common.pleaseReopenSocket: " + InitAndCleanup.PleaseReopenSocket.ToString(CultureInfo.InvariantCulture));
|
||||
Logger.LogDebug("Common.pleaseReopenSocket: " + Common.PleaseReopenSocket.ToString(CultureInfo.InvariantCulture));
|
||||
Common.ReopenSockets(false);
|
||||
MachineStuff.NewDesMachineID = Common.DesMachineID = Common.MachineID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket = 0;
|
||||
Common.PleaseReopenSocket = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (InitAndCleanup.PleaseReopenSocket == InitAndCleanup.REOPEN_WHEN_HOTKEY)
|
||||
if (Common.PleaseReopenSocket == Common.REOPEN_WHEN_HOTKEY)
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket = 0;
|
||||
Common.PleaseReopenSocket = 0;
|
||||
Common.ReopenSockets(true);
|
||||
}
|
||||
else if (InitAndCleanup.PleaseReopenSocket == InitAndCleanup.REOPEN_WHEN_WSAECONNRESET)
|
||||
else if (Common.PleaseReopenSocket == Common.REOPEN_WHEN_WSAECONNRESET)
|
||||
{
|
||||
InitAndCleanup.PleaseReopenSocket = 0;
|
||||
Common.PleaseReopenSocket = 0;
|
||||
Thread.Sleep(1000);
|
||||
MachineStuff.UpdateClientSockets("REOPEN_WHEN_WSAECONNRESET");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,28 @@
|
||||
[Other Logs]
|
||||
===============
|
||||
= MouseWithoutBorders.Common
|
||||
Comma = System.Char[]
|
||||
--System.Char[] = System.Char[]: N/A
|
||||
Star = System.Char[]
|
||||
--System.Char[] = System.Char[]: N/A
|
||||
NullSeparator = System.Char[]
|
||||
--System.Char[] = System.Char[]: N/A
|
||||
lastClipboardEventTime = 0
|
||||
clipboardCopiedTime = 0
|
||||
<LastIDWithClipboardData>k__BackingField = NONE
|
||||
<NextClipboardViewer>k__BackingField = 0
|
||||
<IsClipboardDataImage>k__BackingField = False
|
||||
lastClipboardObject =
|
||||
<HasSwitchedMachineSinceLastCopy>k__BackingField = False
|
||||
ClipboardThreadOldLock = Lock
|
||||
--_owningThreadId = 0
|
||||
--_state = 0
|
||||
--_recursionCount = 0
|
||||
--_spinCount = 22
|
||||
--_waiterStartTimeMs = 0
|
||||
--s_contentionCount = 0
|
||||
--s_maxSpinCount = 22
|
||||
--s_minSpinCountForAdaptiveSpin = -100
|
||||
screenWidth = 0
|
||||
screenHeight = 0
|
||||
lastX = 0
|
||||
@@ -77,6 +99,17 @@ LegalKeyDictionary = Concurrent.ConcurrentDictionary`2[System.String,System.Byte
|
||||
--_budget = ????????????
|
||||
--_growLockArray = True
|
||||
--_comparerIsDefaultForClasses = False
|
||||
initDone = False
|
||||
REOPEN_WHEN_WSAECONNRESET = -10054
|
||||
REOPEN_WHEN_HOTKEY = -10055
|
||||
PleaseReopenSocket = 0
|
||||
ReopenSocketDueToReadError = False
|
||||
<LastResumeSuspendTime>k__BackingField = ????????????
|
||||
--_dateData = ????????????
|
||||
--MinValue = 01/01/0001 00:00:00
|
||||
--MaxValue = 31/12/9999 23:59:59
|
||||
--UnixEpoch = 01/01/1970 00:00:00
|
||||
lastReleaseAllKeysCall = 0
|
||||
PackageSent = MouseWithoutBorders.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
@@ -120,6 +153,12 @@ p = {X=0,Y=0}
|
||||
--y = 0
|
||||
--Empty = {X=0,Y=0}
|
||||
<IpcChannelCreated>k__BackingField = False
|
||||
BIG_CLIPBOARD_DATA_TIMEOUT = 30000
|
||||
MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP = 1048576
|
||||
MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT = 104857600
|
||||
TEXT_HEADER_SIZE = 12
|
||||
DATA_SIZE = 48
|
||||
TEXT_TYPE_SEP = {4CFF57F7-BEDD-43d5-AE8F-27A61E886F2F}
|
||||
TOGGLE_ICONS_SIZE = 4
|
||||
ICON_ONE = 0
|
||||
ICON_ALL = 1
|
||||
@@ -156,36 +195,6 @@ WM_KEYDOWN = 256
|
||||
WM_KEYUP = 257
|
||||
WM_SYSKEYDOWN = 260
|
||||
WM_SYSKEYUP = 261
|
||||
[Clipboard]
|
||||
===============
|
||||
Comma = System.Char[]
|
||||
--System.Char[] = System.Char[]: N/A
|
||||
Star = System.Char[]
|
||||
--System.Char[] = System.Char[]: N/A
|
||||
NullSeparator = System.Char[]
|
||||
--System.Char[] = System.Char[]: N/A
|
||||
lastClipboardEventTime = 0
|
||||
clipboardCopiedTime = 0
|
||||
<LastIDWithClipboardData>k__BackingField = NONE
|
||||
<NextClipboardViewer>k__BackingField = 0
|
||||
<IsClipboardDataImage>k__BackingField = False
|
||||
lastClipboardObject =
|
||||
<HasSwitchedMachineSinceLastCopy>k__BackingField = False
|
||||
ClipboardThreadOldLock = Lock
|
||||
--_owningThreadId = 0
|
||||
--_state = 0
|
||||
--_recursionCount = 0
|
||||
--_spinCount = 22
|
||||
--_waiterStartTimeMs = 0
|
||||
--s_contentionCount = 0
|
||||
--s_maxSpinCount = 22
|
||||
--s_minSpinCountForAdaptiveSpin = -100
|
||||
BIG_CLIPBOARD_DATA_TIMEOUT = 30000
|
||||
MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP = 1048576
|
||||
MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT = 104857600
|
||||
TEXT_HEADER_SIZE = 12
|
||||
DATA_SIZE = 48
|
||||
TEXT_TYPE_SEP = {4CFF57F7-BEDD-43d5-AE8F-27A61E886F2F}
|
||||
[DragDrop]
|
||||
===============
|
||||
isDragging = False
|
||||
@@ -240,19 +249,6 @@ actualLastPos = {X=0,Y=0}
|
||||
--Empty = {X=0,Y=0}
|
||||
myLastX = 0
|
||||
myLastY = 0
|
||||
[InitAndCleanup]
|
||||
===============
|
||||
initDone = False
|
||||
REOPEN_WHEN_WSAECONNRESET = -10054
|
||||
REOPEN_WHEN_HOTKEY = -10055
|
||||
PleaseReopenSocket = 0
|
||||
ReopenSocketDueToReadError = False
|
||||
<LastResumeSuspendTime>k__BackingField = ????????????
|
||||
--_dateData = ????????????
|
||||
--MinValue = 01/01/0001 00:00:00
|
||||
--MaxValue = 31/12/9999 23:59:59
|
||||
--UnixEpoch = 01/01/1970 00:00:00
|
||||
lastReleaseAllKeysCall = 0
|
||||
[Helper]
|
||||
===============
|
||||
signalHelperToExit = False
|
||||
|
||||
@@ -2,44 +2,28 @@
|
||||
# You can modify the rules from these initially generated values to suit your own policies.
|
||||
# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference.
|
||||
|
||||
##################################################
|
||||
# Global settings
|
||||
##################################################
|
||||
|
||||
[*.{cs,vb}]
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
file_header_template = Copyright (c) Microsoft Corporation\nThe Microsoft Corporation licenses this file to you under the MIT license.\nSee the LICENSE file in the project root for more information.
|
||||
|
||||
##################################################
|
||||
# C# specific formatting
|
||||
##################################################
|
||||
|
||||
[*.cs]
|
||||
# ----------------------------------------------
|
||||
# Core editorconfig formatting - indentation
|
||||
# ----------------------------------------------
|
||||
|
||||
file_header_template = Copyright (c) Microsoft Corporation\r\nThe Microsoft Corporation licenses this file to you under the MIT license.\r\nSee the LICENSE file in the project root for more information.
|
||||
|
||||
#Core editorconfig formatting - indentation
|
||||
|
||||
#use soft tabs (spaces) for indentation
|
||||
indent_style = space
|
||||
|
||||
#Formatting - new line options
|
||||
|
||||
#place else statements on a new line
|
||||
csharp_new_line_before_else = true
|
||||
#require braces to be on a new line for lambdas, methods, control_blocks, types, properties, and accessors (also known as "Allman" style)
|
||||
csharp_new_line_before_open_brace = all
|
||||
|
||||
# ----------------------------------------------
|
||||
# Formatting - organize using options
|
||||
# ----------------------------------------------
|
||||
#Formatting - organize using options
|
||||
|
||||
# sort System.* using directives alphabetically, and place them before other usings
|
||||
#sort System.* using directives alphabetically, and place them before other usings
|
||||
dotnet_sort_system_directives_first = true
|
||||
# Do not place System.* using directives before other using directives.
|
||||
dotnet_separate_import_directive_groups = false
|
||||
|
||||
# ----------------------------------------------
|
||||
# Formatting - spacing options
|
||||
# ----------------------------------------------
|
||||
#Formatting - spacing options
|
||||
|
||||
#require NO space between a cast and the value
|
||||
csharp_space_after_cast = false
|
||||
@@ -60,29 +44,17 @@ csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list.
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
|
||||
# ----------------------------------------------
|
||||
# Formatting - wrapping options
|
||||
# ----------------------------------------------
|
||||
#Formatting - wrapping options
|
||||
|
||||
#leave code block on separate lines
|
||||
csharp_preserve_single_line_blocks = true
|
||||
#put each statement on a separate line
|
||||
csharp_preserve_single_line_statements = false
|
||||
|
||||
##################################################
|
||||
# C# style rules
|
||||
##################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - Code block preferences
|
||||
# ----------------------------------------------
|
||||
#Style - Code block preferences
|
||||
|
||||
#prefer curly braces even for one line of code
|
||||
csharp_prefer_braces = true:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - expression bodied member options
|
||||
# ----------------------------------------------
|
||||
#Style - expression bodied member options
|
||||
|
||||
#prefer expression bodies for accessors
|
||||
csharp_style_expression_bodied_accessors = true:warning
|
||||
@@ -93,73 +65,55 @@ csharp_style_expression_bodied_methods = when_on_single_line:silent
|
||||
#prefer expression-bodied members for properties
|
||||
csharp_style_expression_bodied_properties = true:warning
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - expression level options
|
||||
# ----------------------------------------------
|
||||
#Style - expression level options
|
||||
|
||||
#prefer out variables to be declared before the method call
|
||||
csharp_style_inlined_variable_declaration = false:suggestion
|
||||
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - Expression-level preferences
|
||||
# ----------------------------------------------
|
||||
#Style - Expression-level preferences
|
||||
|
||||
#prefer default over default(T)
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
#prefer objects to be initialized using object initializers when possible
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - implicit and explicit types
|
||||
# ----------------------------------------------
|
||||
#Style - implicit and explicit types
|
||||
|
||||
#prefer var over explicit type in all cases, unless overridden by another code style rule
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
#prefer var is used to declare variables with built-in system types such as int
|
||||
csharp_style_var_for_built_in_types = true:warning
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
#prefer var when the type is already mentioned on the right-hand side of a declaration expression
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - language keyword and framework type options
|
||||
# ----------------------------------------------
|
||||
#Style - language keyword and framework type options
|
||||
|
||||
#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - Language rules
|
||||
# ----------------------------------------------
|
||||
|
||||
#Style - Language rules
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
|
||||
csharp_style_var_for_built_in_types = true:warning
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - modifier options
|
||||
# ----------------------------------------------
|
||||
#Style - modifier options
|
||||
|
||||
#prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods.
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - Modifier preferences
|
||||
# ----------------------------------------------
|
||||
#Style - Modifier preferences
|
||||
|
||||
#when this rule is set to a list of modifiers, prefer the specified ordering.
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,async,readonly,override,sealed,abstract,virtual:warning
|
||||
dotnet_style_readonly_field = true:warning
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - Pattern matching
|
||||
# ----------------------------------------------
|
||||
#Style - Pattern matching
|
||||
|
||||
#prefer pattern matching instead of is expression with type casts
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:warning
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - qualification options
|
||||
# ----------------------------------------------
|
||||
#Style - qualification options
|
||||
|
||||
#prefer events not to be prefaced with this. or Me. in Visual Basic
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
@@ -169,26 +123,20 @@ dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
#prefer properties not to be prefaced with this. or Me. in Visual Basic
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - expression bodies
|
||||
# ----------------------------------------------
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
csharp_prefer_simple_using_statement = true:warning
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
|
||||
# ----------------------------------------------
|
||||
# Style - Miscellaneous preferences
|
||||
# ----------------------------------------------
|
||||
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
csharp_prefer_simple_using_statement = true:warning
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
|
||||
[*.{cs,vb}]
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
@@ -198,13 +146,12 @@ dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
[*.{cs,vb}]
|
||||
|
||||
#Style - Unnecessary code rules
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:warning
|
||||
|
||||
##################################################
|
||||
# Naming rules
|
||||
##################################################
|
||||
|
||||
[*.{cs,vb}]
|
||||
#### Naming styles ####
|
||||
|
||||
# Naming rules
|
||||
|
||||
@@ -256,11 +203,7 @@ dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:warning
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
|
||||
# Diagnostic configuration
|
||||
|
||||
##################################################
|
||||
# Diagnostics
|
||||
##################################################
|
||||
|
||||
[*.{cs,vb}]
|
||||
# CS8305: Type is for evaluation purposes only and is subject to change or removal in future updates.
|
||||
dotnet_diagnostic.CS8305.severity = suggestion
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.183" />
|
||||
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.8.250907003" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.7.250513003" />
|
||||
<PackageVersion Include="Shmuelie.WinRTServer" Version="2.1.1" />
|
||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.8" />
|
||||
|
||||
@@ -94,4 +94,16 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Just mark it as AOT compatible. Do not publish with AOT now. We need fully test before we really publish it as AOT enabled-->
|
||||
<!--<PropertyGroup>
|
||||
<SelfContained>true</SelfContained>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
--><!-- <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> --><!--
|
||||
<PublishAot>true</PublishAot>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
</PropertyGroup>-->
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,20 +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 Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
public sealed partial class IconMarginConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
// Only include a margin if there is text to separate from the icon.
|
||||
var text = value as string;
|
||||
return string.IsNullOrEmpty(text) ? new Thickness(0) : new Thickness(0, 0, 4, 0);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException();
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labToolkit="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
x:Name="ShortcutContentControl"
|
||||
mc:Ignorable="d">
|
||||
<Grid MinWidth="498" MinHeight="220">
|
||||
@@ -66,7 +66,7 @@
|
||||
IsTabStop="{Binding ElementName=ShortcutContentControl, Path=IsWarningAltGr, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</Grid>
|
||||
<labToolkit:MarkdownTextBlock
|
||||
<tkcontrols:MarkdownTextBlock
|
||||
x:Uid="InvalidShortcutWarningLabel"
|
||||
Background="Transparent"
|
||||
FontSize="12"
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labToolkit="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
mc:Ignorable="d">
|
||||
@@ -36,7 +36,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<labToolkit:MarkdownTextBlock
|
||||
<tkcontrols:MarkdownTextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
<Thickness x:Key="TagPadding">4,2,4,2</Thickness>
|
||||
<Thickness x:Key="TagBorderThickness">1</Thickness>
|
||||
|
||||
<local:IconMarginConverter x:Key="IconMarginConverter" />
|
||||
|
||||
<Style BasedOn="{StaticResource DefaultTagStyle}" TargetType="local:Tag" />
|
||||
|
||||
<Style x:Key="DefaultTagStyle" TargetType="local:Tag">
|
||||
@@ -73,7 +71,7 @@
|
||||
x:Name="PART_Icon"
|
||||
Grid.Column="0"
|
||||
Height="12"
|
||||
Margin="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource IconMarginConverter}}"
|
||||
Margin="0,0,4,0"
|
||||
SourceKey="{TemplateBinding Icon}" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
|
||||
@@ -11,22 +11,20 @@
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labToolkit="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock"
|
||||
xmlns:local="using:Microsoft.CmdPal.UI"
|
||||
xmlns:markdownTextBlockRns="using:CommunityToolkit.WinUI.Controls.MarkdownTextBlockRns"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<markdownTextBlockRns:MarkdownThemes
|
||||
<tkcontrols:MarkdownThemes
|
||||
x:Key="DefaultMarkdownThemeConfig"
|
||||
H3FontSize="12"
|
||||
H3FontWeight="Normal" />
|
||||
<labToolkit:MarkdownConfig x:Key="DefaultMarkdownConfig" Themes="{StaticResource DefaultMarkdownThemeConfig}" />
|
||||
<tkcontrols:MarkdownConfig x:Key="DefaultMarkdownConfig" Themes="{StaticResource DefaultMarkdownThemeConfig}" />
|
||||
|
||||
<StackLayout
|
||||
x:Name="VerticalStackLayout"
|
||||
@@ -52,10 +50,7 @@
|
||||
|
||||
<DataTemplate x:Key="MarkdownContentTemplate" x:DataType="viewModels:ContentMarkdownViewModel">
|
||||
<Grid Margin="0,4,4,4" Padding="12,8,8,8">
|
||||
<labToolkit:MarkdownTextBlock
|
||||
Background="Transparent"
|
||||
Config="{StaticResource DefaultMarkdownConfig}"
|
||||
Text="{x:Bind Body, Mode=OneWay}" />
|
||||
<tkcontrols:MarkdownTextBlock Config="{StaticResource DefaultMarkdownConfig}" Text="{x:Bind Body, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -67,10 +62,7 @@
|
||||
|
||||
<DataTemplate x:Key="NestedMarkdownContentTemplate" x:DataType="viewModels:ContentMarkdownViewModel">
|
||||
<Grid>
|
||||
<labToolkit:MarkdownTextBlock
|
||||
Background="Transparent"
|
||||
Config="{StaticResource DefaultMarkdownConfig}"
|
||||
Text="{x:Bind Body, Mode=OneWay}" />
|
||||
<tkcontrols:MarkdownTextBlock Config="{StaticResource DefaultMarkdownConfig}" Text="{x:Bind Body, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
|
||||
<PropertyGroup Condition="'$(CIBuild)'=='true'">
|
||||
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
<AppxPackageTestDir>$(OutputPath)\AppPackages\Microsoft.CmdPal.UI_$(Version)_Test\</AppxPackageTestDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:help="using:Microsoft.CmdPal.UI.Helpers"
|
||||
xmlns:labToolkit="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock"
|
||||
xmlns:markdownTextBlockRns="using:CommunityToolkit.WinUI.Controls.MarkdownTextBlockRns"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
||||
@@ -147,11 +146,11 @@
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
<markdownTextBlockRns:MarkdownThemes
|
||||
<tkcontrols:MarkdownThemes
|
||||
x:Key="DefaultMarkdownThemeConfig"
|
||||
H3FontSize="12"
|
||||
H3FontWeight="Normal" />
|
||||
<labToolkit:MarkdownConfig x:Key="DefaultMarkdownConfig" Themes="{StaticResource DefaultMarkdownThemeConfig}" />
|
||||
<tkcontrols:MarkdownConfig x:Key="DefaultMarkdownConfig" Themes="{StaticResource DefaultMarkdownThemeConfig}" />
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
@@ -422,7 +421,7 @@
|
||||
TextWrapping="WrapWholeWords"
|
||||
Visibility="{x:Bind ViewModel.Details.Title, Converter={StaticResource StringNotEmptyToVisibilityConverter}, Mode=OneWay}" />
|
||||
|
||||
<labToolkit:MarkdownTextBlock
|
||||
<tkcontrols:MarkdownTextBlock
|
||||
Grid.Row="2"
|
||||
Margin="0,4,0,24"
|
||||
Background="Transparent"
|
||||
|
||||
@@ -3,15 +3,9 @@
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup>
|
||||
<PathToRoot>..\..\..\..\</PathToRoot>
|
||||
<WasdkNuget>$(PathToRoot)packages\Microsoft.WindowsAppSDK.1.8.250907003</WasdkNuget>
|
||||
<WasdkNuget>$(PathToRoot)packages\Microsoft.WindowsAppSDK.1.7.250513003</WasdkNuget>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
@@ -206,12 +200,6 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(MSBuildThisFileDirectory)..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
@@ -222,18 +210,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', 'Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
|
||||
@@ -4,14 +4,4 @@
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.2903.40" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Base" version="1.8.250831001" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Foundation" version="1.8.250906002" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.WinUI" version="1.8.250906003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Runtime" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.DWrite" version="1.8.25090401" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.InteractiveExperiences" version="1.8.250906004" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Widgets" version="1.8.250904007" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.AI" version="1.8.37" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools.MSIX" version="1.7.20250829.1" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08535 3C7.29127 2.4174 7.84689 2 8.5 2H11.5C12.1531 2 12.7087 2.4174 12.9146 3H14.5C15.3284 3 16 3.67157 16 4.5V16.5C16 17.3284 15.3284 18 14.5 18H5.5C4.67157 18 4 17.3284 4 16.5V4.5C4 3.67157 4.67157 3 5.5 3H7.08535ZM8.5 3C8.22386 3 8 3.22386 8 3.5C8 3.77614 8.22386 4 8.5 4H11.5C11.7761 4 12 3.77614 12 3.5C12 3.22386 11.7761 3 11.5 3H8.5ZM7.08535 4H5.5C5.22386 4 5 4.22386 5 4.5V16.5C5 16.7761 5.22386 17 5.5 17H14.5C14.7761 17 15 16.7761 15 16.5V4.5C15 4.22386 14.7761 4 14.5 4H12.9146C12.7087 4.5826 12.1531 5 11.5 5H8.5C7.84689 5 7.29127 4.5826 7.08535 4Z" fill="#D0D0D0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 695 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08535 3C7.29127 2.4174 7.84689 2 8.5 2H11.5C12.1531 2 12.7087 2.4174 12.9146 3H14.5C15.3284 3 16 3.67157 16 4.5V16.5C16 17.3284 15.3284 18 14.5 18H5.5C4.67157 18 4 17.3284 4 16.5V4.5C4 3.67157 4.67157 3 5.5 3H7.08535ZM8.5 3C8.22386 3 8 3.22386 8 3.5C8 3.77614 8.22386 4 8.5 4H11.5C11.7761 4 12 3.77614 12 3.5C12 3.22386 11.7761 3 11.5 3H8.5ZM7.08535 4H5.5C5.22386 4 5 4.22386 5 4.5V16.5C5 16.7761 5.22386 17 5.5 17H14.5C14.7761 17 15 16.7761 15 16.5V4.5C15 4.22386 14.7761 4 14.5 4H12.9146C12.7087 4.5826 12.1531 5 11.5 5H8.5C7.84689 5 7.29127 4.5826 7.08535 4Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 695 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08535 3C7.29127 2.4174 7.84689 2 8.5 2H11.5C12.1531 2 12.7087 2.4174 12.9146 3H14.5C15.3284 3 16 3.67157 16 4.5V9H15V4.5C15 4.22386 14.7761 4 14.5 4H12.9146C12.7087 4.5826 12.1531 5 11.5 5H8.5C7.84689 5 7.29127 4.5826 7.08535 4H5.5C5.22386 4 5 4.22386 5 4.5V16.5C5 16.7761 5.22386 17 5.5 17H9.03544C9.08595 17.3531 9.18915 17.6891 9.33682 18H5.5C4.67157 18 4 17.3284 4 16.5V4.5C4 3.67157 4.67157 3 5.5 3H7.08535ZM8.5 3C8.22386 3 8 3.22386 8 3.5C8 3.77614 8.22386 4 8.5 4H11.5C11.7761 4 12 3.77614 12 3.5C12 3.22386 11.7761 3 11.5 3H8.5ZM10 12.5C10 11.1193 11.1193 10 12.5 10H16.5C17.8807 10 19 11.1193 19 12.5V16.5C19 17.0095 18.8476 17.4835 18.5858 17.8787L15.5607 14.8536C14.9749 14.2678 14.0251 14.2678 13.4393 14.8536L10.4142 17.8787C10.1524 17.4835 10 17.0095 10 16.5V12.5ZM17 12.75C17 12.3358 16.6642 12 16.25 12C15.8358 12 15.5 12.3358 15.5 12.75C15.5 13.1642 15.8358 13.5 16.25 13.5C16.6642 13.5 17 13.1642 17 12.75ZM11.1213 18.5858C11.5165 18.8476 11.9905 19 12.5 19H16.5C17.0095 19 17.4835 18.8476 17.8787 18.5858L14.8536 15.5607C14.6583 15.3654 14.3417 15.3654 14.1464 15.5607L11.1213 18.5858Z" fill="#D0D0D0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08535 3C7.29127 2.4174 7.84689 2 8.5 2H11.5C12.1531 2 12.7087 2.4174 12.9146 3H14.5C15.3284 3 16 3.67157 16 4.5V9H15V4.5C15 4.22386 14.7761 4 14.5 4H12.9146C12.7087 4.5826 12.1531 5 11.5 5H8.5C7.84689 5 7.29127 4.5826 7.08535 4H5.5C5.22386 4 5 4.22386 5 4.5V16.5C5 16.7761 5.22386 17 5.5 17H9.03544C9.08595 17.3531 9.18915 17.6891 9.33682 18H5.5C4.67157 18 4 17.3284 4 16.5V4.5C4 3.67157 4.67157 3 5.5 3H7.08535ZM8.5 3C8.22386 3 8 3.22386 8 3.5C8 3.77614 8.22386 4 8.5 4H11.5C11.7761 4 12 3.77614 12 3.5C12 3.22386 11.7761 3 11.5 3H8.5ZM10 12.5C10 11.1193 11.1193 10 12.5 10H16.5C17.8807 10 19 11.1193 19 12.5V16.5C19 17.0095 18.8476 17.4835 18.5858 17.8787L15.5607 14.8536C14.9749 14.2678 14.0251 14.2678 13.4393 14.8536L10.4142 17.8787C10.1524 17.4835 10 17.0095 10 16.5V12.5ZM17 12.75C17 12.3358 16.6642 12 16.25 12C15.8358 12 15.5 12.3358 15.5 12.75C15.5 13.1642 15.8358 13.5 16.25 13.5C16.6642 13.5 17 13.1642 17 12.75ZM11.1213 18.5858C11.5165 18.8476 11.9905 19 12.5 19H16.5C17.0095 19 17.4835 18.8476 17.8787 18.5858L14.8536 15.5607C14.6583 15.3654 14.3417 15.3654 14.1464 15.5607L11.1213 18.5858Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08535 3C7.29127 2.4174 7.84689 2 8.5 2H11.5C12.1531 2 12.7087 2.4174 12.9146 3H14.5C15.3284 3 16 3.67157 16 4.5V10.337L15.3698 8.89819C15.2826 8.69904 15.1554 8.52562 15 8.38568V4.5C15 4.22386 14.7761 4 14.5 4H12.9146C12.7087 4.5826 12.1531 5 11.5 5H8.5C7.84689 5 7.29127 4.5826 7.08535 4H5.5C5.22386 4 5 4.22386 5 4.5V16.5C5 16.7761 5.22386 17 5.5 17H9.08561C8.9672 17.3338 8.97447 17.6857 9.08567 18H5.5C4.67157 18 4 17.3284 4 16.5V4.5C4 3.67157 4.67157 3 5.5 3H7.08535ZM8.5 3C8.22386 3 8 3.22386 8 3.5C8 3.77614 8.22386 4 8.5 4H11.5C11.7761 4 12 3.77614 12 3.5C12 3.22386 11.7761 3 11.5 3H8.5ZM14.4538 9.2994C14.3741 9.11744 14.1942 8.99992 13.9956 9C13.797 9.00008 13.6172 9.11776 13.5376 9.29979L10.0417 17.2998C9.93114 17.5528 10.0466 17.8476 10.2997 17.9582C10.5527 18.0687 10.8475 17.9533 10.958 17.7002L12.138 15H15.859L17.0419 17.7006C17.1527 17.9535 17.4475 18.0688 17.7005 17.958C17.9534 17.8472 18.0687 17.5523 17.9579 17.2994L14.4538 9.2994ZM15.421 14H12.575L13.9963 10.7474L15.421 14Z" fill="#D0D0D0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.08535 3C7.29127 2.4174 7.84689 2 8.5 2H11.5C12.1531 2 12.7087 2.4174 12.9146 3H14.5C15.3284 3 16 3.67157 16 4.5V10.337L15.3698 8.89819C15.2826 8.69904 15.1554 8.52562 15 8.38568V4.5C15 4.22386 14.7761 4 14.5 4H12.9146C12.7087 4.5826 12.1531 5 11.5 5H8.5C7.84689 5 7.29127 4.5826 7.08535 4H5.5C5.22386 4 5 4.22386 5 4.5V16.5C5 16.7761 5.22386 17 5.5 17H9.08561C8.9672 17.3338 8.97447 17.6857 9.08567 18H5.5C4.67157 18 4 17.3284 4 16.5V4.5C4 3.67157 4.67157 3 5.5 3H7.08535ZM8.5 3C8.22386 3 8 3.22386 8 3.5C8 3.77614 8.22386 4 8.5 4H11.5C11.7761 4 12 3.77614 12 3.5C12 3.22386 11.7761 3 11.5 3H8.5ZM14.4538 9.2994C14.3741 9.11744 14.1942 8.99992 13.9956 9C13.797 9.00008 13.6172 9.11776 13.5376 9.29979L10.0417 17.2998C9.93114 17.5528 10.0466 17.8476 10.2997 17.9582C10.5527 18.0687 10.8475 17.9533 10.958 17.7002L12.138 15H15.859L17.0419 17.7006C17.1527 17.9535 17.4475 18.0688 17.7005 17.958C17.9534 17.8472 18.0687 17.5523 17.9579 17.2994L14.4538 9.2994ZM15.421 14H12.575L13.9963 10.7474L15.421 14Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 2C6.89543 2 6 2.89543 6 4V14C6 15.1046 6.89543 16 8 16H14C15.1046 16 16 15.1046 16 14V4C16 2.89543 15.1046 2 14 2H8ZM7 4C7 3.44772 7.44772 3 8 3H14C14.5523 3 15 3.44772 15 4V14C15 14.5523 14.5523 15 14 15H8C7.44772 15 7 14.5523 7 14V4ZM4 6.00001C4 5.25973 4.4022 4.61339 5 4.26758V14.5C5 15.8807 6.11929 17 7.5 17H13.7324C13.3866 17.5978 12.7403 18 12 18H7.5C5.567 18 4 16.433 4 14.5V6.00001Z" fill="#D0D0D0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 526 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 2C6.89543 2 6 2.89543 6 4V14C6 15.1046 6.89543 16 8 16H14C15.1046 16 16 15.1046 16 14V4C16 2.89543 15.1046 2 14 2H8ZM7 4C7 3.44772 7.44772 3 8 3H14C14.5523 3 15 3.44772 15 4V14C15 14.5523 14.5523 15 14 15H8C7.44772 15 7 14.5523 7 14V4ZM4 6.00001C4 5.25973 4.4022 4.61339 5 4.26758V14.5C5 15.8807 6.11929 17 7.5 17H13.7324C13.3866 17.5978 12.7403 18 12 18H7.5C5.567 18 4 16.433 4 14.5V6.00001Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 526 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 4C6 2.89543 6.89543 2 8 2H11.5858C11.9836 2 12.3651 2.15804 12.6464 2.43934L16.5607 6.35355C16.842 6.63486 17 7.01639 17 7.41421V14C17 15.1046 16.1046 16 15 16H8C6.89543 16 6 15.1046 6 14V4ZM8 3C7.44772 3 7 3.44772 7 4V14C7 14.5523 7.44772 15 8 15H15C15.5523 15 16 14.5523 16 14V8H12.5C11.6716 8 11 7.32843 11 6.5V3H8ZM12 3.20711V6.5C12 6.77614 12.2239 7 12.5 7H15.7929L12 3.20711ZM4 5C4 4.44772 4.44772 4 5 4V14C5 15.6569 6.34315 17 8 17L15 17C15 17.5523 14.5523 18 14 18H7.93939C5.76373 18 4 16.2363 4 14.0606V5Z" fill="#D0D0D0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 648 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 4C6 2.89543 6.89543 2 8 2H11.5858C11.9836 2 12.3651 2.15804 12.6464 2.43934L16.5607 6.35355C16.842 6.63486 17 7.01639 17 7.41421V14C17 15.1046 16.1046 16 15 16H8C6.89543 16 6 15.1046 6 14V4ZM8 3C7.44772 3 7 3.44772 7 4V14C7 14.5523 7.44772 15 8 15H15C15.5523 15 16 14.5523 16 14V8H12.5C11.6716 8 11 7.32843 11 6.5V3H8ZM12 3.20711V6.5C12 6.77614 12.2239 7 12.5 7H15.7929L12 3.20711ZM4 5C4 4.44772 4.44772 4 5 4V14C5 15.6569 6.34315 17 8 17L15 17C15 17.5523 14.5523 18 14 18H7.93939C5.76373 18 4 16.2363 4 14.0606V5Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 648 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.49751 7.4966C9.04842 7.4966 9.49502 7.05 9.49502 6.4991C9.49502 5.94819 9.04842 5.50159 8.49751 5.50159C7.9466 5.50159 7.5 5.94819 7.5 6.4991C7.5 7.05 7.9466 7.4966 8.49751 7.4966ZM5 6C5 4.34315 6.34315 3 8 3H14C15.6569 3 17 4.34315 17 6V12C17 13.6569 15.6569 15 14 15H8C6.34315 15 5 13.6569 5 12V6ZM8 4C6.89543 4 6 4.89543 6 6V12C6 12.3709 6.10097 12.7182 6.27692 13.016L9.79085 9.50207C10.4586 8.83427 11.5414 8.83427 12.2092 9.50207L15.7231 13.016C15.899 12.7182 16 12.3709 16 12V6C16 4.89543 15.1046 4 14 4H8ZM15.016 13.7231L11.502 10.2092C11.2248 9.9319 10.7752 9.9319 10.498 10.2092L6.98403 13.7231C7.28178 13.899 7.6291 14 8 14H14C14.3709 14 14.7182 13.899 15.016 13.7231ZM12 17C12.8885 17 13.6868 16.6138 14.2361 16H7.5C5.68782 16 4.1973 14.6228 4.01807 12.8579C4.00612 12.7402 4 12.6208 4 12.5V5.76392C3.38625 6.31324 3 7.11152 3 8.00002V12.5C3 14.9853 5.01472 17 7.5 17H12Z" fill="#D0D0D0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1017 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.49751 7.4966C9.04842 7.4966 9.49502 7.05 9.49502 6.4991C9.49502 5.94819 9.04842 5.50159 8.49751 5.50159C7.9466 5.50159 7.5 5.94819 7.5 6.4991C7.5 7.05 7.9466 7.4966 8.49751 7.4966ZM5 6C5 4.34315 6.34315 3 8 3H14C15.6569 3 17 4.34315 17 6V12C17 13.6569 15.6569 15 14 15H8C6.34315 15 5 13.6569 5 12V6ZM8 4C6.89543 4 6 4.89543 6 6V12C6 12.3709 6.10097 12.7182 6.27692 13.016L9.79085 9.50207C10.4586 8.83427 11.5414 8.83427 12.2092 9.50207L15.7231 13.016C15.899 12.7182 16 12.3709 16 12V6C16 4.89543 15.1046 4 14 4H8ZM15.016 13.7231L11.502 10.2092C11.2248 9.9319 10.7752 9.9319 10.498 10.2092L6.98403 13.7231C7.28178 13.899 7.6291 14 8 14H14C14.3709 14 14.7182 13.899 15.016 13.7231ZM12 17C12.8885 17 13.6868 16.6138 14.2361 16H7.5C5.68782 16 4.1973 14.6228 4.01807 12.8579C4.00612 12.7402 4 12.6208 4 12.5V5.76392C3.38625 6.31324 3 7.11152 3 8.00002V12.5C3 14.9853 5.01472 17 7.5 17H12Z" fill="#212121"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1017 B |
@@ -1,12 +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.
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.ClipboardHistory.Helpers;
|
||||
|
||||
internal enum PrimaryAction
|
||||
{
|
||||
Default,
|
||||
Paste,
|
||||
Copy,
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
// 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 Microsoft.CmdPal.Ext.ClipboardHistory.Properties;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
@@ -27,22 +26,10 @@ internal sealed class SettingsManager : JsonSettingsManager, ISettingOptions
|
||||
Resources.settings_confirm_delete_description!,
|
||||
true);
|
||||
|
||||
private readonly ChoiceSetSetting _primaryAction = new(
|
||||
Namespaced(nameof(PrimaryAction)),
|
||||
Resources.settings_primary_action_title!,
|
||||
Resources.settings_primary_action_description!,
|
||||
[
|
||||
new ChoiceSetSetting.Choice(Resources.settings_primary_action_default!, PrimaryAction.Default.ToString("G")),
|
||||
new ChoiceSetSetting.Choice(Resources.settings_primary_action_paste!, PrimaryAction.Paste.ToString("G")),
|
||||
new ChoiceSetSetting.Choice(Resources.settings_primary_action_copy!, PrimaryAction.Copy.ToString("G"))
|
||||
]);
|
||||
|
||||
public bool KeepAfterPaste => _keepAfterPaste.Value;
|
||||
|
||||
public bool DeleteFromHistoryRequiresConfirmation => _confirmDelete.Value;
|
||||
|
||||
public PrimaryAction PrimaryAction => Enum.TryParse<PrimaryAction>(_primaryAction.Value, out var action) ? action : PrimaryAction.Default;
|
||||
|
||||
private static string SettingsJsonPath()
|
||||
{
|
||||
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
|
||||
@@ -58,7 +45,6 @@ internal sealed class SettingsManager : JsonSettingsManager, ISettingOptions
|
||||
|
||||
Settings.Add(_keepAfterPaste);
|
||||
Settings.Add(_confirmDelete);
|
||||
Settings.Add(_primaryAction);
|
||||
|
||||
// Load settings from file upon initialization
|
||||
LoadSettings();
|
||||
|
||||
@@ -6,7 +6,7 @@ using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.ClipboardHistory;
|
||||
|
||||
internal static class Icons
|
||||
internal sealed class Icons
|
||||
{
|
||||
internal static IconInfo CopyIcon { get; } = new("\xE8C8");
|
||||
|
||||
@@ -17,21 +17,4 @@ internal static class Icons
|
||||
internal static IconInfo DeleteIcon { get; } = new("\uE74D");
|
||||
|
||||
internal static IconInfo ClipboardListIcon { get; } = IconHelpers.FromRelativePath("Assets\\ClipboardHistory.svg");
|
||||
|
||||
internal static IconInfo Clipboard { get; } = Create("ic_fluent_clipboard_20_regular");
|
||||
|
||||
internal static IconInfo ClipboardImage { get; } = Create("ic_fluent_clipboard_image_20_regular");
|
||||
|
||||
internal static IconInfo ClipboardLetter { get; } = Create("ic_fluent_clipboard_letter_20_regular");
|
||||
|
||||
internal static IconInfo Copy { get; } = Create(" ic_fluent_copy_20_regular");
|
||||
|
||||
internal static IconInfo DocumentCopy { get; } = Create("ic_fluent_document_copy_20_regular");
|
||||
|
||||
internal static IconInfo ImageCopy { get; } = Create("ic_fluent_image_copy_20_regular");
|
||||
|
||||
private static IconInfo Create(string name)
|
||||
{
|
||||
return IconHelpers.FromRelativePaths($"Assets\\Icons\\{name}.light.svg", $"Assets\\Icons\\{name}.dark.svg");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,41 +39,5 @@
|
||||
<Content Update="Assets\ClipboardHistory.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_clipboard_20_regular.dark.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_clipboard_20_regular.light.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_clipboard_image_20_regular.dark.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_clipboard_image_20_regular.light.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_clipboard_letter_20_regular.dark.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_clipboard_letter_20_regular.light.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_copy_20_regular.dark.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_copy_20_regular.light.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_document_copy_20_regular.dark.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_document_copy_20_regular.light.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_image_copy_20_regular.dark.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Icons\ic_fluent_image_copy_20_regular.light.svg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -3,8 +3,14 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.CmdPal.Common.Commands;
|
||||
using Microsoft.CmdPal.Ext.ClipboardHistory.Commands;
|
||||
using Microsoft.CmdPal.Ext.ClipboardHistory.Helpers;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
@@ -35,8 +41,126 @@ public class ClipboardItem
|
||||
}
|
||||
|
||||
[MemberNotNullWhen(true, nameof(ImageData))]
|
||||
internal bool IsImage => ImageData is not null;
|
||||
private bool IsImage => ImageData is not null;
|
||||
|
||||
[MemberNotNullWhen(true, nameof(Content))]
|
||||
internal bool IsText => !string.IsNullOrEmpty(Content);
|
||||
private bool IsText => !string.IsNullOrEmpty(Content);
|
||||
|
||||
public static List<string> ShiftLinesLeft(List<string> lines)
|
||||
{
|
||||
// Determine the minimum leading whitespace
|
||||
var minLeadingWhitespace = lines
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line))
|
||||
.Min(line => line.TakeWhile(char.IsWhiteSpace).Count());
|
||||
|
||||
// Check if all lines have at least that much leading whitespace
|
||||
if (lines.Any(line => line.TakeWhile(char.IsWhiteSpace).Count() < minLeadingWhitespace))
|
||||
{
|
||||
return lines; // Return the original lines if any line doesn't have enough leading whitespace
|
||||
}
|
||||
|
||||
// Remove the minimum leading whitespace from each line
|
||||
var shiftedLines = lines.Select(line => line.Substring(minLeadingWhitespace)).ToList();
|
||||
|
||||
return shiftedLines;
|
||||
}
|
||||
|
||||
public static List<string> StripLeadingWhitespace(List<string> lines)
|
||||
{
|
||||
// Determine the minimum leading whitespace
|
||||
var minLeadingWhitespace = lines
|
||||
.Min(line => line.TakeWhile(char.IsWhiteSpace).Count());
|
||||
|
||||
// Remove the minimum leading whitespace from each line
|
||||
var shiftedLines = lines.Select(line =>
|
||||
line.Length >= minLeadingWhitespace
|
||||
? line.Substring(minLeadingWhitespace)
|
||||
: line).ToList();
|
||||
|
||||
return shiftedLines;
|
||||
}
|
||||
|
||||
public ListItem ToListItem()
|
||||
{
|
||||
ListItem listItem;
|
||||
|
||||
List<DetailsElement> metadata = [];
|
||||
metadata.Add(new DetailsElement()
|
||||
{
|
||||
Key = "Copied on",
|
||||
Data = new DetailsLink(Item.Timestamp.DateTime.ToString(DateTimeFormatInfo.CurrentInfo)),
|
||||
});
|
||||
|
||||
var deleteConfirmationCommand = new ConfirmableCommand()
|
||||
{
|
||||
Command = new DeleteItemCommand(this),
|
||||
ConfirmationTitle = Properties.Resources.delete_confirmation_title!,
|
||||
ConfirmationMessage = Properties.Resources.delete_confirmation_message!,
|
||||
IsConfirmationRequired = () => Settings.DeleteFromHistoryRequiresConfirmation,
|
||||
};
|
||||
var deleteContextMenuItem = new CommandContextItem(deleteConfirmationCommand)
|
||||
{
|
||||
IsCritical = true,
|
||||
RequestedShortcut = KeyChords.DeleteEntry,
|
||||
};
|
||||
|
||||
if (IsImage)
|
||||
{
|
||||
var iconData = new IconData(ImageData);
|
||||
var heroImage = new IconInfo(iconData, iconData);
|
||||
listItem = new(new CopyCommand(this, ClipboardFormat.Image))
|
||||
{
|
||||
// Placeholder subtitle as there’s no BitmapImage dimensions to retrieve
|
||||
Title = "Image Data",
|
||||
Details = new Details()
|
||||
{
|
||||
HeroImage = heroImage,
|
||||
Title = GetDataType(),
|
||||
Body = Timestamp.ToString(CultureInfo.InvariantCulture),
|
||||
Metadata = metadata.ToArray(),
|
||||
},
|
||||
MoreCommands = [
|
||||
new CommandContextItem(new PasteCommand(this, ClipboardFormat.Image, Settings)),
|
||||
new Separator(),
|
||||
deleteContextMenuItem,
|
||||
],
|
||||
};
|
||||
}
|
||||
else if (IsText)
|
||||
{
|
||||
var splitContent = Content.Split("\n");
|
||||
var head = splitContent.AsSpan(0, Math.Min(3, splitContent.Length)).ToArray().ToList();
|
||||
var preview2 = string.Join(
|
||||
"\n",
|
||||
StripLeadingWhitespace(head));
|
||||
|
||||
listItem = new(new CopyCommand(this, ClipboardFormat.Text))
|
||||
{
|
||||
Title = preview2,
|
||||
|
||||
Details = new Details
|
||||
{
|
||||
Title = GetDataType(),
|
||||
Body = $"```text\n{Content}\n```",
|
||||
Metadata = metadata.ToArray(),
|
||||
},
|
||||
MoreCommands = [
|
||||
new CommandContextItem(new PasteCommand(this, ClipboardFormat.Text, Settings)),
|
||||
new Separator(),
|
||||
deleteContextMenuItem,
|
||||
],
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
listItem = new(new NoOpCommand())
|
||||
{
|
||||
Title = "Unknown",
|
||||
Subtitle = GetDataType(),
|
||||
Details = new Details { Title = GetDataType() },
|
||||
};
|
||||
}
|
||||
|
||||
return listItem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ internal sealed partial class ClipboardHistoryListPage : ListPage
|
||||
var item = clipboardHistory[i];
|
||||
if (item is not null)
|
||||
{
|
||||
listItems.Add(new ClipboardListItem(item, _settingsManager));
|
||||
listItems.Add(item.ToListItem());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,201 +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.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.CmdPal.Common.Commands;
|
||||
using Microsoft.CmdPal.Ext.ClipboardHistory.Commands;
|
||||
using Microsoft.CmdPal.Ext.ClipboardHistory.Helpers;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.ClipboardHistory.Models;
|
||||
|
||||
internal sealed partial class ClipboardListItem : ListItem
|
||||
{
|
||||
private readonly SettingsManager _settingsManager;
|
||||
private readonly ClipboardItem _item;
|
||||
|
||||
private readonly CommandContextItem _deleteContextMenuItem;
|
||||
private readonly CommandContextItem? _pasteCommand;
|
||||
private readonly CommandContextItem? _copyCommand;
|
||||
private readonly Lazy<Details> _lazyDetails;
|
||||
|
||||
public override IDetails? Details
|
||||
{
|
||||
get => _lazyDetails.Value;
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public ClipboardListItem(ClipboardItem item, SettingsManager settingsManager)
|
||||
{
|
||||
_item = item;
|
||||
_settingsManager = settingsManager;
|
||||
_settingsManager.Settings.SettingsChanged += SettingsOnSettingsChanged;
|
||||
|
||||
_lazyDetails = new(() => CreateDetails());
|
||||
|
||||
var deleteConfirmationCommand = new ConfirmableCommand
|
||||
{
|
||||
Command = new DeleteItemCommand(_item),
|
||||
ConfirmationTitle = Properties.Resources.delete_confirmation_title!,
|
||||
ConfirmationMessage = Properties.Resources.delete_confirmation_message!,
|
||||
IsConfirmationRequired = () => _settingsManager.DeleteFromHistoryRequiresConfirmation,
|
||||
};
|
||||
_deleteContextMenuItem = new CommandContextItem(deleteConfirmationCommand)
|
||||
{
|
||||
IsCritical = true,
|
||||
RequestedShortcut = KeyChords.DeleteEntry,
|
||||
};
|
||||
|
||||
if (item.IsImage)
|
||||
{
|
||||
Title = "Image";
|
||||
|
||||
_pasteCommand = new CommandContextItem(new PasteCommand(_item, ClipboardFormat.Image, _settingsManager));
|
||||
_copyCommand = new CommandContextItem(new CopyCommand(_item, ClipboardFormat.Image));
|
||||
}
|
||||
else if (item.IsText)
|
||||
{
|
||||
var splitContent = _item.Content?.Split("\n") ?? [];
|
||||
var head = splitContent.Take(3);
|
||||
var preview2 = string.Join(
|
||||
"\n",
|
||||
StripLeadingWhitespace(head));
|
||||
|
||||
Title = preview2;
|
||||
|
||||
_pasteCommand = new CommandContextItem(new PasteCommand(_item, ClipboardFormat.Text, _settingsManager));
|
||||
_copyCommand = new CommandContextItem(new CopyCommand(_item, ClipboardFormat.Text));
|
||||
}
|
||||
else
|
||||
{
|
||||
_pasteCommand = null;
|
||||
_copyCommand = null;
|
||||
}
|
||||
|
||||
RefreshCommands();
|
||||
}
|
||||
|
||||
private void SettingsOnSettingsChanged(object sender, Settings args)
|
||||
{
|
||||
RefreshCommands();
|
||||
}
|
||||
|
||||
private void RefreshCommands()
|
||||
{
|
||||
if (_item is { IsText: false, IsImage: false })
|
||||
{
|
||||
MoreCommands = [_deleteContextMenuItem];
|
||||
Icon = _settingsManager.PrimaryAction == PrimaryAction.Paste ? Icons.Clipboard : Icons.Copy;
|
||||
}
|
||||
|
||||
switch (_settingsManager.PrimaryAction)
|
||||
{
|
||||
case PrimaryAction.Paste:
|
||||
Command = _pasteCommand?.Command;
|
||||
MoreCommands =
|
||||
[
|
||||
_copyCommand!,
|
||||
new Separator(),
|
||||
_deleteContextMenuItem,
|
||||
];
|
||||
|
||||
if (_item.IsText)
|
||||
{
|
||||
Icon = Icons.ClipboardLetter;
|
||||
}
|
||||
else if (_item.IsImage)
|
||||
{
|
||||
Icon = Icons.ClipboardImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon = Icons.ClipboardImage;
|
||||
}
|
||||
|
||||
break;
|
||||
case PrimaryAction.Default:
|
||||
case PrimaryAction.Copy:
|
||||
default:
|
||||
Command = _copyCommand?.Command;
|
||||
MoreCommands =
|
||||
[
|
||||
_pasteCommand!,
|
||||
new Separator(),
|
||||
_deleteContextMenuItem,
|
||||
];
|
||||
|
||||
if (_item.IsText)
|
||||
{
|
||||
Icon = Icons.DocumentCopy;
|
||||
}
|
||||
else if (_item.IsImage)
|
||||
{
|
||||
Icon = Icons.ImageCopy;
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon = Icons.Copy;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Details CreateDetails()
|
||||
{
|
||||
IDetailsElement[] metadata =
|
||||
[
|
||||
new DetailsElement
|
||||
{
|
||||
Key = "Copied on",
|
||||
Data = new DetailsLink(_item.Timestamp.DateTime.ToString(DateTimeFormatInfo.CurrentInfo)),
|
||||
}
|
||||
];
|
||||
|
||||
if (_item.IsImage)
|
||||
{
|
||||
var iconData = new IconData(_item.ImageData);
|
||||
var heroImage = new IconInfo(iconData);
|
||||
return new Details
|
||||
{
|
||||
Title = _item.GetDataType(),
|
||||
HeroImage = heroImage,
|
||||
Metadata = metadata,
|
||||
};
|
||||
}
|
||||
|
||||
if (_item.IsText)
|
||||
{
|
||||
return new Details
|
||||
{
|
||||
Title = _item.GetDataType(),
|
||||
Body = $"```text\n{_item.Content}\n```",
|
||||
Metadata = metadata,
|
||||
};
|
||||
}
|
||||
|
||||
return new Details { Title = _item.GetDataType() };
|
||||
}
|
||||
|
||||
private static List<string> StripLeadingWhitespace(IEnumerable<string> lines)
|
||||
{
|
||||
// Determine the minimum leading whitespace
|
||||
var minLeadingWhitespace = lines
|
||||
.Min(static line => line.TakeWhile(char.IsWhiteSpace).Count());
|
||||
|
||||
// Remove the minimum leading whitespace from each line
|
||||
var shiftedLines = lines.Select(line =>
|
||||
line.Length >= minLeadingWhitespace
|
||||
? line[minLeadingWhitespace..]
|
||||
: line).ToList();
|
||||
|
||||
return shiftedLines;
|
||||
}
|
||||
}
|
||||
@@ -212,50 +212,5 @@ namespace Microsoft.CmdPal.Ext.ClipboardHistory.Properties {
|
||||
return ResourceManager.GetString("settings_keep_after_paste_title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy to Clipboard.
|
||||
/// </summary>
|
||||
public static string settings_primary_action_copy {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_primary_action_copy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Default (Copy to Clipboard).
|
||||
/// </summary>
|
||||
public static string settings_primary_action_default {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_primary_action_default", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Primary action (Enter key).
|
||||
/// </summary>
|
||||
public static string settings_primary_action_description {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_primary_action_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Paste.
|
||||
/// </summary>
|
||||
public static string settings_primary_action_paste {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_primary_action_paste", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Primary action.
|
||||
/// </summary>
|
||||
public static string settings_primary_action_title {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_primary_action_title", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,19 +168,4 @@
|
||||
<data name="delete_confirmation_message" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this item from clipboard history? This action cannot be undone.</value>
|
||||
</data>
|
||||
<data name="settings_primary_action_title" xml:space="preserve">
|
||||
<value>Primary action</value>
|
||||
</data>
|
||||
<data name="settings_primary_action_description" xml:space="preserve">
|
||||
<value>Primary action (Enter key)</value>
|
||||
</data>
|
||||
<data name="settings_primary_action_default" xml:space="preserve">
|
||||
<value>Default (Copy to Clipboard)</value>
|
||||
</data>
|
||||
<data name="settings_primary_action_paste" xml:space="preserve">
|
||||
<value>Paste</value>
|
||||
</data>
|
||||
<data name="settings_primary_action_copy" xml:space="preserve">
|
||||
<value>Copy to Clipboard</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -30,7 +30,7 @@ internal sealed class ContextMenuHelper
|
||||
|
||||
// Hide menu if Explorer.exe is the shell process or the process name is ApplicationFrameHost.exe
|
||||
// In the first case we would crash the windows ui and in the second case we would kill the generic process for uwp apps.
|
||||
if (!windowData.Process.IsShellProcess && !(windowData.Process.IsUwpAppFrameHost && string.Equals(windowData.Process.Name, "ApplicationFrameHost.exe", StringComparison.OrdinalIgnoreCase))
|
||||
if (!windowData.Process.IsShellProcess && !(windowData.Process.IsUwpApp && string.Equals(windowData.Process.Name, "ApplicationFrameHost.exe", StringComparison.OrdinalIgnoreCase))
|
||||
&& !(windowData.Process.IsFullAccessDenied && SettingsManager.Instance.HideKillProcessOnElevatedProcesses))
|
||||
{
|
||||
contextMenu.Add(new CommandContextItem(new EndTaskCommand(windowData))
|
||||
|
||||
@@ -23,7 +23,7 @@ internal sealed class WindowProcess
|
||||
/// <summary>
|
||||
/// An indicator if the window belongs to an 'Universal Windows Platform (UWP)' process
|
||||
/// </summary>
|
||||
private readonly bool _isUwpAppFrameHost;
|
||||
private readonly bool _isUwpApp;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the id of the process
|
||||
@@ -42,8 +42,7 @@ internal sealed class WindowProcess
|
||||
{
|
||||
try
|
||||
{
|
||||
// Process.Responding doesn't work on UWP apps
|
||||
return ProcessType.Kind == ProcessPackagingKind.UwpApp || Process.GetProcessById((int)ProcessID).Responding;
|
||||
return Process.GetProcessById((int)ProcessID).Responding;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
@@ -77,7 +76,7 @@ internal sealed class WindowProcess
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the window belongs to an 'Universal Windows Platform (UWP)' process
|
||||
/// </summary>
|
||||
public bool IsUwpAppFrameHost => _isUwpAppFrameHost;
|
||||
internal bool IsUwpApp => _isUwpApp;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this is the shell process or not
|
||||
@@ -135,12 +134,9 @@ internal sealed class WindowProcess
|
||||
internal WindowProcess(uint pid, uint tid, string name)
|
||||
{
|
||||
UpdateProcessInfo(pid, tid, name);
|
||||
ProcessType = ProcessPackagingInspector.Inspect((int)pid);
|
||||
_isUwpAppFrameHost = string.Equals(Name, "ApplicationFrameHost.exe", StringComparison.OrdinalIgnoreCase);
|
||||
_isUwpApp = string.Equals(Name, "ApplicationFrameHost.exe", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public ProcessPackagingInfo ProcessType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates the process information of the <see cref="WindowProcess"/> instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute;
|
||||
|
||||
#pragma warning disable SA1649, CA1051, CA1707, CA1028, CA1714, CA1069, SA1402
|
||||
@@ -98,25 +98,6 @@ public static partial class NativeMethods
|
||||
[DllImport("kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetFirmwareType(ref FirmwareType FirmwareType);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool OpenProcessToken(SafeProcessHandle processHandle, TokenAccess desiredAccess, out SafeAccessTokenHandle tokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool GetTokenInformation(
|
||||
SafeAccessTokenHandle tokenHandle,
|
||||
TOKEN_INFORMATION_CLASS tokenInformationClass,
|
||||
out int tokenInformation,
|
||||
int tokenInformationLength,
|
||||
out int returnLength);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "GetPackageFullName")]
|
||||
internal static extern int GetPackageFullName(
|
||||
SafeProcessHandle hProcess,
|
||||
ref uint packageFullNameLength,
|
||||
StringBuilder? packageFullName);
|
||||
}
|
||||
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "These are the names used by win32.")]
|
||||
@@ -402,7 +383,7 @@ public enum ShowWindowCommand
|
||||
|
||||
/// <summary>
|
||||
/// Displays a window in its most recent size and position. This value
|
||||
/// is similar to <see cref="ShowWindowCommand.Normal"/>, except
|
||||
/// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except
|
||||
/// the window is not activated.
|
||||
/// </summary>
|
||||
ShowNoActivate = 4,
|
||||
@@ -420,14 +401,14 @@ public enum ShowWindowCommand
|
||||
|
||||
/// <summary>
|
||||
/// Displays the window as a minimized window. This value is similar to
|
||||
/// <see cref="ShowWindowCommand.ShowMinimized"/>, except the
|
||||
/// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the
|
||||
/// window is not activated.
|
||||
/// </summary>
|
||||
ShowMinNoActive = 7,
|
||||
|
||||
/// <summary>
|
||||
/// Displays the window in its current size and position. This value is
|
||||
/// similar to <see cref="ShowWindowCommand.Show"/>, except the
|
||||
/// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the
|
||||
/// window is not activated.
|
||||
/// </summary>
|
||||
ShowNA = 8,
|
||||
@@ -1119,14 +1100,3 @@ public enum SIGDN : uint
|
||||
FILESYSPATH = 0x80058000,
|
||||
URL = 0x80068000,
|
||||
}
|
||||
|
||||
internal enum TOKEN_INFORMATION_CLASS
|
||||
{
|
||||
TokenIsAppContainer = 29,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum TokenAccess : uint
|
||||
{
|
||||
TOKEN_QUERY = 0x0008,
|
||||
}
|
||||
|
||||
@@ -1,14 +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.
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowWalker.Helpers;
|
||||
|
||||
internal sealed record ProcessPackagingInfo(
|
||||
int Pid,
|
||||
ProcessPackagingKind Kind,
|
||||
bool HasPackageIdentity,
|
||||
bool IsAppContainer,
|
||||
string? PackageFullName,
|
||||
int? LastError
|
||||
);
|
||||
@@ -1,123 +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.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowWalker.Helpers;
|
||||
|
||||
internal static class ProcessPackagingInspector
|
||||
{
|
||||
#pragma warning disable SA1310 // Field names should not contain underscore
|
||||
private const int ERROR_INSUFFICIENT_BUFFER = 122;
|
||||
private const int APPMODEL_ERROR_NO_PACKAGE = 15700;
|
||||
#pragma warning restore SA1310 // Field names should not contain underscore
|
||||
|
||||
/// <summary>
|
||||
/// Inspect a process by PID and classify its packaging.
|
||||
/// </summary>
|
||||
public static ProcessPackagingInfo Inspect(int pid)
|
||||
{
|
||||
var hProcess = NativeMethods.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, pid);
|
||||
using var process = new SafeProcessHandle(hProcess, true);
|
||||
if (process.IsInvalid)
|
||||
{
|
||||
return new ProcessPackagingInfo(
|
||||
pid,
|
||||
ProcessPackagingKind.Unknown,
|
||||
HasPackageIdentity: false,
|
||||
IsAppContainer: false,
|
||||
PackageFullName: null,
|
||||
LastError: Marshal.GetLastPInvokeError());
|
||||
}
|
||||
|
||||
// 1) Check package identity
|
||||
var hasPackage = TryGetPackageFullName(process, out var packageFullName, out _);
|
||||
|
||||
// 2) If packaged, check AppContainer -> strict UWP
|
||||
var isAppContainer = false;
|
||||
int? tokenErr = null;
|
||||
if (hasPackage)
|
||||
{
|
||||
isAppContainer = TryIsAppContainer(process, out tokenErr);
|
||||
}
|
||||
|
||||
var kind =
|
||||
!hasPackage ? ProcessPackagingKind.UnpackagedWin32 :
|
||||
isAppContainer ? ProcessPackagingKind.UwpApp :
|
||||
ProcessPackagingKind.PackagedWin32;
|
||||
|
||||
return new ProcessPackagingInfo(
|
||||
pid,
|
||||
kind,
|
||||
HasPackageIdentity: hasPackage,
|
||||
IsAppContainer: isAppContainer,
|
||||
PackageFullName: packageFullName,
|
||||
LastError: null);
|
||||
}
|
||||
|
||||
private static bool TryGetPackageFullName(SafeProcessHandle hProcess, out string? packageFullName, out int? lastError)
|
||||
{
|
||||
packageFullName = null;
|
||||
lastError = null;
|
||||
|
||||
uint len = 0;
|
||||
var rc = NativeMethods.GetPackageFullName(hProcess, ref len, null);
|
||||
if (rc == APPMODEL_ERROR_NO_PACKAGE)
|
||||
{
|
||||
return false; // no package identity
|
||||
}
|
||||
|
||||
if (rc != ERROR_INSUFFICIENT_BUFFER && rc != 0)
|
||||
{
|
||||
lastError = rc;
|
||||
return false; // unexpected error
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var sb = new StringBuilder((int)len);
|
||||
rc = NativeMethods.GetPackageFullName(hProcess, ref len, sb);
|
||||
if (rc == 0)
|
||||
{
|
||||
packageFullName = sb.ToString();
|
||||
return true;
|
||||
}
|
||||
|
||||
lastError = rc;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryIsAppContainer(SafeProcessHandle hProcess, out int? lastError)
|
||||
{
|
||||
lastError = null;
|
||||
|
||||
if (!NativeMethods.OpenProcessToken(hProcess, TokenAccess.TOKEN_QUERY, out var token))
|
||||
{
|
||||
lastError = Marshal.GetLastPInvokeError();
|
||||
return false; // can't decide; treat as not-UWP for classification
|
||||
}
|
||||
|
||||
using (token)
|
||||
{
|
||||
if (!NativeMethods.GetTokenInformation(
|
||||
token,
|
||||
TOKEN_INFORMATION_CLASS.TokenIsAppContainer,
|
||||
out var val,
|
||||
sizeof(int),
|
||||
out _))
|
||||
{
|
||||
lastError = Marshal.GetLastPInvokeError();
|
||||
return false;
|
||||
}
|
||||
|
||||
return val != 0; // true => AppContainer (UWP)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +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.
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowWalker.Helpers;
|
||||
|
||||
internal enum ProcessPackagingKind
|
||||
{
|
||||
Unknown = 0,
|
||||
UnpackagedWin32,
|
||||
PackagedWin32,
|
||||
UwpApp,
|
||||
}
|
||||
@@ -20,15 +20,13 @@ internal sealed partial class LaunchProfileAsAdminCommand : InvokableCommand
|
||||
private readonly string _profile;
|
||||
private readonly bool _openNewTab;
|
||||
private readonly bool _openQuake;
|
||||
private readonly AppSettingsManager _appSettingsManager;
|
||||
|
||||
internal LaunchProfileAsAdminCommand(string id, string profile, bool openNewTab, bool openQuake, AppSettingsManager appSettingsManager)
|
||||
internal LaunchProfileAsAdminCommand(string id, string profile, bool openNewTab, bool openQuake)
|
||||
{
|
||||
this._id = id;
|
||||
this._profile = profile;
|
||||
this._openNewTab = openNewTab;
|
||||
this._openQuake = openQuake;
|
||||
this._appSettingsManager = appSettingsManager;
|
||||
|
||||
this.Name = Resources.launch_profile_as_admin;
|
||||
this.Icon = Icons.AdminIcon;
|
||||
@@ -61,17 +59,6 @@ internal sealed partial class LaunchProfileAsAdminCommand : InvokableCommand
|
||||
//_context.API.ShowMsg(name, message, string.Empty);
|
||||
Logger.LogError($"Failed to open Windows Terminal: {ex.Message}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_appSettingsManager.Current.AddRecentlyUsedProfile(id, profile);
|
||||
_appSettingsManager.Save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// We don't want to fail the whole operation if we can't save the recently used profile
|
||||
Logger.LogError($"Failed to save recently used profile: {ex.Message}");
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0059, CS0168, SA1005
|
||||
|
||||
|
||||
@@ -20,15 +20,13 @@ internal sealed partial class LaunchProfileCommand : InvokableCommand
|
||||
private readonly string _profile;
|
||||
private readonly bool _openNewTab;
|
||||
private readonly bool _openQuake;
|
||||
private readonly AppSettingsManager _appSettingsManager;
|
||||
|
||||
internal LaunchProfileCommand(string id, string profile, string iconPath, bool openNewTab, bool openQuake, AppSettingsManager appSettingsManager)
|
||||
internal LaunchProfileCommand(string id, string profile, string iconPath, bool openNewTab, bool openQuake)
|
||||
{
|
||||
this._id = id;
|
||||
this._profile = profile;
|
||||
this._openNewTab = openNewTab;
|
||||
this._openQuake = openQuake;
|
||||
this._appSettingsManager = appSettingsManager;
|
||||
|
||||
this.Name = Resources.launch_profile;
|
||||
this.Icon = new IconInfo(iconPath);
|
||||
@@ -64,17 +62,6 @@ internal sealed partial class LaunchProfileCommand : InvokableCommand
|
||||
// _context.API.ShowMsg(name, message, string.Empty);
|
||||
Logger.LogError($"Failed to open Windows Terminal: {ex.Message}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_appSettingsManager.Current.AddRecentlyUsedProfile(id, profile);
|
||||
_appSettingsManager.Save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// We don't want to fail the whole operation if we can't save the recently used profile
|
||||
Logger.LogError($"Failed to save recently used profile: {ex.Message}");
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0059, CS0168
|
||||
|
||||
|
||||
@@ -1,46 +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.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Strongly typed application-level settings for the Windows Terminal extension.
|
||||
/// These are distinct from the dynamic command palette <see cref="JsonSettingsManager"/> based settings
|
||||
/// and are meant for simple persisted state (e.g. last selections).
|
||||
/// </summary>
|
||||
public sealed class AppSettings
|
||||
{
|
||||
private const int MaxRecentProfilesCount = 64;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last selected channel identifier for the Windows Terminal extension.
|
||||
/// Empty string when no channel has been selected yet.
|
||||
/// </summary>
|
||||
[JsonPropertyName("lastSelectedChannel")]
|
||||
public string LastSelectedChannel { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of recently used profile identifiers.
|
||||
/// </summary>
|
||||
[JsonPropertyName("recentlyUsedProfiles")]
|
||||
public List<TerminalProfileKey> RecentlyUsedProfiles { get; init; } = [];
|
||||
|
||||
public void AddRecentlyUsedProfile(string appId, string profileName)
|
||||
{
|
||||
var key = new TerminalProfileKey(appId, profileName);
|
||||
RecentlyUsedProfiles.Remove(key);
|
||||
RecentlyUsedProfiles.Insert(0, key);
|
||||
|
||||
if (RecentlyUsedProfiles.Count > MaxRecentProfilesCount)
|
||||
{
|
||||
RecentlyUsedProfiles.RemoveRange(MaxRecentProfilesCount, RecentlyUsedProfiles.Count - MaxRecentProfilesCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +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.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal sealed partial class AppSettingsJsonContext : JsonSerializerContext;
|
||||
@@ -1,70 +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.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
|
||||
public sealed class AppSettingsManager
|
||||
{
|
||||
private const string FileName = "appsettings.json";
|
||||
|
||||
private static string SettingsPath()
|
||||
{
|
||||
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
|
||||
Directory.CreateDirectory(directory);
|
||||
return Path.Combine(directory, FileName);
|
||||
}
|
||||
|
||||
private readonly string _filePath;
|
||||
|
||||
public AppSettings Current { get; private set; } = new();
|
||||
|
||||
public AppSettingsManager()
|
||||
{
|
||||
_filePath = SettingsPath();
|
||||
Load();
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(_filePath))
|
||||
{
|
||||
var json = File.ReadAllText(_filePath);
|
||||
var loaded = JsonSerializer.Deserialize(json, AppSettingsJsonContext.Default.AppSettings!);
|
||||
if (loaded is not null)
|
||||
{
|
||||
Current = loaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExtensionHost.LogMessage(new LogMessage { Message = ex.ToString() });
|
||||
Logger.LogError("Failed to load app settings", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonSerializer.Serialize(Current, AppSettingsJsonContext.Default.AppSettings!);
|
||||
File.WriteAllText(_filePath, json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExtensionHost.LogMessage(new LogMessage { Message = ex.ToString() });
|
||||
Logger.LogError("Failed to save app settings", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +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.
|
||||
|
||||
#nullable enable
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
|
||||
public enum ProfileSortOrder
|
||||
{
|
||||
Default = 0,
|
||||
Alphabetical = 1,
|
||||
MostRecentlyUsed = 2,
|
||||
}
|
||||
@@ -34,33 +34,13 @@ public class SettingsManager : JsonSettingsManager
|
||||
Resources.open_quake_description,
|
||||
false);
|
||||
|
||||
private readonly ToggleSetting _saveLastSelectedChannel = new(
|
||||
Namespaced(nameof(SaveLastSelectedChannel)),
|
||||
Resources.save_last_selected_channel!,
|
||||
Resources.save_last_selected_channel_description!,
|
||||
false);
|
||||
|
||||
private readonly ChoiceSetSetting _profileSortOrder = new(
|
||||
Namespaced(nameof(ProfileSortOrder)),
|
||||
Resources.profile_sort_order!,
|
||||
Resources.profile_sort_order_description!,
|
||||
[
|
||||
new ChoiceSetSetting.Choice(Resources.profile_sort_order_item_default!, ProfileSortOrder.Default.ToString("G")),
|
||||
new ChoiceSetSetting.Choice(Resources.profile_sort_order_item_alphabetical!, ProfileSortOrder.Alphabetical.ToString("G")),
|
||||
new ChoiceSetSetting.Choice(Resources.profile_sort_order_item_mru!, ProfileSortOrder.MostRecentlyUsed.ToString("G")),
|
||||
]);
|
||||
|
||||
public bool ShowHiddenProfiles => _showHiddenProfiles.Value;
|
||||
|
||||
public bool OpenNewTab => _openNewTab.Value;
|
||||
|
||||
public bool OpenQuake => _openQuake.Value;
|
||||
|
||||
public bool SaveLastSelectedChannel => _saveLastSelectedChannel.Value;
|
||||
|
||||
public ProfileSortOrder ProfileSortOrder => System.Enum.TryParse<ProfileSortOrder>(_profileSortOrder.Value, out var result) ? result : ProfileSortOrder.Default;
|
||||
|
||||
private static string SettingsJsonPath()
|
||||
internal static string SettingsJsonPath()
|
||||
{
|
||||
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
|
||||
Directory.CreateDirectory(directory);
|
||||
@@ -76,8 +56,6 @@ public class SettingsManager : JsonSettingsManager
|
||||
Settings.Add(_showHiddenProfiles);
|
||||
Settings.Add(_openNewTab);
|
||||
Settings.Add(_openQuake);
|
||||
Settings.Add(_saveLastSelectedChannel);
|
||||
Settings.Add(_profileSortOrder);
|
||||
|
||||
// Load settings from file upon initialization
|
||||
LoadSettings();
|
||||
|
||||
@@ -1,8 +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.
|
||||
|
||||
#nullable enable
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
|
||||
public sealed record TerminalProfileKey(string AppId, string ProfileName);
|
||||
@@ -58,10 +58,10 @@ public class TerminalQuery : ITerminalQuery
|
||||
profiles.AddRange(TerminalHelper.ParseSettings(terminal, settingsJson));
|
||||
}
|
||||
|
||||
return profiles;
|
||||
return profiles.OrderBy(p => p.Name);
|
||||
}
|
||||
|
||||
public IEnumerable<TerminalPackage> GetTerminals()
|
||||
private IEnumerable<TerminalPackage> GetTerminals()
|
||||
{
|
||||
var user = WindowsIdentity.GetCurrent().User;
|
||||
var localAppDataPath = Environment.GetEnvironmentVariable("LOCALAPPDATA");
|
||||
|
||||
@@ -6,11 +6,9 @@ using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal;
|
||||
|
||||
internal static class Icons
|
||||
internal sealed class Icons
|
||||
{
|
||||
internal static IconInfo TerminalIcon { get; } = IconHelpers.FromRelativePath("Assets\\WindowsTerminal.svg");
|
||||
|
||||
internal static IconInfo AdminIcon { get; } = new IconInfo("\xE7EF"); // Admin icon
|
||||
|
||||
internal static IconInfo FilterIcon { get; } = new IconInfo("\uE71C"); // Funnel icon
|
||||
}
|
||||
|
||||
@@ -2,99 +2,39 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Commands;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Pages;
|
||||
|
||||
internal sealed partial class ProfilesListPage : ListPage, INotifyItemsChanged
|
||||
internal sealed partial class ProfilesListPage : ListPage
|
||||
{
|
||||
event TypedEventHandler<object, IItemsChangedEventArgs> INotifyItemsChanged.ItemsChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
ItemsChanged += value;
|
||||
EnsureInitialized();
|
||||
SelectTerminalFilter();
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
ItemsChanged -= value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly TerminalQuery _terminalQuery = new();
|
||||
private readonly SettingsManager _terminalSettings;
|
||||
private readonly AppSettingsManager _appSettingsManager;
|
||||
|
||||
private bool showHiddenProfiles;
|
||||
private bool openNewTab;
|
||||
private bool openQuake;
|
||||
|
||||
private bool initialized;
|
||||
private TerminalChannelFilters? terminalFilters;
|
||||
|
||||
public ProfilesListPage(SettingsManager terminalSettings, AppSettingsManager appSettingsManager)
|
||||
public ProfilesListPage(SettingsManager terminalSettings)
|
||||
{
|
||||
Icon = Icons.TerminalIcon;
|
||||
Name = Resources.profiles_list_page_name;
|
||||
_terminalSettings = terminalSettings;
|
||||
_terminalSettings.Settings.SettingsChanged += Settings_SettingsChanged;
|
||||
_appSettingsManager = appSettingsManager;
|
||||
}
|
||||
|
||||
private void Settings_SettingsChanged(object sender, Settings args)
|
||||
#pragma warning disable SA1108
|
||||
public List<ListItem> Query()
|
||||
{
|
||||
EnsureInitialized();
|
||||
RaiseItemsChanged();
|
||||
}
|
||||
|
||||
private List<ListItem> Query()
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
showHiddenProfiles = _terminalSettings.ShowHiddenProfiles;
|
||||
openNewTab = _terminalSettings.OpenNewTab;
|
||||
openQuake = _terminalSettings.OpenQuake;
|
||||
|
||||
var profiles = _terminalQuery.GetProfiles()!;
|
||||
|
||||
switch (_terminalSettings.ProfileSortOrder)
|
||||
{
|
||||
case ProfileSortOrder.MostRecentlyUsed:
|
||||
var mru = _appSettingsManager.Current.RecentlyUsedProfiles ?? [];
|
||||
profiles = profiles.OrderBy(p =>
|
||||
{
|
||||
var key = new TerminalProfileKey(p.Terminal?.AppUserModelId ?? string.Empty, p.Name ?? string.Empty);
|
||||
var index = mru.IndexOf(key);
|
||||
return index == -1 ? int.MaxValue : index;
|
||||
})
|
||||
.ThenBy(static p => p.Name, StringComparer.CurrentCultureIgnoreCase)
|
||||
.ToList();
|
||||
break;
|
||||
case ProfileSortOrder.Default:
|
||||
case ProfileSortOrder.Alphabetical:
|
||||
default:
|
||||
profiles = profiles.OrderBy(static p => p.Name, StringComparer.CurrentCultureIgnoreCase);
|
||||
break;
|
||||
}
|
||||
|
||||
if (terminalFilters?.IsAllSelected == false)
|
||||
{
|
||||
profiles = profiles.Where(profile => profile.Terminal.AppUserModelId == terminalFilters.CurrentFilterId);
|
||||
}
|
||||
var profiles = _terminalQuery.GetProfiles();
|
||||
|
||||
var result = new List<ListItem>();
|
||||
|
||||
@@ -105,73 +45,19 @@ internal sealed partial class ProfilesListPage : ListPage, INotifyItemsChanged
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add(new ListItem(new LaunchProfileCommand(profile.Terminal.AppUserModelId, profile.Name, profile.Terminal.LogoPath, openNewTab, openQuake, _appSettingsManager))
|
||||
result.Add(new ListItem(new LaunchProfileCommand(profile.Terminal.AppUserModelId, profile.Name, profile.Terminal.LogoPath, openNewTab, openQuake))
|
||||
{
|
||||
Title = profile.Name,
|
||||
Subtitle = profile.Terminal.DisplayName,
|
||||
MoreCommands = [
|
||||
new CommandContextItem(new LaunchProfileAsAdminCommand(profile.Terminal.AppUserModelId, profile.Name, openNewTab, openQuake, _appSettingsManager)),
|
||||
new CommandContextItem(new LaunchProfileAsAdminCommand(profile.Terminal.AppUserModelId, profile.Name, openNewTab, openQuake)),
|
||||
],
|
||||
#pragma warning restore SA1108
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var terminals = _terminalQuery.GetTerminals();
|
||||
terminalFilters = new TerminalChannelFilters(terminals);
|
||||
terminalFilters.PropChanged += TerminalFiltersOnPropChanged;
|
||||
SelectTerminalFilter();
|
||||
Filters = terminalFilters;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private void SelectTerminalFilter()
|
||||
{
|
||||
Trace.Assert(terminalFilters != null);
|
||||
|
||||
// Select the preferred channel if it exists; we always select the preferred channel,
|
||||
// but user have an option to save the preferred channel when he changes the filter
|
||||
if (_terminalSettings.SaveLastSelectedChannel)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_appSettingsManager.Current.LastSelectedChannel) &&
|
||||
terminalFilters.ContainsFilter(_appSettingsManager.Current.LastSelectedChannel))
|
||||
{
|
||||
terminalFilters.CurrentFilterId = _appSettingsManager.Current.LastSelectedChannel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
terminalFilters.CurrentFilterId = TerminalChannelFilters.AllTerminalsFilterId;
|
||||
}
|
||||
}
|
||||
|
||||
private void TerminalFiltersOnPropChanged(object sender, IPropChangedEventArgs args)
|
||||
{
|
||||
Trace.Assert(terminalFilters != null);
|
||||
|
||||
RaiseItemsChanged();
|
||||
_appSettingsManager.Current.LastSelectedChannel = terminalFilters.CurrentFilterId;
|
||||
_appSettingsManager.Save();
|
||||
}
|
||||
|
||||
public override IListItem[] GetItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
return [.. Query()];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Failed to list Windows Terminal profiles", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public override IListItem[] GetItems() => Query().ToArray();
|
||||
}
|
||||
|
||||
@@ -1,56 +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.Collections.Generic;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Pages;
|
||||
|
||||
internal sealed partial class TerminalChannelFilters : Filters
|
||||
{
|
||||
internal const string AllTerminalsFilterId = "all";
|
||||
|
||||
private readonly List<TerminalPackage> _terminals;
|
||||
|
||||
public bool IsAllSelected => CurrentFilterId == AllTerminalsFilterId;
|
||||
|
||||
public TerminalChannelFilters(IEnumerable<TerminalPackage> terminals, string preselectedFilterId = AllTerminalsFilterId)
|
||||
{
|
||||
CurrentFilterId = preselectedFilterId;
|
||||
_terminals = [.. terminals];
|
||||
}
|
||||
|
||||
public override IFilterItem[] GetFilters()
|
||||
{
|
||||
var items = new List<IFilterItem>
|
||||
{
|
||||
new Filter()
|
||||
{
|
||||
Id = AllTerminalsFilterId,
|
||||
Name = Resources.all_channels,
|
||||
Icon = Icons.FilterIcon,
|
||||
},
|
||||
new Separator(),
|
||||
};
|
||||
|
||||
foreach (var terminalPackage in _terminals)
|
||||
{
|
||||
items.Add(new Filter()
|
||||
{
|
||||
Id = terminalPackage.AppUserModelId,
|
||||
Name = terminalPackage.DisplayName,
|
||||
Icon = new IconInfo(terminalPackage.LogoPath),
|
||||
});
|
||||
}
|
||||
|
||||
return [.. items];
|
||||
}
|
||||
|
||||
public bool ContainsFilter(string id)
|
||||
{
|
||||
return _terminals.FindIndex(terminal => terminal.AppUserModelId == id) > -1;
|
||||
}
|
||||
}
|
||||
@@ -60,15 +60,6 @@ namespace Microsoft.CmdPal.Ext.WindowsTerminal.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to All channels.
|
||||
/// </summary>
|
||||
internal static string all_channels {
|
||||
get {
|
||||
return ResourceManager.GetString("all_channels", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Windows Terminal Profiles.
|
||||
/// </summary>
|
||||
@@ -141,78 +132,6 @@ namespace Microsoft.CmdPal.Ext.WindowsTerminal.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Preferred channel.
|
||||
/// </summary>
|
||||
internal static string preferred_channel {
|
||||
get {
|
||||
return ResourceManager.GetString("preferred_channel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Preferred channel.
|
||||
/// </summary>
|
||||
internal static string preferred_channel_description {
|
||||
get {
|
||||
return ResourceManager.GetString("preferred_channel_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Profiles order.
|
||||
/// </summary>
|
||||
internal static string profile_sort_order {
|
||||
get {
|
||||
return ResourceManager.GetString("profile_sort_order", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Profiles order.
|
||||
/// </summary>
|
||||
internal static string profile_sort_order_description {
|
||||
get {
|
||||
return ResourceManager.GetString("profile_sort_order_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Alphabetical.
|
||||
/// </summary>
|
||||
internal static string profile_sort_order_item_alphabetical {
|
||||
get {
|
||||
return ResourceManager.GetString("profile_sort_order_item_alphabetical", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to As defined in Terminal.
|
||||
/// </summary>
|
||||
internal static string profile_sort_order_item_as_in_terminal {
|
||||
get {
|
||||
return ResourceManager.GetString("profile_sort_order_item_as_in_terminal", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Default (alphabetical).
|
||||
/// </summary>
|
||||
internal static string profile_sort_order_item_default {
|
||||
get {
|
||||
return ResourceManager.GetString("profile_sort_order_item_default", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Most recently used.
|
||||
/// </summary>
|
||||
internal static string profile_sort_order_item_mru {
|
||||
get {
|
||||
return ResourceManager.GetString("profile_sort_order_item_mru", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Windows Terminal Profiles.
|
||||
/// </summary>
|
||||
@@ -240,24 +159,6 @@ namespace Microsoft.CmdPal.Ext.WindowsTerminal.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Keep last channel filter.
|
||||
/// </summary>
|
||||
internal static string save_last_selected_channel {
|
||||
get {
|
||||
return ResourceManager.GetString("save_last_selected_channel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Remember the last selected channel instead of resetting to All Channels..
|
||||
/// </summary>
|
||||
internal static string save_last_selected_channel_description {
|
||||
get {
|
||||
return ResourceManager.GetString("save_last_selected_channel_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings.
|
||||
/// </summary>
|
||||
|
||||
@@ -158,37 +158,4 @@
|
||||
<data name="list_item_title" xml:space="preserve">
|
||||
<value>Open Windows Terminal Profiles</value>
|
||||
</data>
|
||||
<data name="preferred_channel" xml:space="preserve">
|
||||
<value>Preferred channel</value>
|
||||
</data>
|
||||
<data name="preferred_channel_description" xml:space="preserve">
|
||||
<value>Preferred channel</value>
|
||||
</data>
|
||||
<data name="all_channels" xml:space="preserve">
|
||||
<value>All channels</value>
|
||||
</data>
|
||||
<data name="save_last_selected_channel" xml:space="preserve">
|
||||
<value>Keep last channel filter</value>
|
||||
</data>
|
||||
<data name="save_last_selected_channel_description" xml:space="preserve">
|
||||
<value>Remember the last selected channel instead of resetting to All Channels.</value>
|
||||
</data>
|
||||
<data name="profile_sort_order" xml:space="preserve">
|
||||
<value>Profiles order</value>
|
||||
</data>
|
||||
<data name="profile_sort_order_description" xml:space="preserve">
|
||||
<value>Profiles order</value>
|
||||
</data>
|
||||
<data name="profile_sort_order_item_default" xml:space="preserve">
|
||||
<value>Default (alphabetical)</value>
|
||||
</data>
|
||||
<data name="profile_sort_order_item_mru" xml:space="preserve">
|
||||
<value>Most recently used</value>
|
||||
</data>
|
||||
<data name="profile_sort_order_item_as_in_terminal" xml:space="preserve">
|
||||
<value>As defined in Terminal</value>
|
||||
</data>
|
||||
<data name="profile_sort_order_item_alphabetical" xml:space="preserve">
|
||||
<value>Alphabetical</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -11,8 +11,8 @@ namespace Microsoft.CmdPal.Ext.WindowsTerminal;
|
||||
|
||||
public partial class TerminalTopLevelCommandItem : CommandItem
|
||||
{
|
||||
public TerminalTopLevelCommandItem(SettingsManager settingsManager, AppSettingsManager appSettingsManager)
|
||||
: base(new ProfilesListPage(settingsManager, appSettingsManager))
|
||||
public TerminalTopLevelCommandItem(SettingsManager settingsManager)
|
||||
: base(new ProfilesListPage(settingsManager))
|
||||
{
|
||||
Icon = Icons.TerminalIcon;
|
||||
Title = Resources.list_item_title;
|
||||
|
||||
@@ -13,7 +13,6 @@ public partial class WindowsTerminalCommandsProvider : CommandProvider
|
||||
{
|
||||
private readonly TerminalTopLevelCommandItem _terminalCommand;
|
||||
private readonly SettingsManager _settingsManager = new();
|
||||
private readonly AppSettingsManager _appSettingsManager = new();
|
||||
|
||||
public WindowsTerminalCommandsProvider()
|
||||
{
|
||||
@@ -22,7 +21,7 @@ public partial class WindowsTerminalCommandsProvider : CommandProvider
|
||||
Icon = Icons.TerminalIcon;
|
||||
Settings = _settingsManager.Settings;
|
||||
|
||||
_terminalCommand = new TerminalTopLevelCommandItem(_settingsManager, _appSettingsManager)
|
||||
_terminalCommand = new TerminalTopLevelCommandItem(_settingsManager)
|
||||
{
|
||||
MoreCommands = [
|
||||
new CommandContextItem(Settings.SettingsPage),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PathToRoot>..\..\..\..\..\</PathToRoot>
|
||||
<WasdkNuget>$(PathToRoot)packages\Microsoft.WindowsAppSDK.1.8.250907003</WasdkNuget>
|
||||
<WasdkNuget>$(PathToRoot)packages\Microsoft.WindowsAppSDK.1.7.250513003</WasdkNuget>
|
||||
<CppWinRTNuget>$(PathToRoot)packages\Microsoft.Windows.CppWinRT.2.0.240111.5</CppWinRTNuget>
|
||||
<WindowsSdkBuildToolsNuget>$(PathToRoot)packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188</WindowsSdkBuildToolsNuget>
|
||||
<WebView2Nuget>$(PathToRoot)packages\Microsoft.Web.WebView2.1.0.2903.40</WebView2Nuget>
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.2903.40" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Base" version="1.8.250831001" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Foundation" version="1.8.250906002" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.WinUI" version="1.8.250906003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Runtime" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.DWrite" version="1.8.25090401" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.InteractiveExperiences" version="1.8.250906004" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Widgets" version="1.8.250904007" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.AI" version="1.8.37" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.26100.4188" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools.MSIX" version="1.7.20250829.1" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,15 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" />
|
||||
|
||||
|
||||
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
@@ -216,17 +207,11 @@
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost.1.87.0\build\boost.targets" Condition="Exists('..\..\..\..\packages\boost.1.87.0\build\boost.targets')" />
|
||||
<Import Project="..\..\..\..\packages\boost_regex-vc143.1.87.0\build\boost_regex-vc143.targets" Condition="Exists('..\..\..\..\packages\boost_regex-vc143.1.87.0\build\boost_regex-vc143.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
@@ -236,20 +221,8 @@
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost.1.87.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost.1.87.0\build\boost.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\boost_regex-vc143.1.87.0\build\boost_regex-vc143.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\boost_regex-vc143.1.87.0\build\boost_regex-vc143.targets'))" />
|
||||
</Target>
|
||||
|
||||
@@ -6,14 +6,5 @@
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.26100.4188" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Base" version="1.8.250831001" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Foundation" version="1.8.250906002" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.WinUI" version="1.8.250906003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Runtime" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.DWrite" version="1.8.25090401" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.InteractiveExperiences" version="1.8.250906004" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Widgets" version="1.8.250904007" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.AI" version="1.8.37" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools.MSIX" version="1.7.20250829.1" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.7.250513003" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -4,9 +4,6 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
MinWidth="480"
|
||||
MinHeight="320"
|
||||
|
||||
@@ -58,9 +58,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("gliding_delay_speed")]
|
||||
public IntProperty GlidingDelaySpeed { get; set; }
|
||||
|
||||
[JsonPropertyName("gliding_cursor_enabled")]
|
||||
public BoolProperty GlidingCursorEnabled { get; set; }
|
||||
|
||||
public MousePointerCrosshairsProperties()
|
||||
{
|
||||
ActivationShortcut = DefaultActivationShortcut;
|
||||
@@ -77,7 +74,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
AutoActivate = new BoolProperty(false);
|
||||
GlidingTravelSpeed = new IntProperty(25);
|
||||
GlidingDelaySpeed = new IntProperty(5);
|
||||
GlidingCursorEnabled = new BoolProperty(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +181,6 @@ namespace Microsoft.PowerToys.Tools.XamlIndexBuilder
|
||||
// Define namespaces
|
||||
XNamespace x = "http://schemas.microsoft.com/winfx/2006/xaml";
|
||||
XNamespace controls = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
|
||||
XNamespace labs = "using:CommunityToolkit.Labs.WinUI";
|
||||
XNamespace winui = "using:CommunityToolkit.WinUI.UI.Controls";
|
||||
|
||||
// Extract SettingsPageControl elements
|
||||
var settingsPageElements = doc.Descendants()
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Markdown" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
@@ -184,7 +184,7 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="BuildXamlIndexBeforeSettings" BeforeTargets="CoreCompile" Condition="'$(DesignTimeBuild)' != 'true'">
|
||||
<Target Name="BuildXamlIndexBeforeSettings" BeforeTargets="CoreCompile">
|
||||
<Message Importance="high" Text="[Settings] Building XamlIndexBuilder prior to compile. Views='$(MSBuildProjectDirectory)\SettingsXAML\Views' Out='$(GeneratedJsonFile)'" />
|
||||
<MSBuild Projects="..\Settings.UI.XamlIndexBuilder\Settings.UI.XamlIndexBuilder.csproj" Targets="Build" Properties="Configuration=$(Configuration);Platform=Any CPU;TargetFramework=net9.0;XamlViewsDir=$(MSBuildProjectDirectory)\SettingsXAML\Views;GeneratedJsonFile=$(GeneratedJsonFile)" />
|
||||
</Target>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<converters:ColorFormatConverter x:Key="ColorFormatConverter" />
|
||||
@@ -61,7 +61,7 @@
|
||||
</DataTemplate>
|
||||
|
||||
<ItemsPanelTemplate x:Key="ItemPanelTemplate">
|
||||
<tk7controls:WrapPanel
|
||||
<tkcontrols:WrapPanel
|
||||
HorizontalSpacing="20"
|
||||
Orientation="Horizontal"
|
||||
VerticalSpacing="4" />
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
mc:Ignorable="d">
|
||||
@@ -35,7 +35,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<tk7controls:MarkdownTextBlock
|
||||
<tkcontrols:MarkdownTextBlock
|
||||
Grid.Column="1"
|
||||
Margin="8,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
|
||||
@@ -2,16 +2,48 @@
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.Controls.SettingsPageControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:tkconverters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
|
||||
Loaded="UserControl_Loaded"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<x:Double x:Key="PageMaxWidth">1000</x:Double>
|
||||
<x:Double x:Key="PageHeaderMaxWidth">1020</x:Double>
|
||||
<tkconverters:DoubleToVisibilityConverter
|
||||
x:Name="doubleToVisibilityConverter"
|
||||
FalseValue="Collapsed"
|
||||
GreaterThan="0"
|
||||
TrueValue="Visible" />
|
||||
<animations:ImplicitAnimationSet x:Name="ShowTransitions">
|
||||
<animations:OffsetAnimation
|
||||
EasingMode="EaseOut"
|
||||
From="0,24,0"
|
||||
To="0"
|
||||
Duration="0:0:0.4" />
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseOut"
|
||||
From="0"
|
||||
To="1"
|
||||
Duration="0:0:0.2" />
|
||||
</animations:ImplicitAnimationSet>
|
||||
<animations:ImplicitAnimationSet x:Name="HideTransitions">
|
||||
<animations:OffsetAnimation
|
||||
EasingMode="EaseOut"
|
||||
From="0"
|
||||
To="0,24,0"
|
||||
Duration="0:0:0.2" />
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseOut"
|
||||
From="1"
|
||||
To="0"
|
||||
Duration="0:0:0.1" />
|
||||
</animations:ImplicitAnimationSet>
|
||||
<converters:UriToImageSourceConverter x:Key="UriToImageSourceConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid Padding="20,0,0,0" RowSpacing="24">
|
||||
@@ -33,14 +65,16 @@
|
||||
Padding="0,0,20,48"
|
||||
ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
|
||||
RowSpacing="24">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Top panel -->
|
||||
<Grid MaxWidth="{StaticResource PageMaxWidth}" RowSpacing="16">
|
||||
<Grid MaxWidth="{StaticResource PageMaxWidth}" ColumnSpacing="16" RowSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -48,6 +82,7 @@
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
MaxWidth="160"
|
||||
@@ -65,13 +100,12 @@
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind ModuleDescription}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<ItemsControl
|
||||
<ToggleSwitch IsOn="True"/>
|
||||
<ItemsControl Visibility="Collapsed"
|
||||
x:Name="PrimaryLinksControl"
|
||||
Margin="0,8,0,0"
|
||||
IsTabStop="False"
|
||||
ItemsSource="{x:Bind PrimaryLinks}"
|
||||
Visibility="{x:Bind PrimaryLinks.Count, Converter={StaticResource DoubleToVisibilityConverter}}">
|
||||
ItemsSource="{x:Bind PrimaryLinks}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="controls:PageLink">
|
||||
<HyperlinkButton NavigateUri="{x:Bind Link}" Style="{StaticResource TextButtonStyle}">
|
||||
@@ -81,25 +115,81 @@
|
||||
</ItemsControl.ItemTemplate>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<tk7controls:WrapPanel HorizontalSpacing="24" Orientation="Horizontal" />
|
||||
<tkcontrols:WrapPanel HorizontalSpacing="24" Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Content panel -->
|
||||
<ContentPresenter
|
||||
x:Name="ModuleContentPresenter"
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
MaxWidth="{StaticResource PageMaxWidth}"
|
||||
Margin="0,12,0,0"
|
||||
Content="{x:Bind ModuleContent}" />
|
||||
Margin="0,-48,0,0">
|
||||
<SelectorBar x:Name="PivotBar">
|
||||
<SelectorBarItem
|
||||
IsSelected="True"
|
||||
Tag="Settings"
|
||||
Text="Settings" />
|
||||
<SelectorBarItem Tag="Docs" Text="Documentation" />
|
||||
</SelectorBar>
|
||||
</Grid>
|
||||
|
||||
<toolkit:SwitchPresenter
|
||||
Grid.Row="2"
|
||||
MaxWidth="{StaticResource PageMaxWidth}"
|
||||
Value="{Binding SelectedItem.Tag, ElementName=PivotBar}">
|
||||
<toolkit:Case Value="Settings">
|
||||
<!-- Content panel -->
|
||||
<ContentPresenter
|
||||
x:Name="ModuleContentPresenter"
|
||||
Margin="0,12,0,0"
|
||||
Content="{x:Bind ModuleContent}" />
|
||||
</toolkit:Case>
|
||||
<toolkit:Case Value="Docs">
|
||||
<Grid
|
||||
animations:Implicit.HideAnimations="{StaticResource HideTransitions}"
|
||||
animations:Implicit.ShowAnimations="{StaticResource ShowTransitions}"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{StaticResource OverlayCornerRadius}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ListView
|
||||
x:Name="TocList"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="TocList_ItemClick"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock
|
||||
Margin="{Binding Indent}"
|
||||
Tag="{Binding Id}"
|
||||
Text="{Binding Title}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<ScrollViewer
|
||||
x:Name="DocScroll"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
VerticalScrollMode="Auto">
|
||||
<StackPanel x:Name="DocHost" Orientation="Vertical" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
</toolkit:Case>
|
||||
</toolkit:SwitchPresenter>
|
||||
<!-- Bottom panel -->
|
||||
<StackPanel
|
||||
x:Name="SecondaryLinksPanel"
|
||||
Grid.Row="2"
|
||||
Grid.Row="3"
|
||||
MaxWidth="{StaticResource PageMaxWidth}"
|
||||
AutomationProperties.Name="{x:Bind SecondaryLinksHeader}"
|
||||
Orientation="Vertical"
|
||||
@@ -123,7 +213,7 @@
|
||||
</ItemsControl.ItemTemplate>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<tk7controls:WrapPanel HorizontalSpacing="24" Orientation="Horizontal" />
|
||||
<tkcontrols:WrapPanel HorizontalSpacing="24" Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
@@ -142,9 +232,9 @@
|
||||
<AdaptiveTrigger MinWindowWidth="0" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="DescriptionPanel.(Grid.Row)" Value="1" />
|
||||
<!--<Setter Target="DescriptionPanel.(Grid.Row)" Value="1" />
|
||||
<Setter Target="DescriptionPanel.(Grid.Column)" Value="0" />
|
||||
<Setter Target="DescriptionPanel.(Grid.ColumnSpan)" Value="2" />
|
||||
<Setter Target="DescriptionPanel.(Grid.ColumnSpan)" Value="2" />-->
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
|
||||
@@ -3,26 +3,56 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.WinUI.Controls;
|
||||
using Markdig;
|
||||
using Markdig.Syntax;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Windows.Foundation;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
{
|
||||
public sealed partial class SettingsPageControl : UserControl
|
||||
{
|
||||
private readonly Dictionary<string, FrameworkElement> _anchors = new();
|
||||
private readonly MarkdownPipeline _pipeline = new MarkdownPipelineBuilder().UsePreciseSourceLocation().Build();
|
||||
|
||||
// For section flyouts
|
||||
private string _fullMarkdown = string.Empty;
|
||||
|
||||
private sealed class HeadingInfo
|
||||
{
|
||||
#pragma warning disable SA1401 // Fields should be private
|
||||
public string Id = string.Empty;
|
||||
public string Title = string.Empty;
|
||||
public int Level;
|
||||
public int Start;
|
||||
public int End;
|
||||
#pragma warning restore SA1401 // Fields should be private
|
||||
}
|
||||
|
||||
private readonly List<HeadingInfo> _allHeadings = new();
|
||||
|
||||
public SettingsPageControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
PrimaryLinks = new ObservableCollection<PageLink>();
|
||||
SecondaryLinks = new ObservableCollection<PageLink>();
|
||||
}
|
||||
|
||||
public string ModuleTitle
|
||||
{
|
||||
get { return (string)GetValue(ModuleTitleProperty); }
|
||||
set { SetValue(ModuleTitleProperty, value); }
|
||||
get => (string)GetValue(ModuleTitleProperty);
|
||||
set => SetValue(ModuleTitleProperty, value);
|
||||
}
|
||||
|
||||
public string ModuleDescription
|
||||
@@ -45,8 +75,8 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
|
||||
public string SecondaryLinksHeader
|
||||
{
|
||||
get { return (string)GetValue(SecondaryLinksHeaderProperty); }
|
||||
set { SetValue(SecondaryLinksHeaderProperty, value); }
|
||||
get => (string)GetValue(SecondaryLinksHeaderProperty);
|
||||
set => SetValue(SecondaryLinksHeaderProperty, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<PageLink> SecondaryLinks
|
||||
@@ -57,21 +87,471 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
|
||||
public object ModuleContent
|
||||
{
|
||||
get { return (object)GetValue(ModuleContentProperty); }
|
||||
set { SetValue(ModuleContentProperty, value); }
|
||||
get => GetValue(ModuleContentProperty);
|
||||
set => SetValue(ModuleContentProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ModuleTitleProperty = DependencyProperty.Register(nameof(ModuleTitle), typeof(string), typeof(SettingsPageControl), new PropertyMetadata(defaultValue: null));
|
||||
public static readonly DependencyProperty ModuleDescriptionProperty = DependencyProperty.Register(nameof(ModuleDescription), typeof(string), typeof(SettingsPageControl), new PropertyMetadata(defaultValue: null));
|
||||
public static readonly DependencyProperty ModuleImageSourceProperty = DependencyProperty.Register(nameof(ModuleImageSource), typeof(Uri), typeof(SettingsPageControl), new PropertyMetadata(null));
|
||||
public static readonly DependencyProperty PrimaryLinksProperty = DependencyProperty.Register(nameof(PrimaryLinks), typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
|
||||
public static readonly DependencyProperty SecondaryLinksHeaderProperty = DependencyProperty.Register(nameof(SecondaryLinksHeader), typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||
public static readonly DependencyProperty SecondaryLinksProperty = DependencyProperty.Register(nameof(SecondaryLinks), typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
|
||||
public static readonly DependencyProperty ModuleContentProperty = DependencyProperty.Register(nameof(ModuleContent), typeof(object), typeof(SettingsPageControl), new PropertyMetadata(new Grid()));
|
||||
public static readonly DependencyProperty ModuleTitleProperty =
|
||||
DependencyProperty.Register(nameof(ModuleTitle), typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||
|
||||
public static readonly DependencyProperty ModuleDescriptionProperty =
|
||||
DependencyProperty.Register(nameof(ModuleDescription), typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||
|
||||
public static readonly DependencyProperty ModuleImageSourceProperty =
|
||||
DependencyProperty.Register(nameof(ModuleImageSource), typeof(Uri), typeof(SettingsPageControl), new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty PrimaryLinksProperty =
|
||||
DependencyProperty.Register(nameof(PrimaryLinks), typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
|
||||
|
||||
public static readonly DependencyProperty SecondaryLinksHeaderProperty =
|
||||
DependencyProperty.Register(nameof(SecondaryLinksHeader), typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||
|
||||
public static readonly DependencyProperty SecondaryLinksProperty =
|
||||
DependencyProperty.Register(nameof(SecondaryLinks), typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
|
||||
|
||||
public static readonly DependencyProperty ModuleContentProperty =
|
||||
DependencyProperty.Register(nameof(ModuleContent), typeof(object), typeof(SettingsPageControl), new PropertyMetadata(new Grid()));
|
||||
|
||||
private void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PrimaryLinksControl.Focus(FocusState.Programmatic);
|
||||
_ = LoadAndRenderAsync("https://raw.githubusercontent.com/MicrosoftDocs/windows-dev-docs/refs/heads/docs/hub/powertoys/advanced-paste.md");
|
||||
}
|
||||
|
||||
private sealed class TocItem
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
|
||||
public string Title { get; init; } = string.Empty;
|
||||
|
||||
public int Level { get; init; }
|
||||
}
|
||||
|
||||
private async Task LoadAndRenderAsync(string requestUrl)
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
var raw = await client.GetStringAsync(requestUrl);
|
||||
|
||||
// Preprocess with knowledge of the file URL (so we resolve ../images/...)
|
||||
var md = PreprocessMarkdown(raw, requestUrl);
|
||||
|
||||
var tocItems = BuildDocumentAndAnchors(md);
|
||||
|
||||
// Bind ToC (indent H2/H3 a bit)
|
||||
TocList.ItemsSource = tocItems.Select(i => new
|
||||
{
|
||||
i.Id,
|
||||
i.Title,
|
||||
Indent = new Thickness((i.Level - 1) * 12, 6, 8, 6),
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private List<TocItem> BuildDocumentAndAnchors(string md)
|
||||
{
|
||||
_fullMarkdown = md;
|
||||
DocHost.Children.Clear();
|
||||
_anchors.Clear();
|
||||
_allHeadings.Clear();
|
||||
|
||||
var doc = Markdig.Markdown.Parse(md, _pipeline);
|
||||
|
||||
// Build slugs for ALL headings (H1..H6) so section flyouts can target any level
|
||||
var rawHeadings = doc.Descendants<HeadingBlock>().ToList();
|
||||
var seen = new Dictionary<string, int>();
|
||||
|
||||
foreach (var hb in rawHeadings)
|
||||
{
|
||||
string title = hb.Inline?.FirstChild?.ToString() ?? "Section";
|
||||
string id = MakeSlug(title);
|
||||
|
||||
if (seen.TryGetValue(id, out int n))
|
||||
{
|
||||
n++;
|
||||
seen[id] = n;
|
||||
id = $"{id}-{n}";
|
||||
}
|
||||
else
|
||||
{
|
||||
seen[id] = 1;
|
||||
}
|
||||
|
||||
_allHeadings.Add(new HeadingInfo
|
||||
{
|
||||
Id = id,
|
||||
Title = title,
|
||||
Level = hb.Level,
|
||||
Start = hb.Span.Start,
|
||||
End = md.Length, // fixed below
|
||||
});
|
||||
}
|
||||
|
||||
// Compute section End = next heading with level <= current level (or EOF)
|
||||
for (int i = 0; i < _allHeadings.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < _allHeadings.Count; j++)
|
||||
{
|
||||
if (_allHeadings[j].Level <= _allHeadings[i].Level)
|
||||
{
|
||||
_allHeadings[i].End = _allHeadings[j].Start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render the document in H2/H3 chunks for this UI
|
||||
var headings = _allHeadings.Where(h => h.Level is 2 or 3).ToList();
|
||||
var toc = new List<TocItem>();
|
||||
|
||||
if (headings.Count == 0)
|
||||
{
|
||||
DocHost.Children.Add(new MarkdownTextBlock { Text = md });
|
||||
return toc;
|
||||
}
|
||||
|
||||
foreach (var h in headings)
|
||||
{
|
||||
toc.Add(new TocItem { Id = h.Id, Title = h.Title, Level = h.Level });
|
||||
|
||||
// Invisible anchor just before the rendered section
|
||||
var anchor = new Border { Height = 0, Opacity = 0, Tag = h.Id };
|
||||
DocHost.Children.Add(anchor);
|
||||
_anchors[h.Id] = anchor;
|
||||
|
||||
// Render this section’s markdown (include heading line)
|
||||
string sectionMd = md.Substring(h.Start, h.End - h.Start);
|
||||
var mdtb = new MarkdownTextBlock { Text = sectionMd };
|
||||
|
||||
// NOTE: some toolkit versions use LinkClicked; you used OnLinkClicked in your snippet.
|
||||
// Keep your version:
|
||||
mdtb.OnLinkClicked += Markdown_LinkClicked;
|
||||
|
||||
DocHost.Children.Add(mdtb);
|
||||
}
|
||||
|
||||
return toc;
|
||||
}
|
||||
|
||||
private void Markdown_LinkClicked(object sender, CommunityToolkit.WinUI.Controls.LinkClickedEventArgs e)
|
||||
{
|
||||
var uri = e.Uri;
|
||||
if (uri is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string anchorId = null;
|
||||
|
||||
#pragma warning disable CA1310 // Specify StringComparison for correctness
|
||||
#pragma warning disable CA1866 // Use char overload
|
||||
if (!uri.IsAbsoluteUri && uri.OriginalString.StartsWith("#"))
|
||||
{
|
||||
anchorId = uri.OriginalString.TrimStart('#');
|
||||
}
|
||||
else if (uri.IsAbsoluteUri && !string.IsNullOrEmpty(uri.Fragment))
|
||||
{
|
||||
anchorId = uri.Fragment.TrimStart('#');
|
||||
}
|
||||
#pragma warning restore CA1866 // Use char overload
|
||||
#pragma warning restore CA1310 // Specify StringComparison for correctness
|
||||
|
||||
if (!string.IsNullOrEmpty(anchorId) && _anchors.TryGetValue(anchorId, out _))
|
||||
{
|
||||
ScrollToAnchor(anchorId, TopOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
_ = Launcher.LaunchUriAsync(uri);
|
||||
}
|
||||
|
||||
private const double TopOffset = 40; // pixels
|
||||
|
||||
// Click in ToC -> scroll to anchor
|
||||
private void TocList_ItemClick(object sender, ItemClickEventArgs e)
|
||||
{
|
||||
if (e.ClickedItem is FrameworkElement fe && fe.Tag is string id)
|
||||
{
|
||||
ScrollToAnchor(id, TopOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
var idProp = e.ClickedItem?.GetType().GetProperty("Id")?.GetValue(e.ClickedItem) as string;
|
||||
if (!string.IsNullOrEmpty(idProp))
|
||||
{
|
||||
ScrollToAnchor(idProp!, TopOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollToAnchor(string id, double topOffset = 0)
|
||||
{
|
||||
if (_anchors.TryGetValue(id, out var target))
|
||||
{
|
||||
var opts = new BringIntoViewOptions
|
||||
{
|
||||
VerticalAlignmentRatio = 0.0,
|
||||
HorizontalAlignmentRatio = 0.0,
|
||||
AnimationDesired = true,
|
||||
};
|
||||
target.StartBringIntoView(opts);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Public API: show a section in a flyout (for any H1..H6)
|
||||
// ----------------------------
|
||||
public bool TryShowSectionFlyout(FrameworkElement placementTarget, string sectionId, bool includeHeading = false, FlyoutPlacementMode placement = FlyoutPlacementMode.Bottom)
|
||||
{
|
||||
if (placementTarget is null || string.IsNullOrWhiteSpace(sectionId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var h = _allHeadings.FirstOrDefault(x => string.Equals(x.Id, sectionId, StringComparison.OrdinalIgnoreCase));
|
||||
if (h is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var slice = _fullMarkdown.Substring(h.Start, h.End - h.Start);
|
||||
if (!includeHeading)
|
||||
{
|
||||
int nl = slice.IndexOf('\n');
|
||||
slice = nl >= 0 ? slice[(nl + 1)..] : string.Empty;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(slice))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var title = new TextBlock
|
||||
{
|
||||
Text = h.Title,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Margin = new Thickness(0, 0, 0, 8),
|
||||
Style = (Style)Application.Current.Resources["SubtitleTextBlockStyle"],
|
||||
};
|
||||
|
||||
var body = new MarkdownTextBlock { Text = slice };
|
||||
body.OnLinkClicked += Markdown_LinkClicked;
|
||||
|
||||
var content = new StackPanel { MinWidth = 320, MaxWidth = 560 };
|
||||
content.Children.Add(title);
|
||||
content.Children.Add(new ScrollViewer
|
||||
{
|
||||
Content = body,
|
||||
MaxHeight = 420,
|
||||
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
|
||||
});
|
||||
|
||||
var flyout = new Microsoft.UI.Xaml.Controls.Flyout { Content = content, Placement = placement };
|
||||
flyout.ShowAt(placementTarget);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Markdown preprocessor (MS Learn → standard Markdown)
|
||||
// ----------------------------
|
||||
public static string PreprocessMarkdown(string markdown, string sourceFileUrl)
|
||||
{
|
||||
// Compute the *directory* of the md file (guaranteed trailing slash)
|
||||
var baseDir = new Uri(new Uri(sourceFileUrl), ".");
|
||||
|
||||
string Resolve(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
return new Uri(baseDir, url).ToString();
|
||||
}
|
||||
|
||||
// 1) Strip YAML front matter at the very top
|
||||
markdown = Regex.Replace(
|
||||
markdown,
|
||||
pattern: @"\A---\s*[\s\S]*?^\s*---\s*$\r?\n?",
|
||||
replacement: string.Empty,
|
||||
options: RegexOptions.Multiline);
|
||||
|
||||
// 2) Remove specific Learn notice (example you had)
|
||||
markdown = Regex.Replace(
|
||||
markdown,
|
||||
@"^>\s*\[!IMPORTANT\]\s*> - Phi Silica is not available in China\.\s*$\r?\n?",
|
||||
string.Empty,
|
||||
RegexOptions.Multiline | RegexOptions.IgnoreCase);
|
||||
|
||||
// 3) Convert Learn admonitions to simpler blockquotes with icons
|
||||
var admonitions = new (string Pattern, string Replacement)[]
|
||||
{
|
||||
(@"^>\s*\[!IMPORTANT\]", "> **ℹ️ Important:**"),
|
||||
(@"^>\s*\[!NOTE\]", "> **❗ Note:**"),
|
||||
(@"^>\s*\[!TIP\]", "> **💡 Tip:**"),
|
||||
(@"^>\s*\[!WARNING\]", "> **⚠️ Warning:**"),
|
||||
(@"^>\s*\[!CAUTION\]", "> **⚠️ Caution:**"),
|
||||
};
|
||||
foreach (var (pat, rep) in admonitions)
|
||||
markdown = Regex.Replace(markdown, pat, rep, RegexOptions.Multiline | RegexOptions.IgnoreCase);
|
||||
|
||||
// 4) Convert :::image ... ::: blocks
|
||||
markdown = Regex.Replace(
|
||||
markdown,
|
||||
@":::image\s+(?<attrs>.*?):::",
|
||||
m =>
|
||||
{
|
||||
string attrs = m.Groups["attrs"].Value;
|
||||
|
||||
static string A(string attrs, string name)
|
||||
{
|
||||
var mm = Regex.Match(attrs, $@"\b{name}\s*=\s*""([^""]*)""", RegexOptions.IgnoreCase);
|
||||
return mm.Success ? mm.Groups[1].Value : string.Empty;
|
||||
}
|
||||
|
||||
string src = A(attrs, "source");
|
||||
string alt = A(attrs, "alt-text");
|
||||
string lightbox = A(attrs, "lightbox");
|
||||
string link = A(attrs, "link");
|
||||
|
||||
src = Resolve(src);
|
||||
lightbox = Resolve(lightbox);
|
||||
link = Resolve(link);
|
||||
|
||||
var img = $"![{alt}]";
|
||||
if (!string.IsNullOrWhiteSpace(src))
|
||||
{
|
||||
img += $"({src})";
|
||||
}
|
||||
|
||||
var href = !string.IsNullOrWhiteSpace(link) ? link : lightbox;
|
||||
if (!string.IsNullOrWhiteSpace(href))
|
||||
{
|
||||
img = $"[{img}]({href})";
|
||||
}
|
||||
|
||||
return img + "\n";
|
||||
},
|
||||
RegexOptions.Singleline | RegexOptions.IgnoreCase);
|
||||
|
||||
// 5) Resolve relative links in standard markdown
|
||||
markdown = Regex.Replace(
|
||||
markdown,
|
||||
@"\]\((?!https?://|mailto:|data:|#)(?<rel>[^)]+)\)",
|
||||
m =>
|
||||
{
|
||||
var rel = m.Groups["rel"].Value.Trim();
|
||||
var abs = Resolve(rel);
|
||||
return $"]({abs})";
|
||||
});
|
||||
|
||||
return markdown;
|
||||
}
|
||||
|
||||
private static string MakeSlug(string s)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
return "section";
|
||||
}
|
||||
|
||||
var slug = s.Trim().ToLowerInvariant();
|
||||
slug = Regex.Replace(slug, @"[^\p{L}\p{Nd}\s-]", string.Empty);
|
||||
slug = Regex.Replace(slug, @"\s+", "-");
|
||||
slug = Regex.Replace(slug, @"-+", "-");
|
||||
return slug;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Attached property: set DocSectionFlyout.SectionId on any Button
|
||||
// inside ModuleContent, and it will open a flyout for that section.
|
||||
// ------------------------------------------------------------
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
public static class DocSectionFlyout
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
{
|
||||
public static readonly DependencyProperty SectionIdProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"SectionId",
|
||||
typeof(string),
|
||||
typeof(DocSectionFlyout),
|
||||
new PropertyMetadata(null, OnSectionIdChanged));
|
||||
|
||||
public static void SetSectionId(DependencyObject obj, string value) => obj.SetValue(SectionIdProperty, value);
|
||||
|
||||
public static string GetSectionId(DependencyObject obj) => (string)obj.GetValue(SectionIdProperty);
|
||||
|
||||
public static readonly DependencyProperty IncludeHeadingProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"IncludeHeading",
|
||||
typeof(bool),
|
||||
typeof(DocSectionFlyout),
|
||||
new PropertyMetadata(false));
|
||||
|
||||
public static void SetIncludeHeading(DependencyObject obj, bool value) => obj.SetValue(IncludeHeadingProperty, value);
|
||||
|
||||
public static bool GetIncludeHeading(DependencyObject obj) => (bool)obj.GetValue(IncludeHeadingProperty);
|
||||
|
||||
public static readonly DependencyProperty PlacementProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"Placement",
|
||||
typeof(FlyoutPlacementMode),
|
||||
typeof(DocSectionFlyout),
|
||||
new PropertyMetadata(FlyoutPlacementMode.Bottom));
|
||||
|
||||
public static void SetPlacement(DependencyObject obj, FlyoutPlacementMode value) => obj.SetValue(PlacementProperty, value);
|
||||
|
||||
public static FlyoutPlacementMode GetPlacement(DependencyObject obj) => (FlyoutPlacementMode)obj.GetValue(PlacementProperty);
|
||||
|
||||
private static void OnSectionIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is ButtonBase btn)
|
||||
{
|
||||
btn.Click -= Button_Click;
|
||||
if (e.NewValue is string { Length: > 0 })
|
||||
{
|
||||
btn.Click += Button_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not FrameworkElement fe)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find nearest SettingsPageControl ancestor
|
||||
var parent = fe as DependencyObject;
|
||||
SettingsPageControl host = null;
|
||||
while (parent is not null)
|
||||
{
|
||||
parent = VisualTreeHelper.GetParent(parent);
|
||||
if (parent is SettingsPageControl spc)
|
||||
{
|
||||
host = spc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (host is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var id = GetSectionId(fe);
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var includeHeading = GetIncludeHeading(fe);
|
||||
var placement = GetPlacement(fe);
|
||||
|
||||
host.TryShowSectionFlyout(fe, id, includeHeading, placement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
x:Name="ShortcutContentControl"
|
||||
mc:Ignorable="d">
|
||||
<Grid MinWidth="498" MinHeight="220">
|
||||
@@ -71,9 +71,8 @@
|
||||
Message="{Binding ElementName=ShortcutContentControl, Path=ConflictMessage, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</Grid>
|
||||
<tk7controls:MarkdownTextBlock
|
||||
<tkcontrols:MarkdownTextBlock
|
||||
x:Uid="InvalidShortcutWarningLabel"
|
||||
Background="Transparent"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
</StackPanel>
|
||||
|
||||