Move transients from Client to AbstractClient
Unfortunately introduces a few casts to Client again.
This commit is contained in:
parent
2da04aa26b
commit
2f7597e522
7 changed files with 80 additions and 42 deletions
|
@ -861,4 +861,21 @@ bool AbstractClient::isModal() const
|
|||
return m_modal;
|
||||
}
|
||||
|
||||
void AbstractClient::addTransient(AbstractClient *cl)
|
||||
{
|
||||
assert(!m_transients.contains(cl));
|
||||
assert(cl != this);
|
||||
m_transients.append(cl);
|
||||
}
|
||||
|
||||
void AbstractClient::removeTransient(AbstractClient *cl)
|
||||
{
|
||||
m_transients.removeAll(cl);
|
||||
}
|
||||
|
||||
void AbstractClient::removeTransientFromList(AbstractClient *cl)
|
||||
{
|
||||
m_transients.removeAll(cl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ public:
|
|||
* @todo: remove boolean trap
|
||||
**/
|
||||
virtual bool hasTransient(const AbstractClient* c, bool indirect) const;
|
||||
const QList<AbstractClient*>& transients() const; // Is not indirect
|
||||
virtual QList<AbstractClient*> mainClients() const; // Call once before loop , is not indirect
|
||||
QList<AbstractClient*> allMainClients() const; // Call once before loop , is indirect
|
||||
/**
|
||||
|
@ -497,6 +498,12 @@ protected:
|
|||
void updateColorScheme(QString path);
|
||||
|
||||
void setTransientFor(AbstractClient *transientFor);
|
||||
virtual void addTransient(AbstractClient* cl);
|
||||
virtual void removeTransient(AbstractClient* cl);
|
||||
/**
|
||||
* Just removes the @p cl from the transients without any further checks.
|
||||
**/
|
||||
void removeTransientFromList(AbstractClient* cl);
|
||||
|
||||
private:
|
||||
void handlePaletteChange();
|
||||
|
@ -526,6 +533,7 @@ private:
|
|||
KWayland::Server::PlasmaWindowInterface *m_windowManagementInterface = nullptr;
|
||||
|
||||
AbstractClient *m_transientFor = nullptr;
|
||||
QList<AbstractClient*> m_transients;
|
||||
bool m_modal = false;
|
||||
};
|
||||
|
||||
|
@ -539,6 +547,11 @@ inline void AbstractClient::resizeWithChecks(const QSize& s, AbstractClient::For
|
|||
resizeWithChecks(s.width(), s.height(), force);
|
||||
}
|
||||
|
||||
inline const QList<AbstractClient*>& AbstractClient::transients() const
|
||||
{
|
||||
return m_transients;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(KWin::AbstractClient*)
|
||||
|
|
|
@ -108,8 +108,13 @@ void Activities::toggleClientOnActivity(Client* c, const QString &activity, bool
|
|||
auto transients_stacking_order = ws->ensureStackingOrder(c->transients());
|
||||
for (auto it = transients_stacking_order.constBegin();
|
||||
it != transients_stacking_order.constEnd();
|
||||
++it)
|
||||
toggleClientOnActivity(*it, activity, dont_activate);
|
||||
++it) {
|
||||
Client *c = dynamic_cast<Client *>(*it);
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
toggleClientOnActivity(c, activity, dont_activate);
|
||||
}
|
||||
ws->updateClientArea();
|
||||
}
|
||||
|
||||
|
|
11
client.h
11
client.h
|
@ -175,7 +175,6 @@ public:
|
|||
bool wasOriginallyGroupTransient() const;
|
||||
QList<AbstractClient*> 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);
|
||||
AbstractClient* findModal(bool allow_itself = false) override;
|
||||
const Group* group() const;
|
||||
|
@ -700,15 +699,14 @@ private:
|
|||
void readTransientProperty(Xcb::TransientFor &transientFor);
|
||||
void readTransient();
|
||||
xcb_window_t verifyTransientFor(xcb_window_t transient_for, bool set);
|
||||
void addTransient(Client* cl);
|
||||
void removeTransient(Client* cl);
|
||||
void addTransient(AbstractClient* cl) override;
|
||||
void removeTransient(AbstractClient* cl) override;
|
||||
void removeFromMainClients();
|
||||
void cleanGrouping();
|
||||
void checkGroupTransients();
|
||||
void setTransient(xcb_window_t new_transient_for_id);
|
||||
xcb_window_t m_transientForId;
|
||||
xcb_window_t m_originalTransientForId;
|
||||
ClientList transients_list; // SELI TODO: Make this ordered in stacking order?
|
||||
ShadeMode shade_mode;
|
||||
Client *shade_below;
|
||||
uint deleting : 1; ///< True when doing cleanup and destroying the client
|
||||
|
@ -835,11 +833,6 @@ inline bool Client::isTransient() const
|
|||
return m_transientForId != XCB_WINDOW_NONE;
|
||||
}
|
||||
|
||||
inline const ClientList& Client::transients() const
|
||||
{
|
||||
return transients_list;
|
||||
}
|
||||
|
||||
inline const Group* Client::group() const
|
||||
{
|
||||
return in_group;
|
||||
|
|
66
group.cpp
66
group.cpp
|
@ -96,14 +96,14 @@ bool performTransiencyCheck()
|
|||
ret = false;
|
||||
continue;
|
||||
}
|
||||
if (!(*it2)->transients_list.contains(*it1)) {
|
||||
if (!(*it2)->transients().contains(*it1)) {
|
||||
kdDebug(1212) << "TC:" << *it1 << " has main client " << *it2 << " but main client does not have it as a transient" << endl;
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientList trans = (*it1)->transients_list;
|
||||
for (ClientList::ConstIterator it2 = trans.constBegin();
|
||||
auto trans = (*it1)->transients();
|
||||
for (auto it2 = trans.constBegin();
|
||||
it2 != trans.constEnd();
|
||||
++it2) {
|
||||
if (transiencyCheckNonExistent
|
||||
|
@ -342,7 +342,7 @@ Group* Workspace::findClientLeaderGroup(const Client* c) const
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Workspace::updateMinimizedOfTransients(Client* c)
|
||||
void Workspace::updateMinimizedOfTransients(AbstractClient* c)
|
||||
{
|
||||
// if mainwindow is minimized or shaded, minimize transients too
|
||||
if (c->isMinimized()) {
|
||||
|
@ -637,12 +637,12 @@ void Client::cleanGrouping()
|
|||
// it != mains.end();
|
||||
// ++it )
|
||||
// qDebug() << "MN2:" << *it;
|
||||
for (ClientList::ConstIterator it = transients_list.constBegin();
|
||||
it != transients_list.constEnd();
|
||||
for (auto it = transients().constBegin();
|
||||
it != transients().constEnd();
|
||||
) {
|
||||
if ((*it)->transientFor() == this) {
|
||||
removeTransient(*it);
|
||||
it = transients_list.constBegin(); // restart, just in case something more has changed with the list
|
||||
it = transients().constBegin(); // restart, just in case something more has changed with the list
|
||||
} else
|
||||
++it;
|
||||
}
|
||||
|
@ -699,7 +699,7 @@ void Client::checkGroupTransients()
|
|||
cl = cl->transientFor()) {
|
||||
if (cl == *it1) {
|
||||
// don't use removeTransient(), that would modify *it2 too
|
||||
(*it2)->transients_list.removeAll(*it1);
|
||||
(*it2)->removeTransientFromList(*it1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -708,7 +708,7 @@ void Client::checkGroupTransients()
|
|||
// and should be therefore on top of *it1
|
||||
// TODO This could possibly be optimized, it also requires hasTransient() to check for loops.
|
||||
if ((*it2)->groupTransient() && (*it1)->hasTransient(*it2, true) && (*it2)->hasTransient(*it1, true))
|
||||
(*it2)->transients_list.removeAll(*it1);
|
||||
(*it2)->removeTransientFromList(*it1);
|
||||
// if there are already windows W1 and W2, W2 being transient for W1, and group transient W3
|
||||
// is added, make it transient only for W2, not for W1, because it's already indirectly
|
||||
// transient for it - the indirect transiency actually shouldn't break anything,
|
||||
|
@ -721,9 +721,9 @@ void Client::checkGroupTransients()
|
|||
continue;
|
||||
if ((*it2)->hasTransient(*it1, false) && (*it3)->hasTransient(*it1, false)) {
|
||||
if ((*it2)->hasTransient(*it3, true))
|
||||
(*it2)->transients_list.removeAll(*it1);
|
||||
(*it2)->removeTransientFromList(*it1);
|
||||
if ((*it3)->hasTransient(*it2, true))
|
||||
(*it3)->transients_list.removeAll(*it1);
|
||||
(*it3)->removeTransientFromList(*it1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -797,13 +797,10 @@ xcb_window_t Client::verifyTransientFor(xcb_window_t new_transient_for, bool set
|
|||
return new_transient_for;
|
||||
}
|
||||
|
||||
void Client::addTransient(Client* cl)
|
||||
void Client::addTransient(AbstractClient* cl)
|
||||
{
|
||||
TRANSIENCY_CHECK(this);
|
||||
assert(!transients_list.contains(cl));
|
||||
// assert( !cl->hasTransient( this, true )); will be fixed in checkGroupTransients()
|
||||
assert(cl != this);
|
||||
transients_list.append(cl);
|
||||
AbstractClient::addTransient(cl);
|
||||
if (workspace()->mostRecentlyActivatedClient() == this && cl->isModal())
|
||||
check_active_modal = true;
|
||||
// qDebug() << "ADDTRANS:" << this << ":" << cl;
|
||||
|
@ -814,19 +811,21 @@ void Client::addTransient(Client* cl)
|
|||
// qDebug() << "AT:" << (*it);
|
||||
}
|
||||
|
||||
void Client::removeTransient(Client* cl)
|
||||
void Client::removeTransient(AbstractClient* cl)
|
||||
{
|
||||
TRANSIENCY_CHECK(this);
|
||||
// qDebug() << "REMOVETRANS:" << this << ":" << cl;
|
||||
// qDebug() << kBacktrace();
|
||||
transients_list.removeAll(cl);
|
||||
// cl is transient for this, but this is going away
|
||||
// make cl group transient
|
||||
AbstractClient::removeTransient(cl);
|
||||
if (cl->transientFor() == this) {
|
||||
cl->m_transientForId = XCB_WINDOW_NONE;
|
||||
cl->setTransientFor(nullptr); // SELI
|
||||
if (Client *c = dynamic_cast<Client*>(cl)) {
|
||||
c->m_transientForId = XCB_WINDOW_NONE;
|
||||
c->setTransientFor(nullptr); // SELI
|
||||
// SELI cl->setTransient( rootWindow());
|
||||
cl->setTransient(XCB_WINDOW_NONE);
|
||||
c->setTransient(XCB_WINDOW_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -878,9 +877,14 @@ bool Client::hasTransientInternal(const Client* cl, bool indirect, ConstClientLi
|
|||
set.append(this);
|
||||
for (auto it = transients().constBegin();
|
||||
it != transients().constEnd();
|
||||
++it)
|
||||
if ((*it)->hasTransientInternal(cl, indirect, set))
|
||||
++it) {
|
||||
Client *c = dynamic_cast<Client *>(*it);
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
if (c->hasTransientInternal(cl, indirect, set))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -985,13 +989,19 @@ void Client::checkGroup(Group* set_group, bool force)
|
|||
}
|
||||
}
|
||||
if (in_group != old_group || force) {
|
||||
for (ClientList::Iterator it = transients_list.begin();
|
||||
it != transients_list.end();
|
||||
for (auto it = transients().constBegin();
|
||||
it != transients().constEnd();
|
||||
) {
|
||||
Client *c = dynamic_cast<Client *>(*it);
|
||||
if (!c) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
// group transients in the old group are no longer transient for it
|
||||
if ((*it)->groupTransient() && (*it)->group() != group())
|
||||
it = transients_list.erase(it);
|
||||
else
|
||||
if (c->groupTransient() && c->group() != group()) {
|
||||
removeTransientFromList(c);
|
||||
it = transients().constBegin(); // restart, just in case something more has changed with the list
|
||||
} else
|
||||
++it;
|
||||
}
|
||||
if (groupTransient()) {
|
||||
|
|
|
@ -873,9 +873,9 @@ void Client::updateLayer()
|
|||
(*it)->updateLayer();
|
||||
}
|
||||
|
||||
bool rec_checkTransientOnTop(const ClientList &transients, const Client *topmost)
|
||||
bool rec_checkTransientOnTop(const QList<AbstractClient*> &transients, const Client *topmost)
|
||||
{
|
||||
foreach (const Client *transient, transients) {
|
||||
foreach (const AbstractClient *transient, transients) {
|
||||
if (transient == topmost || rec_checkTransientOnTop(transient->transients(), topmost)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ public:
|
|||
return m_userActionsMenu;
|
||||
}
|
||||
|
||||
void updateMinimizedOfTransients(Client*);
|
||||
void updateMinimizedOfTransients(AbstractClient*);
|
||||
void updateOnAllDesktopsOfTransients(Client*);
|
||||
void checkTransients(xcb_window_t w);
|
||||
|
||||
|
|
Loading…
Reference in a new issue