Merge branch 'dev' into 240430PreviewSetting

This commit is contained in:
DB P 2024-05-18 12:40:07 +09:00 committed by GitHub
commit fa0d42e5ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 835 additions and 816 deletions

View file

@ -3,3 +3,6 @@ https
ssh ssh
ubuntu ubuntu
runcount runcount
Firefox
Português
Português (Brasil)

View file

@ -74,6 +74,7 @@ WCA_ACCENT_POLICY
HGlobal HGlobal
dopusrt dopusrt
firefox firefox
Firefox
msedge msedge
svgc svgc
ime ime

View file

@ -27,8 +27,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public string SelectNextItemHotkey2 { get; set; } = $""; public string SelectNextItemHotkey2 { get; set; } = $"";
public string SelectPrevItemHotkey { get; set; } = $"Shift + Tab"; public string SelectPrevItemHotkey { get; set; } = $"Shift + Tab";
public string SelectPrevItemHotkey2 { get; set; } = $""; public string SelectPrevItemHotkey2 { get; set; } = $"";
public string SelectNextPageHotkey { get; set; } = $""; public string SelectNextPageHotkey { get; set; } = $"PageUp";
public string SelectPrevPageHotkey { get; set; } = $""; public string SelectPrevPageHotkey { get; set; } = $"PageDown";
public string OpenContextMenuHotkey { get; set; } = $"Ctrl+O"; public string OpenContextMenuHotkey { get; set; } = $"Ctrl+O";
public string SettingWindowHotkey { get; set; } = $"Ctrl+I"; public string SettingWindowHotkey { get; set; } = $"Ctrl+I";

View file

@ -185,9 +185,9 @@
<system:String x:Key="autoCompleteHotkey">Auto Complete</system:String> <system:String x:Key="autoCompleteHotkey">Auto Complete</system:String>
<system:String x:Key="autoCompleteHotkeyToolTip">Runs autocomplete for the selected items.</system:String> <system:String x:Key="autoCompleteHotkeyToolTip">Runs autocomplete for the selected items.</system:String>
<system:String x:Key="SelectNextItemHotkey">Select Next Item</system:String> <system:String x:Key="SelectNextItemHotkey">Select Next Item</system:String>
<system:String x:Key="SelectPrevItemHotkey">Select Prev Item</system:String> <system:String x:Key="SelectPrevItemHotkey">Select Previous Item</system:String>
<system:String x:Key="SelectNextPageHotkey">Next Page</system:String> <system:String x:Key="SelectNextPageHotkey">Next Page</system:String>
<system:String x:Key="SelectPrevPageHotkey">Prev Page</system:String> <system:String x:Key="SelectPrevPageHotkey">Previous Page</system:String>
<system:String x:Key="OpenContextMenuHotkey">Open Context Menu</system:String> <system:String x:Key="OpenContextMenuHotkey">Open Context Menu</system:String>
<system:String x:Key="SettingWindowHotkey">Open Setting Window</system:String> <system:String x:Key="SettingWindowHotkey">Open Setting Window</system:String>
<system:String x:Key="CopyFilePathHotkey">Copy File Path</system:String> <system:String x:Key="CopyFilePathHotkey">Copy File Path</system:String>
@ -195,6 +195,7 @@
<system:String x:Key="ToggleHistoryHotkey">Toggle History</system:String> <system:String x:Key="ToggleHistoryHotkey">Toggle History</system:String>
<system:String x:Key="OpenContainFolderHotkey">Open Containing Folder</system:String> <system:String x:Key="OpenContainFolderHotkey">Open Containing Folder</system:String>
<system:String x:Key="RunAsAdminHotkey">Run As Admin</system:String> <system:String x:Key="RunAsAdminHotkey">Run As Admin</system:String>
<system:String x:Key="RequeryHotkey">Refresh Search Results</system:String>
<system:String x:Key="ReloadPluginHotkey">Reload Plugins Data</system:String> <system:String x:Key="ReloadPluginHotkey">Reload Plugins Data</system:String>
<system:String x:Key="QuickWidthHotkey">Quick Adjust Window Width</system:String> <system:String x:Key="QuickWidthHotkey">Quick Adjust Window Width</system:String>
<system:String x:Key="QuickHeightHotkey">Quick Adjust Window Height</system:String> <system:String x:Key="QuickHeightHotkey">Quick Adjust Window Height</system:String>

View file

@ -26,6 +26,7 @@
LocationChanged="OnLocationChanged" LocationChanged="OnLocationChanged"
Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
PreviewKeyDown="OnKeyDown" PreviewKeyDown="OnKeyDown"
PreviewKeyUp="OnKeyUp"
ResizeMode="NoResize" ResizeMode="NoResize"
ShowInTaskbar="False" ShowInTaskbar="False"
SizeToContent="Height" SizeToContent="Height"

View file

