Rename project from DellMonitorControl to MonitorControl to reflect broader monitor compatibility beyond Dell hardware. Update all references in solution file, workflow, and project paths. Add DDC/CI rate limiting and throttling logic to prevent command failures: - Minimum 50ms interval between commands to same monitor - 8-second grace period after system resume before sending commands - 3-second cooldown after timeout to allow monitor recovery - Global semaphore to prevent command collisions Replace old icon with new generic monitor icon (ico and png formats).
86 lines
2.7 KiB
C#
86 lines
2.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|