diff options
Diffstat (limited to 'src/widgets/kernel')
37 files changed, 588 insertions, 537 deletions
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index c2f6e4ce75..a4b81335c5 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -23,7 +23,6 @@ HEADERS += \ kernel/qshortcut.h \ kernel/qsizepolicy.h \ kernel/qstackedlayout.h \ - kernel/qtooltip.h \ kernel/qwidget.h \ kernel/qwidget_p.h \ kernel/qwidgetaction.h \ @@ -51,7 +50,6 @@ SOURCES += \ kernel/qshortcut.cpp \ kernel/qsizepolicy.cpp \ kernel/qstackedlayout.cpp \ - kernel/qtooltip.cpp \ kernel/qwidget.cpp \ kernel/qwidgetaction.cpp \ kernel/qgesture.cpp \ @@ -79,6 +77,11 @@ qtConfig(formlayout) { SOURCES += kernel/qformlayout.cpp } +qtConfig(tooltip) { + HEADERS += kernel/qtooltip.h + SOURCES += kernel/qtooltip.cpp +} + qtConfig(whatsthis) { HEADERS += kernel/qwhatsthis.h SOURCES += kernel/qwhatsthis.cpp diff --git a/src/widgets/kernel/mac.pri b/src/widgets/kernel/mac.pri index f7e7aa869a..d21e5d4a74 100644 --- a/src/widgets/kernel/mac.pri +++ b/src/widgets/kernel/mac.pri @@ -1,4 +1 @@ -macos { - LIBS_PRIVATE += -framework AppKit -lz - *-mwerks:INCLUDEPATH += compat -} +macos: LIBS_PRIVATE += -framework AppKit -lz diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 1ca5514655..f6631199d6 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -1153,8 +1153,9 @@ void QAction::activate(ActionEvent event) if(event == Trigger) { QPointer<QObject> guard = this; if(d->checkable) { - // the checked action of an exclusive group cannot be unchecked - if (d->checked && (d->group && d->group->isExclusive() + // the checked action of an exclusive group may not be unchecked + if (d->checked && (d->group + && d->group->exclusionPolicy() == QActionGroup::ExclusionPolicy::Exclusive && d->group->checkedAction() == this)) { if (!guard.isNull()) emit triggered(true); diff --git a/src/widgets/kernel/qactiongroup.cpp b/src/widgets/kernel/qactiongroup.cpp index 7934ae1d90..ab42b1c7aa 100644 --- a/src/widgets/kernel/qactiongroup.cpp +++ b/src/widgets/kernel/qactiongroup.cpp @@ -52,12 +52,16 @@ class QActionGroupPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QActionGroup) public: - QActionGroupPrivate() : exclusive(1), enabled(1), visible(1) { } + QActionGroupPrivate() : enabled(1), + visible(1), + exclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive) + { + } QList<QAction *> actions; QPointer<QAction> current; - uint exclusive : 1; uint enabled : 1; uint visible : 1; + QActionGroup::ExclusionPolicy exclusionPolicy; private: void _q_actionTriggered(); //private slot @@ -70,7 +74,7 @@ void QActionGroupPrivate::_q_actionChanged() Q_Q(QActionGroup); QAction *action = qobject_cast<QAction*>(q->sender()); Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error"); - if(exclusive) { + if (exclusionPolicy != QActionGroup::ExclusionPolicy::None) { if (action->isChecked()) { if (action != current) { if(current) @@ -127,12 +131,17 @@ void QActionGroupPrivate::_q_actionHovered() actions is chosen. Each action in an action group emits its triggered() signal as usual. - As stated above, an action group is \l exclusive by default; it - ensures that only one checkable action is active at any one time. + As stated above, an action group is exclusive by default; it + ensures that at most only one checkable action is active at any one time. If you want to group checkable actions without making them - exclusive, you can turn of exclusiveness by calling + exclusive, you can turn off exclusiveness by calling setExclusive(false). + By default the active action of an exclusive group cannot be unchecked. + In some cases it may be useful to allow unchecking all the actions, + you can allow this by calling + setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional). + Actions can be added to an action group using addAction(), but it is usually more convenient to specify a group when creating actions; this ensures that actions are automatically created with @@ -146,10 +155,33 @@ void QActionGroupPrivate::_q_actionHovered() */ /*! + \enum QActionGroup::ExclusionPolicy + + This enum specifies the different policies that can be used to + control how the group performs exclusive checking on checkable actions. + + \value None + The actions in the group can be checked independently of each other. + + \value Exclusive + Exactly one action can be checked at any one time. + This is the default policy. + + \value ExclusiveOptional + At most one action can be checked at any one time. The actions + can also be all unchecked. + + \sa exclusionPolicy + \since 5.14 +*/ + +/*! Constructs an action group for the \a parent object. The action group is exclusive by default. Call setExclusive(false) - to make the action group non-exclusive. + to make the action group non-exclusive. To make the group exclusive + but allow unchecking the active action call instead + setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional) */ QActionGroup::QActionGroup(QObject* parent) : QObject(*new QActionGroupPrivate, parent) { @@ -258,26 +290,56 @@ QList<QAction*> QActionGroup::actions() const } /*! - \property QActionGroup::exclusive - \brief whether the action group does exclusive checking + \brief Enable or disable the group exclusion checking - If exclusive is true, only one checkable action in the action group - can ever be active at any time. If the user chooses another - checkable action in the group, the one they chose becomes active and - the one that was active becomes inactive. + This is a convenience method that calls + setExclusionPolicy(ExclusionPolicy::Exclusive). - \sa QAction::checkable + \sa QActionGroup::exclusionPolicy */ void QActionGroup::setExclusive(bool b) { - Q_D(QActionGroup); - d->exclusive = b; + setExclusionPolicy(b ? QActionGroup::ExclusionPolicy::Exclusive + : QActionGroup::ExclusionPolicy::None); } +/*! + \brief Returs true if the group is exclusive + + The group is exclusive if the ExclusionPolicy is either Exclusive + or ExclusionOptional. + +*/ bool QActionGroup::isExclusive() const { + return exclusionPolicy() != QActionGroup::ExclusionPolicy::None; +} + +/*! + \property QActionGroup::exclusionPolicy + \brief This property holds the group exclusive checking policy + + If exclusionPolicy is set to Exclusive, only one checkable + action in the action group can ever be active at any time. If the user + chooses another checkable action in the group, the one they chose becomes + active and the one that was active becomes inactive. If exclusionPolicy is + set to ExclusionOptional the group is exclusive but the active checkable + action in the group can be unchecked leaving the group with no actions + checked. + + \sa QAction::checkable + \since 5.14 +*/ +void QActionGroup::setExclusionPolicy(QActionGroup::ExclusionPolicy policy) +{ + Q_D(QActionGroup); + d->exclusionPolicy = policy; +} + +QActionGroup::ExclusionPolicy QActionGroup::exclusionPolicy() const +{ Q_D(const QActionGroup); - return d->exclusive; + return d->exclusionPolicy; } /*! @@ -316,8 +378,8 @@ bool QActionGroup::isEnabled() const } /*! - Returns the currently checked action in the group, or 0 if none - are checked. + Returns the currently checked action in the group, or \nullptr if + none are checked. */ QAction *QActionGroup::checkedAction() const { diff --git a/src/widgets/kernel/qactiongroup.h b/src/widgets/kernel/qactiongroup.h index 61c90b911d..90f488bedb 100644 --- a/src/widgets/kernel/qactiongroup.h +++ b/src/widgets/kernel/qactiongroup.h @@ -55,11 +55,18 @@ class Q_WIDGETS_EXPORT QActionGroup : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QActionGroup) - Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive) + Q_PROPERTY(QActionGroup::ExclusionPolicy exclusionPolicy READ exclusionPolicy WRITE setExclusionPolicy) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) Q_PROPERTY(bool visible READ isVisible WRITE setVisible) public: + enum class ExclusionPolicy { + None, + Exclusive, + ExclusiveOptional + }; + Q_ENUM(ExclusionPolicy) + explicit QActionGroup(QObject* parent); ~QActionGroup(); @@ -73,6 +80,7 @@ public: bool isExclusive() const; bool isEnabled() const; bool isVisible() const; + ExclusionPolicy exclusionPolicy() const; public Q_SLOTS: @@ -80,6 +88,7 @@ public Q_SLOTS: inline void setDisabled(bool b) { setEnabled(!b); } void setVisible(bool); void setExclusive(bool); + void setExclusionPolicy(ExclusionPolicy policy); Q_SIGNALS: void triggered(QAction *); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 8e01cb17c5..526bf0a0ff 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -570,10 +570,6 @@ void QApplicationPrivate::init() initialize(); eventDispatcher->startingUp(); -#ifdef QT_EVAL - extern void qt_gui_eval_init(QCoreApplicationPrivate::Type); - qt_gui_eval_init(application_type); -#endif #ifndef QT_NO_ACCESSIBILITY // factory for accessible interfaces for widgets shipped with Qt QAccessible::installFactory(&qAccessibleFactory); @@ -767,7 +763,7 @@ QWidget *QApplication::activeModalWidget() /*! Cleans up any window system resources that were allocated by this - application. Sets the global variable \c qApp to 0. + application. Sets the global variable \c qApp to \nullptr. */ QApplication::~QApplication() @@ -876,8 +872,8 @@ void qt_cleanup() /*! \fn QWidget *QApplication::widgetAt(const QPoint &point) - Returns the widget at global screen position \a point, or 0 if there is no - Qt widget there. + Returns the widget at global screen position \a point, or \nullptr + if there is no Qt widget there. This function can be slow. @@ -887,9 +883,9 @@ QWidget *QApplication::widgetAt(const QPoint &p) { QWidget *window = QApplication::topLevelAt(p); if (!window) - return 0; + return nullptr; - QWidget *child = 0; + QWidget *child = nullptr; if (!window->testAttribute(Qt::WA_TransparentForMouseEvents)) child = window->childAt(window->mapFromGlobal(p)); @@ -925,8 +921,8 @@ QWidget *QApplication::widgetAt(const QPoint &p) \overload - Returns the widget at global screen position (\a x, \a y), or 0 if there is - no Qt widget there. + Returns the widget at global screen position (\a x, \a y), or + \nullptr if there is no Qt widget there. */ /*! @@ -1224,6 +1220,7 @@ QStyle* QApplication::setStyle(const QString& style) return s; } +#if QT_DEPRECATED_SINCE(5, 8) /*! Returns the color specification. \obsolete @@ -1298,6 +1295,7 @@ void QApplication::setColorSpec(int spec) { Q_UNUSED(spec) } +#endif /*! \property QApplication::globalStrut @@ -1409,6 +1407,7 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* else *QApplicationPrivate::set_pal = palette; QCoreApplication::setAttribute(Qt::AA_SetPalette); + emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal); } } @@ -1685,13 +1684,13 @@ QWidgetList QApplication::topLevelWidgets() QWidgetList QApplication::allWidgets() { if (QWidgetPrivate::allWidgets) - return QWidgetPrivate::allWidgets->toList(); + return QWidgetPrivate::allWidgets->values(); return QWidgetList(); } /*! - Returns the application widget that has the keyboard input focus, or 0 if - no widget in this application has the focus. + Returns the application widget that has the keyboard input focus, + or \nullptr if no widget in this application has the focus. \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged() */ @@ -1759,7 +1758,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) /*! Returns the application top-level window that has the keyboard input focus, - or 0 if no application window has the focus. There might be an + or \nullptr if no application window has the focus. There might be an activeWindow() even if there is no focusWidget(), for example if no widget in that window accepts key events. @@ -1864,8 +1863,8 @@ void QApplication::aboutQt() This signal is emitted when the widget that has keyboard focus changed from \a old to \a now, i.e., because the user pressed the tab-key, clicked into - a widget or changed the active window. Both \a old and \a now can be the - null-pointer. + a widget or changed the active window. Both \a old and \a now can be \nullptr. + The signal is emitted after both widget have been notified about the change through QFocusEvent. @@ -3853,6 +3852,7 @@ Qt::NavigationMode QApplication::navigationMode() return QApplicationPrivate::navigationMode; } +# if QT_DEPRECATED_SINCE(5, 13) /*! Sets whether Qt should use focus navigation suitable for use with a minimal keypad. @@ -3895,6 +3895,7 @@ bool QApplication::keypadNavigationEnabled() return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder || QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional; } +# endif #endif /*! diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h index 7a5d7ba1a9..27e743a28d 100644 --- a/src/widgets/kernel/qapplication.h +++ b/src/widgets/kernel/qapplication.h @@ -180,8 +180,12 @@ public: bool notify(QObject *, QEvent *) override; #ifdef QT_KEYPAD_NAVIGATION - static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool); - static bool keypadNavigationEnabled(); +# if QT_DEPRECATED_SINCE(5, 13) + static QT_DEPRECATED_X ("Use QApplication::setNavigationMode() instead") + void setKeypadNavigationEnabled(bool); + static QT_DEPRECATED_X ("Use QApplication::navigationMode() instead") + bool keypadNavigationEnabled(); +# endif static void setNavigationMode(Qt::NavigationMode mode); static Qt::NavigationMode navigationMode(); #endif diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 133279f977..98eb9b73c6 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -128,10 +128,10 @@ public: void notifyWindowIconChanged() override; //modality - bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const override; + bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = nullptr) const override; static bool isBlockedByModal(QWidget *widget); static bool modalState(); - static bool tryModalHelper(QWidget *widget, QWidget **rettop = 0); + static bool tryModalHelper(QWidget *widget, QWidget **rettop = nullptr); #if 0 // Used to be included in Qt4 for Q_WS_MAC static QWidget *tryModalHelper_sys(QWidget *top); bool canQuit(); @@ -157,7 +157,7 @@ public: void openPopup(QWidget *popup); static void setFocusWidget(QWidget *focus, Qt::FocusReason reason); static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next, - bool *wrappingOccurred = 0); + bool *wrappingOccurred = nullptr); #if QT_CONFIG(graphicsview) // Maintain a list of all scenes to ensure font and palette propagation to @@ -238,7 +238,7 @@ public: return window; if (const QWidget *nativeParent = widget->nativeParentWidget()) return nativeParent->windowHandle(); - return 0; + return nullptr; } #ifdef Q_OS_WIN diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index 5fb7882932..ac0cfcf2f5 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -176,26 +176,32 @@ void QDesktopWidgetPrivate::_q_updateScreens() // Notice that we trigger screenCountChanged even if a screen was removed and another one added, // in which case the total number of screens did not change. This is the only way for applications // to notice that a screen was swapped out against another one. +#if QT_DEPRECATED_SINCE(5, 11) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->screenCountChanged(targetLength); QT_WARNING_POP +#endif } +#if QT_DEPRECATED_SINCE(5, 11) foreach (int changedScreen, changedScreens) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->resized(changedScreen); QT_WARNING_POP +#endif } void QDesktopWidgetPrivate::_q_availableGeometryChanged() { +#if QT_DEPRECATED_SINCE(5, 11) Q_Q(QDesktopWidget); if (QScreen *screen = qobject_cast<QScreen *>(q->sender())) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->workAreaResized(QGuiApplication::screens().indexOf(screen)); QT_WARNING_POP +#endif } QDesktopWidget::QDesktopWidget() @@ -212,10 +218,12 @@ QDesktopWidget::~QDesktopWidget() { } +#if QT_DEPRECATED_SINCE(5, 11) bool QDesktopWidget::isVirtualDesktop() const { return QDesktopWidgetPrivate::isVirtualDesktop(); } +#endif bool QDesktopWidgetPrivate::isVirtualDesktop() { @@ -242,24 +250,27 @@ int QDesktopWidgetPrivate::height() return geometry().height(); } +#if QT_DEPRECATED_SINCE(5, 11) int QDesktopWidget::primaryScreen() const { return QDesktopWidgetPrivate::primaryScreen(); } +#endif int QDesktopWidgetPrivate::primaryScreen() { return 0; } -int QDesktopWidget::numScreens() const +int QDesktopWidgetPrivate::numScreens() { - return QDesktopWidgetPrivate::numScreens(); + return qMax(QGuiApplication::screens().size(), 1); } -int QDesktopWidgetPrivate::numScreens() +#if QT_DEPRECATED_SINCE(5, 11) +int QDesktopWidget::numScreens() const { - return qMax(QGuiApplication::screens().size(), 1); + return QDesktopWidgetPrivate::numScreens(); } QWidget *QDesktopWidget::screen(int screen) @@ -274,6 +285,7 @@ const QRect QDesktopWidget::availableGeometry(int screenNo) const { return QDesktopWidgetPrivate::availableGeometry(screenNo); } +#endif const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo) { @@ -281,10 +293,12 @@ const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo) return screen ? screen->availableGeometry() : QRect(); } +#if QT_DEPRECATED_SINCE(5, 11) const QRect QDesktopWidget::screenGeometry(int screenNo) const { return QDesktopWidgetPrivate::screenGeometry(screenNo); } +#endif const QRect QDesktopWidgetPrivate::screenGeometry(int screenNo) { @@ -307,20 +321,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w) if (screens.isEmpty()) // This should never happen return primaryScreen(); - const QWindow *winHandle = w->windowHandle(); - if (!winHandle) { - if (const QWidget *nativeParent = w->nativeParentWidget()) - winHandle = nativeParent->windowHandle(); - } - // If there is more than one virtual desktop if (screens.count() != screens.constFirst()->virtualSiblings().count()) { // Find the root widget, get a QScreen from it and use the // virtual siblings for checking the window position. - if (winHandle) { - if (const QScreen *winScreen = winHandle->screen()) - screens = winScreen->virtualSiblings(); - } + if (const QScreen *winScreen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen()) + screens = winScreen->virtualSiblings(); } // Get the screen number from window position using screen geometry @@ -344,10 +350,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w) return allScreens.indexOf(widgetScreen); } +#if QT_DEPRECATED_SINCE(5, 11) int QDesktopWidget::screenNumber(const QPoint &p) const { return QDesktopWidgetPrivate::screenNumber(p); } +#endif int QDesktopWidgetPrivate::screenNumber(const QPoint &p) { diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h index f986f0db20..e5c587984f 100644 --- a/src/widgets/kernel/qdesktopwidget.h +++ b/src/widgets/kernel/qdesktopwidget.h @@ -52,9 +52,11 @@ class QDesktopWidgetPrivate; class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget { Q_OBJECT +#if QT_DEPRECATED_SINCE(5, 11) Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop) Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged) Q_PROPERTY(int primaryScreen READ primaryScreen NOTIFY primaryScreenChanged) +#endif public: QDesktopWidget(); ~QDesktopWidget(); diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 600934b8a1..9146ba84c8 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -419,13 +419,15 @@ void QFormLayoutPrivate::updateSizes() if (label) { maxMinLblWidth = qMax(maxMinLblWidth, label->minSize.width()); maxShLblWidth = qMax(maxShLblWidth, label->sizeHint.width()); - if (field) { + } + if (field) { + if (field->fullRow) { + maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width()); + maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width()); + } else { maxMinFldWidth = qMax(maxMinFldWidth, field->minSize.width() + field->sbsHSpace); maxShFldWidth = qMax(maxShFldWidth, field->sizeHint.width() + field->sbsHSpace); } - } else if (field) { - maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width()); - maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width()); } prevLbl = label; @@ -781,7 +783,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) vLayouts[vidx].expansive = expanding || (vLayouts[vidx].stretch > 0); vLayouts[vidx].empty = false; - if (vLayouts[vidx].stretch > 0) + if (vLayouts[vidx].expansive) addTopBottomStretch = false; if (vidx > 1) @@ -2207,8 +2209,11 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q QSize sz(qMin(label->layoutWidth, label->sizeHint.width()), height); int x = leftOffset + rect.x() + label->layoutPos; - if (fixedAlignment(q->labelAlignment(), layoutDirection) & Qt::AlignRight) + const auto fAlign = fixedAlignment(q->labelAlignment(), layoutDirection); + if (fAlign & Qt::AlignRight) x += label->layoutWidth - sz.width(); + else if (fAlign & Qt::AlignHCenter) + x += label->layoutWidth / 2 - sz.width() / 2; QPoint p(x, layouts.at(label->vLayoutIndex).pos); // ### expansion & sizepolicy stuff diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h index 636103c1e1..cbf8d60892 100644 --- a/src/widgets/kernel/qgesture_p.h +++ b/src/widgets/kernel/qgesture_p.h @@ -111,7 +111,7 @@ class QPinchGesturePrivate : public QGesturePrivate public: QPinchGesturePrivate() - : totalChangeFlags(0), changeFlags(0), + : totalChangeFlags(nullptr), changeFlags(nullptr), totalScaleFactor(1), lastScaleFactor(1), scaleFactor(1), totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0), isNewSequence(true) diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 891858b035..ff7bc1eccf 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -136,7 +136,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r ++m_lastCustomGestureId; type = Qt::GestureType(m_lastCustomGestureId); } - m_recognizers.insertMulti(type, recognizer); + m_recognizers.insert(type, recognizer); return type; } @@ -167,30 +167,26 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type) { - QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin(); - while (iter != m_objectGestures.end()) { - ObjectGesture objectGesture = iter.key(); - if (objectGesture.gesture == type && target == objectGesture.object) { - QSet<QGesture *> gestures = iter.value().toSet(); - for (QHash<QGestureRecognizer *, QSet<QGesture *> >::iterator - it = m_obsoleteGestures.begin(), e = m_obsoleteGestures.end(); it != e; ++it) { - it.value() -= gestures; - } - foreach (QGesture *g, gestures) { - m_deletedRecognizers.remove(g); - m_gestureToRecognizer.remove(g); - m_maybeGestures.remove(g); - m_activeGestures.remove(g); - m_gestureOwners.remove(g); - m_gestureTargets.remove(g); - m_gesturesToDelete.insert(g); - } + const auto iter = m_objectGestures.find({target, type}); + if (iter == m_objectGestures.end()) + return; - iter = m_objectGestures.erase(iter); - } else { - ++iter; - } + const QList<QGesture *> &gestures = iter.value(); + for (auto &e : m_obsoleteGestures) { + for (QGesture *g : gestures) + e -= g; } + for (QGesture *g : gestures) { + m_deletedRecognizers.remove(g); + m_gestureToRecognizer.remove(g); + m_maybeGestures.remove(g); + m_activeGestures.remove(g); + m_gestureOwners.remove(g); + m_gestureTargets.remove(g); + m_gesturesToDelete.insert(g); + } + + m_objectGestures.erase(iter); } // get or create a QGesture object that will represent the state for a given object, used by the recognizer @@ -509,15 +505,15 @@ void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) // return true if accepted (consumed) bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) { - QMap<Qt::GestureType, int> types; + QVarLengthArray<Qt::GestureType, 16> types; QMultiMap<QObject *, Qt::GestureType> contexts; QWidget *w = receiver; typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator; if (!w->d_func()->gestureContext.isEmpty()) { for(ContextIterator it = w->d_func()->gestureContext.constBegin(), e = w->d_func()->gestureContext.constEnd(); it != e; ++it) { - types.insert(it.key(), 0); - contexts.insertMulti(w, it.key()); + types.push_back(it.key()); + contexts.insert(w, it.key()); } } // find all gesture contexts for the widget tree @@ -528,8 +524,8 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) e = w->d_func()->gestureContext.constEnd(); it != e; ++it) { if (!(it.value() & Qt::DontStartGestureOnChildren)) { if (!types.contains(it.key())) { - types.insert(it.key(), 0); - contexts.insertMulti(w, it.key()); + types.push_back(it.key()); + contexts.insert(w, it.key()); } } } @@ -543,15 +539,15 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) #if QT_CONFIG(graphicsview) bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) { - QMap<Qt::GestureType, int> types; + QVarLengthArray<Qt::GestureType, 16> types; QMultiMap<QObject *, Qt::GestureType> contexts; QGraphicsObject *item = receiver; if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) { typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator; for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.constBegin(), e = item->QGraphicsItem::d_func()->gestureContext.constEnd(); it != e; ++it) { - types.insert(it.key(), 0); - contexts.insertMulti(item, it.key()); + types.push_back(it.key()); + contexts.insert(item, it.key()); } } // find all gesture contexts for the graphics object tree @@ -563,8 +559,8 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) e = item->QGraphicsItem::d_func()->gestureContext.constEnd(); it != e; ++it) { if (!(it.value() & Qt::DontStartGestureOnChildren)) { if (!types.contains(it.key())) { - types.insert(it.key(), 0); - contexts.insertMulti(item, it.key()); + types.push_back(it.key()); + contexts.insert(item, it.key()); } } } diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index f1c6c96a6d..4f2b505e32 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -1330,8 +1330,8 @@ QLayoutItem *QGridLayout::itemAt(int index) const /*! \since 4.4 - Returns the layout item that occupies cell (\a row, \a column), or 0 if - the cell is empty. + Returns the layout item that occupies cell (\a row, \a column), or + \nullptr if the cell is empty. \sa getItemPosition(), indexOf() */ @@ -1346,7 +1346,7 @@ QLayoutItem *QGridLayout::itemAtPosition(int row, int column) const return box->item(); } } - return 0; + return nullptr; } /*! diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index eac5674161..f71d038a5f 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -109,7 +109,7 @@ static int menuBarHeightForWidth(QWidget *menubar, int w) /*! Constructs a new top-level QLayout, with parent \a parent. - \a parent may not be a \c nullptr. + \a parent may not be \nullptr. The layout is set directly as the top-level layout for \a parent. There can be only one top-level layout for a @@ -282,6 +282,7 @@ bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment) return false; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QLayout::margin \brief the width of the outside border of the layout @@ -307,6 +308,15 @@ int QLayout::margin() const } /*! + \obsolete +*/ +void QLayout::setMargin(int margin) +{ + setContentsMargins(margin, margin, margin, margin); +} + +#endif +/*! \property QLayout::spacing \brief the spacing between widgets inside the layout @@ -344,14 +354,6 @@ int QLayout::spacing() const } } -/*! - \obsolete -*/ -void QLayout::setMargin(int margin) -{ - setContentsMargins(margin, margin, margin, margin); -} - void QLayout::setSpacing(int spacing) { if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) { @@ -417,9 +419,9 @@ void QLayout::setContentsMargins(const QMargins &margins) /*! \since 4.3 - Extracts the left, top, right, and bottom margins used around the - layout, and assigns them to *\a left, *\a top, *\a right, and *\a - bottom (unless they are null pointers). + For each of \a left, \a top, \a right and \a bottom that is not + \nullptr, stores the size of the margin named in the location the + pointer refers to. By default, QLayout uses the values provided by the style. On most platforms, the margin is 11 pixels in all directions. @@ -474,8 +476,8 @@ QRect QLayout::contentsRect() const /*! - Returns the parent widget of this layout, or 0 if this layout is - not installed on any widget. + Returns the parent widget of this layout, or \nullptr if this + layout is not installed on any widget. If the layout is a sub-layout, this function returns the parent widget of the parent layout. @@ -490,11 +492,11 @@ QWidget *QLayout::parentWidget() const QLayout *parentLayout = qobject_cast<QLayout*>(parent()); if (Q_UNLIKELY(!parentLayout)) { qWarning("QLayout::parentWidget: A layout can only have another layout as a parent."); - return 0; + return nullptr; } return parentLayout->parentWidget(); } else { - return 0; + return nullptr; } } else { Q_ASSERT(parent() && parent()->isWidgetType()); @@ -950,8 +952,8 @@ void QLayout::setMenuBar(QWidget *widget) } /*! - Returns the menu bar set for this layout, or 0 if no menu bar is - set. + Returns the menu bar set for this layout, or \nullptr if no + menu bar is set. */ QWidget *QLayout::menuBar() const @@ -1130,8 +1132,9 @@ bool QLayout::activate() Searches for widget \a from and replaces it with widget \a to if found. Returns the layout item that contains the widget \a from on success. - Otherwise \c 0 is returned. If \a options contains \c Qt::FindChildrenRecursively - (the default), sub-layouts are searched for doing the replacement. + Otherwise \nullptr is returned. + If \a options contains \c Qt::FindChildrenRecursively (the default), + sub-layouts are searched for doing the replacement. Any other flag in \a options is ignored. Notice that the returned item therefore might not belong to this layout, @@ -1153,6 +1156,8 @@ QLayoutItem *QLayout::replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOpt Q_D(QLayout); if (!from || !to) return 0; + if (from == to) // Do not return a QLayoutItem for \a from, since ownership still + return nullptr; // belongs to the layout (since nothing was changed) int index = -1; QLayoutItem *item = 0; diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index 616f4e7164..35a04a35b2 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -63,7 +63,9 @@ class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem Q_OBJECT Q_DECLARE_PRIVATE(QLayout) +#if QT_DEPRECATED_SINCE(5, 13) Q_PROPERTY(int margin READ margin WRITE setMargin) +#endif Q_PROPERTY(int spacing READ spacing WRITE setSpacing) Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint) public: @@ -81,10 +83,12 @@ public: QLayout(); ~QLayout(); +#if QT_DEPRECATED_SINCE(5, 13) int margin() const; - int spacing() const; - void setMargin(int); +#endif + + int spacing() const; void setSpacing(int); void setContentsMargins(int left, int top, int right, int bottom); diff --git a/src/widgets/kernel/qlayout_p.h b/src/widgets/kernel/qlayout_p.h index 8a1b12a6be..8e1d773355 100644 --- a/src/widgets/kernel/qlayout_p.h +++ b/src/widgets/kernel/qlayout_p.h @@ -80,7 +80,7 @@ public: static QWidgetItem *createWidgetItem(const QLayout *layout, QWidget *widget); static QSpacerItem *createSpacerItem(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum); - virtual QLayoutItem* replaceAt(int index, QLayoutItem *newitem) { Q_UNUSED(index); Q_UNUSED(newitem); return 0; } + virtual QLayoutItem* replaceAt(int index, QLayoutItem *newitem) { Q_UNUSED(index); Q_UNUSED(newitem); return nullptr; } static QWidgetItemFactoryMethod widgetItemFactoryMethod; static QSpacerItemFactoryMethod spacerItemFactoryMethod; diff --git a/src/widgets/kernel/qlayoutengine_p.h b/src/widgets/kernel/qlayoutengine_p.h index 812fa7cf3b..948c2424e6 100644 --- a/src/widgets/kernel/qlayoutengine_p.h +++ b/src/widgets/kernel/qlayoutengine_p.h @@ -105,9 +105,9 @@ Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidgetItem *i); Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidget *w); Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QSize &sizeHint, const QSize &minSize, const QSize &maxSize, - const QSizePolicy &sizePolicy, Qt::Alignment align = 0); -Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align = 0); -Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidget *w, Qt::Alignment align = 0); + const QSizePolicy &sizePolicy, Qt::Alignment align = nullptr); +Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align = nullptr); +Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidget *w, Qt::Alignment align = nullptr); Q_WIDGETS_EXPORT int qSmartSpacing(const QLayout *layout, QStyle::PixelMetric pm); diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index 25890e888b..0aab0bb06d 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -309,24 +309,24 @@ void QLayoutItem::invalidate() /*! If this item is a QLayout, it is returned as a QLayout; otherwise - 0 is returned. This function provides type-safe casting. + \nullptr is returned. This function provides type-safe casting. \sa spacerItem(), widget() */ -QLayout * QLayoutItem::layout() +QLayout *QLayoutItem::layout() { - return 0; + return nullptr; } /*! If this item is a QSpacerItem, it is returned as a QSpacerItem; - otherwise 0 is returned. This function provides type-safe casting. + otherwise \nullptr is returned. This function provides type-safe casting. \sa layout(), widget() */ -QSpacerItem * QLayoutItem::spacerItem() +QSpacerItem *QLayoutItem::spacerItem() { - return 0; + return nullptr; } /*! @@ -354,7 +354,7 @@ QSpacerItem * QSpacerItem::spacerItem() /*! If this item manages a QWidget, returns that widget. Otherwise, - \c nullptr is returned. + \nullptr is returned. \note While the functions layout() and spacerItem() perform casts, this function returns another object: QLayout and QSpacerItem inherit QLayoutItem, @@ -362,9 +362,9 @@ QSpacerItem * QSpacerItem::spacerItem() \sa layout(), spacerItem() */ -QWidget * QLayoutItem::widget() +QWidget *QLayoutItem::widget() { - return 0; + return nullptr; } /*! @@ -502,6 +502,17 @@ void QWidgetItem::setGeometry(const QRect &rect) else if (!(align & Qt::AlignTop)) y = y + (r.height() - s.height()) / 2; + // Make sure we don't move outside of the parent, e.g when styles demand + // surplus space that exceeds the available margins (f.ex macOS with QGroupBox) + if (x < 0) { + s.rwidth() += x; + x = 0; + } + if (y < 0) { + s.rheight() += y; + y = 0; + } + wid->setGeometry(x, y, s.width(), s.height()); } diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 7aef74c507..ae7729b49b 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1118,8 +1118,8 @@ void QOpenGLWidget::setTextureFormat(GLenum texFormat) /*! \return the active internal texture format if the widget has already initialized, the requested format if one was set but the widget has not yet - been made visible, or 0 if setTextureFormat() was not called and the widget - has not yet been made visible. + been made visible, or \nullptr if setTextureFormat() was not called and the + widget has not yet been made visible. \since 5.10 */ @@ -1333,11 +1333,8 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const if (d->inBackingStorePaint) return QWidget::metric(metric); - QWidget *tlw = window(); - QWindow *window = tlw ? tlw->windowHandle() : 0; - QScreen *screen = tlw && tlw->windowHandle() ? tlw->windowHandle()->screen() : 0; - if (!screen && QGuiApplication::primaryScreen()) - screen = QGuiApplication::primaryScreen(); + auto window = d->windowHandle(QWidgetPrivate::WindowHandleMode::TopLevel); + QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen(); const float dpmx = qt_defaultDpiX() * 100. / 2.54; const float dpmy = qt_defaultDpiY() * 100. / 2.54; diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index b5a0cd3940..54bf8fe0dc 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 Q_DECL_NOTHROW +QSizePolicy::ControlType QSizePolicy::controlType() const noexcept { return QSizePolicy::ControlType(1 << bits.ctype); } @@ -253,7 +253,7 @@ QSizePolicy::ControlType QSizePolicy::controlType() const Q_DECL_NOTHROW \sa QStyle::layoutSpacing() */ -void QSizePolicy::setControlType(ControlType type) Q_DECL_NOTHROW +void QSizePolicy::setControlType(ControlType type) noexcept { bits.ctype = toControlTypeFieldValue(type); } diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index dba742dec5..f26923eeb0 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE class QVariant; class QSizePolicy; -Q_DECL_CONST_FUNCTION inline uint qHash(QSizePolicy key, uint seed = 0) Q_DECL_NOTHROW; +Q_DECL_CONST_FUNCTION inline uint qHash(QSizePolicy key, uint seed = 0) noexcept; class Q_WIDGETS_EXPORT QSizePolicy { @@ -110,60 +110,60 @@ public: Q_DECLARE_FLAGS(ControlTypes, ControlType) Q_FLAG(ControlTypes) - QT_SIZEPOLICY_CONSTEXPR QSizePolicy() Q_DECL_NOTHROW : data(0) { } + QT_SIZEPOLICY_CONSTEXPR QSizePolicy() noexcept : data(0) { } #if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC) - QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) noexcept : bits{0, 0, quint32(horizontal), quint32(vertical), type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0} {} #else - QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW + QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) noexcept : data(0) { bits.horPolicy = horizontal; bits.verPolicy = vertical; setControlType(type); } #endif // uniform-init - QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const Q_DECL_NOTHROW { return static_cast<Policy>(bits.horPolicy); } - QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const Q_DECL_NOTHROW { return static_cast<Policy>(bits.verPolicy); } - ControlType controlType() const Q_DECL_NOTHROW; + QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const noexcept { return static_cast<Policy>(bits.horPolicy); } + QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const noexcept { return static_cast<Policy>(bits.verPolicy); } + ControlType controlType() const noexcept; - 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; + Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) noexcept { bits.horPolicy = d; } + Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) noexcept { bits.verPolicy = d; } + void setControlType(ControlType type) noexcept; - QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const Q_DECL_NOTHROW { + QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const noexcept { return ( (verticalPolicy() & ExpandFlag) ? Qt::Vertical : Qt::Orientations() ) | ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ; } - 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; } + Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) noexcept { bits.hfw = b; } + QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const noexcept { return bits.hfw; } + Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) noexcept { bits.wfh = b; } + QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const noexcept { return bits.wfh; } - 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; } + QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const noexcept { return data == s.data; } + QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const noexcept { return data != s.data; } - friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) Q_DECL_NOTHROW { return qHash(key.data, seed); } + friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) noexcept { return qHash(key.data, seed); } operator QVariant() const; - QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const Q_DECL_NOTHROW { return static_cast<int>(bits.horStretch); } - QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const Q_DECL_NOTHROW { return static_cast<int>(bits.verStretch); } + QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const noexcept { return static_cast<int>(bits.horStretch); } + QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const noexcept { return static_cast<int>(bits.verStretch); } Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } - 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; } + QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const noexcept { return bits.retainSizeWhenHidden; } + Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) noexcept { bits.retainSizeWhenHidden = retainSize; } - Q_DECL_RELAXED_CONSTEXPR void transpose() Q_DECL_NOTHROW { *this = transposed(); } + Q_DECL_RELAXED_CONSTEXPR void transpose() noexcept { *this = transposed(); } Q_REQUIRED_RESULT #ifndef Q_QDOC QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT #endif - QSizePolicy transposed() const Q_DECL_NOTHROW + QSizePolicy transposed() const noexcept { return QSizePolicy(bits.transposed()); } @@ -173,11 +173,11 @@ 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) Q_DECL_NOTHROW : data(i) { } + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) noexcept : data(i) { } struct Bits; - QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { } + QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) noexcept : bits(b) { } - static Q_DECL_RELAXED_CONSTEXPR quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW + static Q_DECL_RELAXED_CONSTEXPR quint32 toControlTypeFieldValue(ControlType type) noexcept { /* The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, @@ -207,7 +207,7 @@ private: quint32 retainSizeWhenHidden : 1; QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT - Bits transposed() const Q_DECL_NOTHROW + Bits transposed() const noexcept { return {verStretch, // \ swap horStretch, // / diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp index 7430d833db..0412dc188d 100644 --- a/src/widgets/kernel/qstackedlayout.cpp +++ b/src/widgets/kernel/qstackedlayout.cpp @@ -378,20 +378,20 @@ void QStackedLayout::setCurrentWidget(QWidget *widget) /*! - Returns the current widget, or 0 if there are no widgets in this - layout. + Returns the current widget, or \nullptr if there are no widgets + in this layout. \sa currentIndex(), setCurrentWidget() */ QWidget *QStackedLayout::currentWidget() const { Q_D(const QStackedLayout); - return d->index >= 0 ? d->list.at(d->index)->widget() : 0; + return d->index >= 0 ? d->list.at(d->index)->widget() : nullptr; } /*! - Returns the widget at the given \a index, or 0 if there is no - widget at the given position. + Returns the widget at the given \a index, or \nullptr if there is + no widget at the given position. \sa currentWidget(), indexOf() */ @@ -399,7 +399,7 @@ QWidget *QStackedLayout::widget(int index) const { Q_D(const QStackedLayout); if (index < 0 || index >= d->list.size()) - return 0; + return nullptr; return d->list.at(index)->widget(); } diff --git a/src/widgets/kernel/qt_widgets_pch.h b/src/widgets/kernel/qt_widgets_pch.h index bec6536637..b70941950b 100644 --- a/src/widgets/kernel/qt_widgets_pch.h +++ b/src/widgets/kernel/qt_widgets_pch.h @@ -45,41 +45,17 @@ * UNSUPPORTED. */ -// from corelib/global/qt_pch.h +#include "../../gui/kernel/qt_gui_pch.h" + #if defined __cplusplus #include <qtwidgetsglobal.h> - - -#if 0 // Used to be included in Qt4 for Q_WS_WIN -# define _POSIX_ -# include <limits.h> -# undef _POSIX_ -#endif - -#include <qcoreapplication.h> -#include <qlist.h> -#include <qvariant.h> // All moc genereated code has this include -#include <qobject.h> -#include <qregexp.h> -#include <qstring.h> -#include <qstringlist.h> -#if QT_CONFIG(textcodec) -#include <qtextcodec.h> -#endif - #include <qapplication.h> -#include <qbitmap.h> -#include <qcursor.h> -#include <qdesktopwidget.h> -#include <qevent.h> -#include <qimage.h> +#include <qabstractbutton.h> +#include <qabstractscrollarea.h> +#include <qabstractslider.h> +#include <qaction.h> +#include <qcommonstyle.h> #include <qlayout.h> -#include <qpainter.h> -#include <qpixmap.h> #include <qstyle.h> -#include <qtimer.h> #include <qwidget.h> - -#include <stdlib.h> - #endif diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index cf0f3f153b..d030a28356 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -41,7 +41,6 @@ #endif #include <QtWidgets/private/qtwidgetsglobal_p.h> -#include <QtWidgets/private/qlabel_p.h> #include <qapplication.h> #include <qdesktopwidget.h> @@ -61,6 +60,7 @@ #ifndef QT_NO_TOOLTIP #include <qlabel.h> +#include <QtWidgets/private/qlabel_p.h> #include <qtooltip.h> #if 0 // Used to be included in Qt4 for Q_WS_MAC @@ -482,8 +482,8 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o) The \a rect is in the coordinates of the widget you specify with \a w. If the \a rect is not empty you must specify a widget. - Otherwise this argument can be 0 but it is used to determine the - appropriate screen on multi-head systems. + Otherwise this argument can be \nullptr but it is used to + determine the appropriate screen on multi-head systems. If \a text is empty the tool tip is hidden. If the text is the same as the currently shown tooltip, the tip will \e not move. diff --git a/src/widgets/kernel/qtooltip.h b/src/widgets/kernel/qtooltip.h index edf1de0c1d..1b263a6629 100644 --- a/src/widgets/kernel/qtooltip.h +++ b/src/widgets/kernel/qtooltip.h @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class Q_WIDGETS_EXPORT QToolTip { - QToolTip() Q_DECL_EQ_DELETE; + QToolTip() = delete; public: // ### Qt 6 - merge the three showText functions below static void showText(const QPoint &pos, const QString &text, QWidget *w = nullptr); diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index 1fa83d3238..4a798a7490 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -398,10 +398,10 @@ QWhatsThisPrivate::QWhatsThisPrivate() #ifdef QT_NO_CURSOR Q_UNUSED(sentEvent); #else - QApplication::setOverrideCursor((!sentEvent || !e.isAccepted())? + QGuiApplication::setOverrideCursor((!sentEvent || !e.isAccepted())? Qt::ForbiddenCursor:Qt::WhatsThisCursor); } else { - QApplication::setOverrideCursor(Qt::WhatsThisCursor); + QGuiApplication::setOverrideCursor(Qt::WhatsThisCursor); #endif } #ifndef QT_NO_ACCESSIBILITY @@ -417,7 +417,7 @@ QWhatsThisPrivate::~QWhatsThisPrivate() action->setChecked(false); #endif // QT_CONFIG(action) #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif #ifndef QT_NO_ACCESSIBILITY QAccessibleEvent event(this, QAccessible::ContextHelpEnd); diff --git a/src/widgets/kernel/qwhatsthis.h b/src/widgets/kernel/qwhatsthis.h index 59c0b01c9b..fa5b97d98a 100644 --- a/src/widgets/kernel/qwhatsthis.h +++ b/src/widgets/kernel/qwhatsthis.h @@ -54,7 +54,7 @@ class QAction; class Q_WIDGETS_EXPORT QWhatsThis { - QWhatsThis() Q_DECL_EQ_DELETE; + QWhatsThis() = delete; public: static void enterWhatsThisMode(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6ef3a4f163..2176c612d0 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -79,6 +79,7 @@ #include "private/qstylesheetstyle_p.h" #include "private/qstyle_p.h" #include "qfileinfo.h" +#include "qscopeguard.h" #include <QtGui/private/qhighdpiscaling_p.h> #include <QtGui/qinputmethod.h> #include <QtGui/qopenglcontext.h> @@ -511,10 +512,10 @@ void QWidget::setAutoFillBackground(bool enabled) Every widget's constructor accepts one or two standard arguments: \list 1 - \li \c{QWidget *parent = 0} is the parent of the new widget. If it is 0 - (the default), the new widget will be a window. If not, it will be - a child of \e parent, and be constrained by \e parent's geometry - (unless you specify Qt::Window as window flag). + \li \c{QWidget *parent = \nullptr} is the parent of the new widget. + If it is \nullptr (the default), the new widget will be a window. + If not, it will be a child of \e parent, and be constrained by + \e parent's geometry (unless you specify Qt::Window as window flag). \li \c{Qt::WindowFlags f = 0} (where available) sets the window flags; the default is suitable for almost all widgets, but to get, for example, a window without a window system frame, you must use @@ -1003,14 +1004,14 @@ struct QWidgetExceptionCleaner Constructs a widget which is a child of \a parent, with widget flags set to \a f. - If \a parent is 0, the new widget becomes a window. If + If \a parent is \nullptr, the new widget becomes a window. If \a parent is another widget, this widget becomes a child window inside \a parent. The new widget is deleted when its \a parent is deleted. The widget flags argument, \a f, is normally 0, but it can be set - to customize the frame of a window (i.e. \a - parent must be 0). To customize the frame, use a value composed + to customize the frame of a window (i.e. \a parent must be + \nullptr). To customize the frame, use a value composed from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}. If you add a child widget to an already visible widget you must @@ -1123,6 +1124,8 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w) void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) { Q_Q(QWidget); + Q_ASSERT_X(q != parentWidget, Q_FUNC_INFO, "Cannot parent a QWidget to itself"); + if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance()))) qFatal("QWidget: Cannot create a QWidget without QApplication"); @@ -1249,6 +1252,33 @@ void QWidgetPrivate::createRecursively() } } +QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const +{ + if (mode == WindowHandleMode::Direct || mode == WindowHandleMode::Closest) { + if (QTLWExtra *x = maybeTopData()) + return x->window; + } + if (mode == WindowHandleMode::Closest) { + if (auto nativeParent = q_func()->nativeParentWidget()) { + if (auto window = nativeParent->windowHandle()) + return window; + } + } + if (mode == WindowHandleMode::TopLevel || mode == WindowHandleMode::Closest) { + if (auto topLevel = q_func()->topLevelWidget()) { + if (auto window = topLevel ->windowHandle()) + return window; + } + } + return nullptr; +} + +QScreen *QWidgetPrivate::associatedScreen() const +{ + if (auto window = windowHandle(WindowHandleMode::Closest)) + return window->screen(); + return nullptr; +} // ### fixme: Qt 6: Remove parameter window from QWidget::create() @@ -1348,11 +1378,6 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)) setAttribute(Qt::WA_DropSiteRegistered, true); -#ifdef QT_EVAL - extern void qt_eval_init_widget(QWidget *w); - qt_eval_init_widget(this); -#endif - // need to force the resting of the icon after changing parents if (testAttribute(Qt::WA_SetWindowIcon)) d->setWindowIcon_sys(); @@ -2418,29 +2443,34 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrus } } -void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const +bool QWidgetPrivate::updateBrushOrigin(QPainter *painter, const QBrush &brush) const { - Q_Q(const QWidget); - #if QT_CONFIG(scrollarea) - bool resetBrushOrigin = false; - QPointF oldBrushOrigin; + Q_Q(const QWidget); //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture + if (brush.style() == Qt::NoBrush || brush.style() == Qt::SolidPattern) + return false; QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent); if (scrollArea && scrollArea->viewport() == q) { QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data(); QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate); - oldBrushOrigin = painter->brushOrigin(); - resetBrushOrigin = true; painter->setBrushOrigin(-priv->contentsOffset()); - } #endif // QT_CONFIG(scrollarea) + return true; +} +void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const +{ + Q_Q(const QWidget); + + bool brushOriginSet = false; const QBrush autoFillBrush = q->palette().brush(q->backgroundRole()); if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) { const QBrush bg = q->palette().brush(QPalette::Window); + if (!brushOriginSet) + brushOriginSet = updateBrushOrigin(painter, bg); if (!(flags & DontSetCompositionMode)) { //copy alpha straight in QPainter::CompositionMode oldMode = painter->compositionMode(); @@ -2452,8 +2482,11 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int } } - if (q->autoFillBackground()) + if (q->autoFillBackground()) { + if (!brushOriginSet) + brushOriginSet = updateBrushOrigin(painter, autoFillBrush); fillRegion(painter, rgn, autoFillBrush); + } if (q->testAttribute(Qt::WA_StyledBackground)) { painter->setClipRegion(rgn); @@ -2461,11 +2494,6 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int opt.initFrom(q); q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q); } - -#if QT_CONFIG(scrollarea) - if (resetBrushOrigin) - painter->setBrushOrigin(oldBrushOrigin); -#endif // QT_CONFIG(scrollarea) } /* @@ -2499,12 +2527,12 @@ void QWidgetPrivate::deactivateWidgetCleanup() The window identifier type depends on the underlying window system, see \c qwindowdefs.h for the actual definition. If there - is no widget with this identifier, 0 is returned. + is no widget with this identifier, \nullptr is returned. */ QWidget *QWidget::find(WId id) { - return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0; + return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : nullptr; } @@ -3297,7 +3325,7 @@ void QWidget::addActions(QList<QAction*> actions) /*! Inserts the action \a action to this widget's list of actions, - before the action \a before. It appends the action if \a before is 0 or + before the action \a before. It appends the action if \a before is \nullptr or \a before is not a valid action for this widget. A QWidget should only have one of each action. @@ -3331,7 +3359,7 @@ void QWidget::insertAction(QAction *before, QAction *action) /*! Inserts the actions \a actions to this widget's list of actions, - before the action \a before. It appends the action if \a before is 0 or + before the action \a before. It appends the action if \a before is \nullptr or \a before is not a valid action for this widget. A QWidget can have at most one of each action. @@ -4250,7 +4278,7 @@ void QWidget::setFixedHeight(int h) /*! Translates the widget coordinate \a pos to the coordinate system - of \a parent. The \a parent must not be 0 and must be a parent + of \a parent. The \a parent must not be \nullptr and must be a parent of the calling widget. \sa mapFrom(), mapToParent(), mapToGlobal(), underMouse() @@ -4275,7 +4303,7 @@ QPoint QWidget::mapTo(const QWidget * parent, const QPoint & pos) const /*! Translates the widget coordinate \a pos from the coordinate system of \a parent to this widget's coordinate system. The \a parent - must not be 0 and must be a parent of the calling widget. + must not be \nullptr and must be a parent of the calling widget. \sa mapTo(), mapFromParent(), mapFromGlobal(), underMouse() */ @@ -4354,7 +4382,8 @@ QWidget *QWidget::window() const \since 4.4 Returns the native parent for this widget, i.e. the next ancestor widget - that has a system identifier, or 0 if it does not have any native parent. + that has a system identifier, or \nullptr if it does not have any native + parent. \sa effectiveWinId() */ @@ -4975,9 +5004,9 @@ void QWidget::unsetLayoutDirection() Some underlying window implementations will reset the cursor if it leaves a widget even if the mouse is grabbed. If you want to have a cursor set for all widgets, even when outside the window, consider - QApplication::setOverrideCursor(). + QGuiApplication::setOverrideCursor(). - \sa QApplication::setOverrideCursor() + \sa QGuiApplication::setOverrideCursor() */ #ifndef QT_NO_CURSOR @@ -5290,7 +5319,7 @@ QPixmap QWidget::grab(const QRect &rectangle) \brief The graphicsEffect function returns a pointer to the widget's graphics effect. - If the widget has no graphics effect, 0 is returned. + If the widget has no graphics effect, \nullptr is returned. \since 4.6 @@ -5334,7 +5363,7 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect) return; if (d->graphicsEffect) { - d->invalidateBuffer(rect()); + d->invalidateBackingStore(rect()); delete d->graphicsEffect; d->graphicsEffect = 0; } @@ -5754,12 +5783,10 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, QPoint offset = targetOffset; offset -= paintRegion.boundingRect().topLeft(); QPoint redirectionOffset; - QPaintDevice *redirected = 0; + QPaintDevice *redirected = nullptr; if (target->devType() == QInternal::Widget) redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset); - if (!redirected) - redirected = QPainter::redirected(target, &redirectionOffset); if (redirected) { target = redirected; @@ -5936,10 +5963,10 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this widget and its ancestors. The search starts at \a origin (inclusive). - If successful, the function returns the proxy that embeds the widget, or 0 if no embedded - widget was found. + If successful, the function returns the proxy that embeds the widget, or \nullptr if no + embedded widget was found. */ -QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin) +QGraphicsProxyWidget *QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin) { if (origin) { QWExtra *extra = origin->d_func()->extra; @@ -5947,7 +5974,7 @@ QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget return extra->proxyWidget; return nearestGraphicsProxyWidget(origin->parentWidget()); } - return 0; + return nullptr; } #endif @@ -6073,13 +6100,7 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg { Q_ASSERT(widget); -#ifdef QT_EVAL - extern QString qt_eval_adapt_window_title(const QString &title); - QString cap = qt_eval_adapt_window_title(title); -#else QString cap = title; -#endif - if (cap.isEmpty()) return cap; @@ -6419,7 +6440,7 @@ void QWidget::setWindowRole(const QString &role) /*! - Sets the widget's focus proxy to widget \a w. If \a w is 0, the + Sets the widget's focus proxy to widget \a w. If \a w is \nullptr, the function resets this widget to have no focus proxy. Some widgets can "have focus", but create a child widget, such as @@ -6452,15 +6473,15 @@ void QWidget::setFocusProxy(QWidget * w) /*! - Returns the focus proxy, or 0 if there is no focus proxy. + Returns the focus proxy, or \nullptr if there is no focus proxy. \sa setFocusProxy() */ -QWidget * QWidget::focusProxy() const +QWidget *QWidget::focusProxy() const { Q_D(const QWidget); - return d->extra ? (QWidget *)d->extra->focus_proxy : 0; + return d->extra ? (QWidget *)d->extra->focus_proxy : nullptr; } @@ -7363,11 +7384,11 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (renderToTexture) { QRegion updateRegion(q->geometry()); updateRegion += QRect(oldPos, olds); - q->parentWidget()->d_func()->invalidateBuffer(updateRegion); + q->parentWidget()->d_func()->invalidateBackingStore(updateRegion); } else if (isMove && !isResize) { moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); } else { - invalidateBuffer_resizeHelper(oldPos, olds); + invalidateBackingStore_resizeHelper(oldPos, olds); } } } @@ -8126,10 +8147,10 @@ void QWidgetPrivate::show_sys() { Q_Q(QWidget); - QWidgetWindow *window = windowHandle(); + auto window = qobject_cast<QWidgetWindow *>(windowHandle()); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); q->setAttribute(Qt::WA_Mapped); // add our window the modal window list (native dialogs) if (window && q->isWindow() @@ -8172,7 +8193,7 @@ void QWidgetPrivate::show_sys() #ifndef QT_NO_CURSOR qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show #endif - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); window->setNativeWindowVisibility(true); // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? if (window->isTopLevel()) { @@ -8265,7 +8286,7 @@ void QWidgetPrivate::hide_sys() { Q_Q(QWidget); - QWidgetWindow *window = windowHandle(); + auto window = qobject_cast<QWidgetWindow *>(windowHandle()); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { q->setAttribute(Qt::WA_Mapped, false); @@ -8286,12 +8307,12 @@ void QWidgetPrivate::hide_sys() QWidget *p = q->parentWidget(); if (p &&p->isVisible()) { if (renderToTexture) - p->d_func()->invalidateBuffer(q->geometry()); + p->d_func()->invalidateBackingStore(q->geometry()); else - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); } } else { - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); } if (window) @@ -8845,7 +8866,7 @@ QSize QWidget::minimumSizeHint() const /*! \fn QWidget *QWidget::parentWidget() const - Returns the parent of this widget, or 0 if it does not have any + Returns the parent of this widget, or \nullptr if it does not have any parent widget. */ @@ -10189,7 +10210,11 @@ void QWidget::hideEvent(QHideEvent *) \endtable */ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +bool QWidget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) +#else bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) +#endif { Q_UNUSED(eventType); Q_UNUSED(message); @@ -10261,7 +10286,7 @@ QRegion QWidget::mask() const } /*! - Returns the layout manager that is installed on this widget, or 0 + Returns the layout manager that is installed on this widget, or \nullptr if no layout manager is installed. The layout manager sets the geometry of the widget's children @@ -10699,6 +10724,22 @@ static void sendWindowChangeToTextureChildrenRecursively(QWidget *widget) void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) { Q_D(QWidget); + Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QWidget to itself"); +#ifdef QT_DEBUG + const auto checkForParentChildLoops = qScopeGuard([&](){ + int depth = 0; + auto p = parentWidget(); + while (p) { + if (++depth == QObjectPrivate::CheckForParentChildLoopsWarnDepth) { + qWarning("QWidget %p (class: '%s', object name: '%s') may have a loop in its parent-child chain; " + "this is undefined behavior", + this, metaObject()->className(), qPrintable(objectName())); + } + p = p->parentWidget(); + } + }); +#endif + bool resized = testAttribute(Qt::WA_Resized); bool wasCreated = testAttribute(Qt::WA_WState_Created); QWidget *oldtlw = window(); @@ -11933,7 +11974,7 @@ void QWidget::raise() QRegion region(rect()); d->subtractOpaqueSiblings(region); - d->invalidateBuffer(region); + d->invalidateBackingStore(region); } if (testAttribute(Qt::WA_WState_Created)) d->raise_sys(); @@ -11953,7 +11994,7 @@ void QWidgetPrivate::raise_sys() } else if (renderToTexture) { if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } } @@ -12003,7 +12044,7 @@ void QWidgetPrivate::lower_sys() q->windowHandle()->lower(); } else if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } @@ -12047,7 +12088,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget*) Q_Q(QWidget); if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } @@ -12149,14 +12190,14 @@ bool QWidgetPrivate::navigateToDirection(Direction direction) Searches for a widget that is positioned in the \a direction, starting from the current focusWidget. - Returns the pointer to a found widget or 0, if there was no widget in - that direction. + Returns the pointer to a found widget or \nullptr, if there was no widget + in that direction. */ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) { const QWidget *sourceWidget = QApplication::focusWidget(); if (!sourceWidget) - return 0; + return nullptr; const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint())); const int sourceX = (direction == DirectionNorth || direction == DirectionSouth) ? @@ -12170,7 +12211,7 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) const QPoint sourceCenter = sourceRect.center(); const QWidget *sourceWindow = sourceWidget->window(); - QWidget *targetWidget = 0; + QWidget *targetWidget = nullptr; int shortestDistance = INT_MAX; const auto targetCandidates = QApplication::allWidgets(); @@ -12489,7 +12530,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) d->aboutToDestroy(); if (!isWindow() && parentWidget()) - parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); + parentWidget()->d_func()->invalidateBackingStore(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); if ((windowType() == Qt::Popup) && qApp) @@ -12837,7 +12878,7 @@ void QWidget::releaseKeyboard() Returns the widget that is currently grabbing the mouse input. If no widget in this application is currently grabbing the mouse, - 0 is returned. + \nullptr is returned. \sa grabMouse(), keyboardGrabber() */ @@ -12854,7 +12895,7 @@ QWidget *QWidget::mouseGrabber() Returns the widget that is currently grabbing the keyboard input. If no widget in this application is currently grabbing the - keyboard, 0 is returned. + keyboard, \nullptr is returned. \sa grabMouse(), mouseGrabber() */ @@ -13211,7 +13252,7 @@ QDebug operator<<(QDebug debug, const QWidget *widget) if (widget->isWindow()) debug << ", window"; debug << ", " << geometry.width() << 'x' << geometry.height() - << forcesign << geometry.x() << geometry.y() << noforcesign; + << Qt::forcesign << geometry.x() << geometry.y() << Qt::noforcesign; if (frameGeometry != geometry) { const QMargins margins(geometry.x() - frameGeometry.x(), geometry.y() - frameGeometry.y(), @@ -13221,7 +13262,7 @@ QDebug operator<<(QDebug debug, const QWidget *widget) } debug << ", devicePixelRatio=" << widget->devicePixelRatioF(); if (const WId wid = widget->internalWinId()) - debug << ", winId=0x" << hex << wid << dec; + debug << ", winId=0x" << Qt::hex << wid << Qt::dec; } debug << ')'; } else { diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 9d5fe89c70..e47deb5d0d 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -235,7 +235,10 @@ public: bool isEnabled() const; bool isEnabledTo(const QWidget *) const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use isEnabled() instead") bool isEnabledToTLW() const; +#endif public Q_SLOTS: void setEnabled(bool); @@ -552,7 +555,7 @@ public: void addAction(QAction *action); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) void addActions(const QList<QAction*> &actions); - void insertActions(const QAction *before, const QList<QAction*> &actions); + void insertActions(QAction *before, const QList<QAction*> &actions); #else void addActions(QList<QAction*> actions); void insertActions(QAction *before, QList<QAction*> actions); @@ -645,7 +648,12 @@ protected: virtual void showEvent(QShowEvent *event); virtual void hideEvent(QHideEvent *event); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + virtual bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result); +#else virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result); +#endif // Misc. protected functions virtual void changeEvent(QEvent *); @@ -769,8 +777,10 @@ inline bool QWidget::isEnabled() const inline bool QWidget::isModal() const { return data->window_modality != Qt::NonModal; } +#if QT_DEPRECATED_SINCE(5, 13) inline bool QWidget::isEnabledToTLW() const { return isEnabled(); } +#endif inline int QWidget::minimumWidth() const { return minimumSize().width(); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 64bc463ae2..99ec38e050 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -146,11 +146,11 @@ public: inline operator bool() const { - return (0 != m_ptr); + return (nullptr != m_ptr); } private: - Q_DISABLE_COPY(QWidgetBackingStoreTracker) + Q_DISABLE_COPY_MOVE(QWidgetBackingStoreTracker) private: QWidgetBackingStore* m_ptr; @@ -343,7 +343,15 @@ public: QPainter *sharedPainter() const; void setSharedPainter(QPainter *painter); QWidgetBackingStore *maybeBackingStore() const; - QWidgetWindow *windowHandle() const; + + enum class WindowHandleMode { + Direct, + Closest, + TopLevel + }; + QWindow *windowHandle(WindowHandleMode mode = WindowHandleMode::Direct) const; + + QScreen *associatedScreen() const; template <typename T> void repaint(T t); @@ -404,6 +412,7 @@ public: void setUpdatesEnabled_helper(bool ); + bool updateBrushOrigin(QPainter *, const QBrush &brush) const; void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const; bool isAboutToShow() const; QRegion prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags); @@ -412,7 +421,7 @@ public: void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion, QWidget::RenderFlags renderFlags); void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags, - QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0); + QPainter *sharedPainter = nullptr, QWidgetBackingStore *backingStore = nullptr); void sendPaintEvent(const QRegion &toBePainted); @@ -429,7 +438,7 @@ public: QRegion clipRegion() const; void setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion ®ion); void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const; - void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = 0, + void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = nullptr, bool alsoNonOpaque = false) const; void clipToEffectiveMask(QRegion ®ion) const; void updateIsOpaque(); @@ -453,10 +462,11 @@ public: void scrollChildren(int dx, int dy); void moveRect(const QRect &, int dx, int dy); void scrollRect(const QRect &, int dx, int dy); - void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize); - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void invalidateBuffer(const QRegion &); - void invalidateBuffer(const QRect &); + void invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize); + + template <class T> + void invalidateBackingStore(const T &); + QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const; void syncBackingStore(); void syncBackingStore(const QRegion ®ion); @@ -525,7 +535,7 @@ public: void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const; void setLayoutItemMargins(int left, int top, int right, int bottom); - void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0); + void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = nullptr); void updateContentsRect(); QMargins safeAreaMargins() const; @@ -555,7 +565,7 @@ public: QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget); //It's embedded if it has an ancestor if (ancestorProxy) { - if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != 0) { + if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != nullptr) { // One view, let be smart and return the viewport rect then the popup is aligned if (ancestorProxy->scene()->views().size() == 1) { QGraphicsView *view = ancestorProxy->scene()->views().at(0); @@ -586,7 +596,7 @@ public: } inline void restoreRedirected() - { redirectDev = 0; } + { redirectDev = nullptr; } inline void enforceNativeChildren() { @@ -608,6 +618,11 @@ public: return extra ? extra->nativeChildrenForced : false; } + inline QRect effectiveRectFor(const QRegion ®ion) const + { + return effectiveRectFor(region.boundingRect()); + } + inline QRect effectiveRectFor(const QRect &rect) const { #if QT_CONFIG(graphicseffect) @@ -647,7 +662,7 @@ public: QOpenGLContext *shareContext() const; - virtual QObject *focusObject() { return 0; } + virtual QObject *focusObject() { return nullptr; } #ifndef QT_NO_OPENGL virtual GLuint textureId() const { return 0; } @@ -655,7 +670,7 @@ public: Q_Q(QWidget); return q->testAttribute(Qt::WA_AlwaysStackOnTop) ? QPlatformTextureList::StacksOnTop - : QPlatformTextureList::Flags(0); + : QPlatformTextureList::Flags(nullptr); } virtual QImage grabFramebuffer() { return QImage(); } virtual void beginBackingStorePainting() { } @@ -899,7 +914,7 @@ struct QWidgetPaintContext { inline QWidgetPaintContext(QPaintDevice *d, const QRegion &r, const QPoint &o, int f, QPainter *p, QWidgetBackingStore *b) - : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), backingStore(b), painter(0) {} + : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), backingStore(b), painter(nullptr) {} QPaintDevice *pdev; QRegion rgn; @@ -915,14 +930,14 @@ class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate { public: QWidgetEffectSourcePrivate(QWidget *widget) - : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0), updateDueToGraphicsEffect(false) + : QGraphicsEffectSourcePrivate(), m_widget(widget), context(nullptr), updateDueToGraphicsEffect(false) {} void detach() override - { m_widget->d_func()->graphicsEffect = 0; } + { m_widget->d_func()->graphicsEffect = nullptr; } const QGraphicsItem *graphicsItem() const override - { return 0; } + { return nullptr; } const QWidget *widget() const override { return m_widget; } @@ -948,7 +963,7 @@ public: } const QStyleOption *styleOption() const override - { return 0; } + { return nullptr; } QRect deviceRect() const override { return m_widget->window()->rect(); } @@ -978,14 +993,14 @@ inline QTLWExtra *QWidgetPrivate::topData() const inline QTLWExtra *QWidgetPrivate::maybeTopData() const { - return extra ? extra->topextra : 0; + return extra ? extra->topextra : nullptr; } inline QPainter *QWidgetPrivate::sharedPainter() const { Q_Q(const QWidget); QTLWExtra *x = q->window()->d_func()->maybeTopData(); - return x ? x->sharedPainter : 0; + return x ? x->sharedPainter : nullptr; } inline void QWidgetPrivate::setSharedPainter(QPainter *painter) @@ -1006,14 +1021,7 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const { Q_Q(const QWidget); QTLWExtra *x = q->window()->d_func()->maybeTopData(); - return x ? x->backingStoreTracker.data() : 0; -} - -inline QWidgetWindow *QWidgetPrivate::windowHandle() const -{ - if (QTLWExtra *x = maybeTopData()) - return x->window; - return nullptr; + return x ? x->backingStoreTracker.data() : nullptr; } QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index a32eb2a03b..595beeaf47 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -310,12 +310,6 @@ bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *wi return store->scroll(tlwRect, dx, dy); } -void QWidgetBackingStore::releaseBuffer() -{ - if (store) - store->resize(QSize()); -} - /*! Prepares the window surface to paint a\ toClean region of the \a widget and updates the BeginPaintInfo struct accordingly. @@ -507,6 +501,9 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi } } +static inline QRect widgetRectFor(QWidget *, const QRect &r) { return r; } +static inline QRect widgetRectFor(QWidget *widget, const QRegion &) { return widget->rect(); } + /*! Marks the region of the widget as dirty (if not already marked as dirty) and posts an UpdateRequest event to the top-level widget (if not already posted). @@ -517,42 +514,44 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi If the widget paints directly on screen, the event is sent to the widget instead of the top-level widget, and bufferState is completely ignored. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). */ -void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, - UpdateTime updateTime, BufferState bufferState) +template <class T> +void QWidgetBackingStore::markDirty(const T &r, QWidget *widget, UpdateTime updateTime, BufferState bufferState) { Q_ASSERT(tlw->d_func()->extra); Q_ASSERT(tlw->d_func()->extra->topextra); Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rgn.isEmpty()); + Q_ASSERT(!r.isEmpty()); #if QT_CONFIG(graphicseffect) widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif // QT_CONFIG(graphicseffect) +#endif + + QRect widgetRect = widgetRectFor(widget, r); + + // --------------------------------------------------------------------------- if (widget->d_func()->paintOnScreen()) { if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = rgn; + widget->d_func()->dirty = r; sendUpdateRequest(widget, updateTime); return; - } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) { + } else if (qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { if (updateTime == UpdateNow) sendUpdateRequest(widget, updateTime); - return; // Already dirty. + return; // Already dirty } const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rgn; + widget->d_func()->dirty += r; if (!eventAlreadyPosted || updateTime == UpdateNow) sendUpdateRequest(widget, updateTime); return; } - const QPoint offset = widget->mapTo(tlw, QPoint()); + // --------------------------------------------------------------------------- if (QWidgetPrivate::get(widget)->renderToTexture) { if (!widget->d_func()->inDirtyList) @@ -562,133 +561,67 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, return; } - const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect()); - if (qt_region_strictContains(dirty, widgetRect.translated(offset))) { + // --------------------------------------------------------------------------- + + QRect effectiveWidgetRect = widget->d_func()->effectiveRectFor(widgetRect); + const QPoint offset = widget->mapTo(tlw, QPoint()); + QRect translatedRect = effectiveWidgetRect.translated(offset); +#if QT_CONFIG(graphicseffect) + // Graphics effects may exceed window size, clamp + translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size())); +#endif + if (qt_region_strictContains(dirty, translatedRect)) { if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); - return; // Already dirty. + return; // Already dirty } + // --------------------------------------------------------------------------- + if (bufferState == BufferInvalid) { const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent; #if QT_CONFIG(graphicseffect) if (widget->d_func()->graphicsEffect) - dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset); + dirty += widget->d_func()->effectiveRectFor(r).translated(offset); else -#endif // QT_CONFIG(graphicseffect) - dirty += rgn.translated(offset); +#endif + dirty += r.translated(offset); + if (!eventAlreadyPosted || updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); return; } + // --------------------------------------------------------------------------- + if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rgn); + addDirtyWidget(widget, r); sendUpdateRequest(tlw, updateTime); return; } + // --------------------------------------------------------------------------- + if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { + if (!qt_region_strictContains(widget->d_func()->dirty, effectiveWidgetRect)) { #if QT_CONFIG(graphicseffect) if (widget->d_func()->graphicsEffect) - widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()); + widget->d_func()->dirty += widget->d_func()->effectiveRectFor(r); else -#endif // QT_CONFIG(graphicseffect) - widget->d_func()->dirty += rgn; +#endif + widget->d_func()->dirty += r; } } else { - addDirtyWidget(widget, rgn); - } - - if (updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); -} - -/*! - This function is equivalent to calling markDirty(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, - UpdateTime updateTime, BufferState bufferState) -{ - Q_ASSERT(tlw->d_func()->extra); - Q_ASSERT(tlw->d_func()->extra->topextra); - Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); - Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); - Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rect.isEmpty()); - -#if QT_CONFIG(graphicseffect) - widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif // QT_CONFIG(graphicseffect) - - if (widget->d_func()->paintOnScreen()) { - if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = QRegion(rect); - sendUpdateRequest(widget, updateTime); - return; - } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) { - if (updateTime == UpdateNow) - sendUpdateRequest(widget, updateTime); - return; // Already dirty. - } - - const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rect; - if (!eventAlreadyPosted || updateTime == UpdateNow) - sendUpdateRequest(widget, updateTime); - return; + addDirtyWidget(widget, r); } - if (QWidgetPrivate::get(widget)->renderToTexture) { - if (!widget->d_func()->inDirtyList) - addDirtyRenderToTextureWidget(widget); - if (!updateRequestSent || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; - } - - - const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); - QRect translatedRect = widgetRect; - if (widget != tlw) - translatedRect.translate(widget->mapTo(tlw, QPoint())); - // Graphics effects may exceed window size, clamp. - translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size())); - if (qt_region_strictContains(dirty, translatedRect)) { - if (updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; // Already dirty - } - - if (bufferState == BufferInvalid) { - const bool eventAlreadyPosted = !dirty.isEmpty(); - dirty += translatedRect; - if (!eventAlreadyPosted || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; - } - - if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rect); - sendUpdateRequest(tlw, updateTime); - return; - } - - if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) - widget->d_func()->dirty += widgetRect; - } else { - addDirtyWidget(widget, rect); - } + // --------------------------------------------------------------------------- if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); } +template void QWidgetBackingStore::markDirty<QRect>(const QRect &, QWidget *, UpdateTime, BufferState); +template void QWidgetBackingStore::markDirty<QRegion>(const QRegion &, QWidget *, UpdateTime, BufferState); /*! Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from @@ -859,11 +792,11 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (!extra || !extra->hasMask) { parentR -= newRect; } else { - // invalidateBuffer() excludes anything outside the mask + // invalidateBackingStore() excludes anything outside the mask parentR += newRect & clipR; } - pd->invalidateBuffer(parentR); - invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); + pd->invalidateBackingStore(parentR); + invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft())); } else { QWidgetBackingStore *wbs = x->backingStoreTracker.data(); @@ -894,7 +827,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (childUpdatesEnabled) { if (!overlappedExpose.isEmpty()) { overlappedExpose.translate(-data.crect.topLeft()); - invalidateBuffer(overlappedExpose); + invalidateBackingStore(overlappedExpose); } if (!childExpose.isEmpty()) { childExpose.translate(-data.crect.topLeft()); @@ -944,9 +877,9 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) { QRegion region(scrollRect); subtractOpaqueSiblings(region); - invalidateBuffer(region); + invalidateBackingStore(region); }else { - invalidateBuffer(scrollRect); + invalidateBackingStore(scrollRect); } } else { const QPoint toplevelOffset = q->mapTo(tlw, QPoint()); @@ -987,7 +920,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; if (!overlappedExpose.isEmpty()) - invalidateBuffer(overlappedExpose); + invalidateBackingStore(overlappedExpose); if (!childExpose.isEmpty()) { wbs->markDirty(childExpose, q); isScrolled = true; @@ -1471,26 +1404,11 @@ void QWidgetBackingStore::flush(QWidget *widget) dirtyOnScreenWidgets->clear(); } -static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra) -{ - Q_ASSERT(widget); - if (QApplication::closingDown()) - return true; - - if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) - return true; - - if (!widget->isVisible() || !widget->updatesEnabled()) - return true; - - return false; -} - /*! - Invalidates the buffer when the widget is resized. + Invalidates the backing store when the widget is resized. Static areas are never invalidated unless absolutely needed. */ -void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize) +void QWidgetPrivate::invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize) { Q_Q(QWidget); Q_ASSERT(!q->isWindow()); @@ -1515,10 +1433,10 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q if (hasStaticChildren) { QRegion dirty(newWidgetRect); dirty -= staticChildren; - invalidateBuffer(dirty); + invalidateBackingStore(dirty); } else { // Entire widget needs repaint. - invalidateBuffer(newWidgetRect); + invalidateBackingStore(newWidgetRect); } if (!parentAreaExposed) @@ -1530,14 +1448,14 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q parentExpose &= QRect(oldPos, oldSize); if (hasStaticChildren) parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { if (hasStaticChildren && !graphicsEffect) { QRegion parentExpose(QRect(oldPos, oldSize)); parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { - q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize))); + q->parentWidget()->d_func()->invalidateBackingStore(effectiveRectFor(QRect(oldPos, oldSize))); } } return; @@ -1558,7 +1476,7 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) { QRegion newVisible(newWidgetRect); newVisible -= oldWidgetRect; - invalidateBuffer(newVisible); + invalidateBackingStore(newVisible); } if (!parentAreaExposed) @@ -1570,74 +1488,56 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q QRegion parentExpose(oldRect); parentExpose &= extra->mask.translated(oldPos); parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect); - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { QRegion parentExpose(oldRect); parentExpose -= data.crect; - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } } /*! - Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e. - all widgets intersecting with the region will be repainted when the backing store - is synced. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). + Invalidates the \a r (in widget's coordinates) of the backing store, i.e. + all widgets intersecting with the region will be repainted when the backing + store is synced. */ -void QWidgetPrivate::invalidateBuffer(const QRegion &rgn) +template <class T> +void QWidgetPrivate::invalidateBackingStore(const T &r) { - Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty()) + if (r.isEmpty()) return; - QRegion wrgn(rgn); - wrgn &= clipRect(); - if (!graphicsEffect && extra && extra->hasMask) - wrgn &= extra->mask; - if (wrgn.isEmpty()) + if (QApplication::closingDown()) return; - tlwExtra->backingStoreTracker->markDirty(wrgn, q, - QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); -} - -/*! - This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetPrivate::invalidateBuffer(const QRect &rect) -{ Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty()) + if (!q->isVisible() || !q->updatesEnabled()) return; - QRect wRect(rect); - wRect &= clipRect(); - if (wRect.isEmpty()) + QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); + if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) return; - if (graphicsEffect || !extra || !extra->hasMask) { - tlwExtra->backingStoreTracker->markDirty(wRect, q, - QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + T clipped(r); + clipped &= clipRect(); + if (clipped.isEmpty()) return; - } - QRegion wRgn(extra->mask); - wRgn &= wRect; - if (wRgn.isEmpty()) - return; + if (!graphicsEffect && extra && extra->hasMask) { + QRegion masked(extra->mask); + masked &= clipped; + if (masked.isEmpty()) + return; - tlwExtra->backingStoreTracker->markDirty(wRgn, q, + tlwExtra->backingStoreTracker->markDirty(masked, q, QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + } else { + tlwExtra->backingStoreTracker->markDirty(clipped, q, + QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + } } +// Needed by tst_QWidget +template Q_AUTOTEST_EXPORT void QWidgetPrivate::invalidateBackingStore<QRect>(const QRect &r); void QWidgetPrivate::repaint_sys(const QRegion &rgn) { diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 53ccda850a..9409ba7832 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -109,7 +109,7 @@ public: void sync(QWidget *exposedWidget, const QRegion &exposedRegion); void sync(); - void flush(QWidget *widget = 0); + void flush(QWidget *widget = nullptr); QBackingStore *backingStore() const { return store; } @@ -118,10 +118,8 @@ public: return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && dirtyRenderToTextureWidgets.isEmpty()); } - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void markDirty(const QRegion &rgn, QWidget *widget, UpdateTime updateTime = UpdateLater, - BufferState bufferState = BufferValid); - void markDirty(const QRect &rect, QWidget *widget, UpdateTime updateTime = UpdateLater, + template <class T> + void markDirty(const T &r, QWidget *widget, UpdateTime updateTime = UpdateLater, BufferState bufferState = BufferValid); private: @@ -151,14 +149,13 @@ private: void doSync(); bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget); - void releaseBuffer(); void beginPaint(QRegion &toClean, QWidget *widget, QBackingStore *backingStore, BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true); void endPaint(const QRegion &cleaned, QBackingStore *backingStore, BeginPaintInfo *beginPaintInfo); - QRegion dirtyRegion(QWidget *widget = 0) const; - QRegion staticContents(QWidget *widget = 0, const QRect &withinClipRect = QRect()) const; + QRegion dirtyRegion(QWidget *widget = nullptr) const; + QRegion staticContents(QWidget *widget = nullptr, const QRect &withinClipRect = QRect()) const; void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset); @@ -305,7 +302,7 @@ private: friend class QWidget; friend class QBackingStore; - Q_DISABLE_COPY(QWidgetBackingStore) + Q_DISABLE_COPY_MOVE(QWidgetBackingStore) }; QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index fbc71cd0ea..a5d9eee49d 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -106,6 +106,7 @@ public: if (QWidget *widget = q->widget()) QWidgetPrivate::get(widget)->updateContentsRect(); } + bool allowClickThrough(const QPoint &) const override; }; QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const @@ -221,6 +222,11 @@ static inline bool shouldBePropagatedToWidget(QEvent *event) } } +bool QWidgetWindowPrivate::allowClickThrough(const QPoint &) const +{ + return true; +} + bool QWidgetWindow::event(QEvent *event) { if (!m_widget) @@ -586,10 +592,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) w->window()->raise(); } - QWindow *win = w->windowHandle(); - if (!win) - win = w->nativeParentWidget()->windowHandle(); - if (win) { + if (auto win = qt_widget_private(w)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest)) { const QRect globalGeometry = win->isTopLevel() ? win->geometry() : QRect(win->mapToGlobal(QPoint(0, 0)), win->size()); @@ -1018,7 +1021,11 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event } } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) +#else bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) +#endif { return m_widget->nativeEvent(eventType, message, result); } @@ -1096,7 +1103,7 @@ void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e) } } if (fw && fw->isEnabled()) { - QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center(); + QPoint pos = fw->inputMethodQuery(Qt::ImCursorRectangle).toRect().center(); QContextMenuEvent widgetEvent(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos), e->modifiers()); QGuiApplication::forwardEvent(fw, &widgetEvent, e); diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index 0728135467..80a345465d 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -103,7 +103,11 @@ protected: #endif void handleExposeEvent(QExposeEvent *); void handleWindowStateChangedEvent(QWindowStateChangeEvent *event); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override; +#else bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; +#endif #if QT_CONFIG(tabletevent) void handleTabletEvent(QTabletEvent *); #endif diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h index a8754232a8..c6de168c10 100644 --- a/src/widgets/kernel/qwindowcontainer_p.h +++ b/src/widgets/kernel/qwindowcontainer_p.h @@ -64,7 +64,7 @@ class Q_WIDGETS_EXPORT QWindowContainer : public QWidget Q_DECLARE_PRIVATE(QWindowContainer) public: - explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); ~QWindowContainer(); QWindow *containedWindow() const; diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri index f6877b02db..3b3170beb1 100644 --- a/src/widgets/kernel/win.pri +++ b/src/widgets/kernel/win.pri @@ -2,4 +2,7 @@ # -------------------------------------------------------------------- INCLUDEPATH += ../3rdparty/wintab -!winrt: LIBS_PRIVATE *= -lshell32 -luxtheme -ldwmapi +!winrt { + LIBS_PRIVATE *= -luxtheme -ldwmapi + QMAKE_USE_PRIVATE += shell32 +} |