kwin/src/wayland/relativepointer_v1_interface.cpp
Vlad Zahorodnii 178c5d0595 Rewrite wl_pointer implementation with new approach
With this design, a single PointerInterface manages multiple wl_pointer
objects. This makes the API tidier and allows implementing things such as
keyboard grabs more easier.

In addition to that, the PointerInterface doesn't inject its own frame
events anymore. It's up to the compositor to decide when it has to be
sent. However, the PointerInterface may still send a frame event if the
pointer focus changes.

Besides re-writing the pointer interface, this change, unfortunately,
also affects the implementation of pointer-gestures and relative-pointer
protocols because previously they were coupled to individual instances
of PointerInterface.
2021-03-10 14:05:20 +00:00

93 lines
3.1 KiB
C++

/*
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "relativepointer_v1_interface.h"
#include "clientconnection.h"
#include "display.h"
#include "pointer_interface_p.h"
#include "relativepointer_v1_interface_p.h"
#include "seat_interface.h"
#include "surface_interface.h"
namespace KWaylandServer
{
static const int s_version = 1;
RelativePointerManagerV1InterfacePrivate::RelativePointerManagerV1InterfacePrivate(Display *display)
: QtWaylandServer::zwp_relative_pointer_manager_v1(*display, s_version)
{
}
void RelativePointerManagerV1InterfacePrivate::zwp_relative_pointer_manager_v1_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void RelativePointerManagerV1InterfacePrivate::zwp_relative_pointer_manager_v1_get_relative_pointer(Resource *resource, uint32_t id, struct ::wl_resource *pointer_resource)
{
PointerInterface *pointer = PointerInterface::get(pointer_resource);
if (!pointer) {
wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
"invalid pointer");
return;
}
RelativePointerV1Interface *relativePointer = RelativePointerV1Interface::get(pointer);
relativePointer->add(resource->client(), id, resource->version());
}
RelativePointerManagerV1Interface::RelativePointerManagerV1Interface(Display *display, QObject *parent)
: QObject(parent)
, d(new RelativePointerManagerV1InterfacePrivate(display))
{
}
RelativePointerManagerV1Interface::~RelativePointerManagerV1Interface()
{
}
RelativePointerV1Interface::RelativePointerV1Interface(PointerInterface *pointer)
: pointer(pointer)
{
}
RelativePointerV1Interface *RelativePointerV1Interface::get(PointerInterface *pointer)
{
if (pointer) {
PointerInterfacePrivate *pointerPrivate = PointerInterfacePrivate::get(pointer);
return pointerPrivate->relativePointersV1.data();
}
return nullptr;
}
void RelativePointerV1Interface::zwp_relative_pointer_v1_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void RelativePointerV1Interface::sendRelativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
{
if (!pointer->focusedSurface()) {
return;
}
ClientConnection *focusedClient = pointer->focusedSurface()->client();
const QList<Resource *> pointerResources = resourceMap().values(focusedClient->client());
for (Resource *pointerResource : pointerResources) {
if (pointerResource->client() == focusedClient->client()) {
send_relative_motion(pointerResource->handle, microseconds >> 32, microseconds & 0xffffffff,
wl_fixed_from_double(delta.width()),
wl_fixed_from_double(delta.height()),
wl_fixed_from_double(deltaNonAccelerated.width()),
wl_fixed_from_double(deltaNonAccelerated.height()));
}
}
}
} // namespace KWaylandServer