Skip to content
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
5 changes: 5 additions & 0 deletions src/Files.App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ async Task ActivateAsync()
}

await AppLifecycleHelper.InitializeAppComponentsAsync();

MainWindow.Instance.HookWindowMessageReceivedEvent();
}
}

Expand Down Expand Up @@ -196,6 +198,9 @@ private void Window_Activated(object sender, WindowActivatedEventArgs args)
/// </remarks>
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<IUserSettingsService>();
StatusCenterViewModel statusCenterViewModel = Ioc.Default.GetRequiredService<StatusCenterViewModel>();
Expand Down
13 changes: 13 additions & 0 deletions src/Files.App/Helpers/Win32/Win32Helper.WindowManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -58,5 +60,16 @@ public static void ChangeCursor(this UIElement uiElement, InputCursor cursor)
[cursor]
);
}

/// <summary>
/// Force window to stay at bottom of other upper windows.
/// </summary>
/// <param name="lParam">The lParam of the message.</param>
public static void ForceWindowPosition(nint lParam)
{
var windowPos = Marshal.PtrToStructure<WINDOWPOS>(lParam);
windowPos.flags |= SetWindowPosFlags.SWP_NOZORDER;
Marshal.StructureToPtr(windowPos, lParam, false);
}
}
}
34 changes: 34 additions & 0 deletions src/Files.App/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -339,5 +340,38 @@ x.tabItem.NavigationParameter.NavigationParameter is PaneNavigationArguments pan
}
}
}

public bool SetCanWindowToFront(bool canWindowToFront)
{
if (CanWindowToFront != canWindowToFront)
{
CanWindowToFront = canWindowToFront;
return true;
}
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)
{
if (!CanWindowToFront)
{
if (e.Message.MessageId == WM_WINDOWPOSCHANGING)
{
Win32Helper.ForceWindowPosition(e.Message.LParam);
e.Handled = true;
}
}
}
}
}
75 changes: 70 additions & 5 deletions src/Files.App/Views/Layouts/BaseLayoutPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1012,13 +1013,23 @@ 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)
{
e.Cancel = true;
}
}

protected virtual void FileList_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
{
itemDragging = false;
MainWindow.Instance.SetCanWindowToFront(true);
// No need to bring the window to the front
}

private void Item_DragLeave(object sender, DragEventArgs e)
{
var item = GetItemFromElement(sender);
Expand Down Expand Up @@ -1147,13 +1158,19 @@ protected void FileList_ContainerContentChanging(ListViewBase sender, ContainerC
{
RefreshContainer(args.ItemContainer, args.InRecycleQueue);
RefreshItem(args.ItemContainer, args.Item, args.InRecycleQueue, args);

itemDragging = false;
MainWindow.Instance.SetCanWindowToFront(true);
// No need to bring the window to the front
}

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)
Expand All @@ -1163,12 +1180,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;
}
}
}

Expand Down Expand Up @@ -1200,6 +1216,15 @@ 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));
}
}

if (sender is not SelectorItem selectorItem)
return;

Expand All @@ -1225,6 +1250,9 @@ 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;

Expand Down Expand Up @@ -1271,15 +1299,52 @@ selectedItems is not null &&

protected internal void FileListItem_PointerExited(object sender, PointerRoutedEventArgs e)
{
if (!itemDragging)
MainWindow.Instance.SetCanWindowToFront(true);
// No need to bring the window to the front

if (!UserSettingsService.FoldersSettingsService.SelectFilesOnHover)
return;

hoverTimer.Stop();
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))
{
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));
}
}
}

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));
}
}

var rightClickedItem = GetItemFromElement(sender);

if (rightClickedItem is not null && !((SelectorItem)sender).IsSelected)
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Views/Layouts/ColumnLayoutPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Views/Layouts/DetailsLayoutPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Views/Layouts/GridLayoutPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down