From 817836ab287c14ef03390dfde266babd47c0a54d Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sat, 19 Sep 2026 18:58:14 +0200 Subject: [PATCH] (bugfix): main window startup fix --- CHANGELOG.md | 8 +++- data/eu.postclient.desktop.metainfo.xml | 5 +++ src/Directory.Build.props | 2 +- src/MaksIT.PostClient.UI/App.axaml.cs | 40 +++++++------------ src/MaksIT.PostClient.UI/MainWindow.axaml.cs | 8 ---- .../MaksIT.PostClient.UI.csproj | 3 -- 6 files changed, 28 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9227dc..435ac57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format follows [Keep a Changelog](https://keepachangelog.com/) and [Semantic ## [Unreleased] +## [0.3.1] - 2026-09-19 + +### Fixed + +- Reinstalling **0.3.0** over **0.3.0** left the old exe in `C:\Program Files\MaksIT\Postclient` (Windows setup skips same-version files). This build is **0.3.1** so the installer replaces it. Uninstall 0.3.0 first if a same-version repair still leaves the 16:08 exe. +- The main window opens from the desktop shortcut. Closing it exits the app. The tray icon no longer hides the window on close. A worker process is not started until import or retention needs it. + ## [0.3.0] - 2026-09-19 Folder stores replace attached Outlook data files, Gmail/Microsoft sign-in goes through Identity Hub, and folders can expire mail on a schedule. @@ -35,7 +42,6 @@ Folder stores replace attached Outlook data files, Gmail/Microsoft sign-in goes - Identity Hub Google/Microsoft sign-in now picks up the Hub session after the callback page finishes (the WebView no longer waits for you to close a tab). Save Account then stores the Hub tokens. - Microsoft Identity Hub sign-in in the embedded WebView: Entra popups no longer replace the Hub page, script polling stays on `identity.maks-it.com`, and login uses a separate WebView2 profile from HTML mail. Sign-in now checks that Hub can issue a mailbox token. - Identity Hub sign-in opens `identity.maks-it.com` after the WebView adapter is ready (the popup no longer stays on `about:blank`). Google/Microsoft redirects stay in that view; Hub login uses its own WebView2 data folder so it does not clash with HTML mail. The sign-in dialog is owned by Account Settings when that window is open. -- The main window shows on launch from the installed exe (and the desktop shortcut). A background worker is no longer started before the window is mapped, so the process is not left running with no UI. - Connecting a large Outlook data file no longer freezes the UI: PST open/list/index work runs off the UI thread, catalog walks the store in short chunks, and folder switches show the local archive without waiting on indexing. - Large Outlook data files keep readable subjects (MS-PST prefix bytes are stripped) and open by the store item id instead of a subject hash. ANSI `.pst` files are copied once to a Unicode `.postclient.pst` beside the original so encoding stays intact. diff --git a/data/eu.postclient.desktop.metainfo.xml b/data/eu.postclient.desktop.metainfo.xml index d376840..e275289 100644 --- a/data/eu.postclient.desktop.metainfo.xml +++ b/data/eu.postclient.desktop.metainfo.xml @@ -30,6 +30,11 @@ 768 + + +

The main window opens on launch from the Windows setup. Closing the window exits the app.

+
+

Folder stores replace attached Outlook data files. Gmail and Microsoft sign-in go through Identity Hub. Per-folder retention, multi-select, and IMAP/OAuth reliability fixes.

diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 94ea21e..afbfdf2 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ latest enable enable - 0.3.0 + 0.3.1 Postclient Postclient Maksym Sadovnychyy diff --git a/src/MaksIT.PostClient.UI/App.axaml.cs b/src/MaksIT.PostClient.UI/App.axaml.cs index 4059dbf..be4eadc 100644 --- a/src/MaksIT.PostClient.UI/App.axaml.cs +++ b/src/MaksIT.PostClient.UI/App.axaml.cs @@ -1,8 +1,7 @@ -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Avalonia; using Avalonia.Controls; +using Avalonia.Threading; using Avalonia.Markup.Xaml; using Avalonia.Controls.ApplicationLifetimes; using MaksIT.PostClient.Client; @@ -14,7 +13,7 @@ namespace MaksIT.PostClient.UI; public partial class App : Application { - private IHost? _host; + private ServiceProvider? _services; public override void Initialize() => AvaloniaXamlLoader.Load(this); @@ -28,39 +27,30 @@ public partial class App : Application { } base.OnFrameworkInitializationCompleted(); - ShowMain(); + Dispatcher.UIThread.Post(ShowMain, DispatcherPriority.Loaded); } private void CompleteStartup() { AppPaths.EnsureDirectories(); - _host = Host.CreateDefaultBuilder() - .ConfigureAppConfiguration(builder => { - builder.SetBasePath(AppContext.BaseDirectory); - builder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false); - builder.AddJsonFile(AppPaths.SettingsFile(), optional: true, reloadOnChange: true); - }) - .ConfigureServices((_, services) => { - services.AddSingleton(_ => new ConfigurationFileService()); - services.AddPostClient(); - services.AddSingleton(); - services.AddSingleton(); - }) - .Build(); + var services = new ServiceCollection(); + services.AddSingleton(_ => new ConfigurationFileService()); + services.AddPostClient(); + services.AddSingleton(); + services.AddSingleton(); + _services = services.BuildServiceProvider(); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown; - desktop.MainWindow = _host.Services.GetRequiredService(); - ShowMain(); + desktop.ShutdownMode = ShutdownMode.OnMainWindowClose; + desktop.MainWindow = _services.GetRequiredService(); ApplyTrayCopy(); UiLocale.Changed += ApplyTrayCopy; desktop.ShutdownRequested += async (_, _) => { - if (_host is null) + if (_services is null) return; - await _host.Services.GetRequiredService().DisposeAsync(); - await _host.StopAsync(); - _host.Dispose(); - _host = null; + await _services.GetRequiredService().DisposeAsync(); + await _services.DisposeAsync(); + _services = null; }; } } diff --git a/src/MaksIT.PostClient.UI/MainWindow.axaml.cs b/src/MaksIT.PostClient.UI/MainWindow.axaml.cs index 8a33656..fd583fd 100644 --- a/src/MaksIT.PostClient.UI/MainWindow.axaml.cs +++ b/src/MaksIT.PostClient.UI/MainWindow.axaml.cs @@ -806,14 +806,6 @@ public partial class MainWindow : Window { return files.FirstOrDefault()?.TryGetLocalPath(); } - protected override void OnClosing(WindowClosingEventArgs e) { - if (e.IsProgrammatic) - return; - e.Cancel = true; - if (IsVisible) - Hide(); - } - private void OnExitClick(object? sender, RoutedEventArgs e) { if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime life) life.Shutdown(); diff --git a/src/MaksIT.PostClient.UI/MaksIT.PostClient.UI.csproj b/src/MaksIT.PostClient.UI/MaksIT.PostClient.UI.csproj index fb911f4..838641a 100644 --- a/src/MaksIT.PostClient.UI/MaksIT.PostClient.UI.csproj +++ b/src/MaksIT.PostClient.UI/MaksIT.PostClient.UI.csproj @@ -20,9 +20,6 @@ - - -