Skip to content

Commit ed96899

Browse files
committed
Merge branch props into local
2 parents 35002fa + 85f66aa commit ed96899

File tree

5 files changed

+128
-32
lines changed

5 files changed

+128
-32
lines changed

src/Files.App/App.xaml.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ private async void Window_Closed(object sender, WindowEventArgs args)
198198
// Save application state and stop any background activity
199199
IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
200200
StatusCenterViewModel statusCenterViewModel = Ioc.Default.GetRequiredService<StatusCenterViewModel>();
201+
ICommandManager commandManager = Ioc.Default.GetRequiredService<ICommandManager>();
201202

202203
// A Workaround for the crash (#10110)
203204
if (_LastOpenedFlyout?.IsOpen ?? false)
@@ -209,7 +210,10 @@ private async void Window_Closed(object sender, WindowEventArgs args)
209210
}
210211

211212
// Save the current tab list in case it was overwriten by another instance
212-
AppLifecycleHelper.SaveSessionTabs();
213+
if (userSettingsService.GeneralSettingsService.ContinueLastSessionOnStartUp || userSettingsService.AppSettingsService.RestoreTabsOnStartup)
214+
AppLifecycleHelper.SaveSessionTabs();
215+
else
216+
await commandManager.CloseAllTabs.ExecuteAsync();
213217

214218
if (OutputPath is not null)
215219
{

src/Files.App/Helpers/NaturalStringComparer.cs

+108-22
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,118 @@ public sealed class NaturalStringComparer
77
{
88
public static IComparer<object> GetForProcessor()
99
{
10-
return Win32Helper.IsRunningOnArm ? new StringComparerArm64() : new StringComparerDefault();
10+
return new NaturalComparer(StringComparison.CurrentCulture);
1111
}
1212

13-
private sealed class StringComparerArm64 : IComparer<object>
13+
/// <summary>
14+
/// Provides functionality to compare and sort strings in a natural (human-readable) order.
15+
/// </summary>
16+
/// <remarks>
17+
/// This class implements string comparison that respects the natural numeric order in strings,
18+
/// such as "file10" being ordered after "file2".
19+
/// It is designed to handle cases where alphanumeric sorting is required.
20+
/// </remarks>
21+
private sealed class NaturalComparer : IComparer<object?>, IComparer<string?>, IComparer<ReadOnlyMemory<char>>
1422
{
15-
public int Compare(object a, object b)
16-
{
17-
return StringComparer.CurrentCulture.Compare(a, b);
18-
}
19-
}
23+
private readonly StringComparison stringComparison;
2024

21-
private sealed class StringComparerDefault : IComparer<object>
22-
{
23-
public int Compare(object a, object b)
24-
{
25-
return Win32PInvoke.CompareStringEx(
26-
Win32PInvoke.LOCALE_NAME_USER_DEFAULT,
27-
Win32PInvoke.SORT_DIGITSASNUMBERS, // Add other flags if required.
28-
a?.ToString(),
29-
a?.ToString().Length ?? 0,
30-
b?.ToString(),
31-
b?.ToString().Length ?? 0,
32-
IntPtr.Zero,
33-
IntPtr.Zero,
34-
0) - 2;
35-
}
25+
public NaturalComparer(StringComparison stringComparison = StringComparison.Ordinal)
26+
{
27+
this.stringComparison = stringComparison;
28+
}
29+
30+
public int Compare(object? x, object? y)
31+
{
32+
if (x == y) return 0;
33+
if (x == null) return -1;
34+
if (y == null) return 1;
35+
36+
return x switch
37+
{
38+
string x1 when y is string y1 => Compare(x1.AsSpan(), y1.AsSpan(), stringComparison),
39+
IComparable comparable => comparable.CompareTo(y),
40+
_ => StringComparer.FromComparison(stringComparison).Compare(x, y)
41+
};
42+
}
43+
44+
public int Compare(string? x, string? y)
45+
{
46+
if (ReferenceEquals(x, y)) return 0;
47+
if (x is null) return -1;
48+
if (y is null) return 1;
49+
50+
return Compare(x.AsSpan(), y.AsSpan(), stringComparison);
51+
}
52+
53+
public int Compare(ReadOnlySpan<char> x, ReadOnlySpan<char> y)
54+
{
55+
return Compare(x, y, stringComparison);
56+
}
57+
58+
public int Compare(ReadOnlyMemory<char> x, ReadOnlyMemory<char> y)
59+
{
60+
return Compare(x.Span, y.Span, stringComparison);
61+
}
62+
63+
public static int Compare(ReadOnlySpan<char> x, ReadOnlySpan<char> y, StringComparison stringComparison)
64+
{
65+
var length = Math.Min(x.Length, y.Length);
66+
67+
for (var i = 0; i < length; i++)
68+
{
69+
if (char.IsDigit(x[i]) && char.IsDigit(y[i]))
70+
{
71+
var xOut = GetNumber(x.Slice(i), out var xNumAsSpan);
72+
var yOut = GetNumber(y.Slice(i), out var yNumAsSpan);
73+
74+
var compareResult = CompareNumValues(xNumAsSpan, yNumAsSpan);
75+
76+
if (compareResult != 0) return compareResult;
77+
78+
i = -1;
79+
length = Math.Min(xOut.Length, yOut.Length);
80+
81+
x = xOut;
82+
y = yOut;
83+
continue;
84+
}
85+
86+
var charCompareResult = x.Slice(i, 1).CompareTo(y.Slice(i, 1), stringComparison);
87+
if (charCompareResult != 0) return charCompareResult;
88+
}
89+
90+
return x.Length.CompareTo(y.Length);
91+
}
92+
93+
private static ReadOnlySpan<char> GetNumber(ReadOnlySpan<char> span, out ReadOnlySpan<char> number)
94+
{
95+
var i = 0;
96+
while (i < span.Length && char.IsDigit(span[i]))
97+
{
98+
i++;
99+
}
100+
101+
number = span.Slice(0, i);
102+
return span.Slice(i);
103+
}
104+
105+
private static int CompareNumValues(ReadOnlySpan<char> numValue1, ReadOnlySpan<char> numValue2)
106+
{
107+
var num1AsSpan = numValue1.TrimStart('0');
108+
var num2AsSpan = numValue2.TrimStart('0');
109+
110+
if (num1AsSpan.Length < num2AsSpan.Length) return -1;
111+
112+
if (num1AsSpan.Length > num2AsSpan.Length) return 1;
113+
114+
var compareResult = num1AsSpan.CompareTo(num2AsSpan, StringComparison.Ordinal);
115+
116+
if (compareResult != 0) return Math.Sign(compareResult);
117+
118+
if (numValue2.Length == numValue1.Length) return compareResult;
119+
120+
return numValue2.Length < numValue1.Length ? -1 : 1; // "033" < "33" == true
121+
}
36122
}
37123
}
38124
}

