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.
This commit is contained in:
Vlad Zahorodnii 2022-12-19 12:20:21 +02:00
parent 877406ba50
commit 5553d0e0f4
4 changed files with 62 additions and 20 deletions

View file

@ -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<KWaylandServer::ShmClientBuffer *>(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

View file

@ -11,8 +11,14 @@
#include <QImage>
#include <QObject>
#include <QPoint>
#include <QPointer>
#include <QTimer>
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<KWaylandServer::SurfaceInterface> m_surface;
};
} // namespace KWin

View file

@ -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<ShapeCursorSource>();
m_windowSelectionCursor = std::make_unique<ShapeCursorSource>();
m_decoration.cursor = std::make_unique<ShapeCursorSource>();
m_serverCursor.cursor = std::make_unique<ImageCursorSource>();
m_serverCursor.cursor = std::make_unique<SurfaceCursorSource>();
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<KWaylandServer::ShmClientBuffer *>(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)

View file

@ -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<ImageCursorSource> cursor;
std::unique_ptr<SurfaceCursorSource> cursor;
} m_serverCursor;
};