@ -47,6 +47,7 @@ namespace Flow.Launcher
private MainViewModel _viewModel; private MainViewModel _viewModel;
private bool _animating; private bool _animating;
MediaPlayer animationSound = new MediaPlayer(); MediaPlayer animationSound = new MediaPlayer();
private bool isArrowKeyPressed = false;
#endregion #endregion
@ -109,9 +110,11 @@ namespace Flow.Launcher
private void OnInitialized(object sender, EventArgs e) private void OnInitialized(object sender, EventArgs e)
{ {
} }
private void OnLoaded(object sender, RoutedEventArgs _) private void OnLoaded(object sender, RoutedEventArgs _)
{ {
// MouseEventHandler
PreviewMouseMove += MainPreviewMouseMove;
CheckFirstLaunch(); CheckFirstLaunch();
HideStartup(); HideStartup();
// show notify icon when flowlauncher is hidden // show notify icon when flowlauncher is hidden
@ -406,6 +409,7 @@ namespace Flow.Launcher
if (_animating) if (_animating)
return; return;
isArrowKeyPressed = true;
_animating = true; _animating = true;
UpdatePosition(); UpdatePosition();
@ -494,6 +498,7 @@ namespace Flow.Launcher
windowsb.Completed += (_, _) => _animating = false; windowsb.Completed += (_, _) => _animating = false;
_settings.WindowLeft = Left; _settings.WindowLeft = Left;
_settings.WindowTop = Top; _settings.WindowTop = Top;
isArrowKeyPressed = false;
if (QueryTextBox.Text.Length == 0) if (QueryTextBox.Text.Length == 0)
{ {
@ -644,10 +649,12 @@ namespace Flow.Launcher
switch (e.Key) switch (e.Key)
{ {
case Key.Down: case Key.Down:
isArrowKeyPressed = true;
_viewModel.SelectNextItemCommand.Execute(null); _viewModel.SelectNextItemCommand.Execute(null);
e.Handled = true; e.Handled = true;
break; break;
case Key.Up: case Key.Up:
isArrowKeyPressed = true;
_viewModel.SelectPrevItemCommand.Execute(null); _viewModel.SelectPrevItemCommand.Execute(null);
e.Handled = true; e.Handled = true;
break; break;
@ -698,7 +705,21 @@ namespace Flow.Launcher
} }
} }
private void OnKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up || e.Key == Key.Down)
{
isArrowKeyPressed = false;
}
}
private void MainPreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (isArrowKeyPressed)
{
e.Handled = true; // Ignore Mouse Hover when press Arrowkeys
}
}
public void PreviewReset() public void PreviewReset()
{ {
_viewModel.ResetPreview(); _viewModel.ResetPreview();

View file

@ -2802,7 +2802,13 @@
Title="{DynamicResource ToggleGameModeHotkey}" Title="{DynamicResource ToggleGameModeHotkey}"
Icon="&#xe7fc;" Icon="&#xe7fc;"
Type="Inside"> Type="Inside">
<cc:HotkeyDisplay Keys="Ctrl+Shift+C" /> <cc:HotkeyDisplay Keys="Ctrl+F12" />
</cc:Card>
<cc:Card
Title="{DynamicResource RequeryHotkey}"
Icon="&#xe72c;"
Type="Inside">
<cc:HotkeyDisplay Keys="Ctrl+R" />
</cc:Card> </cc:Card>
<cc:Card <cc:Card
Title="{DynamicResource ReloadPluginHotkey}" Title="{DynamicResource ReloadPluginHotkey}"

View file

@ -3,8 +3,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public class ChromeBookmarkLoader : ChromiumBookmarkLoader public class ChromeBookmarkLoader : ChromiumBookmarkLoader
{ {
public override List<Bookmark> GetBookmarks() public override List<Bookmark> GetBookmarks()
@ -22,4 +22,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
return bookmarks; return bookmarks;
} }
} }
}

View file

@ -4,8 +4,8 @@ using System.IO;
using System.Text.Json; using System.Text.Json;
using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Logger;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public abstract class ChromiumBookmarkLoader : IBookmarkLoader public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{ {
public abstract List<Bookmark> GetBookmarks(); public abstract List<Bookmark> GetBookmarks();
@ -92,4 +92,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
} }
} }
} }
}

View file

@ -4,8 +4,8 @@ using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.Plugin.SharedModels;
namespace Flow.Launcher.Plugin.BrowserBookmark.Commands namespace Flow.Launcher.Plugin.BrowserBookmark.Commands;
{
internal static class BookmarkLoader internal static class BookmarkLoader
{ {
internal static MatchResult MatchProgram(Bookmark bookmark, string queryString) internal static MatchResult MatchProgram(Bookmark bookmark, string queryString)
@ -56,4 +56,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands
return allBookmarks.Distinct().ToList(); return allBookmarks.Distinct().ToList();
} }
} }
}

View file

@ -1,8 +1,8 @@
using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.BrowserBookmark.Models;
using System.Collections.Generic; using System.Collections.Generic;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public class CustomChromiumBookmarkLoader : ChromiumBookmarkLoader public class CustomChromiumBookmarkLoader : ChromiumBookmarkLoader
{ {
public CustomChromiumBookmarkLoader(CustomBrowser browser) public CustomChromiumBookmarkLoader(CustomBrowser browser)
@ -16,4 +16,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
public override List<Bookmark> GetBookmarks() => BrowserDataPath != null ? LoadBookmarks(BrowserDataPath, BrowserName) : LoadBookmarksFromFile(BookmarkFilePath, BrowserName); public override List<Bookmark> GetBookmarks() => BrowserDataPath != null ? LoadBookmarks(BrowserDataPath, BrowserName) : LoadBookmarksFromFile(BookmarkFilePath, BrowserName);
} }
}

View file

@ -2,8 +2,8 @@
using System.IO; using System.IO;
using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.BrowserBookmark.Models;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public class CustomFirefoxBookmarkLoader : FirefoxBookmarkLoaderBase public class CustomFirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
{ {
public CustomFirefoxBookmarkLoader(CustomBrowser browser) public CustomFirefoxBookmarkLoader(CustomBrowser browser)
@ -24,4 +24,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
return GetBookmarksFromPath(Path.Combine(BrowserDataPath, "places.sqlite")); return GetBookmarksFromPath(Path.Combine(BrowserDataPath, "places.sqlite"));
} }
} }
}

View file

@ -3,8 +3,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public class EdgeBookmarkLoader : ChromiumBookmarkLoader public class EdgeBookmarkLoader : ChromiumBookmarkLoader
{ {
private List<Bookmark> LoadEdgeBookmarks() private List<Bookmark> LoadEdgeBookmarks()
@ -20,4 +20,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
public override List<Bookmark> GetBookmarks() => LoadEdgeBookmarks(); public override List<Bookmark> GetBookmarks() => LoadEdgeBookmarks();
} }
}

