If a window with rounded corner is transparent, we need to use its mask image
when blurring its background (because it would be silly to decompose rounded
corners into rectangles). If the window is also scaled, then its mask needs to
be scaled too. This was an oversight.
Changelog: Internal: Backend API 2.0 breaking change, backend_blur_args now has
source_mask_scale.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
See the comment.
Related: #1389 (partial fix)
Changelog: BugFix: Fix misaligned shadow and window when they are scaled.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
A bit more precision for mask images. An attempt to reduce gaps when
window/shadow is scaled.
Changelog: Internal: Backend API 2.0 breaking change,
backend_mask_image.origin is now a vec2.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit touches a couple of areas, and unfortunately cannot be broken into
smaller ones since the changes all depends on each other.
To start, a short explanation of how shadows are rendered now. Currently, each
window gets a pre-generated shadow image, this shadow image has shadow-color and
shadow-opacity baked in. Which means changing color or opacity requires
re-generating the shadow image (caveat on shadow-opacity, because it is applied
twice, we can still apply a opacity on the generated shadow image, but that is
wrong and is a bug).
We want to have dynamic shadow colors, which means this has to change.
Firstly, the `opacity` and `dim` parameters for the blit backend operations are
replaced with `tint`, which is a generalization of both parameters. This can be
used to multiply each of the color channels by a separate factor.
Next, we change how shadows are generated. Instead of a color image, we instead
generate a single channel mask image. This is done by mostly removing color,
since what we are doing right now is generating a mask then coloring it, so we
just remove the coloring step. This is fine if the backend support the "blurring
a mask" codepath. But xrender doesn't have that, and is using the "generating a
pixmap -> backend->ops.bind_pixmap" path. This is problematic because
`bind_pixmap` needs a X VisualID, but single channel masks don't have one. This
is why we added a new `new_image_from_pixels` API for uploading CPU pixel bytes
directly into backend images, bypassing `bind_pixmap`. And using it also means
we are no longer limited by the maximum allowed X request size.
Finally, we change how shadows are rendered, by combining the result of previous
two steps - we apply a `tint` to the shadow mask and Voila.
P.S. Implementing tinting in the GL backend is simple, and actually simplifies
the shader code. Only problems is removing `opacity` and `dim` uniforms will
break all existing shaders, and we have kinda committed to a stable shader API.
So, we have to keep them and assign them values that kind of make sense.
Implementing tinting in xrender is more complicated. And it ended up degrading
the performance of color inversion. Color inversion is already slow because it
needs the "Difference" composite operator, which is not hardware accelerated
already, so I think it's a acceptable sacrifice.
Changelog: Internal: Refactor shadow rendering, preparing for dynamic shadow
colors.
Changelog: BugFix: Fix shadow-opacity being applied twice. You may need to
adjust your shadow-opacity settings.
Changelog: BugFix: Properly fix the longstanding "request too big" problem when
uploading shadow images. (Previous workaround: 69b3eee76b)
Related: #257
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
API changes & anticipated API change:
- Generalize the `dim` parameter of blit to `tint`. Allowing a multiplicative
factor for each of the color channels.
- New backend interface: `new_image_from_pixels`. Creating an initialized image
from pixel data. The current create X pixmap -> bind_pixmap code path is
cumbersome for some backends. Most notably it requires an X VisualID for the
pixmap. But some pictfmts (e.g. single channel A8) don't have corresponding
visuals.
Changelog: Internal: Breaking change to backend API, to allow better image
creation, and applying tints to windows.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Allow animation to blend in saved window image before it was refresh.
Window images are refreshed when, for example, the window's size
changed. With this, animations can blend the window before and after the
size change to have a smoother transition.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
It's easier to just store them together, since the same group of
information is needed for parsed window rules, and for window rendering.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Because wm_tree tracks the entire window tree, it's able to replace
several old data structures we used to track windows: the window hash
table, the window stack, and the subwin table. So we got rid of those,
and fully switched to wm_tree.
Fixes window rules for window managers that don't put client window
directly under toplevel windows. This includes, according to people's
reports, at least i3 and KDE.
Fixed a couple small bugs:
* dbus was returning window ID as a boolean.
* window frame extents not cleared after its client window disappears.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
The idea is to allow backend plugins to override backend functions by
modifying this table. Right now, when they do this they are actually
changing a global variable and their change will persist after backend
resets (!). Store the table inside backend_base solves this problem.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
We want to change the backend interface as little as possible once we
release it as a public interface, so while we still can, we should try
to give it maximum flexibility.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>