From 1f2acc776cf74bc1bdc925d0ed1c0d82119d545c Mon Sep 17 00:00:00 2001 From: Aytackydln Date: Wed, 30 Oct 2024 23:15:18 +0100 Subject: [PATCH] fix Ambilight freeze when property changes --- .../Layers/Ambilight/DXScreenCapture.cs | 2 +- .../Layers/Ambilight/GDIScreenCapture.cs | 11 ++-- .../Settings/Layers/AmbilightLayerHandler.cs | 56 ++++++++++--------- .../Project-Aurora/Utils/Temporary.cs | 1 + 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/DXScreenCapture.cs b/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/DXScreenCapture.cs index b00e328bc..06e9e182e 100644 --- a/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/DXScreenCapture.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/DXScreenCapture.cs @@ -160,6 +160,6 @@ public void Dispose() { _desktopDuplicator = null; } - WindowListener.Dispose(); + _windowListenerReference.Dispose(); } } \ No newline at end of file diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/GDIScreenCapture.cs b/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/GDIScreenCapture.cs index 030db61b9..4e33cad43 100644 --- a/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/GDIScreenCapture.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/Ambilight/GDIScreenCapture.cs @@ -12,7 +12,7 @@ internal sealed class GdiScreenCapture : IScreenCapture { public event EventHandler? ScreenshotTaken; - private Bitmap? _bitmap; + private Bitmap? _lastBitmap; private Graphics _graphics = Graphics.FromImage(new Bitmap(8, 8)); private readonly WindowListener.WindowListenerReference _windowListenerReference = new(); @@ -20,7 +20,7 @@ internal sealed class GdiScreenCapture : IScreenCapture public void Capture(Rectangle desktopRegion, Bitmap bitmap) { - if (_bitmap != bitmap) + if (_lastBitmap != bitmap) { _graphics.Dispose(); _graphics = Graphics.FromImage(bitmap); @@ -30,7 +30,7 @@ public void Capture(Rectangle desktopRegion, Bitmap bitmap) _graphics.SmoothingMode = SmoothingMode.HighSpeed; _graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed; - _bitmap = bitmap; + _lastBitmap = bitmap; } _graphics.CopyFromScreen(desktopRegion.Location, Point.Empty, desktopRegion.Size); @@ -44,8 +44,7 @@ public IEnumerable GetDisplays() => public void Dispose() { _graphics.Dispose(); - _bitmap?.Dispose(); - _bitmap = null; - WindowListener.Dispose(); + _lastBitmap = null; + _windowListenerReference.Dispose(); } } \ No newline at end of file diff --git a/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs b/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs index 885d2e7e7..c75639ac4 100644 --- a/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs +++ b/Project-Aurora/Project-Aurora/Settings/Layers/AmbilightLayerHandler.cs @@ -213,7 +213,7 @@ public override void Default() [DoNotNotify] public sealed class AmbilightLayerHandler : LayerHandler { - private Temporary _screenCapture; + private readonly Temporary _screenCapture; private readonly SmartThreadPool _captureWorker; private readonly WorkItemCallback _screenshotWork; @@ -426,35 +426,41 @@ protected override void PropertiesChanged(object? sender, PropertyChangedEventAr _imageAttributes.SetColorMatrix(new ColorMatrix(mtx)); _imageAttributes.SetWrapMode(WrapMode.Clamp); - var activeProcessMonitor = ProcessesModule.ActiveProcessMonitor.Result; - activeProcessMonitor.ActiveProcessChanged -= ProcessChanged; - _screenCapture.Value.WindowListener.WindowCreated -= WindowsChanged; - _screenCapture.Value.WindowListener.WindowDestroyed -= WindowsChanged; - switch (Properties.AmbilightCaptureType) + switch (args.PropertyName) { - case AmbilightCaptureType.SpecificProcess when !string.IsNullOrWhiteSpace(Properties.SpecificProcess): - UpdateSpecificProcessHandle(Properties.SpecificProcess); + case nameof(Properties.AmbilightCaptureType): + { + var activeProcessMonitor = ProcessesModule.ActiveProcessMonitor.Result; + activeProcessMonitor.ActiveProcessChanged -= ProcessChanged; + _screenCapture.Value.WindowListener.WindowCreated -= WindowsChanged; + _screenCapture.Value.WindowListener.WindowDestroyed -= WindowsChanged; + switch (Properties.AmbilightCaptureType) + { + case AmbilightCaptureType.SpecificProcess when !string.IsNullOrWhiteSpace(Properties.SpecificProcess): + UpdateSpecificProcessHandle(Properties.SpecificProcess); - _screenCapture.Value.WindowListener.WindowCreated += WindowsChanged; - _screenCapture.Value.WindowListener.WindowDestroyed += WindowsChanged; - break; - case AmbilightCaptureType.ForegroundApp: - _specificProcessHandle = User32.GetForegroundWindow(); - activeProcessMonitor.ActiveProcessChanged += ProcessChanged; + _screenCapture.Value.WindowListener.WindowCreated += WindowsChanged; + _screenCapture.Value.WindowListener.WindowDestroyed += WindowsChanged; + break; + case AmbilightCaptureType.ForegroundApp: + _specificProcessHandle = User32.GetForegroundWindow(); + activeProcessMonitor.ActiveProcessChanged += ProcessChanged; + break; + case AmbilightCaptureType.Coordinates: + case AmbilightCaptureType.EntireMonitor: + default: + break; + } + + // the instance will be recreated + _screenCapture.Dispose(); break; - case AmbilightCaptureType.Coordinates: - case AmbilightCaptureType.EntireMonitor: - default: + } + case nameof(Properties.ExperimentalMode): + // the instance will be recreated + _screenCapture.Dispose(); break; } - - _screenCapture.Dispose(); - _screenCapture = new Temporary(() => - { - IScreenCapture screenCapture = Properties.ExperimentalMode ? new DxScreenCapture() : new GdiScreenCapture(); - screenCapture.ScreenshotTaken += ScreenshotAction; - return screenCapture; - }); } private void ProcessChanged(object? sender, EventArgs e) diff --git a/Project-Aurora/Project-Aurora/Utils/Temporary.cs b/Project-Aurora/Project-Aurora/Utils/Temporary.cs index 2a3c16164..6216c3dae 100644 --- a/Project-Aurora/Project-Aurora/Utils/Temporary.cs +++ b/Project-Aurora/Project-Aurora/Utils/Temporary.cs @@ -63,6 +63,7 @@ public void Dispose() { disposable.Dispose(); } + _value = null; } public async ValueTask DisposeAsync()