Port SeatInterface to the new approach

This rewrites the wl_seat protocol implementation to adhere to the new
design principles.

Effectively, we've been supporting wl_seat v7 so the version was also
bumped from 5 to 7.
This commit is contained in:
Vlad Zahorodnii 2021-02-13 17:40:56 +02:00
parent 09126dab41
commit 1d7bc7128d
25 changed files with 161 additions and 328 deletions

View file

@ -110,8 +110,6 @@ void TestDataDevice::init()
m_seatInterface = new SeatInterface(m_display, m_display);
m_seatInterface->setHasPointer(true);
m_seatInterface->create();
QVERIFY(m_seatInterface->isValid());
QVERIFY(seatSpy.wait());
m_seat = registry.createSeat(seatSpy.first().first().value<quint32>(),

View file

@ -81,8 +81,6 @@ void TestDragAndDrop::init()
m_seatInterface = new SeatInterface(m_display, m_display);
m_seatInterface->setHasPointer(true);
m_seatInterface->setHasTouch(true);
m_seatInterface->create();
QVERIFY(m_seatInterface->isValid());
m_dataDeviceManagerInterface = new DataDeviceManagerInterface(m_display, m_display);
m_display->createShm();

View file

@ -55,7 +55,6 @@ void IdleTest::init()
m_display->createShm();
m_seatInterface = new SeatInterface(m_display);
m_seatInterface->setName(QStringLiteral("seat0"));
m_seatInterface->create();
m_idleInterface = new IdleInterface(m_display);
// setup connection

View file

@ -69,7 +69,6 @@ void TestPointerConstraints::init()
m_display->createShm();
m_seatInterface = new SeatInterface(m_display, m_display);
m_seatInterface->setHasPointer(true);
m_seatInterface->create();
m_compositorInterface = new CompositorInterface(m_display, m_display);
m_pointerConstraintsInterface = new PointerConstraintsV1Interface(m_display, m_display);

View file

@ -70,7 +70,6 @@ void SelectionTest::init()
m_compositorInterface = new CompositorInterface(m_display, m_display);
m_seatInterface = new SeatInterface(m_display, m_display);
m_seatInterface->setHasKeyboard(true);
m_seatInterface->create();
m_ddmInterface = new DataDeviceManagerInterface(m_display, m_display);
// setup connection

View file

@ -78,7 +78,6 @@ void TextInputTest::init()
m_seatInterface = new SeatInterface(m_display, m_display);
m_seatInterface->setHasKeyboard(true);
m_seatInterface->setHasTouch(true);
m_seatInterface->create();
m_compositorInterface = new CompositorInterface(m_display, m_display);
m_textInputManagerV2Interface = new TextInputManagerV2Interface(m_display, m_display);

View file

@ -162,8 +162,6 @@ void TestWaylandSeat::init()
m_seatInterface = new SeatInterface(m_display);
QVERIFY(m_seatInterface);
m_seatInterface->setName(QStringLiteral("seat0"));
m_seatInterface->create();
QVERIFY(m_seatInterface->isValid());
QVERIFY(seatSpy.wait());
m_compositor = new KWayland::Client::Compositor(this);

View file

@ -103,7 +103,6 @@ void XdgShellTest::init()
m_seatInterface->setHasKeyboard(true);
m_seatInterface->setHasPointer(true);
m_seatInterface->setHasTouch(true);
m_seatInterface->create();
m_compositorInterface = new CompositorInterface(m_display, m_display);
m_xdgShellInterface = new XdgShellInterface(m_display, m_display);

View file

@ -150,7 +150,6 @@ void DataControlInterfaceTest::init()
QVERIFY(m_display->isRunning());
m_seat = new SeatInterface(m_display, this);
m_seat->create();
m_serverCompositor = new CompositorInterface(m_display, this);
m_dataControlDeviceManagerInterface = new DataControlDeviceManagerV1Interface(m_display, this);

View file

@ -177,7 +177,6 @@ void TestInputMethodInterface::initTestCase()
QVERIFY(m_display.isRunning());
m_seat = new SeatInterface(&m_display, this);
m_seat->create();
m_serverCompositor = new CompositorInterface(&m_display, this);
m_inputMethodIface = new InputMethodV1Interface(&m_display, this);
m_inputPanelIface = new InputPanelV1Interface(&m_display, this);

View file

@ -100,7 +100,6 @@ void TestKeyboardShortcutsInhibitorInterface::initTestCase()
QVERIFY(m_display.isRunning());
m_seat = new SeatInterface(&m_display, this);
m_seat->create();
m_serverCompositor = new CompositorInterface(&m_display, this);
m_manager = new KeyboardShortcutsInhibitManagerV1Interface(&m_display, this);

View file

@ -7,6 +7,7 @@
#include <QtTest>
// WaylandServer
#include "../../src/server/display.h"
#include "../../src/server/keyboard_interface.h"
#include "../../src/server/pointer_interface.h"
#include "../../src/server/seat_interface.h"

View file

@ -176,7 +176,6 @@ void TestTabletInterface::initTestCase()
QVERIFY(m_display.isRunning());
m_seat = new SeatInterface(&m_display, this);
m_seat->create();
m_serverCompositor = new CompositorInterface(&m_display, this);
m_tabletManager = new TabletManagerV2Interface(&m_display, this);

View file

@ -121,7 +121,6 @@ void TestTextInputV3Interface::initTestCase()
m_seat = new SeatInterface(&m_display, this);
m_seat->setHasKeyboard(true);
m_seat->create();
m_serverCompositor = new CompositorInterface(&m_display, this);
new TextInputManagerV3Interface(&m_display);

View file

@ -96,7 +96,8 @@ DataControlDeviceV1Interface::DataControlDeviceV1Interface(SeatInterface *seat,
: QObject()
, d(new DataControlDeviceV1InterfacePrivate(this, seat, resource))
{
seat->d_func()->registerDataControlDevice(this);
SeatInterfacePrivate *seatPrivate = SeatInterfacePrivate::get(seat);
seatPrivate->registerDataControlDevice(this);
}
DataControlDeviceV1Interface::~DataControlDeviceV1Interface() = default;

View file

@ -183,7 +183,8 @@ DataDeviceInterface::DataDeviceInterface(SeatInterface *seat, wl_resource *resou
: QObject(nullptr)
, d(new DataDeviceInterfacePrivate(seat, this, resource))
{
seat->d_func()->registerDataDevice(this);
SeatInterfacePrivate *seatPrivate = SeatInterfacePrivate::get(seat);
seatPrivate->registerDataDevice(this);
}
DataDeviceInterface::~DataDeviceInterface() = default;

View file

@ -212,7 +212,7 @@ void KeyboardInterface::keyPressed(quint32 key)
}
const QList<KeyboardInterfacePrivate::Resource *> keyboards = d->keyboardsForClient(d->focusedSurface->client());
const quint32 serial = d->seat->d_func()->nextSerial();
const quint32 serial = d->seat->display()->nextSerial();
for (KeyboardInterfacePrivate::Resource *keyboardResource : keyboards) {
d->send_key(keyboardResource->handle, serial, d->seat->timestamp(), key, KeyboardInterfacePrivate::key_state::key_state_pressed);
}
@ -229,7 +229,7 @@ void KeyboardInterface::keyReleased(quint32 key)
}
const QList<KeyboardInterfacePrivate::Resource *> keyboards = d->keyboardsForClient(d->focusedSurface->client());
const quint32 serial = d->seat->d_func()->nextSerial();
const quint32 serial = d->seat->display()->nextSerial();
for (KeyboardInterfacePrivate::Resource *keyboardResource : keyboards) {
d->send_key(keyboardResource->handle, serial, d->seat->timestamp(), key, KeyboardInterfacePrivate::key_state::key_state_released);
}
@ -255,7 +255,7 @@ void KeyboardInterface::updateModifiers(quint32 depressed, quint32 latched, quin
return;
}
d->modifiers.serial = d->seat->d_func()->nextSerial();
d->modifiers.serial = d->seat->display()->nextSerial();
d->sendModifiers(depressed, latched, locked, group, d->modifiers.serial);
}

