scene: Track stack position in WindowItem

If the WindowItem tracks the stack position, it will automagically
schedule repaints when a window is raised or lowered.
master
Vlad Zahorodnii 2 years ago
parent 8fc634684c
commit fff462aed6

@ -50,6 +50,9 @@ WindowItem::WindowItem(Window *window, Scene *scene, Item *parent)
connect(window, &Window::opacityChanged, this, &WindowItem::updateOpacity);
updateOpacity();
connect(window, &Window::stackingOrderChanged, this, &WindowItem::updateStackingOrder);
updateStackingOrder();
connect(window, &Window::windowClosed, this, &WindowItem::handleWindowClosed);
}
@ -252,6 +255,11 @@ void WindowItem::updateOpacity()
setOpacity(m_window->opacity());
}
void WindowItem::updateStackingOrder()
{
setZ(m_window->stackingOrder());
}
void WindowItem::markDamaged()
{
Q_EMIT m_window->damaged(m_window);

@ -64,6 +64,7 @@ private Q_SLOTS:
void updateSurfaceVisibility();
void updatePosition();
void updateOpacity();
void updateStackingOrder();
private:
bool computeVisibility() const;

@ -85,6 +85,7 @@ namespace KWin
WorkspaceScene::WorkspaceScene(std::unique_ptr<ItemRenderer> renderer)
: Scene(std::move(renderer))
, m_containerItem(std::make_unique<Item>(this))
{
}
@ -94,8 +95,6 @@ WorkspaceScene::~WorkspaceScene()
void WorkspaceScene::initialize()
{
connect(workspace(), &Workspace::stackingOrderChanged, this, &WorkspaceScene::addRepaintFull);
setGeometry(workspace()->geometry());
connect(workspace(), &Workspace::geometryChanged, this, [this]() {
setGeometry(workspace()->geometry());
@ -132,6 +131,11 @@ void WorkspaceScene::destroyDndIconItem()
m_dndIcon.reset();
}
Item *WorkspaceScene::containerItem() const
{
return m_containerItem.get();
}
QRegion WorkspaceScene::damage() const
{
return m_paintContext.damage;
@ -426,14 +430,14 @@ void WorkspaceScene::paintSimpleScreen(int, const QRegion &region)
void WorkspaceScene::createStackingOrder()
{
// Create a list of all windows in the stacking order
QList<Window *> windows = workspace()->stackingOrder();
QList<Item *> items = m_containerItem->sortedChildItems();
// Move elevated windows to the top of the stacking order
const QList<EffectWindow *> elevatedList = static_cast<EffectsHandlerImpl *>(effects)->elevatedWindows();
for (EffectWindow *c : elevatedList) {
Window *t = static_cast<EffectWindowImpl *>(c)->window();
windows.removeAll(t);
windows.append(t);
WindowItem *item = static_cast<EffectWindowImpl *>(c)->windowItem();
items.removeAll(item);
items.append(item);
}
// Skip windows that are not yet ready for being painted and if screen is locked skip windows
@ -442,9 +446,10 @@ void WorkspaceScene::createStackingOrder()
// TODO? This cannot be used so carelessly - needs protections against broken clients, the
// window should not get focus before it's displayed, handle unredirected windows properly and
// so on.
for (Window *window : std::as_const(windows)) {
if (window->windowItem()->isVisible()) {
stacking_order.append(window->windowItem());
for (Item *item : std::as_const(items)) {
WindowItem *windowItem = static_cast<WindowItem *>(item);
if (windowItem->isVisible()) {
stacking_order.append(windowItem);
}
}
}

@ -52,6 +52,8 @@ public:
void initialize();
Item *containerItem() const;
QRegion damage() const override;
SurfaceItem *scanoutCandidate() const override;
void prePaint(SceneDelegate *delegate) override;
@ -133,6 +135,7 @@ private:
// how many times finalPaintScreen() has been called
int m_paintScreenCount = 0;
PaintContext m_paintContext;
std::unique_ptr<Item> m_containerItem;
std::unique_ptr<DragAndDropIconItem> m_dndIcon;
};

@ -348,6 +348,7 @@ bool Window::setupCompositing()
updateShadow();
m_windowItem = createItem(scene);
m_windowItem->setParentItem(scene->containerItem());
m_effectWindow->setWindowItem(m_windowItem.get());
connect(windowItem(), &WindowItem::positionChanged, this, &Window::visibleGeometryChanged);

Loading…
Cancel
Save