|
|
@ -1,6 +1,9 @@ |
|
|
using System; |
|
|
using System; |
|
|
|
|
|
using System.Collections.Generic; |
|
|
using Avalonia.Controls; |
|
|
using Avalonia.Controls; |
|
|
|
|
|
|
|
|
|
|
|
#nullable enable |
|
|
|
|
|
|
|
|
namespace Avalonia.X11 |
|
|
namespace Avalonia.X11 |
|
|
{ |
|
|
{ |
|
|
internal class TransparencyHelper : IDisposable, X11Globals.IGlobalsSubscriber |
|
|
internal class TransparencyHelper : IDisposable, X11Globals.IGlobalsSubscriber |
|
|
@ -9,10 +12,10 @@ namespace Avalonia.X11 |
|
|
private readonly IntPtr _window; |
|
|
private readonly IntPtr _window; |
|
|
private readonly X11Globals _globals; |
|
|
private readonly X11Globals _globals; |
|
|
private WindowTransparencyLevel _currentLevel; |
|
|
private WindowTransparencyLevel _currentLevel; |
|
|
private WindowTransparencyLevel _requestedLevel; |
|
|
private IReadOnlyList<WindowTransparencyLevel>? _requestedLevels; |
|
|
private bool _blurAtomsAreSet; |
|
|
private bool _blurAtomsAreSet; |
|
|
|
|
|
|
|
|
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; } |
|
|
public Action<WindowTransparencyLevel>? TransparencyLevelChanged { get; set; } |
|
|
public WindowTransparencyLevel CurrentLevel => _currentLevel; |
|
|
public WindowTransparencyLevel CurrentLevel => _currentLevel; |
|
|
|
|
|
|
|
|
public TransparencyHelper(X11Info x11, IntPtr window, X11Globals globals) |
|
|
public TransparencyHelper(X11Info x11, IntPtr window, X11Globals globals) |
|
|
@ -23,28 +26,62 @@ namespace Avalonia.X11 |
|
|
_globals.AddSubscriber(this); |
|
|
_globals.AddSubscriber(this); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void SetTransparencyRequest(WindowTransparencyLevel level) |
|
|
public void SetTransparencyRequest(IReadOnlyList<WindowTransparencyLevel> levels) |
|
|
{ |
|
|
{ |
|
|
_requestedLevel = level; |
|
|
WindowTransparencyLevel? newLevel = null; |
|
|
UpdateTransparency(); |
|
|
_requestedLevels = levels; |
|
|
} |
|
|
|
|
|
|
|
|
foreach (var level in levels) |
|
|
|
|
|
{ |
|
|
|
|
|
if (!IsSupported(level)) |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
SetBlur(level == WindowTransparencyLevel.Blur); |
|
|
|
|
|
newLevel = level; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// If no matching transparency level was found, revert to Transparent or None depending
|
|
|
|
|
|
// on whether composition is enabled.
|
|
|
|
|
|
if (!newLevel.HasValue) |
|
|
|
|
|
{ |
|
|
|
|
|
newLevel = _globals.IsCompositionEnabled ? |
|
|
|
|
|
WindowTransparencyLevel.Transparent : |
|
|
|
|
|
WindowTransparencyLevel.None; |
|
|
|
|
|
SetBlur(false); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private void UpdateTransparency() |
|
|
|
|
|
{ |
|
|
|
|
|
var newLevel = UpdateAtomsAndGetTransparency(); |
|
|
|
|
|
if (newLevel != _currentLevel) |
|
|
if (newLevel != _currentLevel) |
|
|
{ |
|
|
{ |
|
|
_currentLevel = newLevel; |
|
|
_currentLevel = newLevel.Value; |
|
|
TransparencyLevelChanged?.Invoke(newLevel); |
|
|
TransparencyLevelChanged?.Invoke(newLevel.Value); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private WindowTransparencyLevel UpdateAtomsAndGetTransparency() |
|
|
private bool IsSupported(WindowTransparencyLevel level) |
|
|
{ |
|
|
{ |
|
|
var blur = _requestedLevel == WindowTransparencyLevel.Blur || |
|
|
// None is suppported when composition is disabled.
|
|
|
_requestedLevel == WindowTransparencyLevel.AcrylicBlur || |
|
|
if (level == WindowTransparencyLevel.None) |
|
|
_requestedLevel == WindowTransparencyLevel.Mica; |
|
|
return !_globals.IsCompositionEnabled; |
|
|
|
|
|
|
|
|
|
|
|
// Transparent is suppported when composition is enabled.
|
|
|
|
|
|
if (level == WindowTransparencyLevel.Transparent) |
|
|
|
|
|
return _globals.IsCompositionEnabled; |
|
|
|
|
|
|
|
|
|
|
|
// Blur is supported when composition is enabled and KWin is used.
|
|
|
|
|
|
if (level == WindowTransparencyLevel.Blur) |
|
|
|
|
|
return _globals.IsCompositionEnabled && _globals.WmName == "KWin"; |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void UpdateTransparency() |
|
|
|
|
|
{ |
|
|
|
|
|
SetTransparencyRequest(_requestedLevels ?? Array.Empty<WindowTransparencyLevel>()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void SetBlur(bool blur) |
|
|
|
|
|
{ |
|
|
if (blur) |
|
|
if (blur) |
|
|
{ |
|
|
{ |
|
|
if (!_blurAtomsAreSet) |
|
|
if (!_blurAtomsAreSet) |
|
|
@ -63,15 +100,7 @@ namespace Avalonia.X11 |
|
|
_blurAtomsAreSet = false; |
|
|
_blurAtomsAreSet = false; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!_globals.IsCompositionEnabled) |
|
|
|
|
|
return WindowTransparencyLevel.None; |
|
|
|
|
|
if (blur && CanBlur) |
|
|
|
|
|
return WindowTransparencyLevel.Blur; |
|
|
|
|
|
return WindowTransparencyLevel.Transparent; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private bool CanBlur => _globals.WmName == "KWin" && _globals.IsCompositionEnabled; |
|
|
|
|
|
|
|
|
|
|
|
public void Dispose() |
|
|
public void Dispose() |
|
|
{ |
|
|
{ |
|
|
|