QPainter's auto-scaling is prone to off-by-one rounding errors and draws on
fractional coordinates. With this change, we paint on a 1x DPR QPainter and
scale the shadow offset and strength manually based on DPR.
This resolves an issue with resulting in seams on the right and bottom
edges of a menu due to shadow boundaries being off-by-one.
BUG: 418166
v2: remove unrelated formatting changes
v3:
- move the DPR helper to ShadowHelper
- retrieve the DPR from the widget instead of the global QGuiApplication
- added BUG reference
The shadow protocol lacks relevant requests to specify the device pixel
ratio. In addition to that, the difference between scaled shadows and
hidpi shadows is very subtle, so it's not worth spending more computing
resources.
The order in which the underlying window and the shadow are destroyed is
undefined. In most cases, the shadow is destroyed after the window, but
in rare cases it may be vice versa, for example it's the case with popup
menus in Dolphin. If the shadow is destroyed before the window, then
the window will be shadowless when the compositor animates it.
The only way to guarantee that the shadow is destroyed after the window
is to create a parent-child relationship between two.
Given that the widget and the window have different lifetimes, we have
to be extra careful with keeping dangling pointers out of _shadows.
(cherry picked from commit 5f62d1c74e)
We would like to destroy a shadow after the decorated window has gotten
unmapped or destroyed. To do that, we install an event filter on the widget
and make the shadow a child of the underlying window.
Unfortunately, the underlying window and the widget have different life
times. To counter for that, we clean up _shadows after the shadow has
been destroyed. This turned out to be a bad idea because when someone
does qDeleteAll(_shadows), QMap iterators will become invalid.
Since KWindowShadow handles the case where it becomes orphaned gracefully,
we can make shadows children of widgets to work around the crash.
Still, it would be nice to call KWindowShadow::destroy() after the native
resources for the window have been destroyed.
Summary:
After a widget has been unregistered, a WinIdChange event may be sent.
If that happens, ShadowHelper is going to try to install a shadow for
the corresponding widget. Obviously, this is wrong.
Reviewers: #plasma, cblack
Reviewed By: cblack
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D28075
Summary:
Since lifetime of a KWindowShadow doesn't strictly match the lifetime
of the associated widget, we need to unregister the shadow when it's
destroyed in order to prevent accessing or deleting dangling pointers
afterwards.
BUG: 416854
Test Plan: plasmashell no longer crashes.
Reviewers: #plasma, broulik
Subscribers: apol, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D26966
Summary:
The primary task of a compositor is to take a bunch of buffers from
different clients and present them on the screen. However, the compositor
may need to present its own stuff on the screen as well.
On X11, internal clients (the ones created by KWin) are backed by real
windows. This looks a bit clumsy since KWin uses X11 to communicate with
itself.
On Wayland, we use our own QPA that talks to KWin directly. Given that
internal clients with the custom QPA are no longer backed by wayland
surfaces or x11 windows, things like blur, background contrast, and
shadows must be set through KWindowSystem APIs so KWin can catch the
relevant API calls and handle them accordingly.
The good thing is that we get rid of a good portion of platform-specific
code. The bad thing is that we still need to be cautious about QPAs that
destroy the underlying platform resources upon a window becoming hidden.
Reviewers: #kwin, #plasma, mart
Reviewed By: #plasma, mart
Subscribers: mart, plasma-devel
Tags: #plasma
Maniphest Tasks: T12496
Differential Revision: https://phabricator.kde.org/D26475
Summary:
KWindowSystem cannot be used in the Qt 4 style plugin. On the other hand,
we need to use KWindowSystem to make QWidget-based internal clients in
KWin cast drop-shadows.
Another problem with the Qt 4 style plugin is that some distributions
have already dropped Qt 4, so one has to build it first in order to
verify that his or her change works with Qt 4.
Given maintenance burden and the fact that Qt 6 is around the corner,
this change drops the Qt 4 style plugin.
Reviewers: #kwin, #plasma, davidedmundson
Reviewed By: #kwin, #plasma, davidedmundson
Subscribers: davidedmundson, mart, plasma-devel
Tags: #plasma
Maniphest Tasks: T12496
Differential Revision: https://phabricator.kde.org/D26476
- removed useless "virtual" specifications
- removed useless destructors
- cleanup variable initializations
- moved protected methods as private when possible for better encapsulation
Summary: Before, shadow size doubled with each new size until Very Large and the smaller shadows were more transparent than the larger shadows. Now shadow size increases linearly and smaller shadows start with more opacity so that they don't become nearly invisible. The new shadows should look better on cheap displays.
Test Plan:
Before
======
Small: {F6622411}
{F6632347}
Medium: {F6622412}
{F6632346}
Large: {F6622413}
{F6632344}
Very Large: {F6622415}
{F6632341}
After
=====
Small: {F6624603}
{F6632334}
Medium: {F6624606}
{F6632335}
Large: {F6624608}
{F6632336}
Very Large: {F6624612}
{F6632337}
Reviewers: #vdg, #breeze, ngraham, rooty
Reviewed By: #vdg, #breeze, ngraham, rooty
Subscribers: filipf, ngraham, zzag, rooty, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D19148
Summary:
Creation of shadows (especially for "Large" and "Very large" sizes) is
a computation expensive task because we have to blur alpha channel of a
shadow texture (which then will be tinted with desired shadow color).
Currently, we use the following approach:
* for blur radius less than 64, use naive 2-pass algorithm;
* for blur radius greater than or equal to 64, use FFT.
Even though the FFT approach is doing its the best, it still takes
impresive amount of time to blur the alpha channel.
What makes things even worse is that while we're blurring the alpha
channel, we're blocking the main thread of KWin (decorations are not
rendered in their own thread). This can result in frame drops (2 or 3
frames, something like that).
So, the only viable alternative is to use an approximation of the Gaussian
blur. As such an approximation, I picked the box blur because it's quite
simple, it's fast, and it takes small amount of iterations to have something
similar to the true Gaussian blur.
In general, there are no big differences between true gaussian shadows
and approximated shadows:
Before:
{F6312610}
After:
{F6312613}
Before:
{F6280935}
After:
{F6312608}
As a win, it takes much less time to generate decoration shadows.
Reviewers: #kwin, #plasma, #breeze, #vdg, ngraham
Reviewed By: #breeze, #vdg, ngraham
Subscribers: cfeck, ngraham, abetts, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D15514
Summary: I tested a bit of code with -02 to measure the speed gains of using a std::initializer_list over appending to a temporary and appending to temporary is around 50% slower, so I removed all the code that appened to temporaries for a initializer list in breeze.
Reviewers: #breeze, #plasma, davidedmundson
Reviewed By: #plasma, davidedmundson
Subscribers: davidedmundson, ngraham, zzag, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D13591
Summary:
Refine shadows in order to match decoration shadows. See D11069
The refined KStyle shadows(from Small to Very Large)
{F5754393, layout=center, size=full}
Desktop experience with the refined shadows
{F5754394, layout=center, size=full}
Depends on D11198
Reviewers: #breeze, #vdg, hpereiradacosta
Reviewed By: hpereiradacosta
Subscribers: abetts, ngraham, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D11175
Summary:
With this changes it's more clear where shadow tiles are created, also it
fixes one possible bug. For example, right now, there are two shady actors
who trigger creation of the shadow tiles:
* the first one lays inside of Style::loadConfiguration(). It creates
shadow tiles as a side effect of configuration of _mdiWindowShadowFactory
* the second one lays inside of ShadowHelper::createPixmapHandles()
Please note, ShadowHelper::createPixmapHandles() is invoked only for X11 not Wayland!
Reviewers: #breeze, hpereiradacosta
Reviewed By: hpereiradacosta
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D11533
Summary:
The old null pointer constants(NULL, 0, etc) are converted to the
the new C++11 nullptr keyword with clang-tidy.
Reviewers: #breeze, mart
Reviewed By: mart
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D11635
Summary:
This implements the menu shadow changes proposed in D9549; now we use a combobox with five options: None, Small, Medium, Large, and Very Large.
Large is the new default value (64px window shadows, 16px menu/tooltip shadows), and implements what we recently changed the default to. Small is the old default value (16px window shadows, 12px menu/tooltip shadows) for people who preferred that.
I had a massive amount of help from @hpereiradacosta; in fact, probably 75% of these changes are his. It's a shame multiple authorship isn't possible. Hugo, feel free to commandeer the revision if you'd like the credit!
Test Plan:
Tested in KDE Neon. New smaller menu shadows for the default window shadow size:
{F5615780}
New shadow chooser UI, with different options:
None (1px border for windows, menus, and tooltips):
{F5623069}
Small (16px window shadows, 12px menu/tooltip shadows); replicates the the old default value:
{F5623071}
Medium (32px window shadows, 14px menu/tooltip shadows):
{F5623072}
Large (64px window shadows, 16px menu/tooltip shadows); the new default:
{F5623073}
Very Large (96px window shadows, 24px menu/tooltip shadows):
{F5623074}
Upgrade story: since this changes the way shadow size is stored in the breezerc file, users who previously had manually set their shadow size to some arbitrary pixel value will now get the new default Large 64 px shadow size.
Reviewers: #vdg, #breeze, hpereiradacosta, abetts, rkflx
Reviewed By: #vdg, hpereiradacosta, abetts, rkflx
Subscribers: rkflx, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D9627
Summary:
FEATURE: 388256
#VDG has decided that shadows should be horizontally centered and bigger. This patch implements those changes in the following way:
- Window and menu shadows are now horizontally centered
- Shadow size increased to the maximum value
- Shadow color changed from pure black to a slightly lighter Breeze standard color: Shade Black
Test Plan:
Tested in KDE Neon. Before:
{F5587393}
After:
{F5587390}
Reviewers: abetts, hpereiradacosta, #vdg, #breeze, alake
Reviewed By: abetts, hpereiradacosta, #vdg
Subscribers: rkflx, zzag, cfeck, januz, rpelorosso, apol, mvourlakos, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D9549
Surface::fromWindow are shared! By deleting the Surface pointer copies in
other areas are getting deleted as well. This breaks e.g. KWin in various
ways.
Summary:
KWin has a problem that breeze crashes it on tear down if the shadow was
created. This is due to breeze destroying the Wayland connection after
KWin destroyed it which triggers a crash in libwayland.
D6571 addresses this problem by deleting the ConnectionThread created by
plugins prior to destroying the Wayland server.
By changing the ownership of the registry and the interfaces to be
children and grandchildren of the ConnectionThread we can ensure that
KWin can clean up this area properly. For non KWin cases this doesn't
change anything, everything is still deleted as a child of ShadowHelper.
Test Plan: Ensured that the Registry gets deleted before KWin's own connection
Reviewers: #kwin, #plasma
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D6572
Summary:
since from Qt 5.8 QtWayland destroys its surfaces every time
a window gets hidden and recreates them again when is shown
(that's how the protocol is defined) install the shadows
every time the window is shown, using a map to keep track of surfaces, in order to delete them on window hide and avoid leaks
Test Plan: popup menus have correct shadows on wayland now
Reviewers: #plasma, hpereiradacosta
Subscribers: anthonyfieroni, davidedmundson, plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D5910
Summary:
This is a change mostly for KWin (the Wayland compositor). The internal
Wayland connection is created after the QStyle is created in the case of
KWin. But both are created before the event dispatcher is run for the
first time. So delaying by one cycle makes it work for KWin and also all
other Wayland applications.
BUG: 372001
FIXED-IN: 5.8.4
Reviewers: #plasma, broulik, hpereiradacosta
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D3239
Integrate with Wayland and create a ShadowManager if available.
With the ShadowManager it's possible to create a Shadow for a Surface.
The Wayland shadow is very similar to the X11 based one, so a lot of
code can be shared. The code is slightly refactored to share the common
code paths to create and destroy the shadow.
REVIEW: 127352
previous shadow change twiddled with the commas breaking the initalizer
list if the breeze_have_x11 if evals to nothing, causing the list to
have a trailing comma and breaking the build
Breeze checks if shadows are supported by checking for a property on the
root window. This is set by kwin at some point after startup.
This leaves a gap for apps/plasmashell to start, determine shadows are
not supported and then never render them for the lifespan of that app.
It also can't handle window managers being replaced.
Not checking solves all the issues with limited drawback
REVIEW: 123284