diff options
author | Jørgen Lind <jorgen.lind@theqtcompany.com> | 2015-05-07 17:10:07 +0200 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@theqtcompany.com> | 2015-08-28 13:09:42 +0200 |
commit | 65800110cb5887c1c110d44307d90c89d708bf9a (patch) | |
tree | f8eb59adc56fd8a2f433f1b73047570ff3345795 /src | |
parent | 8ea41bfe32de3b4dd4c15ec91c8925b1c6508c53 (diff) |
Mouse mouseFocus handling to the QWaylandInputDevice
This because both the touch interface and pointer interface depends on
it
Change-Id: I64718e0db87085c656250a22107715ddb68bc9ae
Diffstat (limited to 'src')
-rw-r--r-- | src/compositor/compositor_api/qwaylandinput.cpp | 15 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandinput.h | 5 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandpointer.cpp | 27 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandpointer.h | 3 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurfaceitem.cpp | 2 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandtouch.cpp | 180 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandtouch.h | 106 | ||||
-rw-r--r-- | src/compositor/extensions/qwlshellsurface.cpp | 1 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlinputdevice.cpp | 26 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlinputdevice_p.h | 5 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlpointer.cpp | 31 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlpointer_p.h | 54 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwltouch.cpp | 11 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwltouch_p.h | 17 |
14 files changed, 381 insertions, 102 deletions
diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp index b2176c7f9..b16ae8d4b 100644 --- a/src/compositor/compositor_api/qwaylandinput.cpp +++ b/src/compositor/compositor_api/qwaylandinput.cpp @@ -57,8 +57,9 @@ QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, co QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags caps) - : QObject(*new QWaylandInputDevicePrivate(this,compositor, caps)) + : QObject(*new QWaylandInputDevicePrivate(this,compositor)) { + d_func()->setCapabilities(caps); } QWaylandInputDevice::~QWaylandInputDevice() @@ -92,12 +93,6 @@ void QWaylandInputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int d d->sendMouseWheelEvent(orientation, delta); } -void QWaylandInputDevice::sendResetCurrentMouseView() -{ - Q_D(QWaylandInputDevice); - d->sendResetCurrentMouseView(); -} - void QWaylandInputDevice::sendKeyPressEvent(uint code) { keyboard()->sendKeyPressEvent(code); @@ -175,6 +170,12 @@ QWaylandSurfaceView *QWaylandInputDevice::mouseFocus() const return d->mouseFocus(); } +void QWaylandInputDevice::setMouseFocus(QWaylandSurfaceView *view) +{ + Q_D(QWaylandInputDevice); + d->setMouseFocus(view); +} + QWaylandOutputSpace *QWaylandInputDevice::outputSpace() const { Q_D(const QWaylandInputDevice); diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandinput.h index 84a630f4a..786eeb46f 100644 --- a/src/compositor/compositor_api/qwaylandinput.h +++ b/src/compositor/compositor_api/qwaylandinput.h @@ -106,7 +106,6 @@ public: void sendMouseReleaseEvent(Qt::MouseButton button); void sendMouseMoveEvent(QWaylandSurfaceView *surface , const QPointF &localPos, const QPointF &globalPos = QPointF()); void sendMouseWheelEvent(Qt::Orientation orientation, int delta); - void sendResetCurrentMouseView(); void sendKeyPressEvent(uint code); void sendKeyReleaseEvent(uint code); @@ -122,6 +121,8 @@ public: QWaylandPointer *pointer() const; + //Normally set by the mouse device, + //But can be set manually for use with touch or can reset unset the current mouse focus; QWaylandSurfaceView *mouseFocus() const; void setMouseFocus(QWaylandSurfaceView *view); @@ -144,7 +145,7 @@ public: virtual bool isOwner(QInputEvent *inputEvent) const; Q_SIGNALS: - void mouseFocusChanged(); + void mouseFocusChanged(QWaylandSurfaceView *newFocus, QWaylandSurfaceView *oldFocus); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandInputDevice::CapabilityFlags) diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index 07f327adf..6262f9b92 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -49,6 +49,7 @@ QWaylandPointer::QWaylandPointer(QWaylandInputDevice *seat, QObject *parent) : QObject(* new QWaylandPointerPrivate(this, seat), parent) { connect(&d_func()->m_focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandPointer::focusDestroyed); + connect(seat, &QWaylandInputDevice::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged); } void QWaylandDefaultPointerGrabber::focus() @@ -160,12 +161,6 @@ void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta d->sendMouseWheelEvent(orientation, delta); } -void QWaylandPointer::resetCurrentView() -{ - Q_D(QWaylandPointer); - d->resetCurrentState(); -} - QWaylandSurfaceView *QWaylandPointer::currentView() const { Q_D(const QWaylandPointer); @@ -202,6 +197,9 @@ struct wl_resource *QWaylandPointer::focusResource() const if (!d->focusResource()) return Q_NULLPTR; + if (!d->focusResource()) + return Q_NULLPTR; + return d->focusResource()->handle; } @@ -247,11 +245,26 @@ void QWaylandPointer::focusDestroyed(void *data) Q_UNUSED(data) d->m_focusDestroyListener.reset(); - d->m_currentPosition.reset(); + inputDevice()->setMouseFocus(Q_NULLPTR); d->m_focusResource = 0; d->m_buttonCount = 0; endGrab(); } +void QWaylandPointer::pointerFocusChanged(QWaylandSurfaceView *newFocus, QWaylandSurfaceView *oldFocus) +{ + Q_UNUSED(newFocus); + Q_D(QWaylandPointer); + d->m_localPosition = QPointF(); + d->m_hasSentEnter = false; + if (d->m_focusResource && oldFocus) { + uint32_t serial = compositor()->nextSerial(); + d->send_leave(d->m_focusResource->handle, serial, oldFocus->surfaceResource()); + d->m_focusDestroyListener.reset(); + d->m_focusResource = 0; + } + +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandpointer.h b/src/compositor/compositor_api/qwaylandpointer.h index a11140733..6cfe9a5f9 100644 --- a/src/compositor/compositor_api/qwaylandpointer.h +++ b/src/compositor/compositor_api/qwaylandpointer.h @@ -104,7 +104,6 @@ public: virtual void sendMouseMoveEvent(QWaylandSurfaceView *view, const QPointF &localPos, const QPointF &outputSpacePos); virtual void sendMouseWheelEvent(Qt::Orientation orientation, int delta); - void resetCurrentView(); QWaylandSurfaceView *currentView() const; QPointF currentLocalPosition() const; QPointF currentSpacePosition() const; @@ -123,7 +122,7 @@ Q_SIGNALS: private: void focusDestroyed(void *data); - void pointerFocusChanged(); + void pointerFocusChanged(QWaylandSurfaceView *newFocus, QWaylandSurfaceView *oldFocus); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index b174961d9..8f32019ef 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -249,7 +249,7 @@ void QWaylandSurfaceItem::hoverLeaveEvent(QHoverEvent *event) { if (shouldSendInputEvents()) { QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendResetCurrentMouseView(); + inputDevice->setMouseFocus(Q_NULLPTR); } else { event->ignore(); } diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp new file mode 100644 index 000000000..f1cb9de6b --- /dev/null +++ b/src/compositor/compositor_api/qwaylandtouch.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandtouch.h" + +#include <QtCompositor/QWaylandCompositor> +#include <QtCompositor/QWaylandInputDevice> +#include <QtCompositor/QWaylandSurfaceView> +#include <QtCompositor/QWaylandClient> + +#include "qwltouch_p.h" + +QT_BEGIN_NAMESPACE + +QWaylandTouchGrabber::QWaylandTouchGrabber() +{ +} + +QWaylandTouchGrabber::~QWaylandTouchGrabber() +{ +} + +QWaylandDefaultTouchGrabber::QWaylandDefaultTouchGrabber() + : QWaylandTouchGrabber() +{ +} + +void QWaylandDefaultTouchGrabber::down(uint32_t time, int touch_id, const QPointF &position) +{ + if (!touch->focusResource() || !touch->mouseFocus()) + return; + + uint32_t serial = wl_display_next_serial(touch->compositor()->waylandDisplay()); + + wl_touch_send_down(touch->focusResource(), serial, time, touch->mouseFocus()->surfaceResource(), touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); +} + +void QWaylandDefaultTouchGrabber::up(uint32_t time, int touch_id) +{ + if (!touch->focusResource()) + return; + + uint32_t serial = touch->compositor()->nextSerial(); + + wl_touch_send_up(touch->focusResource(), serial, time, touch_id); +} +void QWaylandDefaultTouchGrabber::motion(uint32_t time, int touch_id, const QPointF &position) +{ + if (!touch->focusResource()) + return; + + wl_touch_send_motion(touch->focusResource(), time, touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); +} + +QWaylandTouch::QWaylandTouch(QWaylandInputDevice *seat, QObject *parent) + : QObject(*new QWaylandTouchPrivate(this, seat), parent) +{ + connect(&d_func()->m_focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandTouch::focusDestroyed); +} + +QWaylandInputDevice *QWaylandTouch::inputDevice() const +{ + Q_D(const QWaylandTouch); + return d->m_seat; +} + +QWaylandCompositor *QWaylandTouch::compositor() const +{ + Q_D(const QWaylandTouch); + return d->compositor(); +} + + +void QWaylandTouch::startGrab(QWaylandTouchGrabber *grab) +{ + Q_D(QWaylandTouch); + d->startGrab(grab); +} + +void QWaylandTouch::endGrab() +{ + Q_D(QWaylandTouch); + d->endGrab(); +} + +void QWaylandTouch::sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state) +{ + Q_D(QWaylandTouch); + d->sendTouchPoint(id, position, state); +} + +void QWaylandTouch::sendFrameEvent() +{ + Q_D(QWaylandTouch); + d->sendFrame(); +} + +void QWaylandTouch::sendCancelEvent() +{ + Q_D(QWaylandTouch); + d->sendCancel(); +} + +void QWaylandTouch::sendFullTouchEvent(QTouchEvent *event) +{ + Q_D(QWaylandTouch); + d->sendFullTouchEvent(event); +} + +void QWaylandTouch::addClient(QWaylandClient *client, uint32_t id) +{ + Q_D(QWaylandTouch); + d->add(client->client(), id); +} + +struct wl_resource *QWaylandTouch::focusResource() const +{ + Q_D(const QWaylandTouch); + if (!d->focusResource()) + return Q_NULLPTR; + return d->focusResource()->handle; +} + +QWaylandSurfaceView *QWaylandTouch::mouseFocus() const +{ + Q_D(const QWaylandTouch); + return d->m_seat->mouseFocus(); +} + +void QWaylandTouch::focusDestroyed(void *data) +{ + Q_UNUSED(data) + Q_D(QWaylandTouch); + d->resetFocusState(); +} + +void QWaylandTouch::mouseFocusChanged(QWaylandSurfaceView *newFocus, QWaylandSurfaceView *oldFocus) +{ + Q_UNUSED(newFocus); + Q_UNUSED(oldFocus); + Q_D(QWaylandTouch); + d->resetFocusState(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandtouch.h b/src/compositor/compositor_api/qwaylandtouch.h new file mode 100644 index 000000000..a53cc6f51 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandtouch.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDTOUCH_H +#define QWAYLANDTOUCH_H + +#include <QtCompositor/QWaylandExtensionContainer> + +#include <QtCore/QObject> +#include <QtGui/QTouchEvent> + +QT_BEGIN_NAMESPACE + +class QWaylandTouch; +class QWaylandTouchPrivate; +class QWaylandInputDevice; +class QWaylandSurfaceView; +class QWaylandClient; + +class Q_COMPOSITOR_EXPORT QWaylandTouchGrabber { +public: + QWaylandTouchGrabber(); + virtual ~QWaylandTouchGrabber(); + + virtual void down(uint32_t time, int touch_id, const QPointF &position) = 0; + virtual void up(uint32_t time, int touch_id) = 0; + virtual void motion(uint32_t time, int touch_id, const QPointF &position) = 0; + + QWaylandTouch *touch; +}; + +class Q_COMPOSITOR_EXPORT QWaylandDefaultTouchGrabber : public QWaylandTouchGrabber +{ +public: + QWaylandDefaultTouchGrabber(); + + void down(uint32_t time, int touch_id, const QPointF &position) Q_DECL_OVERRIDE; + void up(uint32_t time, int touch_id) Q_DECL_OVERRIDE; + void motion(uint32_t time, int touch_id, const QPointF &position) Q_DECL_OVERRIDE; +}; + +class Q_COMPOSITOR_EXPORT QWaylandTouch : public QObject, public QWaylandExtensionContainer +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandTouch) +public: + QWaylandTouch(QWaylandInputDevice *seat, QObject *parent = 0); + + QWaylandInputDevice *inputDevice() const; + QWaylandCompositor *compositor() const; + + void startGrab(QWaylandTouchGrabber *grab); + void endGrab(); + + virtual void sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state); + virtual void sendFrameEvent(); + virtual void sendCancelEvent(); + + virtual void sendFullTouchEvent(QTouchEvent *event); + + void addClient(QWaylandClient *client, uint32_t id); + + struct wl_resource *focusResource() const; + + QWaylandSurfaceView *mouseFocus() const; +private: + void focusDestroyed(void *data); + void mouseFocusChanged(QWaylandSurfaceView *newFocus, QWaylandSurfaceView *oldFocus); +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDTOUCH_H*/ diff --git a/src/compositor/extensions/qwlshellsurface.cpp b/src/compositor/extensions/qwlshellsurface.cpp index ad171aa0e..58cd6c936 100644 --- a/src/compositor/extensions/qwlshellsurface.cpp +++ b/src/compositor/extensions/qwlshellsurface.cpp @@ -474,7 +474,6 @@ void ShellSurfaceMoveGrabber::button(uint32_t time, Qt::MouseButton button, uint Q_UNUSED(time) if (button == Qt::LeftButton && !state) { - pointer->resetCurrentView(); pointer->endGrab(); shell_surface->resetMoveGrabber(); delete this; diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp index 768050435..9f180e212 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp @@ -54,16 +54,14 @@ QT_BEGIN_NAMESPACE -QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inputdevice, QWaylandCompositor *compositor, QWaylandInputDevice::CapabilityFlags caps) +QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inputdevice, QWaylandCompositor *compositor) : QObjectPrivate() , QtWaylandServer::wl_seat(compositor->waylandDisplay(), 3) , m_dragHandle(new QWaylandDrag(inputdevice)) , m_compositor(compositor) , m_outputSpace(compositor->primaryOutputSpace()) - , m_capabilities(caps) - , m_pointer(m_capabilities & QWaylandInputDevice::Pointer ? new QWaylandPointer(inputdevice) : 0) - , m_keyboard(m_capabilities & QWaylandInputDevice::Keyboard ? new QWaylandKeyboard(inputdevice) : 0) - , m_touch(m_capabilities & QWaylandInputDevice::Touch ? new QWaylandTouch(inputdevice) : 0) + , m_mouseFocus(Q_NULLPTR) + , m_capabilities() , m_inputMethod(m_compositor->extensionFlags() & QWaylandCompositor::TextInputExtension ? new QtWayland::InputMethod(m_compositor, inputdevice) : 0) , m_data_device() { @@ -172,11 +170,6 @@ void QWaylandInputDevicePrivate::sendMouseWheelEvent(Qt::Orientation orientation pointerDevice()->sendMouseWheelEvent(orientation, delta); } -void QWaylandInputDevicePrivate::sendResetCurrentMouseView() -{ - pointerDevice()->resetCurrentView(); -} - void QWaylandInputDevicePrivate::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state) { if (m_touch.isNull()) { @@ -265,7 +258,18 @@ bool QWaylandInputDevicePrivate::setKeyboardFocus(QWaylandSurface *surface) QWaylandSurfaceView *QWaylandInputDevicePrivate::mouseFocus() const { - return m_pointer.isNull() ? 0 : m_pointer->currentView(); + return m_mouseFocus; +} + +void QWaylandInputDevicePrivate::setMouseFocus(QWaylandSurfaceView *focus) +{ + Q_Q(QWaylandInputDevice); + if (focus == m_mouseFocus) + return; + + QWaylandSurfaceView *oldFocus = m_mouseFocus; + m_mouseFocus = focus; + q->mouseFocusChanged(m_mouseFocus, oldFocus); } void QWaylandInputDevicePrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id) diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h index dba63c05a..08cc96c2e 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h +++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h @@ -79,14 +79,13 @@ class Q_COMPOSITOR_EXPORT QWaylandInputDevicePrivate : public QObjectPrivate, pu public: Q_DECLARE_PUBLIC(QWaylandInputDevice) - QWaylandInputDevicePrivate(QWaylandInputDevice *device, QWaylandCompositor *compositor, QWaylandInputDevice::CapabilityFlags caps); + QWaylandInputDevicePrivate(QWaylandInputDevice *device, QWaylandCompositor *compositor); ~QWaylandInputDevicePrivate(); void sendMousePressEvent(Qt::MouseButton button); void sendMouseReleaseEvent(Qt::MouseButton button); void sendMouseMoveEvent(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &spacePos = QPointF()); void sendMouseWheelEvent(Qt::Orientation orientation, int delta); - void sendResetCurrentMouseView(); void sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state); void sendTouchFrameEvent(); @@ -101,6 +100,7 @@ public: bool setKeyboardFocus(QWaylandSurface *surface); QWaylandSurfaceView *mouseFocus() const; + void setMouseFocus(QWaylandSurfaceView *focus); void clientRequestedDataDevice(QtWayland::DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); const QtWayland::DataDevice *dataDevice() const; @@ -129,6 +129,7 @@ private: QScopedPointer<QWaylandDrag> m_dragHandle; QWaylandCompositor *m_compositor; QWaylandOutputSpace *m_outputSpace; + QWaylandSurfaceView *m_mouseFocus; QWaylandInputDevice::CapabilityFlags m_capabilities; QScopedPointer<QWaylandPointer> m_pointer; diff --git a/src/compositor/wayland_wrapper/qwlpointer.cpp b/src/compositor/wayland_wrapper/qwlpointer.cpp index 127003d36..a41ae8a3e 100644 --- a/src/compositor/wayland_wrapper/qwlpointer.cpp +++ b/src/compositor/wayland_wrapper/qwlpointer.cpp @@ -57,6 +57,7 @@ QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylan , m_grabTime() , m_grabSerial() , m_focusResource() + , m_hasSentEnter(false) , m_buttonCount() { } @@ -67,7 +68,7 @@ void QWaylandPointerPrivate::startGrab(QWaylandPointerGrabber *grab) m_grab = grab; grab->pointer = q; - if (m_currentPosition.view()) + if (focusView()) grab->focus(); } @@ -146,29 +147,37 @@ void QWaylandPointerPrivate::sendMouseReleaseEvent(Qt::MouseButton button) void QWaylandPointerPrivate::sendMouseMoveEvent(QWaylandSurfaceView *view, const QPointF &localPos, const QPointF &outputSpacePos) { Q_Q(QWaylandPointer); - if (m_focusResource && focusView() != view) { - uint32_t serial = wl_display_next_serial(compositor()->waylandDisplay()); - send_leave(m_focusResource->handle, serial, focusView()->surface()->handle()->resource()->handle); - m_focusDestroyListener.reset(); + m_seat->setMouseFocus(view); + m_localPosition = localPos; + m_spacePosition = outputSpacePos; + + //we adjust if the mouse position is on the edge + //to work around Qt's event propogation + if (view && view->surface()) { + QSizeF size(view->surface()->size()); + if (m_localPosition.x() == size.width()) + m_localPosition.rx() -= 0.01; + + if (m_localPosition.y() == size.height()) + m_localPosition.ry() -= 0.01; } Resource *resource = view ? resourceMap().value(view->surface()->handle()->resource()->client()) : 0; - - if (resource && (focusView() != view || resource != m_focusResource)) { - uint32_t serial = wl_display_next_serial(compositor()->waylandDisplay()); + if (resource && !m_hasSentEnter) { + uint32_t serial = compositor()->nextSerial(); QWaylandKeyboard *keyboard = m_seat->keyboard(); if (keyboard) { keyboard->sendKeyModifiers(view->surface()->client(), serial); } send_enter(resource->handle, serial, view->surface()->handle()->resource()->handle, - wl_fixed_from_double(currentLocalPosition().x()), wl_fixed_from_double(currentLocalPosition().y())); + wl_fixed_from_double(m_localPosition.x()), wl_fixed_from_double(m_localPosition.y())); m_focusDestroyListener.listenForDestruction(view->surface()->handle()->resource()->handle); + m_hasSentEnter = true; } m_focusResource = resource; - m_currentPosition.updatePosition(view, localPos); - m_spacePosition = outputSpacePos; + if (view && view->output()) q->setOutput(view->output()); diff --git a/src/compositor/wayland_wrapper/qwlpointer_p.h b/src/compositor/wayland_wrapper/qwlpointer_p.h index 616464318..f79418575 100644 --- a/src/compositor/wayland_wrapper/qwlpointer_p.h +++ b/src/compositor/wayland_wrapper/qwlpointer_p.h @@ -63,49 +63,6 @@ namespace QtWayland { class Compositor; class Surface; -class CurrentPosition -{ -public: - CurrentPosition() - : m_view(Q_NULLPTR) - {} - - void reset() - { - m_point = QPointF(); - m_view = Q_NULLPTR; - } - - void updatePosition(QWaylandSurfaceView *view, const QPointF &position) - { - m_view = view; - m_point = position; - //we adjust if the mouse position is on the edge - //to work around Qt's event propogation - if (!m_view || position.isNull()) - return; - if (m_view->surface()) { - QSizeF size(m_view->surface()->size()); - if (m_point.x() == size.width()) - m_point.rx() -= 0.01; - - if (m_point.y() == size.height()) - m_point.ry() -= 0.01; - } - } - - QPointF position() const { return m_point; } - qreal x() const { return m_point.x(); } - qreal y() const { return m_point.y(); } - - QWaylandSurfaceView *view() const { return m_view; } - -private: - QWaylandSurfaceView *m_view; - QPointF m_point; -}; - - } // namespace QtWayland class Q_COMPOSITOR_EXPORT QWaylandPointerPrivate : public QObjectPrivate @@ -138,17 +95,15 @@ public: void sendMouseWheelEvent(Qt::Orientation orientation, int delta); Resource *focusResource() const { return m_focusResource; } - QWaylandSurfaceView *focusView() const { return m_currentPosition.view(); } + QWaylandSurfaceView *focusView() const { return m_seat->mouseFocus(); } bool buttonPressed() const; QWaylandInputDevice *seat() const { return m_seat; } QWaylandCompositor *compositor() const { return m_seat->compositor(); } - void resetCurrentState() { m_currentPosition.reset(); } - QWaylandSurfaceView *currentView() const { return m_currentPosition.view(); } QPointF currentSpacePosition() const { return m_spacePosition; } - QPointF currentLocalPosition() const { return m_currentPosition.position(); } + QPointF currentLocalPosition() const { return m_localPosition; } protected: void pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) Q_DECL_OVERRIDE; void pointer_release(Resource *resource) Q_DECL_OVERRIDE; @@ -160,7 +115,8 @@ private: QWaylandInputDevice *m_seat; QWaylandOutput *m_output; QWaylandDefaultPointerGrabber m_defaultGrab; - QtWayland::CurrentPosition m_currentPosition; + + QPointF m_localPosition; QPointF m_spacePosition; QWaylandPointerGrabber *m_grab; @@ -169,7 +125,7 @@ private: uint32_t m_grabSerial; Resource *m_focusResource; - + bool m_hasSentEnter; int m_buttonCount; diff --git a/src/compositor/wayland_wrapper/qwltouch.cpp b/src/compositor/wayland_wrapper/qwltouch.cpp index 98daa20c9..11ed148a2 100644 --- a/src/compositor/wayland_wrapper/qwltouch.cpp +++ b/src/compositor/wayland_wrapper/qwltouch.cpp @@ -52,7 +52,6 @@ QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDe , m_grab(&m_defaultGrab) { m_grab->touch = touch; - connect(&m_focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandTouchPrivate::focusDestroyed); } void QWaylandTouchPrivate::startGrab(QWaylandTouchGrabber *grab) @@ -67,19 +66,17 @@ void QWaylandTouchPrivate::endGrab() m_grab = &m_defaultGrab; } -void QWaylandTouchPrivate::focusDestroyed(void *data) +void QWaylandTouchPrivate::resetFocusState() { - Q_UNUSED(data) m_focusDestroyListener.reset(); - - m_focus = 0; m_focusResource = 0; } void QWaylandTouchPrivate::touch_destroy_resource(Resource *resource) { - if (m_focusResource == resource) - m_focusResource = 0; + if (m_focusResource == resource) { + resetFocusState(); + } } void QWaylandTouchPrivate::touch_release(Resource *resource) diff --git a/src/compositor/wayland_wrapper/qwltouch_p.h b/src/compositor/wayland_wrapper/qwltouch_p.h index 0ba8ba921..a0f9273b7 100644 --- a/src/compositor/wayland_wrapper/qwltouch_p.h +++ b/src/compositor/wayland_wrapper/qwltouch_p.h @@ -42,6 +42,8 @@ #include <QtCompositor/QWaylandDestroyListener> #include <QtCompositor/QWaylandTouch> #include <QtCompositor/QWaylandInputDevice> +#include <QtCompositor/QWaylandClient> +#include <QtCompositor/QWaylandSurfaceView> #include <QtCore/QPoint> #include <QtCore/private/qobject_p.h> @@ -75,14 +77,25 @@ public: void sendFullTouchEvent(QTouchEvent *event); Resource *focusResource() const { return m_focusResource; } + + void setFocusResource() + { + if (m_focusResource) + return; + + QWaylandSurfaceView *mouseFocus = m_seat->mouseFocus(); + if (!mouseFocus || !mouseFocus->surface()) + return; + + m_focusResource = resourceMap().value(mouseFocus->surface()->client()->client()); + } private: - void focusDestroyed(void *data); + void resetFocusState(); void touch_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; void touch_release(Resource *resource) Q_DECL_OVERRIDE; QWaylandInputDevice *m_seat; - QWaylandSurfaceView *m_focus; Resource *m_focusResource; QWaylandDestroyListener m_focusDestroyListener; |