Skip to content

Commit 3d0fd3a

Browse files
committed
core/window: add parentWindow property to FloatingWindow
1 parent e9bad67 commit 3d0fd3a

File tree

4 files changed

+96
-2
lines changed

4 files changed

+96
-2
lines changed

src/window/floatingwindow.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include <qobject.h>
44
#include <qqmlengine.h>
5-
#include <qqmllist.h>
5+
#include <qqmlinfo.h>
66
#include <qtmetamacros.h>
77
#include <qtypes.h>
88

@@ -15,6 +15,9 @@ void ProxyFloatingWindow::connectWindow() {
1515
this->window->setTitle(this->bTitle);
1616
this->window->setMinimumSize(this->bMinimumSize);
1717
this->window->setMaximumSize(this->bMaximumSize);
18+
19+
// Apply transient parent now that our backing window exists
20+
this->updateTransientParent();
1821
}
1922

2023
void ProxyFloatingWindow::trySetWidth(qint32 implicitWidth) {
@@ -44,6 +47,65 @@ void ProxyFloatingWindow::onMaximumSizeChanged() {
4447
emit this->maximumSizeChanged();
4548
}
4649

50+
QObject* ProxyFloatingWindow::parentWindow() const { return this->mParentWindow; }
51+
52+
void ProxyFloatingWindow::setParentWindow(QObject* window) {
53+
if (window == this->mParentWindow) return;
54+
55+
if (this->mParentWindow) {
56+
QObject::disconnect(this->mParentWindow, nullptr, this, nullptr);
57+
QObject::disconnect(this->mParentProxyWindow, nullptr, this, nullptr);
58+
}
59+
60+
if (window) {
61+
if (auto* proxy = qobject_cast<ProxyWindowBase*>(window)) {
62+
this->mParentProxyWindow = proxy;
63+
} else if (auto* interface = qobject_cast<WindowInterface*>(window)) {
64+
this->mParentProxyWindow = interface->proxyWindow();
65+
} else {
66+
qmlWarning(this) << "parentWindow must be a quickshell window.";
67+
return;
68+
}
69+
70+
this->mParentWindow = window;
71+
QObject::connect(
72+
this->mParentWindow,
73+
&QObject::destroyed,
74+
this,
75+
&ProxyFloatingWindow::onParentDestroyed
76+
);
77+
78+
QObject::connect(
79+
this->mParentProxyWindow,
80+
&ProxyWindowBase::backingWindowChanged,
81+
this,
82+
&ProxyFloatingWindow::updateTransientParent
83+
);
84+
} else {
85+
this->mParentWindow = nullptr;
86+
this->mParentProxyWindow = nullptr;
87+
}
88+
89+
this->updateTransientParent();
90+
emit this->parentWindowChanged();
91+
}
92+
93+
void ProxyFloatingWindow::onParentDestroyed() {
94+
this->mParentWindow = nullptr;
95+
this->mParentProxyWindow = nullptr;
96+
this->updateTransientParent();
97+
emit this->parentWindowChanged();
98+
}
99+
100+
void ProxyFloatingWindow::updateTransientParent() {
101+
if (!this->window) return;
102+
103+
auto* parentBacking =
104+
this->mParentProxyWindow ? this->mParentProxyWindow->backingWindow() : nullptr;
105+
106+
this->window->setTransientParent(parentBacking);
107+
}
108+
47109
// FloatingWindowInterface
48110

49111
FloatingWindowInterface::FloatingWindowInterface(QObject* parent)
@@ -55,6 +117,7 @@ FloatingWindowInterface::FloatingWindowInterface(QObject* parent)
55117
QObject::connect(this->window, &ProxyFloatingWindow::titleChanged, this, &FloatingWindowInterface::titleChanged);
56118
QObject::connect(this->window, &ProxyFloatingWindow::minimumSizeChanged, this, &FloatingWindowInterface::minimumSizeChanged);
57119
QObject::connect(this->window, &ProxyFloatingWindow::maximumSizeChanged, this, &FloatingWindowInterface::maximumSizeChanged);
120+
QObject::connect(this->window, &ProxyFloatingWindow::parentWindowChanged, this, &FloatingWindowInterface::parentWindowChanged);
58121
// clang-format on
59122
}
60123

@@ -66,3 +129,9 @@ void FloatingWindowInterface::onReload(QObject* oldInstance) {
66129
}
67130

68131
ProxyWindowBase* FloatingWindowInterface::proxyWindow() const { return this->window; }
132+
133+
QObject* FloatingWindowInterface::parentWindow() const { return this->window->parentWindow(); }
134+
135+
void FloatingWindowInterface::setParentWindow(QObject* window) {
136+
this->window->setParentWindow(window);
137+
}

src/window/floatingwindow.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class ProxyFloatingWindow: public ProxyWindowBase {
1919

2020
void connectWindow() override;
2121

22+
[[nodiscard]] QObject* parentWindow() const;
23+
void setParentWindow(QObject* window);
24+
2225
// Setting geometry while the window is visible makes the content item shrink but not the window
2326
// which is awful so we disable it for floating windows.
2427
void trySetWidth(qint32 implicitWidth) override;
@@ -28,11 +31,19 @@ class ProxyFloatingWindow: public ProxyWindowBase {
2831
void minimumSizeChanged();
2932
void maximumSizeChanged();
3033
void titleChanged();
34+
void parentWindowChanged();
35+
36+
private slots:
37+
void onParentDestroyed();
3138

3239
private:
3340
void onMinimumSizeChanged();
3441
void onMaximumSizeChanged();
3542
void onTitleChanged();
43+
void updateTransientParent();
44+
45+
QObject* mParentWindow = nullptr;
46+
ProxyWindowBase* mParentProxyWindow = nullptr;
3647

3748
public:
3849
Q_OBJECT_BINDABLE_PROPERTY(
@@ -68,6 +79,9 @@ class FloatingWindowInterface: public WindowInterface {
6879
Q_PROPERTY(QSize minimumSize READ default WRITE default NOTIFY minimumSizeChanged BINDABLE bindableMinimumSize);
6980
/// Maximum window size given to the window system.
7081
Q_PROPERTY(QSize maximumSize READ default WRITE default NOTIFY maximumSizeChanged BINDABLE bindableMaximumSize);
82+
/// The parent window of this window. Setting this makes the window a child of the parent,
83+
/// which affects window stacking behavior.
84+
Q_PROPERTY(QObject* parentWindow READ parentWindow WRITE setParentWindow NOTIFY parentWindowChanged);
7185
// clang-format on
7286
QML_NAMED_ELEMENT(FloatingWindow);
7387

@@ -82,10 +96,14 @@ class FloatingWindowInterface: public WindowInterface {
8296
QBindable<QSize> bindableMaximumSize() { return &this->window->bMaximumSize; }
8397
QBindable<QString> bindableTitle() { return &this->window->bTitle; }
8498

99+
[[nodiscard]] QObject* parentWindow() const;
100+
void setParentWindow(QObject* window);
101+
85102
signals:
86103
void minimumSizeChanged();
87104
void maximumSizeChanged();
88105
void titleChanged();
106+
void parentWindowChanged();
89107

90108
private:
91109
ProxyFloatingWindow* window;

src/window/proxywindow.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ void ProxyWindowBase::onReload(QObject* oldInstance) {
8181

8282
this->reloadComplete = true;
8383

84+
emit this->backingWindowChanged();
8485
emit this->windowConnected();
8586
this->postCompleteWindow();
8687

@@ -148,11 +149,16 @@ void ProxyWindowBase::createWindow() {
148149
this->ensureQWindow();
149150
this->connectWindow();
150151
this->completeWindow();
152+
emit this->backingWindowChanged();
151153
emit this->windowConnected();
152154
}
153155

154156
void ProxyWindowBase::deleteWindow(bool keepItemOwnership) {
155-
if (this->window != nullptr) emit this->windowDestroyed();
157+
if (this->window != nullptr) {
158+
emit this->windowDestroyed();
159+
emit this->backingWindowChanged();
160+
}
161+
156162
if (auto* window = this->disownWindow(keepItemOwnership)) window->deleteLater();
157163
}
158164

src/window/proxywindow.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ class ProxyWindowBase: public Reloadable {
145145
void resourcesLost();
146146
void windowConnected();
147147
void windowDestroyed();
148+
void backingWindowChanged();
148149
void visibleChanged();
149150
void backerVisibilityChanged();
150151
void xChanged();

0 commit comments

Comments
 (0)