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 wl_seat::send_name(resource->handle, QStringLiteral(
"seat%1").arg(QString::number(name)));
92 wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities);
95void QWaylandSeatPrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
97 if (!pointer.isNull()) {
98 pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
102void QWaylandSeatPrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
104 if (!keyboard.isNull()) {
105 keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
109void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
111 if (!touch.isNull()) {
112 touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
117
118
119
120
121
122
123
124
125
126
129
130
131
132
133
134
135
136
139
140
141
142
143
144
145
146
147
150
151
152QWaylandSeat::QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags)
153 : QWaylandObject(*
new QWaylandSeatPrivate(
this))
157 d->name = d->max_name++;
158 d->compositor = compositor;
159 d->capabilities = capabilityFlags;
160 if (compositor->isCreated())
163#if QT_DEPRECATED_SINCE(6
, 1
)
165 connect(
this, &QWaylandSeat::cursorSurfaceRequested,
this, &QWaylandSeat::cursorSurfaceRequest);
170
171
172QWaylandSeat::~QWaylandSeat()
177
178
179
180
181
182
184void QWaylandSeat::initialize()
187 d->init(d->compositor->display(), 4);
189 if (d->capabilities & QWaylandSeat::Pointer)
190 d->pointer.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreatePointerDevice(
this));
191 if (d->capabilities & QWaylandSeat::Touch)
192 d->touch.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateTouchDevice(
this));
193 if (d->capabilities & QWaylandSeat::Keyboard)
194 d->keyboard.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateKeyboardDevice(
this));
196 d->isInitialized =
true;
200
201
202
203
204bool QWaylandSeat::isInitialized()
const
206 Q_D(
const QWaylandSeat);
207 return d->isInitialized;
211
212
213void QWaylandSeat::sendMousePressEvent(Qt::MouseButton button)
216 d->pointer->sendMousePressEvent(button);
220
221
222void QWaylandSeat::sendMouseReleaseEvent(Qt::MouseButton button)
225 d->pointer->sendMouseReleaseEvent(button);
229
230
231
232void QWaylandSeat::sendMouseMoveEvent(QWaylandView *view,
const QPointF &localPos,
const QPointF &outputSpacePos)
235 d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos);
239
240
241void QWaylandSeat::sendMouseWheelEvent(Qt::Orientation orientation,
int delta)
244 d->pointer->sendMouseWheelEvent(orientation, delta);
248
249
250void QWaylandSeat::sendKeyPressEvent(uint code)
253 d->keyboard->sendKeyPressEvent(code);
257
258
259void QWaylandSeat::sendKeyReleaseEvent(uint code)
262 d->keyboard->sendKeyReleaseEvent(code);
266
267
268
269
270
271
272
273
274
275uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface,
int id,
const QPointF &point, Qt::TouchPointState state)
279 if (d->touch.isNull())
282 return d->touch->sendTouchPointEvent(surface, id, point,state);
286
287
288
289
290
291
292
293
294
295
296
297
298
299
302
303
304
305
306
307
308
309
310
311
312
313
314uint QWaylandSeat::sendTouchPointPressed(QWaylandSurface *surface,
int id,
const QPointF &position)
316 return sendTouchPointEvent(surface, id, position, Qt::TouchPointPressed);
320
321
322
323
324
325
326
327
328
329
330
331
332
333
336
337
338
339
340
341
342
343
344
345
346
347
348uint QWaylandSeat::sendTouchPointReleased(QWaylandSurface *surface,
int id,
const QPointF &position)
350 return sendTouchPointEvent(surface, id, position, Qt::TouchPointReleased);
354
355
356
357
358
359
360
361
362
363
364
365
366
367
370
371
372
373
374
375
376
377
378
379
380
381
382uint QWaylandSeat::sendTouchPointMoved(QWaylandSurface *surface,
int id,
const QPointF &position)
384 return sendTouchPointEvent(surface, id, position, Qt::TouchPointMoved);
388
389
390
391
392
395
396
397
398void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
401 if (!d->touch.isNull())
402 d->touch->sendFrameEvent(client);
406
407
408
409
412
413
414void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
417 if (!d->touch.isNull())
418 d->touch->sendCancelEvent(client);
422
423
424
425
426
427
428
429void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
436 d->touch->sendFullTouchEvent(surface, event);
440
441
442
443
444
445
446
447void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event)
451 if (!keyboardFocus()) {
452 qWarning(
"Cannot send key event, no keyboard focus, fix the compositor");
457 if (keyboardFocus()->inputMethodControl()->enabled()
458 && event->nativeScanCode() == 0) {
459 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) {
460 QWaylandTextInput *textInput = QWaylandTextInput::findIn(
this);
462 textInput->sendKeyEvent(event);
467 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) {
468 QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(
this);
469 if (textInputMethod) {
470 textInputMethod->sendKeyEvent(event);
475 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) {
476 QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(
this);
477 if (textInputV3 && !event->text().isEmpty()) {
479 if (event->type() == QEvent::KeyPress)
480 textInputV3->sendKeyEvent(event);
487 if (!d->keyboard.isNull() && !event->isAutoRepeat()) {
489 uint scanCode = event->nativeScanCode();
491 scanCode = d->keyboard->keyToScanCode(event->key());
494 qWarning() <<
"Can't send Wayland key event: Unable to get a valid scan code";
498 if (event->type() == QEvent::KeyPress) {
499 QWaylandKeyboardPrivate::get(d->keyboard.data())->checkAndRepairModifierState(event);
500 d->keyboard->sendKeyPressEvent(scanCode);
501 }
else if (event->type() == QEvent::KeyRelease) {
502 d->keyboard->sendKeyReleaseEvent(scanCode);
508
509
510
511
512
513
516
517
518
519
520
521
522
523
524void QWaylandSeat::sendKeyEvent(
int qtKey,
bool pressed)
527 if (!keyboardFocus()) {
528 qWarning(
"Cannot send Wayland key event, no keyboard focus, fix the compositor");
532 if (
auto scanCode = d->keyboard->keyToScanCode(qtKey)) {
534 d->keyboard->sendKeyPressEvent(scanCode);
536 d->keyboard->sendKeyReleaseEvent(scanCode);
538 qWarning() <<
"Can't send Wayland key event: Unable to get scan code for" << Qt::Key(qtKey);
543
544
545
546
547
548
549
550
553
554
555
556
557
558
559
560
561
562void QWaylandSeat::sendUnicodeKeyPressEvent(uint unicode)
564 sendUnicodeKeyEvent(unicode, QEvent::KeyPress);
568
569
570
571
572
573
574
575
578
579
580
581
582
583
584
585
586
587void QWaylandSeat::sendUnicodeKeyReleaseEvent(uint unicode)
589 sendUnicodeKeyEvent(unicode, QEvent::KeyRelease);
593
594
595
596
597void QWaylandSeat::sendUnicodeKeyEvent(uint unicode, QEvent::Type eventType)
599 if (!keyboardFocus()) {
600 qWarning(
"Can't send a unicode key event, no keyboard focus, fix the compositor");
605 text += QChar::fromUcs4(
static_cast<
char32_t>(unicode));
607 QKeyEvent event(eventType, Qt::Key_unknown, Qt::KeyboardModifiers{}, text);
608 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) {
609 QWaylandTextInput *textInput = QWaylandTextInput::findIn(
this);
611 textInput->sendKeyEvent(&event);
616 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) {
617 QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(
this);
618 if (textInputMethod) {
619 textInputMethod->sendKeyEvent(&event);
624 if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) {
625 QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(
this);
626 if (textInputV3 && !text.isEmpty()) {
628 if (eventType == QEvent::KeyPress)
629 textInputV3->sendKeyEvent(&event);
636 qWarning() <<
"Can't send a unicode key event: Unable to find a text-input protocol.";
641
642
643QWaylandKeyboard *QWaylandSeat::keyboard()
const
645 Q_D(
const QWaylandSeat);
646 return d->keyboard.data();
650
651
652QWaylandSurface *QWaylandSeat::keyboardFocus()
const
654 Q_D(
const QWaylandSeat);
655 if (d->keyboard.isNull() || !d->keyboard->focus())
658 return d->keyboard->focus();
662
663
664
665
666bool QWaylandSeat::setKeyboardFocus(QWaylandSurface *surface)
669 if (surface && surface->isDestroyed())
672 QWaylandSurface *oldSurface = keyboardFocus();
673 if (surface == oldSurface)
676 d->keyboardFocus = surface;
677 if (!d->keyboard.isNull())
678 d->keyboard->setFocus(surface);
679#if QT_CONFIG(wayland_datadevice)
681 d->data_device->setFocus(surface ? surface->client() :
nullptr);
683 emit keyboardFocusChanged(surface, oldSurface);
689
690
692QWaylandKeymap *QWaylandSeat::keymap()
694 Q_D(
const QWaylandSeat);
695 return d->keymap.data();
699
700
701QWaylandPointer *QWaylandSeat::pointer()
const
703 Q_D(
const QWaylandSeat);
704 return d->pointer.data();
708
709
710QWaylandTouch *QWaylandSeat::touch()
const
712 Q_D(
const QWaylandSeat);
713 return d->touch.data();
717
718
719QWaylandView *QWaylandSeat::mouseFocus()
const
721 Q_D(
const QWaylandSeat);
722 return d->mouseFocus;
726
727
728void QWaylandSeat::setMouseFocus(QWaylandView *view)
731 if (view == d->mouseFocus)
734 QWaylandView *oldFocus = d->mouseFocus;
735 d->mouseFocus = view;
738 disconnect(oldFocus, &QObject::destroyed,
this, &QWaylandSeat::handleMouseFocusDestroyed);
740 connect(d->mouseFocus, &QObject::destroyed,
this, &QWaylandSeat::handleMouseFocusDestroyed);
742 emit mouseFocusChanged(d->mouseFocus, oldFocus);
746
747
748QWaylandCompositor *QWaylandSeat::compositor()
const
750 Q_D(
const QWaylandSeat);
751 return d->compositor;
755
756
757#if QT_CONFIG(draganddrop)
758QWaylandDrag *QWaylandSeat::drag()
const
760 Q_D(
const QWaylandSeat);
761 return d->drag_handle.data();
766
767
768QWaylandSeat::CapabilityFlags QWaylandSeat::capabilities()
const
770 Q_D(
const QWaylandSeat);
771 return d->capabilities;
775
776
777bool QWaylandSeat::isOwner(QInputEvent *inputEvent)
const
779 Q_UNUSED(inputEvent);
784
785
786
787QWaylandSeat *QWaylandSeat::fromSeatResource(
struct ::wl_resource *resource)
789 if (
auto p = QtWayland::fromResource<QWaylandSeatPrivate *>(resource))
795
796
797
798
800void QWaylandSeat::handleMouseFocusDestroyed()
806 d->mouseFocus =
nullptr;
807 QWaylandView *oldFocus =
nullptr;
808 emit mouseFocusChanged(d->mouseFocus, oldFocus);
813
814
815
816
817
818
819
820
823
824
825
826
827
828
829
830
833
834
835
836
837
838
839
840
841
845
846
847
848
849
850
851
852
853
854
857
858
859
860
861
862
865
866
867
868
869
870
871
872
873
874
878#include "moc_qwaylandseat.cpp"