diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index d4eb02a909e..cb60251ed95 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -88,6 +88,11 @@ public interface IPublicAPI
/// Show the MainWindow when hiding
///
void ShowMainWindow();
+
+ ///
+ /// Focus the query text box in the main window
+ ///
+ void FocusQueryTextBox();
///
/// Hide MainWindow
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index a0614d90fd5..66e11f88130 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -10,6 +11,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Input;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
@@ -32,7 +34,6 @@
using JetBrains.Annotations;
using Squirrel;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
-using System.ComponentModel;
namespace Flow.Launcher
{
@@ -93,6 +94,8 @@ public async void RestartApp()
public void ShowMainWindow() => _mainVM.Show();
+ public void FocusQueryTextBox() => _mainVM.FocusQueryTextBox();
+
public void HideMainWindow() => _mainVM.Hide();
public bool IsMainWindowVisible() => _mainVM.MainWindowVisibilityStatus;
diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs
index 807275fcbd5..6e1b0dd9379 100644
--- a/Flow.Launcher/ViewModel/MainViewModel.cs
+++ b/Flow.Launcher/ViewModel/MainViewModel.cs
@@ -1926,6 +1926,21 @@ public void UpdateResultView(ICollection resultsForUpdates)
Results.AddResults(resultsForUpdates, token, reSelect);
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "")]
+ public void FocusQueryTextBox()
+ {
+ // When application is exiting, the Application.Current will be null
+ Application.Current?.Dispatcher.Invoke(() =>
+ {
+ // When application is exiting, the Application.Current will be null
+ if (Application.Current?.MainWindow is MainWindow window)
+ {
+ window.QueryTextBox.Focus();
+ Keyboard.Focus(window.QueryTextBox);
+ }
+ });
+ }
+
#endregion
#region IDisposable
diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
index 0d395c0537a..2613c770b35 100644
--- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs
@@ -378,11 +378,17 @@ bool API_GlobalKeyboardEvent(int keyevent, int vkcode, SpecialKeyState state)
private void OnWinRPressed()
{
+ Context.API.ShowMainWindow();
// show the main window and set focus to the query box
- _ = Task.Run(() =>
+ _ = Task.Run(async () =>
{
- Context.API.ShowMainWindow();
Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}");
+
+ // Win+R is a system-reserved shortcut, and though the plugin intercepts the keyboard event and
+ // shows the main window, Windows continues to process the Win key and briefly reclaims focus.
+ // So we need to wait until the keyboard event processing is completed and then set focus
+ await Task.Delay(50);
+ Context.API.FocusQueryTextBox();
});
}