6 #include "seat_interface.h"
7 #include "datadevice_interface.h"
8 #include "datasource_interface.h"
10 #include "keyboard_interface_p.h"
11 #include "pointer_interface_p.h"
12 #include "seat_interface_p.h"
13 #include "surface_interface.h"
14 #include "textinput_interface_p.h"
18 #ifndef WL_SEAT_NAME_SINCE_VERSION
19 #define WL_SEAT_NAME_SINCE_VERSION 2
22 #include <linux/input.h>
30 const quint32 SeatInterface::Private::s_version = 5;
31 const qint32 SeatInterface::Private::s_pointerVersion = 5;
32 const qint32 SeatInterface::Private::s_touchVersion = 5;
33 const qint32 SeatInterface::Private::s_keyboardVersion = 5;
35 SeatInterface::Private::Private(SeatInterface *q, Display *display)
36 : Global::Private(display, &wl_seat_interface, s_version)
42 const struct wl_seat_interface SeatInterface::Private::s_interface = {getPointerCallback, getKeyboardCallback, getTouchCallback, releaseCallback};
45 SeatInterface::SeatInterface(Display *display,
QObject *parent)
46 : Global(new Private(this, display), parent)
49 connect(
this, &SeatInterface::nameChanged,
this, [d] {
50 for (
auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
54 auto sendCapabilitiesAll = [d] {
55 for (
auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
56 d->sendCapabilities(*it);
59 connect(
this, &SeatInterface::hasPointerChanged,
this, sendCapabilitiesAll);
60 connect(
this, &SeatInterface::hasKeyboardChanged,
this, sendCapabilitiesAll);
61 connect(
this, &SeatInterface::hasTouchChanged,
this, sendCapabilitiesAll);
64 SeatInterface::~SeatInterface()
67 while (!d->resources.isEmpty()) {
68 wl_resource_destroy(d->resources.takeLast());
72 void SeatInterface::Private::bind(wl_client *client, uint32_t version, uint32_t
id)
74 wl_resource *r = wl_resource_create(client, &wl_seat_interface, qMin(s_version, version),
id);
76 wl_client_post_no_memory(client);
81 wl_resource_set_implementation(r, &s_interface,
this, unbind);
87 void SeatInterface::Private::unbind(wl_resource *r)
89 cast(r)->resources.removeAll(r);
92 void SeatInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
95 wl_resource_destroy(resource);
98 void SeatInterface::Private::updatePointerButtonSerial(quint32 button, quint32 serial)
100 auto it = globalPointer.buttonSerials.find(button);
101 if (it == globalPointer.buttonSerials.end()) {
102 globalPointer.buttonSerials.insert(button, serial);
108 void SeatInterface::Private::updatePointerButtonState(quint32 button, Pointer::State state)
110 auto it = globalPointer.buttonStates.find(button);
111 if (it == globalPointer.buttonStates.end()) {
112 globalPointer.buttonStates.insert(button, state);
118 bool SeatInterface::Private::updateKey(quint32 key, Keyboard::State state)
120 auto it = keys.states.find(key);
121 if (it == keys.states.end()) {
122 keys.states.insert(key, state);
125 if (it.value() == state) {
132 void SeatInterface::Private::sendName(wl_resource *r)
134 if (wl_resource_get_version(r) < WL_SEAT_NAME_SINCE_VERSION) {
137 wl_seat_send_name(r, name.toUtf8().
constData());
140 void SeatInterface::Private::sendCapabilities(wl_resource *r)
152 wl_seat_send_capabilities(r, capabilities);
155 SeatInterface::Private *SeatInterface::Private::cast(wl_resource *r)
157 return r ?
reinterpret_cast<SeatInterface::Private *
>(wl_resource_get_user_data(r)) :
nullptr;
163 static T *interfaceForSurface(SurfaceInterface *surface,
const QVector<T *> &interfaces)
170 if ((*it)->client() == surface->client()) {
186 if ((*it)->client() == surface->client() && (*it)->resource()) {
194 static bool forEachInterface(SurfaceInterface *surface,
const QVector<T *> &interfaces, std::function<
void(T *)> method)
199 bool calledAtLeastOne =
false;
201 if ((*it)->client() == surface->client() && (*it)->resource()) {
203 calledAtLeastOne =
true;
206 return calledAtLeastOne;
213 return interfacesForSurface(surface, pointers);
218 return interfacesForSurface(surface, keyboards);
223 return interfacesForSurface(surface, touchs);
226 DataDeviceInterface *SeatInterface::Private::dataDeviceForSurface(SurfaceInterface *surface)
const
228 return interfaceForSurface(surface, dataDevices);
231 TextInputInterface *SeatInterface::Private::textInputForSurface(SurfaceInterface *surface)
const
233 return interfaceForSurface(surface, textInputs);
236 void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
238 Q_ASSERT(dataDevice->seat() == q);
239 dataDevices << dataDevice;
240 auto dataDeviceCleanup = [
this, dataDevice] {
241 dataDevices.removeOne(dataDevice);
242 if (keys.focus.selection == dataDevice) {
243 keys.focus.selection =
nullptr;
245 if (currentSelection == dataDevice) {
247 currentSelection =
nullptr;
248 Q_EMIT q->selectionChanged(
nullptr);
249 if (keys.focus.selection) {
250 keys.focus.selection->sendClearSelection();
256 QObject::connect(dataDevice, &DataDeviceInterface::selectionChanged, q, [
this, dataDevice] {
257 updateSelection(dataDevice,
true);
259 QObject::connect(dataDevice, &DataDeviceInterface::selectionCleared, q, [
this, dataDevice] {
260 updateSelection(dataDevice,
false);
262 QObject::connect(dataDevice, &DataDeviceInterface::dragStarted, q, [
this, dataDevice] {
263 const auto dragSerial = dataDevice->dragImplicitGrabSerial();
264 auto *dragSurface = dataDevice->origin();
265 if (q->hasImplicitPointerGrab(dragSerial)) {
266 drag.mode = Drag::Mode::Pointer;
267 drag.sourcePointer = interfaceForSurface(dragSurface, pointers);
268 drag.transformation = globalPointer.focus.transformation;
269 }
else if (q->hasImplicitTouchGrab(dragSerial)) {
270 drag.mode = Drag::Mode::Touch;
271 drag.sourceTouch = interfaceForSurface(dragSurface, touchs);
277 auto *originSurface = dataDevice->origin();
278 const bool proxied = originSurface->dataProxy();
281 drag.target = dataDevice;
282 drag.surface = originSurface;
284 drag.transformation = globalPointer.focus.transformation;
286 drag.source = dataDevice;
287 drag.sourcePointer = interfaceForSurface(originSurface, pointers);
289 endDrag(display->nextSerial());
291 if (dataDevice->dragSource()) {
292 drag.dragSourceDestroyConnection =
QObject::connect(dataDevice->dragSource(), &Resource::aboutToBeUnbound, q, [
this] {
293 const auto serial = display->nextSerial();
295 drag.target->updateDragTarget(nullptr, serial);
296 drag.target = nullptr;
303 dataDevice->updateDragTarget(proxied ?
nullptr : originSurface, dataDevice->dragImplicitGrabSerial());
304 Q_EMIT q->dragStarted();
305 Q_EMIT q->dragSurfaceChanged();
308 if (keys.focus.surface && !keys.focus.selection) {
310 if (keys.focus.surface->client() == dataDevice->client()) {
311 keys.focus.selection = dataDevice;
312 if (currentSelection && currentSelection->selection()) {
313 dataDevice->sendSelection(currentSelection);
319 void SeatInterface::Private::registerTextInput(TextInputInterface *ti)
322 if (textInputs.contains(ti)) {
326 if (textInput.focus.surface && textInput.focus.surface->client() == ti->client()) {
328 if (!textInput.focus.textInput) {
329 textInput.focus.textInput = ti;
330 ti->d_func()->sendEnter(textInput.focus.surface, textInput.focus.serial);
331 Q_EMIT q->focusedTextInputChanged();
335 textInputs.removeAt(textInputs.indexOf(ti));
336 if (textInput.focus.textInput == ti) {
337 textInput.focus.textInput = nullptr;
338 Q_EMIT q->focusedTextInputChanged();
343 void SeatInterface::Private::endDrag(quint32 serial)
345 auto target = drag.target;
348 if (drag.source && drag.source->dragSource()) {
349 drag.source->dragSource()->dropPerformed();
353 target->updateDragTarget(
nullptr, serial);
356 Q_EMIT q->dragSurfaceChanged();
357 Q_EMIT q->dragEnded();
360 void SeatInterface::Private::cancelPreviousSelection(DataDeviceInterface *dataDevice)
362 if (!currentSelection) {
365 if (
auto s = currentSelection->selection()) {
366 if (currentSelection != dataDevice) {
374 void SeatInterface::Private::updateSelection(DataDeviceInterface *dataDevice,
bool set)
376 bool selChanged = currentSelection != dataDevice;
377 if (keys.focus.surface && (keys.focus.surface->client() == dataDevice->client())) {
379 cancelPreviousSelection(dataDevice);
381 currentSelection = dataDevice;
383 if (dataDevice == currentSelection) {
385 if (keys.focus.selection) {
387 keys.focus.selection->sendSelection(dataDevice);
389 keys.focus.selection->sendClearSelection();
390 currentSelection =
nullptr;
396 Q_EMIT q->selectionChanged(currentSelection);
400 void SeatInterface::setHasKeyboard(
bool has)
403 if (d->keyboard == has) {
407 Q_EMIT hasKeyboardChanged(d->keyboard);
410 void SeatInterface::setHasPointer(
bool has)
413 if (d->pointer == has) {
417 Q_EMIT hasPointerChanged(d->pointer);
420 void SeatInterface::setHasTouch(
bool has)
423 if (d->touch == has) {
427 Q_EMIT hasTouchChanged(d->touch);
430 void SeatInterface::setName(
const QString &name)
433 if (d->name == name) {
437 Q_EMIT nameChanged(d->name);
440 void SeatInterface::Private::getPointerCallback(wl_client *client, wl_resource *resource, uint32_t
id)
442 cast(resource)->getPointer(client, resource,
id);
445 void SeatInterface::Private::getPointer(wl_client *client, wl_resource *resource, uint32_t
id)
448 PointerInterface *pointer =
new PointerInterface(q, resource);
449 auto clientConnection = display->getConnection(client);
450 pointer->create(clientConnection, qMin(wl_resource_get_version(resource), s_pointerVersion),
id);
451 if (!pointer->resource()) {
452 wl_resource_post_no_memory(resource);
457 if (globalPointer.focus.surface && globalPointer.focus.surface->client() == clientConnection) {
459 globalPointer.focus.pointers << pointer;
460 pointer->setFocusedSurface(globalPointer.focus.surface, globalPointer.focus.serial);
461 pointer->d_func()->sendFrame();
462 if (globalPointer.focus.pointers.count() == 1) {
464 Q_EMIT q->focusedPointerChanged(pointer);
468 pointers.removeAt(pointers.indexOf(pointer));
469 if (globalPointer.focus.pointers.removeOne(pointer)) {
470 if (globalPointer.focus.pointers.isEmpty()) {
471 Q_EMIT q->focusedPointerChanged(nullptr);
475 Q_EMIT q->pointerCreated(pointer);
478 void SeatInterface::Private::getKeyboardCallback(wl_client *client, wl_resource *resource, uint32_t
id)
480 cast(resource)->getKeyboard(client, resource,
id);
483 void SeatInterface::Private::getKeyboard(wl_client *client, wl_resource *resource, uint32_t
id)
486 KeyboardInterface *keyboard =
new KeyboardInterface(q, resource);
487 auto clientConnection = display->getConnection(client);
488 keyboard->create(clientConnection, qMin(wl_resource_get_version(resource), s_keyboardVersion),
id);
489 if (!keyboard->resource()) {
490 wl_resource_post_no_memory(resource);
494 keyboard->repeatInfo(keys.keyRepeat.charactersPerSecond, keys.keyRepeat.delay);
495 if (keys.keymap.xkbcommonCompatible) {
496 keyboard->setKeymap(keys.keymap.content);
498 keyboards << keyboard;
499 if (keys.focus.surface && keys.focus.surface->client() == clientConnection) {
501 keys.focus.keyboards << keyboard;
502 keyboard->setFocusedSurface(keys.focus.surface, keys.focus.serial);
505 keyboards.removeAt(keyboards.indexOf(keyboard));
506 keys.focus.keyboards.removeOne(keyboard);
508 Q_EMIT q->keyboardCreated(keyboard);
511 void SeatInterface::Private::getTouchCallback(wl_client *client, wl_resource *resource, uint32_t
id)
513 cast(resource)->getTouch(client, resource,
id);
516 void SeatInterface::Private::getTouch(wl_client *client, wl_resource *resource, uint32_t
id)
519 TouchInterface *touch =
new TouchInterface(q, resource);
520 auto clientConnection = display->getConnection(client);
521 touch->create(clientConnection, qMin(wl_resource_get_version(resource), s_touchVersion),
id);
522 if (!touch->resource()) {
523 wl_resource_post_no_memory(resource);
528 if (globalTouch.focus.surface && globalTouch.focus.surface->client() == clientConnection) {
530 globalTouch.focus.touchs << touch;
531 if (!globalTouch.ids.isEmpty()) {
536 touchs.removeAt(touchs.indexOf(touch));
537 globalTouch.focus.touchs.removeOne(touch);
539 Q_EMIT q->touchCreated(touch);
542 QString SeatInterface::name()
const
548 bool SeatInterface::hasPointer()
const
554 bool SeatInterface::hasKeyboard()
const
560 bool SeatInterface::hasTouch()
const
571 SeatInterface::Private *SeatInterface::d_func()
const
573 return reinterpret_cast<Private *
>(d.data());
576 QPointF SeatInterface::pointerPos()
const
579 return d->globalPointer.pos;
582 void SeatInterface::setPointerPos(
const QPointF &pos)
585 if (d->globalPointer.pos == pos) {
588 d->globalPointer.pos = pos;
589 Q_EMIT pointerPosChanged(pos);
592 quint32 SeatInterface::timestamp()
const
598 void SeatInterface::setTimestamp(quint32 time)
601 if (d->timestamp == time) {
605 Q_EMIT timestampChanged(time);
611 if (surface == d->drag.surface) {
615 const quint32 serial = d->display->nextSerial();
616 if (d->drag.target) {
617 d->drag.target->updateDragTarget(
nullptr, serial);
619 d->drag.target = d->dataDeviceForSurface(surface);
620 if (d->drag.mode == Private::Drag::Mode::Pointer) {
621 setPointerPos(globalPosition);
622 }
else if (d->drag.mode == Private::Drag::Mode::Touch && d->globalTouch.focus.firstTouchPos != globalPosition) {
623 touchMove(d->globalTouch.ids.first(), globalPosition);
625 if (d->drag.target) {
626 d->drag.surface = surface;
627 d->drag.transformation = inputTransformation;
628 d->drag.target->updateDragTarget(surface, serial);
630 d->drag.surface =
nullptr;
632 Q_EMIT dragSurfaceChanged();
639 if (d->drag.mode == Private::Drag::Mode::Pointer) {
640 setDragTarget(surface, pointerPos(), inputTransformation);
642 Q_ASSERT(d->drag.mode == Private::Drag::Mode::Touch);
643 setDragTarget(surface, d->globalTouch.focus.firstTouchPos, inputTransformation);
650 return d->globalPointer.focus.surface;
656 m.
translate(-surfacePosition.
x(), -surfacePosition.
y());
657 setFocusedPointerSurface(surface, m);
659 if (d->globalPointer.focus.surface) {
660 d->globalPointer.focus.offset = surfacePosition;
667 if (d->drag.mode == Private::Drag::Mode::Pointer) {
671 const quint32 serial = d->display->nextSerial();
673 for (
auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
674 (*it)->setFocusedSurface(
nullptr, serial);
675 framePointers << *it;
677 if (d->globalPointer.focus.surface) {
678 disconnect(d->globalPointer.focus.destroyConnection);
680 d->globalPointer.focus = Private::Pointer::Focus();
681 d->globalPointer.focus.surface = surface;
682 auto p = d->pointersForSurface(surface);
683 d->globalPointer.focus.pointers = p;
684 if (d->globalPointer.focus.surface) {
685 d->globalPointer.focus.destroyConnection = connect(surface, &
QObject::destroyed,
this, [
this] {
687 d->globalPointer.focus = Private::Pointer::Focus();
688 Q_EMIT focusedPointerChanged(
nullptr);
690 d->globalPointer.focus.offset =
QPointF();
691 d->globalPointer.focus.transformation = transformation;
692 d->globalPointer.focus.serial = serial;
695 Q_EMIT focusedPointerChanged(
nullptr);
696 for (
auto p : std::as_const(framePointers)) {
697 p->d_func()->sendFrame();
702 Q_EMIT focusedPointerChanged(p.first());
703 for (
auto it = p.constBegin(), end = p.constEnd(); it != end; ++it) {
704 (*it)->setFocusedSurface(surface, serial);
705 framePointers << *it;
707 for (
auto p : std::as_const(framePointers)) {
708 p->d_func()->sendFrame();
715 if (d->globalPointer.focus.pointers.isEmpty()) {
718 return d->globalPointer.focus.pointers.first();
721 void SeatInterface::setFocusedPointerSurfacePosition(
const QPointF &surfacePosition)
724 if (d->globalPointer.focus.surface) {
725 d->globalPointer.focus.offset = surfacePosition;
726 d->globalPointer.focus.transformation =
QMatrix4x4();
727 d->globalPointer.focus.transformation.translate(-surfacePosition.
x(), -surfacePosition.
y());
731 QPointF SeatInterface::focusedPointerSurfacePosition()
const
734 return d->globalPointer.focus.offset;
737 void SeatInterface::setFocusedPointerSurfaceTransformation(
const QMatrix4x4 &transformation)
740 if (d->globalPointer.focus.surface) {
741 d->globalPointer.focus.transformation = transformation;
745 QMatrix4x4 SeatInterface::focusedPointerSurfaceTransformation()
const
748 return d->globalPointer.focus.transformation;
774 return s_buttons.
value(button, 0);
780 return isPointerButtonPressed(qtToWaylandButton(button));
783 bool SeatInterface::isPointerButtonPressed(quint32 button)
const
786 auto it = d->globalPointer.buttonStates.constFind(button);
787 if (it == d->globalPointer.buttonStates.constEnd()) {
790 return it.value() == Private::Pointer::State::Pressed ? true :
false;
796 if (d->drag.mode == Private::Drag::Mode::Pointer) {
800 if (d->globalPointer.focus.surface) {
801 for (
auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
802 (*it)->axis(orientation, delta, discreteDelta, source);
810 if (d->drag.mode == Private::Drag::Mode::Pointer) {
814 if (d->globalPointer.focus.surface) {
815 for (
auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
816 (*it)->axis(orientation, delta);
823 const quint32 nativeButton = qtToWaylandButton(button);
824 if (nativeButton == 0) {
827 pointerButtonPressed(nativeButton);
830 void SeatInterface::pointerButtonPressed(quint32 button)
833 const quint32 serial = d->display->nextSerial();
834 d->updatePointerButtonSerial(button, serial);
835 d->updatePointerButtonState(button, Private::Pointer::State::Pressed);
836 if (d->drag.mode == Private::Drag::Mode::Pointer) {
840 if (
auto *focusSurface = d->globalPointer.focus.surface) {
841 for (
auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
842 (*it)->buttonPressed(button, serial);
844 if (focusSurface == d->keys.focus.surface) {
846 auto p = focusedPointer();
848 for (
auto it = d->keys.focus.keyboards.constBegin(), end = d->keys.focus.keyboards.constEnd(); it != end; ++it) {
849 (*it)->d_func()->focusChildSurface(p->d_func()->focusedChildSurface, serial);
858 const quint32 nativeButton = qtToWaylandButton(button);
859 if (nativeButton == 0) {
862 pointerButtonReleased(nativeButton);
865 void SeatInterface::pointerButtonReleased(quint32 button)
868 const quint32 serial = d->display->nextSerial();
869 const quint32 currentButtonSerial = pointerButtonSerial(button);
870 d->updatePointerButtonSerial(button, serial);
871 d->updatePointerButtonState(button, Private::Pointer::State::Released);
872 if (d->drag.mode == Private::Drag::Mode::Pointer) {
873 if (d->drag.source->dragImplicitGrabSerial() != currentButtonSerial) {
880 if (d->globalPointer.focus.surface) {
881 for (
auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
882 (*it)->buttonReleased(button, serial);
889 return pointerButtonSerial(qtToWaylandButton(button));
892 quint32 SeatInterface::pointerButtonSerial(quint32 button)
const
895 auto it = d->globalPointer.buttonSerials.constFind(button);
896 if (it == d->globalPointer.buttonSerials.constEnd()) {
902 void SeatInterface::relativePointerMotion(
const QSizeF &delta,
const QSizeF &deltaNonAccelerated, quint64 microseconds)
905 if (d->globalPointer.focus.surface) {
906 for (
auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) {
907 (*it)->relativeMotion(delta, deltaNonAccelerated, microseconds);
912 void SeatInterface::startPointerSwipeGesture(quint32 fingerCount)
915 if (!d->globalPointer.gestureSurface.isNull()) {
919 if (d->globalPointer.gestureSurface.isNull()) {
922 const quint32 serial = d->display->nextSerial();
923 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [serial, fingerCount](
PointerInterface *p) {
924 p->d_func()->startSwipeGesture(serial, fingerCount);
928 void SeatInterface::updatePointerSwipeGesture(
const QSizeF &delta)
931 if (d->globalPointer.gestureSurface.isNull()) {
934 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [delta](
PointerInterface *p) {
935 p->d_func()->updateSwipeGesture(delta);
939 void SeatInterface::endPointerSwipeGesture()
942 if (d->globalPointer.gestureSurface.isNull()) {
945 const quint32 serial = d->display->nextSerial();
946 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [serial](
PointerInterface *p) {
947 p->d_func()->endSwipeGesture(serial);
949 d->globalPointer.gestureSurface.clear();
952 void SeatInterface::cancelPointerSwipeGesture()
955 if (d->globalPointer.gestureSurface.isNull()) {
958 const quint32 serial = d->display->nextSerial();
959 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [serial](
PointerInterface *p) {
960 p->d_func()->cancelSwipeGesture(serial);
962 d->globalPointer.gestureSurface.clear();
965 void SeatInterface::startPointerPinchGesture(quint32 fingerCount)
968 if (!d->globalPointer.gestureSurface.isNull()) {
972 if (d->globalPointer.gestureSurface.isNull()) {
975 const quint32 serial = d->display->nextSerial();
976 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [serial, fingerCount](
PointerInterface *p) {
977 p->d_func()->startPinchGesture(serial, fingerCount);
981 void SeatInterface::updatePointerPinchGesture(
const QSizeF &delta, qreal scale, qreal rotation)
984 if (d->globalPointer.gestureSurface.isNull()) {
987 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [delta, scale, rotation](
PointerInterface *p) {
988 p->d_func()->updatePinchGesture(delta, scale, rotation);
992 void SeatInterface::endPointerPinchGesture()
995 if (d->globalPointer.gestureSurface.isNull()) {
998 const quint32 serial = d->display->nextSerial();
999 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [serial](
PointerInterface *p) {
1000 p->d_func()->endPinchGesture(serial);
1002 d->globalPointer.gestureSurface.clear();
1005 void SeatInterface::cancelPointerPinchGesture()
1008 if (d->globalPointer.gestureSurface.isNull()) {
1011 const quint32 serial = d->display->nextSerial();
1012 forEachInterface<PointerInterface>(d->globalPointer.gestureSurface.data(), d->pointers, [serial](
PointerInterface *p) {
1013 p->d_func()->cancelPinchGesture(serial);
1015 d->globalPointer.gestureSurface.clear();
1018 void SeatInterface::keyPressed(quint32 key)
1021 d->keys.lastStateSerial = d->display->nextSerial();
1022 if (!d->updateKey(key, Private::Keyboard::State::Pressed)) {
1025 if (d->keys.focus.surface) {
1026 for (
auto it = d->keys.focus.keyboards.constBegin(), end = d->keys.focus.keyboards.constEnd(); it != end; ++it) {
1027 (*it)->keyPressed(key, d->keys.lastStateSerial);
1032 void SeatInterface::keyReleased(quint32 key)
1035 d->keys.lastStateSerial = d->display->nextSerial();
1036 if (!d->updateKey(key, Private::Keyboard::State::Released)) {
1039 if (d->keys.focus.surface) {
1040 for (
auto it = d->keys.focus.keyboards.constBegin(), end = d->keys.focus.keyboards.constEnd(); it != end; ++it) {
1041 (*it)->keyReleased(key, d->keys.lastStateSerial);
1046 SurfaceInterface *SeatInterface::focusedKeyboardSurface()
const
1049 return d->keys.focus.surface;
1055 const quint32 serial = d->display->nextSerial();
1056 for (
auto it = d->keys.focus.keyboards.constBegin(), end = d->keys.focus.keyboards.constEnd(); it != end; ++it) {
1057 (*it)->setFocusedSurface(
nullptr, serial);
1059 if (d->keys.focus.surface) {
1060 disconnect(d->keys.focus.destroyConnection);
1062 d->keys.focus = Private::Keyboard::Focus();
1063 d->keys.focus.surface = surface;
1064 d->keys.focus.keyboards = d->keyboardsForSurface(surface);
1065 if (d->keys.focus.surface) {
1066 d->keys.focus.destroyConnection = connect(surface, &
QObject::destroyed,
this, [
this] {
1068 d->keys.focus = Private::Keyboard::Focus();
1070 d->keys.focus.serial = serial;
1072 d->keys.focus.selection = d->dataDeviceForSurface(surface);
1073 if (d->keys.focus.selection) {
1074 if (d->currentSelection && d->currentSelection->selection()) {
1075 d->keys.focus.selection->sendSelection(d->currentSelection);
1077 d->keys.focus.selection->sendClearSelection();
1081 for (
auto it = d->keys.focus.keyboards.constBegin(), end = d->keys.focus.keyboards.constEnd(); it != end; ++it) {
1082 (*it)->setFocusedSurface(surface, serial);
1085 if (hasKeyboard()) {
1086 setFocusedTextInputSurface(surface);
1090 #if KWAYLANDSERVER_BUILD_DEPRECATED_SINCE(5, 69)
1091 void SeatInterface::setKeymap(
int fd, quint32 size)
1097 const char *address =
reinterpret_cast<char *
>(file.
map(0, size));
1108 d->keys.keymap.xkbcommonCompatible =
true;
1109 d->keys.keymap.content = content;
1110 for (
auto it = d->keyboards.constBegin(); it != d->keyboards.constEnd(); ++it) {
1111 (*it)->setKeymap(content);
1115 void SeatInterface::updateKeyboardModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group)
1118 bool changed =
false;
1119 #define UPDATE(value) \
1120 if (d->keys.modifiers.value != value) { \
1121 d->keys.modifiers.value = value; \
1131 const quint32 serial = d->display->nextSerial();
1132 d->keys.modifiers.serial = serial;
1133 if (d->keys.focus.surface) {
1134 for (
auto it = d->keys.focus.keyboards.constBegin(), end = d->keys.focus.keyboards.constEnd(); it != end; ++it) {
1135 (*it)->updateModifiers(depressed, latched, locked, group, serial);
1140 void SeatInterface::setKeyRepeatInfo(qint32 charactersPerSecond, qint32 delay)
1143 d->keys.keyRepeat.charactersPerSecond = qMax(charactersPerSecond, 0);
1144 d->keys.keyRepeat.delay = qMax(delay, 0);
1145 for (
auto it = d->keyboards.constBegin(); it != d->keyboards.constEnd(); ++it) {
1146 (*it)->repeatInfo(d->keys.keyRepeat.charactersPerSecond, d->keys.keyRepeat.delay);
1150 qint32 SeatInterface::keyRepeatDelay()
const
1153 return d->keys.keyRepeat.delay;
1156 qint32 SeatInterface::keyRepeatRate()
const
1159 return d->keys.keyRepeat.charactersPerSecond;
1162 bool SeatInterface::isKeymapXkbCompatible()
const
1165 return d->keys.keymap.xkbcommonCompatible;
1168 #if KWAYLANDSERVER_BUILD_DEPRECATED_SINCE(5, 69)
1169 int SeatInterface::keymapFileDescriptor()
const
1175 #if KWAYLANDSERVER_BUILD_DEPRECATED_SINCE(5, 69)
1176 quint32 SeatInterface::keymapSize()
const
1182 quint32 SeatInterface::depressedModifiers()
const
1185 return d->keys.modifiers.depressed;
1188 quint32 SeatInterface::groupModifiers()
const
1191 return d->keys.modifiers.group;
1194 quint32 SeatInterface::latchedModifiers()
const
1197 return d->keys.modifiers.latched;
1200 quint32 SeatInterface::lockedModifiers()
const
1203 return d->keys.modifiers.locked;
1206 quint32 SeatInterface::lastModifiersSerial()
const
1209 return d->keys.modifiers.serial;
1216 for (
auto it = d->keys.states.constBegin(); it != d->keys.states.constEnd(); ++it) {
1217 if (it.value() == Private::Keyboard::State::Pressed) {
1224 KeyboardInterface *SeatInterface::focusedKeyboard()
const
1227 if (d->keys.focus.keyboards.isEmpty()) {
1230 return d->keys.focus.keyboards.first();
1233 void SeatInterface::cancelTouchSequence()
1236 for (
auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) {
1239 if (d->drag.mode == Private::Drag::Mode::Touch) {
1241 if (d->drag.target) {
1243 d->drag.target->updateDragTarget(
nullptr, 0);
1244 d->drag.target =
nullptr;
1249 d->globalTouch.ids.clear();
1252 TouchInterface *SeatInterface::focusedTouch()
const
1255 if (d->globalTouch.focus.touchs.isEmpty()) {
1258 return d->globalTouch.focus.touchs.first();
1261 SurfaceInterface *SeatInterface::focusedTouchSurface()
const
1264 return d->globalTouch.focus.surface;
1267 QPointF SeatInterface::focusedTouchSurfacePosition()
const
1270 return d->globalTouch.focus.offset;
1273 bool SeatInterface::isTouchSequence()
const
1276 return !d->globalTouch.ids.isEmpty();
1279 void SeatInterface::setFocusedTouchSurface(SurfaceInterface *surface,
const QPointF &surfacePosition)
1281 if (isTouchSequence()) {
1285 Q_ASSERT(!isDragTouch());
1287 if (d->globalTouch.focus.surface) {
1288 disconnect(d->globalTouch.focus.destroyConnection);
1290 d->globalTouch.focus = Private::Touch::Focus();
1291 d->globalTouch.focus.surface = surface;
1292 d->globalTouch.focus.offset = surfacePosition;
1293 d->globalTouch.focus.touchs = d->touchsForSurface(surface);
1294 if (d->globalTouch.focus.surface) {
1295 d->globalTouch.focus.destroyConnection = connect(surface, &
QObject::destroyed,
this, [
this] {
1297 if (isTouchSequence()) {
1299 for (
auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) {
1303 d->globalTouch.focus = Private::Touch::Focus();
1308 void SeatInterface::setFocusedTouchSurfacePosition(
const QPointF &surfacePosition)
1311 d->globalTouch.focus.offset = surfacePosition;
1314 qint32 SeatInterface::touchDown(
const QPointF &globalPosition)
1317 const qint32
id = d->globalTouch.ids.isEmpty() ? 0 : d->globalTouch.ids.lastKey() + 1;
1318 const qint32 serial = display()->nextSerial();
1319 const auto pos = globalPosition - d->globalTouch.focus.offset;
1320 for (
auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) {
1321 (*it)->down(
id, serial, pos);
1325 d->globalTouch.focus.firstTouchPos = globalPosition;
1328 if (
id == 0 && d->globalTouch.focus.touchs.isEmpty()) {
1331 forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, [
this, pos, serial](PointerInterface *p) {
1332 wl_pointer_send_enter(p->resource(), serial, focusedTouchSurface()->resource(), wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
1333 wl_pointer_send_motion(p->resource(), timestamp(), wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
1335 wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
1336 p->d_func()->sendFrame();
1340 d->globalTouch.ids[id] = serial;
1344 void SeatInterface::touchMove(qint32
id,
const QPointF &globalPosition)
1347 Q_ASSERT(d->globalTouch.ids.contains(
id));
1348 const auto pos = globalPosition - d->globalTouch.focus.offset;
1349 for (
auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) {
1350 (*it)->move(
id, pos);
1354 d->globalTouch.focus.firstTouchPos = globalPosition;
1357 if (
id == 0 && d->globalTouch.focus.touchs.isEmpty()) {
1359 forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, [
this, pos](PointerInterface *p) {
1360 wl_pointer_send_motion(p->resource(), timestamp(), wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
1363 Q_EMIT touchMoved(
id, d->globalTouch.ids[
id], globalPosition);
1366 void SeatInterface::touchUp(qint32
id)
1369 Q_ASSERT(d->globalTouch.ids.contains(
id));
1370 const qint32 serial = display()->nextSerial();
1371 if (d->drag.mode == Private::Drag::Mode::Touch && d->drag.source->dragImplicitGrabSerial() == d->globalTouch.ids.value(
id)) {
1375 for (
auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) {
1376 (*it)->up(
id, serial);
1379 if (
id == 0 && d->globalTouch.focus.touchs.isEmpty()) {
1381 const quint32 serial = display()->nextSerial();
1382 forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, [
this, serial](PointerInterface *p) {
1383 wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
1387 d->globalTouch.ids.remove(
id);
1390 void SeatInterface::touchFrame()
1393 for (
auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) {
1398 bool SeatInterface::hasImplicitTouchGrab(quint32 serial)
const
1401 if (!d->globalTouch.focus.surface) {
1405 return d->globalTouch.ids.key(serial, -1) != -1;
1408 bool SeatInterface::isDrag()
const
1411 return d->drag.mode != Private::Drag::Mode::None;
1414 bool SeatInterface::isDragPointer()
const
1417 return d->drag.mode == Private::Drag::Mode::Pointer;
1420 bool SeatInterface::isDragTouch()
const
1423 return d->drag.mode == Private::Drag::Mode::Touch;
1426 bool SeatInterface::hasImplicitPointerGrab(quint32 serial)
const
1429 const auto &serials = d->globalPointer.buttonSerials;
1430 for (
auto it = serials.constBegin(), end = serials.constEnd(); it != end; it++) {
1431 if (it.value() == serial) {
1432 return isPointerButtonPressed(it.key());
1441 return d->drag.transformation;
1447 return d->drag.surface;
1453 if (d->drag.mode != Private::Drag::Mode::Pointer) {
1457 return d->drag.sourcePointer;
1463 return d->drag.source;
1469 const quint32 serial = d->display->nextSerial();
1470 const auto old = d->textInput.focus.textInput;
1471 if (d->textInput.focus.textInput) {
1473 d->textInput.focus.textInput->d_func()->sendLeave(serial, d->textInput.focus.surface);
1475 if (d->textInput.focus.surface) {
1476 disconnect(d->textInput.focus.destroyConnection);
1478 d->textInput.focus = Private::TextInput::Focus();
1479 d->textInput.focus.surface = surface;
1484 d->textInput.focus.textInput = t;
1485 if (d->textInput.focus.surface) {
1486 d->textInput.focus.destroyConnection = connect(surface, &Resource::aboutToBeUnbound,
this, [
this] {
1487 setFocusedTextInputSurface(
nullptr);
1489 d->textInput.focus.serial = serial;
1493 t->d_func()->sendEnter(surface, serial);
1496 Q_EMIT focusedTextInputChanged();
1503 return d->textInput.focus.surface;
1509 return d->textInput.focus.textInput;
1515 return d->currentSelection;
1521 if (d->currentSelection == dataDevice) {
1525 d->cancelPreviousSelection(dataDevice);
1526 d->currentSelection = dataDevice;
1527 if (d->keys.focus.selection) {
1528 if (dataDevice && dataDevice->selection()) {
1529 d->keys.focus.selection->sendSelection(dataDevice);
1531 d->keys.focus.selection->sendClearSelection();
1534 Q_EMIT selectionChanged(dataDevice);