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 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/Files.App/Helpers/Application/AppLifecycleHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using Windows.Storage;
using Windows.System;
using Windows.UI.Notifications;
using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;

namespace Files.App.Helpers
Expand Down Expand Up @@ -234,6 +236,33 @@ public static void SaveSessionTabs()
.ToList();
}

/// <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)
yaira2 marked this conversation as resolved.
Show resolved Hide resolved
{
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);
}

/// <summary>
/// Shows exception on the Debug Output and sends Toast Notification to the Windows Notification Center.
/// </summary>
Expand Down
22 changes: 19 additions & 3 deletions src/Files.App/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
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)
AppLifecycleHelper.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)
AppLifecycleHelper.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)
AppLifecycleHelper.BringToForegroundEx(new(WindowHandle));
}

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

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

await NavigationHelpers.AddNewTabByParamAsync(typeof(PaneHolderPage), paneNavigationArgs);
}
else
{
rootFrame.Navigate(typeof(MainPage), paneNavigationArgs, new SuppressNavigationTransitionInfo());
}
yaira2 marked this conversation as resolved.
Show resolved Hide resolved
}
foreach (var command in parsedCommands)
{
Expand Down
8 changes: 8 additions & 0 deletions src/Files.App/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,11 @@ LPARAM
WM_LBUTTONUP
WM_RBUTTONUP
WM_DESTROY
SetForegroundWindow
GetForegroundWindow
GetCurrentThreadId
GetWindowThreadProcessId
AttachThreadInput
SetWindowPos
SetFocus
SetActiveWindow
Loading