Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Fixed issue where window wasn't always brought to foreground #14917

Merged
merged 7 commits into from Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/Files.App/Helpers/Interop/InteropHelpers.cs
Expand Up @@ -29,9 +29,6 @@ public static class InteropHelpers
[DllImport("kernel32.dll")]
public static extern bool SetEvent(IntPtr hEvent);

[DllImport("user32.dll", SetLastError = true)]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool altTab);

[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int GetDpiForWindow(IntPtr hwnd);

Expand Down
38 changes: 38 additions & 0 deletions src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs
@@ -0,0 +1,38 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;

namespace Files.App.Helpers
{
public static partial class Win32Helper
{
/// <summary>
/// Brings the app window to foreground.
/// </summary>
/// <remarks>
/// For more information, visit
/// <br/>
/// - <a href="https://stackoverflow.com/questions/1544179/what-are-the-differences-between-bringwindowtotop-setforegroundwindow-setwindo" />
/// <br/>
/// - <a href="https://stackoverflow.com/questions/916259/win32-bring-a-window-to-top" />
/// </remarks>
/// <param name="hWnd">The window handle to bring.</param>
public static unsafe void BringToForegroundEx(Windows.Win32.Foundation.HWND hWnd)
{
var hCurWnd = PInvoke.GetForegroundWindow();
var dwMyID = PInvoke.GetCurrentThreadId();
var dwCurID = PInvoke.GetWindowThreadProcessId(hCurWnd);

PInvoke.AttachThreadInput(dwCurID, dwMyID, true);

PInvoke.SetWindowPos(hWnd, (Windows.Win32.Foundation.HWND)(-1), 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE);
PInvoke.SetWindowPos(hWnd, (Windows.Win32.Foundation.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);
}
}
}
20 changes: 17 additions & 3 deletions src/Files.App/MainWindow.xaml.cs
Expand Up @@ -93,7 +93,9 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
}
else if (!(string.IsNullOrEmpty(launchArgs.Arguments) && MainPageViewModel.AppInstances.Count > 0))
{
InteropHelpers.SwitchToThisWindow(WindowHandle, true);
// Bring to foreground (#14730)
Win32Helper.BringToForegroundEx(new(WindowHandle));

await NavigationHelpers.AddNewTabByPathAsync(typeof(PaneHolderPage), launchArgs.Arguments, true);
}
else
Expand All @@ -106,6 +108,12 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
if (eventArgs.Uri.AbsoluteUri == "files-uwp:")
{
rootFrame.Navigate(typeof(MainPage), null, new SuppressNavigationTransitionInfo());

if (MainPageViewModel.AppInstances.Count > 0)
{
// Bring to foreground (#14730)
Win32Helper.BringToForegroundEx(new(WindowHandle));
}
}
else
{
Expand Down Expand Up @@ -171,7 +179,11 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
index = 1;
}
else
InteropHelpers.SwitchToThisWindow(WindowHandle, true);
{
// Bring to foreground (#14730)
Win32Helper.BringToForegroundEx(new(WindowHandle));
}

for (; index < fileArgs.Files.Count; index++)
{
await NavigationHelpers.AddNewTabByPathAsync(typeof(PaneHolderPage), fileArgs.Files[index].Path, true);
Expand Down Expand Up @@ -245,7 +257,9 @@ async Task PerformNavigationAsync(string payload, string selectItem = null)

if (rootFrame.Content is MainPage && MainPageViewModel.AppInstances.Any())
{
InteropHelpers.SwitchToThisWindow(WindowHandle, true);
// Bring to foreground (#14730)
Win32Helper.BringToForegroundEx(new(WindowHandle));

await NavigationHelpers.AddNewTabByParamAsync(typeof(PaneHolderPage), paneNavigationArgs);
}
else
Expand Down
8 changes: 8 additions & 0 deletions src/Files.App/NativeMethods.txt
Expand Up @@ -31,3 +31,11 @@ LPARAM
WM_LBUTTONUP
WM_RBUTTONUP
WM_DESTROY
SetForegroundWindow
GetForegroundWindow
GetCurrentThreadId
GetWindowThreadProcessId
AttachThreadInput
SetWindowPos
SetFocus
SetActiveWindow