From 5553d0e0f42b64c72a69fe7133e504067ed5c602 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Mon, 19 Dec 2022 12:20:21 +0200 Subject: [PATCH] Introduce SurfaceCursorSource The contents of the cursor can be either a normal image or a wl_surface. At the moment, we get an image from the wl_surface. But it's going to be changed so we use SurfaceItem to render wl_surface cursors. SurfaceCursorSource provides the way to get the wl_surface handle from the cursor. In order to provide backwards compatibility, it also provides a QImage. --- src/cursorsource.cpp | 32 ++++++++++++++++++++++++++++++++ src/cursorsource.h | 25 +++++++++++++++++++++++++ src/pointer_input.cpp | 22 +++------------------- src/pointer_input.h | 3 ++- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/cursorsource.cpp b/src/cursorsource.cpp index e1b0ec3ae5..a0edcd476d 100644 --- a/src/cursorsource.cpp +++ b/src/cursorsource.cpp @@ -6,6 +6,8 @@ #include "cursorsource.h" #include "cursor.h" +#include "wayland/shmclientbuffer.h" +#include "wayland/surface_interface.h" namespace KWin { @@ -116,4 +118,34 @@ void ShapeCursorSource::selectSprite(int index) Q_EMIT changed(); } +SurfaceCursorSource::SurfaceCursorSource(QObject *parent) + : CursorSource(parent) +{ +} + +KWaylandServer::SurfaceInterface *SurfaceCursorSource::surface() const +{ + return m_surface; +} + +void SurfaceCursorSource::update(KWaylandServer::SurfaceInterface *surface, const QPoint &hotspot) +{ + if (!surface) { + m_image = QImage(); + m_hotspot = QPoint(); + m_surface = nullptr; + } else { + auto buffer = qobject_cast(surface->buffer()); + if (buffer) { + m_image = buffer->data().copy(); + m_image.setDevicePixelRatio(surface->bufferScale()); + } else { + m_image = QImage(); + } + m_hotspot = hotspot; + m_surface = surface; + } + Q_EMIT changed(); +} + } // namespace KWin diff --git a/src/cursorsource.h b/src/cursorsource.h index 346ba798a2..701e8e0f62 100644 --- a/src/cursorsource.h +++ b/src/cursorsource.h @@ -11,8 +11,14 @@ #include #include #include +#include #include +namespace KWaylandServer +{ +class SurfaceInterface; +} + namespace KWin { @@ -80,4 +86,23 @@ private: int m_currentSprite = -1; }; +/** + * The SurfaceCursorSource class repsents the contents of a cursor backed by a wl_surface. + */ +class KWIN_EXPORT SurfaceCursorSource : public CursorSource +{ + Q_OBJECT + +public: + explicit SurfaceCursorSource(QObject *parent = nullptr); + + KWaylandServer::SurfaceInterface *surface() const; + +public Q_SLOTS: + void update(KWaylandServer::SurfaceInterface *surface, const QPoint &hotspot); + +private: + QPointer m_surface; +}; + } // namespace KWin diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 47b77976c8..262fec9db6 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -20,12 +20,10 @@ #include "input_event_spy.h" #include "mousebuttons.h" #include "osd.h" -#include "wayland/datadevice_interface.h" #include "wayland/display.h" #include "wayland/pointer_interface.h" #include "wayland/pointerconstraints_v1_interface.h" #include "wayland/seat_interface.h" -#include "wayland/shmclientbuffer.h" #include "wayland/surface_interface.h" #include "wayland_server.h" #include "workspace.h" @@ -891,7 +889,7 @@ CursorImage::CursorImage(PointerInputRedirection *parent) m_moveResizeCursor = std::make_unique(); m_windowSelectionCursor = std::make_unique(); m_decoration.cursor = std::make_unique(); - m_serverCursor.cursor = std::make_unique(); + m_serverCursor.cursor = std::make_unique(); connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::hasPointerChanged, this, &CursorImage::handlePointerChanged); @@ -1014,23 +1012,9 @@ void CursorImage::updateServerCursor() return; } auto c = p->cursor(); - if (!c) { - return; + if (c) { + m_serverCursor.cursor->update(c->surface(), c->hotspot()); } - - QImage image; - QPoint hotspot; - - if (c->surface()) { - auto buffer = qobject_cast(c->surface()->buffer()); - if (buffer) { - image = buffer->data().copy(); - image.setDevicePixelRatio(c->surface()->bufferScale()); - hotspot = c->hotspot(); - } - } - - m_serverCursor.cursor->update(image, hotspot); } void CursorImage::setEffectsOverrideCursor(Qt::CursorShape shape) diff --git a/src/pointer_input.h b/src/pointer_input.h index ce927e105f..7d561de8af 100644 --- a/src/pointer_input.h +++ b/src/pointer_input.h @@ -35,6 +35,7 @@ class InputRedirection; class CursorShape; class ImageCursorSource; class ShapeCursorSource; +class SurfaceCursorSource; namespace Decoration { @@ -245,7 +246,7 @@ private: struct { QMetaObject::Connection connection; - std::unique_ptr cursor; + std::unique_ptr cursor; } m_serverCursor; };