summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXaver Hugl <[email protected]>2025-06-16 18:08:23 +0300
committerDavid Edmundson <[email protected]>2025-06-25 16:56:10 +0100
commit91ef07052720b01478e82860798feac5fc76ebd2 (patch)
tree3c537931451580d6ed8ed335301fda7b2699e82c
parentbc6f4c5db46e1d8263e32e02f2ca6e49d6b4082d (diff)
wayland: Add pointer warp supportHEADdev
This supports partial usage of QCursor::setPos to move the mouse cursor. The wayland protocol only supports moving the cursor within the bounds of the window with pointer focus. Co-ordinates are mapped from global space to be relative to the focussed window. [ChangeLog][Third-Party Code] New protocol synced from wayland-protocols Fixes: QTBUG-127077 Pick-to: 6.10 Change-Id: Ic10142b2771fc9e6afc723b115b1b013a671e711 Reviewed-by: David Redondo <[email protected]>
-rw-r--r--src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml10
-rw-r--r--src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml72
-rw-r--r--src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json17
-rw-r--r--src/plugins/platforms/wayland/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.cpp19
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp5
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay_p.h6
7 files changed, 128 insertions, 2 deletions
diff --git a/src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml b/src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml
new file mode 100644
index 00000000000..61332b79db6
--- /dev/null
+++ b/src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml
@@ -0,0 +1,10 @@
+version = 1
+
+[[annotations]]
+path = "pointer-warp-v1.xml"
+precedence = "closest"
+SPDX-FileCopyrightText = ["Copyright © 2024 Neal Gompa",
+ "Copyright © 2024 Xaver Hugl",
+ "Copyright © 2024 Matthias Klumpp",
+ "Copyright © 2024 Vlad Zahorodnii"]
+SPDX-License-Identifier = "MIT"
diff --git a/src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml b/src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml
new file mode 100644
index 00000000000..158dad83c5d
--- /dev/null
+++ b/src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="pointer_warp_v1">
+ <copyright>
+ Copyright © 2024 Neal Gompa
+ Copyright © 2024 Xaver Hugl
+ Copyright © 2024 Matthias Klumpp
+ Copyright © 2024 Vlad Zahorodnii
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <interface name="wp_pointer_warp_v1" version="1">
+ <description summary="reposition the pointer to a location on a surface">
+ This global interface allows applications to request the pointer to be
+ moved to a position relative to a wl_surface.
+
+ Note that if the desired behavior is to constrain the pointer to an area
+ or lock it to a position, this protocol does not provide a reliable way
+ to do that. The pointer constraint and pointer lock protocols should be
+ used for those use cases instead.
+
+ Warning! The protocol described in this file is currently in the testing
+ phase. Backward compatible changes may be added together with the
+ corresponding interface version bump. Backward incompatible changes can
+ only be done by creating a new major version of the extension.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the warp manager">
+ Destroy the pointer warp manager.
+ </description>
+ </request>
+
+ <request name="warp_pointer">
+ <description summary="reposition the pointer">
+ Request the compositor to move the pointer to a surface-local position.
+ Whether or not the compositor honors the request is implementation defined,
+ but it should
+ - honor it if the surface has pointer focus, including
+ when it has an implicit pointer grab
+ - reject it if the enter serial is incorrect
+ - reject it if the requested position is outside of the surface
+
+ Note that the enter serial is valid for any surface of the client,
+ and does not have to be from the surface the pointer is warped to.
+
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"
+ summary="surface to position the pointer on"/>
+ <arg name="pointer" type="object" interface="wl_pointer"
+ summary="the pointer that should be repositioned"/>
+ <arg name="x" type="fixed"/>
+ <arg name="y" type="fixed"/>
+ <arg name="serial" type="uint" summary="serial number of the enter event"/>
+ </request>
+ </interface>
+</protocol>
diff --git a/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json b/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json
new file mode 100644
index 00000000000..83cd73c3570
--- /dev/null
+++ b/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json
@@ -0,0 +1,17 @@
+[
+ {
+ "Id": "wayland-pointer-warp-protocol",
+ "Name": "Wayland Pointer Warp Protocol",
+ "QDocModule": "qtwaylandcompositor",
+ "QtUsage": "Used in the Qt Wayland platform plugin",
+ "Files": "pointer-warp-v1.xml",
+ "Description": "",
+ "Homepage": "https://wayland.freedesktop.org/",
+ "Version": "version 1",
+ "DownloadLocation": "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/staging/pointer-warp/pointer-warp-v1.xml",
+ "LicenseId": "MIT",
+ "License": "MIT License",
+ "LicenseFile": "../MIT_LICENSE.txt",
+ "Copyright": "Copyright © 2024 Neal Gompa\nCopyright © 2024 Xaver Hugl\nCopyright © 2024 Matthias Klumpp\nCopyright © 2024 Vlad Zahorodnii"
+ }
+]
diff --git a/src/plugins/platforms/wayland/CMakeLists.txt b/src/plugins/platforms/wayland/CMakeLists.txt
index ac90eeadfa2..32a4ae34228 100644
--- a/src/plugins/platforms/wayland/CMakeLists.txt
+++ b/src/plugins/platforms/wayland/CMakeLists.txt
@@ -163,6 +163,7 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/extensions/hardware-integration.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/extensions/server-buffer-extension.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/color-management/xx-color-management-v4.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml
)
#### Keys ignored in scope 1:.:.:client.pro:<TRUE>:
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp
index 04ab7e6a50f..4967f9d46f4 100644
--- a/src/plugins/platforms/wayland/qwaylandcursor.cpp
+++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp
@@ -7,6 +7,7 @@
#include "qwaylanddisplay_p.h"
#include "qwaylandinputdevice_p.h"
#include "qwaylandshmbackingstore_p.h"
+#include "qwayland-pointer-warp-v1.h"
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
@@ -346,8 +347,22 @@ QPoint QWaylandCursor::pos() const
void QWaylandCursor::setPos(const QPoint &pos)
{
- Q_UNUSED(pos);
- qCWarning(lcQpaWayland) << "Setting cursor position is not possible on wayland";
+ if (mDisplay->pointerWarp()) {
+ const auto seats = mDisplay->inputDevices();
+ for (auto *seat : seats) {
+ if (!seat->pointer() || !seat->pointer()->focusWindow()) {
+ continue;
+ }
+ const auto focus = seat->pointer()->focusWindow();
+ if (!focus->windowFrameGeometry().contains(pos)) {
+ continue;
+ }
+ mDisplay->pointerWarp()->warp_pointer(focus->surface(), seat->pointer()->object(), wl_fixed_from_double(pos.x() - focus->windowFrameGeometry().x()), wl_fixed_from_double(pos.y() - focus->windowFrameGeometry().y()), seat->pointer()->mEnterSerial);
+ return;
+ }
+ } else {
+ qCWarning(lcQpaWayland) << "Setting cursor position requires pointer warp v1 protocol support";
+ }
}
void QWaylandCursor::setPosFromEnterEvent(const QPoint &pos)
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index c4cdbecf6ae..071ad78f91c 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -56,6 +56,7 @@
#include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h>
#include <QtWaylandClient/private/qwayland-xdg-toplevel-drag-v1.h>
#include <QtWaylandClient/private/qwayland-wlr-data-control-unstable-v1.h>
+#include <QtWaylandClient/private/qwayland-pointer-warp-v1.h>
#include <QtCore/private/qcore_unix_p.h>
@@ -798,8 +799,12 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mGlobals.colorManager = std::make_unique<ColorManager>(registry, id, 1);
// we need a roundtrip to receive the features the compositor supports
forceRoundTrip();
+ } else if (interface == QLatin1String(QtWayland::wp_pointer_warp_v1::interface()->name)) {
+ mGlobals.pointerWarp.reset(new WithDestructor<QtWayland::wp_pointer_warp_v1, wp_pointer_warp_v1_destroy>(
+ registry, id, 1));
}
+
mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry));
emit globalAdded(mRegistryGlobals.back());
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay_p.h b/src/plugins/platforms/wayland/qwaylanddisplay_p.h
index c8ba4935cf6..29952886421 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay_p.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay_p.h
@@ -58,6 +58,7 @@ namespace QtWayland {
class wp_viewporter;
class xdg_system_bell_v1;
class xdg_toplevel_drag_manager_v1;
+ class wp_pointer_warp_v1;
}
namespace QtWaylandClient {
@@ -225,6 +226,10 @@ public:
{
return mGlobals.colorManager.get();
}
+ QtWayland::wp_pointer_warp_v1 *pointerWarp() const
+ {
+ return mGlobals.pointerWarp.get();
+ }
struct RegistryGlobal {
uint32_t id;
@@ -360,6 +365,7 @@ private:
std::unique_ptr<QWaylandWindowManagerIntegration> windowManagerIntegration;
std::unique_ptr<QWaylandAppMenuManager> appMenuManager;
std::unique_ptr<ColorManager> colorManager;
+ std::unique_ptr<QtWayland::wp_pointer_warp_v1> pointerWarp;
} mGlobals;
int mFd = -1;