Preserve stacking order constraints when closing a window
When closing a window, we may need to change parent-child relationship between windows, but we need to preserve stacking order constraints so dialogs are placed above their parents when they're closed.
This commit is contained in:
parent
2510bf0439
commit
5454cc47c3
3 changed files with 31 additions and 22 deletions
|
@ -221,16 +221,18 @@ void WaylandWindow::doSetActive()
|
||||||
|
|
||||||
void WaylandWindow::cleanGrouping()
|
void WaylandWindow::cleanGrouping()
|
||||||
{
|
{
|
||||||
|
// We want to break parent-child relationships, but preserve stacking
|
||||||
|
// order constraints at the same time for window closing animations.
|
||||||
|
|
||||||
if (transientFor()) {
|
if (transientFor()) {
|
||||||
transientFor()->removeTransient(this);
|
transientFor()->removeTransientFromList(this);
|
||||||
|
setTransientFor(nullptr);
|
||||||
}
|
}
|
||||||
for (auto it = transients().constBegin(); it != transients().constEnd();) {
|
|
||||||
if ((*it)->transientFor() == this) {
|
const auto children = transients();
|
||||||
removeTransient(*it);
|
for (Window *transient : children) {
|
||||||
it = transients().constBegin(); // restart, just in case something more has changed with the list
|
removeTransientFromList(transient);
|
||||||
} else {
|
transient->setTransientFor(nullptr);
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -925,6 +925,7 @@ public:
|
||||||
virtual QRectF transientPlacement(const QRectF &bounds) const;
|
virtual QRectF transientPlacement(const QRectF &bounds) const;
|
||||||
const Window *transientFor() const;
|
const Window *transientFor() const;
|
||||||
Window *transientFor();
|
Window *transientFor();
|
||||||
|
void setTransientFor(Window *transientFor);
|
||||||
/**
|
/**
|
||||||
* @returns @c true if transient is the transient_for window for this window,
|
* @returns @c true if transient is the transient_for window for this window,
|
||||||
* or recursively the transient_for window
|
* or recursively the transient_for window
|
||||||
|
@ -934,6 +935,7 @@ public:
|
||||||
const QList<Window *> &transients() const; // Is not indirect
|
const QList<Window *> &transients() const; // Is not indirect
|
||||||
virtual void addTransient(Window *transient);
|
virtual void addTransient(Window *transient);
|
||||||
virtual void removeTransient(Window *transient);
|
virtual void removeTransient(Window *transient);
|
||||||
|
void removeTransientFromList(Window *cl);
|
||||||
virtual QList<Window *> mainWindows() const; // Call once before loop , is not indirect
|
virtual QList<Window *> mainWindows() const; // Call once before loop , is not indirect
|
||||||
QList<Window *> allMainWindows() const; // Call once before loop , is indirect
|
QList<Window *> allMainWindows() const; // Call once before loop , is indirect
|
||||||
/**
|
/**
|
||||||
|
@ -1623,11 +1625,6 @@ protected:
|
||||||
void setupWindowManagementInterface();
|
void setupWindowManagementInterface();
|
||||||
void updateColorScheme();
|
void updateColorScheme();
|
||||||
void ensurePalette();
|
void ensurePalette();
|
||||||
void setTransientFor(Window *transientFor);
|
|
||||||
/**
|
|
||||||
* Just removes the @p cl from the transients without any further checks.
|
|
||||||
*/
|
|
||||||
void removeTransientFromList(Window *cl);
|
|
||||||
|
|
||||||
virtual Layer belongsToLayer() const;
|
virtual Layer belongsToLayer() const;
|
||||||
virtual bool belongsToDesktop() const;
|
virtual bool belongsToDesktop() const;
|
||||||
|
|
|
@ -3076,19 +3076,29 @@ void X11Window::removeFromMainClients()
|
||||||
// related lists.
|
// related lists.
|
||||||
void X11Window::cleanGrouping()
|
void X11Window::cleanGrouping()
|
||||||
{
|
{
|
||||||
removeFromMainClients();
|
// We want to break parent-child relationships, but preserve stacking
|
||||||
group()->removeMember(this);
|
// order constraints at the same time for window closing animations.
|
||||||
in_group = nullptr;
|
|
||||||
|
|
||||||
for (auto it = transients().constBegin(); it != transients().constEnd();) {
|
if (transientFor()) {
|
||||||
if ((*it)->transientFor() == this) {
|
transientFor()->removeTransientFromList(this);
|
||||||
removeTransient(*it);
|
setTransientFor(nullptr);
|
||||||
it = transients().constBegin(); // restart, just in case something more has changed with the list
|
}
|
||||||
} else {
|
|
||||||
++it;
|
if (groupTransient()) {
|
||||||
|
const auto members = group()->members();
|
||||||
|
for (Window *member : members) {
|
||||||
|
member->removeTransientFromList(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto children = transients();
|
||||||
|
for (Window *transient : children) {
|
||||||
|
removeTransientFromList(transient);
|
||||||
|
transient->setTransientFor(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
group()->removeMember(this);
|
||||||
|
in_group = nullptr;
|
||||||
m_transientForId = XCB_WINDOW_NONE;
|
m_transientForId = XCB_WINDOW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue