Compare commits

..

6 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
6d98056db3 Refine ImageResizer context menu logic to always hide MSIX handler preventing duplicates
Co-authored-by: cinnamon-msft <48369326+cinnamon-msft@users.noreply.github.com>
2025-06-13 19:08:46 +00:00
copilot-swe-agent[bot]
2a275ac1cb Add extended context menu setting to ImageResizer to fix duplicate entries
Co-authored-by: cinnamon-msft <48369326+cinnamon-msft@users.noreply.github.com>
2025-06-13 19:06:33 +00:00
copilot-swe-agent[bot]
406faa4f0d Initial plan for issue 2025-06-13 18:54:04 +00:00
Davide Giacometti
6f68f5f34a [CmdPal] Fix and localize alias settings (#39708)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

Fixes alias settings and add localization for Direct/Indirect.


![Animation](https://github.com/user-attachments/assets/64780f64-f695-4e34-9b90-828ec456c6d3)

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #39569
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end user facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

Manually tested
2025-06-13 19:58:33 +02:00
Davide Giacometti
aa8cfd505a [CmdPal] Close Gracefully (#39589)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

CmdPal is leaking extensions processes as the process is immediately
killed.
This PR fixes the 1.5s wait for the process to end correctly and also
close extensions.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end user facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

- Verified that if CmdPal closes in 1.5s, extensions and process are
closed (note that GitHub extension doesn't close probably due to
https://github.com/microsoft/PowerToys/pull/39209)
- Verified that if CmdPal doesn't close in 1.5s the process is killed
and extensions aren't closed (tested adding a delay in the code)
2025-06-13 19:57:40 +02:00
Gordon Lam
349de60e47 Include all the Unittest as part of CI pipeline (#40024)
Include all the UnitTest as part of CI pipeline.

The results are promising:
a. All tests passed
b. No noticeable increase in execution time
c. Additional modules are now covered, including Settings, Color Picker,
Peek, Run V1, and others.
 
Here is all ~5000 Unittests - [Pipelines - Run PowerToys
CI_2506.12022](https://dev.azure.com/shine-oss/PowerToys/_build/results?buildId=133714&view=ms.vss-test-web.build-test-results-tab)
Here is the original ~3000 Unittests - [Pipelines - Run PowerToys
CI_2506.12021](https://dev.azure.com/shine-oss/PowerToys/_build/results?buildId=133677&view=ms.vss-test-web.build-test-results-tab)

Co-authored-by: Kai Tao <69313318+vanzue@users.noreply.github.com>
2025-06-13 08:59:25 -07:00
15 changed files with 86 additions and 18 deletions

View File

@@ -394,10 +394,7 @@ jobs:
testAssemblyVer2: |
**\KeyboardManagerEngineTest.dll
**\KeyboardManagerEditorTest.dll
**\UnitTests-CommonLib.dll
**\PowerRenameUnitTests.dll
**\UnitTests-FancyZones.dll
**\\WorkspacesLibUnitTests.dll
**\*UnitTest*.dll
!**\obj\**
- pwsh: |-

View File

@@ -133,11 +133,6 @@
<ImportGroup Label="ExtensionTargets">
<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')" />
</ImportGroup>
<ItemGroup>
<ProjectReference Include="..\version\version.vcxproj">
<Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>
</ProjectReference>
</ItemGroup>
<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>

View File

@@ -117,16 +117,18 @@ private:
for (DWORD pid : processIds)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, pid);
if (hProcess != NULL)
{
SetEvent(m_hTerminateEvent);
// Wait for 1.5 seconds for the process to end correctly and stop etw tracer
WaitForSingleObject(hProcess, 1500);
// Wait for 1.5 seconds for the process to end correctly, allowing time for ETW tracer and extensions to stop
if (WaitForSingleObject(hProcess, 1500) == WAIT_TIMEOUT)
{
TerminateProcess(hProcess, 0);
}
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
}

View File

@@ -102,6 +102,8 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
}
HandleChangeAlias();
OnPropertyChanged(nameof(AliasText));
OnPropertyChanged(nameof(IsDirectAlias));
}
}
@@ -116,6 +118,7 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
}
HandleChangeAlias();
OnPropertyChanged(nameof(IsDirectAlias));
}
}

