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