src/Files.App/UserControls/TabBar/TabBar.xaml.cs

+10-6
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,19 @@ private void TabViewItem_Loaded(object sender, RoutedEventArgs e)
358358
}
359359
}
360360

361-
private void DragAreaRectangle_Loaded(object sender, RoutedEventArgs e)
361+
private async void DragAreaRectangle_Loaded(object sender, RoutedEventArgs e)
362362
{
363-
double scaleAdjustment = DragAreaRectangle.XamlRoot.RasterizationScale;
364-
double titleBarInset = ((FilePropertiesHelpers.FlowDirectionSettingIsRightToLeft
363+
if (HorizontalTabView.ActualWidth <= 0 && TabBarAddNewTabButton.Width <= 0)
364+
await Task.Delay(100);
365+
366+
var titleBarInset = ((FilePropertiesHelpers.FlowDirectionSettingIsRightToLeft
365367
? MainWindow.Instance.AppWindow.TitleBar.LeftInset
366-
: MainWindow.Instance.AppWindow.TitleBar.RightInset) / scaleAdjustment) + 40;
368+
: MainWindow.Instance.AppWindow.TitleBar.RightInset) / DragAreaRectangle.XamlRoot.RasterizationScale) + 40;
367369

368-
HorizontalTabView.Measure(new(HorizontalTabView.ActualWidth - TabBarAddNewTabButton.Width - titleBarInset, HorizontalTabView.ActualHeight));
369-
RightPaddingColumn.Width = new(titleBarInset >= 0 ? titleBarInset : 0);
370+
RightPaddingColumn.Width = new(titleBarInset > 40 ? titleBarInset : 138);
371+
HorizontalTabView.Measure(new(
372+
HorizontalTabView.ActualWidth - TabBarAddNewTabButton.Width - titleBarInset,
373+
HorizontalTabView.ActualHeight));
370374
}
371375
}
372376
}

src/Files.App/Utils/Shell/LaunchHelper.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ namespace Files.App.Utils.Shell
1616
/// </summary>
1717
public static class LaunchHelper
1818
{
19-
public static void LaunchSettings(string page)
19+
public unsafe static void LaunchSettings(string page)
2020
{
21-
var appActiveManager = new IApplicationActivationManager();
21+
using ComPtr<IApplicationActivationManager> pApplicationActivationManager = default;
22+
pApplicationActivationManager.CoCreateInstance<Shell32.ApplicationActivationManager>();
2223

23-
appActiveManager.ActivateApplication(
24+
pApplicationActivationManager.Get()->ActivateApplication(
2425
"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel",
2526
page,
2627
ACTIVATEOPTIONS.AO_NONE,

src/Files.App/Views/MainPage.xaml.cs

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ private void UserSettingsService_OnSettingChangedEvent(object? sender, SettingCh
127127
private void HorizontalMultitaskingControl_Loaded(object sender, RoutedEventArgs e)
128128
{
129129
TabControl.DragArea.SizeChanged += (_, _) => MainWindow.Instance.RaiseSetTitleBarDragRegion(SetTitleBarDragRegion);
130+
TabControl.SizeChanged += (_, _) => MainWindow.Instance.RaiseSetTitleBarDragRegion(SetTitleBarDragRegion);
130131
if (ViewModel.MultitaskingControl is not TabBar)
131132
{
132133
ViewModel.MultitaskingControl = TabControl;

0 commit comments

Comments
 (0)