Commit a7d61f7b authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

Fully replace SceneWindow with WindowItem

This completes the initial transition to scene items.
parent 15a97449
Pipeline #174422 passed with stage
in 26 minutes and 16 seconds
......@@ -48,10 +48,15 @@ Deleted::~Deleted()
workspace()->removeDeleted(this);
}
deleteEffectWindow();
deleteSceneWindow();
deleteItem();
deleteShadow();
}
WindowItem *Deleted::createItem()
{
Q_UNREACHABLE();
}
Deleted *Deleted::create(Window *c)
{
Deleted *d = new Deleted();
......
......@@ -100,6 +100,7 @@ public:
void moveResizeInternal(const QRect & /*rect*/, KWin::Window::MoveResizeMode /*mode*/) override { /* nothing to do */ }
void updateCaption() override { /* nothing to do */ }
void resizeWithChecks(const QSize&) override { /* nothing to do */ }
WindowItem *createItem() override;
/**
* Returns whether the client was a popup.
......
......@@ -1113,7 +1113,7 @@ EffectWindowList EffectsHandlerImpl::stackingOrder() const
QList<Window *> list = Workspace::self()->xStackingOrder();
EffectWindowList ret;
for (Window *t : list) {
if (EffectWindow *w = effectWindow(t)) {
if (EffectWindow *w = t->effectWindow()) {
ret.append(w);
}
}
......@@ -1886,7 +1886,7 @@ EffectScreen::Transform EffectScreenImpl::transform() const
EffectWindowImpl::EffectWindowImpl(Window *window)
: EffectWindow(window)
, m_window(window)
, m_sceneWindow(nullptr)
, m_windowItem(nullptr)
{
// Deleted windows are not managed. So, when windowClosed signal is
// emitted, effects can't distinguish managed windows from unmanaged
......@@ -1907,12 +1907,12 @@ EffectWindowImpl::~EffectWindowImpl()
void EffectWindowImpl::refVisible(int reason)
{
m_sceneWindow->windowItem()->refVisible(reason);
m_windowItem->refVisible(reason);
}
void EffectWindowImpl::unrefVisible(int reason)
{
m_sceneWindow->windowItem()->unrefVisible(reason);
m_windowItem->unrefVisible(reason);
}
void EffectWindowImpl::addRepaint(const QRect &r)
......@@ -2091,9 +2091,9 @@ void EffectWindowImpl::setWindow(Window *w)
setParent(w);
}
void EffectWindowImpl::setSceneWindow(SceneWindow *w)
void EffectWindowImpl::setWindowItem(WindowItem *item)
{
m_sceneWindow = w;
m_windowItem = item;
}
QRect EffectWindowImpl::decorationInnerRect() const
......@@ -2191,19 +2191,6 @@ QVariant EffectWindowImpl::data(int role) const
return dataMap.value(role);
}
EffectWindow *effectWindow(Window *w)
{
EffectWindowImpl *ret = w->effectWindow();
return ret;
}
EffectWindow *effectWindow(SceneWindow *w)
{
EffectWindowImpl *ret = w->window()->effectWindow();
ret->setSceneWindow(w);
return ret;
}
void EffectWindowImpl::elevate(bool elevate)
{
effects->setElevatedWindow(this, elevate);
......@@ -2232,16 +2219,12 @@ void EffectWindowImpl::closeWindow()
void EffectWindowImpl::referencePreviousWindowPixmap()
{
if (m_sceneWindow) {
m_sceneWindow->referencePreviousPixmap();
}
// TODO: Implement.
}
void EffectWindowImpl::unreferencePreviousWindowPixmap()
{
if (m_sceneWindow) {
m_sceneWindow->unreferencePreviousPixmap();
}
// TODO: Implement.
}
bool EffectWindowImpl::isManaged() const
......
......@@ -495,9 +495,8 @@ public:
Window *window();
void setWindow(Window *w); // internal
void setSceneWindow(SceneWindow *w); // internal
const SceneWindow *sceneWindow() const; // internal
SceneWindow *sceneWindow(); // internal
void setWindowItem(WindowItem *item); // internal
WindowItem *windowItem() const; // internal
void elevate(bool elevate);
......@@ -506,7 +505,7 @@ public:
private:
Window *m_window;
SceneWindow *m_sceneWindow; // This one is used only during paint pass.
WindowItem *m_windowItem; // This one is used only during paint pass.
QHash<int, QVariant> dataMap;
bool managed = false;
bool m_waylandWindow;
......@@ -660,17 +659,9 @@ inline EffectWindowGroupImpl::EffectWindowGroupImpl(Group *g)
{
}
EffectWindow *effectWindow(Window *w);
EffectWindow *effectWindow(SceneWindow *w);
inline const SceneWindow *EffectWindowImpl::sceneWindow() const
{
return m_sceneWindow;
}
inline SceneWindow *EffectWindowImpl::sceneWindow()
inline WindowItem *EffectWindowImpl::windowItem() const
{
return m_sceneWindow;
return m_windowItem;
}
inline const Window *EffectWindowImpl::window() const
......
......@@ -12,6 +12,7 @@
#include "deleted.h"
#include "platform.h"
#include "surfaceitem.h"
#include "windowitem.h"
#include "workspace.h"
#include <KDecoration2/Decoration>
......@@ -68,6 +69,11 @@ InternalWindow::~InternalWindow()
{
}
WindowItem *InternalWindow::createItem()
{
return new WindowItemInternal(this);
}
bool InternalWindow::isClient() const
{
return true;
......
......@@ -72,6 +72,7 @@ protected:
void doInteractiveResizeSync() override;
void updateCaption() override;
void moveResizeInternal(const QRect &rect, MoveResizeMode mode) override;
WindowItem *createItem() override;
private:
void requestGeometry(const QRect &rect);
......
......@@ -229,16 +229,16 @@ SurfaceItem *Scene::scanoutCandidate() const
SurfaceItem *candidate = nullptr;
if (!static_cast<EffectsHandlerImpl *>(effects)->blocksDirectScanout()) {
for (int i = stacking_order.count() - 1; i >= 0; i--) {
SceneWindow *sceneWindow = stacking_order[i];
Window *window = sceneWindow->window();
WindowItem *windowItem = stacking_order[i];
Window *window = windowItem->window();
if (window->isOnOutput(painted_screen) && window->opacity() > 0) {
if (!window->isClient() || !window->isFullScreen() || window->opacity() != 1.0) {
break;
}
if (!sceneWindow->surfaceItem()) {
if (!windowItem->surfaceItem()) {
break;
}
SurfaceItem *topMost = findTopMostSurface(sceneWindow->surfaceItem());
SurfaceItem *topMost = findTopMostSurface(windowItem->surfaceItem());
auto pixmap = topMost->pixmap();
if (!pixmap) {
break;
......@@ -249,7 +249,7 @@ SurfaceItem *Scene::scanoutCandidate() const
break;
}
// and it has to be completely opaque
if (pixmap->hasAlphaChannel() && !topMost->opaque().contains(QRect(0, 0, sceneWindow->width(), sceneWindow->height()))) {
if (pixmap->hasAlphaChannel() && !topMost->opaque().contains(QRect(0, 0, window->width(), window->height()))) {
break;
}
candidate = topMost;
......@@ -330,16 +330,16 @@ static void accumulateRepaints(Item *item, Output *output, QRegion *repaints)
void Scene::preparePaintGenericScreen()
{
for (SceneWindow *sceneWindow : std::as_const(stacking_order)) {
resetRepaintsHelper(sceneWindow->windowItem(), painted_screen);
for (WindowItem *windowItem : std::as_const(stacking_order)) {
resetRepaintsHelper(windowItem, painted_screen);
WindowPrePaintData data;
data.mask = m_paintContext.mask;
data.paint = infiniteRegion(); // no clipping, so doesn't really matter
effects->prePaintWindow(effectWindow(sceneWindow), data, m_expectedPresentTimestamp);
effects->prePaintWindow(windowItem->window()->effectWindow(), data, m_expectedPresentTimestamp);
m_paintContext.phase2Data.append(Phase2Data{
.window = sceneWindow,
.item = windowItem,
.region = infiniteRegion(),
.opaque = data.opaque,
.mask = data.mask,
......@@ -351,12 +351,11 @@ void Scene::preparePaintGenericScreen()
void Scene::preparePaintSimpleScreen()
{
for (SceneWindow *sceneWindow : std::as_const(stacking_order)) {
const Window *window = sceneWindow->window();
const WindowItem *windowItem = sceneWindow->windowItem();
for (WindowItem *windowItem : std::as_const(stacking_order)) {
Window *window = windowItem->window();
WindowPrePaintData data;
data.mask = m_paintContext.mask;
accumulateRepaints(sceneWindow->windowItem(), painted_screen, &data.paint);
accumulateRepaints(windowItem, painted_screen, &data.paint);
// Clip out the decoration for opaque windows; the decoration is drawn in the second pass.
if (window->opacity() == 1.0) {
......@@ -371,9 +370,9 @@ void Scene::preparePaintSimpleScreen()
}
}
effects->prePaintWindow(effectWindow(sceneWindow), data, m_expectedPresentTimestamp);
effects->prePaintWindow(window->effectWindow(), data, m_expectedPresentTimestamp);
m_paintContext.phase2Data.append(Phase2Data{
.window = sceneWindow,
.item = windowItem,
.region = data.paint,
.opaque = data.opaque,
.mask = data.mask,
......@@ -393,8 +392,8 @@ void Scene::preparePaintSimpleScreen()
void Scene::postPaint()
{
for (SceneWindow *w : std::as_const(stacking_order)) {
effects->postPaintWindow(effectWindow(w));
for (WindowItem *w : std::as_const(stacking_order)) {
effects->postPaintWindow(w->window()->effectWindow());
}
effects->postPaintScreen();
......@@ -403,8 +402,8 @@ void Scene::postPaint()
const std::chrono::milliseconds frameTime =
std::chrono::duration_cast<std::chrono::milliseconds>(painted_screen->renderLoop()->lastPresentationTimestamp());
for (SceneWindow *sceneWindow : std::as_const(stacking_order)) {
Window *window = sceneWindow->window();
for (WindowItem *windowItem : std::as_const(stacking_order)) {
Window *window = windowItem->window();
if (!window->isOnOutput(painted_screen)) {
continue;
}
......@@ -515,7 +514,7 @@ void Scene::paintGenericScreen(int, const ScreenPaintData &)
}
for (const Phase2Data &paintData : std::as_const(m_paintContext.phase2Data)) {
paintWindow(paintData.window, paintData.mask, paintData.region);
paintWindow(paintData.item, paintData.mask, paintData.region);
}
}
......@@ -531,8 +530,7 @@ void Scene::paintSimpleScreen(int, const QRegion &region)
data->region = visible;
if (!(data->mask & PAINT_WINDOW_TRANSFORMED)) {
const Item *item = data->window->windowItem();
data->region &= item->mapToGlobal(item->boundingRect());
data->region &= data->item->mapToGlobal(data->item->boundingRect());
if (!(data->mask & PAINT_WINDOW_TRANSLUCENT)) {
visible -= data->opaque;
......@@ -543,7 +541,7 @@ void Scene::paintSimpleScreen(int, const QRegion &region)
paintBackground(visible);
for (const Phase2Data &paintData : std::as_const(m_paintContext.phase2Data)) {
paintWindow(paintData.window, paintData.mask, paintData.region);
paintWindow(paintData.item, paintData.mask, paintData.region);
}
}
......@@ -573,8 +571,7 @@ void Scene::createStackingOrder()
if (!window->windowItem()->isVisible()) {
continue;
}
Q_ASSERT(window->sceneWindow());
stacking_order.append(window->sceneWindow());
stacking_order.append(window->windowItem());
}
}
......@@ -583,14 +580,15 @@ void Scene::clearStackingOrder()
stacking_order.clear();
}
void Scene::paintWindow(SceneWindow *w, int mask, const QRegion &region)
void Scene::paintWindow(WindowItem *item, int mask, const QRegion &region)
{
if (region.isEmpty()) { // completely clipped
return;
}
WindowPaintData data(w->window()->effectWindow(), screenProjectionMatrix());
effects->paintWindow(effectWindow(w), mask, region, data);
EffectWindowImpl *effectWindow = item->window()->effectWindow();
WindowPaintData data(effectWindow, screenProjectionMatrix());
effects->paintWindow(effectWindow, mask, region, data);
}
// the function that'll be eventually called by paintWindow() above
......@@ -602,7 +600,7 @@ void Scene::finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion &regio
// will be eventually called from drawWindow()
void Scene::finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data)
{
render(w->sceneWindow()->windowItem(), mask, region, data);
render(w->windowItem(), mask, region, data);
}
bool Scene::makeOpenGLContextCurrent()
......@@ -652,89 +650,4 @@ SurfaceTexture *Scene::createSurfaceTextureWayland(SurfacePixmapWayland *pixmap)
return nullptr;
}
//****************************************
// SceneWindow
//****************************************
SceneWindow::SceneWindow(Window *client, QObject *parent)
: QObject(parent)
, m_window(client)
{
if (qobject_cast<WaylandWindow *>(client)) {
m_windowItem.reset(new WindowItemWayland(m_window));
} else if (qobject_cast<X11Window *>(client) || qobject_cast<Unmanaged *>(client)) {
m_windowItem.reset(new WindowItemX11(m_window));
} else if (auto internalClient = qobject_cast<InternalWindow *>(client)) {
m_windowItem.reset(new WindowItemInternal(internalClient));
} else {
Q_UNREACHABLE();
}
connect(m_window, &Window::frameGeometryChanged, this, &SceneWindow::updateWindowPosition);
updateWindowPosition();
}
SceneWindow::~SceneWindow()
{
}
void SceneWindow::setWindow(Window *window)
{
m_window = window;
}
void SceneWindow::referencePreviousPixmap()
{
if (surfaceItem()) {
referencePreviousPixmap_helper(surfaceItem());
}
}
void SceneWindow::referencePreviousPixmap_helper(SurfaceItem *item)
{
item->referencePreviousPixmap();
const QList<Item *> children = item->childItems();
for (Item *child : children) {
referencePreviousPixmap_helper(static_cast<SurfaceItem *>(child));
}
}
void SceneWindow::unreferencePreviousPixmap()
{
if (surfaceItem()) {
unreferencePreviousPixmap_helper(surfaceItem());
}
}
void SceneWindow::unreferencePreviousPixmap_helper(SurfaceItem *item)
{
item->unreferencePreviousPixmap();
const QList<Item *> children = item->childItems();
for (Item *child : children) {
unreferencePreviousPixmap_helper(static_cast<SurfaceItem *>(child));
}
}
WindowItem *SceneWindow::windowItem() const
{
return m_windowItem.data();
}
SurfaceItem *SceneWindow::surfaceItem() const
{
return m_windowItem->surfaceItem();
}
ShadowItem *SceneWindow::shadowItem() const
{
return m_windowItem->shadowItem();
}
void SceneWindow::updateWindowPosition()
{
m_windowItem->setPosition(pos());
}
} // namespace
......@@ -37,7 +37,6 @@ class GLTexture;
class Item;
class RenderLoop;
class Scene;
class SceneWindow;
class Shadow;
class ShadowItem;
class SurfaceItem;
......@@ -114,11 +113,11 @@ public:
virtual Shadow *createShadow(Window *window) = 0;
// Flags controlling how painting is done.
enum {
// SceneWindow (or at least part of it) will be painted opaque.
// WindowItem (or at least part of it) will be painted opaque.
PAINT_WINDOW_OPAQUE = 1 << 0,
// SceneWindow (or at least part of it) will be painted translucent.
// WindowItem (or at least part of it) will be painted translucent.
PAINT_WINDOW_TRANSLUCENT = 1 << 1,
// SceneWindow will be painted with transformed geometry.
// WindowItem will be painted with transformed geometry.
PAINT_WINDOW_TRANSFORMED = 1 << 2,
// Paint only a region of the screen (can be optimized, cannot
// be used together with TRANSFORMED flags).
......@@ -205,7 +204,7 @@ protected:
// called after all effects had their paintWindow() called
void finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data);
// shared implementation, starts painting the window
virtual void paintWindow(SceneWindow *w, int mask, const QRegion &region);
virtual void paintWindow(WindowItem *w, int mask, const QRegion &region);
// called after all effects had their drawWindow() called
void finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data);
......@@ -214,7 +213,7 @@ protected:
// saved data for 2nd pass of optimized screen painting
struct Phase2Data
{
SceneWindow *window = nullptr;
WindowItem *item = nullptr;
QRegion region;
QRegion opaque;
int mask = 0;
......@@ -231,7 +230,7 @@ protected:
Output *painted_screen = nullptr;
// windows in their stacking order
QVector<SceneWindow *> stacking_order;
QVector<WindowItem *> stacking_order;
private:
std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
......@@ -245,90 +244,6 @@ private:
PaintContext m_paintContext;
};
// The base class for windows representations in composite backends
class SceneWindow : public QObject
{
Q_OBJECT
public:
explicit SceneWindow(Window *client, QObject *parent = nullptr);
~SceneWindow() override;
int x() const;
int y() const;
int width() const;
int height() const;
QRect geometry() const;
QPoint pos() const;
QSize size() const;
QRect rect() const;
// access to the internal window class
// TODO eventually get rid of this
Window *window() const;
void setWindow(Window *window);
void referencePreviousPixmap();
void unreferencePreviousPixmap();
WindowItem *windowItem() const;
SurfaceItem *surfaceItem() const;
ShadowItem *shadowItem() const;
protected:
Window *m_window;
private:
void referencePreviousPixmap_helper(SurfaceItem *item);
void unreferencePreviousPixmap_helper(SurfaceItem *item);
void updateWindowPosition();
QScopedPointer<WindowItem> m_windowItem;
Q_DISABLE_COPY(SceneWindow)
};
inline int SceneWindow::x() const
{
return m_window->x();
}
inline int SceneWindow::y() const
{
return m_window->y();
}
inline int SceneWindow::width() const
{
return m_window->width();
}
inline int SceneWindow::height() const
{
return m_window->height();
}
inline QRect SceneWindow::geometry() const
{
return m_window->frameGeometry();
}
inline QSize SceneWindow::size() const
{
return m_window->size();
}
inline QPoint SceneWindow::pos() const
{
return m_window->pos();
}
inline QRect SceneWindow::rect() const
{
return m_window->rect();
}
inline Window *SceneWindow::window() const
{
return m_window;
}
} // namespace
#endif
......@@ -15,6 +15,7 @@
#include "surfaceitem_x11.h"
#include "utils/common.h"
#include "wayland/surface_interface.h"
#include "windowitem.h"
#include "workspace.h"
#include <QDebug>
......@@ -71,6 +72,11 @@ Unmanaged::~Unmanaged()
{
}
WindowItem *Unmanaged::createItem()
{
return new WindowItemX11(this);
}
void Unmanaged::associate()
{
if (surface()->isMapped()) {
......
......@@ -58,6 +58,7 @@ public:
void moveResizeInternal(const QRect & /*rect*/, KWin::Window::MoveResizeMode /*mode*/) override { /* nothing to do */ }
void updateCaption() override { /* nothing to do */ }
void resizeWithChecks(const QSize&) override { /* nothing to do */ }
WindowItem *createItem() override;
public Q_SLOTS:
void release(ReleaseReason releaseReason = ReleaseReason::Release);
......
......@@ -14,6 +14,7 @@
#include "wayland/display.h"
#include "wayland/surface_interface.h"
#include "wayland_server.h"
#include "windowitem.h"
#include "workspace.h"
#include <QFileInfo>
......@@ -54,6 +55,11 @@ WaylandWindow::WaylandWindow(SurfaceInterface *surface)
updateIcon();
}
WindowItem *WaylandWindow::createItem()
{
return new WindowItemWayland(this);
}
QString WaylandWindow::captionNormal() const
{
return m_captionNormal;
......
......@@ -44,6 +44,7 @@ protected:
bool belongsToDesktop() const override;
void doSetActive() override;
void updateCaption() override;
WindowItem *createItem() override;