diff --git a/composite.cpp b/composite.cpp --- a/composite.cpp +++ b/composite.cpp @@ -296,6 +296,7 @@ if (!m_starting) { return; } + Workspace::self()->markXStackingOrderAsDirty(); Q_ASSERT(m_scene); connect(workspace(), &Workspace::destroyed, this, [this] { compositeTimer.stop(); }); claimCompositorSelection(); diff --git a/layers.cpp b/layers.cpp --- a/layers.cpp +++ b/layers.cpp @@ -687,18 +687,23 @@ // Returns all windows in their stacking order on the root window. ToplevelList Workspace::xStackingOrder() const { - if (!x_stacking_dirty) - return x_stacking; - x_stacking_dirty = false; + if (m_xStackingQueryTree) { + const_cast(this)->updateXStackingOrder(); + } + return x_stacking; +} + +void Workspace::updateXStackingOrder() +{ x_stacking.clear(); - Xcb::Tree tree(rootWindow()); + std::unique_ptr tree{std::move(m_xStackingQueryTree)}; // use our own stacking order, not the X one, as they may differ foreach (Toplevel * c, stacking_order) x_stacking.append(c); - if (!tree.isNull()) { - xcb_window_t *windows = tree.children(); - const auto count = tree->children_len; + if (!tree->isNull()) { + xcb_window_t *windows = tree->children(); + const auto count = tree->data()->children_len; int foundUnmanagedCount = unmanaged.count(); for (unsigned int i = 0; i < count; @@ -724,7 +729,6 @@ } } } - return x_stacking; } //******************************* diff --git a/workspace.h b/workspace.h --- a/workspace.h +++ b/workspace.h @@ -32,6 +32,7 @@ #include // std #include +#include // TODO: Cleanup the order of things in this .h file @@ -47,6 +48,7 @@ namespace Xcb { +class Tree; class Window; } @@ -365,6 +367,8 @@ void registerEventFilter(X11EventFilter *filter); void unregisterEventFilter(X11EventFilter *filter); + void markXStackingOrderAsDirty(); + public Q_SLOTS: void performWindowOperation(KWin::AbstractClient* c, Options::WindowOperation op); // Keybindings @@ -546,7 +550,7 @@ static NET::WindowType txtToWindowType(const char* txt); static bool sessionInfoWindowTypeMatch(Client* c, SessionInfo* info); - void markXStackingOrderAsDirty(); + void updateXStackingOrder(); AbstractClient* active_client; AbstractClient* last_active_client; @@ -567,8 +571,8 @@ ToplevelList unconstrained_stacking_order; // Topmost last ToplevelList stacking_order; // Topmost last bool force_restacking; - mutable ToplevelList x_stacking; // From XQueryTree() - mutable bool x_stacking_dirty; + ToplevelList x_stacking; // From XQueryTree() + std::unique_ptr m_xStackingQueryTree; QList should_get_focus; // Last is most recent QList attention_chain; diff --git a/workspace.cpp b/workspace.cpp --- a/workspace.cpp +++ b/workspace.cpp @@ -112,7 +112,6 @@ , movingClient(0) , delayfocus_client(0) , force_restacking(false) - , x_stacking_dirty(true) , showing_desktop(false) , was_user_interaction(false) , session_saving(false) @@ -1768,7 +1767,7 @@ void Workspace::markXStackingOrderAsDirty() { - x_stacking_dirty = true; + m_xStackingQueryTree.reset(new Xcb::Tree(rootWindow())); } } // namespace