Merge branch 'dev/PowerLauncher' into dev/traies/build_features_launcher_integration

This commit is contained in:
Tomas Raies 2020-04-27 10:50:55 -07:00
commit fe77a7e01a
14 changed files with 211 additions and 87 deletions

View File

@ -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; }

View File

@ -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; }

View File

@ -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);
}
}

View File

@ -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 }
Process.Start(_fileExplorerProgramName, path);
return true;
}
};
}
@ -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,

View File

@ -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");
});
}
}
}

View File

@ -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)

View File

@ -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;

View File

@ -375,7 +375,6 @@
x:FieldModifier="public"
Style="{StaticResource CustomAutoSuggestBoxTextBoxStyle}"
PlaceholderText="Start typing"
Text="{Binding QueryText}"
Height="60"
ScrollViewer.BringIntoViewOnFocusChange="False"
Canvas.ZIndex="0"

View File

@ -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);
_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)
@ -368,13 +418,13 @@ namespace PowerLauncher
if (latestTimeOfTyping.Equals(s_lastTimeOfTyping))
{
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)
// {

View File

@ -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; }

View File

@ -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;
}
}
}
}

View File

@ -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]

View File

@ -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
{
SpecialKeyState = GlobalHotkey.Instance.CheckModifiers()
});
MainWindowVisibility = Visibility.Collapsed;
if (hideWindow)
Task.Run(() =>
{
MainWindowVisibility = Visibility.Collapsed;
}
result.Action(new ActionContext
{
SpecialKeyState = GlobalHotkey.Instance.CheckModifiers()
});
});
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)
{
QueryTextCursorMovedToEnd = true;
QueryText = queryText;
SystemQueryText = queryText;
if(requery)
{
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
}
}

View File

@ -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;
}
}
}