Skip to content

Commit

Permalink
Merge branch props into local
Browse files Browse the repository at this point in the history
  • Loading branch information
Lamparter committed Dec 15, 2024
2 parents 35002fa + 85f66aa commit ed96899
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 32 deletions.
6 changes: 5 additions & 1 deletion src/Files.App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ private async void Window_Closed(object sender, WindowEventArgs args)
// Save application state and stop any background activity
IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
StatusCenterViewModel statusCenterViewModel = Ioc.Default.GetRequiredService<StatusCenterViewModel>();
ICommandManager commandManager = Ioc.Default.GetRequiredService<ICommandManager>();

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

// Save the current tab list in case it was overwriten by another instance
AppLifecycleHelper.SaveSessionTabs();
if (userSettingsService.GeneralSettingsService.ContinueLastSessionOnStartUp || userSettingsService.AppSettingsService.RestoreTabsOnStartup)
AppLifecycleHelper.SaveSessionTabs();
else
await commandManager.CloseAllTabs.ExecuteAsync();

if (OutputPath is not null)
{
Expand Down
130 changes: 108 additions & 22 deletions src/Files.App/Helpers/NaturalStringComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,118 @@ public sealed class NaturalStringComparer
{
public static IComparer<object> GetForProcessor()
{
return Win32Helper.IsRunningOnArm ? new StringComparerArm64() : new StringComparerDefault();
return new NaturalComparer(StringComparison.CurrentCulture);
}

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

private sealed class StringComparerDefault : IComparer<object>
{
public int Compare(object a, object b)
{
return Win32PInvoke.CompareStringEx(
Win32PInvoke.LOCALE_NAME_USER_DEFAULT,
Win32PInvoke.SORT_DIGITSASNUMBERS, // Add other flags if required.
a?.ToString(),
a?.ToString().Length ?? 0,
b?.ToString(),
b?.ToString().Length ?? 0,
IntPtr.Zero,
IntPtr.Zero,
0) - 2;
}
public NaturalComparer(StringComparison stringComparison = StringComparison.Ordinal)
{
this.stringComparison = stringComparison;
}

public int Compare(object? x, object? y)
{
if (x == y) return 0;
if (x == null) return -1;
if (y == null) return 1;

return x switch
{
string x1 when y is string y1 => Compare(x1.AsSpan(), y1.AsSpan(), stringComparison),
IComparable comparable => comparable.CompareTo(y),
_ => StringComparer.FromComparison(stringComparison).Compare(x, y)
};
}

public int Compare(string? x, string? y)
{
if (ReferenceEquals(x, y)) return 0;
if (x is null) return -1;
if (y is null) return 1;

return Compare(x.AsSpan(), y.AsSpan(), stringComparison);
}

public int Compare(ReadOnlySpan<char> x, ReadOnlySpan<char> y)
{
return Compare(x, y, stringComparison);
}

public int Compare(ReadOnlyMemory<char> x, ReadOnlyMemory<char> y)
{
return Compare(x.Span, y.Span, stringComparison);
}

public static int Compare(ReadOnlySpan<char> x, ReadOnlySpan<char> y, StringComparison stringComparison)
{
var length = Math.Min(x.Length, y.Length);

for (var i = 0; i < length; i++)
{
if (char.IsDigit(x[i]) && char.IsDigit(y[i]))
{
var xOut = GetNumber(x.Slice(i), out var xNumAsSpan);
var yOut = GetNumber(y.Slice(i), out var yNumAsSpan);

var compareResult = CompareNumValues(xNumAsSpan, yNumAsSpan);

if (compareResult != 0) return compareResult;

i = -1;
length = Math.Min(xOut.Length, yOut.Length);

x = xOut;
y = yOut;
continue;
}

var charCompareResult = x.Slice(i, 1).CompareTo(y.Slice(i, 1), stringComparison);
if (charCompareResult != 0) return charCompareResult;
}

return x.Length.CompareTo(y.Length);
}

private static ReadOnlySpan<char> GetNumber(ReadOnlySpan<char> span, out ReadOnlySpan<char> number)
{
var i = 0;
while (i < span.Length && char.IsDigit(span[i]))
{
i++;
}

number = span.Slice(0, i);
return span.Slice(i);
}

private static int CompareNumValues(ReadOnlySpan<char> numValue1, ReadOnlySpan<char> numValue2)
{
var num1AsSpan = numValue1.TrimStart('0');
var num2AsSpan = numValue2.TrimStart('0');

if (num1AsSpan.Length < num2AsSpan.Length) return -1;

if (num1AsSpan.Length > num2AsSpan.Length) return 1;

var compareResult = num1AsSpan.CompareTo(num2AsSpan, StringComparison.Ordinal);

if (compareResult != 0) return Math.Sign(compareResult);

if (numValue2.Length == numValue1.Length) return compareResult;

return numValue2.Length < numValue1.Length ? -1 : 1; // "033" < "33" == true
}
}
}
}
16 changes: 10 additions & 6 deletions src/Files.App/UserControls/TabBar/TabBar.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,19 @@ private void TabViewItem_Loaded(object sender, RoutedEventArgs e)
}
}

