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.Collections.Generic;
using Avalonia.Controls;
#nullable enable
namespace Avalonia.X11
{
internal class TransparencyHelper : IDisposable, X11Globals.IGlobalsSubscriber
@ -9,10 +12,10 @@ namespace Avalonia.X11
private readonly IntPtr _window;
private readonly X11Globals _globals;
private WindowTransparencyLevel _currentLevel;
private WindowTransparencyLevel _requestedLevel;
private IReadOnlyList<WindowTransparencyLevel>? _requestedLevels;
private bool _blurAtomsAreSet;
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; }
public Action<WindowTransparencyLevel>? TransparencyLevelChanged { get; set; }
public WindowTransparencyLevel CurrentLevel => _currentLevel;
public TransparencyHelper(X11Info x11, IntPtr window, X11Globals globals)
@ -23,28 +26,62 @@ namespace Avalonia.X11
_globals.AddSubscriber(this);
}
public void SetTransparencyRequest(WindowTransparencyLevel level)
public void SetTransparencyRequest(IReadOnlyList<WindowTransparencyLevel> levels)
{
_requestedLevel = level;
UpdateTransparency();
}
WindowTransparencyLevel? newLevel = null;
_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)
{
_currentLevel = newLevel;
TransparencyLevelChanged?.Invoke(newLevel);
_currentLevel = newLevel.Value;
TransparencyLevelChanged?.Invoke(newLevel.Value);
}
}
private WindowTransparencyLevel UpdateAtomsAndGetTransparency()
private bool IsSupported(WindowTransparencyLevel level)
{
var blur = _requestedLevel == WindowTransparencyLevel.Blur ||
_requestedLevel == WindowTransparencyLevel.AcrylicBlur ||
_requestedLevel == WindowTransparencyLevel.Mica;
// None is suppported when composition is disabled.
if (level == WindowTransparencyLevel.None)
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 (!_blurAtomsAreSet)
@ -63,15 +100,7 @@ namespace Avalonia.X11
_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()
{

6
src/Avalonia.X11/X11Window.cs

@ -196,7 +196,7 @@ namespace Avalonia.X11
_rawEventGrouper = new RawEventGrouper(DispatchInput, platform.EventGrouperDispatchQueue);
_transparencyHelper = new TransparencyHelper(_x11, _handle, platform.Globals);
_transparencyHelper.SetTransparencyRequest(WindowTransparencyLevel.None);
_transparencyHelper.SetTransparencyRequest(Array.Empty<WindowTransparencyLevel>());
CreateIC();
@ -1307,9 +1307,9 @@ namespace Avalonia.X11
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)

Loading…
Cancel
Save