summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2017-09-28 16:21:21 +0200
committerJohan Helsing <johan.helsing@qt.io>2017-10-18 11:39:25 +0000
commitfa7a1f77226795ece274b3505655e522881a0e24 (patch)
tree3e3e730642b9f03dbdbbd385ae1a4900f5b7cb19 /tests
parent3876d75305d3a1d2967c887b9591a327f726d91e (diff)
downloadqtwayland-fa7a1f77226795ece274b3505655e522881a0e24.tar.gz
Fix crash after destroying view with mouse focus
Don't emit QWaylandSeat::mouseFocusChanged with a destroyed QWaylandView. QWaylandPointer has been refactored to make it easier to follow enter and leave logic. A missing emit for buttonPressedChanged has been fixed as well. This also adds a test for pointer events to verify that setting mouse focus works and that the crash has been fixed. Task-number: QTBUG-63208 Change-Id: Id0c174a7b609dfd0152f3ae446dd51fd8befd554 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/compositor/compositor/compositor.pro6
-rw-r--r--tests/auto/compositor/compositor/mockpointer.cpp97
-rw-r--r--tests/auto/compositor/compositor/mockpointer.h47
-rw-r--r--tests/auto/compositor/compositor/mockseat.cpp1
-rw-r--r--tests/auto/compositor/compositor/mockseat.h7
-rw-r--r--tests/auto/compositor/compositor/tst_compositor.cpp56
6 files changed, 212 insertions, 2 deletions
diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro
index f0cdaf32..112e2e74 100644
--- a/tests/auto/compositor/compositor/compositor.pro
+++ b/tests/auto/compositor/compositor/compositor.pro
@@ -20,11 +20,13 @@ SOURCES += \
testkeyboardgrabber.cpp \
mockclient.cpp \
mockseat.cpp \
- testseat.cpp
+ testseat.cpp \
+ mockpointer.cpp
HEADERS += \
testcompositor.h \
testkeyboardgrabber.h \
mockclient.h \
mockseat.h \
- testseat.h
+ testseat.h \
+ mockpointer.h
diff --git a/tests/auto/compositor/compositor/mockpointer.cpp b/tests/auto/compositor/compositor/mockpointer.cpp
new file mode 100644
index 00000000..6c51d8bd
--- /dev/null
+++ b/tests/auto/compositor/compositor/mockpointer.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mockpointer.h"
+
+static void pointerEnter(void *pointer, struct wl_pointer *wlPointer, uint serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y)
+{
+ Q_UNUSED(wlPointer);
+ Q_UNUSED(serial);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+
+ static_cast<MockPointer *>(pointer)->m_enteredSurface = surface;
+}
+
+static void pointerLeave(void *pointer, struct wl_pointer *wlPointer, uint32_t serial, struct wl_surface *surface)
+{
+ Q_UNUSED(pointer);
+ Q_UNUSED(wlPointer);
+ Q_UNUSED(serial);
+
+ Q_ASSERT(surface);
+
+ static_cast<MockPointer *>(pointer)->m_enteredSurface = nullptr;
+}
+
+static void pointerMotion(void *pointer, struct wl_pointer *wlPointer, uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
+ Q_UNUSED(pointer);
+ Q_UNUSED(wlPointer);
+ Q_UNUSED(time);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+}
+
+static void pointerButton(void *pointer, struct wl_pointer *wlPointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
+{
+ Q_UNUSED(pointer);
+ Q_UNUSED(wlPointer);
+ Q_UNUSED(serial);
+ Q_UNUSED(time);
+ Q_UNUSED(button);
+ Q_UNUSED(state);
+}
+
+static void pointerAxis(void *pointer, struct wl_pointer *wlPointer, uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ Q_UNUSED(pointer);
+ Q_UNUSED(wlPointer);
+ Q_UNUSED(time);
+ Q_UNUSED(axis);
+ Q_UNUSED(value);
+}
+
+static const struct wl_pointer_listener pointerListener = {
+ pointerEnter,
+ pointerLeave,
+ pointerMotion,
+ pointerButton,
+ pointerAxis,
+};
+
+MockPointer::MockPointer(wl_seat *seat)
+ : m_pointer(wl_seat_get_pointer(seat))
+{
+ wl_pointer_add_listener(m_pointer, &pointerListener, this);
+}
+
+MockPointer::~MockPointer()
+{
+ wl_pointer_destroy(m_pointer);
+}
diff --git a/tests/auto/compositor/compositor/mockpointer.h b/tests/auto/compositor/compositor/mockpointer.h
new file mode 100644
index 00000000..35386141
--- /dev/null
+++ b/tests/auto/compositor/compositor/mockpointer.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOCKPOINTER_H
+#define MOCKPOINTER_H
+
+#include <QObject>
+#include <wayland-client.h>
+
+class MockPointer : public QObject
+{
+ Q_OBJECT
+
+public:
+ MockPointer(wl_seat *seat);
+ ~MockPointer();
+
+ wl_pointer *m_pointer = nullptr;
+ wl_surface *m_enteredSurface = nullptr;
+};
+
+#endif // MOCKPOINTER_H
diff --git a/tests/auto/compositor/compositor/mockseat.cpp b/tests/auto/compositor/compositor/mockseat.cpp
index 29c4a4e1..052c2f90 100644
--- a/tests/auto/compositor/compositor/mockseat.cpp
+++ b/tests/auto/compositor/compositor/mockseat.cpp
@@ -30,6 +30,7 @@
MockSeat::MockSeat(wl_seat *seat)
: m_seat(seat)
+ , m_pointer(new MockPointer(seat))
{
// Bind to the keyboard interface so that the compositor has
// the right resource associations
diff --git a/tests/auto/compositor/compositor/mockseat.h b/tests/auto/compositor/compositor/mockseat.h
index 1c6d324c..e6d5e0b1 100644
--- a/tests/auto/compositor/compositor/mockseat.h
+++ b/tests/auto/compositor/compositor/mockseat.h
@@ -28,6 +28,8 @@
#ifndef MOCKSEAT
#define MOCKSEAT
+#include "mockpointer.h"
+
#include <QObject>
#include <wayland-client.h>
@@ -38,8 +40,13 @@ class MockSeat : public QObject
public:
MockSeat(wl_seat *seat);
~MockSeat();
+ MockPointer *pointer() const { return m_pointer.data(); }
wl_seat *m_seat;
wl_keyboard *m_keyboard;
+
+private:
+ QScopedPointer<MockPointer> m_pointer;
};
+
#endif
diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp
index 3d7d2dab..6f00b6e6 100644
--- a/tests/auto/compositor/compositor/tst_compositor.cpp
+++ b/tests/auto/compositor/compositor/tst_compositor.cpp
@@ -27,6 +27,8 @@
****************************************************************************/
#include "mockclient.h"
+#include "mockseat.h"
+#include "mockpointer.h"
#include "testcompositor.h"
#include "testkeyboardgrabber.h"
#include "testseat.h"
@@ -56,6 +58,7 @@ private slots:
void keyboardGrab();
void seatCreation();
void seatKeyboardFocus();
+ void seatMouseFocus();
void singleClient();
void multipleClients();
void geometry();
@@ -438,6 +441,59 @@ void tst_WaylandCompositor::seatKeyboardFocus()
QTRY_VERIFY(!compositor.defaultSeat()->keyboardFocus());
}
+void tst_WaylandCompositor::seatMouseFocus()
+{
+ TestCompositor compositor(true);
+ compositor.create();
+
+ // Create client after all the seats have been set up as the mock client
+ // does not dynamically listen to new seats
+ MockClient client;
+ wl_surface *surface = client.createSurface();
+ QTRY_COMPARE(compositor.surfaces.size(), 1);
+
+ QWaylandSurface *waylandSurface = compositor.surfaces.at(0);
+ auto view = new QWaylandView;
+ view->setSurface(waylandSurface);
+
+ QWaylandSeat* seat = compositor.defaultSeat();
+ seat->setMouseFocus(view);
+ seat->sendMouseMoveEvent(view, QPointF(10, 10), QPointF(100, 100));
+
+ compositor.flushClients();
+
+ QTRY_VERIFY(seat->mouseFocus());
+ QTRY_VERIFY(seat->pointer());
+ QTRY_COMPARE(seat->mouseFocus()->surface(), waylandSurface);
+
+ QTRY_COMPARE(client.m_seats.size(), 1);
+ MockPointer *mockPointer = client.m_seats.first()->pointer();
+ QVERIFY(mockPointer);
+ QTRY_COMPARE(mockPointer->m_enteredSurface, surface);
+
+ delete view;
+
+ compositor.flushClients();
+
+ QTRY_COMPARE(mockPointer->m_enteredSurface, nullptr);
+ QTRY_VERIFY(!compositor.defaultSeat()->mouseFocus());
+
+ view = new QWaylandView;
+ view->setSurface(waylandSurface);
+ seat->sendMouseMoveEvent(view, QPointF(10, 10), QPointF(100, 100));
+ QTRY_COMPARE(compositor.defaultSeat()->mouseFocus(), view);
+
+ compositor.flushClients();
+
+ QTRY_COMPARE(mockPointer->m_enteredSurface, surface);
+
+ wl_surface_destroy(surface);
+ QTRY_VERIFY(compositor.surfaces.size() == 0);
+ QTRY_VERIFY(!compositor.defaultSeat()->mouseFocus());
+
+ delete view;
+}
+
class XdgTestCompositor: public TestCompositor {
Q_OBJECT
public: