diff --git a/pointer_input.cpp b/pointer_input.cpp
index 1a59dbb7f4..46b84b788d 100644
--- a/pointer_input.cpp
+++ b/pointer_input.cpp
@@ -29,6 +29,7 @@ along with this program. If not, see .
#include "wayland_server.h"
#include "workspace.h"
#include "decorations/decoratedclient.h"
+#include "screens.h"
// KDecoration
#include
// KWayland
@@ -1217,7 +1218,12 @@ void CursorImage::loadThemeCursor(const T &shape, QHash &cursors, Imag
if (!buffer) {
return;
}
- it = decltype(it)(cursors.insert(shape, {buffer->data().copy(), QPoint(cursor->hotspot_x, cursor->hotspot_y)}));
+ auto scale = screens()->maxScale();
+ int hotSpotX = qRound(cursor->hotspot_x / scale);
+ int hotSpotY = qRound(cursor->hotspot_y / scale);
+ QImage img = buffer->data().copy();
+ img.setDevicePixelRatio(scale);
+ it = decltype(it)(cursors.insert(shape, {img, QPoint(hotSpotX, hotSpotY)}));
}
image->hotSpot = it.value().hotSpot;
image->image = it.value().image;
diff --git a/screens.cpp b/screens.cpp
index d28f75ce1a..df119f6490 100644
--- a/screens.cpp
+++ b/screens.cpp
@@ -56,6 +56,7 @@ Screens::Screens(QObject *parent)
, m_currentFollowsMouse(false)
, m_changedTimer(new QTimer(this))
, m_orientationSensor(new OrientationSensor(this))
+ , m_maxScale(1.0)
{
connect(this, &Screens::changed, this,
[this] {
@@ -105,6 +106,11 @@ float Screens::refreshRate(int screen) const
return 60.0f;
}
+qreal Screens::maxScale() const
+{
+ return m_maxScale;
+}
+
qreal Screens::scale(int screen) const
{
Q_UNUSED(screen)
@@ -124,13 +130,19 @@ void Screens::reconfigure()
void Screens::updateSize()
{
QRect bounding;
+ qreal maxScale = 1.0;
for (int i = 0; i < count(); ++i) {
bounding = bounding.united(geometry(i));
+ maxScale = qMax(maxScale, scale(i));
}
if (m_boundingSize != bounding.size()) {
m_boundingSize = bounding.size();
emit sizeChanged();
}
+ if (!qFuzzyCompare(m_maxScale, maxScale)) {
+ m_maxScale = maxScale;
+ emit maxScaleChanged();
+ }
}
void Screens::setCount(int count)
diff --git a/screens.h b/screens.h
index 4fda86fb9f..e9cdf1c93c 100644
--- a/screens.h
+++ b/screens.h
@@ -88,6 +88,14 @@ public:
**/
virtual QSize size(int screen) const = 0;
+ /**
+ * The highest scale() of all connected screens
+ * for use when deciding what scale to load global assets at
+ * Similar to QGuiApplication::scale
+ * @see scale
+ */
+ qreal maxScale() const;
+
/*
* The output scale for this display, for use by high DPI displays
*/
@@ -171,6 +179,11 @@ Q_SIGNALS:
* @see size()
**/
void sizeChanged();
+ /**
+ * Emitted when the maximum scale of all attached screens changes
+ * @see maxScale
+ */
+ void maxScaleChanged();
protected Q_SLOTS:
void setCount(int count);
@@ -196,6 +209,7 @@ private:
KSharedConfig::Ptr m_config;
QSize m_boundingSize;
OrientationSensor *m_orientationSensor;
+ qreal m_maxScale;
KWIN_SINGLETON(Screens)
};
diff --git a/wayland_cursor_theme.cpp b/wayland_cursor_theme.cpp
index 7a77533bbe..9444c2f16b 100644
--- a/wayland_cursor_theme.cpp
+++ b/wayland_cursor_theme.cpp
@@ -20,6 +20,7 @@ along with this program. If not, see .
#include "wayland_cursor_theme.h"
#include "cursor.h"
#include "wayland_server.h"
+#include "screens.h"
// Qt
#include
// KWayland
@@ -37,6 +38,7 @@ WaylandCursorTheme::WaylandCursorTheme(KWayland::Client::ShmPool *shm, QObject *
, m_theme(nullptr)
, m_shm(shm)
{
+ connect(screens(), &Screens::maxScaleChanged, this, &WaylandCursorTheme::loadTheme);
}
WaylandCursorTheme::~WaylandCursorTheme()
@@ -56,6 +58,8 @@ void WaylandCursorTheme::loadTheme()
size = 24;
}
+ size *= screens()->maxScale();
+
auto theme = wl_cursor_theme_load(c->themeName().toUtf8().constData(),
size, m_shm->shm());
if (theme) {