mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 04:00:02 +01:00
CmdPal: Fix SUI crash ; Allow extensions to be disabled (#38040)
Both `TopLevelCommandItemWrapper` and `TopLevelViewModel` were really the same thing. The latter was from an earlier prototype, and the former is a more correct, safer abstraction. We really should have only ever used the former, but alas, we only used it for the SUI, and it piggy-backed off the latter, and that meant the latter's bugs became the former's. tldr: I made the icon access safe in the SUI. And while I was doing this, because we now have a cleaner VM abstraction here in the host, we can actually cleanly disable extensions, because the `CommandProviderWrapper` knows which `ViewModel`s it made. Closes https://github.com/zadjii-msft/PowerToys/issues/426 Closes https://github.com/zadjii-msft/PowerToys/issues/478 Closes https://github.com/zadjii-msft/PowerToys/issues/577
This commit is contained in:
@@ -4,7 +4,10 @@
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Common.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Properties;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
@@ -14,14 +17,13 @@ public partial class ProviderSettingsViewModel(
|
||||
ProviderSettings _providerSettings,
|
||||
IServiceProvider _serviceProvider) : ObservableObject
|
||||
{
|
||||
private readonly TopLevelCommandManager _tlcManager = _serviceProvider.GetService<TopLevelCommandManager>()!;
|
||||
private readonly SettingsModel _settings = _serviceProvider.GetService<SettingsModel>()!;
|
||||
|
||||
public string DisplayName => _provider.DisplayName;
|
||||
|
||||
public string ExtensionName => _provider.Extension?.ExtensionDisplayName ?? "Built-in";
|
||||
|
||||
public string ExtensionSubtext => $"{ExtensionName}, {TopLevelCommands.Count} commands";
|
||||
public string ExtensionSubtext => IsEnabled ? $"{ExtensionName}, {TopLevelCommands.Count} commands" : Resources.builtin_disabled_extension;
|
||||
|
||||
[MemberNotNullWhen(true, nameof(Extension))]
|
||||
public bool IsFromExtension => _provider.Extension != null;
|
||||
@@ -35,7 +37,29 @@ public partial class ProviderSettingsViewModel(
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => _providerSettings.IsEnabled;
|
||||
set => _providerSettings.IsEnabled = value;
|
||||
set
|
||||
{
|
||||
if (value != _providerSettings.IsEnabled)
|
||||
{
|
||||
_providerSettings.IsEnabled = value;
|
||||
Save();
|
||||
WeakReferenceMessenger.Default.Send<ReloadCommandsMessage>(new());
|
||||
OnPropertyChanged(nameof(IsEnabled));
|
||||
OnPropertyChanged(nameof(ExtensionSubtext));
|
||||
}
|
||||
|
||||
if (value == true)
|
||||
{
|
||||
_provider.CommandsChanged -= Provider_CommandsChanged;
|
||||
_provider.CommandsChanged += Provider_CommandsChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Provider_CommandsChanged(CommandProviderWrapper sender, CommandPalette.Extensions.IItemsChangedEventArgs args)
|
||||
{
|
||||
OnPropertyChanged(nameof(ExtensionSubtext));
|
||||
OnPropertyChanged(nameof(TopLevelCommands));
|
||||
}
|
||||
|
||||
public bool HasSettings => _provider.Settings != null && _provider.Settings.SettingsPage != null;
|
||||
@@ -58,24 +82,12 @@ public partial class ProviderSettingsViewModel(
|
||||
|
||||
private List<TopLevelViewModel> BuildTopLevelViewModels()
|
||||
{
|
||||
var topLevelCommands = _tlcManager.TopLevelCommands;
|
||||
var thisProvider = _provider;
|
||||
var providersCommands = thisProvider.TopLevelItems;
|
||||
List<TopLevelViewModel> results = [];
|
||||
|
||||
// Remember! This comes in on the UI thread!
|
||||
// TODO: GH #426
|
||||
// Probably just do a background InitializeProperties
|
||||
// Or better yet, merge TopLevelCommandWrapper and TopLevelViewModel
|
||||
foreach (var command in providersCommands)
|
||||
{
|
||||
var match = topLevelCommands.Where(tlc => tlc.Model.Unsafe == command).FirstOrDefault();
|
||||
if (match != null)
|
||||
{
|
||||
results.Add(new(match, _settings, _serviceProvider));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
return [.. providersCommands];
|
||||
}
|
||||
|
||||
private void Save() => SettingsModel.SaveSettings(_settings);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user