mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
CmdPal: Improvements and fixes for icon loading (#45460)
## Summary of the Pull Request This PR is a follow-up for Icon cache: - Adds decoding and rasterization limit (by width) to reduce memory usage and improves throughput (noticeably) - Fixes timing issue when setting padding for font icons - Resolves race condition in IconBox caused by incorrect guard <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #45460 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the 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
This commit is contained in:
@@ -16,12 +16,12 @@ namespace Microsoft.CmdPal.UI.Controls;
|
||||
/// </summary>
|
||||
public partial class IconBox : ContentControl
|
||||
{
|
||||
private const double DefaultIconFontSize = 16.0;
|
||||
|
||||
private double _lastScale;
|
||||
private ElementTheme _lastTheme;
|
||||
private double _lastFontSize;
|
||||
|
||||
private const double DefaultIconFontSize = 16.0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IconSource"/> to display within the <see cref="IconBox"/>. Overwritten, if <see cref="SourceKey"/> is used instead.
|
||||
/// </summary>
|
||||
@@ -62,6 +62,12 @@ public partial class IconBox : ContentControl
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
#if DEBUG
|
||||
if (_sourceRequested?.GetInvocationList().Length > 1)
|
||||
{
|
||||
Logger.LogWarning("There shouldn't be more than one handler for IconBox.SourceRequested");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
remove => _sourceRequested -= value;
|
||||
}
|
||||
@@ -102,9 +108,12 @@ public partial class IconBox : ContentControl
|
||||
if (Source is FontIconSource fontIcon)
|
||||
{
|
||||
fontIcon.FontSize = _lastFontSize;
|
||||
UpdatePaddingForFontIcon();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePaddingForFontIcon() => Padding = new Thickness(Math.Round(_lastFontSize * -0.2));
|
||||
|
||||
private void OnActualThemeChanged(FrameworkElement sender, object args)
|
||||
{
|
||||
if (_lastTheme == ActualTheme)
|
||||
@@ -150,10 +159,7 @@ public partial class IconBox : ContentControl
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
if (SourceKey is not null)
|
||||
{
|
||||
UpdateSourceKey(this, SourceKey);
|
||||
}
|
||||
UpdateSourceKey(this, SourceKey);
|
||||
}
|
||||
|
||||
private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
@@ -170,8 +176,10 @@ public partial class IconBox : ContentControl
|
||||
self.Padding = default;
|
||||
break;
|
||||
case FontIconSource fontIcon:
|
||||
self.UpdateLastFontSize();
|
||||
if (self.Content is IconSourceElement iconSourceElement)
|
||||
{
|
||||
fontIcon.FontSize = self._lastFontSize;
|
||||
iconSourceElement.IconSource = fontIcon;
|
||||
}
|
||||
else
|
||||
@@ -190,7 +198,7 @@ public partial class IconBox : ContentControl
|
||||
self.Content = elem;
|
||||
}
|
||||
|
||||
self.Padding = new Thickness(Math.Round(self._lastFontSize * -0.2));
|
||||
self.UpdatePaddingForFontIcon();
|
||||
|
||||
break;
|
||||
case BitmapIconSource bitmapIcon:
|
||||
@@ -206,10 +214,12 @@ public partial class IconBox : ContentControl
|
||||
self.Padding = default;
|
||||
|
||||
break;
|
||||
|
||||
case IconSource source:
|
||||
self.Content = source.CreateIconElement();
|
||||
self.Padding = default;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException($"New value of {e.NewValue} is not of type IconSource.");
|
||||
}
|
||||
@@ -233,10 +243,10 @@ public partial class IconBox : ContentControl
|
||||
return;
|
||||
}
|
||||
|
||||
Callback(iconBox, sourceKey);
|
||||
RequestIconFromSource(iconBox, sourceKey);
|
||||
}
|
||||
|
||||
private static async void Callback(IconBox iconBox, object? sourceKey)
|
||||
private static async void RequestIconFromSource(IconBox iconBox, object? sourceKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -256,17 +266,12 @@ public partial class IconBox : ContentControl
|
||||
// list virtualization situation, it's very possible we
|
||||
// may have already been set to a new icon before we
|
||||
// even got back from the await.
|
||||
if (eventArgs.Key != sourceKey)
|
||||
if (!ReferenceEquals(sourceKey, iconBox.SourceKey))
|
||||
{
|
||||
// If the requested icon has changed, then just bail
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventArgs.Value == iconBox.Source)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iconBox.Source = eventArgs.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -219,6 +219,6 @@ internal sealed partial class IconLoaderService : IIconLoaderService
|
||||
iconSize = DefaultIconSize;
|
||||
}
|
||||
|
||||
return IconPathConverter.IconSourceMUX(iconString, false, fontFamily, iconSize);
|
||||
return IconPathConverter.IconSourceMUX(iconString, fontFamily, iconSize);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user