mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-29 08:29:10 +01:00
Compare commits
8 Commits
shawn/mcps
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4c3b16db2 | ||
|
|
652715a06d | ||
|
|
0e3965e6c5 | ||
|
|
bddaba4a21 | ||
|
|
b8d4e4f32a | ||
|
|
16616a6494 | ||
|
|
5ae18fb941 | ||
|
|
b821bdf8a4 |
@@ -141,6 +141,7 @@ public sealed partial class SaveCommand : InvokableCommand
|
||||
internal sealed partial class FallbackCalculatorItem : FallbackCommandItem
|
||||
{
|
||||
private readonly CopyTextCommand _copyCommand = new(string.Empty);
|
||||
private static readonly IconInfo _cachedIcon = IconHelpers.FromRelativePath("Assets\\Calculator.svg");
|
||||
|
||||
public FallbackCalculatorItem()
|
||||
: base(new NoOpCommand(), Resources.calculator_title)
|
||||
@@ -149,7 +150,7 @@ internal sealed partial class FallbackCalculatorItem : FallbackCommandItem
|
||||
_copyCommand.Name = string.Empty;
|
||||
Title = string.Empty;
|
||||
Subtitle = Resources.calculator_placeholder_text;
|
||||
Icon = new IconInfo("\ue8ef"); // Calculator
|
||||
Icon = _cachedIcon;
|
||||
}
|
||||
|
||||
public override void UpdateQuery(string query)
|
||||
|
||||
@@ -13,6 +13,7 @@ using Microsoft.CmdPal.Ext.WindowsServices.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Win32;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsServices.Helpers;
|
||||
|
||||
@@ -53,7 +54,10 @@ public static class ServiceHelper
|
||||
serviceCommand = new ServiceCommand(serviceResult, Action.Stop);
|
||||
moreCommands = [
|
||||
new CommandContextItem(new RestartServiceCommand(serviceResult)),
|
||||
new CommandContextItem(new OpenServicesCommand(serviceResult)),
|
||||
new CommandContextItem(new OpenServicesCommand(serviceResult))
|
||||
{
|
||||
RequestedShortcut = KeyChordHelpers.FromModifiers(true, false, false, false, (int)VirtualKey.O, 0),
|
||||
},
|
||||
];
|
||||
}
|
||||
else
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="wox_plugin_service_open_services" xml:space="preserve">
|
||||
<value>Open services (Ctrl+O)</value>
|
||||
<value>Open services</value>
|
||||
</data>
|
||||
<data name="wox_plugin_service_paused" xml:space="preserve">
|
||||
<value>Paused</value>
|
||||
@@ -142,7 +142,7 @@
|
||||
<value>Service</value>
|
||||
</data>
|
||||
<data name="wox_plugin_service_restart" xml:space="preserve">
|
||||
<value>Restart (Ctrl+R)</value>
|
||||
<value>Restart</value>
|
||||
</data>
|
||||
<data name="wox_plugin_service_restarted_notification" xml:space="preserve">
|
||||
<value>The service has been restarted</value>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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.Immutable;
|
||||
using System.Collections.Specialized;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Ext.Apps;
|
||||
@@ -101,12 +102,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
var commands = _tlcManager.TopLevelCommands;
|
||||
lock (commands)
|
||||
{
|
||||
// This gets called on a background thread, because ListViewModel
|
||||
// updates the .SearchText of all extensions on a BG thread.
|
||||
foreach (var command in commands)
|
||||
{
|
||||
command.TryUpdateFallbackText(newSearch);
|
||||
}
|
||||
UpdateFallbacks(newSearch, commands.ToImmutableArray());
|
||||
|
||||
// Cleared out the filter text? easy. Reset _filteredItems, and bail out.
|
||||
if (string.IsNullOrEmpty(newSearch))
|
||||
@@ -137,6 +133,26 @@ public partial class MainListPage : DynamicListPage,
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFallbacks(string newSearch, IReadOnlyList<TopLevelViewModel> commands)
|
||||
{
|
||||
// fire and forget
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
var needsToUpdate = false;
|
||||
|
||||
foreach (var command in commands)
|
||||
{
|
||||
var changedVisibility = command.SafeUpdateFallbackTextSynchronous(newSearch);
|
||||
needsToUpdate = needsToUpdate || changedVisibility;
|
||||
}
|
||||
|
||||
if (needsToUpdate)
|
||||
{
|
||||
RaiseItemsChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private bool ActuallyLoading()
|
||||
{
|
||||
var tlcManager = _serviceProvider.GetService<TopLevelCommandManager>()!;
|
||||
@@ -149,17 +165,14 @@ public partial class MainListPage : DynamicListPage,
|
||||
// _always_ show up first.
|
||||
private int ScoreTopLevelItem(string query, IListItem topLevelOrAppItem)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var title = topLevelOrAppItem.Title;
|
||||
if (string.IsNullOrEmpty(title))
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var isWhiteSpace = string.IsNullOrWhiteSpace(query);
|
||||
|
||||
var isFallback = false;
|
||||
var isAliasSubstringMatch = false;
|
||||
var isAliasMatch = false;
|
||||
@@ -179,17 +192,45 @@ public partial class MainListPage : DynamicListPage,
|
||||
extensionDisplayName = topLevel.ExtensionHost?.Extension?.PackageDisplayName ?? string.Empty;
|
||||
}
|
||||
|
||||
var nameMatch = StringMatcher.FuzzySearch(query, title);
|
||||
var descriptionMatch = StringMatcher.FuzzySearch(query, topLevelOrAppItem.Subtitle);
|
||||
var extensionTitleMatch = StringMatcher.FuzzySearch(query, extensionDisplayName);
|
||||
// StringMatcher.FuzzySearch will absolutely BEEF IT if you give it a
|
||||
// whitespace-only query.
|
||||
//
|
||||
// in that scenario, we'll just use a simple string contains for the
|
||||
// query. Maybe someone is really looking for things with a space in
|
||||
// them, I don't know.
|
||||
|
||||
// Title:
|
||||
// * whitespace query: 1 point
|
||||
// * otherwise full weight match
|
||||
var nameMatch = isWhiteSpace ?
|
||||
(title.Contains(query) ? 1 : 0) :
|
||||
StringMatcher.FuzzySearch(query, title).Score;
|
||||
|
||||
// Subtitle:
|
||||
// * whitespace query: 1/2 point
|
||||
// * otherwise ~half weight match. Minus a bit, because subtitles tend to be longer
|
||||
var descriptionMatch = isWhiteSpace ?
|
||||
(topLevelOrAppItem.Subtitle.Contains(query) ? .5 : 0) :
|
||||
(StringMatcher.FuzzySearch(query, topLevelOrAppItem.Subtitle).Score - 4) / 2.0;
|
||||
|
||||
// Extension title: despite not being visible, give the extension name itself some weight
|
||||
// * whitespace query: 0 points
|
||||
// * otherwise more weight than a subtitle, but not much
|
||||
var extensionTitleMatch = isWhiteSpace ? 0 : StringMatcher.FuzzySearch(query, extensionDisplayName).Score / 1.5;
|
||||
|
||||
var scores = new[]
|
||||
{
|
||||
nameMatch.Score,
|
||||
(descriptionMatch.Score - 4) / 2.0,
|
||||
nameMatch,
|
||||
descriptionMatch,
|
||||
isFallback ? 1 : 0, // Always give fallbacks a chance...
|
||||
};
|
||||
var max = scores.Max();
|
||||
max = max + (extensionTitleMatch.Score / 1.5);
|
||||
|
||||
// _Add_ the extension name. This will bubble items that match both
|
||||
// title and extension name up above ones that just match title.
|
||||
// e.g. "git" will up-weight "GitHub searches" from the GitHub extension
|
||||
// above "git" from "whatever"
|
||||
max = max + extensionTitleMatch;
|
||||
|
||||
// ... but downweight them
|
||||
var matchSomething = (max / (isFallback ? 3 : 1))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
@@ -209,7 +210,7 @@ public partial class TopLevelCommandManager : ObservableObject,
|
||||
extensionService.OnExtensionAdded -= ExtensionService_OnExtensionAdded;
|
||||
extensionService.OnExtensionRemoved -= ExtensionService_OnExtensionRemoved;
|
||||
|
||||
var extensions = await extensionService.GetInstalledExtensionsAsync();
|
||||
var extensions = (await extensionService.GetInstalledExtensionsAsync()).ToImmutableList();
|
||||
_extensionCommandProviders.Clear();
|
||||
if (extensions != null)
|
||||
{
|
||||
@@ -241,6 +242,7 @@ public partial class TopLevelCommandManager : ObservableObject,
|
||||
// TODO This most definitely needs a lock
|
||||
foreach (var extension in extensions)
|
||||
{
|
||||
Logger.LogDebug($"Starting {extension.PackageFullName}");
|
||||
try
|
||||
{
|
||||
// start it ...
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
@@ -237,32 +236,46 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
|
||||
}
|
||||
}
|
||||
|
||||
public void TryUpdateFallbackText(string newQuery)
|
||||
internal bool SafeUpdateFallbackTextSynchronous(string newQuery)
|
||||
{
|
||||
if (!IsFallback)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
_ = Task.Run(() =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var model = _commandItemViewModel.Model.Unsafe;
|
||||
if (model is IFallbackCommandItem fallback)
|
||||
{
|
||||
var wasEmpty = string.IsNullOrEmpty(Title);
|
||||
fallback.FallbackHandler.UpdateQuery(newQuery);
|
||||
var isEmpty = string.IsNullOrEmpty(Title);
|
||||
if (wasEmpty != isEmpty)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<UpdateFallbackItemsMessage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
});
|
||||
return UnsafeUpdateFallbackSynchronous(newQuery);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex.ToString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls UpdateQuery on our command, if we're a fallback item. This does
|
||||
/// RPC work, so make sure you're calling it on a BG thread.
|
||||
/// </summary>
|
||||
/// <param name="newQuery">The new search text to pass to the extension</param>
|
||||
/// <returns>true if our Title changed across this call</returns>
|
||||
private bool UnsafeUpdateFallbackSynchronous(string newQuery)
|
||||
{
|
||||
var model = _commandItemViewModel.Model.Unsafe;
|
||||
|
||||
// RPC to check type
|
||||
if (model is IFallbackCommandItem fallback)
|
||||
{
|
||||
var wasEmpty = string.IsNullOrEmpty(Title);
|
||||
|
||||
// RPC for method
|
||||
fallback.FallbackHandler.UpdateQuery(newQuery);
|
||||
var isEmpty = string.IsNullOrEmpty(Title);
|
||||
return wasEmpty != isEmpty;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,14 +53,14 @@
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Title, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
<!--<TextBlock
|
||||
Grid.Column="2"
|
||||
Margin="16,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind RequestedShortcut, Mode=OneWay, Converter={StaticResource KeyChordToStringConverter}}" />
|
||||
Text="{x:Bind RequestedShortcut, Mode=OneWay, Converter={StaticResource KeyChordToStringConverter}}" />-->
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<uap5:Extension Category="windows.startupTask">
|
||||
<uap5:StartupTask
|
||||
TaskId="CmdPalStartup"
|
||||
Enabled="true"
|
||||
Enabled="false"
|
||||
DisplayName="ms-resource:StartupTaskNameDev" />
|
||||
</uap5:Extension>
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<uap5:Extension Category="windows.startupTask">
|
||||
<uap5:StartupTask
|
||||
TaskId="CmdPalStartup"
|
||||
Enabled="true"
|
||||
Enabled="false"
|
||||
DisplayName="ms-resource:StartupTaskName" />
|
||||
</uap5:Extension>
|
||||
|
||||
@@ -78,5 +78,6 @@
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources" />
|
||||
<rescap:Capability Name="appLicensing" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
|
||||
@@ -42,12 +42,8 @@ public sealed partial class SettingsWindow : Window,
|
||||
|
||||
private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
||||
{
|
||||
var selectedItem = args.InvokedItem;
|
||||
|
||||
if (selectedItem is not null)
|
||||
{
|
||||
Navigate(selectedItem.ToString()!);
|
||||
}
|
||||
var selectedItem = args.InvokedItemContainer;
|
||||
Navigate((selectedItem.Tag as string)!);
|
||||
}
|
||||
|
||||
private void Navigate(string page)
|
||||
|
||||
@@ -20,7 +20,7 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem
|
||||
Title = string.Empty;
|
||||
_executeItem.Name = string.Empty;
|
||||
Subtitle = Properties.Resources.generic_run_command;
|
||||
Icon = new IconInfo("\uE756");
|
||||
Icon = Icons.RunV2; // Defined in Icons.cs and contains the execute command icon.
|
||||
}
|
||||
|
||||
public override void UpdateQuery(string query)
|
||||
|
||||
Reference in New Issue
Block a user