AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.43k stars 2.21k forks source link

Window transparency (dev-doc) #3300

Closed kekekeks closed 2 years ago

kekekeks commented 4 years ago

Alpha-transparency and blur behind have various support across platforms, the support for those features can also be sometimes turned on and off during a singe user session due to various reasons.

So Avalonia should support different transparency requests from the application and apply the best matching mode supported by the current platform.

Transparency requests:

Blur-behind requests (only take effect if transparency is enabled):

When application runs on a particular platform and the mode is chosen or changed later, Avalonia should set Transparency.CurrentMode attached property on the window to inform it that transparency/blurbehind are enabled. The property should hold a class like this:

class TransparencyMode
{
    public bool TransparencyEnabled {get;}
    public bool BlurBehindEnabled {get;}
}

X11

Transparency

Transparency works kinda out of the box when one uses ARGB visual. The problem is that the window manager should support compositing and not all of them do. Some window managers like KWin turn compositing off when they see a GPU-intensive application (usually full-screen games) running and keep it disabled even if user has alt-tabbed from said application.

Avalonia should detect if _NET_WM_CM_Sn selection is held by the window manager. n is the number of the screen. Since Avalonia only uses one screen, such number should be obtained from XDefaultScreen.

When window manager turns composition on or off or when window manager is replaced by another one, Avalonia should track _NET_WM_CM_Sn selection ownership by subscribing to XFixesSelectionNotify event via XFixesSelectSelectionInput function. See /usr/include/X11/extensions/Xfixes.h for more details.

Blur behind

Blur behind is currently supported by KDE and Deepin Linux via setting _KDE_NET_WM_BLUR_BEHIND_REGION and _NET_WM_DEEPIN_BLUR_REGION_ROUNDED properties.

Windows

Transparency can be enabled by:

OSX

It seems that setting opaque property to false on both NSWindow and NSView should enable transparency. Needs further investigation.

Blur-behind can be enabled via NSVisualEffectView.

Splitwirez commented 4 years ago

Not sure if this is still up for consideration, but just in case, I figure I may as well note a few things that were missed here regarding Microsoft Windows:

  1. DwmEnableBlurBehindWindow ( https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmenableblurbehindwindow ) exists. It is similar to DwmExtendFrameIntoClientArea, but rather than extending the native frame into the body/client area of the window, it simply blurs the specified area with no concern for the frame. Likely useful at least for Windows which lack system decorations, as using DwmExtendFrameIntoClientArea on such a window will actually restore the system drop shadow and system decorations...sort of.
  2. SetWindowCompositionAttribute only exists as of Windows 8, and does not enforce blurbehind at all. It can be used to achieve several different behaviours. More specifically... 2a. On Windows 8.x, you can use it to produce a completely transparent Window, a completely opaque window, a window with a translucent but non-blurred theme-coloured background, and some other weird stuff I don't even understand, but blur is NOT one of the options it provides. 2b. On Windows 10, two different types of blurbehind were added, one with a fairly small blur radius, the other with a much stronger blur radius. If memory serves, the latter option takes the place of one of the options present in Windows 8.x, though I don't recall which. Also it should be noted that the stronger of the two blur options was added in a feature update, not in the initial release of Windows 10.
  3. Any APIs which would produce blurbehind on Windows Vista and 7 will instead produce opaque theme-colour on Windows 8.1 and 10. 3a. If the user has that Aeroglass for Windows 8.1+ program ( http://glass8.eu/ ) installed and active on Windows 8 or 10, the Windows Vista/7 behaviour will apply instead in these cases.
danwalmsley commented 4 years ago

2b. On Windows 10, two different types of blurbehind were added, one with a fairly small blur radius, the other with a much stronger blur radius. If memory serves, the latter option takes the place of one of the options present in Windows 8.x, though I don't recall which. Also it should be noted that the stronger of the two blur options was added in a feature update, not in the initial release of Windows 10.

seems to be the ACCENT_ENABLE_ACRYLIC option... the performance is absolutely terrible and we probably wont be able to use it.

yatli commented 4 years ago

performance is absolutely terrible

Especially when you move/resize the window. The lag feels similar to resizing a vertical, blurbehind task bar. UWP windows don't exhibit this lag though.

kekekeks commented 4 years ago

the performance is absolutely terrible

I think it used to work faster but got broken in relatively recent windows builds (>1900)

Splitwirez commented 4 years ago

...it just hit me that I forgot to mention in my previous post here that SetWindowCompositionAttribute is also an undocumented Windows API, meaning it could potentially change, break, vanish, or whatever at any time.

Also...

performance is absolutely terrible

Especially when you move/resize the window. The lag feels similar to resizing a vertical, blurbehind task bar. UWP windows don't exhibit this lag though.

tbh I'm pretty sure it is what the Taskbar uses.

sudongg commented 2 years ago

In 2022, translucent windows are still unavailable under Windows 7, or are they not intended to be supported?

maxkatz6 commented 2 years ago

Windows 7 is not a priority anymore for the core team. But we can review PRs from the community, if anybody wants to bring some missing features for the Win7.

maxkatz6 commented 2 years ago

@kekekeks do we still need this issue open? Or should we leave it for future refactoring of API? In that case description probably should be updated with some new ideas.

kekekeks commented 2 years ago

My current idea is to make the application to specify an array of requested modes in order or preference and then use the first one that can be satisfied by the platform. That would be way more simple and less error-prone, IMO.