View file

@ -102,7 +102,8 @@ PrimarySelectionDeviceV1Interface::PrimarySelectionDeviceV1Interface(SeatInterfa
: QObject()
, d(new PrimarySelectionDeviceV1InterfacePrivate(this, seat, resource))
{
seat->d_func()->registerPrimarySelectionDevice(this);
SeatInterfacePrivate *seatPrivate = SeatInterfacePrivate::get(seat);
seatPrivate->registerPrimarySelectionDevice(this);
}
PrimarySelectionDeviceV1Interface::~PrimarySelectionDeviceV1Interface() = default;

View file

@ -1,6 +1,7 @@
/*
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
@ -28,12 +29,7 @@
#include "textinput_v2_interface_p.h"
#include "textinput_v3_interface_p.h"
#include "touch_interface_p.h"
// Qt
#include <QFile>
// Wayland
#ifndef WL_SEAT_NAME_SINCE_VERSION
#define WL_SEAT_NAME_SINCE_VERSION 2
#endif
#include "utils.h"
// linux
#include <config-kwaylandserver.h>
#if HAVE_LINUX_INPUT_H
@ -45,93 +41,77 @@
namespace KWaylandServer
{
const quint32 SeatInterface::Private::s_version = 5;
const qint32 SeatInterface::Private::s_pointerVersion = 5;
const qint32 SeatInterface::Private::s_touchVersion = 5;
const qint32 SeatInterface::Private::s_keyboardVersion = 5;
static const int s_version = 7;
SeatInterface::Private::Private(SeatInterface *q, Display *display)
: Global::Private(display, &wl_seat_interface, s_version)
SeatInterfacePrivate *SeatInterfacePrivate::get(SeatInterface *seat)
{
return seat->d.data();
}
SeatInterfacePrivate::SeatInterfacePrivate(SeatInterface *q, Display *display)
: QtWaylandServer::wl_seat(*display, s_version)
, q(q)
, display(display)
{
textInputV2 = new TextInputV2Interface(q);
textInputV3 = new TextInputV3Interface(q);
}
#ifndef K_DOXYGEN
const struct wl_seat_interface SeatInterface::Private::s_interface = {
getPointerCallback,
getKeyboardCallback,
getTouchCallback,
releaseCallback
};
#endif
void SeatInterfacePrivate::seat_bind_resource(Resource *resource)
{
send_capabilities(resource->handle, capabilities);
if (resource->version() >= WL_SEAT_NAME_SINCE_VERSION) {
send_name(resource->handle, name);
}
}
void SeatInterfacePrivate::seat_get_pointer(Resource *resource, uint32_t id)
{
if (pointer) {
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer.data());
pointerPrivate->add(resource->client(), id, resource->version());
}
}
void SeatInterfacePrivate::seat_get_keyboard(Resource *resource, uint32_t id)
{
if (keyboard) {
KeyboardInterfacePrivate *keyboardPrivate = KeyboardInterfacePrivate::get(keyboard.data());
keyboardPrivate->add(resource->client(), id, resource->version());
}
}
void SeatInterfacePrivate::seat_get_touch(Resource *resource, uint32_t id)
{
if (touch) {
TouchInterfacePrivate *touchPrivate = TouchInterfacePrivate::get(touch.data());
touchPrivate->add(resource->client(), id, resource->version());
}
}
void SeatInterfacePrivate::seat_release(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
SeatInterface::SeatInterface(Display *display, QObject *parent)
: Global(new Private(this, display), parent)
: QObject(parent)
, d(new SeatInterfacePrivate(this, display))
{
Q_D();
connect(this, &SeatInterface::nameChanged, this,
[d] {
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
d->sendName(*it);
}
}
);
auto sendCapabilitiesAll = [d] {
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
d->sendCapabilities(*it);
}
};
connect(this, &SeatInterface::hasPointerChanged, this, sendCapabilitiesAll);
connect(this, &SeatInterface::hasKeyboardChanged, this, sendCapabilitiesAll);
connect(this, &SeatInterface::hasTouchChanged, this, sendCapabilitiesAll);
DisplayPrivate *displayPrivate = DisplayPrivate::get(d->display);
displayPrivate->seats.append(this);
}
SeatInterface::~SeatInterface()
{
Q_D();
if (d->display) {
DisplayPrivate *displayPrivate = DisplayPrivate::get(d->display);
displayPrivate->seats.removeOne(this);
}
while (!d->resources.isEmpty()) {
wl_resource_destroy(d->resources.takeLast());
}
}
void SeatInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
{
wl_resource *r = wl_resource_create(client, &wl_seat_interface, qMin(s_version, version), id);
if (!r) {
wl_client_post_no_memory(client);
return;
}
resources << r;
wl_resource_set_implementation(r, &s_interface, this, unbind);
sendCapabilities(r);
sendName(r);
}
void SeatInterface::Private::unbind(wl_resource *r)
{
cast(r)->resources.removeAll(r);
}
void SeatInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void SeatInterface::Private::updatePointerButtonSerial(quint32 button, quint32 serial)
void SeatInterfacePrivate::updatePointerButtonSerial(quint32 button, quint32 serial)
{
auto it = globalPointer.buttonSerials.find(button);
if (it == globalPointer.buttonSerials.end()) {
@ -141,7 +121,7 @@ void SeatInterface::Private::updatePointerButtonSerial(quint32 button, quint32 s
it.value() = serial;
}
void SeatInterface::Private::updatePointerButtonState(quint32 button, Pointer::State state)
void SeatInterfacePrivate::updatePointerButtonState(quint32 button, Pointer::State state)
{
auto it = globalPointer.buttonStates.find(button);
if (it == globalPointer.buttonStates.end()) {
@ -151,40 +131,7 @@ void SeatInterface::Private::updatePointerButtonState(quint32 button, Pointer::S
it.value() = state;
}
void SeatInterface::Private::sendName(wl_resource *r)
{
if (wl_resource_get_version(r) < WL_SEAT_NAME_SINCE_VERSION) {
return;
}
wl_seat_send_name(r, name.toUtf8().constData());
}
void SeatInterface::Private::sendCapabilities(wl_resource *r)
{
uint32_t capabilities = 0;
if (pointer) {
capabilities |= WL_SEAT_CAPABILITY_POINTER;
}
if (keyboard) {
capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
}
if (touch) {
capabilities |= WL_SEAT_CAPABILITY_TOUCH;
}
wl_seat_send_capabilities(r, capabilities);
}
quint32 SeatInterface::Private::nextSerial() const
{
return display->nextSerial();
}
SeatInterface::Private *SeatInterface::Private::cast(wl_resource *r)
{
return r ? reinterpret_cast<SeatInterface::Private*>(wl_resource_get_user_data(r)) : nullptr;
}
QVector<DataDeviceInterface *> SeatInterface::Private::dataDevicesForSurface(SurfaceInterface *surface) const
QVector<DataDeviceInterface *> SeatInterfacePrivate::dataDevicesForSurface(SurfaceInterface *surface) const
{
if (!surface) {
return {};
@ -198,7 +145,7 @@ QVector<DataDeviceInterface *> SeatInterface::Private::dataDevicesForSurface(Sur
return primarySelectionDevices;
}
void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
void SeatInterfacePrivate::registerDataDevice(DataDeviceInterface *dataDevice)
{
Q_ASSERT(dataDevice->seat() == q);
dataDevices << dataDevice;
@ -272,7 +219,7 @@ void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
}
}
void SeatInterface::Private::registerDataControlDevice(DataControlDeviceV1Interface *dataDevice)
void SeatInterfacePrivate::registerDataControlDevice(DataControlDeviceV1Interface *dataDevice)
{
Q_ASSERT(dataDevice->seat() == q);
dataControlDevices << dataDevice;
@ -306,7 +253,7 @@ void SeatInterface::Private::registerDataControlDevice(DataControlDeviceV1Interf
}
}
void SeatInterface::Private::registerPrimarySelectionDevice(PrimarySelectionDeviceV1Interface *primarySelectionDevice)
void SeatInterfacePrivate::registerPrimarySelectionDevice(PrimarySelectionDeviceV1Interface *primarySelectionDevice)
{
Q_ASSERT(primarySelectionDevice->seat() == q);
@ -338,7 +285,7 @@ void SeatInterface::Private::registerPrimarySelectionDevice(PrimarySelectionDevi
}
}
void SeatInterface::Private::cancelDrag(quint32 serial)
void SeatInterfacePrivate::cancelDrag(quint32 serial)
{
if (drag.target) {
drag.target->updateDragTarget(nullptr, serial);
@ -347,7 +294,7 @@ void SeatInterface::Private::cancelDrag(quint32 serial)
endDrag(serial);
}
void SeatInterface::Private::endDrag(quint32 serial)
void SeatInterfacePrivate::endDrag(quint32 serial)
{
QObject::disconnect(drag.destroyConnection);
QObject::disconnect(drag.dragSourceDestroyConnection);
@ -381,7 +328,7 @@ void SeatInterface::Private::endDrag(quint32 serial)
emit q->dragEnded();
}
void SeatInterface::Private::updateSelection(DataDeviceInterface *dataDevice)
void SeatInterfacePrivate::updateSelection(DataDeviceInterface *dataDevice)
{
// if the update is from the focussed window we should inform the active client
if (!(globalKeyboard.focus.surface && (*globalKeyboard.focus.surface->client() == dataDevice->client()))) {
@ -390,7 +337,7 @@ void SeatInterface::Private::updateSelection(DataDeviceInterface *dataDevice)
q->setSelection(dataDevice->selection());
}
void SeatInterface::Private::updatePrimarySelection(PrimarySelectionDeviceV1Interface *primarySelectionDevice)
void SeatInterfacePrivate::updatePrimarySelection(PrimarySelectionDeviceV1Interface *primarySelectionDevice)
{
// if the update is from the focussed window we should inform the active client
if (!(globalKeyboard.focus.surface && (*globalKeyboard.focus.surface->client() == primarySelectionDevice->client()))) {
@ -399,144 +346,122 @@ void SeatInterface::Private::updatePrimarySelection(PrimarySelectionDeviceV1Inte
q->setPrimarySelection(primarySelectionDevice->selection());
}
void SeatInterfacePrivate::sendCapabilities()
{
const auto seatResources = resourceMap();
for (SeatInterfacePrivate::Resource *resource : seatResources) {
send_capabilities(resource->handle, capabilities);
}
}
void SeatInterface::setHasKeyboard(bool has)
{
Q_D();
if (d->keyboard.isNull() != has) {
return;
}
if (has) {
d->capabilities |= SeatInterfacePrivate::capability_keyboard;
d->keyboard.reset(new KeyboardInterface(this));
} else {
d->capabilities &= ~SeatInterfacePrivate::capability_keyboard;
d->keyboard.reset();
}
d->sendCapabilities();
emit hasKeyboardChanged(d->keyboard);
}
void SeatInterface::setHasPointer(bool has)
{
Q_D();
if (d->pointer.isNull() != has) {
return;
}
if (has) {
d->capabilities |= SeatInterfacePrivate::capability_pointer;
d->pointer.reset(new PointerInterface(this));
} else {
d->capabilities &= ~SeatInterfacePrivate::capability_pointer;
d->pointer.reset();
}
d->sendCapabilities();
emit hasPointerChanged(d->pointer);
}
void SeatInterface::setHasTouch(bool has)
{
Q_D();
if (d->touch.isNull() != has) {
return;
}
if (has) {
d->capabilities |= SeatInterfacePrivate::capability_touch;
d->touch.reset(new TouchInterface(this));
} else {
d->capabilities &= ~SeatInterfacePrivate::capability_touch;
d->touch.reset();
}
d->sendCapabilities();
emit hasTouchChanged(d->touch);
}
void SeatInterface::setName(const QString &name)
{
Q_D();
if (d->name == name) {
return;
}
d->name = name;
const auto seatResources = d->resourceMap();
for (SeatInterfacePrivate::Resource *resource : seatResources) {
if (resource->version() >= WL_SEAT_NAME_SINCE_VERSION) {
d->send_name(resource->handle, d->name);
}
}
emit nameChanged(d->name);
}
void SeatInterface::Private::getPointerCallback(wl_client *client, wl_resource *resource, uint32_t id)
{
cast(resource)->getPointer(client, resource, id);
}
void SeatInterface::Private::getPointer(wl_client *client, wl_resource *resource, uint32_t id)
{
if (pointer) {
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer.data());
pointerPrivate->add(client, id, wl_resource_get_version(resource));
}
}
void SeatInterface::Private::getKeyboardCallback(wl_client *client, wl_resource *resource, uint32_t id)
{
cast(resource)->getKeyboard(client, resource, id);
}
void SeatInterface::Private::getKeyboard(wl_client *client, wl_resource *resource, uint32_t id)
{
if (!keyboard) {
return;
}
keyboard->d->add(client, id, wl_resource_get_version(resource));
}
void SeatInterface::Private::getTouchCallback(wl_client *client, wl_resource *resource, uint32_t id)
{
cast(resource)->getTouch(client, resource, id);
}
void SeatInterface::Private::getTouch(wl_client *client, wl_resource *resource, uint32_t id)
{
if (touch) {
TouchInterfacePrivate *touchPrivate = TouchInterfacePrivate::get(touch.data());
touchPrivate->add(client, id, wl_resource_get_version(resource));
}
}
QString SeatInterface::name() const
{
Q_D();
return d->name;
}
bool SeatInterface::hasPointer() const
{
Q_D();
return d->pointer;
}
bool SeatInterface::hasKeyboard() const
{
Q_D();
return d->keyboard;
}
bool SeatInterface::hasTouch() const
{
Q_D();
return d->touch;
}
Display *SeatInterface::display() const
{
return d->display;
}
SeatInterface *SeatInterface::get(wl_resource *native)
{
return Private::get(native);
}
SeatInterface::Private *SeatInterface::d_func() const
{
return reinterpret_cast<Private*>(d.data());
if (SeatInterfacePrivate *seatPrivate = resource_cast<SeatInterfacePrivate *>(native)) {
return seatPrivate->q;
}
return nullptr;
}
QPointF SeatInterface::pointerPos() const
{
Q_D();
return d->globalPointer.pos;
}
void SeatInterface::setPointerPos(const QPointF &pos)
{
Q_D();
if (d->globalPointer.pos == pos) {
return;
}
@ -577,13 +502,11 @@ void SeatInterface::setPointerPos(const QPointF &pos)
quint32 SeatInterface::timestamp() const
{
Q_D();
return d->timestamp;
}
void SeatInterface::setTimestamp(quint32 time)
{
Q_D();
if (d->timestamp == time) {
return;
}
@ -593,7 +516,6 @@ void SeatInterface::setTimestamp(quint32 time)
void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &globalPosition, const QMatrix4x4 &inputTransformation)
{
Q_D();
if (surface == d->drag.surface) {
// no change
return;
@ -612,10 +534,10 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &glob
d->drag.target = d->dataDevicesForSurface(surface).first();
}
if (d->drag.mode == Private::Drag::Mode::Pointer) {
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) {
setPointerPos(globalPosition);
pointerFrame();
} else if (d->drag.mode == Private::Drag::Mode::Touch &&
} else if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Touch &&
d->globalTouch.focus.firstTouchPos != globalPosition) {
touchMove(d->globalTouch.ids.first(), globalPosition);
}
@ -632,11 +554,10 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &glob
void SeatInterface::setDragTarget(SurfaceInterface *surface, const QMatrix4x4 &inputTransformation)
{
Q_D();
if (d->drag.mode == Private::Drag::Mode::Pointer) {
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) {
setDragTarget(surface, pointerPos(), inputTransformation);
} else {
Q_ASSERT(d->drag.mode == Private::Drag::Mode::Touch);
Q_ASSERT(d->drag.mode == SeatInterfacePrivate::Drag::Mode::Touch);
setDragTarget(surface, d->globalTouch.focus.firstTouchPos, inputTransformation);
}
@ -644,7 +565,6 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QMatrix4x4 &i
SurfaceInterface *SeatInterface::focusedPointerSurface() const
{
Q_D();
return d->globalPointer.focus.surface;
}
@ -653,7 +573,6 @@ void SeatInterface::setFocusedPointerSurface(SurfaceInterface *surface, const QP
QMatrix4x4 m;
m.translate(-surfacePosition.x(), -surfacePosition.y());
setFocusedPointerSurface(surface, m);
Q_D();
if (d->globalPointer.focus.surface) {
d->globalPointer.focus.offset = surfacePosition;
}
@ -661,8 +580,7 @@ void SeatInterface::setFocusedPointerSurface(SurfaceInterface *surface, const QP
void SeatInterface::setFocusedPointerSurface(SurfaceInterface *surface, const QMatrix4x4 &transformation)
{
Q_D();
if (d->drag.mode == Private::Drag::Mode::Pointer) {
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) {
// ignore
return;
}
@ -672,12 +590,11 @@ void SeatInterface::setFocusedPointerSurface(SurfaceInterface *surface, const QM
if (d->globalPointer.focus.surface) {
disconnect(d->globalPointer.focus.destroyConnection);
}
d->globalPointer.focus = Private::Pointer::Focus();
d->globalPointer.focus = SeatInterfacePrivate::Pointer::Focus();
d->globalPointer.focus.surface = surface;
if (d->globalPointer.focus.surface) {
d->globalPointer.focus.destroyConnection = connect(surface, &QObject::destroyed, this, [this] {
Q_D();
d->globalPointer.focus = Private::Pointer::Focus();
d->globalPointer.focus = SeatInterfacePrivate::Pointer::Focus();
});
d->globalPointer.focus.serial = serial;
d->globalPointer.focus.transformation = transformation;
@ -701,7 +618,6 @@ void SeatInterface::setFocusedPointerSurface(SurfaceInterface *surface, const QM
void SeatInterface::setFocusedPointerSurfacePosition(const QPointF &surfacePosition)
{
Q_D();
if (d->globalPointer.focus.surface) {
d->globalPointer.focus.offset = surfacePosition;
d->globalPointer.focus.transformation = QMatrix4x4();
@ -711,13 +627,11 @@ void SeatInterface::setFocusedPointerSurfacePosition(const QPointF &surfacePosit
QPointF SeatInterface::focusedPointerSurfacePosition() const
{
Q_D();
return d->globalPointer.focus.offset;
}
void SeatInterface::setFocusedPointerSurfaceTransformation(const QMatrix4x4 &transformation)
{
Q_D();
if (d->globalPointer.focus.surface) {
d->globalPointer.focus.transformation = transformation;
}
@ -725,13 +639,11 @@ void SeatInterface::setFocusedPointerSurfaceTransformation(const QMatrix4x4 &tra
QMatrix4x4 SeatInterface::focusedPointerSurfaceTransformation() const
{
Q_D();
return d->globalPointer.focus.transformation;
}
PointerInterface *SeatInterface::pointer() const
{
Q_D();
return d->pointer.data();
}
@ -772,19 +684,17 @@ bool SeatInterface::isPointerButtonPressed(Qt::MouseButton button) const
bool SeatInterface::isPointerButtonPressed(quint32 button) const
{
Q_D();
auto it = d->globalPointer.buttonStates.constFind(button);
if (it == d->globalPointer.buttonStates.constEnd()) {
return false;
}
return it.value() == Private::Pointer::State::Pressed ? true : false;
return it.value() == SeatInterfacePrivate::Pointer::State::Pressed;
}
void SeatInterface::pointerAxis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source)
{
Q_D();
Q_ASSERT(d->pointer);
if (d->drag.mode == Private::Drag::Mode::Pointer) {
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) {
// ignore
return;
}
@ -802,12 +712,11 @@ void SeatInterface::pointerButtonPressed(Qt::MouseButton button)
void SeatInterface::pointerButtonPressed(quint32 button)
{
Q_D();
Q_ASSERT(d->pointer);
const quint32 serial = d->display->nextSerial();
d->updatePointerButtonSerial(button, serial);
d->updatePointerButtonState(button, Private::Pointer::State::Pressed);
if (d->drag.mode == Private::Drag::Mode::Pointer) {
d->updatePointerButtonState(button, SeatInterfacePrivate::Pointer::State::Pressed);
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) {
// ignore
return;
}
@ -831,13 +740,12 @@ void SeatInterface::pointerButtonReleased(Qt::MouseButton button)
void SeatInterface::pointerButtonReleased(quint32 button)
{
Q_D();
Q_ASSERT(d->pointer);
const quint32 serial = d->display->nextSerial();
const quint32 currentButtonSerial = pointerButtonSerial(button);
d->updatePointerButtonSerial(button, serial);
d->updatePointerButtonState(button, Private::Pointer::State::Released);
if (d->drag.mode == Private::Drag::Mode::Pointer) {
d->updatePointerButtonState(button, SeatInterfacePrivate::Pointer::State::Released);
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) {
if (d->drag.source->dragImplicitGrabSerial() != currentButtonSerial) {
// not our drag button - ignore
return;
@ -850,7 +758,6 @@ void SeatInterface::pointerButtonReleased(quint32 button)
void SeatInterface::pointerFrame()
{
Q_D();
Q_ASSERT(d->pointer);
d->pointer->sendFrame();
}
@ -862,7 +769,6 @@ quint32 SeatInterface::pointerButtonSerial(Qt::MouseButton button) const
quint32 SeatInterface::pointerButtonSerial(quint32 button) const
{
Q_D();
auto it = d->globalPointer.buttonSerials.constFind(button);
if (it == d->globalPointer.buttonSerials.constEnd()) {
return 0;
@ -872,7 +778,6 @@ quint32 SeatInterface::pointerButtonSerial(quint32 button) const
void SeatInterface::relativePointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
{
Q_D();
Q_ASSERT(d->pointer);
auto relativePointer = RelativePointerV1Interface::get(pointer());
@ -883,7 +788,6 @@ void SeatInterface::relativePointerMotion(const QSizeF &delta, const QSizeF &del
void SeatInterface::startPointerSwipeGesture(quint32 fingerCount)
{
Q_D();
Q_ASSERT(d->pointer);
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
@ -894,7 +798,6 @@ void SeatInterface::startPointerSwipeGesture(quint32 fingerCount)
void SeatInterface::updatePointerSwipeGesture(const QSizeF &delta)
{
Q_D();
Q_ASSERT(d->pointer);
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
@ -905,7 +808,6 @@ void SeatInterface::updatePointerSwipeGesture(const QSizeF &delta)
void SeatInterface::endPointerSwipeGesture()
{
Q_D();
Q_ASSERT(d->pointer);
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
@ -916,7 +818,6 @@ void SeatInterface::endPointerSwipeGesture()
void SeatInterface::cancelPointerSwipeGesture()
{
Q_D();
Q_ASSERT(d->pointer);
auto swipeGesture = PointerSwipeGestureV1Interface::get(pointer());
@ -927,7 +828,6 @@ void SeatInterface::cancelPointerSwipeGesture()
void SeatInterface::startPointerPinchGesture(quint32 fingerCount)
{
Q_D();
Q_ASSERT(d->pointer);
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
@ -938,7 +838,6 @@ void SeatInterface::startPointerPinchGesture(quint32 fingerCount)
void SeatInterface::updatePointerPinchGesture(const QSizeF &delta, qreal scale, qreal rotation)
{
Q_D();
Q_ASSERT(d->pointer);
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
@ -949,7 +848,6 @@ void SeatInterface::updatePointerPinchGesture(const QSizeF &delta, qreal scale,
void SeatInterface::endPointerPinchGesture()
{
Q_D();
Q_ASSERT(d->pointer);
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
@ -960,7 +858,6 @@ void SeatInterface::endPointerPinchGesture()
void SeatInterface::cancelPointerPinchGesture()
{
Q_D();
Q_ASSERT(d->pointer);
auto pinchGesture = PointerPinchGestureV1Interface::get(pointer());
@ -971,13 +868,11 @@ void SeatInterface::cancelPointerPinchGesture()
SurfaceInterface *SeatInterface::focusedKeyboardSurface() const
{
Q_D();
return d->globalKeyboard.focus.surface;
}
void SeatInterface::setFocusedKeyboardSurface(SurfaceInterface *surface)
{
Q_D();
if (!d->keyboard) {
qCWarning(KWAYLAND_SERVER) << "Can not set focused keyboard surface without keyboard capability";
return;
@ -988,15 +883,12 @@ void SeatInterface::setFocusedKeyboardSurface(SurfaceInterface *surface)
if (d->globalKeyboard.focus.surface) {
disconnect(d->globalKeyboard.focus.destroyConnection);
}
d->globalKeyboard.focus = Private::Keyboard::Focus();
d->globalKeyboard.focus = SeatInterfacePrivate::Keyboard::Focus();
d->globalKeyboard.focus.surface = surface;
if (d->globalKeyboard.focus.surface) {
d->globalKeyboard.focus.destroyConnection = connect(surface, &QObject::destroyed, this,
[this] {
Q_D();
d->globalKeyboard.focus = Private::Keyboard::Focus();
}
);
d->globalKeyboard.focus.destroyConnection = connect(surface, &QObject::destroyed, this, [this]() {
d->globalKeyboard.focus = SeatInterfacePrivate::Keyboard::Focus();
});
d->globalKeyboard.focus.serial = serial;
// selection?
const QVector<DataDeviceInterface *> dataDevices = d->dataDevicesForSurface(surface);
@ -1036,17 +928,15 @@ void SeatInterface::setFocusedKeyboardSurface(SurfaceInterface *surface)
KeyboardInterface *SeatInterface::keyboard() const
{
Q_D();
return d->keyboard.data();
}
void SeatInterface::cancelTouchSequence()
{
Q_D();
Q_ASSERT(d->touch);
d->touch->sendCancel();
if (d->drag.mode == Private::Drag::Mode::Touch) {
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Touch) {
// cancel the drag, don't drop. serial does not matter
d->cancelDrag(0);
}
@ -1055,25 +945,21 @@ void SeatInterface::cancelTouchSequence()
SurfaceInterface *SeatInterface::focusedTouchSurface() const
{
Q_D();
return d->globalTouch.focus.surface;
}
QPointF SeatInterface::focusedTouchSurfacePosition() const
{
Q_D();
return d->globalTouch.focus.offset;
}
bool SeatInterface::isTouchSequence() const
{
Q_D();
return !d->globalTouch.ids.isEmpty();
}
TouchInterface *SeatInterface::touch() const
{
Q_D();
return d->touch.data();
}
@ -1086,21 +972,19 @@ void SeatInterface::setFocusedTouchSurface(SurfaceInterface *surface, const QPoi
if (isDragTouch()) {
return;
}
Q_D();
if (d->globalTouch.focus.surface) {
disconnect(d->globalTouch.focus.destroyConnection);
}
d->globalTouch.focus = Private::Touch::Focus();
d->globalTouch.focus = SeatInterfacePrivate::Touch::Focus();
d->globalTouch.focus.surface = surface;
d->globalTouch.focus.offset = surfacePosition;
if (d->globalTouch.focus.surface) {
d->globalTouch.focus.destroyConnection = connect(surface, &QObject::destroyed, this, [this]() {
Q_D();
if (isTouchSequence()) {
// Surface destroyed during touch sequence - send a cancel
d->touch->sendCancel();
}
d->globalTouch.focus = Private::Touch::Focus();
d->globalTouch.focus = SeatInterfacePrivate::Touch::Focus();
});
}
d->touch->setFocusedSurface(surface);
@ -1108,13 +992,11 @@ void SeatInterface::setFocusedTouchSurface(SurfaceInterface *surface, const QPoi
void SeatInterface::setFocusedTouchSurfacePosition(const QPointF &surfacePosition)
{
Q_D();
d->globalTouch.focus.offset = surfacePosition;
}
void SeatInterface::touchDown(qint32 id, const QPointF &globalPosition)
{
Q_D();
Q_ASSERT(d->touch);
const qint32 serial = display()->nextSerial();
const auto pos = globalPosition - d->globalTouch.focus.offset;
@ -1142,7 +1024,6 @@ void SeatInterface::touchDown(qint32 id, const QPointF &globalPosition)
void SeatInterface::touchMove(qint32 id, const QPointF &globalPosition)
{
Q_D();
Q_ASSERT(d->touch);
Q_ASSERT(d->globalTouch.ids.contains(id));
@ -1170,11 +1051,10 @@ void SeatInterface::touchMove(qint32 id, const QPointF &globalPosition)
void SeatInterface::touchUp(qint32 id)
{
Q_D();
Q_ASSERT(d->touch);
Q_ASSERT(d->globalTouch.ids.contains(id));
const qint32 serial = display()->nextSerial();
if (d->drag.mode == Private::Drag::Mode::Touch &&
const qint32 serial = d->display->nextSerial();
if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Touch &&
d->drag.source->dragImplicitGrabSerial() == d->globalTouch.ids.value(id)) {
// the implicitly grabbing touch point has been upped
d->endDrag(serial);
@ -1198,14 +1078,12 @@ void SeatInterface::touchUp(qint32 id)
void SeatInterface::touchFrame()
{
Q_D();
Q_ASSERT(d->touch);
d->touch->sendFrame();
}
bool SeatInterface::hasImplicitTouchGrab(quint32 serial) const
{
Q_D();
if (!d->globalTouch.focus.surface) {
// origin surface has been destroyed
return false;
@ -1215,25 +1093,21 @@ bool SeatInterface::hasImplicitTouchGrab(quint32 serial) const
bool SeatInterface::isDrag() const
{
Q_D();
return d->drag.mode != Private::Drag::Mode::None;
return d->drag.mode != SeatInterfacePrivate::Drag::Mode::None;
}
bool SeatInterface::isDragPointer() const
{
Q_D();
return d->drag.mode == Private::Drag::Mode::Pointer;
return d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer;
}
bool SeatInterface::isDragTouch() const
{
Q_D();
return d->drag.mode == Private::Drag::Mode::Touch;
return d->drag.mode == SeatInterfacePrivate::Drag::Mode::Touch;
}
bool SeatInterface::hasImplicitPointerGrab(quint32 serial) const
{
Q_D();
const auto &serials = d->globalPointer.buttonSerials;
for (auto it = serials.constBegin(), end = serials.constEnd(); it != end; it++) {
if (it.value() == serial) {
@ -1245,25 +1119,21 @@ bool SeatInterface::hasImplicitPointerGrab(quint32 serial) const
QMatrix4x4 SeatInterface::dragSurfaceTransformation() const
{
Q_D();
return d->drag.transformation;
}
SurfaceInterface *SeatInterface::dragSurface() const
{
Q_D();
return d->drag.surface;
}
DataDeviceInterface *SeatInterface::dragSource() const
{
Q_D();
return d->drag.source;
}
void SeatInterface::setFocusedTextInputSurface(SurfaceInterface *surface)
{
Q_D();
const quint32 serial = d->display->nextSerial();
if (d->focusedTextInputSurface) {
@ -1292,30 +1162,25 @@ void SeatInterface::setFocusedTextInputSurface(SurfaceInterface *surface)
SurfaceInterface *SeatInterface::focusedTextInputSurface() const
{
Q_D();
return d->focusedTextInputSurface;
}
TextInputV2Interface *SeatInterface::textInputV2() const
{
Q_D();
return d->textInputV2;
}
TextInputV3Interface *SeatInterface::textInputV3() const
{
Q_D();
return d->textInputV3;
}
AbstractDataSource *SeatInterface::selection() const
{
Q_D();
return d->currentSelection;
}
void SeatInterface::setSelection(AbstractDataSource *selection)
{
Q_D();
if (d->currentSelection == selection) {
return;
}
@ -1355,7 +1220,6 @@ void SeatInterface::setSelection(AbstractDataSource *selection)
void SeatInterface::setPrimarySelection(AbstractDataSource *selection)
{
Q_D();
if (d->currentPrimarySelection == selection) {
return;
}

View file

@ -1,32 +1,33 @@
/*
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#pragma once
#include <KWaylandServer/kwaylandserver_export.h>
#include <QObject>
#include <QPoint>
#include <QMatrix4x4>
#include <KWaylandServer/kwaylandserver_export.h>
#include "global.h"
#include "keyboard_interface.h"
#include "pointer_interface.h"
#include "touch_interface.h"
struct wl_client;
struct wl_resource;
namespace KWaylandServer
{
class DataDeviceInterface;
class AbstractDataSource;
class DataDeviceInterface;
class Display;
class KeyboardInterface;
class PointerInterface;
class SeatInterfacePrivate;
class SurfaceInterface;
class TextInputV2Interface;
class TextInputV3Interface;
class TouchInterface;
/**
* Describes the source types for axis events. This indicates to the
@ -103,7 +104,7 @@ enum class PointerAxisSource {
* @see TouchInterface
* @see SurfaceInterface
**/
class KWAYLANDSERVER_EXPORT SeatInterface : public Global
class KWAYLANDSERVER_EXPORT SeatInterface : public QObject
{
Q_OBJECT
/**
@ -139,6 +140,7 @@ public:
explicit SeatInterface(Display *display, QObject *parent = nullptr);
virtual ~SeatInterface();
Display *display() const;
QString name() const;
bool hasPointer() const;
bool hasKeyboard() const;
@ -692,14 +694,8 @@ Q_SIGNALS:
void focusedTextInputSurfaceChanged();
private:
friend class DataControlDeviceV1Interface;
friend class DataDeviceInterface;
friend class PrimarySelectionDeviceV1Interface;
friend class TextInputManagerV2InterfacePrivate;
friend class KeyboardInterface;
class Private;
Private *d_func() const;
QScopedPointer<SeatInterfacePrivate> d;
friend class SeatInterfacePrivate;
};
}

View file

@ -1,5 +1,6 @@
/*
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
@ -7,14 +8,13 @@
// KWayland
#include "seat_interface.h"
#include "global_p.h"
// Qt
#include <QHash>
#include <QMap>
#include <QPointer>
#include <QVector>
// Wayland
#include <wayland-server.h>
#include "qwayland-server-wayland.h"
namespace KWaylandServer
{
@ -27,24 +27,25 @@ class TextInputV2Interface;
class TextInputV3Interface;
class PrimarySelectionDeviceV1Interface;
class SeatInterface::Private : public Global::Private
class SeatInterfacePrivate : public QtWaylandServer::wl_seat
{
public:
Private(SeatInterface *q, Display *d);
void bind(wl_client *client, uint32_t version, uint32_t id) override;
void sendCapabilities(wl_resource *r);
void sendName(wl_resource *r);
static SeatInterfacePrivate *get(SeatInterface *seat);
SeatInterfacePrivate(SeatInterface *q, Display *display);
void sendCapabilities();
QVector<DataDeviceInterface *> dataDevicesForSurface(SurfaceInterface *surface) const;
void registerPrimarySelectionDevice(PrimarySelectionDeviceV1Interface *primarySelectionDevice);
void registerDataDevice(DataDeviceInterface *dataDevice);
void registerDataControlDevice(DataControlDeviceV1Interface *dataDevice);
void endDrag(quint32 serial);
void cancelDrag(quint32 serial);
quint32 nextSerial() const;
SeatInterface *q;
QPointer<Display> display;
QString name;
QList<wl_resource*> resources;
quint32 timestamp = 0;
quint32 capabilities = 0;
QScopedPointer<KeyboardInterface> keyboard;
QScopedPointer<PointerInterface> pointer;
QScopedPointer<TouchInterface> touch;
@ -127,32 +128,16 @@ public:
};
Drag drag;
static SeatInterface *get(wl_resource *native) {
auto s = cast(native);
return s ? s->q : nullptr;
}
protected:
void seat_bind_resource(Resource *resource) override;
void seat_get_pointer(Resource *resource, uint32_t id) override;
void seat_get_keyboard(Resource *resource, uint32_t id) override;
void seat_get_touch(Resource *resource, uint32_t id) override;
void seat_release(Resource *resource) override;
private:
void getPointer(wl_client *client, wl_resource *resource, uint32_t id);
void getKeyboard(wl_client *client, wl_resource *resource, uint32_t id);
void getTouch(wl_client *client, wl_resource *resource, uint32_t id);
void updateSelection(DataDeviceInterface *dataDevice);
void updatePrimarySelection(PrimarySelectionDeviceV1Interface *primarySelectionDevice);
static Private *cast(wl_resource *r);
static void unbind(wl_resource *r);
// interface
static void getPointerCallback(wl_client *client, wl_resource *resource, uint32_t id);
static void getKeyboardCallback(wl_client *client, wl_resource *resource, uint32_t id);
static void getTouchCallback(wl_client *client, wl_resource *resource, uint32_t id);
static void releaseCallback(wl_client *client, wl_resource *resource);
static const struct wl_seat_interface s_interface;
static const quint32 s_version;
static const qint32 s_pointerVersion;
static const qint32 s_touchVersion;
static const qint32 s_keyboardVersion;
SeatInterface *q;
};
}
} // namespace KWaylandServer

View file

@ -256,7 +256,6 @@ int main(int argc, char **argv)
seat->setHasKeyboard(true);
seat->setHasPointer(true);
seat->setName(QStringLiteral("testSeat0"));
seat->create();
CompositorWindow compositorWindow;
compositorWindow.setSeat(seat);

View file

@ -105,7 +105,6 @@ int main(int argc, char **argv)
SeatInterface *seat = new SeatInterface(&display);
seat->setName(QStringLiteral("testSeat0"));
seat->create();
return app.exec();
}

View file

@ -262,6 +262,7 @@ Q_SIGNALS:
private:
friend class TextInputManagerV2InterfacePrivate;
friend class SeatInterface;
friend class SeatInterfacePrivate;
friend class TextInputV2InterfacePrivate;
explicit TextInputV2Interface(SeatInterface *seat);

View file

@ -191,6 +191,7 @@ Q_SIGNALS:
private:
friend class TextInputManagerV3InterfacePrivate;
friend class SeatInterface;
friend class SeatInterfacePrivate;
friend class TextInputV3InterfacePrivate;
explicit TextInputV3Interface(SeatInterface *seat);