slint icon indicating copy to clipboard operation
slint copied to clipboard

add `set_window_background_blurred(&self, bool)/is_window_background_blurred(&self) -> bool` apis, which allows the functionality of background blurring

Open LaoLittle opened this issue 1 year ago • 13 comments
trafficstars

Currently, winit has implemented this api on macOS and Linux (KDE) which could be found on link.

The api marks Windows as Unsupported, which is quite confusing. But it works well on my Mac.

https://github.com/slint-ui/slint/assets/93422095/e73977e3-568e-456e-a74c-f43757a608da

LaoLittle avatar Mar 20 '24 13:03 LaoLittle

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Mar 20 '24 13:03 CLAassistant

Sorry to go all nit-picky...

"blur" is sometimes used as the opposite of "focus". So you focus a window and you blur it again when you focus another window.

So I would prefer a longer name. Are there other effects as well? If yes, then we might want to have a set_window_background_effect(...) taking an Enum with one value being Blur.

The video is actually pretty cool :-) Thanks for looking into this topic.

hunger avatar Mar 20 '24 15:03 hunger

So I would prefer a longer name. Are there other effects as well? If yes, then we might want to have a set_window_background_effect(...) taking an Enum with one value being Blur.

Windows has multiple effects while macOS doesn’t (I don’t know what effects does Linux have). Maybe we can ignore the variants on platforms other than Windows.

Or we can call the enum “PreferredEffect”?

LaoLittle avatar Mar 20 '24 15:03 LaoLittle

I see two options:

  1. We take an API like this, with a slightly more elaborate name, but keep it simple as a boolean property. The documentation needs to explain that this basically only works on macOS and (with a different look) on Wayland when running under KDE (I guess there's also an x11 prop, but it doesn't look implemented in winit). This is not a cross-platform feature, and indeed I also see no way of doing this with public Qt API (see QTBUG-85310). There used to be Api in Qt to do this for Windows, but it's deprecated. It also doesn't help that the Windows 10 (and newer) design doesn't seem to make use of it (as much as Windows 7 did). And on top of that, on macOS this is using private API - that might become an issue for App Store submissions in the future.

  2. We don't add this API to slint::Window, given the "niche" feature it looks to be like. Instead we promote the access to Slint's winit backend, and perhaps commit to slint-backend-winit-0.X (as opposed to i-slint-backend-winit).

Regarding the naming, I suggest to call it slint::Window::set_blur_window_background(bool). In DWM it's called DwmEnableBlurBehindWindow, and on macOS the underlying private API is CGSSetWindowBackgroundBlurRadius. We can argue if it's the background that's blurred of it "blurring is enabled behind the window". I find the former an easier way of thinking of it - it's a feature of the window, not what's behind it.

The fact that this is KDE only and uses private Apple APIs on macOS makes me uneasy about (1), but I have no objection against (2) given that it's really really simple API.

tronical avatar Mar 20 '24 17:03 tronical

I see two options:

  1. We take an API like this, with a slightly more elaborate name, but keep it simple as a boolean property. The documentation needs to explain that this basically only works on macOS and (with a different look) on Wayland when running under KDE (I guess there's also an x11 prop, but it doesn't look implemented in winit). This is not a cross-platform feature, and indeed I also see no way of doing this with public Qt API (see QTBUG-85310). There used to be Api in Qt to do this for Windows, but it's deprecated. It also doesn't help that the Windows 10 (and newer) design doesn't seem to make use of it (as much as Windows 7 did). And on top of that, on macOS this is using private API - that might become an issue for App Store submissions in the future.

  2. We don't add this API to slint::Window, given the "niche" feature it looks to be like. Instead we promote the access to Slint's winit backend, and perhaps commit to slint-backend-winit-0.X (as opposed to i-slint-backend-winit).

Regarding the naming, I suggest to call it slint::Window::set_blur_window_background(bool). In DWM it's called DwmEnableBlurBehindWindow, and on macOS the underlying private API is CGSSetWindowBackgroundBlurRadius. We can argue if it's the background that's blurred of it "blurring is enabled behind the window". I find the former an easier way of thinking of it - it's a feature of the window, not what's behind it.

The fact that this is KDE only and uses private Apple APIs on macOS makes me uneasy about (1), but I have no objection against (2) given that it's really really simple API.

Maybe we can implement the effects on macOS through the NSVfxView instead of using the existing winit api, and make a variant of the enum called "Vibrancy".

And I would try to implement this feature on Windows through the dwm apis. Also, a new variant of the enum would be introduced.

