diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-12-06 12:00:55 +0100 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2019-02-15 09:12:35 +0000 |
commit | 15b3afd621a5c0e8d1dd1cd9d5ae816e15aa4a1a (patch) | |
tree | efe8e2944f983d1b263ce44efeb2a3eeee6ef0bb /src/client/qwaylandcursor.cpp | |
parent | 8073af6668cbcf308c83359ef2797d85d971946f (diff) |
Client: Refactor cursors and fix various bugs
This patch is mostly a cleanup to prepare for implementations of
xcursor-configuration, but also fixes a couple of issues.
Most of the logic has now been moved out of QWaylandDisplay and QWaylandCursor
and into QWaylandInputDevice and QWaylandInputDevice::Pointer. QWaylandDisplay
now only contains mechanisms for avoiding loading the same theme multiple
times.
There is now only one setCursor method on QWaylandInputDevice, accepting a
QCursor and storing its values so changing scale factor doesn't require calling
setCursor again. QWaylandInputDevice::Pointer::updateCursor() is called
instead.
Cursor buffer scale is now set according to enter/leave events of the cursor
surface itself instead of the current window, this fixes incorrect buffer
scales for cursors on windows that span multiple outputs. The window buffer
scale can still be passed into the seat as a fallback until the first enter
event is received.
This also fixes a bug where the QWaylandBuffer of a bitmap cursor could be
deleted while it was being used as a cursor.
[ChangeLog][QPA plugin] Fixed a bug where the DPI of bitmap cursors were not
sent to the compositor, leading to the compositor incorrectly scaling the
cursor up or down.
[ChangeLog][QPA plugin] Fixed a bug where bitmap cursor hotspots were off when
the screen scale factor was different from the bitmap cursor device pixel
ratio.
Task-number: QTBUG-68571
Change-Id: I747a47ffff01b7b5f6a0ede3552ab37884c4fa60
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/client/qwaylandcursor.cpp')
-rw-r--r-- | src/client/qwaylandcursor.cpp | 67 |
1 files changed, 18 insertions, 49 deletions
diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp index 6947e97f1..8b2ed036d 100644 --- a/src/client/qwaylandcursor.cpp +++ b/src/client/qwaylandcursor.cpp @@ -41,7 +41,6 @@ #include "qwaylanddisplay_p.h" #include "qwaylandinputdevice_p.h" -#include "qwaylandscreen_p.h" #include "qwaylandshmbackingstore_p.h" #include <QtGui/QImageReader> @@ -53,12 +52,6 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -QWaylandCursorTheme *QWaylandCursorTheme::create(QWaylandShm *shm, int size) -{ - static QString themeName = qEnvironmentVariable("XCURSOR_THEME", QStringLiteral("default")); - return create(shm, size, themeName); -} - QWaylandCursorTheme *QWaylandCursorTheme::create(QWaylandShm *shm, int size, const QString &themeName) { QByteArray nameBytes = themeName.toLocal8Bit(); @@ -244,56 +237,32 @@ struct wl_cursor_image *QWaylandCursorTheme::cursorImage(Qt::CursorShape shape) return image; } -QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) - : mDisplay(screen->display()) - , mCursorTheme(mDisplay->loadCursorTheme(screen->devicePixelRatio())) +QWaylandCursor::QWaylandCursor(QWaylandDisplay *display) + : mDisplay(display) { } -QSharedPointer<QWaylandBuffer> QWaylandCursor::cursorBitmapImage(const QCursor *cursor) +QSharedPointer<QWaylandBuffer> QWaylandCursor::cursorBitmapBuffer(QWaylandDisplay *display, const QCursor *cursor) { - if (cursor->shape() != Qt::BitmapCursor) - return QSharedPointer<QWaylandShmBuffer>(); - + Q_ASSERT(cursor->shape() == Qt::BitmapCursor); const QImage &img = cursor->pixmap().toImage(); - QSharedPointer<QWaylandShmBuffer> buffer(new QWaylandShmBuffer(mDisplay, img.size(), img.format())); - memcpy(buffer->image()->bits(), img.bits(), img.sizeInBytes()); - return buffer; -} - -struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape shape) -{ - if (!mCursorTheme) - return nullptr; - return mCursorTheme->cursorImage(shape); + QSharedPointer<QWaylandShmBuffer> buffer(new QWaylandShmBuffer(display, img.size(), img.format())); + memcpy(buffer->image()->bits(), img.bits(), size_t(img.sizeInBytes())); + return std::move(buffer); } void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) { - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; - - if (newShape == Qt::BlankCursor) { - mDisplay->setCursor(nullptr, nullptr, 1); - return; - } - - if (newShape == Qt::BitmapCursor) { - mDisplay->setCursor(cursorBitmapImage(cursor), cursor->hotSpot(), window->screen()->devicePixelRatio()); - return; - } - - if (!mCursorTheme) { - qCWarning(lcQpaWayland) << "Can't set cursor from shape with no cursor theme"; - return; - } - - if (struct ::wl_cursor_image *image = mCursorTheme->cursorImage(newShape)) { - struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); - mDisplay->setCursor(buffer, image, window->screen()->devicePixelRatio()); - return; - } - - qCWarning(lcQpaWayland) << "Unable to change to cursor" << cursor; + Q_UNUSED(window); + // Create the buffer here so we don't have to create one per input device + QSharedPointer<QWaylandBuffer> bitmapBuffer; + if (cursor && cursor->shape() == Qt::BitmapCursor) + bitmapBuffer = cursorBitmapBuffer(mDisplay, cursor); + + int fallbackOutputScale = int(window->devicePixelRatio()); + const auto seats = mDisplay->inputDevices(); + for (auto *seat : seats) + seat->setCursor(cursor, bitmapBuffer, fallbackOutputScale); } void QWaylandCursor::pointerEvent(const QMouseEvent &event) @@ -312,6 +281,6 @@ void QWaylandCursor::setPos(const QPoint &pos) qCWarning(lcQpaWayland) << "Setting cursor position is not possible on wayland"; } -} +} // namespace QtWaylandClient QT_END_NAMESPACE |