Commit c4c3dfc7 authored by Martin Flöser's avatar Martin Flöser

Move transientFor from Client to AbstractClient

Right now this caused a few dynamic_casts. On the other hand existing
dynamic_casts from AbstractClient to Client can be removed again.
parent 07dd7434
......@@ -793,4 +793,23 @@ bool AbstractClient::performMouseCommand(Options::MouseCommand cmd, const QPoint
return replay;
}
void AbstractClient::setTransientFor(AbstractClient *transientFor)
{
if (m_transientFor == transientFor) {
return;
}
m_transientFor = transientFor;
emit transientChanged();
}
const AbstractClient *AbstractClient::transientFor() const
{
return m_transientFor;
}
AbstractClient *AbstractClient::transientFor()
{
return m_transientFor;
}
}
......@@ -166,6 +166,10 @@ class AbstractClient : public Toplevel
* @see transientFor
**/
Q_PROPERTY(bool transient READ isTransient NOTIFY transientChanged)
/**
* The Client to which this Client is a transient if any.
**/
Q_PROPERTY(KWin::AbstractClient *transientFor READ transientFor NOTIFY transientChanged)
public:
virtual ~AbstractClient();
......@@ -243,6 +247,8 @@ public:
// TODO: remove boolean trap
virtual AbstractClient *findModal(bool allow_itself = false) = 0;
virtual bool isTransient() const;
const AbstractClient* transientFor() const;
AbstractClient* transientFor();
/**
* 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.)
......@@ -465,6 +471,8 @@ protected:
void updateColorScheme(QString path);
void setTransientFor(AbstractClient *transientFor);
private:
void handlePaletteChange();
QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
......@@ -491,6 +499,8 @@ private:
static std::shared_ptr<Decoration::DecorationPalette> s_defaultPalette;
KWayland::Server::PlasmaWindowInterface *m_windowManagementInterface = nullptr;
AbstractClient *m_transientFor = nullptr;
};
inline void AbstractClient::move(const QPoint& p, ForceGeometry_t force)
......
......@@ -105,7 +105,6 @@ Client::Client()
, m_moveResizeGrabWindow()
, move_resize_has_keyboard_grab(false)
, m_managed(false)
, transient_for (NULL)
, m_transientForId(XCB_WINDOW_NONE)
, m_originalTransientForId(XCB_WINDOW_NONE)
, shade_below(NULL)
......
......@@ -113,10 +113,6 @@ class Client
* Because of that there is no notify signal.
**/
Q_PROPERTY(bool resizeable READ isResizable)
/**
* The Client to which this Client is a transient if any.
**/
Q_PROPERTY(KWin::Client *transientFor READ transientFor NOTIFY transientChanged)
/**
* By how much the window wishes to grow/shrink at least. Usually QSize(1,1).
* MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all.
......@@ -178,8 +174,6 @@ public:
xcb_window_t inputId() const { return m_decoInputExtent; }
virtual xcb_window_t frameId() const override;
const Client* transientFor() const;
Client* transientFor();
bool isTransient() const override;
bool groupTransient() const;
bool wasOriginallyGroupTransient() const;
......@@ -721,7 +715,6 @@ private:
void cleanGrouping();
void checkGroupTransients();
void setTransient(xcb_window_t new_transient_for_id);
Client* transient_for;
xcb_window_t m_transientForId;
xcb_window_t m_originalTransientForId;
ClientList transients_list; // SELI TODO: Make this ordered in stacking order?
......@@ -835,16 +828,6 @@ inline bool Client::isClientSideDecorated() const
return m_clientSideDecorated;
}
inline const Client* Client::transientFor() const
{
return transient_for;
}
inline Client* Client::transientFor()
{
return transient_for;
}
inline bool Client::groupTransient() const
{
return m_transientForId == rootWindow();
......
......@@ -471,8 +471,8 @@ bool Client::belongToSameApplication(const Client* c1, const Client* c2, bool ac
bool Client::sameAppWindowRoleMatch(const Client* c1, const Client* c2, bool active_hack)
{
if (c1->isTransient()) {
while (c1->transientFor() != NULL)
c1 = c1->transientFor();
while (const Client *t = dynamic_cast<const Client*>(c1->transientFor()))
c1 = t;
if (c1->groupTransient())
return c1->group() == c2->group();
#if 0
......@@ -483,8 +483,8 @@ bool Client::sameAppWindowRoleMatch(const Client* c1, const Client* c2, bool act
#endif
}
if (c2->isTransient()) {
while (c2->transientFor() != NULL)
c2 = c2->transientFor();
while (const Client *t = dynamic_cast<const Client*>(c2->transientFor()))
c2 = t;
if (c2->groupTransient())
return c1->group() == c2->group();
#if 0
......@@ -580,13 +580,14 @@ void Client::setTransient(xcb_window_t new_transient_for_id)
TRANSIENCY_CHECK(this);
if (new_transient_for_id != m_transientForId) {
removeFromMainClients();
transient_for = NULL;
Client *transient_for = nullptr;
m_transientForId = new_transient_for_id;
if (m_transientForId != XCB_WINDOW_NONE && !groupTransient()) {
transient_for = workspace()->findClient(Predicate::WindowMatch, m_transientForId);
assert(transient_for != NULL); // verifyTransient() had to check this
transient_for->addTransient(this);
} // checkGroup() will check 'check_active_modal'
setTransientFor(transient_for);
checkGroup(NULL, true); // force, because transiency has changed
workspace()->updateClientLayer(this);
workspace()->resetUpdateToolWindowsTimer();
......@@ -597,8 +598,8 @@ void Client::setTransient(xcb_window_t new_transient_for_id)
void Client::removeFromMainClients()
{
TRANSIENCY_CHECK(this);
if (transientFor() != NULL)
transientFor()->removeTransient(this);
if (Client *t = dynamic_cast<Client*>(transientFor()))
t->removeTransient(this);
if (groupTransient()) {
for (ClientList::ConstIterator it = group()->members().constBegin();
it != group()->members().constEnd();
......@@ -693,7 +694,7 @@ void Client::checkGroupTransients()
// so don't make them transient for the ones that are transient for it
if (*it1 == *it2)
continue;
for (Client* cl = (*it2)->transientFor();
for (AbstractClient* cl = (*it2)->transientFor();
cl != NULL;
cl = cl->transientFor()) {
if (cl == *it1) {
......@@ -823,7 +824,7 @@ void Client::removeTransient(Client* cl)
// make cl group transient
if (cl->transientFor() == this) {
cl->m_transientForId = XCB_WINDOW_NONE;
cl->transient_for = NULL; // SELI
cl->setTransientFor(nullptr); // SELI
// SELI cl->setTransient( rootWindow());
cl->setTransient(XCB_WINDOW_NONE);
}
......@@ -850,15 +851,15 @@ bool Client::hasTransient(const Client* cl, bool indirect) const
bool Client::hasTransientInternal(const Client* cl, bool indirect, ConstClientList& set) const
{
if (cl->transientFor() != NULL) {
if (cl->transientFor() == this)
if (const Client *t = dynamic_cast<const Client*>(cl->transientFor())) {
if (t == this)
return true;
if (!indirect)
return false;
if (set.contains(cl))
return false;
set.append(cl);
return hasTransientInternal(cl->transientFor(), indirect, set);
return hasTransientInternal(t, indirect, set);
}
if (!cl->isTransient())
return false;
......@@ -884,8 +885,8 @@ ClientList Client::mainClients() const
{
if (!isTransient())
return ClientList();
if (transientFor() != NULL)
return ClientList() << const_cast< Client* >(transientFor());
if (const Client *t = qobject_cast<const Client*>(transientFor()))
return ClientList() << const_cast< Client* >(t);
ClientList result;
Q_ASSERT(group());
for (ClientList::ConstIterator it = group()->members().constBegin();
......@@ -934,10 +935,11 @@ void Client::checkGroup(Group* set_group, bool force)
}
} else if (info->groupLeader() != XCB_WINDOW_NONE) {
Group* new_group = workspace()->findGroup(info->groupLeader());
if (transientFor() != NULL && transientFor()->group() != new_group) {
Client *t = qobject_cast<Client*>(transientFor());
if (t != NULL && t->group() != new_group) {
// move the window to the right group (e.g. a dialog provided
// by different app, but transient for this one, so make it part of that group)
new_group = transientFor()->group();
new_group = t->group();
}
if (new_group == NULL) // doesn't exist yet
new_group = new Group(info->groupLeader());
......@@ -948,14 +950,14 @@ void Client::checkGroup(Group* set_group, bool force)
in_group->addMember(this);
}
} else {
if (transientFor() != NULL) {
if (Client *t = qobject_cast<Client*>(transientFor())) {
// doesn't have window group set, but is transient for something
// so make it part of that group
Group* new_group = transientFor()->group();
Group* new_group = t->group();
if (new_group != in_group) {
if (in_group != NULL)
in_group->removeMember(this);
in_group = transientFor()->group();
in_group = t->group();
in_group->addMember(this);
}
} else if (groupTransient()) {
......
......@@ -368,8 +368,8 @@ void Workspace::raiseClient(AbstractClient* c, bool nogroup)
StackingUpdatesBlocker blocker(this);
if (!nogroup && c->isTransient()) {
ClientList transients;
Client *transient_parent = static_cast<Client*>(c);
QList<AbstractClient*> transients;
AbstractClient *transient_parent = c;
while ((transient_parent = transient_parent->transientFor()))
transients << transient_parent;
foreach (transient_parent, transients)
......
......@@ -661,7 +661,7 @@ void Workspace::updateToolWindows(bool also_hide)
group = client->group();
break;
}
client = client->transientFor();
client = dynamic_cast<const Client*>(client->transientFor());
}
// Use stacking order only to reduce flicker, it doesn't matter if block_stacking_updates == 0,
// I.e. if it's not up to date
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment