When the inner radius of the top left corner is 0, the corresponding arc
does not get drawn, resulting in a path going from the bottom left
corner to the top right corner when the path is closed.
Fix this by always including a line_to from the bottom left to the top
left corner.
Fixes: dde13b30c ("st/theme-node-drawing: Trace the correct path for inset box shadows")
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7996
Previously we just copied the outer path and scaled it down, but that
resulted in an inconsistent thickness at the corners because the pivot
points for the arcs also moved inward.
So now we trace the inset path explicitly to maintain the correct
thickness (spread) around all the corners.
The spec actually mentions you need to do it in section 6.1 [1]:
> Note that for inner shadows, expanding the shadow (creating more
> shadow area) means contracting the shadow’s perimeter shape.
Despite the fact the example diagram gets it wrong in section 6.1.1 [2],
it does then follow with more confirmation that the shadow radius should
be reduced:
> To preserve the box’s shape when spread is applied, the corner radii
> of the shadow are also increased (decreased, for inner shadows) from
> the border-box (padding-box) radii by adding (subtracting) the spread
> distance (and flooring at zero).
[1] https://www.w3.org/TR/css-backgrounds-3/#box-shadow
[2] https://www.w3.org/TR/css-backgrounds-3/#shadow-shape
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7913
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3488>
The corner pipelines state theme node paint state was not necessarily
free of existing pipelines, so make sure to free them before looking up
new ones.
This avoids leaking thousands of CoglPipeline instances after toggling
the overview a bunch of times.
Fixes: e1868cab1a ("st/theme-node-drawing: Factor in border radius in update_resources()")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3421>
The reduced border radius from st_theme_node_reduce_border_radius() depends
on the allocation size, and when it changes, has_large_corners can change.
has_large_corners is used to determine whether to pre-render using cairo,
so that means a change to the allocation size can influence whether the
pre-render using cairo should happen or not.
On changes to the allocation size we don't want to call render_resources()
though, but just update_resources() instead. And since we know now that
changes to the allocation size might cause pre-rendering to get enabled
or disabled, we need to do the "should pre-render" checks in
update_resources(), too.
So factor out those "should pre-render" checks into a new function
st_theme_node_maybe_prerender_background(), and then call that function from
both render_resources() and update_resources().
This fixes rendering artifacts with borders or rounded corners after changes
to the actor size.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6567
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3354>
Switch to render nodes. Most of the changes follow the pattern of
replacing a cogl_framebuffer_draw_*() call by (1) creating a paint
node, and (2) calling the corresponding clutter_paint_node_add_*()
API.
StWidget now overrides ClutterActor.paint_node(), instead of paint.
All subclasses that overrided the paint vfunc also are changed to
override paint_node.
The entry point for CSS rendering, st_widget_paint_background(), now
receives a root ClutterPaintNode, and propagates it to the rendering
machinery.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1538>
Only when part of it is actually visible.
Because the central rectangle is generally the largest part, this
eliminates most of the shadow's render time. For example, animating
`.workspace-background` by tapping Super, the shell's overall render
time is reduced about 15%.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1915>
Until now, the absence of a `background-color` would cause `box-shadow`s
to be invisible. That was a bug because `box-shadow` is meant to be either
the color specified in `box-shadow`, or if none was specified then the
foreground `color`.
There is nothing in the spec that says the `box-shadow` rendering should
depend on `background-color`, so separate them. This ensures `box-shadow`
is rendered even when `background-color` is absent or transparent.
https://www.w3.org/TR/css-backgrounds-3/#box-shadow
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1904>
We want to use the fast path of filling the entire area if either the
left and right shadows would overlap or the top and bottom shadows. The
latter check was wrong due to a typo resulting in the regular path
being used in some cases it couldn't (and shouldn't) handle.
This was causing the inset shadow used to highlight panel buttons to
not appear for buttons above a certain width.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1646>
What the blur shader does is going n_steps in each direction (e.g. in case
we're in the horizontal pass that means left and right direction), sampling
the adjacent texels of the texel we're currently blurring. That means
n_steps actually is the amount of texels we're sampling in one direction,
not in both directions.
Make n_steps match what the blur shader does, and rename it to sampling_radius
to match what it really means. Do that for both st-theme-node-drawing.c and
st-private.c
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1542>
In some styles the top or left sections of box-shadows would go missing
even though they had non-zero thickness. This was because the inner
local coordinates could become very slightly negative and were then
incorrectly judged to be invisible.
Negative coordinates should not be ignored because that's where the
entire top/left sections of shadow are meant to exist. It's only the
sections of shadow with zero thickness that we should skip.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1417>
Each node stores the scale factor in place when it was created.
Creating nodes with the same style, but with different scale
factors, yields different nodes.
Use the node's scale factor instead of retrieving the context's
one.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1176
The use of box-shadow on a StWidget that has a background-gradient was
not been rendered correctly, the shadow borders was calculated inside
the st_theme_node_prerender_shadow function and in the case that we've a
prerendered_texture the max_borders was not calculated and are 0.
This patch creates a new static function to compute shadow maximum
borders copying the code from st_theme_node_prerender_shadow, and call
this new method in the case that we've a prerendered_texture.
https://gitlab.gnome.org/GNOME/gnome-shell/issues/1186
Instead of just passing a scale when getting a cached icon, pass both a
'paint_scale', the scale of which the icon will be painted on the
stage, and a 'resource_scale', the scale of the resource used for
painting.
In effect, the texture size will use the scale 'paint_scale * resource_scale'
in a ceiled value while the size of the actor will use 'paint_scale' when
determining the size.
this would load a bigger texture, but the downscaling would keep the visual
quality.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/5https://bugzilla.gnome.org/show_bug.cgi?id=765011
Create the surfaces for background shadows at scaled sizes and then draw on them
using logical coordinates, by setting the surface device scale accordingly.
Use the said surface scale when generating the actual shadow cairo pattern
but in such case, to reduce the number of code changes, is better to work in
absolute coordinates, and to do so:
1) Create a temporary shadow-spec copy with scaled values to absolute sizes
2) Invert the scaling on the shadow matrix
3) Do the actual painting in absolute coordinates
4) Set the shadow matrix scaling back to the logical coordinates.
Finally scale down the created shadow pattern surface size when painting it,
applying again a reverse scale to the matrix.
https://bugzilla.gnome.org/show_bug.cgi?id=765011https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/5
Pass resource-scale to drawing phase, and use it to create texture
surfaces scaled with the widget current scaling.
Also redraw by default widgets when the resource scale changes.
https://bugzilla.gnome.org/show_bug.cgi?id=765011
Same case of the previous patch; _st_paint_shadow_with_opacity()
uses cogl_get_draw_framebuffer(), and this patch makes it receive
a CoglFramebuffer as a parameter instead.
The cautious reader might notice that this commit apparently goes
against the long-term goal, for it introduces more instances of
cogl_get_draw_framebuffer(). This is not wrong, but these introduced
ones will be removed later on, when ClutterActor.paint() receives
a CoglFramebuffer as a parameter instead.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/283
When computing the effective border color, we operate on colors with
premultiplied alpha to simplify the calculations, then unpremultiply
the result. However we miss a bounds check in the last check, so any
color component can overflow the allowed maximum of 0xff and shift the
result in unexpected ways.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/305
If the actor is not on the stage yet (i.e. does not have a theme
node), but has a paint state cached, we currently fail to invalidate
it, which will lead to the actor painting with old contents once it
gets onto the stage.
This commit fixes the issue by changing our invalidation strategy;
previously we were looking at the widget's own theme node to determine
if it should be invalidated or not.
Now we look at the theme nodes of our cached paint states. When the
widget is mapped on stage, those are the same as the widget's own
theme node, but when the widget is not on the stage, we'll still be
able to invalidate them.
As part of this, we move the invalidation API to StThemeNodePaintState,
which is a more natural place for our use case.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/314
cogl_texture_new() is used in a few places in GNOME Shell, but
it's a deprecated Cogl function. The replacement is the less
verbose cogl_texture_2d_new_with_size(), that is very much a
straightforward replacement.
Remove the few places where this function is used, replacing
it by the CoglTexture2d counterpart.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/287
Checking offscreen for COGL_INVALID_HANDLE is not sufficient,
as cogl_offscreen_new_with_texture doesn't initialize framebuffer
objects but lets Cogl solve this the lazy way.
cogl_offscreen_new_with_texture will never return COGL_INVALID_HANDLE
anyways.
https://bugzilla.gnome.org/show_bug.cgi?id=764898
While CoglError is a define to GError, it doesn't follow the convention
of ignoring errors when NULL is passed, but rather treats the error as
fatal :-(
That's clearly unwanted for a compositor, so make sure to always pass
an error parameter where a runtime error is possible
https://bugzilla.gnome.org/show_bug.cgi?id=765061
Since commit 48a54e8ac4, paint() has an explicit framebuffer parameter,
however a couple of submethods are still using the draw framebuffer,
which breaks when rendering to an offscreen buffer.
If we are trying to render a shadow at a size that is very large in one
direction, but small in the other direction (so that we don't 9-slice
the texture), then allocating the backing texture for the offscreen
buffer may fail due to texture-size limits. Don't crash in that case.
https://bugzilla.gnome.org/show_bug.cgi?id=757150
There are quite a few crashes in retrace.fedoraproject.org that are a result of
of cairo_pattern_get_surface() failing, then a subsequent call to
cairo_image_surface_get_width() crashing because no surface was returned to the
out parameter. Knowing what causes these is hard - my best guess is widgets getting
allocated at ridiculous sizes - but avoiding the crash makes sense in any case.
See https://bugzilla.redhat.com/show_bug.cgi?id=1206754https://bugzilla.gnome.org/show_bug.cgi?id=756983