summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2022-01-04 10:35:04 +0100
committerMarc Mutz <marc.mutz@qt.io>2022-04-14 19:07:16 +0200
commitda0f72ebb817bb9c92c7a183b281d8a4bf31a135 (patch)
tree072e6051b2464dba616634b94e1657d695a81715 /tests/auto/gui
parentec59ae6189c2a0405cc50f548c95c7007603934f (diff)
QEvent: start to de-inline copy ctor and clone() of all subclasses
There's no advantage to them being inline: Absent de-virtualisation, clone() is only supposed to be called through the vtable, and the copy ctor is only supposed to be used in the implementation of clone(). And when the compiler de-virtualises, we don't want the code duplication associated with inlining. Enforce this by introducing new macros to hide the boilerplate. This fixes missing out-of-line dtors in: - QSinglePointEvent - QApplicationStateChangeEvent - QFutureCallOutEvent Wrong covariant return in: - QFutureCallOutEvent And missing clone() reimplementations in: - QCloseEvent - QIconDragEvent - QShowEvent - QHideEvent - QDragEnterEvent - QDragLeaveEvent While these don't carry extra data or members, a dynamic_cast of the result of clone() as well as using the expected covariant return value would fail: QShowEvent *e = ~~~; QShowEvent *e2 = e->clone(); // ERROR: converting QEvent* to QShowEvent* Check that reimplementing clone() is binary compatible (covariant returns may change the numerical pointer value returned, cf. https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B). The copy-assignment operator stays inline for the time being, as the goal is to = delete it in the future. This patch covers, roughly, QtCore and QtGui. [ChangeLog][QtGui][QEvent subclasses] Fixed missing clone() reimplementations on QCloseEvent, QIconDragEvent, QShowEvent, QHideEvent, QDragEnterEvent, and QDragLeaveEvent. Task-number: QTBUG-45582 Task-number: QTBUG-97601 Change-Id: Ib8a0519dbe85a7a8da61050d48be338004dfa69a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/gui')
-rw-r--r--tests/auto/gui/kernel/qevent/CMakeLists.txt3
-rw-r--r--tests/auto/gui/kernel/qevent/tst_qevent.cpp82
2 files changed, 83 insertions, 2 deletions
diff --git a/tests/auto/gui/kernel/qevent/CMakeLists.txt b/tests/auto/gui/kernel/qevent/CMakeLists.txt
index 2bb22eb469..7b37b0c51a 100644
--- a/tests/auto/gui/kernel/qevent/CMakeLists.txt
+++ b/tests/auto/gui/kernel/qevent/CMakeLists.txt
@@ -7,4 +7,7 @@
qt_internal_add_test(tst_qevent
SOURCES
tst_qevent.cpp
+ PUBLIC_LIBRARIES
+ Qt::Gui
+ Qt::CorePrivate
)
diff --git a/tests/auto/gui/kernel/qevent/tst_qevent.cpp b/tests/auto/gui/kernel/qevent/tst_qevent.cpp
index 6542ed5ad3..cc8ac6ea6c 100644
--- a/tests/auto/gui/kernel/qevent/tst_qevent.cpp
+++ b/tests/auto/gui/kernel/qevent/tst_qevent.cpp
@@ -29,8 +29,73 @@
#include <QTest>
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qcoreevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qevent.h>
+#include <QtCore/private/qfutureinterface_p.h>
+
+#define FOR_EACH_CORE_EVENT(X) \
+ /* qcoreevent.h */ \
+ X(QEvent, (QEvent::None)) \
+ X(QTimerEvent, (42)) \
+ X(QChildEvent, (QEvent::ChildAdded, nullptr)) \
+ X(QDynamicPropertyChangeEvent, ("size")) \
+ X(QDeferredDeleteEvent, ()) \
+ /* qfutureinterface_p.h */ \
+ X(QFutureCallOutEvent, ()) \
+ /* end */
+
+#define FOR_EACH_GUI_EVENT(X) \
+ /* qevent.h */ \
+ X(QInputEvent, (QEvent::None, nullptr)) \
+ X(QPointerEvent, (QEvent::None, nullptr)) \
+ /* doesn't work with nullptr: */ \
+ X(QSinglePointEvent, (QEvent::None, QPointingDevice::primaryPointingDevice(), {}, {}, {}, {}, {}, {})) \
+ X(QEnterEvent, ({}, {}, {})) \
+ X(QMouseEvent, (QEvent::None, {}, {}, {}, {}, {}, {}, {}, QPointingDevice::primaryPointingDevice())) \
+ X(QHoverEvent, (QEvent::None, {}, {}, QPointF{})) \
+ X(QWheelEvent, ({}, {}, {}, {}, {}, {}, {}, {})) \
+ X(QTabletEvent, (QEvent::None, QPointingDevice::primaryPointingDevice(), {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {})) \
+ X(QNativeGestureEvent, ({}, QPointingDevice::primaryPointingDevice(), 0, {}, {}, {}, {}, {})) \
+ X(QKeyEvent, (QEvent::None, 0, {})) \
+ X(QFocusEvent, (QEvent::None)) \
+ X(QPaintEvent, (QRect{0, 0, 100, 100})) \
+ X(QMoveEvent, ({}, {})) \
+ X(QExposeEvent, ({})) \
+ X(QPlatformSurfaceEvent, ({})) \
+ X(QResizeEvent, ({}, {})) \
+ X(QCloseEvent, ()) \
+ X(QIconDragEvent, ()) \
+ X(QShowEvent, ()) \
+ X(QHideEvent, ()) \
+ QT_WARNING_PUSH \
+ QT_WARNING_DISABLE_DEPRECATED \
+ X(QContextMenuEvent, (QContextMenuEvent::Reason::Keyboard, {})) \
+ QT_WARNING_POP \
+ X(QInputMethodEvent, ()) \
+ X(QInputMethodQueryEvent, ({})) \
+ X(QDropEvent, ({}, {}, {}, {}, {})) \
+ X(QDragMoveEvent, ({}, {}, {}, {}, {})) \
+ X(QDragEnterEvent, ({}, {}, {}, {}, {})) \
+ X(QDragLeaveEvent, ()) \
+ X(QHelpEvent, ({}, {}, {})) \
+ X(QStatusTipEvent, ({})) \
+ X(QWhatsThisClickedEvent, ({})) \
+ X(QActionEvent, (0, nullptr)) \
+ X(QFileOpenEvent, (QString{})) \
+ X(QToolBarChangeEvent, (false)) \
+ X(QShortcutEvent, ({}, 0)) \
+ X(QWindowStateChangeEvent, ({})) \
+ X(QTouchEvent, (QEvent::None)) \
+ X(QScrollPrepareEvent, ({})) \
+ X(QScrollEvent, ({}, {}, {})) \
+ X(QScreenOrientationChangeEvent, (nullptr, {})) \
+ X(QApplicationStateChangeEvent, ({})) \
+ /* end */
+
+#define FOR_EACH_EVENT(X) \
+ FOR_EACH_CORE_EVENT(X) \
+ FOR_EACH_GUI_EVENT(X) \
+ /* end */
class tst_QEvent : public QObject
{
@@ -40,6 +105,7 @@ public:
~tst_QEvent();
private slots:
+ void clone() const;
void registerEventType_data();
void registerEventType();
void exhaustEventTypeRegistration(); // keep behind registerEventType() test
@@ -55,6 +121,18 @@ tst_QEvent::tst_QEvent()
tst_QEvent::~tst_QEvent()
{ }
+void tst_QEvent::clone() const
+{
+#define ACTION(Type, Init) do { \
+ const std::unique_ptr<const Type> e(new Type Init); \
+ auto c = e->clone(); \
+ static_assert(std::is_same_v<decltype(c), Type *>); \
+ delete c; \
+ } while (0);
+
+ FOR_EACH_EVENT(ACTION)
+}
+
void tst_QEvent::registerEventType_data()
{
QTest::addColumn<int>("hint");