using CMM.Library.Method; using Hardcodet.Wpf.TaskbarNotification; using Microsoft.Win32; using System.Windows; namespace MonitorControl { public partial class App : Application { private TaskbarIcon? _trayIcon; private MainWindow? _mainWindow; private UpdateInfo? _pendingUpdate; private async void Application_Startup(object sender, StartupEventArgs e) { _trayIcon = (TaskbarIcon)FindResource("TrayIcon"); _trayIcon.TrayLeftMouseUp += TrayIcon_Click; _trayIcon.TrayBalloonTipClicked += TrayIcon_BalloonTipClicked; _mainWindow = new MainWindow(); // Listen for system sleep/resume to protect monitors during wake SystemEvents.PowerModeChanged += OnPowerModeChanged; // Check for updates in background await CheckForUpdatesAsync(); } private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e) { if (e.Mode == PowerModes.Resume) { // Notify the DDC/CI layer that monitors need time to wake up CMMCommand.NotifySystemResumed(); DebugLogger.Log("System resumed from sleep - DDC/CI grace period activated"); } } private async System.Threading.Tasks.Task CheckForUpdatesAsync() { try { _pendingUpdate = await UpdateChecker.CheckForUpdateAsync(); if (_pendingUpdate != null && _trayIcon != null) { _trayIcon.ShowBalloonTip( "Update Available", $"Monitor Control v{_pendingUpdate.LatestVersion} is available.\nClick to download.", BalloonIcon.Info); } } catch { } } private void TrayIcon_BalloonTipClicked(object sender, RoutedEventArgs e) { if (_pendingUpdate != null && !string.IsNullOrEmpty(_pendingUpdate.DownloadUrl)) { UpdateChecker.OpenDownloadPage(_pendingUpdate.DownloadUrl); } } private async void TrayIcon_Click(object sender, RoutedEventArgs e) { if (_mainWindow == null) return; if (_mainWindow.IsVisible) { _mainWindow.Hide(); } else { _mainWindow.ShowNearTray(); await _mainWindow.LoadMonitors(); } } protected override void OnExit(ExitEventArgs e) { SystemEvents.PowerModeChanged -= OnPowerModeChanged; _trayIcon?.Dispose(); base.OnExit(e); } } }