View File

@@ -67,6 +67,7 @@ public partial class App : Application
"Local\\PowerToysCmdPal-ExitEvent-eb73f6be-3f22-4b36-aee3-62924ba40bfd", () =>
{
EtwTrace?.Dispose();
AppWindow?.Close();
Environment.Exit(0);
});
}

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Microsoft.CmdPal.UI.Settings.ExtensionPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -92,12 +92,11 @@
<controls:SettingsCard x:Uid="Settings_ExtensionPage_Alias_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=&#xE8AC;}">
<StackPanel Orientation="Vertical">
<TextBox Text="{x:Bind AliasText, Mode=TwoWay}" />
<TextBox Text="{x:Bind AliasText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ToggleSwitch
x:Uid="Settings_ExtensionPage_Alias_ToggleSwitch"
IsEnabled="{x:Bind AliasText, Converter={StaticResource StringEmptyToBoolConverter}, Mode=OneWay}"
IsOn="{x:Bind IsDirectAlias, Mode=TwoWay}"
OffContent="Indirect"
OnContent="Direct" />
IsOn="{x:Bind IsDirectAlias, Mode=TwoWay}" />
</StackPanel>
</controls:SettingsCard>

View File

@@ -418,4 +418,10 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<data name="TrayMenu_Exit" xml:space="preserve">
<value>Exit</value>
</data>
<data name="Settings_ExtensionPage_Alias_ToggleSwitch.OnContent" xml:space="preserve">
<value>Direct</value>
</data>
<data name="Settings_ExtensionPage_Alias_ToggleSwitch.OffContent" xml:space="preserve">
<value>Indirect</value>
</data>
</root>

View File

@@ -89,6 +89,11 @@ public:
*cmdState = ECS_HIDDEN;
return S_OK;
}
// Hide MSIX handler to prevent duplicate context menu entries
// The traditional handler provides the context menu functionality
*cmdState = ECS_HIDDEN;
return S_OK;
// Hide if the file is not an image
*cmdState = ECS_HIDDEN;
// Suppressing C26812 warning as the issue is in the shtypes.h library

View File

