Skip to content

Commit 6daee6c

Browse files
authored
Fix: Fixed crash with properties window (#12500)
1 parent 2e91e77 commit 6daee6c

File tree

3 files changed

+54
-12
lines changed

3 files changed

+54
-12
lines changed

src/Files.App/App.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ await SafetyExtensions.IgnoreExceptions(async () =>
329329
},
330330
Logger);
331331

332+
// Destroy cached properties windows
333+
FilePropertiesHelpers.DestroyCachedWindows();
334+
AppModel.IsMainWindowClosed = true;
335+
332336
// Wait for ongoing file operations
333337
FileOperationsHelpers.WaitForCompletion();
334338
}

src/Files.App/Data/Models/AppModel.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,12 @@ public bool IsPasteEnabled
6767
get => isPasteEnabled;
6868
set => SetProperty(ref isPasteEnabled, value);
6969
}
70+
71+
private bool isMainWindowClosed = false;
72+
public bool IsMainWindowClosed
73+
{
74+
get => isMainWindowClosed;
75+
set => SetProperty(ref isMainWindowClosed, value);
76+
}
7077
}
7178
}

src/Files.App/Helpers/FilePropertiesHelpers.cs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
using Microsoft.UI.Windowing;
66
using Microsoft.UI.Xaml;
77
using Microsoft.UI.Xaml.Controls;
8+
using Microsoft.UI.Xaml.Media;
89
using Microsoft.UI.Xaml.Media.Animation;
910
using Microsoft.Windows.ApplicationModel.Resources;
11+
using System.Collections.Concurrent;
1012
using System.IO;
1113
using Windows.ApplicationModel;
1214
using Windows.Graphics;
@@ -38,6 +40,8 @@ public static string LogoPath
3840
public static nint GetWindowHandle(Window w)
3941
=> WinRT.Interop.WindowNative.GetWindowHandle(w);
4042

43+
private static BlockingCollection<WinUIEx.WindowEx> WindowCache = new();
44+
4145
/// <summary>
4246
/// Open properties window
4347
/// </summary>
@@ -97,17 +101,21 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
97101
RequestedTheme = ThemeHelper.RootTheme
98102
};
99103

100-
var propertiesWindow = new WinUIEx.WindowEx
104+
WinUIEx.WindowEx propertiesWindow;
105+
if (!WindowCache.TryTake(out propertiesWindow!))
101106
{
102-
IsMinimizable = false,
103-
IsMaximizable = false,
104-
MinWidth = 460,
105-
MinHeight = 550,
106-
Width = 800,
107-
Height = 550,
108-
Content = frame,
109-
Backdrop = new WinUIEx.MicaSystemBackdrop(),
110-
};
107+
propertiesWindow = new();
108+
propertiesWindow.Closed += PropertiesWindow_Closed;
109+
}
110+
111+
propertiesWindow.IsMinimizable = false;
112+
propertiesWindow.IsMaximizable = false;
113+
propertiesWindow.MinWidth = 460;
114+
propertiesWindow.MinHeight = 550;
115+
propertiesWindow.Width = 800;
116+
propertiesWindow.Height = 550;
117+
propertiesWindow.Content = frame;
118+
propertiesWindow.SystemBackdrop = new MicaBackdrop();
111119

112120
var appWindow = propertiesWindow.AppWindow;
113121
appWindow.Title = "Properties".GetLocalizedResource();
@@ -128,8 +136,6 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
128136
},
129137
new SuppressNavigationTransitionInfo());
130138

131-
appWindow.Show();
132-
133139
// WINUI3: Move window to cursor position
134140
InteropHelpers.GetCursorPos(out var pointerPosition);
135141
var displayArea = DisplayArea.GetFromPoint(new PointInt32(pointerPosition.X, pointerPosition.Y), DisplayAreaFallback.Nearest);
@@ -142,6 +148,31 @@ public static void OpenPropertiesWindow(object item, IShellPage associatedInstan
142148
};
143149

144150
appWindow.Move(appWindowPos);
151+
152+
appWindow.Show();
153+
}
154+
155+
// Destruction of Window objects seems to cause access violation. (#12057)
156+
// So instead of destroying the Window object, cache it and reuse it as a workaround.
157+
private static void PropertiesWindow_Closed(object sender, WindowEventArgs args)
158+
{
159+
if (!App.AppModel.IsMainWindowClosed && sender is WinUIEx.WindowEx window)
160+
{
161+
args.Handled = true;
162+
163+
window.AppWindow.Hide();
164+
window.Content = null;
165+
WindowCache.Add(window);
166+
}
167+
}
168+
169+
public static void DestroyCachedWindows()
170+
{
171+
while (WindowCache.TryTake(out var window))
172+
{
173+
window.Closed -= PropertiesWindow_Closed;
174+
window.Close();
175+
}
145176
}
146177
}
147178
}

0 commit comments

Comments
 (0)