View file

@ -5,21 +5,22 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
{ {
public abstract List<Bookmark> GetBookmarks(); public abstract List<Bookmark> GetBookmarks();
private const string queryAllBookmarks = @"SELECT moz_places.url, moz_bookmarks.title private const string QueryAllBookmarks = """
SELECT moz_places.url, moz_bookmarks.title
FROM moz_places FROM moz_places
INNER JOIN moz_bookmarks ON ( INNER JOIN moz_bookmarks ON (
moz_bookmarks.fk NOT NULL AND moz_bookmarks.title NOT NULL AND moz_bookmarks.fk = moz_places.id moz_bookmarks.fk NOT NULL AND moz_bookmarks.title NOT NULL AND moz_bookmarks.fk = moz_places.id
) )
ORDER BY moz_places.visit_count DESC ORDER BY moz_places.visit_count DESC
"; """;
private const string dbPathFormat = "Data Source ={0}"; private const string DbPathFormat = "Data Source ={0}";
protected static List<Bookmark> GetBookmarksFromPath(string placesPath) protected static List<Bookmark> GetBookmarksFromPath(string placesPath)
{ {
@ -27,24 +28,24 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
if (string.IsNullOrEmpty(placesPath) || !File.Exists(placesPath)) if (string.IsNullOrEmpty(placesPath) || !File.Exists(placesPath))
return new List<Bookmark>(); return new List<Bookmark>();
var bookmarkList = new List<Bookmark>();
Main.RegisterBookmarkFile(placesPath); Main.RegisterBookmarkFile(placesPath);
// create the connection string and init the connection // create the connection string and init the connection
string dbPath = string.Format(dbPathFormat, placesPath); string dbPath = string.Format(DbPathFormat, placesPath);
using var dbConnection = new SqliteConnection(dbPath); using var dbConnection = new SqliteConnection(dbPath);
// Open connection to the database file and execute the query // Open connection to the database file and execute the query
dbConnection.Open(); dbConnection.Open();
var reader = new SqliteCommand(queryAllBookmarks, dbConnection).ExecuteReader(); var reader = new SqliteCommand(QueryAllBookmarks, dbConnection).ExecuteReader();
// return results in List<Bookmark> format // return results in List<Bookmark> format
bookmarkList = reader.Select( return reader
x => new Bookmark(x["title"] is DBNull ? string.Empty : x["title"].ToString(), .Select(
x["url"].ToString()) x => new Bookmark(
).ToList(); x["title"] is DBNull ? string.Empty : x["title"].ToString(),
x["url"].ToString()
return bookmarkList; )
)
.ToList();
} }
} }
@ -73,11 +74,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
return string.Empty; return string.Empty;
// get firefox default profile directory from profiles.ini // get firefox default profile directory from profiles.ini
string ini; using var sReader = new StreamReader(profileIni);
using (var sReader = new StreamReader(profileIni)) var ini = sReader.ReadToEnd();
{
ini = sReader.ReadToEnd();
}
/* /*
Current profiles.ini structure example as of Firefox version 69.0.1 Current profiles.ini structure example as of Firefox version 69.0.1
@ -106,23 +104,19 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
StartWithLastProfile=1 StartWithLastProfile=1
Version=2 Version=2
*/ */
var lines = ini.Split("\r\n").ToList();
var lines = ini.Split(new string[] var defaultProfileFolderNameRaw = lines.FirstOrDefault(x => x.Contains("Default=") && x != "Default=1") ?? string.Empty;
{
"\r\n"
}, StringSplitOptions.None).ToList();
var defaultProfileFolderNameRaw = lines.Where(x => x.Contains("Default=") && x != "Default=1").FirstOrDefault() ?? string.Empty;
if (string.IsNullOrEmpty(defaultProfileFolderNameRaw)) if (string.IsNullOrEmpty(defaultProfileFolderNameRaw))
return string.Empty; return string.Empty;
var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last(); var defaultProfileFolderName = defaultProfileFolderNameRaw.Split('=').Last();
var indexOfDefaultProfileAtttributePath = lines.IndexOf("Path=" + defaultProfileFolderName); var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
// Seen in the example above, the IsRelative attribute is always above the Path attribute // Seen in the example above, the IsRelative attribute is always above the Path attribute
var relativeAttribute = lines[indexOfDefaultProfileAtttributePath - 1]; var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0 return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
? defaultProfileFolderName + @"\places.sqlite" ? defaultProfileFolderName + @"\places.sqlite"
@ -141,4 +135,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
} }
} }
} }
}

View file