private void DragAreaRectangle_Loaded(object sender, RoutedEventArgs e)
private async void DragAreaRectangle_Loaded(object sender, RoutedEventArgs e)
{
double scaleAdjustment = DragAreaRectangle.XamlRoot.RasterizationScale;
double titleBarInset = ((FilePropertiesHelpers.FlowDirectionSettingIsRightToLeft
if (HorizontalTabView.ActualWidth <= 0 && TabBarAddNewTabButton.Width <= 0)
await Task.Delay(100);

var titleBarInset = ((FilePropertiesHelpers.FlowDirectionSettingIsRightToLeft
? MainWindow.Instance.AppWindow.TitleBar.LeftInset
: MainWindow.Instance.AppWindow.TitleBar.RightInset) / scaleAdjustment) + 40;
: MainWindow.Instance.AppWindow.TitleBar.RightInset) / DragAreaRectangle.XamlRoot.RasterizationScale) + 40;

HorizontalTabView.Measure(new(HorizontalTabView.ActualWidth - TabBarAddNewTabButton.Width - titleBarInset, HorizontalTabView.ActualHeight));
RightPaddingColumn.Width = new(titleBarInset >= 0 ? titleBarInset : 0);
RightPaddingColumn.Width = new(titleBarInset > 40 ? titleBarInset : 138);
HorizontalTabView.Measure(new(
HorizontalTabView.ActualWidth - TabBarAddNewTabButton.Width - titleBarInset,
HorizontalTabView.ActualHeight));
}
}
}
7 changes: 4 additions & 3 deletions src/Files.App/Utils/Shell/LaunchHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ namespace Files.App.Utils.Shell
/// </summary>
public static class LaunchHelper
{
public static void LaunchSettings(string page)
public unsafe static void LaunchSettings(string page)
{
var appActiveManager = new IApplicationActivationManager();
using ComPtr<IApplicationActivationManager> pApplicationActivationManager = default;
pApplicationActivationManager.CoCreateInstance<Shell32.ApplicationActivationManager>();

appActiveManager.ActivateApplication(
pApplicationActivationManager.Get()->ActivateApplication(
"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel",
page,
ACTIVATEOPTIONS.AO_NONE,
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Views/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ private void UserSettingsService_OnSettingChangedEvent(object? sender, SettingCh
private void HorizontalMultitaskingControl_Loaded(object sender, RoutedEventArgs e)
{
TabControl.DragArea.SizeChanged += (_, _) => MainWindow.Instance.RaiseSetTitleBarDragRegion(SetTitleBarDragRegion);
TabControl.SizeChanged += (_, _) => MainWindow.Instance.RaiseSetTitleBarDragRegion(SetTitleBarDragRegion);
if (ViewModel.MultitaskingControl is not TabBar)
{
ViewModel.MultitaskingControl = TabControl;
Expand Down

0 comments on commit ed96899

Please sign in to comment.