From da76caa13ea471e5ea2eedc16e33009c3ab97b9a Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sun, 26 Mar 2023 19:14:39 +0200 Subject: [PATCH] NotificationArea: Correct painting position =========================================== QT has a open bug regarding filling the contents of a QMenu in aboutShow: https://bugreports.qt.io/browse/QTBUG-54421 This commit presents a work-around this bug. The two step procedure of this commit, forces a recalculation of the size from the slot and then manually moves the widget to the right position. --- src/Gui/NotificationArea.cpp | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Gui/NotificationArea.cpp b/src/Gui/NotificationArea.cpp index 325786ebbb..141d3580c4 100644 --- a/src/Gui/NotificationArea.cpp +++ b/src/Gui/NotificationArea.cpp @@ -510,6 +510,11 @@ public: pushedItems.push_front(item); } + QSize size() + { + return tableWidget->size(); + } + protected: /// creates the Notifications Widget QWidget* createWidget(QWidget* parent) override @@ -759,11 +764,42 @@ NotificationArea::NotificationArea(QWidget* parent) } static_cast(pImp->notificationaction)->synchroniseWidget(); - // the position of the action has already been calculated (for a non-synchronised widget), - // the size could be recalculated here, but not the position according to the previous size. - // This resize event forces this recalculation. - QResizeEvent re(pImp->menu->size(), pImp->menu->size()); + + // There is a Qt bug in not respecting a QMenu size when size changes in aboutToShow. + // + // https://bugreports.qt.io/browse/QTBUG-54421 + // https://forum.qt.io/topic/68765/how-to-update-geometry-on-qaction-visibility-change-in-qmenu-abouttoshow/3 + // + // None of this works + // pImp->menu->updateGeometry(); + // pImp->menu->adjustSize(); + // pImp->menu->ensurePolished(); + // this->updateGeometry(); + // this->adjustSize(); + // this->ensurePolished(); + + // This does correct the size + QSize size = static_cast(pImp->notificationaction)->size(); + QResizeEvent re(size, size); qApp->sendEvent(pImp->menu, &re); + + // This corrects the position of the menu + QTimer::singleShot(0, [&] { + QWidget* statusbar = static_cast(this->parent()); + QPoint statusbar_top_right = statusbar->mapToGlobal(statusbar->rect().topRight()); + QSize menusize = pImp->menu->size(); + QWidget* w = this; + QPoint button_pos = w->mapToGlobal(w->rect().topLeft()); + QPoint widget_pos; + if ((statusbar_top_right.x() - menusize.width()) > button_pos.x()) { + widget_pos = QPoint(button_pos.x(), statusbar_top_right.y() - menusize.height()); + } + else { + widget_pos = QPoint(statusbar_top_right.x() - menusize.width(), + statusbar_top_right.y() - menusize.height()); + } + pImp->menu->move(widget_pos); + }); });