Almost - top level items can pin/unpin _after_ a reload??

Like, we're not actually realizing that command needed us to build a
context menu for it until we re-retrieve it. dafuq
This commit is contained in:
Mike Griese
2026-02-18 06:36:56 -06:00
parent fd31b286ac
commit d7d72fe2f4
3 changed files with 39 additions and 16 deletions

View File

@@ -226,13 +226,14 @@ public sealed class CommandProviderWrapper
WeakReference<IPageContext> pageContext)
{
var settings = serviceProvider.GetService<SettingsModel>()!;
var contextMenuFactory = serviceProvider.GetService<IContextMenuFactory>()!;
var providerSettings = GetProviderSettings(settings);
var ourContext = GetProviderContext();
var makeAndAdd = (ICommandItem? i, bool fallback) =>
{
// n.b. Mike, you may want to revisit this after the dock stuff merges,
// because I think we'll need to pass a contextMenuFactory to dock items
CommandItemViewModel commandItemViewModel = new(new(i), pageContext, contextMenuFactory: null);
CommandItemViewModel commandItemViewModel = new(new(i), pageContext, contextMenuFactory: contextMenuFactory);
TopLevelViewModel topLevelViewModel = new(commandItemViewModel, fallback, ExtensionHost, ourContext, settings, providerSettings, serviceProvider, i);
topLevelViewModel.InitializeProperties();

View File

@@ -24,7 +24,6 @@ public partial class TopLevelCommandManager : ObservableObject,
IRecipient<ReloadCommandsMessage>,
IRecipient<PinCommandItemMessage>,
IRecipient<UnpinCommandItemMessage>,
IPageContext,
IDisposable
{
private readonly IServiceProvider _serviceProvider;
@@ -36,10 +35,6 @@ public partial class TopLevelCommandManager : ObservableObject,
private readonly Lock _commandProvidersLock = new();
private readonly SupersedingAsyncGate _reloadCommandsGate;
TaskScheduler IPageContext.Scheduler => _taskScheduler;
CommandProviderContext IPageContext.ProviderContext => throw new NotImplementedException("You shouldn't ever be using the provider context of the top-level manager");
public TopLevelCommandManager(IServiceProvider serviceProvider, ICommandProviderCache commandProviderCache)
{
_serviceProvider = serviceProvider;
@@ -108,9 +103,10 @@ public partial class TopLevelCommandManager : ObservableObject,
// May be called from a background thread
private async Task<IEnumerable<TopLevelViewModel>> LoadTopLevelCommandsFromProvider(CommandProviderWrapper commandProvider)
{
WeakReference<IPageContext> weakSelf = new(this);
TopLevelItemPageContext pageContext = new(commandProvider, _taskScheduler);
WeakReference<IPageContext> weak = new(pageContext);
await commandProvider.LoadTopLevelCommands(_serviceProvider, weakSelf);
await commandProvider.LoadTopLevelCommands(_serviceProvider, weak);
var commands = await Task.Factory.StartNew(
() =>
@@ -157,8 +153,9 @@ public partial class TopLevelCommandManager : ObservableObject,
/// <returns>an awaitable task</returns>
private async Task UpdateCommandsForProvider(CommandProviderWrapper sender, IItemsChangedEventArgs args)
{
WeakReference<IPageContext> weakSelf = new(this);
await sender.LoadTopLevelCommands(_serviceProvider, weakSelf);
TopLevelItemPageContext pageContext = new(sender, _taskScheduler);
WeakReference<IPageContext> weak = new(pageContext);
await sender.LoadTopLevelCommands(_serviceProvider, weak);
List<TopLevelViewModel> newItems = [.. sender.TopLevelItems];
foreach (var i in sender.FallbackItems)
@@ -441,12 +438,6 @@ public partial class TopLevelCommandManager : ObservableObject,
}
}
void IPageContext.ShowException(Exception ex, string? extensionHint)
{
var message = DiagnosticsHelper.BuildExceptionMessage(ex, extensionHint ?? "TopLevelCommandManager");
CommandPaletteHost.Instance.Log(message);
}
internal bool IsProviderActive(string id)
{
lock (_commandProvidersLock)

View File

@@ -0,0 +1,31 @@
// 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.CmdPal.Core.Common.Helpers;
using Microsoft.CmdPal.Core.ViewModels;
namespace Microsoft.CmdPal.UI.ViewModels;
internal partial class TopLevelItemPageContext : IPageContext
{
public TaskScheduler Scheduler { get; private set; }
public CommandProviderContext ProviderContext { get; private set; }
TaskScheduler IPageContext.Scheduler => Scheduler;
CommandProviderContext IPageContext.ProviderContext => ProviderContext;
internal TopLevelItemPageContext(CommandProviderWrapper provider, TaskScheduler scheduler)
{
ProviderContext = provider.GetProviderContext();
Scheduler = scheduler;
}
public void ShowException(Exception ex, string? extensionHint = null)
{
var message = DiagnosticsHelper.BuildExceptionMessage(ex, extensionHint ?? $"TopLevelItemPageContext({ProviderContext.ProviderId})");
CommandPaletteHost.Instance.Log(message);
}
}