10#if QT_CONFIG(draganddrop)
11#include <QtWaylandCompositor/QWaylandDrag>
13#include <QtWaylandCompositor/QWaylandTouch>
14#include <QtWaylandCompositor/QWaylandPointer>
15#include <QtWaylandCompositor/QWaylandKeymap>
16#include <QtWaylandCompositor/private/qwaylandseat_p.h>
17#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
18#include <QtWaylandCompositor/private/qwaylandkeyboard_p.h>
19#if QT_CONFIG(wayland_datadevice)
20#include <QtWaylandCompositor/private/qwldatadevice_p.h>
22#include <QtWaylandCompositor/private/qwaylandutils_p.h>
24#include "extensions/qwaylandtextinput.h"
25#include "extensions/qwaylandtextinputv3.h"
26#include "extensions/qwaylandqttextinputmethod.h"
30int QWaylandSeatPrivate::max_name = 0;
32QWaylandSeatPrivate::QWaylandSeatPrivate(QWaylandSeat *seat) :
33#if QT_CONFIG(wayland_datadevice)
34 drag_handle(
new QWaylandDrag(seat)),
36 keymap(
new QWaylandKeymap())
40QWaylandSeatPrivate::~QWaylandSeatPrivate()
44void QWaylandSeatPrivate::setCapabilities(QWaylandSeat::CapabilityFlags caps)
47 if (capabilities != caps) {
48 QWaylandSeat::CapabilityFlags changed = caps ^ capabilities;
50 if (changed & QWaylandSeat::Pointer) {
51 pointer.reset(pointer.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreatePointerDevice(q) :
nullptr);
54 if (changed & QWaylandSeat::Keyboard) {
55 keyboard.reset(keyboard.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateKeyboardDevice(q) :
nullptr);
58 if (changed & QWaylandSeat::Touch) {
59 touch.reset(touch.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateTouchDevice(q) :
nullptr);
63 QList<Resource *> resources = resourceMap().values();
64 for (
int i = 0; i < resources.size(); i++) {
65 wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)capabilities);
68 if ((changed & caps & QWaylandSeat::Keyboard) && keyboardFocus !=
nullptr)
69 keyboard->setFocus(keyboardFocus);
73#if QT_CONFIG(wayland_datadevice)
74void QWaylandSeatPrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *,
struct wl_client *client, uint32_t id)
78 data_device.reset(
new QtWayland::DataDevice(q));
79 data_device->add(client, id, 1);
83void QWaylandSeatPrivate::seat_destroy_resource(wl_seat::Resource *)
88void QWaylandSeatPrivate::seat_bind_resource(wl_seat::Resource *resource)
90 if (resource->version() >= WL_SEAT_NAME_SINCE_VERSION)
91 wl_seat::send_name(resource->handle, QLatin1String(
"seat") + QString::number(name));
93 wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities);
96void QWaylandSeatPrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
98 if (!pointer.isNull()) {
99 pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
103void QWaylandSeatPrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
105 if (!keyboard.isNull()) {
106 keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
110void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
112 if (!touch.isNull()) {
113 touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
118
119
120
121
122
123
124
125
126
127
130
131
132
133
134
135
136
137
140
141
142
143
144
145
146
147
148
151
152
153QWaylandSeat::QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags)
154 : QWaylandObject(*
new QWaylandSeatPrivate(
this))
158 d->name = d->max_name++;
159 d->compositor = compositor;
160 d->capabilities = capabilityFlags;
161 if (compositor->isCreated())
164#if QT_DEPRECATED_SINCE(6
, 1
)
166 connect(
this, &QWaylandSeat::cursorSurfaceRequested,
this, &QWaylandSeat::cursorSurfaceRequest);
171
172
173QWaylandSeat::~QWaylandSeat()
178
179
180
181
182
183
185void QWaylandSeat::initialize()
188 d->init(d->compositor->display(), 4);
190 if (d->capabilities & QWaylandSeat::Pointer)
191 d->pointer.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreatePointerDevice(
this));
192 if (d->capabilities & QWaylandSeat::Touch)
193 d->touch.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateTouchDevice(
this));
194 if (d->capabilities & QWaylandSeat::Keyboard)
195 d->keyboard.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateKeyboardDevice(
this));
197 d->isInitialized =
true;
201
202
203
204
205bool QWaylandSeat::isInitialized()
const
207 Q_D(
const QWaylandSeat);
208 return d->isInitialized;
212
213
214void QWaylandSeat::sendMousePressEvent(Qt::MouseButton button)
217 d->pointer->sendMousePressEvent(button);
221
222
223void QWaylandSeat::sendMouseReleaseEvent(Qt::MouseButton button)
226 d->pointer->sendMouseReleaseEvent(button);
230
231
232
233void QWaylandSeat::sendMouseMoveEvent(QWaylandView *view,
const QPointF &localPos,
const QPointF &outputSpacePos)
236 d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos);
240
241
242void QWaylandSeat::sendMouseWheelEvent(Qt::Orientation orientation,
int delta)
245 d->pointer->sendMouseWheelEvent(orientation, delta);
249
250
251void QWaylandSeat::sendKeyPressEvent(uint code)
254 d->keyboard->sendKeyPressEvent(code);
258
259
260void QWaylandSeat::sendKeyReleaseEvent(uint code)
263 d->keyboard->sendKeyReleaseEvent(code);
267
268
269
270
271
272
273
274
275
276uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface,
int id,
const QPointF &point, Qt::TouchPointState state)
280 if (d->touch.isNull())
283 return d->touch->sendTouchPointEvent(surface, id, point,state);
287
288
289
290
291
292
293
294
295
296
297
298
299
300
303
304
305
306
307
308
309
310
311
312
313
314
315uint QWaylandSeat::sendTouchPointPressed(QWaylandSurface *surface,
int id,
const QPointF &position)
317 return sendTouchPointEvent(surface, id, position, Qt::TouchPointPressed);
321
322
323
324
325
326
327
328
329
330
331
332
333
334
337
338
339
340
341
342
343
344
345
346
347
348
349uint QWaylandSeat::sendTouchPointReleased(QWaylandSurface *surface,
int id,
const QPointF &position)
351 return sendTouchPointEvent(surface, id, position, Qt::TouchPointReleased);
355
356
357
358
359
360
361
362
363
364
365
366
367
368
371
372
373
374
375
376
377
378
379
380
381
382
383uint QWaylandSeat::sendTouchPointMoved(QWaylandSurface *surface,
int id,
const QPointF &position)
385 return sendTouchPointEvent(surface, id, position, Qt::TouchPointMoved);
389
390
391
392
393
396
397
398
399void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
402 if (!d->touch.isNull())
403 d->touch->sendFrameEvent(client);
407
408
409
410
413
414
415void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
418 if (!d->touch.isNull())
419 d->touch->sendCancelEvent(client);
423
424
425
426
427
428
429
430void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
437 d->touch->sendFullTouchEvent(surface, event);
441
442
443
444
445
446
447
448void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event)
452 if (!keyboardFocus()) {
453 qWarning(
"Cannot send key event, no keyboard focus, fix the compositor");
458 if (keyboardFocus()->inputMethodControl()->enabled()
459 && event->nativeScanCode() == 0) {
460 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) {
461 QWaylandTextInput *textInput = QWaylandTextInput::findIn(
this);
463 textInput->sendKeyEvent(event);
468 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) {
469 QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(
this);
470 if (textInputMethod) {
471 textInputMethod->sendKeyEvent(event);
476 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) {
477 QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(
this);
478 if (textInputV3 && !event->text().isEmpty()) {
480 if (event->type() == QEvent::KeyPress)
481 textInputV3->sendKeyEvent(event);
488 if (!d->keyboard.isNull() && !event->isAutoRepeat()) {
490 uint scanCode = event->nativeScanCode();
492 scanCode = d->keyboard->keyToScanCode(event->key());
495 qWarning() <<
"Can't send Wayland key event: Unable to get a valid scan code";
499 if (event->type() == QEvent::KeyPress) {
500 QWaylandKeyboardPrivate::get(d->keyboard.data())->checkAndRepairModifierState(event);
501 d->keyboard->sendKeyPressEvent(scanCode);
502 }
else if (event->type() == QEvent::KeyRelease) {
503 d->keyboard->sendKeyReleaseEvent(scanCode);
509
510
511
512
513
514
517
518
519
520
521
522
523
524
525void QWaylandSeat::sendKeyEvent(
int qtKey,
bool pressed)
528 if (!keyboardFocus()) {
529 qWarning(
"Cannot send Wayland key event, no keyboard focus, fix the compositor");
533 if (
auto scanCode = d->keyboard->keyToScanCode(qtKey)) {
535 d->keyboard->sendKeyPressEvent(scanCode);
537 d->keyboard->sendKeyReleaseEvent(scanCode);
539 qWarning() <<
"Can't send Wayland key event: Unable to get scan code for" << Qt::Key(qtKey);
544
545
546
547
548
549
550
551
554
555
556
557
558
559
560
561
562
563void QWaylandSeat::sendUnicodeKeyPressEvent(uint unicode)
565 sendUnicodeKeyEvent(unicode, QEvent::KeyPress);
569
570
571
572
573
574
575
576
579
580
581
582
583
584
585
586
587
588void QWaylandSeat::sendUnicodeKeyReleaseEvent(uint unicode)
590 sendUnicodeKeyEvent(unicode, QEvent::KeyRelease);
594
595
596
597
598void QWaylandSeat::sendUnicodeKeyEvent(uint unicode, QEvent::Type eventType)
600 if (!keyboardFocus()) {
601 qWarning(
"Can't send a unicode key event, no keyboard focus, fix the compositor");
606 text += QChar::fromUcs4(
static_cast<
char32_t>(unicode));
608 QKeyEvent event(eventType, Qt::Key_unknown, Qt::KeyboardModifiers{}, text);
609 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) {
610 QWaylandTextInput *textInput = QWaylandTextInput::findIn(
this);
612 textInput->sendKeyEvent(&event);
617 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) {
618 QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(
this);
619 if (textInputMethod) {
620 textInputMethod->sendKeyEvent(&event);
625 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) {
626 QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(
this);
627 if (textInputV3 && !text.isEmpty()) {
629 if (eventType == QEvent::KeyPress)
630 textInputV3->sendKeyEvent(&event);
637 qWarning() <<
"Can't send a unicode key event: Unable to find a text-input protocol.";
642
643
644QWaylandKeyboard *QWaylandSeat::keyboard()
const
646 Q_D(
const QWaylandSeat);
647 return d->keyboard.data();
651
652
653QWaylandSurface *QWaylandSeat::keyboardFocus()
const
655 Q_D(
const QWaylandSeat);
656 if (d->keyboard.isNull() || !d->keyboard->focus())
659 return d->keyboard->focus();
663
664
665
666
667bool QWaylandSeat::setKeyboardFocus(QWaylandSurface *surface)
670 if (surface && surface->isDestroyed())
673 QWaylandSurface *oldSurface = keyboardFocus();
674 if (surface == oldSurface)
677 d->keyboardFocus = surface;
678 if (!d->keyboard.isNull())
679 d->keyboard->setFocus(surface);
680#if QT_CONFIG(wayland_datadevice)
682 d->data_device->setFocus(surface ? surface->client() :
nullptr);
684 emit keyboardFocusChanged(surface, oldSurface);
690
691
693QWaylandKeymap *QWaylandSeat::keymap()
695 Q_D(
const QWaylandSeat);
696 return d->keymap.data();
700
701
702QWaylandPointer *QWaylandSeat::pointer()
const
704 Q_D(
const QWaylandSeat);
705 return d->pointer.data();
709
710
711QWaylandTouch *QWaylandSeat::touch()
const
713 Q_D(
const QWaylandSeat);
714 return d->touch.data();
718
719
720QWaylandView *QWaylandSeat::mouseFocus()
const
722 Q_D(
const QWaylandSeat);
723 return d->mouseFocus;
727
728
729void QWaylandSeat::setMouseFocus(QWaylandView *view)
732 if (view == d->mouseFocus)
735 QWaylandView *oldFocus = d->mouseFocus;
736 d->mouseFocus = view;
739 disconnect(oldFocus, &QObject::destroyed,
this, &QWaylandSeat::handleMouseFocusDestroyed);
741 connect(d->mouseFocus, &QObject::destroyed,
this, &QWaylandSeat::handleMouseFocusDestroyed);
743 emit mouseFocusChanged(d->mouseFocus, oldFocus);
747
748
749QWaylandCompositor *QWaylandSeat::compositor()
const
751 Q_D(
const QWaylandSeat);
752 return d->compositor;
756
757
758#if QT_CONFIG(draganddrop)
759QWaylandDrag *QWaylandSeat::drag()
const
761 Q_D(
const QWaylandSeat);
762 return d->drag_handle.data();
767
768
769QWaylandSeat::CapabilityFlags QWaylandSeat::capabilities()
const
771 Q_D(
const QWaylandSeat);
772 return d->capabilities;
776
777
778bool QWaylandSeat::isOwner(QInputEvent *inputEvent)
const
780 Q_UNUSED(inputEvent);
785
786
787
788QWaylandSeat *QWaylandSeat::fromSeatResource(
struct ::wl_resource *resource)
790 if (
auto p = QtWayland::fromResource<QWaylandSeatPrivate *>(resource))
796
797
798
799
801void QWaylandSeat::handleMouseFocusDestroyed()
807 d->mouseFocus =
nullptr;
808 QWaylandView *oldFocus =
nullptr;
809 emit mouseFocusChanged(d->mouseFocus, oldFocus);
814
815
816
817
818
819
820
821
824
825
826
827
828
829
830
831
834
835
836
837
838
839
840
841
842
846
847
848
849
850
851
852
853
854
855
858
859
860
861
862
863
866
867
868
869
870
871
872
873
874
875
879#include "moc_qwaylandseat.cpp"
Combined button and popup list for selecting options.