Load Kwin's internal cursors for the highest resolution of attached monitors

Test Plan:
Hovered over decoration
Looked super crystal clear
Same physical size as when I hover over window contents (which had a buffer scale of 1)

Reviewers: #kwin, graesslin

Reviewed By: #kwin, graesslin

Subscribers: graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D13608
This commit is contained in:
David Edmundson 2018-06-23 23:26:54 +01:00
parent 1761b75b55
commit c857c03561
4 changed files with 37 additions and 1 deletions

View file

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_server.h"
#include "workspace.h"
#include "decorations/decoratedclient.h"
#include "screens.h"
// KDecoration
#include <KDecoration2/Decoration>
// KWayland
@ -1217,7 +1218,12 @@ void CursorImage::loadThemeCursor(const T &shape, QHash<T, Image> &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;

View file

@ -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)

View file

@ -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)
};

View file

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_cursor_theme.h"
#include "cursor.h"
#include "wayland_server.h"
#include "screens.h"
// Qt
#include <QVector>
// 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) {