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..18de790c5b1 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,40 @@ internal static bool IsForegroundWindow(HWND handle)
return handle.Equals(PInvoke.GetForegroundWindow());
}
+ ///
+ /// Brings the window to foreground if window is visible. From https://github.com/files-community/Files.
+ ///
+ ///
+ /// For more information, visit
+ ///
+ /// -
+ ///
+ /// -
+ ///
+ /// The window to bring.
+ 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 a86b96800c2..4bb87424bee 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;
@@ -412,11 +412,11 @@ 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
- await Task.Delay(50);
+ await Task.Delay(1000);
Context.API.FocusQueryTextBox();
});
}