@@ -63,6 +63,7 @@ CSettings::CSettings()
void CSettings::Save()
{
json::JsonObject jsonData;
jsonData.SetNamedValue(L"extendedContextMenuOnly", json::value(settings.extendedContextMenuOnly));
json::to_file(jsonFilePath, jsonData);
GetSystemTimeAsFileTime(&lastLoadedTime);
@@ -133,6 +134,7 @@ void CSettings::ParseJson()
try
{
// NB: add any new settings here
json::get(jsonSettings, L"extendedContextMenuOnly", settings.extendedContextMenuOnly, false);
}
catch (const winrt::hresult_error&)
{

View File

@@ -19,6 +19,16 @@ public:
return settings.enabled;
}
inline bool GetExtendedContextMenuOnly() const
{
return settings.extendedContextMenuOnly;
}
inline void SetExtendedContextMenuOnly(bool extendedOnly)
{
settings.extendedContextMenuOnly = extendedOnly;
}
void Save();
void Load();
@@ -26,6 +36,7 @@ private:
struct Settings
{
bool enabled{ true };
bool extendedContextMenuOnly{ false }; // Disabled by default.
};
void RefreshEnabledState();

View File

@@ -70,6 +70,10 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
if (!CSettingsInstance().GetEnabled())
return E_FAIL;
// Check if we should only be on the extended context menu
if (CSettingsInstance().GetExtendedContextMenuOnly() && (!(uFlags & CMF_EXTENDEDVERBS)))
return E_FAIL;
// NB: We just check the first item. We could iterate through more if the first one doesn't meet the criteria
HDropIterator i(m_pdtobj);
i.First();

View File

@@ -27,6 +27,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
ImageresizerKeepDateModified = new BoolProperty();
ImageresizerFallbackEncoder = new StringProperty(new System.Guid("19e4a5aa-5662-4fc5-a0c0-1758028e1057").ToString());
ImageresizerCustomSize = new ImageResizerCustomSizeProperty(new ImageSize(4, "custom", ResizeFit.Fit, 1024, 640, ResizeUnit.Pixel));
ImageresizerExtendedContextMenuOnly = new BoolProperty(false);
}
public ImageResizerProperties(Func<string, string> resourceLoader)
@@ -84,6 +85,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[CmdConfigureIgnoreAttribute]
public ImageResizerCustomSizeProperty ImageresizerCustomSize { get; set; }
[JsonPropertyName("imageresizer_extendedContextMenuOnly")]
public BoolProperty ImageresizerExtendedContextMenuOnly { get; set; }
public string ToJsonString()
{
return JsonSerializer.Serialize(this);

View File

@@ -48,6 +48,21 @@
</InfoBar.IconSource>
</InfoBar>
<controls:SettingsGroup x:Uid="ImageResizer_ShellIntegration" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsExpander x:Uid="ImageResizer_Toggle_ContextMenu" IsExpanded="False">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind ViewModel.ExtendedContextMenuOnly, Mode=TwoWay, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="ImageResizer_Toggle_StandardContextMenu" />
<ComboBoxItem x:Uid="ImageResizer_Toggle_ExtendedContextMenu" />
</ComboBox>
</tkcontrols:SettingsExpander>
<InfoBar
x:Uid="ExtendedContextMenuInfo"
IsClosable="False"
IsOpen="True"
IsTabStop="False"
Severity="Informational" />
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="ImageResizer_CustomSizes" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsCard x:Uid="ImageResizer_Presets" HeaderIcon="{ui:FontIcon Glyph=&#xE792;}">
<Button

View File

@@ -1406,6 +1406,18 @@
<data name="ImageResizer_UseResizeDate.Content" xml:space="preserve">
<value>Timestamp of resize action</value>
</data>
<data name="ImageResizer_ShellIntegration.Header" xml:space="preserve">
<value>Shell integration</value>
</data>
<data name="ImageResizer_Toggle_ContextMenu.Header" xml:space="preserve">
<value>Show Image Resizer in</value>
</data>
<data name="ImageResizer_Toggle_StandardContextMenu.Content" xml:space="preserve">
<value>Default and extended context menu</value>
</data>
<data name="ImageResizer_Toggle_ExtendedContextMenu.Content" xml:space="preserve">
<value>Extended context menu only</value>
</data>
<data name="Encoding.Header" xml:space="preserve">
<value>Encoding</value>
</data>

View File

@@ -94,6 +94,7 @@ public partial class ImageResizerViewModel : Observable
FileName = Settings.Properties.ImageresizerFileName.Value;
KeepDateModified = Settings.Properties.ImageresizerKeepDateModified.Value;
Encoder = GetEncoderIndex(Settings.Properties.ImageresizerFallbackEncoder.Value);
ExtendedContextMenuOnly = Settings.Properties.ImageresizerExtendedContextMenuOnly.Value;
_customSize = Settings.Properties.ImageresizerCustomSize.Value;
@@ -125,6 +126,7 @@ public partial class ImageResizerViewModel : Observable
private string _fileName;
private bool _keepDateModified;
private int _encoderGuidId;
private bool _extendedContextMenuOnly;
public bool IsListViewFocusRequested { get; set; }
@@ -285,6 +287,16 @@ public partial class ImageResizerViewModel : Observable
}
}
public bool ExtendedContextMenuOnly
{
get => _extendedContextMenuOnly;
set
{
SetProperty(ref _extendedContextMenuOnly, value, v => Settings.Properties.ImageresizerExtendedContextMenuOnly.Value = v);
}
}
public int Encoder
{
get => _encoderGuidId;