Skip to content

Commit 799527c

Browse files
committed
Init
1 parent 114bff3 commit 799527c

File tree

9 files changed

+135
-120
lines changed

9 files changed

+135
-120
lines changed

.github/NOTICE.md

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -199,35 +199,6 @@ The above copyright notice and this permission notice shall be included in all c
199199
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
200200
```
201201

202-
## INI File Parser
203-
204-
**Source**: [https://github.com/rickyah/ini-parser](https://github.com/rickyah/ini-parser)
205-
206-
### License
207-
208-
```
209-
The MIT License (MIT)
210-
211-
Copyright (c) 2008 Ricardo Amores Hernández
212-
213-
Permission is hereby granted, free of charge, to any person obtaining a copy of
214-
this software and associated documentation files (the "Software"), to deal in
215-
the Software without restriction, including without limitation the rights to
216-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
217-
the Software, and to permit persons to whom the Software is furnished to do so,
218-
subject to the following conditions:
219-
220-
The above copyright notice and this permission notice shall be included in all
221-
copies or substantial portions of the Software.
222-
223-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
224-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
225-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
226-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
227-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
229-
```
230-
231202
## SevenZipSharp
232203

233204
**Source**: [https://github.com/files-community/SevenZipSharp](https://github.com/files-community/SevenZipSharp)
@@ -645,36 +616,6 @@ A "contributor" is any person that distributes its contribution under this licen
645616
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
646617
```
647618

648-
## WinUIEx
649-
650-
**Source**: [https://github.com/dotMorten/WinUIEx](https://github.com/dotMorten/WinUIEx)
651-
652-
### License
653-
654-
```
655-
MIT License
656-
657-
Copyright (c) 2021 Morten Nielsen
658-
659-
Permission is hereby granted, free of charge, to any person obtaining a copy
660-
of this software and associated documentation files (the "Software"), to deal
661-
in the Software without restriction, including without limitation the rights
662-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
663-
copies of the Software, and to permit persons to whom the Software is
664-
furnished to do so, subject to the following conditions:
665-
666-
The above copyright notice and this permission notice shall be included in all
667-
copies or substantial portions of the Software.
668-
669-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
670-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
671-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
672-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
673-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
674-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
675-
SOFTWARE.
676-
```
677-
678619
## libgit2sharp
679620

680621
**Source**: [https://github.com/libgit2/libgit2sharp](https://github.com/libgit2/libgit2sharp)
@@ -732,4 +673,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
732673
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
733674
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
734675
DEALINGS IN THE SOFTWARE.
735-
```
676+
```

src/Files.App/Data/Contexts/Window/WindowContext.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,18 @@ public WindowContext()
2525
IsRunningAsAdmin = WindowsSecurityService.IsAppElevated();
2626
CanDragAndDrop = WindowsSecurityService.CanDragAndDrop();
2727

28-
MainWindow.Instance.PresenterChanged += Window_PresenterChanged;
28+
MainWindow.Instance.AppWindow.Changed += AppWindow_Changed;
2929
}
3030

31-
private void Window_PresenterChanged(object? sender, AppWindowPresenter e)
31+
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
3232
{
33-
SetProperty(
34-
ref isCompactOverlay,
35-
e.Kind is AppWindowPresenterKind.CompactOverlay,
36-
nameof(IsCompactOverlay));
33+
if (args.DidPresenterChange)
34+
{
35+
SetProperty(
36+
ref isCompactOverlay,
37+
sender.Presenter.Kind is AppWindowPresenterKind.CompactOverlay,
38+
nameof(IsCompactOverlay));
39+
}
3740
}
3841
}
3942
}

src/Files.App/Data/Items/WindowEx.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using Microsoft.UI.Windowing;
5+
using Microsoft.UI.Xaml;
6+
using System.Runtime.InteropServices;
7+
using Windows.Win32;
8+
using Windows.Win32.Foundation;
9+
using Windows.Win32.UI.WindowsAndMessaging;
10+
11+
namespace Files.App.Data.Items
12+
{
13+
public unsafe class WindowEx : Window
14+
{
15+
private readonly WNDPROC _oldWndProc;
16+
private readonly WNDPROC _newWndProc;
17+
18+
public nint WindowHandle { get; }
19+
20+
public int MinWidth { get; set; }
21+
public int MinHeight { get; set; }
22+
23+
private bool _IsMaximizable = true;
24+
public bool IsMaximizable
25+
{
26+
get => _IsMaximizable;
27+
set
28+
{
29+
_IsMaximizable = value;
30+
UpdateOverlappedPresenter((c) => c.IsMaximizable = value);
31+
32+
if (value)
33+
{
34+
// NOTE:
35+
// Indicates to the Shell that the window should not be treated as full-screen.
36+
// WORKAROUND:
37+
// https://github.com/microsoft/microsoft-ui-xaml/issues/8431
38+
// Not to mess up the taskbar when being full-screen mode.
39+
// This property should only be set if the "Automatically hide the taskbar" in Windows 11,
40+
// or "Automatically hide the taskbar in desktop mode" in Windows 10 is enabled.
41+
// Setting this property when the setting is disabled will result in the taskbar overlapping the application.
42+
if (AppLifecycleHelper.IsAutoHideTaskbarEnabled())
43+
Win32PInvoke.SetPropW(WindowHandle, "NonRudeHWND", new IntPtr(1));
44+
}
45+
}
46+
}
47+
48+
private bool _IsMinimizable = true;
49+
public bool IsMinimizable
50+
{
51+
get => _IsMinimizable;
52+
set
53+
{
54+
_IsMaximizable = value;
55+
UpdateOverlappedPresenter((c) => c.IsMinimizable = value);
56+
}
57+
}
58+
59+
public unsafe WindowEx(int minWidth = 400, int minHeight = 300)
60+
{
61+
WindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this);
62+
MinWidth = minWidth;
63+
MinHeight = minHeight;
64+
65+
_newWndProc = new(NewWindowProc);
66+
var pNewWndProc = Marshal.GetFunctionPointerForDelegate(_newWndProc);
67+
var pOldWndProc = PInvoke.SetWindowLongPtr(new(WindowHandle), WINDOW_LONG_PTR_INDEX.GWL_WNDPROC, pNewWndProc);
68+
_oldWndProc = Marshal.GetDelegateForFunctionPointer<WNDPROC>(pOldWndProc);
69+
}
70+
71+
private void UpdateOverlappedPresenter(Action<OverlappedPresenter> action)
72+
{
73+
if (AppWindow.Presenter is OverlappedPresenter overlapped)
74+
action(overlapped);
75+
else
76+
throw new NotSupportedException($"'{AppWindow.Presenter.Kind}' presenter is not supported.");
77+
}
78+
79+
private LRESULT NewWindowProc(HWND param0, uint param1, WPARAM param2, LPARAM param3)
80+
{
81+
switch (param1)
82+
{
83+
case 0x0024: /*WM_GETMINMAXINFO*/
84+
{
85+
var dpi = PInvoke.GetDpiForWindow(new(param0));
86+
float scalingFactor = (float)dpi / 96;
87+
88+
var minMaxInfo = Marshal.PtrToStructure<MINMAXINFO>(param3);
89+
minMaxInfo.ptMinTrackSize.X = (int)(MinWidth * scalingFactor);
90+
minMaxInfo.ptMinTrackSize.Y = (int)(MinHeight * scalingFactor);
91+
Marshal.StructureToPtr(minMaxInfo, param3, true);
92+
break;
93+
}
94+
}
95+
96+
return PInvoke.CallWindowProc(_oldWndProc, param0, param1, param2, param3);
97+
}
98+
}
99+
}

src/Files.App/Files.App.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@
8585
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
8686
<PackageReference Include="TagLibSharp" Version="2.3.0" />
8787
<PackageReference Include="Tulpep.ActiveDirectoryObjectPicker" Version="3.0.11" />
88-
<PackageReference Include="WinUIEx" Version="2.3.4" />
8988
<PackageReference Include="Vanara.Windows.Extensions" Version="4.0.1" />
9089
<PackageReference Include="Vanara.Windows.Shell" Version="4.0.1" />
9190
<PackageReference Include="Microsoft.Management.Infrastructure" Version="3.0.0" />

