mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-13 06:07:30 -04:00
Libation's releases are ReadyToRun, so a Serilog reference resolves lazily when the line holding it runs. An install folder whose Serilog.dll is missing or older than the build therefore threw inside the very catch blocks that were meant to report the problem, which destroyed the original exception and aborted the in-app upgrade recovery before it could roll anything back. Add StartupLog: a Serilog-free, never-throwing buffer for the window before ConfigureLogging runs, replayed into Serilog once logging exists. Move the pre-logging call sites onto it, including the crash-message and crash-dialog paths that run precisely when the install is broken. Those messages were silent before this change: Serilog.Log.Logger is still Serilog's silent logger until App.RunMigrations. They now reach the log file. Co-authored-by: rmcrackan <rmcrackan@gmail.com>
117 lines
3.4 KiB
C#
117 lines
3.4 KiB
C#
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls.ApplicationLifetimes;
|
|
using Avalonia.Platform;
|
|
using Dinah.Core;
|
|
using LibationFileManager;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace LibationAvalonia;
|
|
|
|
public static class FormSaveExtension
|
|
{
|
|
static readonly WindowIcon? WindowIcon;
|
|
static FormSaveExtension()
|
|
{
|
|
WindowIcon = Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop && desktop.MainWindow?.Icon is WindowIcon icon
|
|
? icon
|
|
: null;
|
|
}
|
|
|
|
public static void SetLibationIcon(this Window form)
|
|
{
|
|
form.Icon = WindowIcon;
|
|
}
|
|
|
|
public static void RestoreSizeAndLocation(this Window form, Configuration config)
|
|
{
|
|
if (Design.IsDesignMode) return;
|
|
try
|
|
{
|
|
var savedState = config.GetNonString<FormSizeAndPosition?>(defaultValue: null, form.GetType().Name);
|
|
|
|
if (savedState is null)
|
|
return;
|
|
|
|
// too small -- something must have gone wrong. use defaults
|
|
if (savedState.Width < form.MinWidth || savedState.Height < form.MinHeight)
|
|
{
|
|
savedState.Width = (int)form.Width;
|
|
savedState.Height = (int)form.Height;
|
|
}
|
|
if ((form.Screens.Primary ?? form.Screens.All.FirstOrDefault()) is Screen primaryScreen)
|
|
{
|
|
// Fit to the current screen size in case the screen resolution changed since the size was last persisted
|
|
if (savedState.Width > primaryScreen.WorkingArea.Width)
|
|
savedState.Width = primaryScreen.WorkingArea.Width;
|
|
if (savedState.Height > primaryScreen.WorkingArea.Height)
|
|
savedState.Height = primaryScreen.WorkingArea.Height;
|
|
}
|
|
|
|
var rect = new PixelRect(savedState.X, savedState.Y, savedState.Width, savedState.Height);
|
|
|
|
form.Width = savedState.Width;
|
|
form.Height = savedState.Height;
|
|
|
|
// is proposed rect on a screen?
|
|
if (form.Screens.All.Any(screen => screen.WorkingArea.Contains(rect)))
|
|
{
|
|
form.WindowStartupLocation = WindowStartupLocation.Manual;
|
|
form.Position = new PixelPoint(savedState.X, savedState.Y);
|
|
}
|
|
else
|
|
{
|
|
form.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
|
}
|
|
|
|
// FINAL: for Maximized: start normal state, set size and location, THEN set max state
|
|
form.WindowState = savedState.IsMaximized ? WindowState.Maximized : WindowState.Normal;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// The crash dialog restores its own position, so this runs while the install may be broken.
|
|
// Logging through Serilog here took the dialog down with it. See issue #2001.
|
|
StartupLog.Error(ex, $"Failed to restore {form.GetType().Name} size and location");
|
|
}
|
|
}
|
|
public static void SaveSizeAndLocation(this Window form, Configuration config)
|
|
{
|
|
if (Design.IsDesignMode) return;
|
|
|
|
try
|
|
{
|
|
var saveState = new FormSizeAndPosition();
|
|
|
|
saveState.IsMaximized = form.WindowState == WindowState.Maximized;
|
|
|
|
// restore normal state to get real window size.
|
|
if (form.WindowState != WindowState.Normal)
|
|
{
|
|
form.WindowState = WindowState.Normal;
|
|
}
|
|
|
|
saveState.X = form.Position.X;
|
|
saveState.Y = form.Position.Y;
|
|
|
|
saveState.Width = (int)form.Bounds.Size.Width;
|
|
saveState.Height = (int)form.Bounds.Size.Height;
|
|
|
|
config.SetNonString(saveState, form.GetType().Name);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
StartupLog.Error(ex, $"Failed to save {form.GetType().Name} size and location");
|
|
}
|
|
}
|
|
|
|
private record FormSizeAndPosition
|
|
{
|
|
public int X;
|
|
public int Y;
|
|
public int Height;
|
|
public int Width;
|
|
public bool IsMaximized;
|
|
}
|
|
}
|