mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 17:42:45 +08:00
Merge branch 'dev/PowerLauncher' into dev/traies/build_features_launcher_integration
This commit is contained in:
commit
fe77a7e01a
@ -6,8 +6,6 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class PowerLauncherProperties
|
||||
{
|
||||
public bool enable_powerlauncher { get; set; }
|
||||
|
||||
public string search_result_preference { get; set; }
|
||||
|
||||
public string search_type_preference { get; set; }
|
||||
|
@ -8,7 +8,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class PowerLauncherSettings : BasePTModuleSettings
|
||||
{
|
||||
public const string POWERTOYNAME = "PowerLauncher";
|
||||
public const string POWERTOYNAME = "Launcher";
|
||||
|
||||
public PowerLauncherProperties properties { get; set; }
|
||||
|
||||
|
@ -88,6 +88,13 @@ namespace Microsoft.Plugin.Indexer
|
||||
return hide;
|
||||
};
|
||||
r.ContextData = searchResult;
|
||||
|
||||
//If the result is a directory, then it's display should show a directory.
|
||||
if(Directory.Exists(path))
|
||||
{
|
||||
r.QueryTextDisplay = path;
|
||||
}
|
||||
|
||||
results.Add(r);
|
||||
}
|
||||
}
|
||||
|
@ -94,30 +94,14 @@ namespace Wox.Plugin.Folder
|
||||
Title = title,
|
||||
IcoPath = path,
|
||||
SubTitle = subtitle,
|
||||
QueryTextDisplay = path,
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path },
|
||||
Action = c =>
|
||||
{
|
||||
if (c.SpecialKeyState.CtrlPressed)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(_fileExplorerProgramName, path);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Could not start " + path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string changeTo = path.EndsWith("\\") ? path : path + "\\";
|
||||
_context.API.ChangeQuery(string.IsNullOrEmpty(query.ActionKeyword) ?
|
||||
changeTo :
|
||||
query.ActionKeyword + " " + changeTo);
|
||||
return false;
|
||||
},
|
||||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path }
|
||||
};
|
||||
}
|
||||
|
||||
@ -273,6 +257,7 @@ namespace Wox.Plugin.Folder
|
||||
return new Result
|
||||
{
|
||||
Title = firstResult,
|
||||
QueryTextDisplay = search,
|
||||
SubTitle = $"Use > to search within the directory. Use * to search for file extensions. Or use both >*.",
|
||||
IcoPath = search,
|
||||
Score = 500,
|
||||
|
@ -2,8 +2,10 @@ using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using Wox.Infrastructure.Storage;
|
||||
@ -20,6 +22,9 @@ namespace Wox.Plugin.Program
|
||||
internal static UWP.Application[] _uwps { get; set; }
|
||||
internal static Settings _settings { get; set; }
|
||||
|
||||
FileSystemWatcher _watcher = null;
|
||||
System.Timers.Timer _timer = null;
|
||||
|
||||
private static bool IsStartupIndexProgramsRequired => _settings.LastIndexTime.AddDays(3) < DateTime.Today;
|
||||
|
||||
private static PluginInitContext _context;
|
||||
@ -58,6 +63,9 @@ namespace Wox.Plugin.Program
|
||||
Task.WaitAll(a, b);
|
||||
|
||||
_settings.LastIndexTime = DateTime.Today;
|
||||
|
||||
InitializeFileWatchers();
|
||||
InitializeTimer();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
@ -176,5 +184,52 @@ namespace Wox.Plugin.Program
|
||||
public void UpdateSettings(PowerLauncherSettings settings)
|
||||
{
|
||||
}
|
||||
void InitializeFileWatchers()
|
||||
{
|
||||
// Create a new FileSystemWatcher and set its properties.
|
||||
_watcher = new FileSystemWatcher();
|
||||
var resolvedPath = Environment.ExpandEnvironmentVariables("%ProgramFiles%");
|
||||
_watcher.Path = resolvedPath;
|
||||
|
||||
//Filter to create and deletes of 'microsoft.system.package.metadata' directories.
|
||||
_watcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName;
|
||||
_watcher.IncludeSubdirectories = true;
|
||||
|
||||
// Add event handlers.
|
||||
_watcher.Created += OnChanged;
|
||||
_watcher.Deleted += OnChanged;
|
||||
|
||||
// Begin watching.
|
||||
_watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
void InitializeTimer()
|
||||
{
|
||||
//multiple file writes occur on install / unistall. Adding a delay before actually indexing.
|
||||
var delayInterval = 5000;
|
||||
_timer = new System.Timers.Timer(delayInterval);
|
||||
_timer.Enabled = true;
|
||||
_timer.AutoReset = false;
|
||||
_timer.Elapsed += FileWatchElapsedTimer;
|
||||
_timer.Stop();
|
||||
}
|
||||
|
||||
//When a watched directory changes then reset the timer.
|
||||
private void OnChanged(object source, FileSystemEventArgs e)
|
||||
{
|
||||
Log.Debug($"|Wox.Plugin.Program.Main|Directory Changed: {e.FullPath} {e.ChangeType} - Resetting timer.");
|
||||
_timer.Stop();
|
||||
_timer.Start();
|
||||
}
|
||||
|
||||
private void FileWatchElapsedTimer(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Log.Debug($"|Wox.Plugin.Program.Main| ReIndexing UWP Programs");
|
||||
IndexUWPPrograms();
|
||||
Log.Debug($"|Wox.Plugin.Program.Main| Done ReIndexing");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -291,6 +291,9 @@ namespace Wox.Plugin.Shell
|
||||
|
||||
bool API_GlobalKeyboardEvent(int keyevent, int vkcode, SpecialKeyState state)
|
||||
{
|
||||
// not overriding Win+R
|
||||
// crutkas we need to earn the right for Win+R override
|
||||
|
||||
if (_settings.ReplaceWinR)
|
||||
{
|
||||
if (keyevent == (int)KeyEvent.WM_KEYDOWN && vkcode == (int)Keys.R && state.WinPressed)
|
||||
|
@ -5,7 +5,10 @@ namespace Wox.Plugin.Shell
|
||||
public class Settings
|
||||
{
|
||||
public Shell Shell { get; set; } = Shell.RunCommand;
|
||||
public bool ReplaceWinR { get; set; } = true;
|
||||
|
||||
// not overriding Win+R
|
||||
// crutkas we need to earn the right for Win+R override
|
||||
public bool ReplaceWinR { get; set; } = false;
|
||||
public bool LeaveShellOpen { get; set; }
|
||||
public bool RunAsAdministrator { get; set; } = false;
|
||||
|
||||
|
@ -375,7 +375,6 @@
|
||||
x:FieldModifier="public"
|
||||
Style="{StaticResource CustomAutoSuggestBoxTextBoxStyle}"
|
||||
PlaceholderText="Start typing"
|
||||
Text="{Binding QueryText}"
|
||||
Height="60"
|
||||
ScrollViewer.BringIntoViewOnFocusChange="False"
|
||||
Canvas.ZIndex="0"
|
||||
|
@ -22,6 +22,7 @@ using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Core;
|
||||
using System.Windows.Media;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace PowerLauncher
|
||||
{
|
||||
@ -33,11 +34,10 @@ namespace PowerLauncher
|
||||
private readonly Storyboard _progressBarStoryboard = new Storyboard();
|
||||
private Settings _settings;
|
||||
private MainViewModel _viewModel;
|
||||
|
||||
private bool _isTextSetProgramatically;
|
||||
const int ROW_COUNT = 4;
|
||||
const int ROW_HEIGHT = 75;
|
||||
const int MAX_LIST_HEIGHT = 300;
|
||||
|
||||
#endregion
|
||||
|
||||
public MainWindow(Settings settings, MainViewModel mainVM)
|
||||
@ -60,6 +60,7 @@ namespace PowerLauncher
|
||||
|
||||
private void OnInitialized(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, System.Windows.RoutedEventArgs _)
|
||||
@ -153,7 +154,7 @@ namespace PowerLauncher
|
||||
_launcher = (PowerLauncher.UI.LauncherControl)host.Child;
|
||||
_launcher.DataContext = _viewModel;
|
||||
_launcher.KeyDown += _launcher_KeyDown;
|
||||
_launcher.TextBox.TextChanged += QueryTextBox_TextChanged;
|
||||
_launcher.TextBox.TextChanging += QueryTextBox_TextChanging;
|
||||
_launcher.TextBox.Loaded += TextBox_Loaded;
|
||||
_launcher.PropertyChanged += UserControl_PropertyChanged;
|
||||
_viewModel.PropertyChanged += (o, e) =>
|
||||
@ -177,9 +178,16 @@ namespace PowerLauncher
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(e.PropertyName == nameof(MainViewModel.SystemQueryText))
|
||||
{
|
||||
this._isTextSetProgramatically = true;
|
||||
_launcher.TextBox.Text = _viewModel.SystemQueryText;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UserControl_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "SolidBorderBrush")
|
||||
@ -210,10 +218,16 @@ namespace PowerLauncher
|
||||
_resultList = (UI.ResultList)host.Child;
|
||||
_resultList.DataContext = _viewModel;
|
||||
_resultList.Tapped += SuggestionsList_Tapped;
|
||||
_resultList.SuggestionsList.Loaded += SuggestionsList_Loaded;
|
||||
_resultList.SuggestionsList.SelectionChanged += SuggestionsList_SelectionChanged;
|
||||
_resultList.SuggestionsList.ContainerContentChanging += SuggestionList_UpdateListSize;
|
||||
}
|
||||
|
||||
private void SuggestionsList_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
_viewModel.ColdStartFix();
|
||||
}
|
||||
|
||||
private bool IsKeyDown(VirtualKey key)
|
||||
{
|
||||
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(key);
|
||||
@ -225,21 +239,25 @@ namespace PowerLauncher
|
||||
if (e.Key == VirtualKey.Tab && IsKeyDown(VirtualKey.Shift))
|
||||
{
|
||||
_viewModel.SelectPrevTabItemCommand.Execute(null);
|
||||
UpdateTextBoxToSelectedItem();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Tab)
|
||||
{
|
||||
_viewModel.SelectNextTabItemCommand.Execute(null);
|
||||
UpdateTextBoxToSelectedItem();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Down)
|
||||
{
|
||||
_viewModel.SelectNextItemCommand.Execute(null);
|
||||
UpdateTextBoxToSelectedItem();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Up)
|
||||
{
|
||||
_viewModel.SelectPrevItemCommand.Execute(null);
|
||||
UpdateTextBoxToSelectedItem();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.PageDown)
|
||||
@ -254,6 +272,15 @@ namespace PowerLauncher
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTextBoxToSelectedItem()
|
||||
{
|
||||
var itemText = _viewModel?.Results?.SelectedItem?.ToString() ?? null;
|
||||
if (!String.IsNullOrEmpty(itemText))
|
||||
{
|
||||
_viewModel.ChangeQueryText(itemText);
|
||||
}
|
||||
}
|
||||
|
||||
private void SuggestionsList_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
var result = ((Windows.UI.Xaml.FrameworkElement)e.OriginalSource).DataContext;
|
||||
@ -324,8 +351,7 @@ namespace PowerLauncher
|
||||
|
||||
private string ListView_FirstItem(String input)
|
||||
{
|
||||
string s = input;
|
||||
if (s.Length > 0)
|
||||
if (!String.IsNullOrEmpty(input))
|
||||
{
|
||||
String selectedItem = _viewModel.Results?.SelectedItem?.ToString();
|
||||
int selectedIndex = _viewModel.Results.SelectedIndex;
|
||||
@ -341,25 +367,49 @@ namespace PowerLauncher
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
|
||||
private void QueryTextBox_TextChanged(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs e)
|
||||
private void QueryTextBox_TextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
|
||||
{
|
||||
var latestTimeOfTyping = DateTime.Now;
|
||||
var text = ((Windows.UI.Xaml.Controls.TextBox)sender).Text;
|
||||
Task.Run(() => DelayedCheck(latestTimeOfTyping, text));
|
||||
s_lastTimeOfTyping = latestTimeOfTyping;
|
||||
ClearAllQueryTextChangedHanlders();
|
||||
|
||||
if(this._isTextSetProgramatically)
|
||||
{
|
||||
this._launcher.TextBox.TextChanged += QueryTextBox_TextChangedProgramatically;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._launcher.TextBox.TextChanged += QueryTextBox_TextChangedByUserInput;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearAllQueryTextChangedHanlders()
|
||||
{
|
||||
this._launcher.TextBox.TextChanged -= QueryTextBox_TextChangedProgramatically;
|
||||
this._launcher.TextBox.TextChanged -= QueryTextBox_TextChangedByUserInput;
|
||||
}
|
||||
|
||||
private void QueryTextBox_TextChangedProgramatically(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
var textBox = ((Windows.UI.Xaml.Controls.TextBox)sender);
|
||||
textBox.SelectionStart = textBox.Text.Length;
|
||||
|
||||
this._isTextSetProgramatically = false;
|
||||
}
|
||||
|
||||
|
||||
private void QueryTextBox_TextChangedByUserInput(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
var text = ((Windows.UI.Xaml.Controls.TextBox)sender).Text;
|
||||
//To clear the auto-suggest immediately instead of waiting for selection changed
|
||||
if(text == String.Empty)
|
||||
if (text == String.Empty)
|
||||
{
|
||||
_launcher.AutoCompleteTextBox.PlaceholderText = String.Empty;
|
||||
}
|
||||
|
||||
if (_viewModel.QueryTextCursorMovedToEnd)
|
||||
{
|
||||
_launcher.TextBox.SelectionStart = _launcher.TextBox.Text.Length;
|
||||
_viewModel.QueryTextCursorMovedToEnd = false;
|
||||
}
|
||||
_viewModel.QueryText = text;
|
||||
var latestTimeOfTyping = DateTime.Now;
|
||||
|
||||
Task.Run(() => DelayedCheck(latestTimeOfTyping, text));
|
||||
s_lastTimeOfTyping = latestTimeOfTyping;
|
||||
}
|
||||
|
||||
private async Task DelayedCheck(DateTime latestTimeOfTyping, string text)
|
||||
@ -369,12 +419,12 @@ namespace PowerLauncher
|
||||
{
|
||||
await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
_viewModel.QueryText = text;
|
||||
_viewModel.Query();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private void WindowsXamlHost_PreviewMouseDown(object sender, MouseButtonEventArgs e)
|
||||
private void WindowsXamlHost_PreviewMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// if (sender != null && e.OriginalSource != null)
|
||||
// {
|
||||
|
@ -18,6 +18,11 @@ namespace Wox.Plugin
|
||||
|
||||
public string FontFamily { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The text that will get displayed in the Search text box, when this item is selected in the result list.
|
||||
/// </summary>
|
||||
public string QueryTextDisplay { get; set; }
|
||||
|
||||
public string IcoPath
|
||||
{
|
||||
get { return _icoPath; }
|
||||
|
@ -235,16 +235,9 @@ namespace Wox
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (_viewModel.QueryTextCursorMovedToEnd)
|
||||
{
|
||||
QueryTextBox.CaretIndex = QueryTextBox.Text.Length;
|
||||
_viewModel.QueryTextCursorMovedToEnd = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -38,12 +38,12 @@ namespace Wox
|
||||
|
||||
public void ChangeQuery(string query, bool requery = false)
|
||||
{
|
||||
_mainVM.ChangeQueryText(query);
|
||||
_mainVM.ChangeQueryText(query, requery);
|
||||
}
|
||||
|
||||
public void ChangeQueryText(string query, bool selectAll = false)
|
||||
{
|
||||
_mainVM.ChangeQueryText(query);
|
||||
_mainVM.ChangeQueryText(query, false);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
|
@ -51,7 +51,6 @@ namespace Wox.ViewModel
|
||||
{
|
||||
_saved = false;
|
||||
_queryTextBeforeLeaveResults = "";
|
||||
_queryText = "";
|
||||
_lastQuery = new Query();
|
||||
|
||||
_settings = settings;
|
||||
@ -179,17 +178,17 @@ namespace Wox.ViewModel
|
||||
if (!didExecuteContextButton)
|
||||
{
|
||||
var result = results.SelectedItem.Result;
|
||||
if (result != null) // SelectedItem returns null if selection is empty.
|
||||
if (result != null && result.Action != null) // SelectedItem returns null if selection is empty.
|
||||
{
|
||||
bool hideWindow = result.Action != null && result.Action(new ActionContext
|
||||
MainWindowVisibility = Visibility.Collapsed;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
result.Action(new ActionContext
|
||||
{
|
||||
SpecialKeyState = GlobalHotkey.Instance.CheckModifiers()
|
||||
});
|
||||
|
||||
if (hideWindow)
|
||||
{
|
||||
MainWindowVisibility = Visibility.Collapsed;
|
||||
}
|
||||
});
|
||||
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
@ -242,29 +241,29 @@ namespace Wox.ViewModel
|
||||
public ResultsViewModel ContextMenu { get; private set; }
|
||||
public ResultsViewModel History { get; private set; }
|
||||
|
||||
private string _queryText;
|
||||
public string QueryText
|
||||
{
|
||||
get { return _queryText; }
|
||||
set
|
||||
{
|
||||
_queryText = value;
|
||||
Query();
|
||||
}
|
||||
}
|
||||
public string SystemQueryText { get; set; } = String.Empty;
|
||||
|
||||
public string QueryText { get; set; } = String.Empty;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// we need move cursor to end when we manually changed query
|
||||
/// but we don't want to move cursor to end when query is updated from TextBox
|
||||
/// but we don't want to move cursor to end when query is updated from TextBox.
|
||||
/// Also we don't want to force the results to change unless explicity told to.
|
||||
/// </summary>
|
||||
/// <param name="queryText"></param>
|
||||
public void ChangeQueryText(string queryText)
|
||||
/// <param name="requery">Optional Parameter that if true, will automatically execute a query against the updated text</param>
|
||||
public void ChangeQueryText(string queryText, bool requery=false)
|
||||
{
|
||||
SystemQueryText = queryText;
|
||||
|
||||
if(requery)
|
||||
{
|
||||
QueryTextCursorMovedToEnd = true;
|
||||
QueryText = queryText;
|
||||
Query();
|
||||
}
|
||||
}
|
||||
public bool LastQuerySelected { get; set; }
|
||||
public bool QueryTextCursorMovedToEnd { get; set; }
|
||||
|
||||
private ResultsViewModel _selectedResults;
|
||||
private ResultsViewModel SelectedResults
|
||||
@ -632,6 +631,32 @@ namespace Wox.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
public void ColdStartFix()
|
||||
{
|
||||
// Fix Cold start for List view xaml island
|
||||
List<Result> list = new List<Result>();
|
||||
Result r = new Result
|
||||
{
|
||||
Title = "hello"
|
||||
};
|
||||
list.Add(r);
|
||||
Results.AddResults(list, "0");
|
||||
Results.Clear();
|
||||
MainWindowVisibility = System.Windows.Visibility.Collapsed;
|
||||
|
||||
// Fix Cold start for plugins
|
||||
string s = "m";
|
||||
var query = QueryBuilder.Build(s.Trim(), PluginManager.NonGlobalPlugins);
|
||||
var plugins = PluginManager.ValidPluginsForQuery(query);
|
||||
foreach (PluginPair plugin in plugins)
|
||||
{
|
||||
if (!plugin.Metadata.Disabled && plugin.Metadata.Name != "Window Walker")
|
||||
{
|
||||
var _ = PluginManager.QueryForPlugin(plugin, query);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -255,7 +255,8 @@ namespace Wox.ViewModel
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Result.Title.ToString();
|
||||
var display = String.IsNullOrEmpty(Result.QueryTextDisplay) ? Result.Title : Result.QueryTextDisplay;
|
||||
return display;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user