From 4860db1b4d03cc790b5ce14e3a2779d7d309e36d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 22 Nov 2024 08:14:11 -0300 Subject: [PATCH 01/10] Feature: Added support for not focusing Files window when dragging a file/folder (#13255) --- .../Win32/Win32Helper.WindowManagement.cs | 13 ++++ src/Files.App/MainWindow.xaml.cs | 31 +++++++++ src/Files.App/Views/Layouts/BaseLayoutPage.cs | 65 +++++++++++++++++-- .../Views/Layouts/ColumnLayoutPage.xaml | 1 + .../Views/Layouts/DetailsLayoutPage.xaml | 1 + .../Views/Layouts/GridLayoutPage.xaml | 1 + 6 files changed, 107 insertions(+), 5 deletions(-) diff --git a/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs b/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs index ff57f45abc32..56a0768c8252 100644 --- a/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs +++ b/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs @@ -4,8 +4,10 @@ using Microsoft.UI.Input; using Microsoft.UI.Xaml; using System.Reflection; +using System.Runtime.InteropServices; using Windows.Win32; using Windows.Win32.UI.WindowsAndMessaging; +using static Vanara.PInvoke.User32; namespace Files.App.Helpers { @@ -58,5 +60,16 @@ public static void ChangeCursor(this UIElement uiElement, InputCursor cursor) [cursor] ); } + + /// + /// Force window to stay at bottom of other upper windows. + /// + /// The lParam of the message. + public static void ForceWindowPosition(nint lParam) + { + var windowPos = Marshal.PtrToStructure(lParam); + windowPos.flags |= SetWindowPosFlags.SWP_NOZORDER; + Marshal.StructureToPtr(windowPos, lParam, false); + } } } diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index e80e55247649..dcdb6dc9bde5 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -19,6 +19,7 @@ public sealed partial class MainWindow : WinUIEx.WindowEx public static MainWindow Instance => _Instance ??= new(); public nint WindowHandle { get; } + private bool CanWindowToFront { get; set; } = true; public MainWindow() { @@ -35,6 +36,8 @@ public MainWindow() AppWindow.TitleBar.ButtonPressedBackgroundColor = Colors.Transparent; AppWindow.TitleBar.ButtonHoverBackgroundColor = Colors.Transparent; AppWindow.SetIcon(AppLifecycleHelper.AppIconPath); + + WinUIEx.WindowManager.Get(this).WindowMessageReceived += WindowManager_WindowMessageReceived; } public void ShowSplashScreen() @@ -339,5 +342,33 @@ x.tabItem.NavigationParameter.NavigationParameter is PaneNavigationArguments pan } } } + + public bool SetCanWindowToFront(bool canWindowToFront) + { + if (CanWindowToFront != canWindowToFront) + { + CanWindowToFront = canWindowToFront; + return true; + } + return false; + } + + public void BringToFrontEx() + { + Win32Helper.BringToForegroundEx(new(WindowHandle)); + } + + private const int WM_WINDOWPOSCHANGING = 0x0046; + private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e) + { + if (!CanWindowToFront) + { + if (e.Message.MessageId == WM_WINDOWPOSCHANGING) + { + Win32Helper.ForceWindowPosition(e.Message.LParam); + e.Handled = true; + } + } + } } } diff --git a/src/Files.App/Views/Layouts/BaseLayoutPage.cs b/src/Files.App/Views/Layouts/BaseLayoutPage.cs index 4a78f5a34e13..cd38a17d514b 100644 --- a/src/Files.App/Views/Layouts/BaseLayoutPage.cs +++ b/src/Files.App/Views/Layouts/BaseLayoutPage.cs @@ -66,6 +66,7 @@ public abstract class BaseLayoutPage : Page, IBaseLayoutPage, INotifyPropertyCha private CancellationTokenSource? groupingCancellationToken; private bool shiftPressed; + private bool itemDragging; private ListedItem? dragOverItem = null; private ListedItem? hoveredItem = null; @@ -1012,6 +1013,9 @@ protected virtual void FileList_DragItemsStarting(object sender, DragItemsStarti var storageItemList = orderedItems.Where(x => !(x.IsHiddenItem && x.IsLinkItem && x.IsRecycleBinItem && x.IsShortcut)).Select(x => VirtualStorageItem.FromListedItem(x)); e.Data.SetStorageItems(storageItemList, false); } + + MainWindow.Instance.SetCanWindowToFront(false); + itemDragging = true; } catch (Exception) { @@ -1019,6 +1023,12 @@ protected virtual void FileList_DragItemsStarting(object sender, DragItemsStarti } } + protected virtual void FileList_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args) + { + itemDragging = false; + MainWindow.Instance.SetCanWindowToFront(true); + } + private void Item_DragLeave(object sender, DragEventArgs e) { var item = GetItemFromElement(sender); @@ -1147,6 +1157,9 @@ protected void FileList_ContainerContentChanging(ListViewBase sender, ContainerC { RefreshContainer(args.ItemContainer, args.InRecycleQueue); RefreshItem(args.ItemContainer, args.Item, args.InRecycleQueue, args); + + MainWindow.Instance.SetCanWindowToFront(true); + itemDragging = false; } private void RefreshContainer(SelectorItem container, bool inRecycleQueue) @@ -1154,6 +1167,8 @@ private void RefreshContainer(SelectorItem container, bool inRecycleQueue) container.PointerPressed -= FileListItem_PointerPressed; container.PointerEntered -= FileListItem_PointerEntered; container.PointerExited -= FileListItem_PointerExited; + container.Tapped -= FileListItem_Tapped; + container.DoubleTapped -= FileListItem_DoubleTapped; container.RightTapped -= FileListItem_RightTapped; if (inRecycleQueue) @@ -1163,12 +1178,11 @@ private void RefreshContainer(SelectorItem container, bool inRecycleQueue) else { container.PointerPressed += FileListItem_PointerPressed; + container.PointerEntered += FileListItem_PointerEntered; + container.PointerExited += FileListItem_PointerExited; + container.Tapped += FileListItem_Tapped; + container.DoubleTapped += FileListItem_DoubleTapped; container.RightTapped += FileListItem_RightTapped; - if (UserSettingsService.FoldersSettingsService.SelectFilesOnHover) - { - container.PointerEntered += FileListItem_PointerEntered; - container.PointerExited += FileListItem_PointerExited; - } } } @@ -1200,6 +1214,9 @@ private void RefreshItem(SelectorItem container, object item, bool inRecycleQueu protected internal void FileListItem_PointerPressed(object sender, PointerRoutedEventArgs e) { + if (!itemDragging) + MainWindow.Instance.SetCanWindowToFront(true); + if (sender is not SelectorItem selectorItem) return; @@ -1225,6 +1242,11 @@ protected internal void FileListItem_PointerPressed(object sender, PointerRouted protected internal void FileListItem_PointerEntered(object sender, PointerRoutedEventArgs e) { + if (sender is SelectorItem selectorItem && selectorItem.IsSelected) + { + MainWindow.Instance.SetCanWindowToFront(false); + } + if (!UserSettingsService.FoldersSettingsService.SelectFilesOnHover) return; @@ -1271,6 +1293,9 @@ selectedItems is not null && protected internal void FileListItem_PointerExited(object sender, PointerRoutedEventArgs e) { + if (!itemDragging) + MainWindow.Instance.SetCanWindowToFront(true); + if (!UserSettingsService.FoldersSettingsService.SelectFilesOnHover) return; @@ -1278,8 +1303,38 @@ protected internal void FileListItem_PointerExited(object sender, PointerRoutedE hoveredItem = null; } + protected void FileListItem_Tapped(object sender, TappedRoutedEventArgs e) + { + if (!itemDragging) + { + // No need to bring the window to the front again + if (MainWindow.Instance.SetCanWindowToFront(true)) + { + MainWindow.Instance.BringToFrontEx(); + } + } + } + + protected void FileListItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) + { + if (!itemDragging) + { + // No need to bring the window to the front again + if (MainWindow.Instance.SetCanWindowToFront(true)) + { + MainWindow.Instance.BringToFrontEx(); + } + } + } + protected void FileListItem_RightTapped(object sender, RightTappedRoutedEventArgs e) { + if (!itemDragging) + { + MainWindow.Instance.SetCanWindowToFront(true); + MainWindow.Instance.BringToFrontEx(); + } + var rightClickedItem = GetItemFromElement(sender); if (rightClickedItem is not null && !((SelectorItem)sender).IsSelected) diff --git a/src/Files.App/Views/Layouts/ColumnLayoutPage.xaml b/src/Files.App/Views/Layouts/ColumnLayoutPage.xaml index aca14800c17f..b9d707b42174 100644 --- a/src/Files.App/Views/Layouts/ColumnLayoutPage.xaml +++ b/src/Files.App/Views/Layouts/ColumnLayoutPage.xaml @@ -183,6 +183,7 @@ CanDragItems="{x:Bind AllowItemDrag, Mode=OneWay}" ContainerContentChanging="FileList_ContainerContentChanging" DoubleTapped="FileList_DoubleTapped" + DragItemsCompleted="FileList_DragItemsCompleted" DragItemsStarting="FileList_DragItemsStarting" DragOver="ItemsLayout_DragOver" Drop="ItemsLayout_Drop" diff --git a/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml b/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml index 2c6c5d87bbdd..265bdf3e78a0 100644 --- a/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml +++ b/src/Files.App/Views/Layouts/DetailsLayoutPage.xaml @@ -229,6 +229,7 @@ CanDragItems="{x:Bind AllowItemDrag, Mode=OneWay}" ContainerContentChanging="FileList_ContainerContentChanging" DoubleTapped="FileList_DoubleTapped" + DragItemsCompleted="FileList_DragItemsCompleted" DragItemsStarting="FileList_DragItemsStarting" DragOver="ItemsLayout_DragOver" Drop="ItemsLayout_Drop" diff --git a/src/Files.App/Views/Layouts/GridLayoutPage.xaml b/src/Files.App/Views/Layouts/GridLayoutPage.xaml index bb3ddef90e59..e4f61e8a851d 100644 --- a/src/Files.App/Views/Layouts/GridLayoutPage.xaml +++ b/src/Files.App/Views/Layouts/GridLayoutPage.xaml @@ -787,6 +787,7 @@ ContainerContentChanging="FileList_ContainerContentChanging" DoubleTapped="FileList_DoubleTapped" DragEnter="ItemsLayout_DragEnter" + DragItemsCompleted="FileList_DragItemsCompleted" DragItemsStarting="FileList_DragItemsStarting" DragLeave="ItemsLayout_DragLeave" DragOver="ItemsLayout_DragOver" From 04244fc5efb334e3770887173425498354ccd629 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 22 Nov 2024 08:41:45 -0300 Subject: [PATCH 02/10] Code Quality: Registered window manager event after app components initialized & Added unregisteration --- src/Files.App/App.xaml.cs | 5 +++++ src/Files.App/MainWindow.xaml.cs | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Files.App/App.xaml.cs b/src/Files.App/App.xaml.cs index 4d305570a86d..7dbc2e8e669f 100644 --- a/src/Files.App/App.xaml.cs +++ b/src/Files.App/App.xaml.cs @@ -157,6 +157,8 @@ async Task ActivateAsync() } await AppLifecycleHelper.InitializeAppComponentsAsync(); + + MainWindow.Instance.HookWindowMessageReceivedEvent(); } } @@ -196,6 +198,9 @@ private void Window_Activated(object sender, WindowActivatedEventArgs args) /// private async void Window_Closed(object sender, WindowEventArgs args) { + // Unhook events for the window + MainWindow.Instance.UnhookWindowMessageReceivedEvent(); + // Save application state and stop any background activity IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService(); StatusCenterViewModel statusCenterViewModel = Ioc.Default.GetRequiredService(); diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index dcdb6dc9bde5..4f1db0cc00c7 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -36,8 +36,6 @@ public MainWindow() AppWindow.TitleBar.ButtonPressedBackgroundColor = Colors.Transparent; AppWindow.TitleBar.ButtonHoverBackgroundColor = Colors.Transparent; AppWindow.SetIcon(AppLifecycleHelper.AppIconPath); - - WinUIEx.WindowManager.Get(this).WindowMessageReceived += WindowManager_WindowMessageReceived; } public void ShowSplashScreen() @@ -358,6 +356,16 @@ public void BringToFrontEx() Win32Helper.BringToForegroundEx(new(WindowHandle)); } + public void HookWindowMessageReceivedEvent() + { + WinUIEx.WindowManager.Get(this).WindowMessageReceived += WindowManager_WindowMessageReceived; + } + + public void UnhookWindowMessageReceivedEvent() + { + WinUIEx.WindowManager.Get(this).WindowMessageReceived -= WindowManager_WindowMessageReceived; + } + private const int WM_WINDOWPOSCHANGING = 0x0046; private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e) { From 6739f4f91aba771d72d9515cd37f3417855a01a7 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 22 Nov 2024 08:44:44 -0300 Subject: [PATCH 03/10] Code Quality: Removed useless function --- src/Files.App/MainWindow.xaml.cs | 5 ----- src/Files.App/Views/Layouts/BaseLayoutPage.cs | 7 ++++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index 4f1db0cc00c7..f01000396b2d 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -351,11 +351,6 @@ public bool SetCanWindowToFront(bool canWindowToFront) return false; } - public void BringToFrontEx() - { - Win32Helper.BringToForegroundEx(new(WindowHandle)); - } - public void HookWindowMessageReceivedEvent() { WinUIEx.WindowManager.Get(this).WindowMessageReceived += WindowManager_WindowMessageReceived; diff --git a/src/Files.App/Views/Layouts/BaseLayoutPage.cs b/src/Files.App/Views/Layouts/BaseLayoutPage.cs index cd38a17d514b..474756b1b817 100644 --- a/src/Files.App/Views/Layouts/BaseLayoutPage.cs +++ b/src/Files.App/Views/Layouts/BaseLayoutPage.cs @@ -1310,7 +1310,7 @@ protected void FileListItem_Tapped(object sender, TappedRoutedEventArgs e) // No need to bring the window to the front again if (MainWindow.Instance.SetCanWindowToFront(true)) { - MainWindow.Instance.BringToFrontEx(); + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); } } } @@ -1322,7 +1322,7 @@ protected void FileListItem_DoubleTapped(object sender, DoubleTappedRoutedEventA // No need to bring the window to the front again if (MainWindow.Instance.SetCanWindowToFront(true)) { - MainWindow.Instance.BringToFrontEx(); + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); } } } @@ -1332,7 +1332,8 @@ protected void FileListItem_RightTapped(object sender, RightTappedRoutedEventArg if (!itemDragging) { MainWindow.Instance.SetCanWindowToFront(true); - MainWindow.Instance.BringToFrontEx(); + // Bring the window to the front agin + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); } var rightClickedItem = GetItemFromElement(sender); From 8f5a5e4874d14011562626bfc34fbd278c6e08ae Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 22 Nov 2024 11:25:22 -0300 Subject: [PATCH 04/10] Code Quality: Improved redundant bring to front action --- src/Files.App/Views/Layouts/BaseLayoutPage.cs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Files.App/Views/Layouts/BaseLayoutPage.cs b/src/Files.App/Views/Layouts/BaseLayoutPage.cs index 474756b1b817..44928af4f426 100644 --- a/src/Files.App/Views/Layouts/BaseLayoutPage.cs +++ b/src/Files.App/Views/Layouts/BaseLayoutPage.cs @@ -1027,6 +1027,7 @@ protected virtual void FileList_DragItemsCompleted(ListViewBase sender, DragItem { itemDragging = false; MainWindow.Instance.SetCanWindowToFront(true); + // No need to bring the window to the front } private void Item_DragLeave(object sender, DragEventArgs e) @@ -1158,8 +1159,9 @@ protected void FileList_ContainerContentChanging(ListViewBase sender, ContainerC RefreshContainer(args.ItemContainer, args.InRecycleQueue); RefreshItem(args.ItemContainer, args.Item, args.InRecycleQueue, args); - MainWindow.Instance.SetCanWindowToFront(true); itemDragging = false; + MainWindow.Instance.SetCanWindowToFront(true); + // No need to bring the window to the front } private void RefreshContainer(SelectorItem container, bool inRecycleQueue) @@ -1215,7 +1217,13 @@ private void RefreshItem(SelectorItem container, object item, bool inRecycleQueu protected internal void FileListItem_PointerPressed(object sender, PointerRoutedEventArgs e) { if (!itemDragging) - MainWindow.Instance.SetCanWindowToFront(true); + { + // No need to bring the window to the front again + if (MainWindow.Instance.SetCanWindowToFront(true)) + { + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); + } + } if (sender is not SelectorItem selectorItem) return; @@ -1243,9 +1251,7 @@ protected internal void FileListItem_PointerPressed(object sender, PointerRouted protected internal void FileListItem_PointerEntered(object sender, PointerRoutedEventArgs e) { if (sender is SelectorItem selectorItem && selectorItem.IsSelected) - { MainWindow.Instance.SetCanWindowToFront(false); - } if (!UserSettingsService.FoldersSettingsService.SelectFilesOnHover) return; @@ -1295,6 +1301,7 @@ protected internal void FileListItem_PointerExited(object sender, PointerRoutedE { if (!itemDragging) MainWindow.Instance.SetCanWindowToFront(true); + // No need to bring the window to the front if (!UserSettingsService.FoldersSettingsService.SelectFilesOnHover) return; @@ -1331,9 +1338,11 @@ protected void FileListItem_RightTapped(object sender, RightTappedRoutedEventArg { if (!itemDragging) { - MainWindow.Instance.SetCanWindowToFront(true); - // Bring the window to the front agin - Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); + // No need to bring the window to the front again + if (MainWindow.Instance.SetCanWindowToFront(true)) + { + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); + } } var rightClickedItem = GetItemFromElement(sender); From 7dc84effc9a108c1c3dfd664bbe3bf1889aabee0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 22 Nov 2024 12:43:43 -0300 Subject: [PATCH 05/10] Code Quality: Combined statements and updated comments --- src/Files.App/Views/Layouts/BaseLayoutPage.cs | 47 ++++++------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/src/Files.App/Views/Layouts/BaseLayoutPage.cs b/src/Files.App/Views/Layouts/BaseLayoutPage.cs index 44928af4f426..0acc0707a171 100644 --- a/src/Files.App/Views/Layouts/BaseLayoutPage.cs +++ b/src/Files.App/Views/Layouts/BaseLayoutPage.cs @@ -1216,14 +1216,9 @@ private void RefreshItem(SelectorItem container, object item, bool inRecycleQueu protected internal void FileListItem_PointerPressed(object sender, PointerRoutedEventArgs e) { - if (!itemDragging) - { - // No need to bring the window to the front again - if (MainWindow.Instance.SetCanWindowToFront(true)) - { - Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); - } - } + // Set can window to front and bring the window to the front if necessary + if ((!itemDragging) && MainWindow.Instance.SetCanWindowToFront(true)) + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); if (sender is not SelectorItem selectorItem) return; @@ -1250,6 +1245,7 @@ protected internal void FileListItem_PointerPressed(object sender, PointerRouted protected internal void FileListItem_PointerEntered(object sender, PointerRoutedEventArgs e) { + // Set can window to front before the item is dragged if (sender is SelectorItem selectorItem && selectorItem.IsSelected) MainWindow.Instance.SetCanWindowToFront(false); @@ -1299,9 +1295,9 @@ selectedItems is not null && protected internal void FileListItem_PointerExited(object sender, PointerRoutedEventArgs e) { + // Set can window to front if (!itemDragging) MainWindow.Instance.SetCanWindowToFront(true); - // No need to bring the window to the front if (!UserSettingsService.FoldersSettingsService.SelectFilesOnHover) return; @@ -1312,38 +1308,23 @@ protected internal void FileListItem_PointerExited(object sender, PointerRoutedE protected void FileListItem_Tapped(object sender, TappedRoutedEventArgs e) { - if (!itemDragging) - { - // No need to bring the window to the front again - if (MainWindow.Instance.SetCanWindowToFront(true)) - { - Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); - } - } + // Set can window to front and bring the window to the front if necessary + if ((!itemDragging) && MainWindow.Instance.SetCanWindowToFront(true)) + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); } protected void FileListItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { - if (!itemDragging) - { - // No need to bring the window to the front again - if (MainWindow.Instance.SetCanWindowToFront(true)) - { - Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); - } - } + // Set can window to front and bring the window to the front if necessary + if ((!itemDragging) && MainWindow.Instance.SetCanWindowToFront(true)) + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); } protected void FileListItem_RightTapped(object sender, RightTappedRoutedEventArgs e) { - if (!itemDragging) - { - // No need to bring the window to the front again - if (MainWindow.Instance.SetCanWindowToFront(true)) - { - Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); - } - } + // Set can window to front and bring the window to the front if necessary + if ((!itemDragging) && MainWindow.Instance.SetCanWindowToFront(true)) + Win32Helper.BringToForegroundEx(new(MainWindow.Instance.WindowHandle)); var rightClickedItem = GetItemFromElement(sender); From 1aa2cd6b6b02e49540218e52e9734e7c04213ffe Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 22 Nov 2024 13:01:16 -0300 Subject: [PATCH 06/10] Code Quality: Replace Vanara with CsWin32 --- src/Files.App.CsWin32/Windows.Win32.Extras.cs | 46 +++++++++++++++++++ .../Win32/Win32Helper.WindowManagement.cs | 3 +- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/Files.App.CsWin32/Windows.Win32.Extras.cs b/src/Files.App.CsWin32/Windows.Win32.Extras.cs index c12b9bc62569..e626c5390633 100644 --- a/src/Files.App.CsWin32/Windows.Win32.Extras.cs +++ b/src/Files.App.CsWin32/Windows.Win32.Extras.cs @@ -16,5 +16,51 @@ namespace UI.WindowsAndMessaging { [UnmanagedFunctionPointer(CallingConvention.Winapi)] public delegate LRESULT WNDPROC(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam); + + /// Contains information about the size and position of a window. + /// + /// Learn more about this API from docs.microsoft.com. + /// + public partial struct WINDOWPOS + { + /// + /// Type: HWND A handle to the window. + /// Read more on docs.microsoft.com. + /// + internal HWND hwnd; + + /// + /// Type: HWND The position of the window in Z order (front-to-back position). This member can be a handle to the window behind which this window is placed, or can be one of the special values listed with the SetWindowPos function. + /// Read more on docs.microsoft.com. + /// + internal HWND hwndInsertAfter; + + /// + /// Type: int The position of the left edge of the window. + /// Read more on docs.microsoft.com. + /// + internal int x; + + /// + /// Type: int The position of the top edge of the window. + /// Read more on docs.microsoft.com. + /// + internal int y; + + /// + /// Type: int The window width, in pixels. + /// Read more on docs.microsoft.com. + /// + internal int cx; + + /// + /// Type: int The window height, in pixels. + /// Read more on docs.microsoft.com. + /// + internal int cy; + + /// Type: UINT + public SET_WINDOW_POS_FLAGS flags; + } } } diff --git a/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs b/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs index 56a0768c8252..a93c4b707a9f 100644 --- a/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs +++ b/src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs @@ -7,7 +7,6 @@ using System.Runtime.InteropServices; using Windows.Win32; using Windows.Win32.UI.WindowsAndMessaging; -using static Vanara.PInvoke.User32; namespace Files.App.Helpers { @@ -68,7 +67,7 @@ public static void ChangeCursor(this UIElement uiElement, InputCursor cursor) public static void ForceWindowPosition(nint lParam) { var windowPos = Marshal.PtrToStructure(lParam); - windowPos.flags |= SetWindowPosFlags.SWP_NOZORDER; + windowPos.flags |= SET_WINDOW_POS_FLAGS.SWP_NOZORDER; Marshal.StructureToPtr(windowPos, lParam, false); } } From 6c36665d8b164eac71da19d93e120ca6c00d7ecf Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 30 Nov 2024 16:21:47 +0800 Subject: [PATCH 07/10] Fix: Fixed an issue where function does not work after closing window to background --- src/Files.App/App.xaml.cs | 5 ----- src/Files.App/MainWindow.xaml.cs | 12 ++---------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/Files.App/App.xaml.cs b/src/Files.App/App.xaml.cs index 7dbc2e8e669f..4d305570a86d 100644 --- a/src/Files.App/App.xaml.cs +++ b/src/Files.App/App.xaml.cs @@ -157,8 +157,6 @@ async Task ActivateAsync() } await AppLifecycleHelper.InitializeAppComponentsAsync(); - - MainWindow.Instance.HookWindowMessageReceivedEvent(); } } @@ -198,9 +196,6 @@ private void Window_Activated(object sender, WindowActivatedEventArgs args) /// private async void Window_Closed(object sender, WindowEventArgs args) { - // Unhook events for the window - MainWindow.Instance.UnhookWindowMessageReceivedEvent(); - // Save application state and stop any background activity IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService(); StatusCenterViewModel statusCenterViewModel = Ioc.Default.GetRequiredService(); diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index f01000396b2d..7d65ec3ce9aa 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -36,6 +36,8 @@ public MainWindow() AppWindow.TitleBar.ButtonPressedBackgroundColor = Colors.Transparent; AppWindow.TitleBar.ButtonHoverBackgroundColor = Colors.Transparent; AppWindow.SetIcon(AppLifecycleHelper.AppIconPath); + + WinUIEx.WindowManager.Get(this).WindowMessageReceived += WindowManager_WindowMessageReceived; } public void ShowSplashScreen() @@ -351,16 +353,6 @@ public bool SetCanWindowToFront(bool canWindowToFront) return false; } - public void HookWindowMessageReceivedEvent() - { - WinUIEx.WindowManager.Get(this).WindowMessageReceived += WindowManager_WindowMessageReceived; - } - - public void UnhookWindowMessageReceivedEvent() - { - WinUIEx.WindowManager.Get(this).WindowMessageReceived -= WindowManager_WindowMessageReceived; - } - private const int WM_WINDOWPOSCHANGING = 0x0046; private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e) { From 24750cf6e32e3ad0ea6aa2832e33622b011a9f64 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 3 Dec 2024 13:01:23 +0800 Subject: [PATCH 08/10] Code quality: Improved code quality --- src/Files.App/MainWindow.xaml.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index 7d65ec3ce9aa..74009527ebd0 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -356,13 +356,10 @@ public bool SetCanWindowToFront(bool canWindowToFront) private const int WM_WINDOWPOSCHANGING = 0x0046; private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e) { - if (!CanWindowToFront) + if ((!CanWindowToFront) && e.Message.MessageId == WM_WINDOWPOSCHANGING) { - if (e.Message.MessageId == WM_WINDOWPOSCHANGING) - { - Win32Helper.ForceWindowPosition(e.Message.LParam); - e.Handled = true; - } + Win32Helper.ForceWindowPosition(e.Message.LParam); + e.Handled = true; } } } From c61ace3750d7f09cbcfb7445570e0fb4904f48b7 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 3 Dec 2024 13:07:03 +0800 Subject: [PATCH 09/10] Fix: Fixed an issue when multiple threads handle CanWindowToFront flag --- src/Files.App/MainWindow.xaml.cs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index 74009527ebd0..753fa48bc287 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -20,6 +20,7 @@ public sealed partial class MainWindow : WinUIEx.WindowEx public nint WindowHandle { get; } private bool CanWindowToFront { get; set; } = true; + private readonly object _canWindowToFrontLock = new(); public MainWindow() { @@ -343,15 +344,18 @@ x.tabItem.NavigationParameter.NavigationParameter is PaneNavigationArguments pan } } - public bool SetCanWindowToFront(bool canWindowToFront) - { - if (CanWindowToFront != canWindowToFront) - { - CanWindowToFront = canWindowToFront; - return true; - } - return false; - } + public bool SetCanWindowToFront(bool canWindowToFront) + { + lock (_canWindowToFrontLock) + { + if (CanWindowToFront != canWindowToFront) + { + CanWindowToFront = canWindowToFront; + return true; + } + return false; + } + } private const int WM_WINDOWPOSCHANGING = 0x0046; private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e) From 881b9d13d5445b2f2be6c6aec7598b6b396c2783 Mon Sep 17 00:00:00 2001 From: Jack Ye <1160210343@qq.com> Date: Wed, 4 Dec 2024 00:02:18 +0800 Subject: [PATCH 10/10] Code quality: Used tab for indentation Co-authored-by: hishitetsu <66369541+hishitetsu@users.noreply.github.com> --- src/Files.App/MainWindow.xaml.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index 753fa48bc287..3f08fdfbb482 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -344,18 +344,18 @@ x.tabItem.NavigationParameter.NavigationParameter is PaneNavigationArguments pan } } - public bool SetCanWindowToFront(bool canWindowToFront) - { - lock (_canWindowToFrontLock) - { - if (CanWindowToFront != canWindowToFront) - { - CanWindowToFront = canWindowToFront; - return true; - } - return false; - } - } + public bool SetCanWindowToFront(bool canWindowToFront) + { + lock (_canWindowToFrontLock) + { + if (CanWindowToFront != canWindowToFront) + { + CanWindowToFront = canWindowToFront; + return true; + } + return false; + } + } private const int WM_WINDOWPOSCHANGING = 0x0046; private void WindowManager_WindowMessageReceived(object? sender, WinUIEx.Messaging.WindowMessageEventArgs e)