From bace97aa5ba382191ccc616b33bbb11fe2b72f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 11 Feb 2020 16:31:10 +0100 Subject: Improve error message when mixing incompatible Qt library versions The implementation of the check has been moved to a single helper function. The reason for doing this check in QWidgetPrivate as well, when it's already done in QObjectPrivate, is to catch incompatible libraries where QtWidgets is the odd one out, e.g.: QtSomeModule 5.15.0 -> QtWidget 5.15.1 -> QtCore 5.15.0 Technically any non-final subclass of QObjectPrivate should have this check. Change-Id: Ia74064ad27de7335040a6d6b37d11574f818c878 Reviewed-by: Thiago Macieira --- src/widgets/kernel/qwidget.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index fdad879209..4ca2e996ad 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -191,15 +191,7 @@ QWidgetPrivate::QWidgetPrivate(int version) return; } -#ifdef QT_BUILD_INTERNAL - // Don't check the version parameter in internal builds. - // This allows incompatible versions to be loaded, possibly for testing. - Q_UNUSED(version); -#else - if (Q_UNLIKELY(version != QObjectPrivateVersion)) - qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)", - version, QObjectPrivateVersion); -#endif + checkForIncompatibleLibraryVersion(version); isWidget = true; memset(high_attributes, 0, sizeof(high_attributes)); -- cgit v1.2.3 From 6a56862a2214e4ff1743fc3ce97427a30475b48a Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 12 Feb 2020 15:13:57 +0100 Subject: QAbstractItemView: do not request illegal model indexes If a model is empty, there is no index (0, 0); requesting it is undefined behavior. Rather than protecting the calls with checks on rowCount/columnCount, remove the Q_ASSERTs altogether: they're trying to do some basic sanity checks on the model, something that doesn't belong to a view (but, say, to QAbstractItemModelTester). Change-Id: I0ea25604fdcf524a10f5922a03a4d0700447f6a7 Reviewed-by: Andre Somers Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qabstractitemview.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index b07faf8be4..c3f8dd894e 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -705,15 +705,6 @@ void QAbstractItemView::setModel(QAbstractItemModel *model) } d->model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel()); - // These asserts do basic sanity checking of the model - Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0), - "QAbstractItemView::setModel", - "A model should return the exact same index " - "(including its internal id/pointer) when asked for it twice in a row."); - Q_ASSERT_X(!d->model->index(0,0).parent().isValid(), - "QAbstractItemView::setModel", - "The parent of a top level index should be invalid"); - if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) { connect(d->model, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); -- cgit v1.2.3 From 882f340f62b8dc34633f5f296be12243b6e8999d Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 14 Feb 2020 17:11:13 +0100 Subject: Deprecate QTabletEvent::device() in favor of deviceType() The idea is to reserve device() to return a pointer to a QInputDevice in the future, which is in sync with QQuickPointerEvent::device() and with QTouchEvent::device(). Change-Id: Ifda6e8aea72d5121955b31bdcbd91bf1bfa4cec4 Reviewed-by: Allan Sandfeld Jensen --- src/widgets/kernel/qapplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 129569a466..2d7919e874 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3299,7 +3299,7 @@ QT_WARNING_POP bool eventAccepted = tablet->isAccepted(); while (w) { QTabletEvent te(tablet->type(), relpos, tablet->globalPosF(), - tablet->device(), tablet->pointerType(), + tablet->deviceType(), tablet->pointerType(), tablet->pressure(), tablet->xTilt(), tablet->yTilt(), tablet->tangentialPressure(), tablet->rotation(), tablet->z(), tablet->modifiers(), tablet->uniqueId(), tablet->button(), tablet->buttons()); -- cgit v1.2.3 From e2e596c0c5726212cc41a8a262b2a7ecd80c4500 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 17 Feb 2020 12:38:13 +0100 Subject: Windows style: Turn off SH_EtchDisabledText in dark mode It does not look good in dark mode. Task-number: QTBUG-82197 Change-Id: I043c7d66d962e4c82581f37e52f279d4f4ed8c7e Reviewed-by: Oliver Wolff --- src/widgets/styles/qwindowsstyle.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 8eb24d7557..4965d146b0 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -548,6 +548,8 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid switch (hint) { case SH_EtchDisabledText: + ret = d_func()->isDarkMode() ? 0 : 1; + break; case SH_Slider_SnapToValue: case SH_PrintDialog_RightAlignButtons: case SH_FontDialog_SelectAssociatedText: -- cgit v1.2.3 From 9029c5586460950b4fa6773a5d08c67e5ba16e8a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 13 Feb 2020 15:33:00 +0100 Subject: Send the LanguageChange event to all top level windows, not just widgets By sending it to all top level windows it will make it possible for non widget based controls to listen for this event if it cares about it so it can handle translation updates as appropriate. Task-number: QTBUG-78141 Task-number: QTBUG-82020 Change-Id: I8f35cdcccd81a199ff780c3f4f3d2c663480d638 Reviewed-by: Mitch Curtis --- src/widgets/kernel/qapplication.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 2d7919e874..f49461b2d0 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1904,9 +1904,12 @@ bool QApplication::event(QEvent *e) } if(e->type() == QEvent::LanguageChange) { + // QGuiApplication::event does not account for the cases where + // there is a top level widget without a window handle. So they + // need to have the event posted here const QWidgetList list = topLevelWidgets(); for (auto *w : list) { - if (!(w->windowType() == Qt::Desktop)) + if (!w->windowHandle() && (w->windowType() != Qt::Desktop)) postEvent(w, new QEvent(QEvent::LanguageChange)); } } -- cgit v1.2.3 From 045a143c2c72c72f264dd40f5da2994e647dc0ee Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Feb 2020 09:44:35 +0100 Subject: Fix RollEffect misplacements in High DPI setups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the correct screen as parent of the roll effect widget. Fixes: QTBUG-82011 Change-Id: I25c163cb2e4c038e60ceced702a1ea6c18aa5424 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/widgets/qeffects.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp index 7069ef0368..fe1bdac644 100644 --- a/src/widgets/widgets/qeffects.cpp +++ b/src/widgets/widgets/qeffects.cpp @@ -54,6 +54,15 @@ QT_BEGIN_NAMESPACE +static QWidget *effectParent(const QWidget* w) +{ + const int screenNumber = w ? QGuiApplication::screens().indexOf(w->screen()) : 0; + QT_WARNING_PUSH // ### Qt 6: Find a replacement for QDesktopWidget::screen() + QT_WARNING_DISABLE_DEPRECATED + return QApplication::desktop()->screen(screenNumber); + QT_WARNING_POP +} + /* Internal class QAlphaWidget. @@ -98,12 +107,9 @@ static QAlphaWidget* q_blend = 0; /* Constructs a QAlphaWidget. */ -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED // ### Qt 6: Find a replacement for QDesktopWidget::screen() QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) - : QWidget(QApplication::desktop()->screen(QDesktopWidgetPrivate::screenNumber(w)), f) + : QWidget(effectParent(w), f) { -QT_WARNING_POP #ifndef Q_OS_WIN setEnabled(false); #endif @@ -383,7 +389,7 @@ static QRollEffect* q_roll = 0; Construct a QRollEffect widget. */ QRollEffect::QRollEffect(QWidget* w, Qt::WindowFlags f, DirFlags orient) - : QWidget(0, f), orientation(orient) + : QWidget(effectParent(w), f), orientation(orient) { #ifndef Q_OS_WIN setEnabled(false); -- cgit v1.2.3 From 1576f81baa8a1c992a005397edfc5d6f9e1b44c1 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Mon, 17 Feb 2020 16:13:15 +0200 Subject: Android: QFileDialog check isLocalFile() with static functions The functions below try to return the selected QUrl string with toLocalFile(), however in case of Android "content" Uri isLocalFile() is false, thus we end up with empty path. This checks is QUrl isLocalFile() otherwise return QUrl::toString(). * QString QFileDialog::getSaveFileName() * QString QFileDialog::getOpenFileName() * QStringList QFileDialog::getOpenFileNames() * QString QFileDialog::getExistingDirectory() Change-Id: If7eefb3a067d4bd09849807e60554e0ded507f19 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/dialogs/qfiledialog.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 7c2c202cd6..af2007a4d1 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2193,8 +2193,12 @@ QString QFileDialog::getOpenFileName(QWidget *parent, Options options) { const QStringList schemes = QStringList(QStringLiteral("file")); - const QUrl selectedUrl = getOpenFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes); - return selectedUrl.toLocalFile(); + const QUrl selectedUrl = getOpenFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter, + selectedFilter, options, schemes); + if (selectedUrl.isLocalFile() || selectedUrl.isEmpty()) + return selectedUrl.toLocalFile(); + else + return selectedUrl.toString(); } /*! @@ -2303,11 +2307,16 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, Options options) { const QStringList schemes = QStringList(QStringLiteral("file")); - const QList selectedUrls = getOpenFileUrls(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes); + const QList selectedUrls = getOpenFileUrls(parent, caption, QUrl::fromLocalFile(dir), + filter, selectedFilter, options, schemes); QStringList fileNames; fileNames.reserve(selectedUrls.size()); - for (const QUrl &url : selectedUrls) - fileNames << url.toLocalFile(); + for (const QUrl &url : selectedUrls) { + if (url.isLocalFile() || url.isEmpty()) + fileNames << url.toLocalFile(); + else + fileNames << url.toString(); + } return fileNames; } @@ -2549,8 +2558,12 @@ QString QFileDialog::getSaveFileName(QWidget *parent, Options options) { const QStringList schemes = QStringList(QStringLiteral("file")); - const QUrl selectedUrl = getSaveFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes); - return selectedUrl.toLocalFile(); + const QUrl selectedUrl = getSaveFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter, + selectedFilter, options, schemes); + if (selectedUrl.isLocalFile() || selectedUrl.isEmpty()) + return selectedUrl.toLocalFile(); + else + return selectedUrl.toString(); } /*! @@ -2657,8 +2670,12 @@ QString QFileDialog::getExistingDirectory(QWidget *parent, Options options) { const QStringList schemes = QStringList(QStringLiteral("file")); - const QUrl selectedUrl = getExistingDirectoryUrl(parent, caption, QUrl::fromLocalFile(dir), options, schemes); - return selectedUrl.toLocalFile(); + const QUrl selectedUrl = + getExistingDirectoryUrl(parent, caption, QUrl::fromLocalFile(dir), options, schemes); + if (selectedUrl.isLocalFile() || selectedUrl.isEmpty()) + return selectedUrl.toLocalFile(); + else + return selectedUrl.toString(); } /*! -- cgit v1.2.3 From 8c3cc07bf5254cb91b37a0000191871e9e32014e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 17 Feb 2020 15:08:58 +0100 Subject: widgets: Translate QWindow move events into widget relative position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a widget backed by a QWindow is moved we need to translate the window geometry into a position relative to the parent widget. In most cases this was incidentally working due to widgets backed by QWindows always having QWindow parents too, so the QWindow position was applicable to the widget as well. But when Qt::WA_DontCreateNativeAncestors is used this is no longer the case, and we would end up with a widget geometry that included the parent positions all the way up to the next native widget. The updatePos() function has been squashed into handleMoveEvent(), since we need to ensure the position in the move event sent to the widget is correct as well. Change-Id: I55894ad7ab42a6d4d65e446a332ecdd7dcdcc263 Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qwidgetwindow.cpp | 37 +++++++++++++++++++++--------------- src/widgets/kernel/qwidgetwindow_p.h | 1 - 2 files changed, 22 insertions(+), 16 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 904067afda..4ba5469e9d 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -727,19 +727,6 @@ bool QWidgetWindow::updateSize() return changed; } -bool QWidgetWindow::updatePos() -{ - bool changed = false; - if (m_widget->testAttribute(Qt::WA_OutsideWSRange)) - return changed; - if (m_widget->data->crect.topLeft() != geometry().topLeft()) { - changed = true; - m_widget->data->crect.moveTopLeft(geometry().topLeft()); - } - updateMargins(); - return changed; -} - void QWidgetWindow::updateMargins() { const QMargins margins = frameMargins(); @@ -800,8 +787,28 @@ void QWidgetWindow::updateNormalGeometry() void QWidgetWindow::handleMoveEvent(QMoveEvent *event) { - if (updatePos()) - QGuiApplication::forwardEvent(m_widget, event); + if (m_widget->testAttribute(Qt::WA_OutsideWSRange)) + return; + + auto oldPosition = m_widget->data->crect.topLeft(); + auto newPosition = geometry().topLeft(); + + if (!m_widget->isTopLevel()) { + if (auto *nativeParent = m_widget->nativeParentWidget()) + newPosition = m_widget->parentWidget()->mapFrom(nativeParent, newPosition); + } + + bool changed = newPosition != oldPosition; + + if (changed) + m_widget->data->crect.moveTopLeft(newPosition); + + updateMargins(); // FIXME: Only do when changed? + + if (changed) { + QMoveEvent widgetEvent(newPosition, oldPosition); + QGuiApplication::forwardEvent(m_widget, &widgetEvent, event); + } } void QWidgetWindow::handleResizeEvent(QResizeEvent *event) diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index 80a345465d..5689e129c3 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -125,7 +125,6 @@ private slots: private: void repaintWindow(); bool updateSize(); - bool updatePos(); void updateMargins(); void updateNormalGeometry(); -- cgit v1.2.3 From 1821f5163d160ccd5faf9c4b995e72a7ed762c9a Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 19 Feb 2020 14:11:12 +0100 Subject: Fix font and palette propagation for themed children created at runtime Widgets have a default palette and font that is influenced by several factors: theme, style, QApplication-wide overrides, and the parent's. If an application sets a font or palette on a parent, then widgets inherit those settings, no matter when they are added to the parent. The bug is that this is not true for widgets that have an application- wide override defined by the platform theme. For those, we need to merge parent palette and font attributes with the theme, and this is currently not done correctly, as the respective masks are not merged and inherited. This change fixes this for fonts and palettes. Children are inheriting their parent's inheritance masks, combined with the mask for the attributes set explicitly on the parent. This makes the font and palette resolving code correctly adopt those attributes that are set explicily, while leaving everything else as per the theme override. The test verifies that this works for children and grand children added to a widget that has a palette or font set, both when themed and unthemed. Children with own entries don't inherit from parent. The QFont::resetFont test had to be changed, as it was testing the wrong behavior. If the child would be added to the parent before the font property was set, then the test would have failed. Since this change makes sure that children inherit fonts in the same way, no matter on when they are added to their parent, the test is now modified to cover both cases, and ensures that they return identical results. [ChangeLog][QtWidgets][QWidget] Fonts and palette settings are inherited by children from their parents even if the children have application- wide platform theme overrides. Change-Id: I179a652b735e85bba3fafc30098d08d61684f488 Fixes: QTBUG-82125 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Qt CI Bot Reviewed-by: Vitaly Fanaskov --- src/widgets/kernel/qwidget.cpp | 11 ++++++++++- src/widgets/kernel/qwidget_p.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 4ca2e996ad..2da967485b 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -150,6 +150,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #endif , directFontResolveMask(0) , inheritedFontResolveMask(0) + , directPaletteResolveMask(0) , inheritedPaletteResolveMask(0) , leftmargin(0) , topmargin(0) @@ -1845,7 +1846,9 @@ void QWidgetPrivate::propagatePaletteChange() if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedPaletteResolveMask = 0; } - int mask = data.pal.resolve() | inheritedPaletteResolveMask; + + directPaletteResolveMask = data.pal.resolve(); + auto mask = directPaletteResolveMask | inheritedPaletteResolveMask; const bool useStyleSheetPropagationInWidgetStyles = QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles); @@ -10452,6 +10455,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet) && (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) { + // if the parent has a font set or inherited, then propagate the mask to the new child + if (parent) { + const auto pd = parent->d_func(); + d->inheritedFontResolveMask = pd->directFontResolveMask | pd->inheritedFontResolveMask; + d->inheritedPaletteResolveMask = pd->directPaletteResolveMask | pd->inheritedPaletteResolveMask; + } d->resolveFont(); d->resolvePalette(); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 6915782cb3..2597017318 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -672,6 +672,7 @@ public: // Other variables. uint directFontResolveMask; uint inheritedFontResolveMask; + decltype(std::declval().resolve()) directPaletteResolveMask; uint inheritedPaletteResolveMask; short leftmargin; short topmargin; -- cgit v1.2.3 From 4e1c41a26eaa51ebb133e9c846e8e93bbe318a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 20 Feb 2020 11:25:49 +0100 Subject: QStyle: Use primary screen DPI as default DPI Change d603ee68 made the default DPI be 96, for cases where a style option is not provided. This causes inconsistencies, since there are in fact several cases where QStyle API is called without a style option. Restore historical Qt behavior of using the primary screen DPI. Single-screen systems should now be consistent, as before. Task-number: QTBUG-82356 Change-Id: I849934ca2e5604b9fb2f045ed4f6058f3e0426ff Reviewed-by: Friedemann Kleint --- src/widgets/styles/qstylehelper.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index 9477ca86da..6016224faa 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -101,7 +101,13 @@ Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option) if (option) return option->fontMetrics.fontDpi(); + // Fall back to historical Qt behavior: hardocded 72 DPI on mac, + // primary screen DPI on other platforms. +#ifdef Q_OS_DARWIN return qstyleBaseDpi; +#else + return qt_defaultDpiX(); +#endif } Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi) -- cgit v1.2.3 From 3c20b9b97377172dd1fc384bd28d3c7dbff0f523 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 17 Feb 2020 15:32:39 +0100 Subject: QGraphicsProxyWidgets: document that using OpenGL comes with limitations The documentation already states that high-performance scenarios are not a usecase that mixes well with QGraphicsProxyWidget. However, we can generally not test or support all combinations of widgets and styles with an OpenGL viewport. That Qt's basic framework code has to be graphicsview aware is already unfortunate enough; adding more special checks all over the place hurts maintainability, makes the general usecase slower, and poorly serves use-cases that are beyond of what QGraphicsProxyWidget was designed for. Change-Id: Iff43ead292240f7b068dcf9206bb3bee3031b1dc Fixes: QTBUG-63687 Reviewed-by: Friedemann Kleint Reviewed-by: Paul Wicking --- src/widgets/graphicsview/qgraphicsproxywidget.cpp | 4 +++- src/widgets/graphicsview/qgraphicsview.cpp | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index a9a57c57fa..fe3475e6bb 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -183,7 +183,9 @@ QT_BEGIN_NAMESPACE \warning This class is provided for convenience when bridging QWidgets and QGraphicsItems, it should not be used for - high-performance scenarios. + high-performance scenarios. In particular, embedding widgets into a scene + that is then displayed through a QGraphicsView that uses an OpenGL viewport + will not work for all combinations. \sa QGraphicsScene::addWidget(), QGraphicsWidget */ diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 686b41960a..7ac9aebfe6 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -123,6 +123,10 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < \image graphicsview-view.png + \note Using an OpenGL viewport limits the ability to use QGraphicsProxyWidget. + Not all combinations of widgets and styles can be supported with such a setup. + You should carefully test your UI and make the necessary adjustments. + \sa QGraphicsScene, QGraphicsItem, QGraphicsSceneEvent */ -- cgit v1.2.3 From 1559c328d536ceb8b7f78892a60aced4716b40b6 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 31 Jan 2020 20:51:03 +0100 Subject: QTableWidget: avoid complete redrawing when an item is removed When an item gets removed from QTableWidget, the dataChanged() signal is sent out with an invalid index. This triggers a complete repaint which is not needed since only one cell is changed. Fix it by retrieving the model index *before* the internal structure is cleaned for the given item since otherwise index() will no longer find the item and return an invalid index. Change-Id: Ia0d82edb6b44118e8a1546904250ca29d9c45140 Reviewed-by: Friedemann Kleint --- src/widgets/itemviews/qtablewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 60abd02564..7b1f1a1caf 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -247,8 +247,8 @@ void QTableModel::removeItem(QTableWidgetItem *item) { int i = tableItems.indexOf(item); if (i != -1) { - tableItems[i] = 0; QModelIndex idx = index(item); + tableItems[i] = nullptr; emit dataChanged(idx, idx); return; } -- cgit v1.2.3 From 835e18d9ff79867f508fc8baac7fcc5bb4efc0cb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 20 Feb 2020 11:37:41 +0100 Subject: Fix wrong DPI used by QStyle::pixelMetric() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass on the option or the widget in order to ensure usage of the correct DPI for High DPI scaling. Task-number: QTBUG-82356 Change-Id: I5df903a83f88adebd143e514e2fead367d39f015 Reviewed-by: Morten Johan Sørvig --- src/widgets/dialogs/qcolordialog.cpp | 3 +- src/widgets/dialogs/qwizard.cpp | 7 ++-- src/widgets/graphicsview/qgraphicslayout_p.h | 4 +-- .../graphicsview/qgraphicslayoutstyleinfo.cpp | 4 ++- src/widgets/graphicsview/qgraphicswidget.cpp | 2 +- src/widgets/itemviews/qitemdelegate.cpp | 2 +- src/widgets/itemviews/qlistview.cpp | 7 ++-- src/widgets/styles/qcommonstyle.cpp | 42 +++++++++++----------- src/widgets/styles/qfusionstyle.cpp | 8 ++--- src/widgets/styles/qpixmapstyle.cpp | 4 +-- src/widgets/widgets/qcalendarwidget.cpp | 4 ++- src/widgets/widgets/qcombobox_p.h | 2 +- src/widgets/widgets/qcommandlinkbutton.cpp | 8 +++-- src/widgets/widgets/qfocusframe.cpp | 12 +++---- src/widgets/widgets/qgroupbox.cpp | 6 ++-- src/widgets/widgets/qlineedit.cpp | 2 +- src/widgets/widgets/qmenu.cpp | 2 +- src/widgets/widgets/qmenubar.cpp | 2 +- src/widgets/widgets/qtoolbarextension.cpp | 4 ++- src/widgets/widgets/qwidgettextcontrol.cpp | 2 +- 20 files changed, 71 insertions(+), 56 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index d00a600424..9a34a4a9b6 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -346,7 +346,8 @@ void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect) const QPalette & g = palette(); QStyleOptionFrame opt; - int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + opt.initFrom(this); + int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt); opt.lineWidth = dfw; opt.midLineWidth = 1; opt.rect = rect.adjusted(b, b, -b, -b); diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 0295241a74..a50dc13bc1 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -64,6 +64,7 @@ # include "qshortcut.h" #endif #include "qstyle.h" +#include "qstyleoption.h" #include "qvarlengtharray.h" #if defined(Q_OS_MACX) #include @@ -897,7 +898,9 @@ QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage() QWizardLayoutInfo info; - const int layoutHorizontalSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + QStyleOption option; + option.initFrom(q); + const int layoutHorizontalSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, &option); info.topLevelMarginLeft = style->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, q); info.topLevelMarginRight = style->pixelMetric(QStyle::PM_LayoutRightMargin, 0, q); info.topLevelMarginTop = style->pixelMetric(QStyle::PM_LayoutTopMargin, 0, q); @@ -909,7 +912,7 @@ QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage() info.hspacing = (layoutHorizontalSpacing == -1) ? style->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Horizontal) : layoutHorizontalSpacing; - info.vspacing = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing); + info.vspacing = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing, &option); info.buttonSpacing = (layoutHorizontalSpacing == -1) ? style->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal) : layoutHorizontalSpacing; diff --git a/src/widgets/graphicsview/qgraphicslayout_p.h b/src/widgets/graphicsview/qgraphicslayout_p.h index 0d91151e22..9e86ae2f76 100644 --- a/src/widgets/graphicsview/qgraphicslayout_p.h +++ b/src/widgets/graphicsview/qgraphicslayout_p.h @@ -87,8 +87,8 @@ public: Q_ASSERT(style); if (widget) //### m_styleOption.initFrom(widget); - m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); - m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing); + m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, &m_styleOption); + m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing, &m_styleOption); } inline void invalidate() { m_valid = false; m_style = nullptr; m_widget = nullptr; } diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp index da2510a8cb..7759cfe757 100644 --- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp +++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp @@ -80,7 +80,9 @@ qreal QGraphicsLayoutStyleInfo::perItemSpacing(QLayoutPolicy::ControlType contro qreal QGraphicsLayoutStyleInfo::spacing(Qt::Orientation orientation) const { Q_ASSERT(style()); - return style()->pixelMetric(orientation == Qt::Horizontal ? QStyle::PM_LayoutHorizontalSpacing : QStyle::PM_LayoutVerticalSpacing); + return style()->pixelMetric(orientation == Qt::Horizontal + ? QStyle::PM_LayoutHorizontalSpacing : QStyle::PM_LayoutVerticalSpacing, + &m_styleOption); } qreal QGraphicsLayoutStyleInfo::windowMargin(Qt::Orientation orientation) const diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index cf041b9817..1bb668e74c 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -615,7 +615,7 @@ void QGraphicsWidget::unsetWindowFrameMargins() QStyleOptionTitleBar bar; d->initStyleOptionTitleBar(&bar); QStyle *style = this->style(); - qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth); + const qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar); qreal titleBarHeight = d->titleBarHeight(bar); setWindowFrameMargins(margin, titleBarHeight, margin, margin); } else { diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index 460764f1b8..f048b1b7e8 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -1122,7 +1122,7 @@ QRect QItemDelegate::textRectangle(QPainter * /*painter*/, const QRect &rect, QSizeF fpSize = d->doTextLayout(rect.width()); const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height())); // ###: textRectangle should take style option as argument - const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1; return QRect(0, 0, size.width() + 2 * textMargin, size.height()); } diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 62fffc17df..c3720aef73 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1728,8 +1728,11 @@ void QListViewPrivate::prepareItemsLayout() layoutBounds = QRect(QPoint(), q->maximumViewportSize()); int frameAroundContents = 0; - if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) - frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2; + if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) { + QStyleOption option; + option.initFrom(q); + frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option) * 2; + } // maximumViewportSize() already takes scrollbar into account if policy is // Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 9fa00b8d3f..ea42749846 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -431,7 +431,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q QIcon::Active, QIcon::Off); } - int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize); + const int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize, opt); QIcon::Mode mode = opt->state & State_Enabled ? (opt->state & State_Raised ? QIcon::Active : QIcon::Normal) : QIcon::Disabled; @@ -477,7 +477,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q if (const QStyleOptionFrame *frame = qstyleoption_cast(opt)) { int lw = frame->lineWidth; if (lw <= 0) - lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth); + lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, opt); qDrawShadePanel(p, frame->rect, frame->palette, false, lw); } @@ -563,8 +563,8 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q int bsx = 0; int bsy = 0; if (opt->state & State_Sunken) { - bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); - bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt); } p->save(); p->translate(sx + bsx, sy + bsy); @@ -994,7 +994,7 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int } if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator) - bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin); + bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option) - 2 * textMargin); const int lineWidth = bounds.width(); const QSizeF size = viewItemTextLayout(textLayout, lineWidth); @@ -1240,7 +1240,7 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w if (!opt->icon.isNull()) { QSize iconSize = opt->iconSize; if (!iconSize.isValid()) { - int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize); + int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize, opt); iconSize = QSize(iconExtent, iconExtent); } QSize tabIconSize = opt->icon.actualSize(iconSize, @@ -1490,7 +1490,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) alignment |= Qt::TextHideMnemonic; - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt); QPixmap pix = mbi->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); if (!pix.isNull()) proxy()->drawItemPixmap(p,mbi->rect, alignment, pix); @@ -1646,7 +1646,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (const QStyleOptionHeader *header = qstyleoption_cast(opt)) { QRect rect = header->rect; if (!header->icon.isNull()) { - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt); QPixmap pixmap = header->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); int pixw = pixmap.width() / pixmap.devicePixelRatio(); @@ -3857,8 +3857,8 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl if (opt->activeSubControls & QStyle::SC_MdiCloseButton && (opt->state & State_Sunken)) { btnOpt.state |= State_Sunken; btnOpt.state &= ~State_Raised; - bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); - bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt); } else { btnOpt.state |= State_Raised; btnOpt.state &= ~State_Sunken; @@ -3874,8 +3874,8 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl if (opt->activeSubControls & QStyle::SC_MdiNormalButton && (opt->state & State_Sunken)) { btnOpt.state |= State_Sunken; btnOpt.state &= ~State_Raised; - bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); - bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt); } else { btnOpt.state |= State_Raised; btnOpt.state &= ~State_Sunken; @@ -3891,8 +3891,8 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl if (opt->activeSubControls & QStyle::SC_MdiMinButton && (opt->state & State_Sunken)) { btnOpt.state |= State_Sunken; btnOpt.state &= ~State_Raised; - bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); - bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt); } else { btnOpt.state |= State_Raised; btnOpt.state &= ~State_Sunken; @@ -4775,12 +4775,12 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid } else if (widget) { isWindow = widget->isWindow(); } - ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin); + ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin, opt); } break; case PM_LayoutHorizontalSpacing: case PM_LayoutVerticalSpacing: - ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing); + ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing, opt); break; case PM_DefaultTopLevelMargin: @@ -4931,7 +4931,7 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, } else { h = mi->fontMetrics.height() + 8; if (!mi->icon.isNull()) { - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt); h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4); } } @@ -4957,7 +4957,7 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_ComboBox: if (const QStyleOptionComboBox *cmb = qstyleoption_cast(opt)) { int fw = cmb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0; - const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1); + const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin, opt) + 1); // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins... int other = qMax(23, 2*textMargins + proxy()->pixelMetric(QStyle::PM_ScrollBarExtent, opt, widget)); sz = QSize(sz.width() + fw + other, sz.height() + fw); @@ -5207,8 +5207,8 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget if (widget) { if(QStyleHintReturnMask *mask = qstyleoption_cast(hret)) { mask->region = widget->rect(); - int vmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin), - hmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin); + const int vmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt); + const int hmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt); mask->region -= QRect(widget->rect().adjusted(hmargin, vmargin, -hmargin, -vmargin)); } } @@ -5221,7 +5221,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget ret = true; if(QStyleHintReturnMask *mask = qstyleoption_cast(hret)) { mask->region = opt->rect; - int margin = proxy()->pixelMetric(PM_DefaultFrameWidth) * 2; + const int margin = proxy()->pixelMetric(PM_DefaultFrameWidth, opt) * 2; mask->region -= opt->rect.adjusted(margin, margin, -margin, -margin); } } diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 1646ec7583..548469068f 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -3347,8 +3347,8 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom switch (subControl) { case SC_SliderHandle: { if (slider->orientation == Qt::Horizontal) { - rect.setHeight(proxy()->pixelMetric(PM_SliderThickness)); - rect.setWidth(proxy()->pixelMetric(PM_SliderLength)); + rect.setHeight(proxy()->pixelMetric(PM_SliderThickness, option)); + rect.setWidth(proxy()->pixelMetric(PM_SliderLength, option)); int centerY = slider->rect.center().y() - rect.height() / 2; if (slider->tickPosition & QSlider::TicksAbove) centerY += tickSize; @@ -3356,8 +3356,8 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom centerY -= tickSize; rect.moveTop(centerY); } else { - rect.setWidth(proxy()->pixelMetric(PM_SliderThickness)); - rect.setHeight(proxy()->pixelMetric(PM_SliderLength)); + rect.setWidth(proxy()->pixelMetric(PM_SliderThickness, option)); + rect.setHeight(proxy()->pixelMetric(PM_SliderLength, option)); int centerX = slider->rect.center().x() - rect.width() / 2; if (slider->tickPosition & QSlider::TicksAbove) centerX += tickSize; diff --git a/src/widgets/styles/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp index 05e8467528..7cc32b2039 100644 --- a/src/widgets/styles/qpixmapstyle.cpp +++ b/src/widgets/styles/qpixmapstyle.cpp @@ -1003,13 +1003,13 @@ QSize QPixmapStyle::pushButtonSizeFromContents(const QStyleOption *option, return d->computeSize(desc, w, h); } -QSize QPixmapStyle::lineEditSizeFromContents(const QStyleOption *, +QSize QPixmapStyle::lineEditSizeFromContents(const QStyleOption *option, const QSize &contentsSize, const QWidget *) const { Q_D(const QPixmapStyle); const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled); - const int border = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth); + const int border = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, option); int w = contentsSize.width() + border + desc.margins.left() + desc.margins.right(); int h = contentsSize.height() + border + desc.margins.top() + desc.margins.bottom(); diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 8593001f8b..da958a61dc 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -2232,7 +2232,9 @@ QSize QCalendarWidget::minimumSizeHint() const int rows = 7; int cols = 8; - const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) * 2; + QStyleOption option; + option.initFrom(this); + const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option) + 1) * 2; if (horizontalHeaderFormat() == QCalendarWidget::NoHorizontalHeader) { rows = 6; diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 5967776a61..8d660c11e1 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -146,7 +146,7 @@ public: setAttribute(Qt::WA_NoMousePropagation); } QSize sizeHint() const override { - return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight)); + return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, nullptr, this)); } protected: diff --git a/src/widgets/widgets/qcommandlinkbutton.cpp b/src/widgets/widgets/qcommandlinkbutton.cpp index 2b9258fd91..e9462ed229 100644 --- a/src/widgets/widgets/qcommandlinkbutton.cpp +++ b/src/widgets/widgets/qcommandlinkbutton.cpp @@ -208,7 +208,7 @@ bool QCommandLinkButtonPrivate::usingVistaStyle() const //### This is a hack to detect if we are indeed running Vista style themed and not in classic // When we add api to query for this, we should change this implementation to use it. return q->style()->inherits("QWindowsVistaStyle") - && !q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal); + && q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, nullptr) == 0; } void QCommandLinkButtonPrivate::init() @@ -355,8 +355,10 @@ void QCommandLinkButton::paintEvent(QPaintEvent *) option.icon = QIcon(); //we draw this ourselves QSize pixmapSize = icon().actualSize(iconSize()); - int vOffset = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical) : 0; - int hOffset = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal) : 0; + const int vOffset = isDown() + ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option) : 0; + const int hOffset = isDown() + ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option) : 0; //Draw icon p.drawControl(QStyle::CE_PushButton, option); diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp index 0992becdf0..c5b2a32aec 100644 --- a/src/widgets/widgets/qfocusframe.cpp +++ b/src/widgets/widgets/qfocusframe.cpp @@ -86,8 +86,10 @@ void QFocusFramePrivate::updateSize() if (!widget) return; - int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin), - hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin); + QStyleOption opt; + q->initStyleOption(&opt); + int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &opt), + hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &opt); QPoint pos(widget->x(), widget->y()); if (q->parentWidget() != widget->parentWidget()) pos = widget->parentWidget()->mapTo(q->parentWidget(), pos); @@ -98,8 +100,6 @@ void QFocusFramePrivate::updateSize() q->setGeometry(geom); QStyleHintReturnMask mask; - QStyleOption opt; - q->initStyleOption(&opt); if (q->style()->styleHint(QStyle::SH_FocusFrame_Mask, &opt, q, &mask)) q->setMask(mask.region); } @@ -263,8 +263,8 @@ QFocusFrame::paintEvent(QPaintEvent *) QStylePainter p(this); QStyleOption option; initStyleOption(&option); - int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin); - int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin); + const int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &option); + const int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option); QWidgetPrivate *wd = qt_widget_private(d->widget); QRect rect = wd->clipRect().adjusted(0, 0, hmargin*2, vmargin*2); p.setClipRect(rect); diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp index eec794562a..735e950602 100644 --- a/src/widgets/widgets/qgroupbox.cpp +++ b/src/widgets/widgets/qgroupbox.cpp @@ -491,9 +491,9 @@ QSize QGroupBox::minimumSizeHint() const int baseWidth = metrics.horizontalAdvance(d->title) + metrics.horizontalAdvance(QLatin1Char(' ')); int baseHeight = metrics.height(); if (d->checkable) { - baseWidth += style()->pixelMetric(QStyle::PM_IndicatorWidth); - baseWidth += style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing); - baseHeight = qMax(baseHeight, style()->pixelMetric(QStyle::PM_IndicatorHeight)); + baseWidth += style()->pixelMetric(QStyle::PM_IndicatorWidth, &option); + baseWidth += style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &option); + baseHeight = qMax(baseHeight, style()->pixelMetric(QStyle::PM_IndicatorHeight, &option)); } QSize size = style()->sizeFromContents(QStyle::CT_GroupBox, &option, QSize(baseWidth, baseHeight), this); diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 658315028a..eaf31551d9 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -2073,7 +2073,7 @@ void QLineEdit::paintEvent(QPaintEvent *) if (d->cursorVisible && !d->control->isReadOnly()) flags |= QWidgetLineControl::DrawCursor; - d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth)); + d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth, &panel)); d->control->draw(&p, topLeft, r, flags); } diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 57ef7905d9..2d6e6179af 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2828,7 +2828,7 @@ void QMenu::paintEvent(QPaintEvent *e) frame.rect = rect(); frame.palette = palette(); frame.state = QStyle::State_None; - frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth); + frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &frame); frame.midLineWidth = 0; style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this); } diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 7a751597bc..a2087c8ab1 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1019,7 +1019,7 @@ void QMenuBar::paintEvent(QPaintEvent *e) frame.rect = rect(); frame.palette = palette(); frame.state = QStyle::State_None; - frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth); + frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame); frame.midLineWidth = 0; style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this); } diff --git a/src/widgets/widgets/qtoolbarextension.cpp b/src/widgets/widgets/qtoolbarextension.cpp index bbe7eddaa4..165c7f274b 100644 --- a/src/widgets/widgets/qtoolbarextension.cpp +++ b/src/widgets/widgets/qtoolbarextension.cpp @@ -81,7 +81,9 @@ void QToolBarExtension::paintEvent(QPaintEvent *) QSize QToolBarExtension::sizeHint() const { - int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent); + QStyleOption opt; + opt.initFrom(this); + const int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt); return QSize(ext, ext); } diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 83e2315c36..fb41f38b5a 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2463,7 +2463,7 @@ void QWidgetTextControl::setCursorWidth(int width) Q_UNUSED(width); #else if (width == -1) - width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth); + width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth, nullptr); d->doc->documentLayout()->setProperty("cursorWidth", width); #endif d->repaintCursor(); -- cgit v1.2.3 From 875420f1c29f0d5e66b4dcacbe95d31dd5dca585 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 3 Feb 2020 20:26:22 +0100 Subject: QAbstractItemView: Make sure to update the editor geometries QAbstractItemView::setIndexWidget() does not trigger a relayouting when a new widget is set. This results in a wrong editor geometry under some circumstances. Fix it by triggering a delayed relayout. Fixes: QTBUG-81763 Change-Id: I75d0e19bd5e56d63effe4990d782d202fb39e3e6 Reviewed-by: Friedemann Kleint --- src/widgets/itemviews/qabstractitemview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index c3f8dd894e..f879af6ad2 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3234,8 +3234,10 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget widget->installEventFilter(this); widget->show(); dataChanged(index, index); // update the geometry - if (!d->delayedPendingLayout) + if (!d->delayedPendingLayout) { widget->setGeometry(visualRect(index)); + d->doDelayedItemsLayout(); // relayout due to updated geometry + } } } -- cgit v1.2.3 From 02e0c30a8aad785343ba1cddba82ccfe59099445 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 17 Feb 2020 16:01:20 +0100 Subject: QGraphicsView: Clear the rubber band when dragMode changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this change, and ongoing rubber-band selection will not be cleared when the dragmode property changes (e.g. because of a key press) which leaves a rubber-band displayed on the view. Move the rubber-band-clearing code from mouseReleaseEvent into a private helper that is then called from setDragMode. Change-Id: I32c15f7fe4ef2b8002ef5dd58e22f4bb30dd2409 Fixes: QTBUG-65186 Reviewed-by: Jan Arve Sæther --- src/widgets/graphicsview/qgraphicsview.cpp | 40 +++++++++++++++++++----------- src/widgets/graphicsview/qgraphicsview_p.h | 1 + 2 files changed, 27 insertions(+), 14 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 7ac9aebfe6..a75f1ab24b 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -786,6 +786,27 @@ void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event) if (scene) scene->setSelectionArea(selectionArea, rubberBandSelectionOperation, rubberBandSelectionMode, q->viewportTransform()); } + +void QGraphicsViewPrivate::clearRubberBand() +{ + Q_Q(QGraphicsView); + if (dragMode != QGraphicsView::RubberBandDrag || !sceneInteractionAllowed || !rubberBanding) + return; + + if (viewportUpdateMode != QGraphicsView::NoViewportUpdate) { + if (viewportUpdateMode != QGraphicsView::FullViewportUpdate) + q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect)); + else + updateAll(); + } + + rubberBanding = false; + rubberBandSelectionOperation = Qt::ReplaceSelection; + if (!rubberBandRect.isNull()) { + rubberBandRect = QRect(); + emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF()); + } +} #endif /*! @@ -1489,6 +1510,10 @@ void QGraphicsView::setDragMode(DragMode mode) if (d->dragMode == mode) return; +#if QT_CONFIG(rubberband) + d->clearRubberBand(); +#endif + #ifndef QT_NO_CURSOR if (d->dragMode == ScrollHandDrag) viewport()->unsetCursor(); @@ -3358,20 +3383,7 @@ void QGraphicsView::mouseReleaseEvent(QMouseEvent *event) #if QT_CONFIG(rubberband) if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed && !event->buttons()) { - if (d->rubberBanding) { - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){ - if (d->viewportUpdateMode != FullViewportUpdate) - viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect)); - else - d->updateAll(); - } - d->rubberBanding = false; - d->rubberBandSelectionOperation = Qt::ReplaceSelection; - if (!d->rubberBandRect.isNull()) { - d->rubberBandRect = QRect(); - emit rubberBandChanged(d->rubberBandRect, QPointF(), QPointF()); - } - } + d->clearRubberBand(); } else #endif if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) { diff --git a/src/widgets/graphicsview/qgraphicsview_p.h b/src/widgets/graphicsview/qgraphicsview_p.h index 01af61d6ba..e877e6e887 100644 --- a/src/widgets/graphicsview/qgraphicsview_p.h +++ b/src/widgets/graphicsview/qgraphicsview_p.h @@ -140,6 +140,7 @@ public: QRect rubberBandRect; QRegion rubberBandRegion(const QWidget *widget, const QRect &rect) const; void updateRubberBand(const QMouseEvent *event); + void clearRubberBand(); bool rubberBanding; Qt::ItemSelectionMode rubberBandSelectionMode; Qt::ItemSelectionOperation rubberBandSelectionOperation; -- cgit v1.2.3 From 66e0079569393f29e542f8868ece2b9f3c362525 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 25 Feb 2020 15:21:57 +0100 Subject: QStyle: deprecate enum values that are marked for removal in Qt 6 Those enum values are not used by widget code. Exception is PE_PanelItemViewRow, which is used by all item views, and no replacement is provided. So removing the ### Qt 6 comment from this value. Change-Id: Id4371bda5c3b14e3565c87ab233ee621d995f081 Reviewed-by: Shawn Rutledge --- src/widgets/styles/qstyle.cpp | 2 +- src/widgets/styles/qstyle.h | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 987465efae..5570d59276 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1075,7 +1075,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SE_TreeViewDisclosureItem Area for the actual disclosure item in a tree branch. - \value SE_DialogButtonBoxLayoutItem Area that counts for the parent layout. + \omitvalue SE_DialogButtonBoxLayoutItem \value SE_GroupBoxLayoutItem Area that counts for the parent layout. diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 04628e6ef9..5be1b4b290 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -191,7 +191,7 @@ public: PE_IndicatorItemViewItemDrop, PE_PanelItemViewItem, - PE_PanelItemViewRow, // ### Qt 6: remove + PE_PanelItemViewRow, PE_PanelStatusBar, @@ -332,8 +332,10 @@ public: SE_CheckBoxLayoutItem, SE_ComboBoxLayoutItem, SE_DateTimeEditLayoutItem, - SE_DialogButtonBoxLayoutItem, // ### Qt 6: remove - SE_LabelLayoutItem, +#if QT_DEPRECATED_SINCE(5, 15) // ### Qt 6: remove + SE_DialogButtonBoxLayoutItem Q_DECL_ENUMERATOR_DEPRECATED, +#endif + SE_LabelLayoutItem = SE_DateTimeEditLayoutItem + 2, SE_ProgressBarLayoutItem, SE_PushButtonLayoutItem, SE_RadioButtonLayoutItem, @@ -535,11 +537,13 @@ public: PM_SpinBoxSliderHeight, - PM_DefaultTopLevelMargin, // ### Qt 6: remove - PM_DefaultChildMargin, // ### Qt 6: remove - PM_DefaultLayoutSpacing, // ### Qt 6: remove +#if QT_DEPRECATED_SINCE(5, 15) // ### Qt 6: remove + PM_DefaultTopLevelMargin Q_DECL_ENUMERATOR_DEPRECATED, + PM_DefaultChildMargin Q_DECL_ENUMERATOR_DEPRECATED, + PM_DefaultLayoutSpacing Q_DECL_ENUMERATOR_DEPRECATED, +#endif - PM_ToolBarIconSize, + PM_ToolBarIconSize = PM_SpinBoxSliderHeight + 4, PM_ListViewIconSize, PM_IconViewIconSize, PM_SmallIconSize, -- cgit v1.2.3