From 99195bb6e8f5e9d373309d09f7ace2a3008ab7dd Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 20:49:43 +0800 Subject: [PATCH 1/3] Enlarge delay time --- Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs index a86b96800c2..dc2638a58cb 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -416,7 +416,7 @@ private void OnWinRPressed() // 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); + await Task.Delay(1000); Context.API.FocusQueryTextBox(); }); } From b393e9ac5b42ebb3b2f839acb2f9d9ce8eac3b30 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 21:07:20 +0800 Subject: [PATCH 2/3] Add BringToForegroundEx --- .../NativeMethods.txt | 11 +++++- Flow.Launcher.Infrastructure/Win32Helper.cs | 37 ++++++++++++++++++- Flow.Launcher/ViewModel/MainViewModel.cs | 1 + Plugins/Flow.Launcher.Plugin.Shell/Main.cs | 2 +- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt index eb844dd7ca0..085a6b3e148 100644 --- a/Flow.Launcher.Infrastructure/NativeMethods.txt +++ b/Flow.Launcher.Infrastructure/NativeMethods.txt @@ -86,4 +86,13 @@ EVENT_OBJECT_HIDE EVENT_SYSTEM_DIALOGEND WM_POWERBROADCAST -PBT_APMRESUMEAUTOMATIC \ No newline at end of file +PBT_APMRESUMEAUTOMATIC + +SetForegroundWindow +GetForegroundWindow +GetCurrentThreadId +GetWindowThreadProcessId +AttachThreadInput +SetWindowPos +SetFocus +SetActiveWindow \ No newline at end of file diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs index 8117339254d..2dcaf6dcdb4 100644 --- a/Flow.Launcher.Infrastructure/Win32Helper.cs +++ b/Flow.Launcher.Infrastructure/Win32Helper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -151,6 +151,41 @@ internal static bool IsForegroundWindow(HWND handle) return handle.Equals(PInvoke.GetForegroundWindow()); } + /// + /// Brings the app window to foreground. From https://github.com/files-community/Files. + /// + /// + /// For more information, visit + ///
+ /// - + ///
+ /// -
+ ///
+ /// The window handle to bring. + /// If true, the window will be set as topmost before bringing it to the foreground. + public static unsafe void BringToForegroundEx(Window window) + { + var hWnd = GetWindowHandle(window); + var topMost = window.Topmost; + var hCurWnd = PInvoke.GetForegroundWindow(); + var dwMyID = PInvoke.GetCurrentThreadId(); + var dwCurID = PInvoke.GetWindowThreadProcessId(hCurWnd); + + PInvoke.AttachThreadInput(dwCurID, dwMyID, true); + + // Set the window to be the topmost window + PInvoke.SetWindowPos(hWnd, (HWND)(-1), 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE); + if (!topMost) + { + // Restore the window to its original position + PInvoke.SetWindowPos(hWnd, (HWND)(-2), 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW | SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE); + } + PInvoke.SetForegroundWindow(hWnd); + PInvoke.SetFocus(hWnd); + PInvoke.SetActiveWindow(hWnd); + PInvoke.AttachThreadInput(dwCurID, dwMyID, false); + } + #endregion #region Task Switching diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index d492f28c58c..2ba1e8a7223 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -2249,6 +2249,7 @@ public void FocusQueryTextBox() // When application is exiting, the Application.Current will be null if (Application.Current?.MainWindow is MainWindow window) { + Win32Helper.BringToForegroundEx(window); window.QueryTextBox.Focus(); Keyboard.Focus(window.QueryTextBox); } diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs index dc2638a58cb..4bb87424bee 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs @@ -412,7 +412,7 @@ private void OnWinRPressed() _ = Task.Run(async () => { 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 From 69072c3ed768bef009b025a11b91f36266f28926 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Wed, 17 Sep 2025 21:08:09 +0800 Subject: [PATCH 3/3] Improve code comments --- Flow.Launcher.Infrastructure/Win32Helper.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs index 2dcaf6dcdb4..18de790c5b1 100644 --- a/Flow.Launcher.Infrastructure/Win32Helper.cs +++ b/Flow.Launcher.Infrastructure/Win32Helper.cs @@ -152,7 +152,7 @@ internal static bool IsForegroundWindow(HWND handle) } /// - /// Brings the app window to foreground. From https://github.com/files-community/Files. + /// Brings the window to foreground if window is visible. From https://github.com/files-community/Files. /// /// /// For more information, visit @@ -161,8 +161,7 @@ internal static bool IsForegroundWindow(HWND handle) ///
/// -
/// - /// The window handle to bring. - /// If true, the window will be set as topmost before bringing it to the foreground. + /// The window to bring. public static unsafe void BringToForegroundEx(Window window) { var hWnd = GetWindowHandle(window);