11#if QT_CONFIG(draganddrop)
12#include <QtWaylandCompositor/QWaylandDrag>
14#include <QtWaylandCompositor/QWaylandTouch>
15#include <QtWaylandCompositor/QWaylandPointer>
16#include <QtWaylandCompositor/QWaylandKeymap>
17#include <QtWaylandCompositor/private/qwaylandseat_p.h>
18#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
19#include <QtWaylandCompositor/private/qwaylandkeyboard_p.h>
20#if QT_CONFIG(wayland_datadevice)
21#include <QtWaylandCompositor/private/qwldatadevice_p.h>
23#include <QtWaylandCompositor/private/qwaylandutils_p.h>
25#include "extensions/qwaylandtextinput.h"
26#include "extensions/qwaylandtextinputv3.h"
27#include "extensions/qwaylandqttextinputmethod.h"
31int QWaylandSeatPrivate::max_name = 0;
33QWaylandSeatPrivate::QWaylandSeatPrivate(QWaylandSeat *seat) :
34#if QT_CONFIG(wayland_datadevice)
35 drag_handle(
new QWaylandDrag(seat)),
37 keymap(
new QWaylandKeymap())
41QWaylandSeatPrivate::~QWaylandSeatPrivate()
45void QWaylandSeatPrivate::setCapabilities(QWaylandSeat::CapabilityFlags caps)
48 if (capabilities != caps) {
49 QWaylandSeat::CapabilityFlags changed = caps ^ capabilities;
51 if (changed & QWaylandSeat::Pointer) {
52 pointer.reset(pointer.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreatePointerDevice(q) :
nullptr);
55 if (changed & QWaylandSeat::Keyboard) {
56 keyboard.reset(keyboard.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateKeyboardDevice(q) :
nullptr);
59 if (changed & QWaylandSeat::Touch) {
60 touch.reset(touch.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateTouchDevice(q) :
nullptr);
64 QList<Resource *> resources = resourceMap().values();
65 for (
int i = 0; i < resources.size(); i++) {
66 wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)capabilities);
69 if ((changed & caps & QWaylandSeat::Keyboard) && keyboardFocus !=
nullptr)
70 keyboard->setFocus(keyboardFocus);
74#if QT_CONFIG(wayland_datadevice)
75void QWaylandSeatPrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *,
struct wl_client *client, uint32_t id)
79 data_device.reset(
new QtWayland::DataDevice(q));
80 data_device->add(client, id, 1);
84void QWaylandSeatPrivate::seat_destroy_resource(wl_seat::Resource *)
89void QWaylandSeatPrivate::seat_bind_resource(wl_seat::Resource *resource)
91 if (resource->version() >= WL_SEAT_NAME_SINCE_VERSION)
92 wl_seat::send_name(resource->handle, QLatin1String(
"seat") + QString::number(name));
94 wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities);
97void QWaylandSeatPrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
99 if (!pointer.isNull()) {
100 pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
104void QWaylandSeatPrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
106 if (!keyboard.isNull()) {
107 keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
111void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
113 if (!touch.isNull()) {
114 touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
119
120
121
122
123
124
125
126
127
128
131
132
133
134
135
136
137
138
141
142
143
144
145
146
147
148
149
152
153
154QWaylandSeat::QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags)
155 : QWaylandObject(*
new QWaylandSeatPrivate(
this))
159 d->name = d->max_name++;
160 d->compositor = compositor;
161 d->capabilities = capabilityFlags;
162 if (compositor->isCreated())
165#if QT_DEPRECATED_SINCE(6
, 1
)
167 connect(
this, &QWaylandSeat::cursorSurfaceRequested,
this, &QWaylandSeat::cursorSurfaceRequest);
172
173
174QWaylandSeat::~QWaylandSeat()
179
180
181
182
183
184
186void QWaylandSeat::initialize()
189 d->init(d->compositor->display(), 4);
191 if (d->capabilities & QWaylandSeat::Pointer)
192 d->pointer.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreatePointerDevice(
this));
193 if (d->capabilities & QWaylandSeat::Touch)
194 d->touch.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateTouchDevice(
this));
195 if (d->capabilities & QWaylandSeat::Keyboard)
196 d->keyboard.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateKeyboardDevice(
this));
198 d->isInitialized =
true;
202
203
204
205
206bool QWaylandSeat::isInitialized()
const
208 Q_D(
const QWaylandSeat);
209 return d->isInitialized;
213
214
215void QWaylandSeat::sendMousePressEvent(Qt::MouseButton button)
218 d->pointer->sendMousePressEvent(button);
222
223
224void QWaylandSeat::sendMouseReleaseEvent(Qt::MouseButton button)
227 d->pointer->sendMouseReleaseEvent(button);
231
232
233
234void QWaylandSeat::sendMouseMoveEvent(QWaylandView *view,
const QPointF &localPos,
const QPointF &outputSpacePos)
237 d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos);
241
242
243void QWaylandSeat::sendMouseWheelEvent(Qt::Orientation orientation,
int delta)
246 d->pointer->sendMouseWheelEvent(orientation, delta);
250
251
252void QWaylandSeat::sendKeyPressEvent(uint code)
255 d->keyboard->sendKeyPressEvent(code);
259
260
261void QWaylandSeat::sendKeyReleaseEvent(uint code)
264 d->keyboard->sendKeyReleaseEvent(code);
268
269
270
271
272
273
274
275
276
277uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface,
int id,
const QPointF &point, Qt::TouchPointState state)
281 if (d->touch.isNull())
284 return d->touch->sendTouchPointEvent(surface, id, point,state);
288
289
290
291
292
293
294
295
296
297
298
299
300
301
304
305
306
307
308
309
310
311
312
313
314
315
316uint QWaylandSeat::sendTouchPointPressed(QWaylandSurface *surface,
int id,
const QPointF &position)
318 return sendTouchPointEvent(surface, id, position, Qt::TouchPointPressed);
322
323
324
325
326
327
328
329
330
331
332
333
334
335
338
339
340
341
342
343
344
345
346
347
348
349
350uint QWaylandSeat::sendTouchPointReleased(QWaylandSurface *surface,
int id,
const QPointF &position)
352 return sendTouchPointEvent(surface, id, position, Qt::TouchPointReleased);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
372
373
374
375
376
377
378
379
380
381
382
383
384uint QWaylandSeat::sendTouchPointMoved(QWaylandSurface *surface,
int id,
const QPointF &position)
386 return sendTouchPointEvent(surface, id, position, Qt::TouchPointMoved);
390
391
392
393
394
397
398
399
400void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
403 if (!d->touch.isNull())
404 d->touch->sendFrameEvent(client);
408
409
410
411
414
415
416void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
419 if (!d->touch.isNull())
420 d->touch->sendCancelEvent(client);
424
425
426
427
428
429
430
431void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
438 d->touch->sendFullTouchEvent(surface, event);
442
443
444
445
446
447
448
449void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event)
453 if (!keyboardFocus()) {
454 qWarning(
"Cannot send key event, no keyboard focus, fix the compositor");
459 if (keyboardFocus()->inputMethodControl()->enabled()
460 && event->nativeScanCode() == 0) {
461 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) {
462 QWaylandTextInput *textInput = QWaylandTextInput::findIn(
this);
464 textInput->sendKeyEvent(event);
469 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) {
470 QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(
this);
471 if (textInputMethod) {
472 textInputMethod->sendKeyEvent(event);
477 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) {
478 QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(
this);
479 if (textInputV3 && !event->text().isEmpty()) {
481 if (event->type() == QEvent::KeyPress)
482 textInputV3->sendKeyEvent(event);
489 if (!d->keyboard.isNull() && !event->isAutoRepeat()) {
491 uint scanCode = event->nativeScanCode();
493 scanCode = d->keyboard->keyToScanCode(event->key());
496 qWarning() <<
"Can't send Wayland key event: Unable to get a valid scan code";
500 if (event->type() == QEvent::KeyPress) {
501 QWaylandKeyboardPrivate::get(d->keyboard.data())->checkAndRepairModifierState(event);
502 d->keyboard->sendKeyPressEvent(scanCode);
503 }
else if (event->type() == QEvent::KeyRelease) {
504 d->keyboard->sendKeyReleaseEvent(scanCode);
510
511
512
513
514
515
518
519
520
521
522
523
524
525
526void QWaylandSeat::sendKeyEvent(
int qtKey,
bool pressed)
529 if (!keyboardFocus()) {
530 qWarning(
"Cannot send Wayland key event, no keyboard focus, fix the compositor");
534 if (
auto scanCode = d->keyboard->keyToScanCode(qtKey)) {
536 d->keyboard->sendKeyPressEvent(scanCode);
538 d->keyboard->sendKeyReleaseEvent(scanCode);
540 qWarning() <<
"Can't send Wayland key event: Unable to get scan code for" << Qt::Key(qtKey);
545
546
547
548
549
550
551
552
555
556
557
558
559
560
561
562
563
564void QWaylandSeat::sendUnicodeKeyPressEvent(uint unicode)
566 sendUnicodeKeyEvent(unicode, QEvent::KeyPress);
570
571
572
573
574
575
576
577
580
581
582
583
584
585
586
587
588
589void QWaylandSeat::sendUnicodeKeyReleaseEvent(uint unicode)
591 sendUnicodeKeyEvent(unicode, QEvent::KeyRelease);
595
596
597
598
599void QWaylandSeat::sendUnicodeKeyEvent(uint unicode, QEvent::Type eventType)
601 if (!keyboardFocus()) {
602 qWarning(
"Can't send a unicode key event, no keyboard focus, fix the compositor");
607 text += QChar::fromUcs4(
static_cast<
char32_t>(unicode));
609 QKeyEvent event(eventType, Qt::Key_unknown, Qt::KeyboardModifiers{}, text);
610 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) {
611 QWaylandTextInput *textInput = QWaylandTextInput::findIn(
this);
613 textInput->sendKeyEvent(&event);
618 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) {
619 QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(
this);
620 if (textInputMethod) {
621 textInputMethod->sendKeyEvent(&event);
626 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) {
627 QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(
this);
628 if (textInputV3 && !text.isEmpty()) {
630 if (eventType == QEvent::KeyPress)
631 textInputV3->sendKeyEvent(&event);
638 qWarning() <<
"Can't send a unicode key event: Unable to find a text-input protocol.";
643
644
645QWaylandKeyboard *QWaylandSeat::keyboard()
const
647 Q_D(
const QWaylandSeat);
648 return d->keyboard.data();
652
653
654QWaylandSurface *QWaylandSeat::keyboardFocus()
const
656 Q_D(
const QWaylandSeat);
657 if (d->keyboard.isNull() || !d->keyboard->focus())
660 return d->keyboard->focus();
664
665
666
667
668bool QWaylandSeat::setKeyboardFocus(QWaylandSurface *surface)
671 if (surface && surface->isDestroyed())
674 QWaylandSurface *oldSurface = keyboardFocus();
675 if (surface == oldSurface)
678 d->keyboardFocus = surface;
679 if (!d->keyboard.isNull())
680 d->keyboard->setFocus(surface);
681#if QT_CONFIG(wayland_datadevice)
683 d->data_device->setFocus(surface ? surface->client() :
nullptr);
685 emit keyboardFocusChanged(surface, oldSurface);
691
692
694QWaylandKeymap *QWaylandSeat::keymap()
696 Q_D(
const QWaylandSeat);
697 return d->keymap.data();
701
702
703QWaylandPointer *QWaylandSeat::pointer()
const
705 Q_D(
const QWaylandSeat);
706 return d->pointer.data();
710
711
712QWaylandTouch *QWaylandSeat::touch()
const
714 Q_D(
const QWaylandSeat);
715 return d->touch.data();
719
720
721QWaylandView *QWaylandSeat::mouseFocus()
const
723 Q_D(
const QWaylandSeat);
724 return d->mouseFocus;
728
729
730void QWaylandSeat::setMouseFocus(QWaylandView *view)
733 if (view == d->mouseFocus)
736 QWaylandView *oldFocus = d->mouseFocus;
737 d->mouseFocus = view;
740 disconnect(oldFocus, &QObject::destroyed,
this, &QWaylandSeat::handleMouseFocusDestroyed);
742 connect(d->mouseFocus, &QObject::destroyed,
this, &QWaylandSeat::handleMouseFocusDestroyed);
744 emit mouseFocusChanged(d->mouseFocus, oldFocus);
748
749
750QWaylandCompositor *QWaylandSeat::compositor()
const
752 Q_D(
const QWaylandSeat);
753 return d->compositor;
757
758
759#if QT_CONFIG(draganddrop)
760QWaylandDrag *QWaylandSeat::drag()
const
762 Q_D(
const QWaylandSeat);
763 return d->drag_handle.data();
768
769
770QWaylandSeat::CapabilityFlags QWaylandSeat::capabilities()
const
772 Q_D(
const QWaylandSeat);
773 return d->capabilities;
777
778
779bool QWaylandSeat::isOwner(QInputEvent *inputEvent)
const
781 Q_UNUSED(inputEvent);
786
787
788
789QWaylandSeat *QWaylandSeat::fromSeatResource(
struct ::wl_resource *resource)
791 if (
auto p = QtWayland::fromResource<QWaylandSeatPrivate *>(resource))
797
798
799
800
802void QWaylandSeat::handleMouseFocusDestroyed()
808 d->mouseFocus =
nullptr;
809 QWaylandView *oldFocus =
nullptr;
810 emit mouseFocusChanged(d->mouseFocus, oldFocus);
815
816
817
818
819
820
821
822
825
826
827
828
829
830
831
832
835
836
837
838
839
840
841
842
843
847
848
849
850
851
852
853
854
855
856
859
860
861
862
863
864
867
868
869
870
871
872
873
874
875
876
880#include "moc_qwaylandseat.cpp"
Combined button and popup list for selecting options.