@ -1,10 +1,9 @@
using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.BrowserBookmark.Models;
using System.Collections.Generic; using System.Collections.Generic;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public interface IBookmarkLoader public interface IBookmarkLoader
{ {
public List<Bookmark> GetBookmarks(); public List<Bookmark> GetBookmarks();
} }
}

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Plugin.BrowserBookmark.Commands; using Flow.Launcher.Plugin.BrowserBookmark.Commands;
@ -12,21 +11,21 @@ using System.Threading.Channels;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
namespace Flow.Launcher.Plugin.BrowserBookmark namespace Flow.Launcher.Plugin.BrowserBookmark;
{
public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable
{ {
private static PluginInitContext context; private static PluginInitContext _context;
private static List<Bookmark> cachedBookmarks = new List<Bookmark>(); private static List<Bookmark> _cachedBookmarks = new List<Bookmark>();
private static Settings _settings; private static Settings _settings;
private static bool initialized = false; private static bool _initialized = false;
public void Init(PluginInitContext context) public void Init(PluginInitContext context)
{ {
Main.context = context; _context = context;
_settings = context.API.LoadSettingJsonStorage<Settings>(); _settings = context.API.LoadSettingJsonStorage<Settings>();
@ -35,21 +34,21 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
private static void LoadBookmarksIfEnabled() private static void LoadBookmarksIfEnabled()
{ {
if (context.CurrentPluginMetadata.Disabled) if (_context.CurrentPluginMetadata.Disabled)
{ {
// Don't load or monitor files if disabled // Don't load or monitor files if disabled
return; return;
} }
cachedBookmarks = BookmarkLoader.LoadAllBookmarks(_settings); _cachedBookmarks = BookmarkLoader.LoadAllBookmarks(_settings);
_ = MonitorRefreshQueueAsync(); _ = MonitorRefreshQueueAsync();
initialized = true; _initialized = true;
} }
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
// For when the plugin being previously disabled and is now renabled // For when the plugin being previously disabled and is now re-enabled
if (!initialized) if (!_initialized)
{ {
LoadBookmarksIfEnabled(); LoadBookmarksIfEnabled();
} }
@ -63,7 +62,9 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
if (!topResults) if (!topResults)
{ {
// Since we mixed chrome and firefox bookmarks, we should order them again // Since we mixed chrome and firefox bookmarks, we should order them again
var returnList = cachedBookmarks.Select(c => new Result() return _cachedBookmarks
.Select(
c => new Result
{ {
Title = c.Name, Title = c.Name,
SubTitle = c.Url, SubTitle = c.Url,
@ -71,20 +72,21 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
Score = BookmarkLoader.MatchProgram(c, param).Score, Score = BookmarkLoader.MatchProgram(c, param).Score,
Action = _ => Action = _ =>
{ {
context.API.OpenUrl(c.Url); _context.API.OpenUrl(c.Url);
return true; return true;
}, },
ContextData = new BookmarkAttributes ContextData = new BookmarkAttributes { Url = c.Url }
{
Url = c.Url
} }
}).Where(r => r.Score > 0); )
return returnList.ToList(); .Where(r => r.Score > 0)
.ToList();
} }
else else
{ {
return cachedBookmarks.Select(c => new Result() return _cachedBookmarks
.Select(
c => new Result
{ {
Title = c.Name, Title = c.Name,
SubTitle = c.Url, SubTitle = c.Url,
@ -92,30 +94,29 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
Score = 5, Score = 5,
Action = _ => Action = _ =>
{ {
context.API.OpenUrl(c.Url); _context.API.OpenUrl(c.Url);
return true; return true;
}, },
ContextData = new BookmarkAttributes ContextData = new BookmarkAttributes { Url = c.Url }
{
Url = c.Url
} }
}).ToList(); )
.ToList();
} }
} }
private static Channel<byte> refreshQueue = Channel.CreateBounded<byte>(1); private static Channel<byte> _refreshQueue = Channel.CreateBounded<byte>(1);
private static SemaphoreSlim fileMonitorSemaphore = new(1, 1); private static SemaphoreSlim _fileMonitorSemaphore = new(1, 1);
private static async Task MonitorRefreshQueueAsync() private static async Task MonitorRefreshQueueAsync()
{ {
if (fileMonitorSemaphore.CurrentCount < 1) if (_fileMonitorSemaphore.CurrentCount < 1)
{ {
return; return;
} }
await fileMonitorSemaphore.WaitAsync(); await _fileMonitorSemaphore.WaitAsync();
var reader = refreshQueue.Reader; var reader = _refreshQueue.Reader;
while (await reader.WaitToReadAsync()) while (await reader.WaitToReadAsync())
{ {
if (reader.TryRead(out _)) if (reader.TryRead(out _))
@ -123,7 +124,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
ReloadAllBookmarks(false); ReloadAllBookmarks(false);
} }
} }
fileMonitorSemaphore.Release(); _fileMonitorSemaphore.Release();
} }
private static readonly List<FileSystemWatcher> Watchers = new(); private static readonly List<FileSystemWatcher> Watchers = new();
@ -149,12 +150,12 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
watcher.Changed += static (_, _) => watcher.Changed += static (_, _) =>
{ {
refreshQueue.Writer.TryWrite(default); _refreshQueue.Writer.TryWrite(default);
}; };
watcher.Renamed += static (_, _) => watcher.Renamed += static (_, _) =>
{ {
refreshQueue.Writer.TryWrite(default); _refreshQueue.Writer.TryWrite(default);
}; };
watcher.EnableRaisingEvents = true; watcher.EnableRaisingEvents = true;
@ -169,7 +170,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
public static void ReloadAllBookmarks(bool disposeFileWatchers = true) public static void ReloadAllBookmarks(bool disposeFileWatchers = true)
{ {
cachedBookmarks.Clear(); _cachedBookmarks.Clear();
if (disposeFileWatchers) if (disposeFileWatchers)
DisposeFileWatchers(); DisposeFileWatchers();
LoadBookmarksIfEnabled(); LoadBookmarksIfEnabled();
@ -177,12 +178,12 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
public string GetTranslatedPluginTitle() public string GetTranslatedPluginTitle()
{ {
return context.API.GetTranslation("flowlauncher_plugin_browserbookmark_plugin_name"); return _context.API.GetTranslation("flowlauncher_plugin_browserbookmark_plugin_name");
} }
public string GetTranslatedPluginDescription() public string GetTranslatedPluginDescription()
{ {
return context.API.GetTranslation("flowlauncher_plugin_browserbookmark_plugin_description"); return _context.API.GetTranslation("flowlauncher_plugin_browserbookmark_plugin_description");
} }
public Control CreateSettingPanel() public Control CreateSettingPanel()
@ -196,13 +197,13 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
{ {
new Result new Result
{ {
Title = context.API.GetTranslation("flowlauncher_plugin_browserbookmark_copyurl_title"), Title = _context.API.GetTranslation("flowlauncher_plugin_browserbookmark_copyurl_title"),
SubTitle = context.API.GetTranslation("flowlauncher_plugin_browserbookmark_copyurl_subtitle"), SubTitle = _context.API.GetTranslation("flowlauncher_plugin_browserbookmark_copyurl_subtitle"),
Action = _ => Action = _ =>
{ {
try try
{ {
context.API.CopyToClipboard(((BookmarkAttributes)selectedResult.ContextData).Url); _context.API.CopyToClipboard(((BookmarkAttributes)selectedResult.ContextData).Url);
return true; return true;
} }
@ -211,12 +212,12 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
var message = "Failed to set url in clipboard"; var message = "Failed to set url in clipboard";
Log.Exception("Main", message, e, "LoadContextMenus"); Log.Exception("Main", message, e, "LoadContextMenus");
context.API.ShowMsg(message); _context.API.ShowMsg(message);
return false; return false;
} }
}, },
IcoPath = "Images\\copylink.png", IcoPath = @"Images\copylink.png",
Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\ue8c8") Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\ue8c8")
} }
}; };
@ -241,4 +242,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark
Watchers.Clear(); Watchers.Clear();
} }
} }
}

