Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MoneyShot/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MoneyShot"
StartupUri="MainWindow.xaml">
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
Expand Down
8 changes: 8 additions & 0 deletions MoneyShot/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ protected override void OnStartup(StartupEventArgs e)
}

base.OnStartup(e);

// StartupUri is intentionally not used. It calls Show() during startup, which paints an
// unrendered (black) frame before the Loaded handler can hide it when StartInTray is set.
// Instead we create the window here and let InitializeApplication decide whether to show
// it or just realize its handle for hotkeys — see MainWindow.InitializeApplication.
var mainWindow = new MainWindow();
MainWindow = mainWindow;
mainWindow.InitializeApplication();
}

protected override void OnExit(ExitEventArgs e)
Expand Down
32 changes: 23 additions & 9 deletions MoneyShot/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using MoneyShot.Services;
using MoneyShot.Views;
Expand Down Expand Up @@ -37,27 +38,40 @@ public MainWindow()
_historyService = new HistoryService();

SetupSystemTray();
Loaded += MainWindow_Loaded;
}

private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
/// <summary>
/// Performs post-construction startup: realizes the native handle, binds global hotkeys, and
/// shows the window only when the user hasn't opted to start in the tray. Called once from
/// <see cref="App.OnStartup"/>. When <see cref="Models.AppSettings.StartInTray"/> is set the
/// window is never shown — <see cref="WindowInteropHelper.EnsureHandle"/> creates the HWND that
/// hotkey registration needs without painting anything, which avoids the black-frame flash that
/// Show()-then-Hide() produced.
/// </summary>
public void InitializeApplication()
{
try
{
_hotKeyService.Initialize(this);
RegisterHotKeys();
PopulateMonitorButtons();

// Check if app should start in tray
var settings = _settingsService.LoadSettings();

if (settings.StartInTray)
{
Hide();
// Realize the Win32 handle without making the window visible.
new WindowInteropHelper(this).EnsureHandle();
}
else
{
ShowMainWindow();
}

// The HWND now exists (via EnsureHandle or Show), so global hotkeys can bind to it.
_hotKeyService.Initialize(this);
RegisterHotKeys();
PopulateMonitorButtons();

if (settings.CheckForUpdatesOnStartup)
{
await CheckForUpdatesOnStartupAsync();
_ = CheckForUpdatesOnStartupAsync();
}
}
catch (Exception ex)
Expand Down
Loading