From edae4328527e68dbca8d71fd343f154bb453b3ea Mon Sep 17 00:00:00 2001 From: DB p Date: Thu, 22 May 2025 04:14:30 +0900 Subject: [PATCH 1/2] Add FocusQueryTextBox method to set focus on the query text box in MainWindow --- Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 5 +++++ Flow.Launcher/PublicAPIInstance.cs | 13 +++++++++++++ Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 7 +++++-- 3 files changed, 23 insertions(+), 2 deletions(-) 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..7b80ec48029 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -33,6 +33,7 @@ using Squirrel; using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; using System.ComponentModel; +using System.Windows.Input; namespace Flow.Launcher { @@ -92,6 +93,18 @@ public async void RestartApp() } public void ShowMainWindow() => _mainVM.Show(); + + public void FocusQueryTextBox() + { + Application.Current.Dispatcher.Invoke(new Action(() => + { + if (Application.Current.MainWindow is MainWindow mw) + { + mw.QueryTextBox.Focus(); + Keyboard.Focus(mw.QueryTextBox); + } + })); + } public void HideMainWindow() => _mainVM.Hide(); diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs index 0d395c0537a..758ad09d52e 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs @@ -378,10 +378,13 @@ 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(); + await Task.Delay(50); // 💡 키보드 이벤트 처리가 끝난 뒤 + Context.API.FocusQueryTextBox(); + Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeywords[0]}{Plugin.Query.TermSeparator}"); }); } From 3718ae5640bbe5e9af2a389964386d9d81444114 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 22 May 2025 10:39:09 +0800 Subject: [PATCH 2/2] Improve code quality & Improve code comments --- Flow.Launcher/PublicAPIInstance.cs | 18 ++++-------------- Flow.Launcher/ViewModel/MainViewModel.cs | 15 +++++++++++++++ Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 9 ++++++--- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 7b80ec48029..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,8 +34,6 @@ using JetBrains.Annotations; using Squirrel; using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; -using System.ComponentModel; -using System.Windows.Input; namespace Flow.Launcher { @@ -93,18 +93,8 @@ public async void RestartApp() } public void ShowMainWindow() => _mainVM.Show(); - - public void FocusQueryTextBox() - { - Application.Current.Dispatcher.Invoke(new Action(() => - { - if (Application.Current.MainWindow is MainWindow mw) - { - mw.QueryTextBox.Focus(); - Keyboard.Focus(mw.QueryTextBox); - } - })); - } + + public void FocusQueryTextBox() => _mainVM.FocusQueryTextBox(); public void HideMainWindow() => _mainVM.Hide(); 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 758ad09d52e..2613c770b35 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs @@ -382,10 +382,13 @@ private void OnWinRPressed() // show the main window and set focus to the query box _ = Task.Run(async () => { - await Task.Delay(50); // 💡 키보드 이벤트 처리가 끝난 뒤 - Context.API.FocusQueryTextBox(); - 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(); }); }