summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorGiulio Camuffo <giuliocamuffo@gmail.com>2013-12-12 22:25:29 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-23 20:48:28 +0100
commite697d28dae8cbf4793132577131c81f3a252629b (patch)
treea48e6aecd571901efd1fdf90a44bb6e35501e604 /src/plugins
parent24b43e8ca5aa4d0248285354f92d4c88ce368070 (diff)
Implement keyboard auto-repeat
Wayland does not send auto-repeat key events, so the clients must implement it themselves. The times used here are taken from Weston's toy toolkit implementation. Change-Id: I13ec7799672ee5ca2904c9b18ac5ec0c8816d6fc Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> Reviewed-by: Andy Nichols <andy.nichols@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp45
-rw-r--r--src/plugins/platforms/wayland_common/qwaylandinputdevice.h13
2 files changed, 49 insertions, 9 deletions
diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp
index ac6a0c7da..b9338b4c3 100644
--- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp
@@ -70,7 +70,8 @@
QT_BEGIN_NAMESPACE
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
- : QtWayland::wl_seat(display->wl_registry(), id)
+ : QObject()
+ , QtWayland::wl_seat(display->wl_registry(), id)
, mQDisplay(display)
, mDisplay(display->wl_display())
, mFocusCallback(0)
@@ -114,6 +115,8 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
if (mQDisplay->dndSelectionHandler()) {
mDataDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this);
}
+
+ connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
}
QWaylandInputDevice::~QWaylandInputDevice()
@@ -156,8 +159,10 @@ void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
{
if (window == mPointerFocus)
mPointerFocus = 0;
- if (window == mKeyboardFocus)
+ if (window == mKeyboardFocus) {
mKeyboardFocus = 0;
+ mRepeatTimer.stop();
+ }
}
void QWaylandInputDevice::setDataDevice(QWaylandDataDevice *device)
@@ -555,6 +560,7 @@ void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surfa
mFocusCallback = wl_display_sync(mDisplay);
wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this);
}
+ mRepeatTimer.stop();
}
const wl_callback_listener QWaylandInputDevice::callback = {
@@ -589,6 +595,7 @@ void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t
uint32_t numSyms = xkb_key_get_syms(mXkbState, code, &syms);
xkb_state_update_key(mXkbState, code,
isDown ? XKB_KEY_DOWN : XKB_KEY_UP);
+ QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
if (!window) {
// We destroyed the keyboard focus surface, but the server
@@ -596,15 +603,17 @@ void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t
return;
}
+ int qtkey = key + 8; // qt-compositor substracts 8 for some reason
+ QString text;
+
if (numSyms == 1) {
xkb_keysym_t sym = syms[0];
Qt::KeyboardModifiers modifiers = this->modifiers();
- QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
uint utf32 = xkb_keysym_to_utf32(sym);
- QString text = QString::fromUcs4(&utf32, 1);
+ text = QString::fromUcs4(&utf32, 1);
- int qtkey = keysymToQtKey(sym, modifiers, text);
+ qtkey = keysymToQtKey(sym, modifiers, text);
QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
time, type, qtkey,
@@ -615,12 +624,32 @@ void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t
// Generic fallback for single hard keys: Assume 'key' is a Qt key code.
if (window) {
QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
- time, state ? QEvent::KeyPress : QEvent::KeyRelease,
- key + 8, // qt-compositor substracts 8 for some reason
+ time, type,
+ qtkey,
Qt::NoModifier,
- key + 8, 0, 0);
+ code, 0, 0);
}
#endif
+
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
+ mRepeatKey = qtkey;
+ mRepeatCode = code;
+ mRepeatTime = time;
+ mRepeatText = text;
+ mRepeatTimer.setInterval(400);
+ mRepeatTimer.start();
+ } else {
+ mRepeatTimer.stop();
+ }
+}
+
+void QWaylandInputDevice::repeatKey()
+{
+ mRepeatTimer.setInterval(25);
+ QWindowSystemInterface::handleExtendedKeyEvent(mKeyboardFocus->window(),
+ mRepeatTime, QEvent::KeyPress, mRepeatKey,
+ Qt::NoModifier,
+ mRepeatCode, 0, 0, mRepeatText);
}
void QWaylandInputDevice::keyboard_modifiers(uint32_t serial,
diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h
index be1e4885d..15b0571d6 100644
--- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h
+++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h
@@ -46,6 +46,7 @@
#include <QSocketNotifier>
#include <QObject>
+#include <QTimer>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
@@ -66,8 +67,9 @@ class QWaylandWindow;
class QWaylandDisplay;
class QWaylandDataDevice;
-class QWaylandInputDevice : public QtWayland::wl_pointer, public QtWayland::wl_keyboard, public QtWayland::wl_touch, public QtWayland::wl_seat
+class QWaylandInputDevice : public QObject, public QtWayland::wl_pointer, public QtWayland::wl_keyboard, public QtWayland::wl_touch, public QtWayland::wl_seat
{
+ Q_OBJECT
public:
QWaylandInputDevice(QWaylandDisplay *display, uint32_t id);
~QWaylandInputDevice();
@@ -92,6 +94,9 @@ public:
uint32_t serial() const;
uint32_t cursorSerial() const { return mCursorSerial; }
+private slots:
+ void repeatKey();
+
private:
QWaylandDisplay *mQDisplay;
struct wl_display *mDisplay;
@@ -174,6 +179,12 @@ private:
xkb_state *mXkbState;
#endif
+ int mRepeatKey;
+ uint32_t mRepeatCode;
+ uint32_t mRepeatTime;
+ QString mRepeatText;
+ QTimer mRepeatTimer;
+
friend class QWaylandTouchExtension;
friend class QWaylandQtKeyExtension;
};