actually draw drag icons in the mouse cursor during drags

Summary:
paint together the cursor image and the extra dnd image if available
on X11 with QDrag::setHotspot is possible to control their relative
position, which doesn't seem to have a wayland protocol correspondence
so their relative position are controlled just by the hotspot of the cursor itself

Test Plan:
folder graphics from dolphin is painted correctly
{F8086937}

Reviewers: #plasma, #kwin, davidedmundson

Reviewed By: #plasma, #kwin, davidedmundson

Subscribers: davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D27174
This commit is contained in:
Marco Martin 2020-02-06 13:24:07 +01:00
parent b9423a033c
commit baebfb7f7e

View file

@ -51,6 +51,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QHoverEvent>
#include <QWindow>
#include <QPainter>
// Wayland
#include <wayland-cursor.h>
@ -1221,6 +1222,7 @@ void CursorImage::updateDragCursor()
if (auto dragIcon = ddi->icon()) {
if (auto buffer = dragIcon->buffer()) {
additionalIcon = buffer->data().copy();
additionalIcon.setOffset(dragIcon->offset());
}
}
}
@ -1253,7 +1255,32 @@ void CursorImage::updateDragCursor()
return;
}
m_drag.cursor.hotSpot = c->hotspot();
m_drag.cursor.image = buffer->data().copy();
if (additionalIcon.isNull()) {
m_drag.cursor.image = buffer->data().copy();
} else {
QRect cursorRect = buffer->data().rect();
QRect iconRect = additionalIcon.rect();
if (-m_drag.cursor.hotSpot.x() < additionalIcon.offset().x()) {
iconRect.moveLeft(m_drag.cursor.hotSpot.x() - additionalIcon.offset().x());
} else {
cursorRect.moveLeft(-additionalIcon.offset().x() - m_drag.cursor.hotSpot.x());
}
if (-m_drag.cursor.hotSpot.y() < additionalIcon.offset().y()) {
iconRect.moveTop(m_drag.cursor.hotSpot.y() - additionalIcon.offset().y());
} else {
cursorRect.moveTop(-additionalIcon.offset().y() - m_drag.cursor.hotSpot.y());
}
m_drag.cursor.image = QImage(cursorRect.united(iconRect).size(), QImage::Format_ARGB32_Premultiplied);
m_drag.cursor.image.fill(Qt::transparent);
QPainter p(&m_drag.cursor.image);
p.drawImage(iconRect, additionalIcon);
p.drawImage(cursorRect, buffer->data());
p.end();
}
if (needsEmit) {
emit changed();
}