core/popupanchor: reposition on popup size change

This commit is contained in:
outfoxxed 2024-07-24 00:44:42 -07:00
parent ebfa8ec448
commit 60388f10ca
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
3 changed files with 21 additions and 15 deletions

View file

@ -2,6 +2,7 @@
#include <qlogging.h> #include <qlogging.h>
#include <qobject.h> #include <qobject.h>
#include <qsize.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qwindow.h> #include <qwindow.h>
@ -11,7 +12,8 @@
bool PopupAnchorState::operator==(const PopupAnchorState& other) const { bool PopupAnchorState::operator==(const PopupAnchorState& other) const {
return this->rect == other.rect && this->edges == other.edges && this->gravity == other.gravity return this->rect == other.rect && this->edges == other.edges && this->gravity == other.gravity
&& this->adjustment == other.adjustment && this->anchorpoint == other.anchorpoint; && this->adjustment == other.adjustment && this->anchorpoint == other.anchorpoint
&& this->size == other.size;
} }
bool PopupAnchor::isDirty() const { bool PopupAnchor::isDirty() const {
@ -128,8 +130,9 @@ void PopupAnchor::setAdjustment(PopupAdjustment::Flags adjustment) {
emit this->adjustmentChanged(); emit this->adjustmentChanged();
} }
void PopupAnchor::updateAnchorpoint(const QPoint& anchorpoint) { void PopupAnchor::updatePlacement(const QPoint& anchorpoint, const QSize& size) {
this->state.anchorpoint = anchorpoint; this->state.anchorpoint = anchorpoint;
this->state.size = size;
} }
static PopupPositioner* POSITIONER = nullptr; // NOLINT static PopupPositioner* POSITIONER = nullptr; // NOLINT
@ -140,10 +143,15 @@ void PopupPositioner::reposition(PopupAnchor* anchor, QWindow* window, bool only
qFatal() << "Cannot reposition popup that does not have a transient parent."; qFatal() << "Cannot reposition popup that does not have a transient parent.";
} }
auto adjustment = anchor->adjustment();
auto screenGeometry = parentWindow->screen()->geometry();
auto parentGeometry = parentWindow->geometry(); auto parentGeometry = parentWindow->geometry();
auto windowGeometry = window->geometry(); auto windowGeometry = window->geometry();
anchor->updatePlacement(parentGeometry.topLeft(), windowGeometry.size());
if (onlyIfDirty && !anchor->isDirty()) return;
anchor->markClean();
auto adjustment = anchor->adjustment();
auto screenGeometry = parentWindow->screen()->geometry();
auto anchorRectGeometry = anchor->rect().qrect().translated(parentGeometry.topLeft()); auto anchorRectGeometry = anchor->rect().qrect().translated(parentGeometry.topLeft());
auto anchorEdges = anchor->edges(); auto anchorEdges = anchor->edges();
@ -160,10 +168,6 @@ void PopupPositioner::reposition(PopupAnchor* anchor, QWindow* window, bool only
: anchorEdges.testFlag(Edges::Bottom) ? anchorRectGeometry.bottom() : anchorEdges.testFlag(Edges::Bottom) ? anchorRectGeometry.bottom()
: anchorRectGeometry.center().y(); : anchorRectGeometry.center().y();
anchor->updateAnchorpoint({anchorX, anchorY});
if (onlyIfDirty && !anchor->isDirty()) return;
anchor->markClean();
auto calcEffectiveX = [&]() { auto calcEffectiveX = [&]() {
return anchorGravity.testFlag(Edges::Left) ? anchorX - windowGeometry.width() + 1 return anchorGravity.testFlag(Edges::Left) ? anchorX - windowGeometry.width() + 1
: anchorGravity.testFlag(Edges::Right) ? anchorX : anchorGravity.testFlag(Edges::Right) ? anchorX

View file

@ -8,6 +8,7 @@
#include <qobject.h> #include <qobject.h>
#include <qpoint.h> #include <qpoint.h>
#include <qqmlintegration.h> #include <qqmlintegration.h>
#include <qsize.h>
#include <qtclasshelpermacros.h> #include <qtclasshelpermacros.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qwindow.h> #include <qwindow.h>
@ -64,6 +65,7 @@ struct PopupAnchorState {
Edges::Flags gravity = Edges::Bottom | Edges::Right; Edges::Flags gravity = Edges::Bottom | Edges::Right;
PopupAdjustment::Flags adjustment = PopupAdjustment::Slide; PopupAdjustment::Flags adjustment = PopupAdjustment::Slide;
QPoint anchorpoint; QPoint anchorpoint;
QSize size;
}; };
///! Anchorpoint or positioner for popup windows. ///! Anchorpoint or positioner for popup windows.
@ -123,7 +125,7 @@ public:
[[nodiscard]] PopupAdjustment::Flags adjustment() const; [[nodiscard]] PopupAdjustment::Flags adjustment() const;
void setAdjustment(PopupAdjustment::Flags adjustment); void setAdjustment(PopupAdjustment::Flags adjustment);
void updateAnchorpoint(const QPoint& anchorpoint); void updatePlacement(const QPoint& anchorpoint, const QSize& size);
signals: signals:
void windowChanged(); void windowChanged();

View file

@ -26,12 +26,12 @@ ProxyPopupWindow::ProxyPopupWindow(QObject* parent): ProxyWindowBase(parent) {
void ProxyPopupWindow::completeWindow() { void ProxyPopupWindow::completeWindow() {
this->ProxyWindowBase::completeWindow(); this->ProxyWindowBase::completeWindow();
QObject::connect(
this->window, // clang-format off
&QWindow::visibleChanged, QObject::connect(this->window, &QWindow::visibleChanged, this, &ProxyPopupWindow::onVisibleChanged);
this, QObject::connect(this->window, &QWindow::widthChanged, this, &ProxyPopupWindow::reposition);
&ProxyPopupWindow::onVisibleChanged QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyPopupWindow::reposition);
); // clang-format on
this->window->setFlag(Qt::ToolTip); this->window->setFlag(Qt::ToolTip);
} }