summaryrefslogtreecommitdiffstats
path: root/src/client/qwaylandinputdevice.cpp
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2019-01-24 14:42:28 +0100
committerJohan Helsing <johan.helsing@qt.io>2019-02-27 11:48:30 +0000
commit021bd4d7ed1f4221a0132e21ef0ee5b07f74be3e (patch)
tree67bf87802a099743279b50fe62d05628dbd2bee0 /src/client/qwaylandinputdevice.cpp
parent2f0e6d773647d2112fcf34ab0d9d724f8278477c (diff)
Client: Decrease buffer_scale for small cursor themes
Not all setups or themes have cursors with a matching DPI. In such cases, wl_cursor_load_theme will then return a theme that is the closest resolution it can get. With the previous implementation, cursors themes without a high dpi version would become become really tiny on high DPI displays. This patch prevents it by setting a lower wl_surface.scale for those themes. This also implements proper tracking of the cursor surface's entered outputs (i.e. if the entered surface is destroyed, the scale is reset, and similarly the following sequence of events should also be handled: wl_surface.enter(wl_output@1) wl_surface.enter(wl_output@2) wl_surface.leave(wl_output@2) In the old implementation, we would be stuck with the scale from wl_output@2, but now we now should correctly get the scale of wl_output@1. [ChangeLog][QPA plugin] Cursors on high DPI screens are now scaled up if the cursor theme does not have an appropriate high resolution version. Change-Id: Ic87d00e35612b5afdf8c2e3a4463fcfef1f1f09d Reviewed-by: Giulio Camuffo <giulio.camuffo@kdab.com>
Diffstat (limited to 'src/client/qwaylandinputdevice.cpp')
-rw-r--r--src/client/qwaylandinputdevice.cpp52
1 files changed, 44 insertions, 8 deletions
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 43ca6dbd0..65267869f 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -188,7 +188,8 @@ QWaylandInputDevice::Pointer::~Pointer()
#if QT_CONFIG(cursor)
-class CursorSurface : public QtWayland::wl_surface {
+class CursorSurface : public QObject, public QtWayland::wl_surface
+{
public:
explicit CursorSurface(QWaylandInputDevice::Pointer *pointer, QWaylandDisplay *display)
: m_pointer(pointer)
@@ -196,6 +197,14 @@ public:
init(display->createSurface(this));
//TODO: When we upgrade to libwayland 1.10, use wl_surface_get_version instead.
m_version = display->compositorVersion();
+ connect(qApp, &QGuiApplication::screenRemoved, this, [this](QScreen *screen) {
+ int oldScale = outputScale();
+ if (!m_screens.removeOne(static_cast<QWaylandScreen *>(screen->handle())))
+ return;
+
+ if (outputScale() != oldScale)
+ m_pointer->updateCursor();
+ });
}
void hide()
@@ -225,18 +234,38 @@ public:
commit();
}
- int outputScale() const { return m_outputScale; }
+ int outputScale() const
+ {
+ int scale = 0;
+ for (auto *screen : m_screens)
+ scale = qMax(scale, screen->scale());
+ return scale;
+ }
protected:
void surface_enter(struct ::wl_output *output) override
{
- //TODO: Can be improved to keep track of all entered screens
- int scale = QWaylandScreen::fromWlOutput(output)->scale();
- if (scale == m_outputScale)
+ int oldScale = outputScale();
+ auto *screen = QWaylandScreen::fromWlOutput(output);
+ if (m_screens.contains(screen))
+ return;
+
+ m_screens.append(screen);
+
+ if (outputScale() != oldScale)
+ m_pointer->updateCursor();
+ }
+
+ void surface_leave(struct ::wl_output *output) override
+ {
+ int oldScale = outputScale();
+ auto *screen = QWaylandScreen::fromWlOutput(output);
+
+ if (!m_screens.removeOne(screen))
return;
- m_outputScale = scale;
- m_pointer->updateCursor();
+ if (outputScale() != oldScale)
+ m_pointer->updateCursor();
}
private:
@@ -244,7 +273,7 @@ private:
uint m_version = 0;
uint m_setSerial = 0;
QPoint m_hotspot;
- int m_outputScale = 0;
+ QVector<QWaylandScreen *> m_screens;
};
QString QWaylandInputDevice::Pointer::cursorThemeName() const
@@ -280,6 +309,13 @@ void QWaylandInputDevice::Pointer::updateCursorTheme()
int pixelSize = cursorSize() * scale;
auto *display = seat()->mQDisplay;
mCursor.theme = display->loadCursorTheme(cursorThemeName(), pixelSize);
+ if (auto *arrow = mCursor.theme->cursorImage(Qt::ArrowCursor)) {
+ int arrowPixelSize = qMax(arrow->width, arrow->height); // Not all cursor themes are square
+ while (scale > 1 && arrowPixelSize / scale < cursorSize())
+ --scale;
+ } else {
+ qWarning(lcQpaWayland) << "Cursor theme does not support the arrow cursor";
+ }
mCursor.themeBufferScale = scale;
}