fix wrong cursor hotspot under Wayland on VMs

This commit is contained in:
Andrey Butirsky 2021-08-02 09:03:07 +00:00 committed by David Edmundson
parent 47e38b7141
commit 998bbf4eba
3 changed files with 15 additions and 7 deletions

View file

@ -103,7 +103,8 @@ bool DrmOutput::hideCursor()
bool DrmOutput::showCursor()
{
bool visibleBefore = m_pipeline->isCursorVisible();
if (m_pipeline->setCursor(m_cursor)) {
const Cursor * const cursor = Cursors::self()->currentCursor();
if (m_pipeline->setCursor(m_cursor, logicalToNativeMatrix(cursor->rect(), scale(), transform()).map(cursor->hotspot()) )) {
if (RenderLoopPrivate::get(m_renderLoop)->presentMode == RenderLoopPrivate::SyncMode::Adaptive
&& !visibleBefore
&& m_pipeline->isCursorVisible()) {
@ -149,7 +150,7 @@ bool DrmOutput::updateCursor()
p.setWorldTransform(logicalToNativeMatrix(cursor->rect(), 1, transform()).toTransform());
p.drawImage(QPoint(0, 0), cursorImage);
p.end();
if (m_pipeline->setCursor(m_cursor)) {
if (m_pipeline->setCursor(m_cursor, logicalToNativeMatrix(cursor->rect(), scale(), transform()).map(cursor->hotspot()) )) {
if (RenderLoopPrivate::get(m_renderLoop)->presentMode == RenderLoopPrivate::SyncMode::Adaptive
&& m_pipeline->isCursorVisible()) {
m_renderLoop->scheduleRepaint();

View file

@ -305,18 +305,24 @@ bool DrmPipeline::checkTestBuffer()
return false;
}
bool DrmPipeline::setCursor(const QSharedPointer<DrmDumbBuffer> &buffer)
bool DrmPipeline::setCursor(const QSharedPointer<DrmDumbBuffer> &buffer, const QPoint &hotspot)
{
if (!m_cursor.dirty && m_cursor.buffer == buffer) {
if (!m_cursor.dirty && m_cursor.buffer == buffer && m_cursor.hotspot == hotspot) {
return true;
}
const QSize &s = buffer ? buffer->size() : QSize(64, 64);
if (drmModeSetCursor(m_gpu->fd(), m_crtc->id(), buffer ? buffer->handle() : 0, s.width(), s.height()) != 0) {
int ret = drmModeSetCursor2(m_gpu->fd(), m_crtc->id(), buffer ? buffer->handle() : 0, s.width(), s.height(), hotspot.x(), hotspot.y());
if (ret == ENOTSUP) {
// for NVIDIA case that does not support drmModeSetCursor2
ret = drmModeSetCursor(m_gpu->fd(), m_crtc->id(), buffer ? buffer->handle() : 0, s.width(), s.height());
}
if (ret != 0) {
qCWarning(KWIN_DRM) << "Could not set cursor:" << strerror(errno);
return false;
}
m_cursor.buffer = buffer;
m_cursor.dirty = false;
m_cursor.hotspot = hotspot;
return true;
}
@ -374,7 +380,7 @@ bool DrmPipeline::setActive(bool active)
}
if (m_active) {
// enable cursor (again)
setCursor(m_cursor.buffer);
setCursor(m_cursor.buffer, m_cursor.hotspot);
}
return success;
}

View file

@ -54,7 +54,7 @@ public:
bool test(const QVector<DrmPipeline*> &pipelines);
bool modeset(int modeIndex);
bool setCursor(const QSharedPointer<DrmDumbBuffer> &buffer);
bool setCursor(const QSharedPointer<DrmDumbBuffer> &buffer, const QPoint &hotspot = QPoint());
bool setActive(bool enable);
bool setGammaRamp(const GammaRamp &ramp);
bool setTransformation(const DrmPlane::Transformations &transform);
@ -103,6 +103,7 @@ private:
bool m_legacyNeedsModeset = true;
struct {
QPoint pos = QPoint(100, 100);
QPoint hotspot;
QSharedPointer<DrmDumbBuffer> buffer;
bool dirty = true;// we don't know what the current state is
} m_cursor;