A new implementation of present windows and desktop grid based on QML should be implemented.
This allows to make the two effects more consistent, that is provide the exactly same functionality. The windows could be exposed to QML through a Qt tree-structured model with a proxy model to get the windows for a desktop, for a screen and so on. Different QML files could then be used to visualize the same model as either desktop grid or present windows.
Furthermore a QML based solution would remove the coupling to compositing. That is with compositing disabled the functionality could still be provided by rendering icon and caption instead of a thumbnail.
To give a status update on this.
We now have support for (nicely!) rendering QtQuick inside an Effect.
The close button is implemented as relatively easy to work with object instead of a set of hacks and external windows.
EffectFrame also follows the same path (patch in review). It's a clear starting point.
That still leaves the problem of windows, we have two options here:
- Add a QQuickItem subclass that has a window as a texture.
Present windows can just be a fullscreen QtQuick window that shows that.
Challenge is that to do it in the "correct" place in QSG means rendering from one context to another.
Would be simple if we just shared one common context instead of using a shared context, but that would require Kwin letting Qt create the main GL context.
Also doing the animation from the current state will be somewhat tricky to get spot on. It requires the present windows effect going fullscreen and faking the current state.
- Add a QQuickItem subclass that doesn't draw anything and just manipulates an EffectWindow
Downside is this kinda means you can only draw a window once, which means we can't share this path with a regular tabbox.
Also you can't control stacking order with overlays/underlays.
It's still better than the current Tabbox style faux-QQuickItem that overlays another window as the code will be a lot less spider-y, and it can be underneath the rendered QML.
(In reply to David Edmundson from comment #1)
> - Add a QQuickItem subclass that has a window as a texture.
I personally would prefer this option because it means we won't have to make unnecessary copies of client buffers. In many cases, we don't need to render every window in an offscreen texture. QtQuick has the best knowledge of the scene, so it makes sense to let it decide whether to render the window in an offscreen texture.
However, the sharing of scene textures with QtQuick raises several issues:
(a) We will have to share scene textures between OpenGL contexts
(b) In addition to sharing OpenGL textures, we will also have to share client buffers
The problem (a) is a bit problematic on X11, but I think it's not a big issue on Wayland. Given that the API of the WindowThumbnail is super minimalistic, we could maintain both thumbnail implementations for the time being and switch between two at runtime, e.g. if it's wayland, use the new thumbnails implementation, otherwise fallback to the old one.
In order to fix problem (b) we need to refactor buffer management code in KWin. Ideally, we need a client buffer and perhaps(?) an integration/a factory class for those buffers (for better encapsulation), e.g.
class ClientBuffer : public QObject
virtual bool isValid() const;
virtual bool isDirty() const;
virtual bool create();
virtual void update();
virtual QRegion damage() const;
virtual QRegion shape() const;
virtual QRect rect() const;
virtual qreal scale() const;
virtual bool haveAlphaChannel() const;
virtual Toplevel *toplevel() const;
virtual QOpenGLTexture *toOpenGLTexture() const;
virtual QImage toImage() const;
// virtual vkImage toVulkanImage() const;
void lost(); // or something
Once we have a client buffer abstraction in kwin, sharing client buffers between the opengl scene and qt quick will be straightforward to implement.
The introduction of the ClientBuffer class would require a ground up rework, but I think it's going to be worth the effort because we need to move damage tracking from Toplevel to ClientBuffer to properly handle sub-surfaces on Wayland. We also need the ClientBuffer for the opaque-ness stuff in the scene.
>(a) We will have to share scene textures between OpenGL contexts
FWIW, I did introduce a shared context for getting the OpenGL textures into kwin, so doing a real surface is easy.
The problem is PresentWindows wants the composited buffer (i.e window decorations and subsurfaces).
If this was all one context we would just render the window into a buffer during the QQuickEventLoop - but because it's not we have this awkward updating a cache and then we have to either have code updating that cache ahead of the QQuick render, which gives us issues with sizes and state potentially changing.
Git commit 6132329c2c48e22d48a37e7ec40028f6faefa1fd by Vlad Zahorodnii.
Committed on 19/08/2021 at 06:30.
Pushed by vladz into branch 'master'.
Add Overview effect
This effect is meant to be as a replacement for the present windows and
the desktop grid effect. It is written using QML.
So far, this effect implements only the basic features of the present
windows effect. Desktop management features will be added later.
Related: bug 303438
M +5 -0 autotests/test_builtin_effectloader.cpp
M +4 -0 src/effects/CMakeLists.txt
M +17 -0 src/effects/effect_builtins.cpp
M +1 -0 src/effects/effect_builtins.h
A +7 -0 src/effects/overview/CMakeLists.txt
A +794 -0 src/effects/overview/expolayout.cpp [License: GPL(v2.0+)]
A +142 -0 src/effects/overview/expolayout.h [License: GPL(v2.0+)]
A +20 -0 src/effects/overview/kcm/CMakeLists.txt
A +79 -0 src/effects/overview/kcm/overvieweffectkcm.cpp [License: GPL(v2.0+)]
A +12 -0 src/effects/overview/kcm/overvieweffectkcm.desktop
A +32 -0 src/effects/overview/kcm/overvieweffectkcm.h [License: GPL(v2.0+)]
A +70 -0 src/effects/overview/kcm/overvieweffectkcm.ui
A +20 -0 src/effects/overview/overviewconfig.kcfg
A +9 -0 src/effects/overview/overviewconfig.kcfgc
A +326 -0 src/effects/overview/overvieweffect.cpp [License: GPL(v2.0+)]
A +94 -0 src/effects/overview/overvieweffect.h [License: GPL(v2.0+)]
A +110 -0 src/effects/overview/qml/ScreenView.qml [License: GPL(v2.0+)]
A +339 -0 src/effects/overview/qml/WindowHeap.qml [License: GPL(v2.0+)]
M +5 -0 src/kcmkwin/kwinscreenedges/kwinscreenedgesettings.kcfg
M +5 -0 src/kcmkwin/kwinscreenedges/kwintouchscreensettings.kcfg
M +16 -0 src/kcmkwin/kwinscreenedges/main.cpp
M +1 -0 src/kcmkwin/kwinscreenedges/main.h
M +16 -0 src/kcmkwin/kwinscreenedges/touch.cpp
M +1 -0 src/kcmkwin/kwinscreenedges/touch.h
It turns out the Overview effect won't replace Present Windows and Desktop Grid after all. Instead, Present Windows and Desktop Grid have has been rewritten to use the same modern, maintainable backend technology found in the Overview effect. This fixes approximately a gazillion Bugzilla tickets, too!
This work has been done by Marco Martin with:
- https://invent.kde.org/plasma/kwin/-/merge_requests/2279 (Present Windows)
- https://invent.kde.org/plasma/kwin/-/merge_requests/2327 (Desktop Grid)