LaoLittle avatar Mar 20 '24 18:03 LaoLittle

Screenshot 2024-03-21 at 15 36 54

implemented with NSVfxView

LaoLittle avatar Mar 21 '24 07:03 LaoLittle

Sounds good, I'm fine with (1) and it can be incrementally improved :-). Naming wise I'd go for set_window_background_blurred(bool) and is_window_background_blurred().

What do the others think?

tronical avatar Mar 21 '24 08:03 tronical

Oh, I didn't know about window_vibrancy from the lovely Tauri folks. That's pretty cool!

I'd still prefer to just have a boolean for a blur effect, instead of the whole set of effects.

I'd rather we make it possible for people to use window_vibrancy with Slint, instead of forwarding the APIs.

tronical avatar Mar 21 '24 09:03 tronical

Oh, I didn't know about window_vibrancy from the lovely Tauri folks. That's pretty cool!

I'd still prefer to just have a boolean for a blur effect, instead of the whole set of effects.

I'd rather we make it possible for people to use window_vibrancy with Slint, instead of forwarding the APIs.

window_vibrancy doesn't work on Linux though, and something wrong on macOS (that's why I implemented it myself).

I've added a 'General' effect variant so, personally, it could act as a boolean (None or Some(General))

LaoLittle avatar Mar 21 '24 09:03 LaoLittle

Windows:

Dark

Light

LaoLittle avatar Mar 21 '24 10:03 LaoLittle

Oh, I didn't know about window_vibrancy from the lovely Tauri folks. That's pretty cool! I'd still prefer to just have a boolean for a blur effect, instead of the whole set of effects. I'd rather we make it possible for people to use window_vibrancy with Slint, instead of forwarding the APIs.

window_vibrancy doesn't work on Linux though, and something wrong on macOS (that's why I implemented it myself).

I've added a 'General' effect variant so, personally, it could act as a boolean (None or Some(General))

or maybe we can use the 'Into' instead, so the function can accept both boolean and the Effect enum.

like

// true => General, false => None
impl From<bool> for Effect {}

fn set<T: Into<Effect>>(eff: T);

LaoLittle avatar Mar 21 '24 10:03 LaoLittle

Oh, I didn't know about window_vibrancy from the lovely Tauri folks. That's pretty cool! I'd still prefer to just have a boolean for a blur effect, instead of the whole set of effects. I'd rather we make it possible for people to use window_vibrancy with Slint, instead of forwarding the APIs.

window_vibrancy doesn't work on Linux though,

Yes, that's fine - a fall back to winit's set_blur() would be okay - if our API was just a boolean "blur window background" property.

and something wrong on macOS (that's why I implemented it myself).

Wouldn't it be better to fix that in window_vibrancy? (and meanwhile use winit's set_blur() on macOS).

I've added a 'General' effect variant so, personally, it could act as a boolean (None or Some(General))

I'm less concerned about the ability to use it in a boolean manner than about the API surface we're exposing. A general effect enum that is limited to certain Windows versions and macOS and has its caveats seems too big for my taste. As I said, I'd prefer a plain boolean API to blur what's behind the window, we document it with the known caveats (macOS, windows, KDE only), and separately make it possible for advanced users to combine window_vibrancy with Slint (by supporting raw-window-handle, which is something I've started looking at again).

To summarise my point of view again: In the scope of this PR my preference would be a clean, simple "set_window_background_blurred(&self, bool)/is_window_background_blurred(&self) -> bool` API. We get that sorted out first, and then concerned next steps.

If window effects become widely popular and we agree on the need for a general effect enum, then that can still be placed besides an existing boolean API in a compatible manner.

tronical avatar Mar 21 '24 14:03 tronical

"set_window_background_blurred(&self, bool)/is_window_background_blurred(&self) -> bool` API.

i've changed to these apis, and removed all the previous Effect enums

macOS we use FullScreenUI while Windows we use acrylic. And the implementation on Linux is just simply call the winit api.

LaoLittle avatar Mar 21 '24 15:03 LaoLittle

Meanwhile, it's now possible to use window_vibrancy with Slint via raw-window-handle: https://github.com/slint-ui/slint/pull/4918

tronical avatar Mar 22 '24 16:03 tronical

Meanwhile, it's now possible to use window_vibrancy with Slint via raw-window-handle: #4918

I think I can make my own crate to support this feature by taking the advantage of the new rwh feature.

LaoLittle avatar Mar 22 '24 18:03 LaoLittle