src/Files.App/MainWindow.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<!-- Copyright (c) 2024 Files Community. Licensed under the MIT License. See the LICENSE. -->
2-
<winuiex:WindowEx
2+
<items:WindowEx
33
x:Class="Files.App.MainWindow"
44
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
55
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
66
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:items="using:Files.App.Data.Items"
78
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8-
xmlns:winuiex="using:WinUIEx"
99
mc:Ignorable="d" />

src/Files.App/MainWindow.xaml.cs

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
using Microsoft.UI.Windowing;
77
using Microsoft.UI.Xaml.Controls;
88
using Microsoft.UI.Xaml.Media.Animation;
9-
using Microsoft.UI.Xaml.Navigation;
109
using System.Runtime.InteropServices;
1110
using Windows.ApplicationModel.Activation;
1211
using Windows.Storage;
13-
using WinUIEx;
1412
using IO = System.IO;
1513

1614
namespace Files.App
@@ -20,39 +18,17 @@ public sealed partial class MainWindow : WindowEx
2018
private static MainWindow? _Instance;
2119
public static MainWindow Instance => _Instance ??= new();
2220

23-
public IntPtr WindowHandle { get; }
24-
25-
private MainWindow()
21+
public MainWindow() : base(minWidth: 516, minHeight: 416)
2622
{
27-
WindowHandle = this.GetWindowHandle();
28-
2923
InitializeComponent();
3024

31-
EnsureEarlyWindow();
32-
}
33-
34-
private void EnsureEarlyWindow()
35-
{
36-
// Set PersistenceId
37-
PersistenceId = "FilesMainWindow";
38-
39-
// Set minimum sizes
40-
MinHeight = 416;
41-
MinWidth = 516;
42-
43-
AppWindow.Title = "Files";
44-
AppWindow.SetIcon(AppLifecycleHelper.AppIconPath);
45-
AppWindow.TitleBar.ExtendsContentIntoTitleBar = true;
25+
ExtendsContentIntoTitleBar = true;
26+
Title = "Files";
4627
AppWindow.TitleBar.ButtonBackgroundColor = Colors.Transparent;
4728
AppWindow.TitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
48-
49-
// Workaround for full screen window messing up the taskbar
50-
// https://github.com/microsoft/microsoft-ui-xaml/issues/8431
51-
// This property should only be set if the "Automatically hide the taskbar" in Windows 11,
52-
// or "Automatically hide the taskbar in desktop mode" in Windows 10 is enabled.
53-
// Setting this property when the setting is disabled will result in the taskbar overlapping the application
54-
if (AppLifecycleHelper.IsAutoHideTaskbarEnabled())
55-
Win32PInvoke.SetPropW(WindowHandle, "NonRudeHWND", new IntPtr(1));
29+
AppWindow.TitleBar.ButtonPressedBackgroundColor = Colors.Transparent;
30+
AppWindow.TitleBar.ButtonHoverBackgroundColor = Colors.Transparent;
31+
AppWindow.SetIcon(AppLifecycleHelper.AppIconPath);
5632
}
5733

5834
public void ShowSplashScreen()
@@ -209,8 +185,9 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
209185
Activate();
210186
}
211187

212-
if (Windows.Win32.PInvoke.IsIconic(new(WindowHandle)))
213-
Instance.Restore(); // Restore window if minimized
188+
if (Windows.Win32.PInvoke.IsIconic(new(WindowHandle)) &&
189+
AppWindow.Presenter is OverlappedPresenter presenter)
190+
presenter.Restore(); // Restore window if minimized
214191
}
215192

216193
private Frame? EnsureWindowIsInitialized()
@@ -224,7 +201,10 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
224201
{
225202
// Create a Frame to act as the navigation context and navigate to the first page
226203
rootFrame = new() { CacheSize = 1 };
227-
rootFrame.NavigationFailed += OnNavigationFailed;
204+
rootFrame.NavigationFailed += (s, e) =>
205+
{
206+
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
207+
};
228208

229209
// Place the frame in the current Window
230210
Instance.Content = rootFrame;
@@ -238,14 +218,6 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
238218
}
239219
}
240220

