From 10d0f4cba99d2386db28a3afd71832e35992b797 Mon Sep 17 00:00:00 2001 From: Oleg Yadrov Date: Fri, 17 Feb 2017 11:23:46 -0800 Subject: QMacStyle::sizeFromContents: don't do anything in CT_Menu case In this case we can safely return the same QSize which we accept since it is already contains the right size for the given menu and this size will be bounded to screen geometry before QMenu will be displayed anyway. We also get rid of one dependency on HITheme. Change-Id: I7502a96d180fc4a41ce3dfabe8a200b886016348 Reviewed-by: Gabriel de Dietrich --- src/widgets/styles/qmacstyle_mac.mm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 007ce20175..238e96ab4f 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -6759,12 +6759,7 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, break; } case CT_Menu: { - QStyleHintReturnMask menuMask; - QStyleOption myOption = *opt; - myOption.rect.setSize(sz); - if (proxy()->styleHint(SH_Menu_Mask, &myOption, widget, &menuMask)) { - sz = menuMask.region.boundingRect().size(); - } + sz = csz; break; } case CT_HeaderSection:{ const QStyleOptionHeader *header = qstyleoption_cast(opt); -- cgit v1.2.3 From d57bb19902f863fc6db07674f6bd8881b0886b39 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 20 Feb 2017 13:26:18 +0100 Subject: Fix crash while dropping a tabbed group into a single floating QDockWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The problem was caused by commit 0feeb6f6d2cfaa964763ca1fcab65672812b4eef which fixed QTBUG-58036. It reparented widget that used to be skiped. In particular, floating widgets are skiped. But seting the parent of a floating widget docks it. And so as a result it would not be skiped anymore. This has two side effect: This breaks the animation (as the widget is docked too early; and cause crash when QDockWidgetGroupWindow get reparented as this breaks invariant that these are always floating. So restore the skip from before commit 0feeb6f6d2cfaa964763ca1fcab65672812b4eef, and explicitly set the parent in all cases when the animation finishes. Change-Id: I0e3e29ad22d6ffe4d62242d48a18dadb916fc14f Reviewed-by: Sérgio Martins --- src/widgets/widgets/qdockarealayout.cpp | 2 +- src/widgets/widgets/qmainwindowlayout.cpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index b33f2dc798..8d9280ebb5 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2092,7 +2092,7 @@ void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent) const QDockAreaLayoutItem &item = item_list.at(i); if (item.flags & QDockAreaLayoutItem::GapItem) continue; - if (!item.widgetItem && item.skip()) + if (item.skip()) continue; if (item.subinfo) item.subinfo->reparentWidgets(parent); diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 68ca571acf..0d9c42fdf0 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -2195,10 +2195,8 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } if (QDockWidget *dw = qobject_cast(widget)) { - if (currentHoveredFloat) { - dw->setParent(currentHoveredFloat); - dw->show(); - } + dw->setParent(currentHoveredFloat ? currentHoveredFloat.data() : parentWidget()); + dw->show(); dw->d_func()->plug(currentGapRect); } #endif -- cgit v1.2.3 From 8c1f147eaf2769f84fa5ae8425394eb315949395 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Thu, 16 Feb 2017 09:58:20 +0000 Subject: dockwidgets: recalculate the press position if the window resizes A window can resize while dragging, this happens on Windows when dragging across screens, to a screen with a bigger scale factor. When that occurs it might lead to the press pos being outside of the window. Change-Id: Ic61ec7088c8fa81395d43ce665952dbd2eecba39 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qdockwidget.cpp | 13 +++++++++++++ src/widgets/widgets/qdockwidget_p.h | 1 + 2 files changed, 14 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 53cb21186f..f51e3c7988 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -1024,6 +1024,12 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) } } +void QDockWidgetPrivate::recalculatePressPos(QResizeEvent *event) +{ + qreal ratio = event->oldSize().width() / (1.0 * event->size().width()); + state->pressPos.setX(state->pressPos.x() / ratio); +} + /*! \internal Called when the QDockWidget or the QDockWidgetGroupWindow is moved */ @@ -1540,6 +1546,13 @@ bool QDockWidget::event(QEvent *event) // if the mainwindow is plugging us, we don't want to update undocked geometry if (isFloating() && layout != 0 && layout->pluggingWidget != this) d->undockedGeometry = geometry(); + + // Usually the window won't get resized while it's being moved, but it can happen, + // for example on Windows when moving to a screen with bigger scale factor + // (and Qt::AA_EnableHighDpiScaling is enabled). If that happens we should + // update state->pressPos, otherwise it will be outside the window when the window shrinks. + if (d->state && d->state->dragging) + d->recalculatePressPos(static_cast(event)); break; default: break; diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h index 94a3ad3b34..84bf8efacf 100644 --- a/src/widgets/widgets/qdockwidget_p.h +++ b/src/widgets/widgets/qdockwidget_p.h @@ -118,6 +118,7 @@ public: void startDrag(bool group = true); void endDrag(bool abort = false); void moveEvent(QMoveEvent *event); + void recalculatePressPos(QResizeEvent *event); void unplug(const QRect &rect); void plug(const QRect &rect); -- cgit v1.2.3 From ea615b421b76668332a3029ad31fa725b5bb9e58 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 26 Nov 2015 19:27:10 +0100 Subject: handle TabletMove events during stylus hover The main reason for this is to get feedback about the stylus orientation (angles and rotation) before the user presses it. For example an application might provide an image of the brush which rotates along with the stylus. As with mouse events, applications can distinguish hovering by the fact that no buttons are pressed. On the xcb platform we need to stop blocking the hover events, and in QWidgetWindow we need to send the event to the widget being hovered, while keeping the existing "grab" behavior: after pressing the stylus (or any button on the stylus or on the tablet), keep sending the events to the same widget until release. Task-number: QTBUG-26116 Change-Id: Iaed8b3b94961290dbb29b5fd2ea892fed7221685 Reviewed-by: Dmitry Kazakov Reviewed-by: Andy Shaw --- src/widgets/kernel/qwidgetwindow.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 7295cc36f6..5abce140ce 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -973,22 +973,26 @@ bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long void QWidgetWindow::handleTabletEvent(QTabletEvent *event) { static QPointer qt_tablet_target = 0; - if (event->type() == QEvent::TabletPress) { - QWidget *widget = m_widget->childAt(event->pos()); - if (!widget) - widget = m_widget; - qt_tablet_target = widget; + QWidget *widget = qt_tablet_target; + + if (!widget) { + widget = m_widget->childAt(event->pos()); + if (event->type() == QEvent::TabletPress) { + if (!widget) + widget = m_widget; + qt_tablet_target = widget; + } } - if (qt_tablet_target) { + if (widget) { QPointF delta = event->globalPosF() - event->globalPos(); - QPointF mapped = qt_tablet_target->mapFromGlobal(event->globalPos()) + delta; + QPointF mapped = widget->mapFromGlobal(event->globalPos()) + delta; QTabletEvent ev(event->type(), mapped, event->globalPosF(), event->device(), event->pointerType(), event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(), event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons()); ev.setTimestamp(event->timestamp()); - QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev); + QGuiApplication::sendSpontaneousEvent(widget, &ev); event->setAccepted(ev.isAccepted()); } -- cgit v1.2.3 From 6aaf8532222759226a9b406bfe6c57787236cbf1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 17 Feb 2017 13:32:01 +0100 Subject: make TabletMove hover events conditional on QWidget::tabletTracking This adds the tabletTracking property in the same way that mouseTracking already existed: there is a WA_TabletTracking attribute, and a TabletTrackingChange event to notify when it changes. So for widget applications it's an opt-in feature. QtQuick applications don't yet make use of tablet events, but when they do in the future, we don't yet have a mechanism to turn the move events off; it remains to be seen whether that will be necessary. [ChangeLog][QtWidget] QWidget now has a tabletTracking property, analogous to mouseTracking, which will enable TabletMove events while the stylus is hovering, even if no button is pressed. This allows applications to show feedback based on the other tablet event properties such as rotation and tilt. Task-number: QTBUG-26116 Change-Id: Ie96e8acad882b167e967796cdd17f1ad747a2771 Reviewed-by: Andy Shaw --- src/widgets/kernel/qwidget.cpp | 34 +++++++++++++++++++++++++++++++++- src/widgets/kernel/qwidget.h | 10 ++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2cb259468d..70bc407587 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6387,6 +6387,24 @@ void QWidget::setWindowRole(const QString &role) \sa mouseMoveEvent() */ +/*! + \property QWidget::tabletTracking + \brief whether tablet tracking is enabled for the widget + \since 5.9 + + If tablet tracking is disabled (the default), the widget only + receives tablet move events when the stylus is in contact with + the tablet, or at least one stylus button is pressed, + while the stylus is being moved. + + If tablet tracking is enabled, the widget receives tablet move + events even while hovering in proximity. This is useful for + monitoring position as well as the auxiliary properties such + as rotation and tilt, and providing feedback in the UI. + + \sa tabletEvent() +*/ + /*! Sets the widget's focus proxy to widget \a w. If \a w is 0, the @@ -8788,6 +8806,9 @@ bool QWidget::event(QEvent *event) #endif #ifndef QT_NO_TABLETEVENT case QEvent::TabletMove: + if (static_cast(event)->buttons() == Qt::NoButton && !testAttribute(Qt::WA_TabletTracking)) + break; + Q_FALLTHROUGH(); case QEvent::TabletPress: case QEvent::TabletRelease: tabletEvent((QTabletEvent*)event); @@ -9020,6 +9041,7 @@ bool QWidget::event(QEvent *event) case QEvent::IconTextChange: case QEvent::ModifiedChange: case QEvent::MouseTrackingChange: + case QEvent::TabletTrackingChange: case QEvent::ParentChange: case QEvent::LocaleChange: case QEvent::MacSizeChange: @@ -9425,7 +9447,13 @@ void QWidget::wheelEvent(QWheelEvent *event) The default implementation ignores the event. - \sa QEvent::ignore(), QEvent::accept(), event(), + If tablet tracking is switched off, tablet move events only occur if the + stylus is in contact with the tablet, or at least one stylus button is + pressed, while the stylus is being moved. If tablet tracking is switched on, + tablet move events occur even while the stylus is hovering in proximity of + the tablet, with no buttons pressed. + + \sa QEvent::ignore(), QEvent::accept(), event(), setTabletTracking(), QTabletEvent */ @@ -11194,6 +11222,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) QEvent e(QEvent::MouseTrackingChange); QApplication::sendEvent(this, &e); break; } + case Qt::WA_TabletTracking: { + QEvent e(QEvent::TabletTrackingChange); + QApplication::sendEvent(this, &e); + break; } case Qt::WA_NativeWindow: { d->createTLExtra(); if (on) diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 4c80038a4f..1c378924a0 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -161,6 +161,7 @@ class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor) #endif Q_PROPERTY(bool mouseTracking READ hasMouseTracking WRITE setMouseTracking) + Q_PROPERTY(bool tabletTracking READ hasTabletTracking WRITE setTabletTracking) Q_PROPERTY(bool isActiveWindow READ isActiveWindow) Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy) Q_PROPERTY(bool focus READ hasFocus) @@ -328,6 +329,9 @@ public: bool hasMouseTracking() const; bool underMouse() const; + void setTabletTracking(bool enable); + bool hasTabletTracking() const; + void setMask(const QBitmap &); void setMask(const QRegion &); QRegion mask() const; @@ -809,6 +813,12 @@ inline bool QWidget::hasMouseTracking() const inline bool QWidget::underMouse() const { return testAttribute(Qt::WA_UnderMouse); } +inline void QWidget::setTabletTracking(bool enable) +{ setAttribute(Qt::WA_TabletTracking, enable); } + +inline bool QWidget::hasTabletTracking() const +{ return testAttribute(Qt::WA_TabletTracking); } + inline bool QWidget::updatesEnabled() const { return !testAttribute(Qt::WA_UpdatesDisabled); } -- cgit v1.2.3 From 758a56e6628be36df3f11431f9a770c930b13f14 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 26 Dec 2014 21:43:40 +0100 Subject: QSizePolicy: plaster API with Q_DECL_NOTHROW This is mostly straight-forward, but some things are worth noting: 1. Yes, this is necessary. The noexcept operator looks for noexcept tagging, not at the contents of the function to determine whether to return true. The more conditionally-noexcept functions are used, the more important it becomes that low-level classes are correctly marked noexcept. In that, it is like constexpr. 2. In accordance with the rules governing noexcept specifications for the standard library itself, the set*Stretch() functions are not marked as noexcept, since they have preconditions and thus a narrow contract. Narrow-contract functions should not be noexcept. All other functions have wide contracts (ie. no preconditions). Change-Id: I853e0fc2d98cf3fcb16402a18ab136cccca24d89 Reviewed-by: Thiago Macieira --- src/widgets/kernel/qsizepolicy.cpp | 4 ++-- src/widgets/kernel/qsizepolicy.h | 44 +++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index b08a9abb1e..477b3421a0 100644 --- a/src/widgets/kernel/qsizepolicy.cpp +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -232,7 +232,7 @@ QT_BEGIN_NAMESPACE Returns the control type associated with the widget for which this size policy applies. */ -QSizePolicy::ControlType QSizePolicy::controlType() const +QSizePolicy::ControlType QSizePolicy::controlType() const Q_DECL_NOTHROW { return QSizePolicy::ControlType(1 << bits.ctype); } @@ -253,7 +253,7 @@ QSizePolicy::ControlType QSizePolicy::controlType() const \sa QStyle::layoutSpacing() */ -void QSizePolicy::setControlType(ControlType type) +void QSizePolicy::setControlType(ControlType type) Q_DECL_NOTHROW { bits.ctype = toControlTypeFieldValue(type); } diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 83ce5853ab..7674a8e922 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -117,55 +117,55 @@ public: Q_DECLARE_FLAGS(ControlTypes, ControlType) Q_FLAG(ControlTypes) - QT_SIZEPOLICY_CONSTEXPR QSizePolicy() : data(0) { } + QT_SIZEPOLICY_CONSTEXPR QSizePolicy() Q_DECL_NOTHROW : data(0) { } #ifdef Q_COMPILER_UNIFORM_INIT - QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW : bits{0, 0, quint32(horizontal), quint32(vertical), type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0} {} #else - QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) + QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW : data(0) { bits.horPolicy = horizontal; bits.verPolicy = vertical; setControlType(type); } #endif // uniform-init - QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const { return static_cast(bits.horPolicy); } - QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const { return static_cast(bits.verPolicy); } - ControlType controlType() const; + QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const Q_DECL_NOTHROW { return static_cast(bits.horPolicy); } + QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const Q_DECL_NOTHROW { return static_cast(bits.verPolicy); } + ControlType controlType() const Q_DECL_NOTHROW; - Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) { bits.horPolicy = d; } - Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) { bits.verPolicy = d; } - void setControlType(ControlType type); + Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) Q_DECL_NOTHROW { bits.horPolicy = d; } + Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) Q_DECL_NOTHROW { bits.verPolicy = d; } + void setControlType(ControlType type) Q_DECL_NOTHROW; - QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const { + QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const Q_DECL_NOTHROW { return ( (verticalPolicy() & ExpandFlag) ? Qt::Vertical : Qt::Orientations() ) | ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ; } - Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) { bits.hfw = b; } - QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const { return bits.hfw; } - Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) { bits.wfh = b; } - QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const { return bits.wfh; } + Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) Q_DECL_NOTHROW { bits.hfw = b; } + QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const Q_DECL_NOTHROW { return bits.hfw; } + Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) Q_DECL_NOTHROW { bits.wfh = b; } + QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const Q_DECL_NOTHROW { return bits.wfh; } - QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const { return data == s.data; } - QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const { return data != s.data; } + QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const Q_DECL_NOTHROW { return data == s.data; } + QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const Q_DECL_NOTHROW { return data != s.data; } friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) Q_DECL_NOTHROW { return qHash(key.data, seed); } operator QVariant() const; - QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const { return static_cast(bits.horStretch); } - QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const { return static_cast(bits.verStretch); } + QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const Q_DECL_NOTHROW { return static_cast(bits.horStretch); } + QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const Q_DECL_NOTHROW { return static_cast(bits.verStretch); } Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast(qBound(0, stretchFactor, 255)); } Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast(qBound(0, stretchFactor, 255)); } - QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; } - Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; } + QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const Q_DECL_NOTHROW { return bits.retainSizeWhenHidden; } + Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) Q_DECL_NOTHROW { bits.retainSizeWhenHidden = retainSize; } - Q_DECL_RELAXED_CONSTEXPR void transpose() { *this = transposed(); } + Q_DECL_RELAXED_CONSTEXPR void transpose() Q_DECL_NOTHROW { *this = transposed(); } #ifndef Q_QDOC QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT #endif @@ -179,7 +179,7 @@ private: friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &); friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &); #endif - QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) : data(i) { } + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) Q_DECL_NOTHROW : data(i) { } struct Bits; QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { } -- cgit v1.2.3 From 1d0ee8954825a38b789351558a04cbde04fa0490 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 22 Feb 2017 11:24:15 +0100 Subject: QSideBar: replace a QPair with a struct Instead of the incomprehensible "names" .first and .second, the code can now use .index and .path. Change-Id: I1449ba668f703b9a8b9391b0a0774072c8c6e8aa Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qsidebar.cpp | 10 +++++----- src/widgets/dialogs/qsidebar_p.h | 9 ++++++++- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index 713ccb6556..9bb046db61 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -274,7 +274,7 @@ void QUrlModel::addUrls(const QList &list, int row, bool move) continue; insertRows(row, 1); setUrl(index(row, 0), url, idx); - watching.append(qMakePair(idx, cleanUrl)); + watching.append({idx, cleanUrl}); } } @@ -326,7 +326,7 @@ void QUrlModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto { QModelIndex parent = topLeft.parent(); for (int i = 0; i < watching.count(); ++i) { - QModelIndex index = watching.at(i).first; + QModelIndex index = watching.at(i).index; if (index.model() && topLeft.model()) { Q_ASSERT(index.model() == topLeft.model()); } @@ -335,7 +335,7 @@ void QUrlModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto && index.column() >= topLeft.column() && index.column() <= bottomRight.column() && index.parent() == parent) { - changed(watching.at(i).second); + changed(watching.at(i).path); } } } @@ -349,12 +349,12 @@ void QUrlModel::layoutChanged() const int numPaths = watching.count(); paths.reserve(numPaths); for (int i = 0; i < numPaths; ++i) - paths.append(watching.at(i).second); + paths.append(watching.at(i).path); watching.clear(); for (int i = 0; i < numPaths; ++i) { QString path = paths.at(i); QModelIndex newIndex = fileSystemModel->index(path); - watching.append(QPair(newIndex, path)); + watching.append({newIndex, path}); if (newIndex.isValid()) changed(path); } diff --git a/src/widgets/dialogs/qsidebar_p.h b/src/widgets/dialogs/qsidebar_p.h index 3e177e7e68..0685e81b2b 100644 --- a/src/widgets/dialogs/qsidebar_p.h +++ b/src/widgets/dialogs/qsidebar_p.h @@ -108,9 +108,16 @@ private: void changed(const QString &path); void addIndexToWatch(const QString &path, const QModelIndex &index); QFileSystemModel *fileSystemModel; - QVector > watching; + struct WatchItem { + QModelIndex index; + QString path; + }; + friend class QTypeInfo; + + QVector watching; QList invalidUrls; }; +Q_DECLARE_TYPEINFO(QUrlModel::WatchItem, Q_MOVABLE_TYPE); class Q_AUTOTEST_EXPORT QSidebar : public QListView { -- cgit v1.2.3 From 46d4dc8afb4c38165b3b050e44170d9f3b03a0f5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 24 Feb 2017 00:48:33 +0100 Subject: QStyleSheetStyle: optimize away triple key lookup Instead of contains()/value()/remove(), all of which perform a new lookup, and a new application of qHash(), get an iterator using find(), deref it, then pass it to erase(). Also add some optimistic std::move(). Change-Id: I27a623dcd974de9c67d11d030e9b98d7598efc93 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/styles/qstylesheetstyle.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 9be19b2679..65894a6dde 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -2607,9 +2607,10 @@ void QStyleSheetStyle::unsetPalette(QWidget *w) const bool useStyleSheetPropagationInWidgetStyles = QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles); - if (styleSheetCaches->customPaletteWidgets.contains(w)) { - QPair p = styleSheetCaches->customPaletteWidgets.value(w); - styleSheetCaches->customPaletteWidgets.remove(w); + const auto it = styleSheetCaches->customPaletteWidgets.find(w); + if (it != styleSheetCaches->customPaletteWidgets.end()) { + QPair p = std::move(*it); + styleSheetCaches->customPaletteWidgets.erase(it); QPalette original = p.first; @@ -2649,9 +2650,10 @@ void QStyleSheetStyle::unsetPalette(QWidget *w) void QStyleSheetStyle::unsetStyleSheetFont(QWidget *w) const { - if (styleSheetCaches->customFontWidgets.contains(w)) { - QPair f = styleSheetCaches->customFontWidgets.value(w); - styleSheetCaches->customFontWidgets.remove(w); + const auto it = styleSheetCaches->customFontWidgets.find(w); + if (it != styleSheetCaches->customFontWidgets.end()) { + QPair f = std::move(*it); + styleSheetCaches->customFontWidgets.erase(it); QFont original = f.first; original.resolve(original.resolve() & f.second); -- cgit v1.2.3 From 4d3781b640e8fb0a04e96b2d05199247556b8d86 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 21 Feb 2017 15:45:00 +0100 Subject: QDockWidget: Fix memory leak when dragging a tab outside of a floating tab window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A QDockWidgetItem will be leaked if a QDockWidget is dragged out of a floating tab window, and then plugged back somewhere. The problem is that QMainWindowLayout::unplug was not returning the QDockWidgetItem* from the floating tab's layout. When that's the case, a new QDockWidgetItem is created in QDockWidgetPrivate::startDrag and will be put into the layout, leaking the old QDockWidgetItem. Change-Id: Ifb9c1c562cb74383ebff1df0f91ee225c5cdb296 Reviewed-by: Sérgio Martins --- src/widgets/widgets/qmainwindowlayout.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 0d9c42fdf0..640154063e 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -2378,7 +2378,8 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) // We are unplugging a dock widget from a floating window. if (QDockWidget *dw = qobject_cast(widget)) { dw->d_func()->unplug(widget->geometry()); - return 0; + int index = widget->parentWidget()->layout()->indexOf(widget); + return widget->parentWidget()->layout()->itemAt(index); } } } -- cgit v1.2.3 From e6d23860f08f59caa131bae8ca90f9e36e4dc033 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 17 Feb 2017 15:12:40 -0800 Subject: QApplication: Remove code duplication We always send mouse move events through the application event filters even if the widget has no mouse tracking enabled. This code portion is an almost verbatim copy of QCoreApplicationPrivate::sendThroughApplicationEventFilters(). The only difference is that previously the filter and the widget had to be in the same thread. Now, we compare the filter's thread to the application's. This is without consequence since widgets must live in the application thread. Change-Id: Ifee9c041e06d80ea0c2d2a947231e58ee4dfa24d Reviewed-by: Marc Mutz Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qapplication.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 2c85ed3c0b..0e4ee30c19 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3182,17 +3182,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) if (!w->hasMouseTracking() && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) { // but still send them through all application event filters (normally done by notify_helper) - for (int i = 0; d->extraData && i < d->extraData->eventFilters.size(); ++i) { - QObject *obj = d->extraData->eventFilters.at(i); - if (!obj) - continue; - if (Q_UNLIKELY(obj->d_func()->threadData != w->d_func()->threadData)) { - qWarning("QApplication: Object event filter cannot be in a different thread."); - continue; - } - if (obj->eventFilter(w, w == receiver ? mouse : &me)) - break; - } + d->sendThroughApplicationEventFilters(w, w == receiver ? mouse : &me); res = true; } else { w->setAttribute(Qt::WA_NoMouseReplay, false); -- cgit v1.2.3 From f85f21edbc3b3a5a2e8e4bf652d987903b5dad6e Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Fri, 24 Feb 2017 13:35:48 +0100 Subject: Fix build for -no-feature-textdate Change-Id: I31ad3fdde293759f04a136d7c7212288cafdc840 Reviewed-by: Lars Knoll --- src/widgets/configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/configure.json b/src/widgets/configure.json index e7007f71b7..7bc2e06a32 100644 --- a/src/widgets/configure.json +++ b/src/widgets/configure.json @@ -121,7 +121,7 @@ "label": "QDateTimeEdit", "purpose": "Supports editing dates and times.", "section": "Widgets", - "condition": "features.calendarwidget && features.datestring", + "condition": "features.calendarwidget && features.datestring && features.textdate", "output": [ "publicFeature", "feature" ] }, "stackedwidget": { -- cgit v1.2.3 From dfc338613ef54de67f2f2b2962d08b0c5a99fcdd Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 26 Feb 2017 17:18:40 +0100 Subject: Make QPlatformSurface events work with QWindowContainer Embeddeding a QWindow via QWidget::createWindowContainer() fails to deliver the SurfaceAboutToBeDestroyed event. This breaks any OpenGL or Vulkan based QWindow that releases resources upon this event, and is particularly critical with Vulkan where the only way to do properly ordered swapchain - surface cleanup is via this event. In the non-embedded case close() eventually ends up in an explicit destroy() in QWindow. In the embedded case destroy() only gets called from ~QWindow. This then silently breaks since the subclass' reimplemented event() virtual is not getting called anymore. To remedy the problem, simply add an explicit destroy() to QWindowContainer. Task-number: QTBUG-55166 Change-Id: I1671e8f4d39f6c44e19eca7b9387f55fe3788294 Reviewed-by: Sean Harmer --- src/widgets/kernel/qwindowcontainer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index bb25a3a986..7ae63e54b3 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -241,6 +241,14 @@ QWindow *QWindowContainer::containedWindow() const QWindowContainer::~QWindowContainer() { Q_D(QWindowContainer); + + // Call destroy() explicitly first. The dtor would do this too, but + // QEvent::PlatformSurface delivery relies on virtuals. Getting + // SurfaceAboutToBeDestroyed can be essential for OpenGL, Vulkan, etc. + // QWindow subclasses in particular. Keep these working. + if (d->window) + d->window->destroy(); + delete d->window; } -- cgit v1.2.3 From 3fdbba7a7a92b45ae58e74f53459565ae70f8fbf Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 25 Feb 2017 20:07:20 +0100 Subject: QSizePolicy: mark as relocatable type Use Q_RELOCATABLE_TYPE now that we have it. Change-Id: I04bb946695ebb9f0899bb73becbef301805389ef Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qsizepolicy.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 7674a8e922..2235082f17 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -216,6 +216,8 @@ private: #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) // Can't add in Qt 5, as QList would be BiC: Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE); +#else +Q_DECLARE_TYPEINFO(QSizePolicy, Q_RELOCATABLE_TYPE); #endif Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes) -- cgit v1.2.3 From bc641ad9f8ba3ea65dc400aa2f6520b4a5d5434d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 25 Feb 2017 20:11:32 +0100 Subject: QSizePolicy: simplify implementation Even though we revoke its Q_COMPILER_UNIFORM_INIT for certain bugs that affect existing usage in Qt, it turns out that MSVC 2013 supports enough of braced initialization to make the macro magic in Bits::transformed() moot. Change-Id: I824d7fa298a2b95b4ad45c9e259e91c5ececfc0c Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qsizepolicy.h | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 2235082f17..e19770cf92 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -51,10 +51,6 @@ QT_BEGIN_NAMESPACE # define QT_SIZEPOLICY_CONSTEXPR Q_DECL_CONSTEXPR # if defined(Q_COMPILER_UNIFORM_INIT) # define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT Q_DECL_CONSTEXPR -# if defined(Q_COMPILER_CONSTEXPR) -# define QT_SIZEPOLICY_RETURN_BITS(E1, E2, E3, E4, E5, E6, E7, E8) \ - return Bits{ E1, E2, E3, E4, E5, E6, E7, E8 } -# endif // constexpr && uniform-init # endif // uniform-init #endif @@ -64,10 +60,6 @@ QT_BEGIN_NAMESPACE #ifndef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT # define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT #endif -#ifndef QT_SIZEPOLICY_RETURN_BITS -# define QT_SIZEPOLICY_RETURN_BITS(E1, E2, E3, E4, E5, E6, E7, E8) \ - const Bits result = { E1, E2, E3, E4, E5, E6, E7, E8 }; return result -#endif class QVariant; class QSizePolicy; @@ -198,14 +190,14 @@ private: QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT Bits transposed() const Q_DECL_NOTHROW { - QT_SIZEPOLICY_RETURN_BITS(verStretch, // \ swap - horStretch, // / - verPolicy, // \ swap - horPolicy, // / - ctype, - hfw, // \ don't swap (historic behavior) - wfh, // / - retainSizeWhenHidden); + return {verStretch, // \ swap + horStretch, // / + verPolicy, // \ swap + horPolicy, // / + ctype, + hfw, // \ don't swap (historic behavior) + wfh, // / + retainSizeWhenHidden}; } }; union { @@ -234,7 +226,6 @@ Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QSizePolicy &); #undef QT_SIZEPOLICY_CONSTEXPR #undef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT -#undef QT_SIZEPOLICY_RETURN_BITS QT_END_NAMESPACE -- cgit v1.2.3 From 49c558eb0db3ec544fface24939a16f92d794987 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 22 Feb 2017 09:43:10 +0100 Subject: QSizePolicy: inline toControlTypeFieldValue() The implementation now uses the relaxed-constexpr qCountTrailingZeroBits() function from QtAlgorithms, making the QSizePolicy(Policy, Policy, ControlType) constructor constexpr on C++14 compilers. The explicit check for DefaultType remains to keep the constructor C++11-constexpr when called with just (Policy, Policy). Extend the constExpr tests a bit. Change-Id: I59690f0921d9bdee08e3615d0d1f4a9b92870c32 Reviewed-by: Giuseppe D'Angelo --- src/widgets/kernel/qsizepolicy.cpp | 24 ------------------------ src/widgets/kernel/qsizepolicy.h | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 25 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index 477b3421a0..b5a0cd3940 100644 --- a/src/widgets/kernel/qsizepolicy.cpp +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -258,30 +258,6 @@ void QSizePolicy::setControlType(ControlType type) Q_DECL_NOTHROW bits.ctype = toControlTypeFieldValue(type); } -quint32 QSizePolicy::toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW -{ - /* - The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, - etc. In memory, we pack it onto the available bits (CTSize) in - setControlType(), and unpack it here. - - Example: - - 0x00000001 maps to 0 - 0x00000002 maps to 1 - 0x00000004 maps to 2 - 0x00000008 maps to 3 - etc. - */ - - int i = 0; - while (true) { - if (type & (0x1 << i)) - return i; - ++i; - } -} - /*! \fn void QSizePolicy::setHeightForWidth(bool dependent) diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index e19770cf92..07d8393c6f 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -42,6 +42,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -175,7 +176,24 @@ private: struct Bits; QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { } - static quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW; + static Q_DECL_RELAXED_CONSTEXPR quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW + { + /* + The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, + etc. In memory, we pack it onto the available bits (CTSize) in + setControlType(), and unpack it here. + + Example: + + 0x00000001 maps to 0 + 0x00000002 maps to 1 + 0x00000004 maps to 2 + 0x00000008 maps to 3 + etc. + */ + + return qCountTrailingZeroBits(static_cast(type)); + } struct Bits { quint32 horStretch : 8; -- cgit v1.2.3 From 58cf57492cc5fd6c80428489d6ffe003167ea580 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 21 Feb 2017 10:26:32 +0100 Subject: Widgets: Replace LGPL21 with LGPL license header Also use canonical contact url. Change-Id: I59ed3d09d2fee877a577a00e7e1cb09782d26512 Reviewed-by: Lars Knoll --- src/widgets/widgets/qbuttongroup_p.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qbuttongroup_p.h b/src/widgets/widgets/qbuttongroup_p.h index b94dd170b4..93f3f4e0ec 100644 --- a/src/widgets/widgets/qbuttongroup_p.h +++ b/src/widgets/widgets/qbuttongroup_p.h @@ -1,31 +1,37 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** -- cgit v1.2.3