11#if QT_CONFIG(wayland_datadevice)
15#if QT_CONFIG(wayland_client_primary_selection)
18#if QT_CONFIG(tabletevent)
33#include <QtGui/private/qpixmap_raster_p.h>
34#include <QtGui/private/qguiapplication_p.h>
35#include <qpa/qplatformwindow.h>
36#include <qpa/qplatforminputcontext.h>
37#include <qpa/qplatformtheme.h>
45#include <wayland-cursor.h>
48#include <QtGui/QGuiApplication>
49#include <QtGui/QPointingDevice>
64 init(
p->get_keyboard());
65 mRepeatTimer.callOnTimeout(
this, [&]() {
71 mRepeatTimer.setInterval(1000 / mRepeatRate);
74 mRepeatKey.code, mRepeatKey.nativeVirtualKey,
this->mNativeModifiers,
75 mRepeatKey.text,
true);
77 mRepeatKey.code, mRepeatKey.nativeVirtualKey,
this->mNativeModifiers,
78 mRepeatKey.text,
true);
82#if QT_CONFIG(xkbcommon)
83bool QWaylandInputDevice::Keyboard::createDefaultKeymap()
85 struct xkb_context *
ctx = mParent->mQDisplay->xkbContext();
89 struct xkb_rule_names
names;
90 names.rules =
"evdev";
91 names.model =
"pc105";
96 mXkbKeymap.reset(xkb_keymap_new_from_names(
ctx, &
names, XKB_KEYMAP_COMPILE_NO_FLAGS));
98 mXkbState.reset(xkb_state_new(mXkbKeymap.get()));
100 if (!mXkbKeymap || !mXkbState) {
101 qCWarning(lcQpaWayland,
"failed to create default keymap");
109QWaylandInputDevice::Keyboard::~Keyboard()
114 wl_keyboard_release(
object());
116 wl_keyboard_destroy(
object());
119QWaylandWindow *QWaylandInputDevice::Keyboard::focusWindow()
const
121 return mFocus ? mFocus->waylandWindow() :
nullptr;
124QWaylandInputDevice::Pointer::Pointer(QWaylandInputDevice *seat)
127 init(seat->get_pointer());
129 if (
auto cursorShapeManager = seat->mQDisplay->cursorShapeManager()) {
130 mCursor.shape.reset(
new QWaylandCursorShape(cursorShapeManager->get_pointer(
object())));
133 mCursor.frameTimer.setSingleShot(
true);
134 mCursor.frameTimer.callOnTimeout(
this, [&]() {
135 cursorTimerCallback();
140QWaylandInputDevice::Pointer::~Pointer()
143 wl_pointer_release(
object());
145 wl_pointer_destroy(
object());
148QWaylandWindow *QWaylandInputDevice::Pointer::focusWindow()
const
150 return mFocus ? mFocus->waylandWindow() :
nullptr;
155class WlCallback :
public QtWayland::wl_callback {
157 explicit WlCallback(::wl_callback *callback, std::function<
void(uint32_t)> fn)
161 ~WlCallback()
override { wl_callback_destroy(
object()); }
162 void callback_done(uint32_t callback_data)
override {
166 std::function<
void(uint32_t)> m_fn;
172 explicit CursorSurface(QWaylandInputDevice::Pointer *
pointer, QWaylandDisplay *
display)
176 connect(
this, &QWaylandSurface::screensChanged,
177 m_pointer, &QWaylandInputDevice::Pointer::updateCursor);
187 void update(wl_buffer *
buffer,
const QPoint &hotspot,
const QSize &
size,
int bufferScale,
bool animated =
false)
190 Q_ASSERT(bufferScale == 1 || version() >= 3);
192 auto enterSerial = m_pointer->mEnterSerial;
193 if (m_setSerial < enterSerial || m_hotspot != hotspot) {
194 m_pointer->set_cursor(m_pointer->mEnterSerial,
object(), hotspot.
x(), hotspot.
y());
195 m_setSerial = enterSerial;
200 set_buffer_scale(bufferScale);
203 damage(0, 0,
size.width(),
size.height());
204 m_frameCallback.reset();
206 m_frameCallback.reset(
new WlCallback(
frame(), [
this](uint32_t
time){
208 m_pointer->cursorFrameCallback();
214 int outputScale()
const
217 for (
auto *
screen : m_screens)
223 QScopedPointer<WlCallback> m_frameCallback;
224 QWaylandInputDevice::Pointer *m_pointer =
nullptr;
225 uint m_setSerial = 0;
229int QWaylandInputDevice::Pointer::idealCursorScale()
const
231 if (seat()->mQDisplay->compositor()->version() < 3) {
235 if (
auto *
s = mCursor.surface.data()) {
236 if (
s->outputScale() > 0)
237 return s->outputScale();
240 return seat()->mCursor.fallbackOutputScale;
243void QWaylandInputDevice::Pointer::updateCursorTheme()
253 if (cursorThemeName.isEmpty())
255 if (cursorSize.isEmpty())
256 cursorSize =
QSize(24, 24);
258 int scale = idealCursorScale();
259 int pixelSize = cursorSize.width() *
scale;
260 auto *
display = seat()->mQDisplay;
261 mCursor.theme =
display->loadCursorTheme(cursorThemeName, pixelSize);
267 int arrowPixelSize =
qMax(arrow->images[0]->width, arrow->images[0]->height);
268 while (
scale > 1 && arrowPixelSize /
scale < cursorSize.width())
271 qCWarning(lcQpaWayland) <<
"Cursor theme does not support the arrow cursor";
273 mCursor.themeBufferScale =
scale;
276void QWaylandInputDevice::Pointer::updateCursor()
278 if (mEnterSerial == 0)
281 auto shape = seat()->mCursor.shape;
285 mCursor.surface->reset();
286 set_cursor(mEnterSerial,
nullptr, 0, 0);
291 auto buffer = seat()->mCursor.bitmapBuffer;
293 qCWarning(lcQpaWayland) <<
"No buffer for bitmap cursor, can't set cursor";
296 auto hotspot = seat()->mCursor.hotspot;
297 int bufferScale = seat()->mCursor.bitmapScale;
298 getOrCreateCursorSurface()->update(
buffer->buffer(), hotspot,
buffer->size(), bufferScale);
303 if (mCursor.surface) {
304 mCursor.surface->reset();
306 mCursor.shape->setShape(mEnterSerial, shape);
310 if (!mCursor.theme || idealCursorScale() != mCursor.themeBufferScale)
317 uint time = seat()->mCursor.animationTimer.elapsed();
319 if (struct ::wl_cursor *waylandCursor = mCursor.theme->cursor(shape)) {
321 int frame = wl_cursor_frame_and_duration(waylandCursor,
time, &duration);
322 ::wl_cursor_image *
image = waylandCursor->images[
frame];
324 struct wl_buffer *
buffer = wl_cursor_image_get_buffer(
image);
326 qCWarning(lcQpaWayland) <<
"Could not find buffer for cursor" << shape;
329 int bufferScale = mCursor.themeBufferScale;
332 bool animated = duration > 0;
334 mCursor.gotFrameCallback =
false;
335 mCursor.gotTimerCallback =
false;
336 mCursor.frameTimer.start(duration);
338 getOrCreateCursorSurface()->update(
buffer, hotspot,
size, bufferScale, animated);
342 qCWarning(lcQpaWayland) <<
"Unable to change to cursor" << shape;
345CursorSurface *QWaylandInputDevice::Pointer::getOrCreateCursorSurface()
347 if (!mCursor.surface)
348 mCursor.surface.reset(
new CursorSurface(
this, seat()->mQDisplay));
349 return mCursor.surface.get();
352void QWaylandInputDevice::Pointer::cursorTimerCallback()
354 mCursor.gotTimerCallback =
true;
355 if (mCursor.gotFrameCallback) {
360void QWaylandInputDevice::Pointer::cursorFrameCallback()
362 mCursor.gotFrameCallback =
true;
363 if (mCursor.gotTimerCallback) {
370QWaylandInputDevice::Touch::Touch(QWaylandInputDevice *
p)
373 init(
p->get_touch());
376QWaylandInputDevice::Touch::~Touch()
379 wl_touch_release(
object());
381 wl_touch_destroy(
object());
387 , mDisplay(
display->wl_display())
389#if QT_CONFIG(wayland_datadevice)
391 mDataDevice =
mQDisplay->dndSelectionHandler()->getDataDevice(
this);
395#if QT_CONFIG(wayland_client_primary_selection)
397 if (
auto *psm =
mQDisplay->primarySelectionManager())
398 setPrimarySelectionDevice(psm->createDevice(
this));
416#if QT_CONFIG(tabletevent)
417 if (
auto *tm =
mQDisplay->tabletManager())
424 if (version() >= WL_SEAT_RELEASE_SINCE_VERSION)
427 wl_seat_destroy(
object());
434 if (caps & WL_SEAT_CAPABILITY_KEYBOARD && !
mKeyboard) {
436 }
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) &&
mKeyboard) {
440 if (caps & WL_SEAT_CAPABILITY_POINTER && !
mPointer) {
444 if (pointerGestures) {
456 }
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) &&
mPointer) {
462 if (caps & WL_SEAT_CAPABILITY_TOUCH && !
mTouch) {
473 }
else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) &&
mTouch) {
531#if QT_CONFIG(wayland_datadevice)
537QWaylandDataDevice *QWaylandInputDevice::dataDevice()
const
543#if QT_CONFIG(wayland_client_primary_selection)
544void QWaylandInputDevice::setPrimarySelectionDevice(QWaylandPrimarySelectionDeviceV1 *primarySelectionDevice)
546 mPrimarySelectionDevice.reset(primarySelectionDevice);
549QWaylandPrimarySelectionDeviceV1 *QWaylandInputDevice::primarySelectionDevice()
const
551 return mPrimarySelectionDevice.data();
603#if QT_CONFIG(xkbcommon)
620Qt::KeyboardModifiers QWaylandInputDevice::Keyboard::modifiers()
const
624#if QT_CONFIG(xkbcommon)
635void QWaylandInputDevice::setCursor(
const QCursor *
cursor,
const QSharedPointer<QWaylandBuffer> &cachedBuffer,
int fallbackOutputScale)
637 CursorState oldCursor = mCursor;
638 mCursor = CursorState();
641 mCursor.fallbackOutputScale = fallbackOutputScale;
642 mCursor.animationTimer.start();
645 mCursor.bitmapBuffer = cachedBuffer ? cachedBuffer : QWaylandCursor::cursorBitmapBuffer(
mQDisplay,
cursor);
647 mCursor.bitmapScale = int(
dpr);
649 if (mCursor.bitmapScale <
dpr)
650 mCursor.hotspot *=
dpr / mCursor.bitmapScale;
655 && mCursor.shape == oldCursor.shape
656 && mCursor.hotspot == oldCursor.hotspot
657 && mCursor.fallbackOutputScale == oldCursor.fallbackOutputScale) {
675void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial,
struct wl_surface *surface,
676 wl_fixed_t sx, wl_fixed_t sy)
687 qCWarning(lcQpaWayland) <<
"The compositor sent a wl_pointer.enter event before sending a"
688 <<
"leave event first, this is not allowed by the wayland protocol"
689 <<
"attempting to work around it by invalidating the current focus";
692 mFocus =
window->waylandSurface();
695 mSurfacePos =
QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy));
696 mGlobalPos =
window->mapToGlobal(mSurfacePos.toPoint());
698 mParent->mSerial = serial;
699 mEnterSerial = serial;
708 setFrameEvent(
new EnterEvent(
window, mSurfacePos, mGlobalPos));
716 localPos, globalPos,
Qt::NoButton,
Qt::NoButton,
Qt::NoModifier)
720void QWaylandInputDevice::Pointer::pointer_leave(uint32_t
time,
struct wl_surface *surface)
725 mParent->mTime =
time;
737 setFrameEvent(
new LeaveEvent(
window, mSurfacePos, mGlobalPos));
751void QWaylandInputDevice::Pointer::pointer_motion(uint32_t
time, wl_fixed_t surface_x, wl_fixed_t surface_y)
753 QWaylandWindow *
window = focusWindow();
760 QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
767 mParent->mTime =
time;
770 if (grab && grab !=
window) {
774 global = grab->mapToGlobal(
pos.toPoint());
804void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t
time,
807 QWaylandWindow *
window = focusWindow();
838 mLastButton = qt_button;
841 mButtons |= qt_button;
843 mButtons &= ~qt_button;
845 mParent->mTime =
time;
846 mParent->mSerial = serial;
848 mParent->mQDisplay->setLastInputDevice(mParent, serial,
window);
854 if (grab && grab != focusWindow()) {
856 global = grab->mapToGlobal(
pos.toPoint());
862 setFrameEvent(
new PressEvent(
window,
time,
pos,
global, mButtons, qt_button, mParent->modifiers()));
864 setFrameEvent(
new ReleaseEvent(
window,
time,
pos,
global, mButtons, qt_button, mParent->modifiers()));
867void QWaylandInputDevice::Pointer::invalidateFocus()
876void QWaylandInputDevice::Pointer::releaseButtons()
883 if (
auto *
window = focusWindow()) {
884 ReleaseEvent e(focusWindow(), mParent->mTime, mSurfacePos, mGlobalPos, mButtons, mLastButton, mParent->modifiers());
885 window->handleMouse(mParent, e);
903void QWaylandInputDevice::Pointer::pointer_axis(uint32_t
time, uint32_t axis, int32_t
value)
905 if (!focusWindow()) {
913 case WL_POINTER_AXIS_VERTICAL_SCROLL:
914 mFrameData.delta.ry() += wl_fixed_to_double(
value);
915 qCDebug(lcQpaWaylandInput) <<
"wl_pointer.axis vertical:" << mFrameData.delta.y();
917 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
918 mFrameData.delta.rx() += wl_fixed_to_double(
value);
919 qCDebug(lcQpaWaylandInput) <<
"wl_pointer.axis horizontal:" << mFrameData.delta.x();
923 qCWarning(lcQpaWaylandInput) <<
"wl_pointer.axis: Unknown axis:" << axis;
927 mParent->mTime =
time;
929 if (version() < WL_POINTER_FRAME_SINCE_VERSION) {
930 qCDebug(lcQpaWaylandInput) <<
"Flushing new event; no frame event in this version";
935void QWaylandInputDevice::Pointer::pointer_frame()
940void QWaylandInputDevice::Pointer::pointer_axis_source(uint32_t
source)
943 case axis_source_wheel:
944 qCDebug(lcQpaWaylandInput) <<
"Axis source wheel";
946 case axis_source_finger:
947 qCDebug(lcQpaWaylandInput) <<
"Axis source finger";
949 case axis_source_continuous:
950 qCDebug(lcQpaWaylandInput) <<
"Axis source continuous";
952 case axis_source_wheel_tilt:
953 qCDebug(lcQpaWaylandInput) <<
"Axis source wheel tilt";
955 mFrameData.axisSource = axis_source(
source);
958void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t
time, uint32_t axis)
963 mParent->mTime =
time;
965 case axis_vertical_scroll:
966 qCDebug(lcQpaWaylandInput) <<
"Received vertical wl_pointer.axis_stop";
967 mFrameData.delta.setY(0);
969 case axis_horizontal_scroll:
970 qCDebug(lcQpaWaylandInput) <<
"Received horizontal wl_pointer.axis_stop";
971 mFrameData.delta.setX(0);
974 qCWarning(lcQpaWaylandInput) <<
"wl_pointer.axis_stop: Unknown axis: " << axis
975 <<
"This is most likely a compositor bug";
981 if (!mScrollBeginSent) {
991 Qt::KeyboardModifiers mods = mParent->modifiers();
992 const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted;
995 target->handleMouse(mParent, wheelEvent);
996 mScrollBeginSent =
false;
997 mScrollDeltaRemainder =
QPointF();
1000void QWaylandInputDevice::Pointer::pointer_axis_discrete(uint32_t axis, int32_t
value)
1005 const int32_t delta120 =
value * 15 * 8;
1008 case axis_vertical_scroll:
1009 qCDebug(lcQpaWaylandInput) <<
"wl_pointer.axis_discrete vertical:" <<
value;
1010 mFrameData.delta120.ry() += delta120;
1012 case axis_horizontal_scroll:
1013 qCDebug(lcQpaWaylandInput) <<
"wl_pointer.axis_discrete horizontal:" <<
value;
1014 mFrameData.delta120.rx() += delta120;
1018 qCWarning(lcQpaWaylandInput) <<
"wl_pointer.axis_discrete: Unknown axis:" << axis;
1023void QWaylandInputDevice::Pointer::pointer_axis_value120(uint32_t axis, int32_t
value)
1029 case axis_vertical_scroll:
1030 qCDebug(lcQpaWaylandInput) <<
"wl_pointer.axis_value120 vertical:" <<
value;
1031 mFrameData.delta120.ry() +=
value;
1033 case axis_horizontal_scroll:
1034 qCDebug(lcQpaWaylandInput) <<
"wl_pointer.axis_value120 horizontal:" <<
value;
1035 mFrameData.delta120.rx() +=
value;
1038 qCWarning(lcQpaWaylandInput) <<
"wl_pointer.axis_value120: Unknown axis:" << axis;
1043void QWaylandInputDevice::Pointer::pointer_axis_relative_direction(uint32_t axis, uint32_t
direction)
1045 const bool inverted =
direction == axis_relative_direction_inverted;
1047 case axis_vertical_scroll:
1048 mFrameData.verticalAxisInverted = inverted;
1050 case axis_horizontal_scroll:
1051 mFrameData.horizontalAxisInverted = inverted;
1054 qCWarning(lcQpaWaylandInput) <<
"wl_pointer.axis_relative_direction: Unknown axis:" << axis;
1058void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *
event)
1060 qCDebug(lcQpaWaylandInput) <<
"Setting frame event " <<
event->type;
1061 if (mFrameData.event && mFrameData.event->type !=
event->type) {
1062 qCDebug(lcQpaWaylandInput) <<
"Flushing; previous was " << mFrameData.event->type;
1066 mFrameData.event =
event;
1068 if (version() < WL_POINTER_FRAME_SINCE_VERSION) {
1069 qCDebug(lcQpaWaylandInput) <<
"Flushing new event; no frame event in this version";
1074void QWaylandInputDevice::Pointer::FrameData::resetScrollData()
1078 axisSource = axis_source_wheel;
1079 horizontalAxisInverted =
false;
1080 verticalAxisInverted =
false;
1083bool QWaylandInputDevice::Pointer::FrameData::hasPixelDelta()
const
1085 switch (axisSource) {
1086 case axis_source_wheel_tilt:
1087 case axis_source_wheel:
1092 case axis_source_finger:
1093 case axis_source_continuous:
1100QPoint QWaylandInputDevice::Pointer::FrameData::pixelDeltaAndError(
QPointF *accumulatedError)
const
1102 if (!hasPixelDelta())
1107 QPoint pixelDelta = (delta + *accumulatedError).toPoint();
1108 *accumulatedError += delta - pixelDelta;
1120QPoint QWaylandInputDevice::Pointer::FrameData::angleDelta()
const
1122 if (delta120.isNull()) {
1125 return (delta * -12).toPoint();
1136 switch (axisSource) {
1137 case axis_source_wheel_tilt:
1138 case axis_source_wheel:
1140 case axis_source_finger:
1141 case axis_source_continuous:
1147void QWaylandInputDevice::Pointer::flushScrollEvent()
1149 QPoint angleDelta = mFrameData.angleDelta();
1152 if (!angleDelta.
isNull()) {
1157 if (isDefinitelyTerminated(mFrameData.axisSource) && !mScrollBeginSent) {
1158 qCDebug(lcQpaWaylandInput) <<
"Flushing scroll event sending ScrollBegin";
1162 mParent->modifiers(),
false));
1163 mScrollBeginSent =
true;
1164 mScrollDeltaRemainder =
QPointF();
1168 QPoint pixelDelta = mFrameData.pixelDeltaAndError(&mScrollDeltaRemainder);
1174 const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted;
1176 qCDebug(lcQpaWaylandInput) <<
"Flushing scroll event" << phase << pixelDelta << angleDelta;
1177 target->handleMouse(mParent,
WheelEvent(focusWindow(), phase, mParent->mTime, mSurfacePos, mGlobalPos,
1178 pixelDelta, angleDelta,
source, mParent->modifiers(), inverted));
1180 mFrameData.resetScrollData();
1183void QWaylandInputDevice::Pointer::flushFrameEvent()
1185 if (
auto *
event = mFrameData.event) {
1196 delete mFrameData.event;
1197 mFrameData.event =
nullptr;
1204bool QWaylandInputDevice::Pointer::isDefinitelyTerminated(QtWayland::wl_pointer::axis_source
source)
const
1206 return source == axis_source_finger;
1209void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t
format, int32_t
fd, uint32_t
size)
1212#if QT_CONFIG(xkbcommon)
1213 if (
format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
1219 char *map_str =
static_cast<char *
>(mmap(
nullptr,
size, PROT_READ, MAP_PRIVATE,
fd, 0));
1225 mXkbKeymap.reset(xkb_keymap_new_from_string(mParent->mQDisplay->xkbContext(), map_str,
1226 XKB_KEYMAP_FORMAT_TEXT_V1,
1227 XKB_KEYMAP_COMPILE_NO_FLAGS));
1230 munmap(map_str,
size);
1234 mXkbState.reset(xkb_state_new(mXkbKeymap.get()));
1236 mXkbState.reset(
nullptr);
1243void QWaylandInputDevice::Keyboard::keyboard_enter(uint32_t
time,
struct wl_surface *surface,
struct wl_array *
keys)
1259 qCWarning(lcQpaWayland()) <<
"Unexpected wl_keyboard.enter event. Keyboard already has focus";
1263 mFocus =
window->waylandSurface();
1266 mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
1269void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t
time,
struct wl_surface *surface)
1282 if (
window->waylandSurface() != mFocus) {
1283 qCWarning(lcQpaWayland) <<
"Ignoring unexpected wl_keyboard.leave event."
1284 <<
"wl_surface argument does not match the current focus"
1285 <<
"This is most likely a compositor bug";
1302 nativeModifiers,
text, autorepeat,
count);
1303 event.setTimestamp(timestamp);
1308 auto window = focusWindow()->window();
1320 nativeScanCode, nativeVirtualKey, nativeModifiers,
text, autorepeat,
count);
1324void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t
time, uint32_t
key, uint32_t
state)
1326 if (mKeymapFormat != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 && mKeymapFormat != WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP) {
1331 auto *
window = focusWindow();
1338 mParent->mSerial = serial;
1340 const bool isDown =
state != WL_KEYBOARD_KEY_STATE_RELEASED;
1342 mParent->mQDisplay->setLastInputDevice(mParent, serial,
window);
1344 if (mKeymapFormat == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
1345#if QT_CONFIG(xkbcommon)
1346 if ((!mXkbKeymap || !mXkbState) && !createDefaultKeymap())
1351 xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState.get(), code);
1354 int qtkey = keysymToQtKey(sym,
modifiers, mXkbState.get(), code);
1360 if (
state == WL_KEYBOARD_KEY_STATE_PRESSED && xkb_keymap_key_repeats(mXkbKeymap.get(), code) && mRepeatRate > 0) {
1361 mRepeatKey.key = qtkey;
1362 mRepeatKey.code =
code;
1363 mRepeatKey.time =
time;
1364 mRepeatKey.text =
text;
1365 mRepeatKey.nativeVirtualKey = sym;
1366 mRepeatTimer.setInterval(mRepeatDelay);
1367 mRepeatTimer.start();
1368 }
else if (mRepeatKey.code == code) {
1369 mRepeatTimer.stop();
1374 qCWarning(lcQpaWayland,
"xkbcommon not available on this build, not performing key mapping");
1377 }
else if (mKeymapFormat == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP) {
1383void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
1388void QWaylandInputDevice::Keyboard::handleFocusLost()
1391 mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
1392 mRepeatTimer.stop();
1395void QWaylandInputDevice::Keyboard::keyboard_modifiers(uint32_t serial,
1396 uint32_t mods_depressed,
1397 uint32_t mods_latched,
1398 uint32_t mods_locked,
1402#if QT_CONFIG(xkbcommon)
1404 xkb_state_update_mask(mXkbState.get(),
1405 mods_depressed, mods_latched, mods_locked,
1407 mNativeModifiers = mods_depressed | mods_latched | mods_locked;
1416void QWaylandInputDevice::Keyboard::keyboard_repeat_info(int32_t
rate, int32_t delay)
1419 mRepeatDelay = delay;
1422void QWaylandInputDevice::Touch::touch_down(uint32_t serial,
1424 struct wl_surface *surface,
1436 mParent->mTime =
time;
1437 mParent->mSerial = serial;
1439 mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus);
1444void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t
time, int32_t
id)
1447 mParent->mTime =
time;
1450 if (allTouchPointsReleased()) {
1459 qCDebug(lcQpaWayland,
"Generating fake frame event to work around Weston bug");
1464void QWaylandInputDevice::Touch::touch_motion(uint32_t
time, int32_t
id, wl_fixed_t
x, wl_fixed_t
y)
1467 mParent->mTime =
time;
1471void QWaylandInputDevice::Touch::touch_cancel()
1473 mPendingTouchPoints.clear();
1475 QWaylandTouchExtension *touchExt = mParent->mQDisplay->touchExtension();
1477 touchExt->touchCanceled();
1485 auto end =
mTouch->mPendingTouchPoints.end();
1515 QPointF localPosition =
win->mapFromWlSurface(surfacePosition);
1530bool QWaylandInputDevice::Touch::allTouchPointsReleased()
1532 for (
const auto &tp :
std::as_const(mPendingTouchPoints)) {
1539void QWaylandInputDevice::Touch::releasePoints()
1541 if (mPendingTouchPoints.empty())
1550void QWaylandInputDevice::Touch::touch_frame()
1560 if (mPendingTouchPoints.empty())
1565 QMargins margins = mFocus->clientSideMargins();
1568 if (mFocus->touchDragDecoration(mParent, localPos, tp.
area.
center(), tp.
state, mParent->modifiers()))
1575 const auto prevTouchPoints = mPendingTouchPoints;
1576 mPendingTouchPoints.clear();
1577 for (
const auto &prevPoint: prevTouchPoints) {
1582 mPendingTouchPoints.append(tp);
1592#include "moc_qwaylandinputdevice_p.cpp"
IOBluetoothDevice * device
The QCursor class provides a mouse cursor with an arbitrary shape.
QPixmap pixmap() const
Returns the cursor pixmap.
Qt::CursorShape shape() const
Returns the cursor shape identifier.
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
QPoint hotSpot() const
Returns the cursor hot spot, or (0, 0) if it is one of the standard cursors.
The QEventPoint class provides information about a point in a QPointerEvent.
State
Specifies the state of this event point.
Type
This enum type defines the valid event types in Qt.
static QPlatformIntegration * platformIntegration()
static QPlatformTheme * platformTheme()
The QKeyEvent class describes a key event.
constexpr int left() const noexcept
Returns the left margin.
constexpr int top() const noexcept
Returns the top margin.
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
qreal devicePixelRatio() const
Returns the device pixel ratio for the pixmap.
The QPlatformInputContext class abstracts the input method dependent data and composing state.
virtual bool filterEvent(const QEvent *event)
This function can be reimplemented to filter input events.
\inmodule QtCore\reentrant
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0.0 (ignoring the sign); otherwise returns fa...
\inmodule QtCore\reentrant
constexpr bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
QPointingDeviceUniqueId identifies a unique object, such as a tagged token or stylus,...
The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
\inmodule QtCore\reentrant
constexpr void moveCenter(const QPointF &p) noexcept
Moves the rectangle, leaving the center point at the given position.
constexpr QPointF center() const noexcept
Returns the center point of the rectangle.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\macro QT_RESTRICTED_CAST_FROM_ASCII
\qmltype WaylandSurface \instantiates QWaylandSurface \inqmlmodule QtWayland.Compositor
static bool handleTouchEvent(QWindow *window, const QPointingDevice *device, const QList< struct TouchPoint > &points, Qt::KeyboardModifiers mods=Qt::NoModifier)
static void handleFocusWindowChanged(QWindow *window, Qt::FocusReason r=Qt::OtherFocusReason)
static bool handleTouchCancelEvent(QWindow *window, const QPointingDevice *device, Qt::KeyboardModifiers mods=Qt::NoModifier)
static void handleContextMenuEvent(QWindow *window, bool mouseTriggered, const QPoint &pos, const QPoint &globalPos, Qt::KeyboardModifiers modifiers)
static bool handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static void registerInputDevice(const QInputDevice *device)
static bool handleExtendedKeyEvent(QWindow *window, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
static QString lookupString(struct xkb_state *state, xkb_keycode_t code)
static void verifyHasLatinLayout(xkb_keymap *keymap)
static Qt::KeyboardModifiers modifiers(struct xkb_state *state, xkb_keysym_t keysym=XKB_KEY_VoidSymbol)
static QList< int > possibleKeys(xkb_state *state, const QKeyEvent *event, bool superAsMeta=false, bool hyperAsMeta=false)
EnterEvent(QWaylandWindow *surface, const QPointF &local, const QPointF &global)
LeaveEvent(QWaylandWindow *surface, const QPointF &localPos, const QPointF &globalPos)
MotionEvent(QWaylandWindow *surface, ulong timestamp, const QPointF &localPos, const QPointF &globalPos, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
PressEvent(QWaylandWindow *surface, ulong timestamp, const QPointF &localPos, const QPointF &globalPos, Qt::MouseButtons buttons, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
QtWayland::zwp_text_input_manager_v3 * textInputManagerv3() const
QtWayland::zwp_text_input_manager_v1 * textInputManagerv1() const
QWaylandPointerGestures * pointerGestures() const
QtWayland::zwp_text_input_manager_v2 * textInputManagerv2() const
QtWayland::qt_text_input_method_manager_v1 * textInputMethodManager() const
QPointer< QWaylandWindow > surface
static QWaylandWindow * fromWlSurface(::wl_surface *surface)
static QWaylandWindow * mouseGrab()
ReleaseEvent(QWaylandWindow *surface, ulong timestamp, const QPointF &localPos, const QPointF &globalPos, Qt::MouseButtons buttons, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
WheelEvent(QWaylandWindow *surface, Qt::ScrollPhase phase, ulong timestamp, const QPointF &local, const QPointF &global, const QPoint &pixelDelta, const QPoint &angleDelta, Qt::MouseEventSource source, Qt::KeyboardModifiers modifiers, bool inverted)
EGLImageKHR int int EGLuint64KHR * modifiers
QSet< QString >::iterator it
struct wl_display * display
Combined button and popup list for selecting options.
QFuture< typename std::decay_t< Sequence >::value_type > filtered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep)
Calls filterFunction once for each item in sequence and returns a new Sequence of kept items.
static const int MaxTouchPoints
@ MouseEventSynthesizedBySystem
@ MouseEventNotSynthesized
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLint GLint GLint GLsizei GLsizei GLsizei GLboolean commit
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
GLsizei const void * pointer
GLenum GLenum GLenum GLenum GLenum scale
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
myObject disconnect()
[26]