From 740b5c1fea56d1ec7b227b25e58a64355a8963f9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 24 Feb 2017 11:27:21 +0100 Subject: Fix UB in QWidgetResizeHandler::eventFilter Unconditional cast to a QMouseEvent while the event might also be a QKeyEvent. Change-Id: If5eb6fbad6e4440c167ff95298f51efde1834217 Reviewed-by: Marc Mutz --- src/widgets/widgets/qwidgetresizehandler.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/widgets/widgets') diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp index 016598849b..dc7353a6ca 100644 --- a/src/widgets/widgets/qwidgetresizehandler.cpp +++ b/src/widgets/widgets/qwidgetresizehandler.cpp @@ -112,9 +112,9 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) return false; } - QMouseEvent *e = (QMouseEvent*)ee; - switch (e->type()) { + switch (ee->type()) { case QEvent::MouseButtonPress: { + QMouseEvent *e = static_cast(ee); if (w->isMaximized()) break; if (!widget->rect().contains(widget->mapFromGlobal(e->globalPos()))) @@ -155,7 +155,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) case QEvent::MouseButtonRelease: if (w->isMaximized()) break; - if (e->button() == Qt::LeftButton) { + if (static_cast(ee)->button() == Qt::LeftButton) { moveResizeMode = false; buttonDown = false; widget->releaseMouse(); @@ -171,6 +171,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) case QEvent::MouseMove: { if (w->isMaximized()) break; + QMouseEvent *e = static_cast(ee); buttonDown = buttonDown && (e->buttons() & Qt::LeftButton); // safety, state machine broken! bool me = movingEnabled; movingEnabled = (me && o == widget && (buttonDown || moveResizeMode)); @@ -184,11 +185,11 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) } } break; case QEvent::KeyPress: - keyPressEvent((QKeyEvent*)e); + keyPressEvent(static_cast(ee)); break; case QEvent::ShortcutOverride: if (buttonDown) { - ((QKeyEvent*)ee)->accept(); + ee->accept(); return true; } break; -- cgit v1.2.3 From 8387d87bdcf7dfb359515f44b17f523791bc8edb Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 2 Mar 2017 08:55:35 +0100 Subject: QDialogButtonGroup: Fix removal of deleted buttons As the destroyed() signal is emitted from ~QObject, it is not allowed to use static_cast to a QAbstractButton on that pointer anymore. And the qobject_cast will also fail which will keep a dangling pointer in the hash. Change-Id: If0d22fcc30cde87e771e70914c3afb04ea207289 Reviewed-by: Marc Mutz --- src/widgets/widgets/qdialogbuttonbox.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/widgets/widgets') diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 23158cf82f..984669f29a 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -716,8 +716,7 @@ void QDialogButtonBox::removeButton(QAbstractButton *button) return; // Remove it from the standard button hash first and then from the roles - if (QPushButton *pushButton = qobject_cast(button)) - d->standardButtonHash.remove(pushButton); + d->standardButtonHash.remove(reinterpret_cast(button)); for (int i = 0; i < NRoles; ++i) { QList &list = d->buttonLists[i]; for (int j = 0; j < list.count(); ++j) { @@ -883,7 +882,7 @@ void QDialogButtonBoxPrivate::_q_handleButtonDestroyed() Q_Q(QDialogButtonBox); if (QObject *object = q->sender()) { QBoolBlocker skippy(internalRemove); - q->removeButton(static_cast(object)); + q->removeButton(reinterpret_cast(object)); } } -- cgit v1.2.3 From ad5565b6438cb239ad36722605a31b1006cd6478 Mon Sep 17 00:00:00 2001 From: Oleg Yadrov Date: Thu, 12 Jan 2017 10:03:10 -0800 Subject: Wide QMenu: fix size and position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes 2 issues related to wide menus: 1) Menu took on full screen height when menu width was larger than screen width; 2) On a multi-display system wide menu might appear on wrong monitor (not the one where show event was triggered). The idea is we limit parent menu and all its submenus within the screen where it was opened. Note that this patch fixes only geometry-related issues and there are also some style flaws which need to be addressed (for example, currently the text does not elide if it doesn’t fit to the menu’s width). Task-number: QTBUG-56917 Change-Id: I7e9ff4a48bf03060d76e34d33a13ad6cc890c133 Reviewed-by: Gabriel de Dietrich --- src/widgets/widgets/qmenu.cpp | 45 +++++++++++++++---------------------------- src/widgets/widgets/qmenu_p.h | 1 - 2 files changed, 16 insertions(+), 30 deletions(-) (limited to 'src/widgets/widgets') diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 2917083415..16f8734d7b 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -401,17 +401,6 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const itemsDirty = 0; } -QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen) -{ - Q_Q(QMenu); - QSize ret = screen.size(); - itemsDirty = true; - updateActionRects(screen); - const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); - ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw); - return ret; -} - int QMenuPrivate::getLastVisibleAction() const { //let's try to get the last visible action @@ -2265,7 +2254,8 @@ void QMenu::popup(const QPoint &p, QAction *atAction) else pos = p; - QSize size = sizeHint(); + const QSize menuSizeHint(sizeHint()); + QSize size = menuSizeHint; QRect screen; #ifndef QT_NO_GRAPHICSVIEW bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this); @@ -2278,13 +2268,11 @@ void QMenu::popup(const QPoint &p, QAction *atAction) bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen); // if the screens have very different geometries and the menu is too big, we have to recalculate - if (size.height() > screen.height() || size.width() > screen.width()) { - size = d->adjustMenuSizeForScreen(screen); - adjustToDesktop = true; - } - // Layout is not right, we might be able to save horizontal space - if (d->ncols >1 && size.height() < screen.height()) { - size = d->adjustMenuSizeForScreen(screen); + if ((size.height() > screen.height() || size.width() > screen.width()) || + // Layout is not right, we might be able to save horizontal space + (d->ncols >1 && size.height() < screen.height())) { + size.setWidth(qMin(menuSizeHint.width(), screen.width() - desktopFrame * 2)); + size.setHeight(qMin(menuSizeHint.height(), screen.height() - desktopFrame * 2)); adjustToDesktop = true; } @@ -2337,7 +2325,6 @@ void QMenu::popup(const QPoint &p, QAction *atAction) d->mousePopupPos = mouse; const bool snapToMouse = !d->causedPopup.widget && (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse)); - const QSize menuSize(sizeHint()); if (adjustToDesktop) { // handle popup falling "off screen" if (isRightToLeft()) { @@ -2371,7 +2358,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (pos.y() < screen.top() + desktopFrame) pos.setY(screen.top() + desktopFrame); - if (pos.y() + menuSize.height() - 1 > screen.bottom() - desktopFrame) { + if (pos.y() + menuSizeHint.height() - 1 > screen.bottom() - desktopFrame) { if (d->scroll) { d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown); int y = qMax(screen.y(),pos.y()); @@ -2384,29 +2371,29 @@ void QMenu::popup(const QPoint &p, QAction *atAction) } const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); QMenu *caused = qobject_cast(d_func()->causedPopup.widget); - if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) { + if (caused && caused->geometry().width() + menuSizeHint.width() + subMenuOffset < screen.width()) { QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction)); const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft()); parentActionRect.moveTopLeft(actionTopLeft); if (isRightToLeft()) { - if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset) + if ((pos.x() + menuSizeHint.width() > parentActionRect.left() - subMenuOffset) && (pos.x() < parentActionRect.right())) { - pos.rx() = parentActionRect.left() - menuSize.width(); + pos.rx() = parentActionRect.left() - menuSizeHint.width(); if (pos.x() < screen.x()) pos.rx() = parentActionRect.right(); - if (pos.x() + menuSize.width() > screen.x() + screen.width()) + if (pos.x() + menuSizeHint.width() > screen.x() + screen.width()) pos.rx() = screen.x(); } } else { if ((pos.x() < parentActionRect.right() + subMenuOffset) - && (pos.x() + menuSize.width() > parentActionRect.left())) + && (pos.x() + menuSizeHint.width() > parentActionRect.left())) { pos.rx() = parentActionRect.right(); - if (pos.x() + menuSize.width() > screen.x() + screen.width()) - pos.rx() = parentActionRect.left() - menuSize.width(); + if (pos.x() + menuSizeHint.width() > screen.x() + screen.width()) + pos.rx() = parentActionRect.left() - menuSizeHint.width(); if (pos.x() < screen.x()) - pos.rx() = screen.x() + screen.width() - menuSize.width(); + pos.rx() = screen.x() + screen.width() - menuSizeHint.width(); } } } diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 64291e842f..898fa3161b 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -311,7 +311,6 @@ public: mutable uint ncols : 4; //4 bits is probably plenty uint collapsibleSeparators : 1; uint toolTipsVisible : 1; - QSize adjustMenuSizeForScreen(const QRect & screen); int getLastVisibleAction() const; bool activationRecursionGuard; -- cgit v1.2.3 From f2e103296f9077a747e0dd43504e3e7630f56605 Mon Sep 17 00:00:00 2001 From: Oleg Yadrov Date: Fri, 13 Jan 2017 10:33:49 -0800 Subject: QMenu: make wide submenu appear on the same screen with its parent menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a multi-display system wide submenu might either appear on wrong screen or not appear at all (depending on the specific display configuration). Task-number: QTBUG-56917 Change-Id: I40013b0bee340a01ae1c08a5e074afa63da4dbfd Reviewed-by: Gabriel de Dietrich Reviewed-by: Błażej Szczygieł --- src/widgets/widgets/qmenu.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/widgets/widgets') diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 16f8734d7b..1925b58326 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -3501,11 +3501,22 @@ void QMenu::internalDelayedPopup() d->activeMenu->d_func()->causedPopup.widget = this; d->activeMenu->d_func()->causedPopup.action = d->currentAction; + QRect screen; +#ifndef QT_NO_GRAPHICSVIEW + bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this); + if (isEmbedded) + screen = d->popupGeometry(this); + else +#endif + screen = d->popupGeometry(QApplication::desktop()->screenNumber(pos())); + int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); const QRect actionRect(d->actionRect(d->currentAction)); - const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); + QPoint subMenuPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); + if (subMenuPos.x() > screen.right()) + subMenuPos.setX(QCursor::pos().x()); - d->activeMenu->popup(rightPos); + d->activeMenu->popup(subMenuPos); d->sloppyState.setSubMenuPopup(actionRect, d->currentAction, d->activeMenu); #if !defined(Q_OS_DARWIN) -- cgit v1.2.3 From d6330a19b29ebff359a6746250c78437dbcaf77d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 19 Dec 2016 10:34:32 +0100 Subject: Use QT_CONFIG(library) instead of QT_NO_LIBRARY For the windows file system engine, we add an extra macro to use library loading if configured to do so, but avoid it on WinRT, as none of the symbols would be found. We also QT_REQUIRE_CONFIG(library) in the library headers and exclude the sources from the build if library loading is disabled. This, in turn, makes it necessary to clean up some header inclusions. Change-Id: I2b152cb5b47a2658996b6f4702b038536a5704ec Reviewed-by: Oswald Buddenhagen --- src/widgets/widgets/qabstractscrollarea.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/widgets/widgets') diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 35b9851cad..5d3a054922 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -65,7 +65,6 @@ #include #endif #ifdef Q_OS_WIN -# include # include #endif -- cgit v1.2.3