diff --git a/DesktopClock/MainWindow.xaml.cs b/DesktopClock/MainWindow.xaml.cs index 30b74e8..e386390 100644 --- a/DesktopClock/MainWindow.xaml.cs +++ b/DesktopClock/MainWindow.xaml.cs @@ -10,6 +10,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DesktopClock.Properties; +using DesktopClock.Utilities; using H.NotifyIcon; using H.NotifyIcon.EfficiencyMode; using Humanizer; @@ -23,13 +24,11 @@ namespace DesktopClock; [ObservableObject] public partial class MainWindow : Window { - private readonly Random _random = new(); private readonly SystemClockTimer _systemClockTimer; private TaskbarIcon _trayIcon; private TimeZoneInfo _timeZone; private SoundPlayer _soundPlayer; - private double totalShiftX; - private double totalShiftY; + private PixelShifter _pixelShifter; /// /// The date and time to countdown to, or null if regular clock is desired. @@ -204,23 +203,6 @@ private void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e) } } - private void ShiftWindow() - { - const int MaxTotalShift = 10; - const int MaxShiftPerTick = 5; - - double ApplyShift(ref double totalShift) - { - var shift = _random.Next(-MaxShiftPerTick, MaxShiftPerTick + 1); - totalShift += shift; - - return Math.Min(MaxTotalShift, totalShift); - } - - Left += ApplyShift(ref totalShiftX); - Top += ApplyShift(ref totalShiftY); - } - /// /// Handles the event when the system clock timer signals a second change. /// @@ -230,7 +212,11 @@ private void SystemClockTimer_SecondChanged(object sender, EventArgs e) TryPlaySound(); - Dispatcher.Invoke(ShiftWindow); + if (Settings.Default.BurnInMitigation) + { + _pixelShifter ??= new(this); + Dispatcher.Invoke(_pixelShifter.ShiftWindow); + } } /// diff --git a/DesktopClock/Properties/Settings.cs b/DesktopClock/Properties/Settings.cs index 802447b..9ffe2a0 100644 --- a/DesktopClock/Properties/Settings.cs +++ b/DesktopClock/Properties/Settings.cs @@ -180,7 +180,7 @@ private Settings() public bool RightAligned { get; set; } = false; /// - /// Experimental: Shifts the clock's pixels and makes the background more transparent in order to prevent burn-in. + /// Experimental: Shifts the clock around in order to prevent burn-in. /// public bool BurnInMitigation { get; set; } = false; diff --git a/DesktopClock/Utilities/PixelShifter.cs b/DesktopClock/Utilities/PixelShifter.cs new file mode 100644 index 0000000..fb675c5 --- /dev/null +++ b/DesktopClock/Utilities/PixelShifter.cs @@ -0,0 +1,53 @@ +using System; +using System.Windows; + +namespace DesktopClock.Utilities; + +public class PixelShifter +{ + private readonly Random _random = new(); + private readonly Window _window; + private double _totalShiftX; + private double _totalShiftY; + + /// + /// The number of pixels that will be shifted each time. + /// + public int ShiftAmount { get; set; } = 2; + + /// + /// The maximum amount of drift that can occur in each direction. + /// + public int MaxTotalShift { get; set; } = 4; + + public PixelShifter(Window window) + { + _window = window; + } + + /// + /// Shifts the location of the window randomly to help prevent screen burn-in. + /// + public void ShiftWindow() + { + double CalculateShift(ref double totalShift) + { + var shift = _random.Next(-ShiftAmount, ShiftAmount + 1); + var newTotalShift = totalShift + shift; + + if (Math.Abs(newTotalShift) <= MaxTotalShift) + { + totalShift = newTotalShift; + return shift; + } + + return 0; + } + + var shiftX = CalculateShift(ref _totalShiftX); + var shiftY = CalculateShift(ref _totalShiftY); + + _window.Left += shiftX; + _window.Top += shiftY; + } +}