Client: Fix incorrect decoration size when QT_SCALE_FACTOR is set

[ChangeLog][QPA plugin] Fixed a bug where window decorations were to small for
for the content when QT_SCALE_FACTOR was set.

Fixes: QTBUG-72993
Change-Id: I1ed26e038c27f7c4454a6bcc04f0849e4af789e7
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
Johan Klokkhammer Helsing 2019-01-22 14:38:44 +01:00 committed by Johan Helsing
parent db7724afe3
commit f91e358902
4 changed files with 49 additions and 26 deletions

View File

@ -109,19 +109,22 @@ QWaylandBradientDecoration::QWaylandBradientDecoration()
QRectF QWaylandBradientDecoration::closeButtonRect() const
{
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 0 - BUTTONS_RIGHT_MARGIN,
const int windowRight = waylandWindow()->windowGeometry().right() + 1;
return QRectF(windowRight - BUTTON_WIDTH - BUTTON_SPACING * 0 - BUTTONS_RIGHT_MARGIN,
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
QRectF QWaylandBradientDecoration::maximizeButtonRect() const
{
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 1 - BUTTONS_RIGHT_MARGIN,
const int windowRight = waylandWindow()->windowGeometry().right() + 1;
return QRectF(windowRight - BUTTON_WIDTH * 2 - BUTTON_SPACING * 1 - BUTTONS_RIGHT_MARGIN,
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
QRectF QWaylandBradientDecoration::minimizeButtonRect() const
{
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 2 - BUTTONS_RIGHT_MARGIN,
const int windowRight = waylandWindow()->windowGeometry().right() + 1;
return QRectF(windowRight - BUTTON_WIDTH * 3 - BUTTON_SPACING * 2 - BUTTONS_RIGHT_MARGIN,
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
@ -133,13 +136,13 @@ QMargins QWaylandBradientDecoration::margins() const
void QWaylandBradientDecoration::paint(QPaintDevice *device)
{
bool active = window()->handle()->isActive();
QRect surfaceRect(QPoint(), window()->frameGeometry().size());
QRect wg = waylandWindow()->windowGeometry();
QRect clips[] =
{
QRect(0, 0, surfaceRect.width(), margins().top()),
QRect(0, surfaceRect.height() - margins().bottom(), surfaceRect.width(), margins().bottom()),
QRect(0, margins().top(), margins().left(), surfaceRect.height() - margins().top() - margins().bottom()),
QRect(surfaceRect.width() - margins().right(), margins().top(), margins().left(), surfaceRect.height() - margins().top() - margins().bottom())
QRect(wg.left(), wg.top(), wg.width(), margins().top()),
QRect(wg.left(), (wg.bottom() + 1) - margins().bottom(), wg.width(), margins().bottom()),
QRect(wg.left(), margins().top(), margins().left(), wg.height() - margins().top() - margins().bottom()),
QRect((wg.right() + 1) - margins().right(), wg.top() + margins().top(), margins().right(), wg.height() - margins().top() - margins().bottom())
};
QRect top = clips[0];
@ -149,7 +152,7 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
// Title bar
QPainterPath roundedRect;
roundedRect.addRoundedRect(surfaceRect, 3, 3);
roundedRect.addRoundedRect(wg, 3, 3);
for (int i = 0; i < 4; ++i) {
p.save();
p.setClipRect(clips[i]);
@ -264,13 +267,14 @@ bool QWaylandBradientDecoration::handleMouse(QWaylandInputDevice *inputDevice, c
Q_UNUSED(global);
// Figure out what area mouse is in
if (local.y() <= margins().top()) {
QRect wg = waylandWindow()->windowGeometry();
if (local.y() <= wg.top() + margins().top()) {
processMouseTop(inputDevice,local,b,mods);
} else if (local.y() > window()->height() + margins().top()) {
} else if (local.y() > wg.bottom() - margins().bottom()) {
processMouseBottom(inputDevice,local,b,mods);
} else if (local.x() <= margins().left()) {
} else if (local.x() <= wg.left() + margins().left()) {
processMouseLeft(inputDevice,local,b,mods);
} else if (local.x() > window()->width() + margins().left()) {
} else if (local.x() > wg.right() - margins().right()) {
processMouseRight(inputDevice,local,b,mods);
} else {
#if QT_CONFIG(cursor)
@ -308,15 +312,16 @@ bool QWaylandBradientDecoration::handleTouch(QWaylandInputDevice *inputDevice, c
void QWaylandBradientDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
QRect wg = waylandWindow()->windowGeometry();
Q_UNUSED(mods);
if (local.y() <= margins().bottom()) {
if (local.y() <= wg.top() + margins().bottom()) {
if (local.x() <= margins().left()) {
//top left bit
#if QT_CONFIG(cursor)
waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
#endif
startResize(inputDevice, Qt::TopEdge | Qt::LeftEdge, b);
} else if (local.x() > window()->width() + margins().left()) {
} else if (local.x() > wg.right() - margins().right()) {
//top right bit
#if QT_CONFIG(cursor)
waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
@ -329,9 +334,9 @@ void QWaylandBradientDecoration::processMouseTop(QWaylandInputDevice *inputDevic
#endif
startResize(inputDevice, Qt::TopEdge, b);
}
} else if (local.x() <= margins().left()) {
} else if (local.x() <= wg.left() + margins().left()) {
processMouseLeft(inputDevice, local, b, mods);
} else if (local.x() > window()->width() + margins().left()) {
} else if (local.x() > wg.right() - margins().right()) {
processMouseRight(inputDevice, local, b, mods);
} else if (isRightClicked(b)) {
showWindowMenu(inputDevice);

View File

@ -115,16 +115,17 @@ const QImage &QWaylandAbstractDecoration::contentImage()
{
Q_D(QWaylandAbstractDecoration);
if (d->m_isDirty) {
//Update the decoration backingstore
// Update the decoration backingstore
const int scale = waylandWindow()->scale();
const QSize imageSize = window()->frameGeometry().size() * scale;
const int bufferScale = waylandWindow()->scale();
const QSize imageSize = waylandWindow()->surfaceSize() * bufferScale;
d->m_decorationContentImage = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
d->m_decorationContentImage.setDevicePixelRatio(scale);
// Only scale by buffer scale, not QT_SCALE_FACTOR etc.
d->m_decorationContentImage.setDevicePixelRatio(bufferScale);
d->m_decorationContentImage.fill(Qt::transparent);
this->paint(&d->m_decorationContentImage);
QRegion damage = marginsRegion(window()->geometry().size(), window()->frameMargins());
QRegion damage = marginsRegion(waylandWindow()->surfaceSize(), waylandWindow()->frameMargins());
for (QRect r : damage)
waylandWindow()->damage(r);

View File

@ -341,7 +341,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
sendExposeEvent(exposeGeometry);
if (mShellSurface)
mShellSurface->setWindowGeometry(QRect(QPoint(0, 0), window()->frameGeometry().size()));
mShellSurface->setWindowGeometry(windowGeometry());
}
void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
@ -654,6 +654,23 @@ QMargins QWaylandWindow::frameMargins() const
return QPlatformWindow::frameMargins();
}
/*!
* Size, with decorations (including including eventual shadows) in wl_surface coordinates
*/
QSize QWaylandWindow::surfaceSize() const
{
return geometry().marginsAdded(frameMargins()).size();
}
/*!
* Window geometry as defined by the xdg-shell spec (in wl_surface coordinates)
* topLeft is where the shadow stops and the decorations border start.
*/
QRect QWaylandWindow::windowGeometry() const
{
return QRect(QPoint(), surfaceSize());
}
QWaylandShellSurface *QWaylandWindow::shellSurface() const
{
return mShellSurface;
@ -848,9 +865,7 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan
#if QT_CONFIG(cursor)
if (e.type == QWaylandPointerEvent::Enter) {
QRect windowGeometry = window()->frameGeometry();
windowGeometry.moveTopLeft({0, 0}); // convert to wayland surface coordinates
QRect contentGeometry = windowGeometry.marginsRemoved(frameMargins());
QRect contentGeometry = windowGeometry().marginsRemoved(frameMargins());
if (contentGeometry.contains(e.local.toPoint()))
restoreMouseCursor(inputDevice);
}

View File

@ -125,6 +125,8 @@ public:
void waitForFrameSync();
QMargins frameMargins() const override;
QSize surfaceSize() const;
QRect windowGeometry() const;
static QWaylandWindow *fromWlSurface(::wl_surface *surface);