-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Window shadows #43
Window shadows #43
Conversation
39a86d6
to
964fbf2
Compare
Looks great! Thanks for this work! I tried compiling
|
Oh, nevermind. Looks like winit needs to pass that argument, i changed it by hand. And it works! Looks great! |
Right, anyone who wants to try this in their project, and is already using winit 0.29, can put this in their Cargo.toml: [patch.crates-io]
winit = { git = "https://github.com/Friz64/winit.git", branch = "window-shadows-0.29.4" } The patch is very simple: Friz64/winit@b2bd287 |
4939ec0
to
0034ddb
Compare
Rebased. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks awesome! Thanks!
@PolyMeilex can you please make a release? And another unrelated question. Is there a reason for having circular buttons, instead of circular buttons with same color as background, as in Adwaita? I can try fixing it, if this a desired change. |
Cool job! It looks really great! Who needs libdecor, right? |
This PR consists of two parts that can be reviewed individually:
Decoupling the border size from the resize range
We place regions around the window in which the window borders are drawn. These regions currently stretch out as far as the resize range (e.g. how close to the window the pointer needs to be in order for it to be able to resize the window). We need to be able to draw shadows further than the resize range. This involves restricting the input region of the, now enlarged, border parts. Unfortunately, this is requires a breaking change in
AdwaitaFrame::new
as we need access to thewl_compositor
for creatingwl_region
objects.Generating and drawing the window shadow
I wanted the window shadows to be as close to libadwaita's window shadows as possible. But as far as I can see, its shadows are defined in (S)CSS, which is not an option for this crate. The solution to this I came up with is to measure libadwaita's shadow from a screenshot and use a curve-fitting algorithm to create an exponential function that lets us sample the alpha value of the shadow given the distance from the window's border.
To achieve this, I took these screenshots of a simple libadwaita window in both an active and inactive state (the shadow shrinks when the window is unfocused/inactive):
Next, I used this python script: https://gist.github.com/Friz64/ef941181f4d6aef82332f7066f984815
It's usage is as following:
When running it against active.png, it outputs the following:
a
,b
, andc
are the parameters for the exponential decay functiona * exp(-b * x) + c
.shadow size
is the pixel distance from the window border at which the resulting u8 alpha value would round down to 0, making it meaningless to sample the function beyond this point.Click to reveal: If desired, the script can also display a plot comparing the input and output.
The X axis represents the distance from the window border in pixels (e.g. the input), the Y axis represents the alpha value between 0 and 1 (e.g. the output).
Armed with this function, we now have the ability to draw the window shadow with any given scale factor. To do this, we generate the following two pixmaps for each encountered pair of scale factor and active state by sampling it at each pixel.
We offset this distance by the corner radius, so that we can place the edge shadow around the rounded window corners.
Then, all that's left is to copy these images (or parts of them) to the appropriate parts of the border, and we're done. We cache our work as much as possible in order to save resources.
Click to reveal: Screenshot of end result.
Presented through winit.
Fixes #4.