summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-03-02 09:04:38 +0100
committerLiang Qi <liang.qi@qt.io>2017-03-02 09:04:38 +0100
commit71264bae08d81bdeceb96133fdb01c370504dfcc (patch)
treed5dadaac8209d5ef1857a4d65197b9ee12b39848 /src/widgets/kernel
parent5e785c0b83c9908c665f253c131629ac325a21f5 (diff)
parent6d10f739cd750968d0dd0e9d8fa4b64353a86c6c (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r--src/widgets/kernel/qapplication.cpp12
-rw-r--r--src/widgets/kernel/qsizepolicy.cpp28
-rw-r--r--src/widgets/kernel/qsizepolicy.h91
-rw-r--r--src/widgets/kernel/qwidget.cpp34
-rw-r--r--src/widgets/kernel/qwidget.h10
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp20
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp8
7 files changed, 117 insertions, 86 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 2c85ed3c0b..0e4ee30c19 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -3182,17 +3182,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (!w->hasMouseTracking()
&& mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
// but still send them through all application event filters (normally done by notify_helper)
- for (int i = 0; d->extraData && i < d->extraData->eventFilters.size(); ++i) {
- QObject *obj = d->extraData->eventFilters.at(i);
- if (!obj)
- continue;
- if (Q_UNLIKELY(obj->d_func()->threadData != w->d_func()->threadData)) {
- qWarning("QApplication: Object event filter cannot be in a different thread.");
- continue;
- }
- if (obj->eventFilter(w, w == receiver ? mouse : &me))
- break;
- }
+ d->sendThroughApplicationEventFilters(w, w == receiver ? mouse : &me);
res = true;
} else {
w->setAttribute(Qt::WA_NoMouseReplay, false);
diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp
index b08a9abb1e..b5a0cd3940 100644
--- a/src/widgets/kernel/qsizepolicy.cpp
+++ b/src/widgets/kernel/qsizepolicy.cpp
@@ -232,7 +232,7 @@ QT_BEGIN_NAMESPACE
Returns the control type associated with the widget for which
this size policy applies.
*/
-QSizePolicy::ControlType QSizePolicy::controlType() const
+QSizePolicy::ControlType QSizePolicy::controlType() const Q_DECL_NOTHROW
{
return QSizePolicy::ControlType(1 << bits.ctype);
}
@@ -253,35 +253,11 @@ QSizePolicy::ControlType QSizePolicy::controlType() const
\sa QStyle::layoutSpacing()
*/
-void QSizePolicy::setControlType(ControlType type)
+void QSizePolicy::setControlType(ControlType type) Q_DECL_NOTHROW
{
bits.ctype = toControlTypeFieldValue(type);
}
-quint32 QSizePolicy::toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW
-{
- /*
- The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
- etc. In memory, we pack it onto the available bits (CTSize) in
- setControlType(), and unpack it here.
-
- Example:
-
- 0x00000001 maps to 0
- 0x00000002 maps to 1
- 0x00000004 maps to 2
- 0x00000008 maps to 3
- etc.
- */
-
- int i = 0;
- while (true) {
- if (type & (0x1 << i))
- return i;
- ++i;
- }
-}
-
/*!
\fn void QSizePolicy::setHeightForWidth(bool dependent)
diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h
index 83ce5853ab..07d8393c6f 100644
--- a/src/widgets/kernel/qsizepolicy.h
+++ b/src/widgets/kernel/qsizepolicy.h
@@ -42,6 +42,7 @@
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtCore/qobject.h>
+#include <QtCore/qalgorithms.h>
QT_BEGIN_NAMESPACE
@@ -51,10 +52,6 @@ QT_BEGIN_NAMESPACE
# define QT_SIZEPOLICY_CONSTEXPR Q_DECL_CONSTEXPR
# if defined(Q_COMPILER_UNIFORM_INIT)
# define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT Q_DECL_CONSTEXPR
-# if defined(Q_COMPILER_CONSTEXPR)
-# define QT_SIZEPOLICY_RETURN_BITS(E1, E2, E3, E4, E5, E6, E7, E8) \
- return Bits{ E1, E2, E3, E4, E5, E6, E7, E8 }
-# endif // constexpr && uniform-init
# endif // uniform-init
#endif
@@ -64,10 +61,6 @@ QT_BEGIN_NAMESPACE
#ifndef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
# define QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
#endif
-#ifndef QT_SIZEPOLICY_RETURN_BITS
-# define QT_SIZEPOLICY_RETURN_BITS(E1, E2, E3, E4, E5, E6, E7, E8) \
- const Bits result = { E1, E2, E3, E4, E5, E6, E7, E8 }; return result
-#endif
class QVariant;
class QSizePolicy;
@@ -117,55 +110,55 @@ public:
Q_DECLARE_FLAGS(ControlTypes, ControlType)
Q_FLAG(ControlTypes)
- QT_SIZEPOLICY_CONSTEXPR QSizePolicy() : data(0) { }
+ QT_SIZEPOLICY_CONSTEXPR QSizePolicy() Q_DECL_NOTHROW : data(0) { }
#ifdef Q_COMPILER_UNIFORM_INIT
- QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType)
+ QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW
: bits{0, 0, quint32(horizontal), quint32(vertical),
type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0}
{}
#else
- QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType)
+ QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) Q_DECL_NOTHROW
: data(0) {
bits.horPolicy = horizontal;
bits.verPolicy = vertical;
setControlType(type);
}
#endif // uniform-init
- QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); }
- QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); }
- ControlType controlType() const;
+ 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;
- Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) { bits.horPolicy = d; }
- Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) { bits.verPolicy = d; }
- void setControlType(ControlType type);
+ Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) Q_DECL_NOTHROW { bits.horPolicy = d; }
+ Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) Q_DECL_NOTHROW { bits.verPolicy = d; }
+ void setControlType(ControlType type) Q_DECL_NOTHROW;
- QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const {
+ QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const Q_DECL_NOTHROW {
return ( (verticalPolicy() & ExpandFlag) ? Qt::Vertical : Qt::Orientations() )
| ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ;
}
- Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) { bits.hfw = b; }
- QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const { return bits.hfw; }
- Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) { bits.wfh = b; }
- QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const { return bits.wfh; }
+ Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) Q_DECL_NOTHROW { bits.hfw = b; }
+ QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const Q_DECL_NOTHROW { return bits.hfw; }
+ Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) Q_DECL_NOTHROW { bits.wfh = b; }
+ QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const Q_DECL_NOTHROW { return bits.wfh; }
- QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const { return data == s.data; }
- QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const { return data != s.data; }
+ QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const Q_DECL_NOTHROW { return data == s.data; }
+ QT_SIZEPOLICY_CONSTEXPR bool operator!=(const QSizePolicy& s) const Q_DECL_NOTHROW { return data != s.data; }
friend Q_DECL_CONST_FUNCTION uint qHash(QSizePolicy key, uint seed) Q_DECL_NOTHROW { return qHash(key.data, seed); }
operator QVariant() const;
- QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const { return static_cast<int>(bits.horStretch); }
- QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const { return static_cast<int>(bits.verStretch); }
+ 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); }
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 { return bits.retainSizeWhenHidden; }
- Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; }
+ QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const Q_DECL_NOTHROW { return bits.retainSizeWhenHidden; }
+ Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) Q_DECL_NOTHROW { bits.retainSizeWhenHidden = retainSize; }
- Q_DECL_RELAXED_CONSTEXPR void transpose() { *this = transposed(); }
+ Q_DECL_RELAXED_CONSTEXPR void transpose() Q_DECL_NOTHROW { *this = transposed(); }
#ifndef Q_QDOC
QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
#endif
@@ -179,11 +172,28 @@ private:
friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
#endif
- QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) : data(i) { }
+ QT_SIZEPOLICY_CONSTEXPR QSizePolicy(int i) Q_DECL_NOTHROW : data(i) { }
struct Bits;
QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { }
- static quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW;
+ static Q_DECL_RELAXED_CONSTEXPR quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW
+ {
+ /*
+ The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
+ etc. In memory, we pack it onto the available bits (CTSize) in
+ setControlType(), and unpack it here.
+
+ Example:
+
+ 0x00000001 maps to 0
+ 0x00000002 maps to 1
+ 0x00000004 maps to 2
+ 0x00000008 maps to 3
+ etc.
+ */
+
+ return qCountTrailingZeroBits(static_cast<quint32>(type));
+ }
struct Bits {
quint32 horStretch : 8;
@@ -198,14 +208,14 @@ private:
QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
Bits transposed() const Q_DECL_NOTHROW
{
- QT_SIZEPOLICY_RETURN_BITS(verStretch, // \ swap
- horStretch, // /
- verPolicy, // \ swap
- horPolicy, // /
- ctype,
- hfw, // \ don't swap (historic behavior)
- wfh, // /
- retainSizeWhenHidden);
+ return {verStretch, // \ swap
+ horStretch, // /
+ verPolicy, // \ swap
+ horPolicy, // /
+ ctype,
+ hfw, // \ don't swap (historic behavior)
+ wfh, // /
+ retainSizeWhenHidden};
}
};
union {
@@ -216,6 +226,8 @@ private:
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
// Can't add in Qt 5, as QList<QSizePolicy> would be BiC:
Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE);
+#else
+Q_DECLARE_TYPEINFO(QSizePolicy, Q_RELOCATABLE_TYPE);
#endif
Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
@@ -232,7 +244,6 @@ Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QSizePolicy &);
#undef QT_SIZEPOLICY_CONSTEXPR
#undef QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
-#undef QT_SIZEPOLICY_RETURN_BITS
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index cf9fbe2572..8a642940cd 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -6386,6 +6386,24 @@ void QWidget::setWindowRole(const QString &role)
\sa mouseMoveEvent()
*/
+/*!
+ \property QWidget::tabletTracking
+ \brief whether tablet tracking is enabled for the widget
+ \since 5.9
+
+ If tablet tracking is disabled (the default), the widget only
+ receives tablet move events when the stylus is in contact with
+ the tablet, or at least one stylus button is pressed,
+ while the stylus is being moved.
+
+ If tablet tracking is enabled, the widget receives tablet move
+ events even while hovering in proximity. This is useful for
+ monitoring position as well as the auxiliary properties such
+ as rotation and tilt, and providing feedback in the UI.
+
+ \sa tabletEvent()
+*/
+
/*!
Sets the widget's focus proxy to widget \a w. If \a w is 0, the
@@ -8787,6 +8805,9 @@ bool QWidget::event(QEvent *event)
#endif
#ifndef QT_NO_TABLETEVENT
case QEvent::TabletMove:
+ if (static_cast<QTabletEvent *>(event)->buttons() == Qt::NoButton && !testAttribute(Qt::WA_TabletTracking))
+ break;
+ Q_FALLTHROUGH();
case QEvent::TabletPress:
case QEvent::TabletRelease:
tabletEvent((QTabletEvent*)event);
@@ -9019,6 +9040,7 @@ bool QWidget::event(QEvent *event)
case QEvent::IconTextChange:
case QEvent::ModifiedChange:
case QEvent::MouseTrackingChange:
+ case QEvent::TabletTrackingChange:
case QEvent::ParentChange:
case QEvent::LocaleChange:
case QEvent::MacSizeChange:
@@ -9424,7 +9446,13 @@ void QWidget::wheelEvent(QWheelEvent *event)
The default implementation ignores the event.
- \sa QEvent::ignore(), QEvent::accept(), event(),
+ If tablet tracking is switched off, tablet move events only occur if the
+ stylus is in contact with the tablet, or at least one stylus button is
+ pressed, while the stylus is being moved. If tablet tracking is switched on,
+ tablet move events occur even while the stylus is hovering in proximity of
+ the tablet, with no buttons pressed.
+
+ \sa QEvent::ignore(), QEvent::accept(), event(), setTabletTracking(),
QTabletEvent
*/
@@ -11193,6 +11221,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
QEvent e(QEvent::MouseTrackingChange);
QApplication::sendEvent(this, &e);
break; }
+ case Qt::WA_TabletTracking: {
+ QEvent e(QEvent::TabletTrackingChange);
+ QApplication::sendEvent(this, &e);
+ break; }
case Qt::WA_NativeWindow: {
d->createTLExtra();
if (on)
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index 4c80038a4f..1c378924a0 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -161,6 +161,7 @@ class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
#endif
Q_PROPERTY(bool mouseTracking READ hasMouseTracking WRITE setMouseTracking)
+ Q_PROPERTY(bool tabletTracking READ hasTabletTracking WRITE setTabletTracking)
Q_PROPERTY(bool isActiveWindow READ isActiveWindow)
Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy)
Q_PROPERTY(bool focus READ hasFocus)
@@ -328,6 +329,9 @@ public:
bool hasMouseTracking() const;
bool underMouse() const;
+ void setTabletTracking(bool enable);
+ bool hasTabletTracking() const;
+
void setMask(const QBitmap &);
void setMask(const QRegion &);
QRegion mask() const;
@@ -809,6 +813,12 @@ inline bool QWidget::hasMouseTracking() const
inline bool QWidget::underMouse() const
{ return testAttribute(Qt::WA_UnderMouse); }
+inline void QWidget::setTabletTracking(bool enable)
+{ setAttribute(Qt::WA_TabletTracking, enable); }
+
+inline bool QWidget::hasTabletTracking() const
+{ return testAttribute(Qt::WA_TabletTracking); }
+
inline bool QWidget::updatesEnabled() const
{ return !testAttribute(Qt::WA_UpdatesDisabled); }
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 7295cc36f6..5abce140ce 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -973,22 +973,26 @@ bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long
void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
{
static QPointer<QWidget> qt_tablet_target = 0;
- if (event->type() == QEvent::TabletPress) {
- QWidget *widget = m_widget->childAt(event->pos());
- if (!widget)
- widget = m_widget;
- qt_tablet_target = widget;
+ QWidget *widget = qt_tablet_target;
+
+ if (!widget) {
+ widget = m_widget->childAt(event->pos());
+ if (event->type() == QEvent::TabletPress) {
+ if (!widget)
+ widget = m_widget;
+ qt_tablet_target = widget;
+ }
}
- if (qt_tablet_target) {
+ if (widget) {
QPointF delta = event->globalPosF() - event->globalPos();
- QPointF mapped = qt_tablet_target->mapFromGlobal(event->globalPos()) + delta;
+ QPointF mapped = widget->mapFromGlobal(event->globalPos()) + delta;
QTabletEvent ev(event->type(), mapped, event->globalPosF(), event->device(), event->pointerType(),
event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(),
event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons());
ev.setTimestamp(event->timestamp());
- QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev);
+ QGuiApplication::sendSpontaneousEvent(widget, &ev);
event->setAccepted(ev.isAccepted());
}
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index e72479fd09..a17c69c5ce 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -241,6 +241,14 @@ QWindow *QWindowContainer::containedWindow() const
QWindowContainer::~QWindowContainer()
{
Q_D(QWindowContainer);
+
+ // Call destroy() explicitly first. The dtor would do this too, but
+ // QEvent::PlatformSurface delivery relies on virtuals. Getting
+ // SurfaceAboutToBeDestroyed can be essential for OpenGL, Vulkan, etc.
+ // QWindow subclasses in particular. Keep these working.
+ if (d->window)
+ d->window->destroy();
+
delete d->window;
}