44#include < qcontainerfwd.h>
55#include < qlogging.h>
66#include < qobject.h>
7+ #include < qquickitem.h>
78#include < qsize.h>
89#include < qtmetamacros.h>
910#include < qwindow.h>
@@ -25,14 +26,11 @@ bool PopupAnchor::isDirty() const {
2526void PopupAnchor::markClean () { this ->lastState = this ->state ; }
2627void PopupAnchor::markDirty () { this ->lastState .reset (); }
2728
28- QObject* PopupAnchor::window () const { return this ->mWindow ; }
29- ProxyWindowBase* PopupAnchor::proxyWindow () const { return this ->mProxyWindow ; }
30-
3129QWindow* PopupAnchor::backingWindow () const {
3230 return this ->mProxyWindow ? this ->mProxyWindow ->backingWindow () : nullptr ;
3331}
3432
35- void PopupAnchor::setWindow (QObject* window) {
33+ void PopupAnchor::setWindowInternal (QObject* window) {
3634 if (window == this ->mWindow ) return ;
3735
3836 if (this ->mWindow ) {
@@ -78,25 +76,69 @@ void PopupAnchor::setWindow(QObject* window) {
7876 }
7977}
8078
79+ void PopupAnchor::setWindow (QObject* window) {
80+ this ->setItem (nullptr );
81+ this ->setWindowInternal (window);
82+ }
83+
84+ void PopupAnchor::setItem (QQuickItem* item) {
85+ if (item == this ->mItem ) return ;
86+
87+ if (this ->mItem ) {
88+ QObject::disconnect (this ->mItem , nullptr , this , nullptr );
89+ }
90+
91+ this ->mItem = item;
92+ this ->onItemWindowChanged ();
93+
94+ if (item) {
95+ QObject::connect (item, &QObject::destroyed, this , &PopupAnchor::onItemDestroyed);
96+ QObject::connect (item, &QQuickItem::windowChanged, this , &PopupAnchor::onItemWindowChanged);
97+ }
98+ }
99+
81100void PopupAnchor::onWindowDestroyed () {
82101 this ->mWindow = nullptr ;
83102 this ->mProxyWindow = nullptr ;
84103 emit this ->windowChanged ();
85104 emit this ->backingWindowVisibilityChanged ();
86105}
87106
88- Box PopupAnchor::rect () const { return this ->state .rect ; }
107+ void PopupAnchor::onItemDestroyed () {
108+ this ->mItem = nullptr ;
109+ emit this ->itemChanged ();
110+ this ->setWindowInternal (nullptr );
111+ }
112+
113+ void PopupAnchor::onItemWindowChanged () {
114+ if (auto * window = qobject_cast<ProxiedWindow*>(this ->mItem ->window ())) {
115+ this ->setWindowInternal (window->proxy ());
116+ } else {
117+ this ->setWindowInternal (nullptr );
118+ }
119+ }
89120
90121void PopupAnchor::setRect (Box rect) {
91- if (rect == this ->state .rect ) return ;
92122 if (rect.w <= 0 ) rect.w = 1 ;
93123 if (rect.h <= 0 ) rect.h = 1 ;
124+ if (rect == this ->mUserRect ) return ;
94125
95- this ->state . rect = rect;
126+ this ->mUserRect = rect;
96127 emit this ->rectChanged ();
128+
129+ this ->setWindowRect (rect);
130+ }
131+
132+ void PopupAnchor::setWindowRect (Box rect) {
133+ if (rect.w <= 0 ) rect.w = 1 ;
134+ if (rect.h <= 0 ) rect.h = 1 ;
135+ if (rect == this ->state .rect ) return ;
136+
137+ this ->state .rect = rect;
138+ emit this ->windowRectChanged ();
97139}
98140
99- Edges::Flags PopupAnchor::edges () const { return this ->state . edges ; }
141+ void PopupAnchor::resetRect () { this ->mUserRect = Box () ; }
100142
101143void PopupAnchor::setEdges (Edges::Flags edges) {
102144 if (edges == this ->state .edges ) return ;
@@ -110,8 +152,6 @@ void PopupAnchor::setEdges(Edges::Flags edges) {
110152 emit this ->edgesChanged ();
111153}
112154
113- Edges::Flags PopupAnchor::gravity () const { return this ->state .gravity ; }
114-
115155void PopupAnchor::setGravity (Edges::Flags gravity) {
116156 if (gravity == this ->state .gravity ) return ;
117157
@@ -124,8 +164,6 @@ void PopupAnchor::setGravity(Edges::Flags gravity) {
124164 emit this ->gravityChanged ();
125165}
126166
127- PopupAdjustment::Flags PopupAnchor::adjustment () const { return this ->state .adjustment ; }
128-
129167void PopupAnchor::setAdjustment (PopupAdjustment::Flags adjustment) {
130168 if (adjustment == this ->state .adjustment ) return ;
131169 this ->state .adjustment = adjustment;
@@ -137,6 +175,19 @@ void PopupAnchor::updatePlacement(const QPoint& anchorpoint, const QSize& size)
137175 this ->state .size = size;
138176}
139177
178+ void PopupAnchor::updateAnchor () {
179+ if (this ->mItem && this ->mProxyWindow ) {
180+ auto rect = this ->mProxyWindow ->contentItem ()->mapRectFromItem (
181+ this ->mItem ,
182+ this ->mUserRect .isEmpty () ? this ->mItem ->boundingRect () : this ->mUserRect .qrect ()
183+ );
184+
185+ this ->setWindowRect (rect);
186+ }
187+
188+ emit this ->anchoring ();
189+ }
190+
140191static PopupPositioner* POSITIONER = nullptr ; // NOLINT
141192
142193void PopupPositioner::reposition (PopupAnchor* anchor, QWindow* window, bool onlyIfDirty) {
@@ -148,15 +199,15 @@ void PopupPositioner::reposition(PopupAnchor* anchor, QWindow* window, bool only
148199 auto parentGeometry = parentWindow->geometry ();
149200 auto windowGeometry = window->geometry ();
150201
151- emit anchor->anchoring ();
202+ anchor->updateAnchor ();
152203 anchor->updatePlacement (parentGeometry.topLeft (), windowGeometry.size ());
153204
154205 if (onlyIfDirty && !anchor->isDirty ()) return ;
155206 anchor->markClean ();
156207
157208 auto adjustment = anchor->adjustment ();
158209 auto screenGeometry = parentWindow->screen ()->geometry ();
159- auto anchorRectGeometry = anchor->rect ().qrect ().translated (parentGeometry.topLeft ());
210+ auto anchorRectGeometry = anchor->windowRect ().qrect ().translated (parentGeometry.topLeft ());
160211
161212 auto anchorEdges = anchor->edges ();
162213 auto anchorGravity = anchor->gravity ();
0 commit comments