View file

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Flow.Launcher.Plugin.BrowserBookmark.Models namespace Flow.Launcher.Plugin.BrowserBookmark.Models;
{
// Source may be important in the future // Source may be important in the future
public record Bookmark(string Name, string Url, string Source = "") public record Bookmark(string Name, string Url, string Source = "")
{ {
@ -19,4 +19,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Models
public List<CustomBrowser> CustomBrowsers { get; set; } = new(); public List<CustomBrowser> CustomBrowsers { get; set; } = new();
} }
}

View file

@ -1,10 +1,10 @@
namespace Flow.Launcher.Plugin.BrowserBookmark.Models namespace Flow.Launcher.Plugin.BrowserBookmark.Models;
{
public class CustomBrowser : BaseModel public class CustomBrowser : BaseModel
{ {
private string _name; private string _name;
private string _dataDirectoryPath; private string _dataDirectoryPath;
private BrowserType browserType = BrowserType.Chromium; private BrowserType _browserType = BrowserType.Chromium;
public string Name public string Name
{ {
@ -12,7 +12,7 @@
set set
{ {
_name = value; _name = value;
OnPropertyChanged(nameof(Name)); OnPropertyChanged();
} }
} }
@ -22,17 +22,17 @@
set set
{ {
_dataDirectoryPath = value; _dataDirectoryPath = value;
OnPropertyChanged(nameof(DataDirectoryPath)); OnPropertyChanged();
} }
} }
public BrowserType BrowserType public BrowserType BrowserType
{ {
get => browserType; get => _browserType;
set set
{ {
browserType = value; _browserType = value;
OnPropertyChanged(nameof(BrowserType)); OnPropertyChanged();
} }
} }
} }
@ -42,4 +42,3 @@
Chromium, Chromium,
Firefox, Firefox,
} }
}

View file

@ -1,7 +1,7 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
namespace Flow.Launcher.Plugin.BrowserBookmark.Models namespace Flow.Launcher.Plugin.BrowserBookmark.Models;
{
public class Settings : BaseModel public class Settings : BaseModel
{ {
public bool OpenInNewBrowserWindow { get; set; } = true; public bool OpenInNewBrowserWindow { get; set; } = true;
@ -14,4 +14,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Models
public ObservableCollection<CustomBrowser> CustomChromiumBrowsers { get; set; } = new(); public ObservableCollection<CustomBrowser> CustomChromiumBrowsers { get; set; } = new();
} }
}

View file

@ -63,7 +63,6 @@
<StackPanel Margin="26,0,26,0"> <StackPanel Margin="26,0,26,0">
<StackPanel Margin="0,0,0,12"> <StackPanel Margin="0,0,0,12">
<TextBlock <TextBlock
Grid.Column="0"
Margin="0,0,0,0" Margin="0,0,0,0"
FontSize="20" FontSize="20"
FontWeight="SemiBold" FontWeight="SemiBold"

View file

@ -3,18 +3,18 @@ using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Forms; using System.Windows.Forms;
namespace Flow.Launcher.Plugin.BrowserBookmark.Views namespace Flow.Launcher.Plugin.BrowserBookmark.Views;
{
/// <summary> /// <summary>
/// Interaction logic for CustomBrowserSetting.xaml /// Interaction logic for CustomBrowserSetting.xaml
/// </summary> /// </summary>
public partial class CustomBrowserSettingWindow : Window public partial class CustomBrowserSettingWindow : Window
{ {
private CustomBrowser currentCustomBrowser; private CustomBrowser _currentCustomBrowser;
public CustomBrowserSettingWindow(CustomBrowser browser) public CustomBrowserSettingWindow(CustomBrowser browser)
{ {
InitializeComponent(); InitializeComponent();
currentCustomBrowser = browser; _currentCustomBrowser = browser;
DataContext = new CustomBrowser DataContext = new CustomBrowser
{ {
Name = browser.Name, Name = browser.Name,
@ -26,9 +26,9 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
private void ConfirmEditCustomBrowser(object sender, RoutedEventArgs e) private void ConfirmEditCustomBrowser(object sender, RoutedEventArgs e)
{ {
CustomBrowser editBrowser = (CustomBrowser)DataContext; CustomBrowser editBrowser = (CustomBrowser)DataContext;
currentCustomBrowser.Name = editBrowser.Name; _currentCustomBrowser.Name = editBrowser.Name;
currentCustomBrowser.DataDirectoryPath = editBrowser.DataDirectoryPath; _currentCustomBrowser.DataDirectoryPath = editBrowser.DataDirectoryPath;
currentCustomBrowser.BrowserType = editBrowser.BrowserType; _currentCustomBrowser.BrowserType = editBrowser.BrowserType;
DialogResult = true; DialogResult = true;
Close(); Close();
} }
@ -54,4 +54,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
editBrowser.DataDirectoryPath = dialog.SelectedPath; editBrowser.DataDirectoryPath = dialog.SelectedPath;
} }
} }
}

View file

@ -4,8 +4,8 @@ using System.Windows.Input;
using System.ComponentModel; using System.ComponentModel;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Flow.Launcher.Plugin.BrowserBookmark.Views namespace Flow.Launcher.Plugin.BrowserBookmark.Views;
{
public partial class SettingsControl : INotifyPropertyChanged public partial class SettingsControl : INotifyPropertyChanged
{ {
public Settings Settings { get; } public Settings Settings { get; }
@ -92,13 +92,11 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
private void Others_Click(object sender, RoutedEventArgs e) private void Others_Click(object sender, RoutedEventArgs e)
{ {
CustomBrowsersList.Visibility = CustomBrowsersList.Visibility switch
if (CustomBrowsersList.Visibility == Visibility.Collapsed)
{ {
CustomBrowsersList.Visibility = Visibility.Visible; Visibility.Collapsed => Visibility.Visible,
} _ => Visibility.Collapsed
else };
CustomBrowsersList.Visibility = Visibility.Collapsed;
} }
private void EditCustomBrowser(object sender, RoutedEventArgs e) private void EditCustomBrowser(object sender, RoutedEventArgs e)
@ -119,4 +117,3 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
} }
} }
} }
}

178
README.md
View file

@ -16,77 +16,15 @@
</p> </p>
<p align="center"> <p align="center">
Dedicated to making your work flow more seamless. Search everything from applications, files, bookmarks, YouTube, Twitter and more. Flow will continue to evolve, designed to be open and built with the community at heart. A quick file search and app launcher for Windows with community-made plugins.</p>
<p align="center">
Dedicated to making your work flow more seamless. Search everything from applications, files, bookmarks, YouTube, Twitter and more. Flow will continue to evolve, designed to be open and built with the community at heart.</p>
<p align="center"> <sub>Remember to star it, flow will love you more :)</sub></p> <p align="center"> <sub>Remember to star it, flow will love you more :)</sub></p>
<img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%"> <img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%">
## 🎅 New Features🤶
### Preview Panel
<img src="https://user-images.githubusercontent.com/6903107/207159213-662999d3-2c18-4256-b473-c417efca0069.png" width="400">
- Use the F1 key to open/hide the preview panel.
- Media files will be displayed as large images, otherwise a large icon and entire path will be displayed.
- Turn on preview permanently via Settings (Always Preview).
- Use hotkeys (Ctrl+Plus,Minus / Ctrl+],[) to adjust flow's search window width and height quickly if the preview area is too narrow.
- This feature is currently in its early stages.
### Everything Plugin Merged Into Explorer
<img src="https://user-images.githubusercontent.com/6903107/207171178-78912e76-31c2-4ba2-b3cf-de4b0b5e5691.png" width="300">
- Switch easily between Everything and Windows Search to take advantage of both search engines (remember to remove existing Everything plugin).
- Use features available to both Everything and Explorer plugins
### Date & Time Display In Search Window
<img src="https://user-images.githubusercontent.com/6903107/207159348-8b0c7a2b-0836-4764-916b-e0236087f7f3.png" width="400">
- Display the date and time when the search window is triggered.
### Drag & Drop
<img src="https://user-images.githubusercontent.com/6903107/207159486-1993510f-09f2-4e33-bba7-4ca59ca1bc5a.png" width="500">
- Drag an item to Discord or computer location.
- The target program determines whether the drop is to copy or move the item (can change via CTRL or Alt), and the operation is displayed on the mouse cursor.
### Custom Shortcut
<img src="Flow.Launcher/Images/illustration_02.png" width="300">
<img src="Flow.Launcher/Images/illustration_01.png" width="300">
- New shortcut functionality to set additional action keywords or search terms.
### Improved Program Plugin
- PATH is now indexed
- Support for .url files, flow can now search installed steam/epic games.
- Improved UWP indexing.
### Improved Memory Usage
- Fixed a memory leak and reduced overall memory usage.
### Improved Plugin / Plugin Store
- Search plugins in the Plugin Store and existing plugin tab.
- Categorised sections in Plugin Store to easily see new and updated plugins.
### Improved Non-C# Plugin's Panel Design
<img src="https://user-images.githubusercontent.com/6903107/207166078-871a17aa-5ab4-4808-8d8f-12b7cb66ea89.png" width="450">
- The design has been adjusted to align to the overall look and feel of flow.
- Simplified the information displayed on buttons
🚂[Full Changelogs](https://github.com/Flow-Launcher/Flow.Launcher/releases)
<img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%">
<h4 align="center"> <h4 align="center">
<a href="#-getting-started">Getting Started</a> <a href="#-getting-started">Getting Started</a>
<a href="#-features">Features</a> <a href="#-features">Features</a>
@ -104,15 +42,29 @@ Dedicated to making your work flow more seamless. Search everything from applica
### Installation ### Installation
| [Windows 7+ installer](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest/download/Flow-Launcher-Setup.exe) | [Portable](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest/download/Flow-Launcher-Portable.zip) | [Windows 7+ Installer](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest/download/Flow-Launcher-Setup.exe) or [Portable Version](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest/download/Flow-Launcher-Portable.zip)
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| `winget install "Flow Launcher"` | `scoop install Flow-Launcher` | `choco install Flow-Launcher` | #### Winget
| :------------------------------: | :------------------------------: | :------------------------------: |
```
winget install "Flow Launcher"
```
#### Scoop
```
scoop install Flow-Launcher
```
#### Chocolatey
```
choco install Flow-Launcher
```
> When installing for the first time Windows may raise an issue about security due to code not being signed, if you downloaded from this repo then you are good to continue the set up. > When installing for the first time Windows may raise an issue about security due to code not being signed, if you downloaded from this repo then you are good to continue the set up.
And you can download [early access version](https://github.com/Flow-Launcher/Prereleases/releases). Or download the [early access version](https://github.com/Flow-Launcher/Prereleases/releases).
<img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%"> <img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%">
@ -123,6 +75,7 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
<img src="https://user-images.githubusercontent.com/6903107/145332614-74909973-f6eb-47c2-8235-289931e30718.png" width="400"> <img src="https://user-images.githubusercontent.com/6903107/145332614-74909973-f6eb-47c2-8235-289931e30718.png" width="400">
- Search for apps, files or file contents. - Search for apps, files or file contents.
- Supports Everything and Windows Index.
<img src="https://user-images.githubusercontent.com/6903107/145018796-658b7c24-a34f-46b6-98d4-cf4f636d8b60.png" width="400"> <img src="https://user-images.githubusercontent.com/6903107/145018796-658b7c24-a34f-46b6-98d4-cf4f636d8b60.png" width="400">
@ -156,7 +109,7 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
<img src="https://user-images.githubusercontent.com/6903107/207142197-9e910147-96a9-466e-bbc4-b1163314ef59.png" width="400"> <img src="https://user-images.githubusercontent.com/6903107/207142197-9e910147-96a9-466e-bbc4-b1163314ef59.png" width="400">
- Run batch and PowerShell commands as Administrator or a different user. - Run batch and PowerShell commands as Administrator or a different user.
- Ctrl+Enter to Run as Administrator. - <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Enter</kbd> to Run as Administrator.
### Explorer ### Explorer
@ -164,6 +117,13 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
- Save file or folder locations for quick access. - Save file or folder locations for quick access.
#### Drag & Drop
<img src="https://user-images.githubusercontent.com/6903107/207159486-1993510f-09f2-4e33-bba7-4ca59ca1bc5a.png" width="500">
- Drag a file/folder to File Exlporer, or even Discord.
- Copy/move behavior can be change via <kbd>Ctrl</kbd> or <kbd>Shift</kbd>, and the operation is displayed on the mouse cursor.
### Windows & Control Panel Settings ### Windows & Control Panel Settings
<img src="https://user-images.githubusercontent.com/6903107/207140658-52c1bea6-5b14-4db8-ae35-acc65e6bda85.png" width="400"> <img src="https://user-images.githubusercontent.com/6903107/207140658-52c1bea6-5b14-4db8-ae35-acc65e6bda85.png" width="400">
@ -176,6 +136,16 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
- Prioritise the order of each plugin's results. - Prioritise the order of each plugin's results.
### Preview Panel
<img src="https://user-images.githubusercontent.com/6903107/207159213-662999d3-2c18-4256-b473-c417efca0069.png" width="400">
- Use <kbd>F1</kbd> to toggle the preview panel.
- Media files will be displayed as large images, otherwise a large icon and full path will be displayed.
- Turn on preview permanently via Settings (Always Preview).
- Use <kbd>Ctrl</kbd>+<kbd>+</kbd>/<kbd>-</kbd> and <kbd>Ctrl</kbd>+<kbd>[</kbd>/<kbd>]</kbd> to adjust search window width and height quickly if the preview area is too narrow.
### Customizations ### Customizations
<img src="https://user-images.githubusercontent.com/6903107/144693887-1b92ed16-dca1-4b7e-8644-5e9524cdfb31.gif" width="500"> <img src="https://user-images.githubusercontent.com/6903107/144693887-1b92ed16-dca1-4b7e-8644-5e9524cdfb31.gif" width="500">
@ -187,12 +157,48 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
- There are various themes and you also can make your own. - There are various themes and you also can make your own.
### 💬 Language #### Date & Time Display In Search Window
<img src="https://user-images.githubusercontent.com/6903107/207159348-8b0c7a2b-0836-4764-916b-e0236087f7f3.png" width="400">
- Display date and time in search window.
### 💬 Languages
- Supports languages from Chinese to Italian and more. - Supports languages from Chinese to Italian and more.
- Supports Pinyin search. - Supports Pinyin (拼音) search.
- [Crowdin](https://crowdin.com/project/flow-launcher) support for language translations. - [Crowdin](https://crowdin.com/project/flow-launcher) support for language translations.
<details>
<summary>Supported languages</summary>
<ul>
<li>English</li>
<li>中文</li>
<li>中文(繁体)</li>
<li>Українська</li>
<li>Русский</li>
<li>Français</li>
<li>日本語</li>
<li>Dutch</li>
<li>Polski</li>
<li>Dansk</li>
<li>de, Deutsch</li>
<li>ko, 한국어</li>
<li>Srpski</li>
<li>Português</li>
<li>Português (Brasil)</li>
<li>Spanish</li>
<li>es-419, Spanish (Latin America)</li>
<li>Italiano</li>
<li>Norsk Bokmål</li>
<li>Slovenčina</li>
<li>Türkçe</li>
<li>čeština</li>
<li>اللغة العربية</li>
<li>Tiếng Việt</li>
</ul>
</details>
### Portable ### Portable
- Fully portable. - Fully portable.
@ -206,7 +212,7 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
<img src="https://user-images.githubusercontent.com/6903107/207144711-0c5f8b2b-4b1b-44c8-b23e-c123f6b05146.png" width="200"> <img src="https://user-images.githubusercontent.com/6903107/207144711-0c5f8b2b-4b1b-44c8-b23e-c123f6b05146.png" width="200">
- Pause hotkey activation when you are playing games. - Pause hotkey activation when you are playing games.
- When in search window use Ctrl+F12 to toggle on/off. - When in search window use <kbd>Ctrl</kbd>+<kbd>F12</kbd> to toggle on/off.
- Type `Toggle Game Mode` - Type `Toggle Game Mode`
<img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%"> <img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%">
@ -257,6 +263,7 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
<img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%"> <img src="https://user-images.githubusercontent.com/6903107/144858082-8b654daf-60fb-4ee6-89b2-6183b73510d1.png" width="100%">
### 🛒 Plugin Store ### 🛒 Plugin Store
<img src="https://user-images.githubusercontent.com/6903107/207155616-d559f0d2-ee95-4072-a7bc-3ffcc2faec27.png" width="700"> <img src="https://user-images.githubusercontent.com/6903107/207155616-d559f0d2-ee95-4072-a7bc-3ffcc2faec27.png" width="700">
- You can view the full plugin list or quickly install a plugin via the Plugin Store menu inside Settings - You can view the full plugin list or quickly install a plugin via the Plugin Store menu inside Settings
@ -268,25 +275,28 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
## ⌨️ Hotkeys ## ⌨️ Hotkeys
| Hotkey | Description | | Hotkey | Description |
| ------------------------------------------------------------------ | ---------------------------------------------- | | ------------------------------------------------------------------------- | ----------------------------------------------- |
| <kbd>Alt</kbd>+<kbd>Space</kbd> | Open search window (default and configurable) | | <kbd>Alt</kbd>+<kbd>Space</kbd> | Open search window (default and configurable) |
| <kbd>Enter</kbd> | Execute | | <kbd>Enter</kbd> | Execute |
| <kbd>Ctrl</kbd>+<kbd>Enter</kbd> | Open containing folder |
| <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Enter</kbd> | Run as admin | | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Enter</kbd> | Run as admin |
| <kbd></kbd><kbd></kbd> | Scroll up & down | | <kbd></kbd>/<kbd></kbd>, <kbd>Shift</kbd>+<kbd>Tab</kbd>/<kbd>Tab</kbd> | Previous / Next result |
| <kbd></kbd><kbd></kbd> | Back to result / Open Context Menu | | <kbd></kbd>/<kbd></kbd> | Back to result / Open Context Menu |
| <kbd>Ctrl</kbd>+<kbd>O</kbd> , <kbd>Shift</kbd>+<kbd>Enter</kbd> | Open Context Menu | | <kbd>Ctrl</kbd>+<kbd>O</kbd> , <kbd>Shift</kbd>+<kbd>Enter</kbd> | Open Context Menu |
| <kbd>Tab</kbd> | Autocomplete | | <kbd>Ctrl</kbd>+<kbd>Tab</kbd> | Autocomplete |
| <kbd>F1</kbd> | Toggle Preview Panel (default and configurable) | | <kbd>F1</kbd> | Toggle Preview Panel (default and configurable) |
| <kbd>Esc</kbd> | Back to results / hide search window | | <kbd>Esc</kbd> | Back to results / hide search window |
| <kbd>Ctrl</kbd> +<kbd>C</kbd> | Copy the actual folder / file | | <kbd>Ctrl</kbd>+<kbd>C</kbd> | Copy folder / file |
| <kbd>Ctrl</kbd> +<kbd>I</kbd> | Open flow's settings | | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>C</kbd> | Copy folder / file path |
| <kbd>Ctrl</kbd>+<kbd>I</kbd> | Open Flow's settings |
| <kbd>Ctrl</kbd>+<kbd>R</kbd> | Run the current query again (refresh results) | | <kbd>Ctrl</kbd>+<kbd>R</kbd> | Run the current query again (refresh results) |
| <kbd>F5</kbd> | Reload all plugin data | | <kbd>F5</kbd> | Reload all plugin data |
| <kbd>Ctrl</kbd>+<kbd>F12</kbd> | Toggle Game Mode when in search window | | <kbd>Ctrl</kbd>+<kbd>F12</kbd> | Toggle Game Mode when in search window |
| <kbd>Ctrl</kbd> + <kbd>+</kbd>,<kbd>-</kbd> | Quickly change maximum results shown | | <kbd>Ctrl</kbd>+<kbd>+</kbd>,<kbd>-</kbd> | Adjust maximum results shown |
| <kbd>Ctrl</kbd> + <kbd>[</kbd>,<kbd>]</kbd> | Quickly change search window width | | <kbd>Ctrl</kbd>+<kbd>[</kbd>,<kbd>]</kbd> | Adjust search window width |
| <kbd>Ctrl</kbd>+<kbd>H</kbd> | Open search history | | <kbd>Ctrl</kbd>+<kbd>H</kbd> | Open search history |
| <kbd>Ctrl</kbd>+<kbd>Backspace</kbd> | Back to previous directory | | <kbd>Ctrl</kbd>+<kbd>Backspace</kbd> | Back to previous directory |
| <kbd>PageUp</kbd>/<kbd>PageDown</kbd> | Previous / Next Page |
## System Command List ## System Command List
@ -313,8 +323,6 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre
| Flow Launcher UserData Folder | Open the location where Flow Launcher's settings are stored | | Flow Launcher UserData Folder | Open the location where Flow Launcher's settings are stored |
| Toggle Game Mode | Toggle Game Mode | | Toggle Game Mode | Toggle Game Mode |
### 💁‍♂️ Tips ### 💁‍♂️ Tips
- [More tips](https://flowlauncher.com/docs/#/usage-tips) - [More tips](https://flowlauncher.com/docs/#/usage-tips)