Implement support for pointer gestures v1
Change-Id: Ie9ee615de123e6deab5b7a5081ca9bcf53399df7 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
ac704a5b90
commit
2679eeaac9
@ -33,6 +33,7 @@ qt_internal_add_module(WaylandClient
|
||||
qwaylandinputmethodcontext.cpp qwaylandinputmethodcontext_p.h
|
||||
qwaylandintegration.cpp qwaylandintegration_p.h
|
||||
qwaylandnativeinterface.cpp qwaylandnativeinterface_p.h
|
||||
qwaylandpointergestures.cpp qwaylandpointergestures_p.h
|
||||
qwaylandqtkey.cpp qwaylandqtkey_p.h
|
||||
qwaylandscreen.cpp qwaylandscreen_p.h
|
||||
qwaylandshellsurface.cpp qwaylandshellsurface_p.h
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include "qwaylandclientbufferintegration_p.h"
|
||||
|
||||
#include "qwaylandextendedsurface_p.h"
|
||||
#include "qwaylandpointergestures_p.h"
|
||||
#include "qwaylandsubsurface_p.h"
|
||||
#include "qwaylandtouch_p.h"
|
||||
#include "qwaylandtabletv2_p.h"
|
||||
@ -355,6 +356,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||
mQtKeyExtension.reset(new QWaylandQtKeyExtension(this, id));
|
||||
} else if (interface == QStringLiteral("zwp_tablet_manager_v2")) {
|
||||
mTabletManager.reset(new QWaylandTabletManagerV2(this, id, qMin(1, int(version))));
|
||||
} else if (interface == QStringLiteral("zwp_pointer_gestures_v1")) {
|
||||
mPointerGestures.reset(new QWaylandPointerGestures(this, id, 1));
|
||||
#if QT_CONFIG(wayland_client_primary_selection)
|
||||
} else if (interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) {
|
||||
mPrimarySelectionManager.reset(new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1));
|
||||
|
@ -101,6 +101,7 @@ class QWaylandDataDeviceManager;
|
||||
class QWaylandPrimarySelectionDeviceManagerV1;
|
||||
#endif
|
||||
class QWaylandTabletManagerV2;
|
||||
class QWaylandPointerGestures;
|
||||
class QWaylandTouchExtension;
|
||||
class QWaylandQtKeyExtension;
|
||||
class QWaylandWindow;
|
||||
@ -172,6 +173,7 @@ public:
|
||||
#endif
|
||||
QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension.data(); }
|
||||
QWaylandTabletManagerV2 *tabletManager() const { return mTabletManager.data(); }
|
||||
QWaylandPointerGestures *pointerGestures() const { return mPointerGestures.data(); }
|
||||
QWaylandTouchExtension *touchExtension() const { return mTouchExtension.data(); }
|
||||
QtWayland::qt_text_input_method_manager_v1 *textInputMethodManager() const { return mTextInputMethodManager.data(); }
|
||||
QtWayland::zwp_text_input_manager_v2 *textInputManager() const { return mTextInputManager.data(); }
|
||||
@ -275,6 +277,7 @@ private:
|
||||
QScopedPointer<QWaylandQtKeyExtension> mQtKeyExtension;
|
||||
QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration;
|
||||
QScopedPointer<QWaylandTabletManagerV2> mTabletManager;
|
||||
QScopedPointer<QWaylandPointerGestures> mPointerGestures;
|
||||
#if QT_CONFIG(wayland_client_primary_selection)
|
||||
QScopedPointer<QWaylandPrimarySelectionDeviceManagerV1> mPrimarySelectionManager;
|
||||
#endif
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "qwaylandprimaryselectionv1_p.h"
|
||||
#endif
|
||||
#include "qwaylandtabletv2_p.h"
|
||||
#include "qwaylandpointergestures_p.h"
|
||||
#include "qwaylandtouch_p.h"
|
||||
#include "qwaylandscreen_p.h"
|
||||
#include "qwaylandcursor_p.h"
|
||||
@ -82,6 +83,10 @@ namespace QtWaylandClient {
|
||||
|
||||
Q_LOGGING_CATEGORY(lcQpaWaylandInput, "qt.qpa.wayland.input");
|
||||
|
||||
// The maximum number of concurrent touchpoints is not exposed in wayland, so we assume a
|
||||
// reasonable number of them. As of 2021 most touchscreen panels support 10 concurrent touchpoints.
|
||||
static const int MaxTouchPoints = 10;
|
||||
|
||||
QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p)
|
||||
: mParent(p)
|
||||
{
|
||||
@ -446,9 +451,28 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps)
|
||||
if (caps & WL_SEAT_CAPABILITY_POINTER && !mPointer) {
|
||||
mPointer = createPointer(this);
|
||||
mPointer->init(get_pointer());
|
||||
|
||||
auto *pointerGestures = mQDisplay->pointerGestures();
|
||||
if (pointerGestures) {
|
||||
// NOTE: The name of the device and its system ID are not exposed on Wayland.
|
||||
mTouchPadDevice = new QPointingDevice(QLatin1String("touchpad"), 0,
|
||||
QInputDevice::DeviceType::TouchPad,
|
||||
QPointingDevice::PointerType::Finger,
|
||||
QInputDevice::Capability::Position,
|
||||
MaxTouchPoints, 0);
|
||||
QWindowSystemInterface::registerInputDevice(mTouchPadDevice);
|
||||
mPointerGesturePinch = pointerGestures->createPointerGesturePinch(this);
|
||||
mPointerGesturePinch->init(pointerGestures->get_pinch_gesture(get_pointer()));
|
||||
mPointerGestureSwipe = pointerGestures->createPointerGestureSwipe(this);
|
||||
mPointerGestureSwipe->init(pointerGestures->get_swipe_gesture(get_pointer()));
|
||||
}
|
||||
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && mPointer) {
|
||||
delete mPointer;
|
||||
mPointer = nullptr;
|
||||
delete mPointerGesturePinch;
|
||||
mPointerGesturePinch = nullptr;
|
||||
delete mPointerGestureSwipe;
|
||||
mPointerGestureSwipe = nullptr;
|
||||
}
|
||||
|
||||
if (caps & WL_SEAT_CAPABILITY_TOUCH && !mTouch) {
|
||||
@ -458,8 +482,8 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps)
|
||||
if (!mTouchDevice) {
|
||||
// TODO number of touchpoints, actual name and ID
|
||||
mTouchDevice = new QPointingDevice(QLatin1String("some touchscreen"), 0,
|
||||
QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
|
||||
QInputDevice::Capability::Position, 10, 0);
|
||||
QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
|
||||
QInputDevice::Capability::Position, MaxTouchPoints, 0);
|
||||
QWindowSystemInterface::registerInputDevice(mTouchDevice);
|
||||
}
|
||||
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && mTouch) {
|
||||
@ -493,6 +517,16 @@ QWaylandInputDevice::Pointer *QWaylandInputDevice::pointer() const
|
||||
return mPointer;
|
||||
}
|
||||
|
||||
QWaylandPointerGestureSwipe *QWaylandInputDevice::pointerGestureSwipe() const
|
||||
{
|
||||
return mPointerGestureSwipe;
|
||||
}
|
||||
|
||||
QWaylandPointerGesturePinch *QWaylandInputDevice::pointerGesturePinch() const
|
||||
{
|
||||
return mPointerGesturePinch;
|
||||
}
|
||||
|
||||
QWaylandInputDevice::Touch *QWaylandInputDevice::touch() const
|
||||
{
|
||||
return mTouch;
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <QtWaylandClient/private/qwayland-wayland.h>
|
||||
#include <QtWaylandClient/private/qwayland-pointer-gestures-unstable-v1.h>
|
||||
|
||||
#if QT_CONFIG(xkbcommon)
|
||||
#include <QtGui/private/qxkbcommon_p.h>
|
||||
@ -90,6 +91,9 @@ class QWaylandDisplay;
|
||||
class QWaylandPrimarySelectionDeviceV1;
|
||||
#endif
|
||||
class QWaylandTabletSeatV2;
|
||||
class QWaylandPointerGestures;
|
||||
class QWaylandPointerGestureSwipe;
|
||||
class QWaylandPointerGesturePinch;
|
||||
class QWaylandTextInput;
|
||||
class QWaylandTextInputMethod;
|
||||
#if QT_CONFIG(cursor)
|
||||
@ -97,6 +101,8 @@ class QWaylandCursorTheme;
|
||||
class CursorSurface;
|
||||
#endif
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcQpaWaylandInput);
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice
|
||||
: public QObject
|
||||
, public QtWayland::wl_seat
|
||||
@ -158,6 +164,8 @@ public:
|
||||
|
||||
Keyboard *keyboard() const;
|
||||
Pointer *pointer() const;
|
||||
QWaylandPointerGestureSwipe *pointerGestureSwipe() const;
|
||||
QWaylandPointerGesturePinch *pointerGesturePinch() const;
|
||||
Touch *touch() const;
|
||||
|
||||
protected:
|
||||
@ -187,6 +195,8 @@ protected:
|
||||
|
||||
Keyboard *mKeyboard = nullptr;
|
||||
Pointer *mPointer = nullptr;
|
||||
QWaylandPointerGestureSwipe *mPointerGestureSwipe = nullptr;
|
||||
QWaylandPointerGesturePinch *mPointerGesturePinch = nullptr;
|
||||
Touch *mTouch = nullptr;
|
||||
|
||||
QScopedPointer<QWaylandTextInput> mTextInput;
|
||||
@ -200,9 +210,13 @@ protected:
|
||||
void handleTouchPoint(int id, Qt::TouchPointState state, const QPointF &surfacePosition = QPoint());
|
||||
|
||||
QPointingDevice *mTouchDevice = nullptr;
|
||||
QPointingDevice *mTouchPadDevice = nullptr;
|
||||
|
||||
friend class QWaylandTouchExtension;
|
||||
friend class QWaylandQtKeyExtension;
|
||||
friend class QWaylandPointerGestureSwipe;
|
||||
friend class QWaylandPointerGesturePinch;
|
||||
friend class QWaylandWindow;
|
||||
};
|
||||
|
||||
inline uint32_t QWaylandInputDevice::serial() const
|
||||
@ -461,6 +475,63 @@ public:
|
||||
QPointer<QWaylandWindow> surface;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
class QWaylandPointerGestureSwipeEvent
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
inline QWaylandPointerGestureSwipeEvent(QWaylandWindow *surface, Qt::GestureState state,
|
||||
ulong timestamp, const QPointF &local,
|
||||
const QPointF &global, uint fingers, const QPointF& delta)
|
||||
: surface(surface)
|
||||
, state(state)
|
||||
, timestamp(timestamp)
|
||||
, local(local)
|
||||
, global(global)
|
||||
, fingers(fingers)
|
||||
, delta(delta)
|
||||
{}
|
||||
|
||||
QPointer<QWaylandWindow> surface;
|
||||
Qt::GestureState state = Qt::GestureState::NoGesture;
|
||||
ulong timestamp = 0;
|
||||
QPointF local;
|
||||
QPointF global;
|
||||
uint fingers = 0;
|
||||
QPointF delta;
|
||||
};
|
||||
|
||||
class QWaylandPointerGesturePinchEvent
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
inline QWaylandPointerGesturePinchEvent(QWaylandWindow *surface, Qt::GestureState state,
|
||||
ulong timestamp, const QPointF &local,
|
||||
const QPointF &global, uint fingers, const QPointF& delta,
|
||||
qreal scale_delta, qreal rotation_delta)
|
||||
: surface(surface)
|
||||
, state(state)
|
||||
, timestamp(timestamp)
|
||||
, local(local)
|
||||
, global(global)
|
||||
, fingers(fingers)
|
||||
, delta(delta)
|
||||
, scale_delta(scale_delta)
|
||||
, rotation_delta(rotation_delta)
|
||||
{}
|
||||
|
||||
QPointer<QWaylandWindow> surface;
|
||||
Qt::GestureState state = Qt::GestureState::NoGesture;
|
||||
ulong timestamp = 0;
|
||||
QPointF local;
|
||||
QPointF global;
|
||||
uint fingers = 0;
|
||||
QPointF delta;
|
||||
qreal scale_delta = 0;
|
||||
qreal rotation_delta = 0;
|
||||
};
|
||||
#endif // #ifndef QT_NO_GESTURES
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
222
src/plugins/platforms/wayland/qwaylandpointergestures.cpp
Normal file
222
src/plugins/platforms/wayland/qwaylandpointergestures.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** 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-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwaylandpointergestures_p.h"
|
||||
#include "qwaylanddisplay_p.h"
|
||||
#include "qwaylandinputdevice_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
QWaylandPointerGestures::QWaylandPointerGestures(QWaylandDisplay *display, uint id, uint version)
|
||||
: zwp_pointer_gestures_v1(display->wl_registry(), id, qMin(version, uint(1)))
|
||||
{
|
||||
}
|
||||
|
||||
QWaylandPointerGestureSwipe *
|
||||
QWaylandPointerGestures::createPointerGestureSwipe(QWaylandInputDevice *device)
|
||||
{
|
||||
return new QWaylandPointerGestureSwipe(device);
|
||||
}
|
||||
|
||||
QWaylandPointerGesturePinch *
|
||||
QWaylandPointerGestures::createPointerGesturePinch(QWaylandInputDevice *device)
|
||||
{
|
||||
return new QWaylandPointerGesturePinch(device);
|
||||
}
|
||||
|
||||
QWaylandPointerGestureSwipe::QWaylandPointerGestureSwipe(QWaylandInputDevice *p)
|
||||
: mParent(p)
|
||||
{
|
||||
}
|
||||
|
||||
QWaylandPointerGestureSwipe::~QWaylandPointerGestureSwipe()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void QWaylandPointerGestureSwipe::zwp_pointer_gesture_swipe_v1_begin(uint32_t serial, uint32_t time,
|
||||
struct ::wl_surface *surface,
|
||||
uint32_t fingers)
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
mParent->mSerial = serial;
|
||||
mFocus = QWaylandWindow::fromWlSurface(surface);
|
||||
mFingers = fingers;
|
||||
|
||||
const auto* pointer = mParent->pointer();
|
||||
|
||||
qCDebug(lcQpaWaylandInput) << "zwp_pointer_gesture_swipe_v1_begin @ "
|
||||
<< pointer->mSurfacePos << "fingers" << fingers;
|
||||
|
||||
auto e = QWaylandPointerGestureSwipeEvent(mFocus, Qt::GestureStarted, time,
|
||||
pointer->mSurfacePos, pointer->mGlobalPos, mFingers,
|
||||
QPointF());
|
||||
|
||||
mFocus->handleSwipeGesture(mParent, e);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QWaylandPointerGestureSwipe::zwp_pointer_gesture_swipe_v1_update(uint32_t time,
|
||||
wl_fixed_t dx, wl_fixed_t dy)
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
const auto* pointer = mParent->pointer();
|
||||
|
||||
const QPointF delta = QPointF(wl_fixed_to_double(dx), wl_fixed_to_double(dy));
|
||||
qCDebug(lcQpaWaylandInput) << "zwp_pointer_gesture_swipe_v1_update @ "
|
||||
<< pointer->mSurfacePos << "delta" << delta;
|
||||
|
||||
auto e = QWaylandPointerGestureSwipeEvent(mFocus, Qt::GestureUpdated, time,
|
||||
pointer->mSurfacePos, pointer->mGlobalPos, mFingers, delta);
|
||||
|
||||
mFocus->handleSwipeGesture(mParent, e);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QWaylandPointerGestureSwipe::zwp_pointer_gesture_swipe_v1_end(uint32_t serial, uint32_t time,
|
||||
int32_t cancelled)
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
mParent->mSerial = serial;
|
||||
const auto* pointer = mParent->pointer();
|
||||
|
||||
qCDebug(lcQpaWaylandInput) << "zwp_pointer_gesture_swipe_v1_end @ "
|
||||
<< pointer->mSurfacePos << (cancelled ? "CANCELED" : "");
|
||||
|
||||
auto gestureType = cancelled ? Qt::GestureFinished : Qt::GestureCanceled;
|
||||
|
||||
auto e = QWaylandPointerGestureSwipeEvent(mFocus, gestureType, time,
|
||||
pointer->mSurfacePos, pointer->mGlobalPos, mFingers,
|
||||
QPointF());
|
||||
|
||||
mFocus->handleSwipeGesture(mParent, e);
|
||||
|
||||
mFocus.clear();
|
||||
mFingers = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
QWaylandPointerGesturePinch::QWaylandPointerGesturePinch(QWaylandInputDevice *p)
|
||||
: mParent(p)
|
||||
{
|
||||
}
|
||||
|
||||
QWaylandPointerGesturePinch::~QWaylandPointerGesturePinch()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void QWaylandPointerGesturePinch::zwp_pointer_gesture_pinch_v1_begin(uint32_t serial, uint32_t time,
|
||||
struct ::wl_surface *surface,
|
||||
uint32_t fingers)
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
mParent->mSerial = serial;
|
||||
mFocus = QWaylandWindow::fromWlSurface(surface);
|
||||
mFingers = fingers;
|
||||
mLastScale = 1;
|
||||
|
||||
const auto* pointer = mParent->pointer();
|
||||
|
||||
qCDebug(lcQpaWaylandInput) << "zwp_pointer_gesture_pinch_v1_begin @ "
|
||||
<< pointer->mSurfacePos << "fingers" << fingers;
|
||||
|
||||
auto e = QWaylandPointerGesturePinchEvent(mFocus, Qt::GestureStarted, time,
|
||||
pointer->mSurfacePos, pointer->mGlobalPos, mFingers,
|
||||
QPointF(), 0, 0);
|
||||
|
||||
mFocus->handlePinchGesture(mParent, e);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QWaylandPointerGesturePinch::zwp_pointer_gesture_pinch_v1_update(uint32_t time,
|
||||
wl_fixed_t dx, wl_fixed_t dy,
|
||||
wl_fixed_t scale,
|
||||
wl_fixed_t rotation)
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
const auto* pointer = mParent->pointer();
|
||||
|
||||
const qreal rscale = wl_fixed_to_double(scale);
|
||||
const qreal rot = wl_fixed_to_double(rotation);
|
||||
const QPointF delta = QPointF(wl_fixed_to_double(dx), wl_fixed_to_double(dy));
|
||||
qCDebug(lcQpaWaylandInput) << "zwp_pointer_gesture_pinch_v1_update @ "
|
||||
<< pointer->mSurfacePos << "delta" << delta
|
||||
<< "scale" << mLastScale << "->" << rscale
|
||||
<< "delta" << rscale - mLastScale << "rot" << rot;
|
||||
|
||||
auto e = QWaylandPointerGesturePinchEvent(mFocus, Qt::GestureUpdated, time,
|
||||
pointer->mSurfacePos, pointer->mGlobalPos, mFingers,
|
||||
delta, rscale - mLastScale, rot);
|
||||
|
||||
mFocus->handlePinchGesture(mParent, e);
|
||||
|
||||
mLastScale = rscale;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QWaylandPointerGesturePinch::zwp_pointer_gesture_pinch_v1_end(uint32_t serial, uint32_t time,
|
||||
int32_t cancelled)
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
mParent->mSerial = serial;
|
||||
const auto* pointer = mParent->pointer();
|
||||
|
||||
qCDebug(lcQpaWaylandInput) << "zwp_pointer_gesture_swipe_v1_end @ "
|
||||
<< pointer->mSurfacePos << (cancelled ? "CANCELED" : "");
|
||||
|
||||
auto gestureType = cancelled ? Qt::GestureFinished : Qt::GestureCanceled;
|
||||
|
||||
auto e = QWaylandPointerGesturePinchEvent(mFocus, gestureType, time,
|
||||
pointer->mSurfacePos, pointer->mGlobalPos, mFingers,
|
||||
QPointF(), 0, 0);
|
||||
|
||||
mFocus->handlePinchGesture(mParent, e);
|
||||
|
||||
mFocus.clear();
|
||||
mFingers = 0;
|
||||
mLastScale = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QtWaylandClient
|
||||
|
||||
QT_END_NAMESPACE
|
150
src/plugins/platforms/wayland/qwaylandpointergestures_p.h
Normal file
150
src/plugins/platforms/wayland/qwaylandpointergestures_p.h
Normal file
@ -0,0 +1,150 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** 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-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QWAYLANDPOINTERGESTURES_P_H
|
||||
#define QWAYLANDPOINTERGESTURES_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtWaylandClient/private/qwayland-pointer-gestures-unstable-v1.h>
|
||||
|
||||
#include <QtWaylandClient/private/qtwaylandclientglobal_p.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
class QWaylandDisplay;
|
||||
class QWaylandWindow;
|
||||
class QWaylandInputDevice;
|
||||
class QWaylandPointerGestureSwipe;
|
||||
class QWaylandPointerGesturePinch;
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandPointerGestures : public QtWayland::zwp_pointer_gestures_v1
|
||||
{
|
||||
public:
|
||||
explicit QWaylandPointerGestures(QWaylandDisplay *display, uint id, uint version);
|
||||
|
||||
QWaylandPointerGestureSwipe *createPointerGestureSwipe(QWaylandInputDevice *device);
|
||||
QWaylandPointerGesturePinch *createPointerGesturePinch(QWaylandInputDevice *device);
|
||||
};
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandPointerGestureSwipe :
|
||||
public QtWayland::zwp_pointer_gesture_swipe_v1
|
||||
{
|
||||
public:
|
||||
QWaylandPointerGestureSwipe(QWaylandInputDevice *p);
|
||||
~QWaylandPointerGestureSwipe() override;
|
||||
|
||||
void zwp_pointer_gesture_swipe_v1_begin(uint32_t serial,
|
||||
uint32_t time,
|
||||
struct ::wl_surface *surface,
|
||||
uint32_t fingers) override;
|
||||
|
||||
void zwp_pointer_gesture_swipe_v1_update(uint32_t time,
|
||||
wl_fixed_t dx,
|
||||
wl_fixed_t dy) override;
|
||||
|
||||
void zwp_pointer_gesture_swipe_v1_end(uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t cancelled) override;
|
||||
|
||||
struct ::zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1()
|
||||
{
|
||||
return QtWayland::zwp_pointer_gesture_swipe_v1::object();
|
||||
}
|
||||
|
||||
QWaylandInputDevice *mParent = nullptr;
|
||||
QPointer<QWaylandWindow> mFocus;
|
||||
uint mFingers = 0;
|
||||
};
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandPointerGesturePinch :
|
||||
public QtWayland::zwp_pointer_gesture_pinch_v1
|
||||
{
|
||||
public:
|
||||
QWaylandPointerGesturePinch(QWaylandInputDevice *p);
|
||||
~QWaylandPointerGesturePinch() override;
|
||||
|
||||
void zwp_pointer_gesture_pinch_v1_begin(uint32_t serial,
|
||||
uint32_t time,
|
||||
struct ::wl_surface *surface,
|
||||
uint32_t fingers) override;
|
||||
|
||||
void zwp_pointer_gesture_pinch_v1_update(uint32_t time,
|
||||
wl_fixed_t dx,
|
||||
wl_fixed_t dy,
|
||||
wl_fixed_t scale,
|
||||
wl_fixed_t rotation) override;
|
||||
|
||||
void zwp_pointer_gesture_pinch_v1_end(uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t cancelled) override;
|
||||
|
||||
struct ::zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1()
|
||||
{
|
||||
return QtWayland::zwp_pointer_gesture_pinch_v1::object();
|
||||
}
|
||||
|
||||
QWaylandInputDevice *mParent = nullptr;
|
||||
QPointer<QWaylandWindow> mFocus;
|
||||
uint mFingers = 0;
|
||||
|
||||
// We need to convert between absolute scale provided by wayland/libinput and zoom deltas
|
||||
// that Qt expects. This stores the scale of the last pinch event or 1.0 if there was none.
|
||||
qreal mLastScale = 1;
|
||||
};
|
||||
|
||||
} // namespace QtWaylandClient
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWAYLANDPOINTERGESTURES_P_H
|
@ -978,6 +978,133 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
void QWaylandWindow::handleSwipeGesture(QWaylandInputDevice *inputDevice,
|
||||
const QWaylandPointerGestureSwipeEvent &e)
|
||||
{
|
||||
switch (e.state) {
|
||||
case Qt::GestureStarted:
|
||||
if (mGestureState != GestureNotActive)
|
||||
qCWarning(lcQpaWaylandInput) << "Unexpected gesture state. Gestures will act weird.";
|
||||
|
||||
if (mWindowDecoration && !mMouseEventsInContentArea) {
|
||||
// whole gesture sequence will be ignored
|
||||
mGestureState = GestureActiveInDecoration;
|
||||
return;
|
||||
}
|
||||
|
||||
mGestureState = GestureActiveInContentArea;
|
||||
QWindowSystemInterface::handleGestureEvent(window(), e.timestamp,
|
||||
inputDevice->mTouchPadDevice,
|
||||
Qt::BeginNativeGesture,
|
||||
e.local, e.global, e.fingers);
|
||||
break;
|
||||
case Qt::GestureUpdated:
|
||||
if (mGestureState != GestureActiveInContentArea)
|
||||
return;
|
||||
|
||||
if (!e.delta.isNull()) {
|
||||
QWindowSystemInterface::handleGestureEventWithValueAndDeltas(
|
||||
window(), e.timestamp, inputDevice->mTouchPadDevice,
|
||||
Qt::PanNativeGesture,
|
||||
0, QVector2D(e.delta), e.local, e.global, e.fingers);
|
||||
}
|
||||
break;
|
||||
case Qt::GestureFinished:
|
||||
case Qt::GestureCanceled:
|
||||
if (mGestureState == GestureActiveInDecoration) {
|
||||
mGestureState = GestureNotActive;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGestureState != GestureActiveInContentArea)
|
||||
qCWarning(lcQpaWaylandInput) << "Unexpected gesture state. Gestures will act weird.";
|
||||
|
||||
mGestureState = GestureNotActive;
|
||||
|
||||
// There's currently no way to expose cancelled gestures to the rest of Qt, so
|
||||
// this part of information is lost.
|
||||
QWindowSystemInterface::handleGestureEvent(window(), e.timestamp,
|
||||
inputDevice->mTouchPadDevice,
|
||||
Qt::EndNativeGesture,
|
||||
e.local, e.global, e.fingers);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandWindow::handlePinchGesture(QWaylandInputDevice *inputDevice,
|
||||
const QWaylandPointerGesturePinchEvent &e)
|
||||
{
|
||||
switch (e.state) {
|
||||
case Qt::GestureStarted:
|
||||
if (mGestureState != GestureNotActive)
|
||||
qCWarning(lcQpaWaylandInput) << "Unexpected gesture state. Gestures will act weird.";
|
||||
|
||||
if (mWindowDecoration && !mMouseEventsInContentArea) {
|
||||
// whole gesture sequence will be ignored
|
||||
mGestureState = GestureActiveInDecoration;
|
||||
return;
|
||||
}
|
||||
|
||||
mGestureState = GestureActiveInContentArea;
|
||||
QWindowSystemInterface::handleGestureEvent(window(), e.timestamp,
|
||||
inputDevice->mTouchPadDevice,
|
||||
Qt::BeginNativeGesture,
|
||||
e.local, e.global, e.fingers);
|
||||
break;
|
||||
case Qt::GestureUpdated:
|
||||
if (mGestureState != GestureActiveInContentArea)
|
||||
return;
|
||||
|
||||
if (!e.delta.isNull()) {
|
||||
QWindowSystemInterface::handleGestureEventWithValueAndDeltas(
|
||||
window(), e.timestamp, inputDevice->mTouchPadDevice,
|
||||
Qt::PanNativeGesture,
|
||||
0, QVector2D(e.delta), e.local, e.global, e.fingers);
|
||||
}
|
||||
if (e.rotation_delta != 0) {
|
||||
QWindowSystemInterface::handleGestureEventWithRealValue(window(), e.timestamp,
|
||||
inputDevice->mTouchPadDevice,
|
||||
Qt::RotateNativeGesture,
|
||||
e.rotation_delta,
|
||||
e.local, e.global, e.fingers);
|
||||
}
|
||||
if (e.scale_delta != 0) {
|
||||
QWindowSystemInterface::handleGestureEventWithRealValue(window(), e.timestamp,
|
||||
inputDevice->mTouchPadDevice,
|
||||
Qt::ZoomNativeGesture,
|
||||
e.scale_delta,
|
||||
e.local, e.global, e.fingers);
|
||||
}
|
||||
break;
|
||||
case Qt::GestureFinished:
|
||||
case Qt::GestureCanceled:
|
||||
if (mGestureState == GestureActiveInDecoration) {
|
||||
mGestureState = GestureNotActive;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGestureState != GestureActiveInContentArea)
|
||||
qCWarning(lcQpaWaylandInput) << "Unexpected gesture state. Gestures will act weird.";
|
||||
|
||||
mGestureState = GestureNotActive;
|
||||
|
||||
// There's currently no way to expose cancelled gestures to the rest of Qt, so
|
||||
// this part of information is lost.
|
||||
QWindowSystemInterface::handleGestureEvent(window(), e.timestamp,
|
||||
inputDevice->mTouchPadDevice,
|
||||
Qt::EndNativeGesture,
|
||||
e.local, e.global, e.fingers);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // #ifndef QT_NO_GESTURES
|
||||
|
||||
|
||||
bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
if (!mWindowDecoration)
|
||||
|
@ -83,6 +83,8 @@ class QWaylandInputDevice;
|
||||
class QWaylandScreen;
|
||||
class QWaylandShmBackingStore;
|
||||
class QWaylandPointerEvent;
|
||||
class QWaylandPointerGestureSwipeEvent;
|
||||
class QWaylandPointerGesturePinchEvent;
|
||||
class QWaylandSurface;
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow
|
||||
@ -177,6 +179,12 @@ public:
|
||||
QWaylandAbstractDecoration *decoration() const;
|
||||
|
||||
void handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||
#ifndef QT_NO_GESTURES
|
||||
void handleSwipeGesture(QWaylandInputDevice *inputDevice,
|
||||
const QWaylandPointerGestureSwipeEvent &e);
|
||||
void handlePinchGesture(QWaylandInputDevice *inputDevice,
|
||||
const QWaylandPointerGesturePinchEvent &e);
|
||||
#endif
|
||||
|
||||
bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
|
||||
Qt::TouchPointState state, Qt::KeyboardModifiers mods);
|
||||
@ -241,6 +249,23 @@ protected:
|
||||
bool mMouseEventsInContentArea = false;
|
||||
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
enum GestureState {
|
||||
GestureNotActive,
|
||||
GestureActiveInContentArea,
|
||||
GestureActiveInDecoration
|
||||
};
|
||||
|
||||
// We want gestures started in the decoration area to be completely ignored even if the mouse
|
||||
// pointer is later moved to content area. Likewise, gestures started in the content area should
|
||||
// keep sending events even if the mouse pointer is moved over the decoration (consider that
|
||||
// the events for that gesture will be sent to us even if it's moved outside the window).
|
||||
// So we track the gesture state and accept or ignore events based on that. Note that
|
||||
// concurrent gestures of different types are not allowed in the protocol, so single state is
|
||||
// enough
|
||||
GestureState mGestureState = GestureNotActive;
|
||||
#endif
|
||||
|
||||
WId mWindowId;
|
||||
bool mWaitingForFrameCallback = false;
|
||||
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
|
||||
|
Loading…
x
Reference in New Issue
Block a user