diff --git a/input.cpp b/input.cpp
index faa4dfc881..8aa4b99996 100644
--- a/input.cpp
+++ b/input.cpp
@@ -33,6 +33,7 @@ along with this program. If not, see .
#include "libinput/connection.h"
#endif
#if HAVE_WAYLAND
+#include "wayland_backend.h"
#include "wayland_server.h"
#include
#endif
@@ -267,10 +268,17 @@ void InputRedirection::updatePointerWindow()
// disconnect old surface
if (oldWindow) {
disconnect(oldWindow.data(), &Toplevel::geometryChanged, this, &InputRedirection::updateFocusedPointerPosition);
+ if (Wayland::WaylandBackend *w = Wayland::WaylandBackend::self()) {
+ disconnect(seat->focusedPointer()->cursor(), &KWayland::Server::Cursor::changed, w, &Wayland::WaylandBackend::installCursorFromServer);
+ }
}
if (t && t->surface()) {
seat->setFocusedPointerSurface(t->surface(), t->pos());
connect(t, &Toplevel::geometryChanged, this, &InputRedirection::updateFocusedPointerPosition);
+ if (Wayland::WaylandBackend *w = Wayland::WaylandBackend::self()) {
+ w->installCursorFromServer();
+ connect(seat->focusedPointer()->cursor(), &KWayland::Server::Cursor::changed, w, &Wayland::WaylandBackend::installCursorFromServer);
+ }
} else {
seat->setFocusedPointerSurface(nullptr);
t = nullptr;
diff --git a/wayland_backend.cpp b/wayland_backend.cpp
index 1c36a6a986..2a52aade16 100644
--- a/wayland_backend.cpp
+++ b/wayland_backend.cpp
@@ -41,15 +41,15 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include
+#include
// Qt
#include
#include
#include
#include
#include
-// xcb
-#include
// Wayland
#include
#include
@@ -61,97 +61,6 @@ namespace Wayland
using namespace KWayland::Client;
-CursorData::CursorData()
- : m_valid(init())
-{
-}
-
-CursorData::~CursorData()
-{
-}
-
-bool CursorData::init()
-{
- QScopedPointer cursor(
- xcb_xfixes_get_cursor_image_reply(connection(),
- xcb_xfixes_get_cursor_image_unchecked(connection()),
- NULL));
- if (cursor.isNull()) {
- return false;
- }
-
- QImage cursorImage((uchar *) xcb_xfixes_get_cursor_image_cursor_image(cursor.data()), cursor->width, cursor->height,
- QImage::Format_ARGB32_Premultiplied);
- if (cursorImage.isNull()) {
- return false;
- }
- // the backend for the cursorImage is destroyed once the xcb cursor goes out of scope
- // because of that we create a copy
- m_cursor = cursorImage.copy();
-
- m_hotSpot = QPoint(cursor->xhot, cursor->yhot);
- return true;
-}
-
-X11CursorTracker::X11CursorTracker(WaylandBackend *backend, QObject* parent)
- : QObject(parent)
- , m_backend(backend)
- , m_lastX11Cursor(0)
-{
- Cursor::self()->startCursorTracking();
- connect(Cursor::self(), SIGNAL(cursorChanged(uint32_t)), SLOT(cursorChanged(uint32_t)));
-}
-
-X11CursorTracker::~X11CursorTracker()
-{
- if (Cursor::self()) {
- // Cursor might have been destroyed before Wayland backend gets destroyed
- Cursor::self()->stopCursorTracking();
- }
-}
-
-void X11CursorTracker::cursorChanged(uint32_t serial)
-{
- if (m_lastX11Cursor == serial) {
- // not changed;
- return;
- }
- m_lastX11Cursor = serial;
- QHash::iterator it = m_cursors.find(serial);
- if (it != m_cursors.end()) {
- installCursor(it.value());
- return;
- }
- ShmPool *pool = m_backend->shmPool();
- if (!pool->isValid()) {
- return;
- }
- CursorData cursor;
- if (cursor.isValid()) {
- // TODO: discard unused cursors after some time?
- m_cursors.insert(serial, cursor);
- }
- installCursor(cursor);
-}
-
-void X11CursorTracker::installCursor(const CursorData& cursor)
-{
- const QImage &cursorImage = cursor.cursor();
- auto buffer = m_backend->shmPool()->createBuffer(cursorImage);
- if (!buffer) {
- return;
- }
- emit cursorImageChanged(buffer, cursorImage.size(), cursor.hotSpot());
-}
-
-void X11CursorTracker::resetCursor()
-{
- QHash::iterator it = m_cursors.find(m_lastX11Cursor);
- if (it != m_cursors.end()) {
- installCursor(it.value());
- }
-}
-
WaylandSeat::WaylandSeat(wl_seat *seat, WaylandBackend *backend)
: QObject(NULL)
, m_seat(new Seat(this))
@@ -244,14 +153,6 @@ WaylandSeat::WaylandSeat(wl_seat *seat, WaylandBackend *backend)
input()->processPointerAxis(toAxis(), delta, time);
}
);
- connect(m_backend->cursorTracker(), &X11CursorTracker::cursorImageChanged, this,
- [this](Buffer::Ptr image, const QSize &size, const QPoint &hotspot) {
- if (image.isNull()) {
- return;
- }
- installCursorImage(image.toStrongRef()->buffer(), size, hotspot);
- }
- );
} else {
destroyPointer();
}
@@ -317,6 +218,11 @@ void WaylandSeat::installCursorImage(Qt::CursorShape shape)
QPoint(image->hotspot_x, image->hotspot_y));
}
+void WaylandSeat::installCursorImage(const QImage &image, const QPoint &hotSpot)
+{
+ installCursorImage(*(m_backend->shmPool()->createBuffer(image).data()), image.size(), hotSpot);
+}
+
void WaylandSeat::setInstallCursor(bool install)
{
// TODO: remove, add?
@@ -381,14 +287,6 @@ WaylandCursor::WaylandCursor(Surface *parentSurface, WaylandBackend *backend)
auto surface = backend->compositor()->createSurface(this);
m_subSurface = backend->subCompositor()->createSubSurface(QPointer(surface), QPointer(parentSurface), this);
- connect(m_backend->cursorTracker(), &X11CursorTracker::cursorImageChanged, this,
- [this](Buffer::Ptr image, const QSize &size, const QPoint &hotspot) {
- if (image.isNull()) {
- return;
- }
- setCursorImage(image.toStrongRef()->buffer(), size, hotspot);
- }
- );
connect(Cursor::self(), &Cursor::posChanged, this,
[this](const QPoint &pos) {
m_subSurface->setPosition(pos - m_hotSpot);
@@ -432,6 +330,11 @@ void WaylandCursor::setCursorImage(wl_buffer *image, const QSize &size, const QP
parent->commit(Surface::CommitFlag::None);
}
+void WaylandCursor::setCursorImage(const QImage &image, const QPoint &hotspot)
+{
+ setCursorImage(*(m_backend->shmPool()->createBuffer(image).data()), image.size(), hotspot);
+}
+
void WaylandCursor::setCursorImage(Qt::CursorShape shape)
{
wl_cursor_image *image = m_theme->get(shape);
@@ -462,7 +365,6 @@ WaylandBackend::WaylandBackend(QObject *parent)
, m_shellSurface(NULL)
, m_seat()
, m_shm(new ShmPool(this))
- , m_cursorTracker()
, m_connectionThreadObject(nullptr)
, m_connectionThread(nullptr)
, m_fullscreenShell(new FullscreenShell(this))
@@ -558,14 +460,12 @@ void WaylandBackend::initConnection()
// setup registry
m_registry->create(m_display);
m_registry->setup();
- m_cursorTracker.reset(new X11CursorTracker(this, this));
},
Qt::QueuedConnection);
connect(m_connectionThreadObject, &ConnectionThread::connectionDied, this,
[this]() {
m_ready = false;
emit systemCompositorDied();
- m_cursorTracker.reset();
m_seat.reset();
m_shm->destroy();
destroyOutputs();
@@ -609,6 +509,30 @@ void WaylandBackend::installCursorImage(Qt::CursorShape shape)
}
}
+void WaylandBackend::installCursorFromServer()
+{
+ if (!waylandServer() || !waylandServer()->seat()->focusedPointer()) {
+ return;
+ }
+ auto c = waylandServer()->seat()->focusedPointer()->cursor();
+ if (c) {
+ auto cursorSurface = c->surface();
+ if (!cursorSurface.isNull()) {
+ auto buffer = cursorSurface.data()->buffer();
+ if (buffer) {
+ // set cursor
+ if (!m_seat.isNull() && m_seat->isInstallCursor()) {
+ m_seat->installCursorImage(buffer->data(), c->hotspot());
+ } else if (m_cursor) {
+ m_cursor->setCursorImage(buffer->data(), c->hotspot());
+ }
+ return;
+ }
+ }
+ }
+ // TODO: unset cursor
+}
+
void WaylandBackend::createSurface()
{
m_surface = m_compositor->createSurface(this);
@@ -642,7 +566,6 @@ void WaylandBackend::createSurface()
// map the surface as fullscreen
m_shellSurface = m_shell->createSurface(m_surface, this);
m_shellSurface->setFullscreen();
- connect(m_shellSurface, &ShellSurface::pinged, m_cursorTracker.data(), &X11CursorTracker::resetCursor);
connect(m_shellSurface, &ShellSurface::sizeChanged, this, &WaylandBackend::shellSurfaceSizeChanged);
}
}
diff --git a/wayland_backend.h b/wayland_backend.h
index f1a6bbcecd..337a9858fb 100644
--- a/wayland_backend.h
+++ b/wayland_backend.h
@@ -68,42 +68,6 @@ namespace Wayland
class WaylandBackend;
class WaylandSeat;
-class CursorData
-{
-public:
- CursorData();
- ~CursorData();
- bool isValid() const;
- const QPoint &hotSpot() const;
- const QImage &cursor() const;
-private:
- bool init();
- QImage m_cursor;
- QPoint m_hotSpot;
- bool m_valid;
-};
-
-class X11CursorTracker : public QObject
-{
- Q_OBJECT
-public:
- explicit X11CursorTracker(WaylandBackend *backend, QObject* parent = 0);
- virtual ~X11CursorTracker();
- void resetCursor();
-
-Q_SIGNALS:
- void cursorImageChanged(QWeakPointer image, const QSize &size, const QPoint &hotSpot);
-
-private Q_SLOTS:
- void cursorChanged(uint32_t serial);
-private:
- void installCursor(const CursorData &cursor);
- QHash m_cursors;
- WaylandBackend *m_backend;
- uint32_t m_installedCursor;
- uint32_t m_lastX11Cursor;
-};
-
class WaylandCursorTheme : public QObject
{
Q_OBJECT
@@ -129,6 +93,7 @@ public:
void installCursorImage(wl_buffer *image, const QSize &size, const QPoint &hotspot);
void installCursorImage(Qt::CursorShape shape);
+ void installCursorImage(const QImage &image, const QPoint &hotspot);
void setInstallCursor(bool install);
bool isInstallCursor() const {
return m_installCursor;
@@ -157,6 +122,7 @@ public:
return m_hotSpot;
}
void setCursorImage(wl_buffer *image, const QSize &size, const QPoint &hotspot);
+ void setCursorImage(const QImage &image, const QPoint &hotspot);
void setCursorImage(Qt::CursorShape shape);
Q_SIGNALS:
@@ -185,11 +151,11 @@ public:
const QList &outputs() const;
KWayland::Client::ShmPool *shmPool();
KWayland::Client::SubCompositor *subCompositor();
- X11CursorTracker *cursorTracker();
KWayland::Client::Surface *surface() const;
QSize shellSurfaceSize() const;
void installCursorImage(Qt::CursorShape shape);
+ void installCursorFromServer();
protected:
void connectNotify(const QMetaMethod &signal) override;
@@ -214,7 +180,6 @@ private:
KWayland::Client::ShellSurface *m_shellSurface;
QScopedPointer m_seat;
KWayland::Client::ShmPool *m_shm;
- QScopedPointer m_cursorTracker;
QList m_outputs;
KWayland::Client::ConnectionThread *m_connectionThreadObject;
QThread *m_connectionThread;
@@ -226,24 +191,6 @@ private:
KWIN_SINGLETON(WaylandBackend)
};
-inline
-bool CursorData::isValid() const
-{
- return m_valid;
-}
-
-inline
-const QPoint& CursorData::hotSpot() const
-{
- return m_hotSpot;
-}
-
-inline
-const QImage &CursorData::cursor() const
-{
- return m_cursor;
-}
-
inline
wl_display *WaylandBackend::display()
{
@@ -268,12 +215,6 @@ KWayland::Client::ShmPool* WaylandBackend::shmPool()
return m_shm;
}
-inline
-X11CursorTracker *WaylandBackend::cursorTracker()
-{
- return m_cursorTracker.data();
-}
-
inline
KWayland::Client::Surface *WaylandBackend::surface() const
{