241-
/// <summary>
242-
/// Invoked when Navigation to a certain page fails
243-
/// </summary>
244-
/// <param name="sender">The Frame which failed navigation</param>
245-
/// <param name="e">Details about the navigation failure</param>
246-
private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
247-
=> throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
248-
249221
private async Task InitializeFromCmdLineArgsAsync(Frame rootFrame, ParsedCommands parsedCommands, string activationPath = "")
250222
{
251223
async Task PerformNavigationAsync(string payload, string selectItem = null)

src/Files.App/NativeMethods.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,8 @@ FindWindow
9898
SendMessage
9999
IsWindowVisible
100100
COPYDATASTRUCT
101+
SetWindowLongPtr
102+
GetDpiForWindow
103+
CallWindowProc
104+
MINMAXINFO
105+
SUBCLASSPROC

src/Files.App/Utils/Storage/Helpers/FilePropertiesHelpers.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using Microsoft.UI.Xaml.Media.Animation;
1010
using Microsoft.Windows.ApplicationModel.Resources;
1111
using System.Collections.Concurrent;
12-
using Windows.ApplicationModel;
1312
using Windows.Graphics;
1413
using Windows.Win32;
1514

@@ -37,7 +36,7 @@ public static nint GetWindowHandle(Window w)
3736
=> WinRT.Interop.WindowNative.GetWindowHandle(w);
3837

3938
private static TaskCompletionSource? PropertiesWindowsClosingTCS;
40-
private static readonly BlockingCollection<WinUIEx.WindowEx> WindowCache = [];
39+
private static readonly BlockingCollection<WindowEx> WindowCache = [];
4140

4241
/// <summary>
4342
/// Open properties window
@@ -99,11 +98,10 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
9998

10099
var frame = new Frame
101100
{
102-
RequestedTheme = (ElementTheme)AppThemeModeService.AppThemeMode
101+
RequestedTheme = AppThemeModeService.AppThemeMode
103102
};
104103

105-
WinUIEx.WindowEx propertiesWindow;
106-
if (!WindowCache.TryTake(out propertiesWindow!))
104+
if (!WindowCache.TryTake(out var propertiesWindow))
107105
{
108106
propertiesWindow = new();
109107
propertiesWindow.Closed += PropertiesWindow_Closed;
@@ -113,8 +111,7 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
113111
propertiesWindow.IsMaximizable = false;
114112
propertiesWindow.MinWidth = 460;
115113
propertiesWindow.MinHeight = 550;
116-
propertiesWindow.Width = 800;
117-
propertiesWindow.Height = 550;
114+
propertiesWindow.AppWindow.Resize(new(800, 550));
118115
propertiesWindow.Content = frame;
119116
propertiesWindow.SystemBackdrop = new AppSystemBackdrop(true);
120117

@@ -127,7 +124,7 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
127124
appWindow.SetIcon(AppLifecycleHelper.AppIconPath);
128125

129126
frame.Navigate(
130-
typeof(Views.Properties.MainPropertiesPage),
127+
typeof(MainPropertiesPage),
131128
new PropertiesPageNavigationParameter
132129
{
133130
Parameter = item,
@@ -160,7 +157,7 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
160157
// So instead of destroying the Window object, cache it and reuse it as a workaround.
161158
private static void PropertiesWindow_Closed(object sender, WindowEventArgs args)
162159
{
163-
if (!App.AppModel.IsMainWindowClosed && sender is WinUIEx.WindowEx window)
160+
if (!App.AppModel.IsMainWindowClosed && sender is WindowEx window)
164161
{
165162
args.Handled = true;
166163

src/Files.App/ViewModels/Settings/AboutViewModel.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ public AboutViewModel()
6969
new ("https://github.com/CommunityToolkit/WindowsCommunityToolkit", "Windows Community Toolkit 7.x"),
7070
new ("https://github.com/mono/taglib-sharp", "TagLibSharp"),
7171
new ("https://github.com/Tulpep/Active-Directory-Object-Picker", "ActiveDirectoryObjectPicker"),
72-
new ("https://github.com/dotMorten/WinUIEx", "WinUIEx"),
7372
new ("https://github.com/PowerShell/MMI", "MMI"),
7473
new ("https://github.com/microsoft/CsWin32", "CsWin32"),
7574
new ("https://github.com/microsoft/CsWinRT", "CsWinRT"),

0 commit comments

Comments
 (0)