scene: Rework window elevation
The order in which windows are painted is computed dynamically every frame. On the other hand, with the introduction of items, it's desired to avoid doing that so repaints can be scheduled as needed. The unification also opens the possibilities for more rendering related refactors to make the code nicer and more reusable.
This commit is contained in:
parent
1cbc9185fb
commit
b4413f4b8b
5 changed files with 32 additions and 32 deletions
|
@ -178,7 +178,6 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, WorkspaceScene *s
|
|||
});
|
||||
connect(ws, &Workspace::deletedRemoved, this, [this](KWin::Window *d) {
|
||||
Q_EMIT windowDeleted(d->effectWindow());
|
||||
elevated_windows.removeAll(d->effectWindow());
|
||||
});
|
||||
connect(ws->sessionManager(), &SessionManager::stateChanged, this, &KWin::EffectsHandler::sessionStateChanged);
|
||||
connect(vds, &VirtualDesktopManager::countChanged, this, &EffectsHandler::numberDesktopsChanged);
|
||||
|
@ -1097,11 +1096,13 @@ EffectWindowList EffectsHandlerImpl::stackingOrder() const
|
|||
|
||||
void EffectsHandlerImpl::setElevatedWindow(KWin::EffectWindow *w, bool set)
|
||||
{
|
||||
elevated_windows.removeAll(w);
|
||||
WindowItem *item = static_cast<EffectWindowImpl *>(w)->windowItem();
|
||||
|
||||
if (set) {
|
||||
elevated_windows.append(w);
|
||||
item->elevate();
|
||||
} else {
|
||||
item->deelevate();
|
||||
}
|
||||
addRepaint(w->expandedGeometry());
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::setTabBoxWindow(EffectWindow *w)
|
||||
|
|
|
@ -183,8 +183,6 @@ public:
|
|||
QStringList loadedEffects() const;
|
||||
QStringList listOfEffects() const;
|
||||
void unloadAllEffects();
|
||||
|
||||
QList<EffectWindow *> elevatedWindows() const;
|
||||
QStringList activeEffects() const;
|
||||
|
||||
/**
|
||||
|
@ -313,7 +311,6 @@ protected:
|
|||
|
||||
Effect *keyboard_grab_effect;
|
||||
Effect *fullscreen_effect;
|
||||
QList<EffectWindow *> elevated_windows;
|
||||
QMultiMap<int, EffectPair> effect_order;
|
||||
QHash<long, int> registered_atoms;
|
||||
|
||||
|
@ -621,14 +618,6 @@ private:
|
|||
QRect m_geometry;
|
||||
};
|
||||
|
||||
inline QList<EffectWindow *> EffectsHandlerImpl::elevatedWindows() const
|
||||
{
|
||||
if (isScreenLocked()) {
|
||||
return QList<EffectWindow *>();
|
||||
}
|
||||
return elevated_windows;
|
||||
}
|
||||
|
||||
inline xcb_window_t EffectsHandlerImpl::x11RootWindow() const
|
||||
{
|
||||
return kwinApp()->x11RootWindow();
|
||||
|
|
|
@ -124,6 +124,24 @@ void WindowItem::unrefVisible(int reason)
|
|||
updateVisibility();
|
||||
}
|
||||
|
||||
void WindowItem::elevate()
|
||||
{
|
||||
// Not ideal, but it's also highly unlikely that there are more than 1000 windows. The
|
||||
// elevation constantly increases so it's possible to force specific stacking order. It
|
||||
// can potentially overflow, but it's unlikely to happen because windows are elevated
|
||||
// rarely.
|
||||
static int elevation = 1000;
|
||||
|
||||
m_elevation = elevation++;
|
||||
updateStackingOrder();
|
||||
}
|
||||
|
||||
void WindowItem::deelevate()
|
||||
{
|
||||
m_elevation.reset();
|
||||
updateStackingOrder();
|
||||
}
|
||||
|
||||
void WindowItem::handleWindowClosed(Window *original, Window *deleted)
|
||||
{
|
||||
m_window = deleted;
|
||||
|
@ -262,7 +280,11 @@ void WindowItem::updateOpacity()
|
|||
|
||||
void WindowItem::updateStackingOrder()
|
||||
{
|
||||
setZ(m_window->stackingOrder());
|
||||
if (m_elevation.has_value()) {
|
||||
setZ(m_elevation.value());
|
||||
} else {
|
||||
setZ(m_window->stackingOrder());
|
||||
}
|
||||
}
|
||||
|
||||
void WindowItem::markDamaged()
|
||||
|
|
|
@ -51,6 +51,9 @@ public:
|
|||
void refVisible(int reason);
|
||||
void unrefVisible(int reason);
|
||||
|
||||
void elevate();
|
||||
void deelevate();
|
||||
|
||||
protected:
|
||||
explicit WindowItem(Window *window, Scene *scene, Item *parent = nullptr);
|
||||
void updateSurfaceItem(SurfaceItem *surfaceItem);
|
||||
|
@ -75,6 +78,7 @@ private:
|
|||
std::unique_ptr<SurfaceItem> m_surfaceItem;
|
||||
std::unique_ptr<DecorationItem> m_decorationItem;
|
||||
std::unique_ptr<ShadowItem> m_shadowItem;
|
||||
std::optional<int> m_elevation;
|
||||
int m_forceVisibleByHiddenCount = 0;
|
||||
int m_forceVisibleByDeleteCount = 0;
|
||||
int m_forceVisibleByDesktopCount = 0;
|
||||
|
|
|
@ -427,23 +427,7 @@ void WorkspaceScene::paintSimpleScreen(const RenderTarget &renderTarget, const R
|
|||
|
||||
void WorkspaceScene::createStackingOrder()
|
||||
{
|
||||
// Create a list of all windows in the stacking order
|
||||
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) {
|
||||
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
|
||||
// that are neither lockscreen nor inputmethod windows.
|
||||
//
|
||||
// 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 (Item *item : std::as_const(items)) {
|
||||
WindowItem *windowItem = static_cast<WindowItem *>(item);
|
||||
if (windowItem->isVisible()) {
|
||||
|
|
Loading…
Reference in a new issue