diff --git a/pointer_input.cpp b/pointer_input.cpp --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -29,6 +29,7 @@ #include "wayland_server.h" #include "workspace.h" #include "decorations/decoratedclient.h" +#include "screens.h" // KDecoration #include // KWayland @@ -1217,7 +1218,12 @@ 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.h b/screens.h --- a/screens.h +++ b/screens.h @@ -88,6 +88,14 @@ **/ 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 @@ * @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 @@ KSharedConfig::Ptr m_config; QSize m_boundingSize; OrientationSensor *m_orientationSensor; + qreal m_maxScale; KWIN_SINGLETON(Screens) }; diff --git a/screens.cpp b/screens.cpp --- a/screens.cpp +++ b/screens.cpp @@ -56,6 +56,7 @@ , 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 @@ 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::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/wayland_cursor_theme.cpp b/wayland_cursor_theme.cpp --- a/wayland_cursor_theme.cpp +++ b/wayland_cursor_theme.cpp @@ -20,6 +20,7 @@ #include "wayland_cursor_theme.h" #include "cursor.h" #include "wayland_server.h" +#include "screens.h" // Qt #include // KWayland @@ -37,6 +38,7 @@ , m_theme(nullptr) , m_shm(shm) { + connect(screens(), &Screens::maxScaleChanged, this, &WaylandCursorTheme::loadTheme); } WaylandCursorTheme::~WaylandCursorTheme() @@ -56,6 +58,8 @@ size = 24; } + size *= screens()->maxScale(); + auto theme = wl_cursor_theme_load(c->themeName().toUtf8().constData(), size, m_shm->shm()); if (theme) {