2
0
Files
logikonline 404e6f42da
All checks were successful
Build / build (push) Successful in 9h0m26s
Build and Release / build (push) Successful in 8h0m15s
refactor(ci): rename DellMonitorControl to MonitorControl
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).
2026-01-29 18:14:58 -05:00

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);
}
}
}