Browse Source

Implement transparency level hint list on X11.

pull/11509/head
Steven Kirk 3 years ago
parent
commit
9715d71bd9
  1. 77
      src/Avalonia.X11/TransparencyHelper.cs
  2. 6
      src/Avalonia.X11/X11Window.cs

77
src/Avalonia.X11/TransparencyHelper.cs

@ -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()
{ {

6
src/Avalonia.X11/X11Window.cs

@ -196,7 +196,7 @@ namespace Avalonia.X11
_rawEventGrouper = new RawEventGrouper(DispatchInput, platform.EventGrouperDispatchQueue); _rawEventGrouper = new RawEventGrouper(DispatchInput, platform.EventGrouperDispatchQueue);
_transparencyHelper = new TransparencyHelper(_x11, _handle, platform.Globals); _transparencyHelper = new TransparencyHelper(_x11, _handle, platform.Globals);
_transparencyHelper.SetTransparencyRequest(WindowTransparencyLevel.None); _transparencyHelper.SetTransparencyRequest(Array.Empty<WindowTransparencyLevel>());
CreateIC(); CreateIC();
@ -1307,9 +1307,9 @@ namespace Avalonia.X11
public IPopupPositioner? PopupPositioner { get; } public IPopupPositioner? PopupPositioner { get; }
public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevel) public void SetTransparencyLevelHint(IReadOnlyList<WindowTransparencyLevel> transparencyLevels)
{ {
////_transparencyHelper?.SetTransparencyRequest(transparencyLevel); _transparencyHelper?.SetTransparencyRequest(transparencyLevels);
} }
public void SetWindowManagerAddShadowHint(bool enabled) public void SetWindowManagerAddShadowHint(bool enabled)

Loading…
Cancel
Save