diff --git a/abstract_client.cpp b/abstract_client.cpp index 6989505af9..0ec6320fbc 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -828,4 +828,21 @@ bool AbstractClient::hasTransient(const AbstractClient *c, bool indirect) const return c->transientFor() == this; } +QList< AbstractClient* > AbstractClient::mainClients() const +{ + if (const AbstractClient *t = transientFor()) { + return QList{const_cast< AbstractClient* >(t)}; + } + return QList(); +} + +QList AbstractClient::allMainClients() const +{ + auto result = mainClients(); + foreach (const auto *cl, result) { + result += cl->allMainClients(); + } + return result; +} + } diff --git a/abstract_client.h b/abstract_client.h index c89aecc039..9f714e6826 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -264,6 +264,8 @@ public: * @todo: remove boolean trap **/ virtual bool hasTransient(const AbstractClient* c, bool indirect) const; + virtual QList mainClients() const; // Call once before loop , is not indirect + QList allMainClients() const; // Call once before loop , is indirect /** * Returns true for "special" windows and false for windows which are "normal" * (normal=window which has a border, can be moved by the user, can be closed, etc.) diff --git a/activation.cpp b/activation.cpp index 34bfa4a8ee..8a8a0ab135 100644 --- a/activation.cpp +++ b/activation.cpp @@ -483,13 +483,11 @@ bool Workspace::activateNextClient(AbstractClient* c) if (!get_focus) { // no suitable window under the mouse -> find sth. else // first try to pass the focus to the (former) active clients leader - if (Client *client = qobject_cast(c)) { - if (client->isTransient()) { - ClientList leaders = client->mainClients(); - if (leaders.count() == 1 && FocusChain::self()->isUsableFocusCandidate(leaders.at(0), c)) { - get_focus = leaders.at(0); - raiseClient(get_focus); // also raise - we don't know where it came from - } + if (c->isTransient()) { + auto leaders = c->mainClients(); + if (leaders.count() == 1 && FocusChain::self()->isUsableFocusCandidate(leaders.at(0), c)) { + get_focus = leaders.at(0); + raiseClient(get_focus); // also raise - we don't know where it came from } } if (!get_focus) { @@ -730,11 +728,21 @@ xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, c && cl != this && Client::belongToSameApplication(cl, this, true); }; if (isTransient()) { + auto clientMainClients = [this] () -> ClientList { + ClientList ret; + const auto mcs = mainClients(); + for (auto mc: mcs) { + if (Client *c = dynamic_cast(mc)) { + ret << c; + } + } + return ret; + }; if (act->hasTransient(this, true)) ; // is transient for currently active window, even though it's not // the same app (e.g. kcookiejar dialog) -> allow activation else if (groupTransient() && - findInList(mainClients(), sameApplicationActiveHackPredicate) == NULL) + findInList(clientMainClients(), sameApplicationActiveHackPredicate) == NULL) ; // standalone transient else first_window = false; @@ -782,8 +790,8 @@ void Client::doSetActive() { StackingUpdatesBlocker blocker(workspace()); workspace()->updateClientLayer(this); // active windows may get different layer - ClientList mainclients = mainClients(); - for (ClientList::ConstIterator it = mainclients.constBegin(); + auto mainclients = mainClients(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd(); ++it) if ((*it)->isFullScreen()) // fullscreens go high even if their transient is active diff --git a/client.cpp b/client.cpp index 4fc9e10a48..d8b7a22bad 100644 --- a/client.cpp +++ b/client.cpp @@ -706,8 +706,8 @@ bool Client::isMinimizable() const if (isTransient()) { // #66868 - Let other xmms windows be minimized when the mainwindow is minimized bool shown_mainwindow = false; - ClientList mainclients = mainClients(); - for (ClientList::ConstIterator it = mainclients.constBegin(); + auto mainclients = mainClients(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd(); ++it) if ((*it)->isShown(true)) @@ -747,7 +747,11 @@ QRect Client::iconGeometry() const return geom; else { // Check all mainwindows of this window (recursively) - foreach (Client * mainwin, mainClients()) { + foreach (AbstractClient * amainwin, mainClients()) { + Client *mainwin = dynamic_cast(amainwin); + if (!mainwin) { + continue; + } geom = mainwin->iconGeometry(); if (geom.isValid()) return geom; @@ -1235,7 +1239,7 @@ void Client::doSetDesktop(int desktop, int was_desk) // the (just moved) modal dialog will confusingly return to the mainwindow with // the next desktop change { - foreach (Client * c2, mainClients()) + foreach (AbstractClient * c2, mainClients()) c2->setDesktop(desktop); } updateVisibility(); @@ -1754,8 +1758,8 @@ void Client::getIcons() } if (icon.isNull() && isTransient()) { // Then mainclients - ClientList mainclients = mainClients(); - for (ClientList::ConstIterator it = mainclients.constBegin(); + auto mainclients = mainClients(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd() && icon.isNull(); ++it) { if (!(*it)->icon().isNull()) { diff --git a/client.h b/client.h index d0b605b1bd..8a650a00ee 100644 --- a/client.h +++ b/client.h @@ -177,8 +177,7 @@ public: bool isTransient() const override; bool groupTransient() const; bool wasOriginallyGroupTransient() const; - ClientList mainClients() const; // Call once before loop , is not indirect - ClientList allMainClients() const; // Call once before loop , is indirect + QList mainClients() const override; // Call once before loop , is not indirect bool hasTransient(const AbstractClient* c, bool indirect) const override; const ClientList& transients() const; // Is not indirect void checkTransient(xcb_window_t w); diff --git a/deleted.cpp b/deleted.cpp index f85a789774..08dd5f7f67 100644 --- a/deleted.cpp +++ b/deleted.cpp @@ -102,9 +102,11 @@ void Deleted::copyToDeleted(Toplevel* c) } m_minimized = client->isMinimized(); m_modal = client->isModal(); + } + if (AbstractClient *client = dynamic_cast(c)) { m_mainClients = client->mainClients(); - foreach (Client *c, m_mainClients) { - connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(mainClientClosed(KWin::Toplevel*))); + foreach (AbstractClient *c, m_mainClients) { + connect(c, &AbstractClient::windowClosed, this, &Deleted::mainClientClosed); } } } diff --git a/deleted.h b/deleted.h index b4d5723650..783862bc05 100644 --- a/deleted.h +++ b/deleted.h @@ -26,6 +26,8 @@ along with this program. If not, see . namespace KWin { +class AbstractClient; + namespace Decoration { class Renderer; @@ -64,7 +66,7 @@ public: bool isModal() const { return m_modal; } - ClientList mainClients() const { + QList mainClients() const { return m_mainClients; } NET::WindowType windowType(bool direct = false, int supported_types = 0) const; @@ -102,7 +104,7 @@ private: Layer m_layer; bool m_minimized; bool m_modal; - ClientList m_mainClients; + QList m_mainClients; bool m_wasClient; Decoration::Renderer *m_decorationRenderer; double m_opacity; diff --git a/effects.cpp b/effects.cpp index fa68eaaa41..6a9c7c29e6 100644 --- a/effects.cpp +++ b/effects.cpp @@ -1668,8 +1668,8 @@ EffectWindowList getMainWindows(Toplevel *toplevel) { T *c = static_cast(toplevel); EffectWindowList ret; - ClientList mainclients = c->mainClients(); - for (Client * tmp : mainclients) + const auto mainclients = c->mainClients(); + for (auto tmp : mainclients) ret.append(tmp->effectWindow()); return ret; } diff --git a/group.cpp b/group.cpp index 8cdaa3d3eb..5e5fbc8dc2 100644 --- a/group.cpp +++ b/group.cpp @@ -358,7 +358,7 @@ void Workspace::updateMinimizedOfTransients(Client* c) } } if (c->isModal()) { // if a modal dialog is minimized, minimize its mainwindow too - foreach (Client * c2, c->mainClients()) + foreach (AbstractClient * c2, c->mainClients()) c2->minimize(); } } else { @@ -372,7 +372,7 @@ void Workspace::updateMinimizedOfTransients(Client* c) } } if (c->isModal()) { - foreach (Client * c2, c->mainClients()) + foreach (AbstractClient * c2, c->mainClients()) c2->unminimize(); } } @@ -884,13 +884,13 @@ bool Client::hasTransientInternal(const Client* cl, bool indirect, ConstClientLi return false; } -ClientList Client::mainClients() const +QList Client::mainClients() const { if (!isTransient()) - return ClientList(); - if (const Client *t = qobject_cast(transientFor())) - return ClientList() << const_cast< Client* >(t); - ClientList result; + return QList(); + if (const AbstractClient *t = transientFor()) + return QList{const_cast< AbstractClient* >(t)}; + QList result; Q_ASSERT(group()); for (ClientList::ConstIterator it = group()->members().constBegin(); it != group()->members().constEnd(); @@ -900,14 +900,6 @@ ClientList Client::mainClients() const return result; } -ClientList Client::allMainClients() const -{ - ClientList result = mainClients(); - foreach (const Client * cl, result) - result += cl->allMainClients(); - return result; -} - AbstractClient* Client::findModal(bool allow_itself) { for (auto it = transients().constBegin(); diff --git a/manage.cpp b/manage.cpp index 4dd10331c1..049ead4448 100644 --- a/manage.cpp +++ b/manage.cpp @@ -188,12 +188,12 @@ bool Client::manage(xcb_window_t w, bool isMapped) // same window as its parent. this is necessary when an application // starts up on a different desktop than is currently displayed if (isTransient()) { - ClientList mainclients = mainClients(); + auto mainclients = mainClients(); bool on_current = false; bool on_all = false; - Client* maincl = NULL; + AbstractClient* maincl = nullptr; // This is slightly duplicated from Placement::placeOnMainWindow() - for (ClientList::ConstIterator it = mainclients.constBegin(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd(); ++it) { if (mainclients.count() > 1 && (*it)->isSpecialWindow()) @@ -470,8 +470,8 @@ bool Client::manage(xcb_window_t w, bool isMapped) // if client has initial state set to Iconic and is transient with a parent // window that is not Iconic, set init_state to Normal if (init_minimize && isTransient()) { - ClientList mainclients = mainClients(); - for (ClientList::ConstIterator it = mainclients.constBegin(); + auto mainclients = mainClients(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd(); ++it) if ((*it)->isShown(true)) @@ -482,8 +482,8 @@ bool Client::manage(xcb_window_t w, bool isMapped) bool visible_parent = false; // Use allMainClients(), to include also main clients of group transients // that have been optimized out in Client::checkGroupTransients() - ClientList mainclients = allMainClients(); - for (ClientList::ConstIterator it = mainclients.constBegin(); + auto mainclients = allMainClients(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd(); ++it) if ((*it)->isShown(true)) @@ -591,10 +591,12 @@ bool Client::manage(xcb_window_t w, bool isMapped) */ needsSessionInteract = true; //show the parent too - ClientList mainclients = mainClients(); - for (ClientList::ConstIterator it = mainclients.constBegin(); + auto mainclients = mainClients(); + for (auto it = mainclients.constBegin(); it != mainclients.constEnd(); ++it) { - (*it)->setSessionInteract(true); + if (Client *mc = dynamic_cast((*it))) { + mc->setSessionInteract(true); + } (*it)->unminimize(); } } else if (allow) { diff --git a/placement.cpp b/placement.cpp index 1b4873fe09..b427ae5afa 100644 --- a/placement.cpp +++ b/placement.cpp @@ -521,14 +521,11 @@ void Placement::placeOnMainWindow(AbstractClient* c, QRect& area, Policy nextPla if (nextPlacement == Maximizing) // maximize if needed placeMaximizing(c, area, NoPlacement); area = checkArea(c, area); - ClientList mainwindows; - if (Client *client = qobject_cast(c)) { - mainwindows = client->mainClients(); - } + auto mainwindows = c->mainClients(); AbstractClient* place_on = nullptr; AbstractClient* place_on2 = nullptr; int mains_count = 0; - for (ClientList::ConstIterator it = mainwindows.constBegin(); + for (auto it = mainwindows.constBegin(); it != mainwindows.constEnd(); ++it) { if (mainwindows.count() > 1 && (*it)->isSpecialWindow()) diff --git a/workspace.cpp b/workspace.cpp index 9318ea4cc9..71b8854228 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -693,12 +693,12 @@ void Workspace::updateToolWindows(bool also_hide) show = false; } if (!show && also_hide) { - const ClientList mainclients = c->mainClients(); + const auto mainclients = c->mainClients(); // Don't hide utility windows which are standalone(?) or // have e.g. kicker as mainwindow if (mainclients.isEmpty()) show = true; - for (ClientList::ConstIterator it2 = mainclients.constBegin(); + for (auto it2 = mainclients.constBegin(); it2 != mainclients.constEnd(); ++it2) { if ((*it2)->isSpecialWindow())