From d0063d0972b29e9a2d4bdff837e3d4c23ac2e6cc Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Tue, 22 Jan 2019 14:38:44 +0100 Subject: 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 --- src/client/qwaylandabstractdecoration.cpp | 11 +++--- src/client/qwaylandwindow.cpp | 23 ++++++++++--- src/client/qwaylandwindow_p.h | 2 ++ .../client/wayland-egl/qwaylandglcontext.cpp | 4 +-- src/plugins/decorations/bradient/main.cpp | 39 ++++++++++++---------- 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp index 32fa6e1b5..0f00b9890 100644 --- a/src/client/qwaylandabstractdecoration.cpp +++ b/src/client/qwaylandabstractdecoration.cpp @@ -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); diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index e81221fb5..9e95b3068 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -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); } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 146767a1e..0e573f350 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -125,6 +125,8 @@ public: void waitForFrameSync(); QMargins frameMargins() const override; + QSize surfaceSize() const; + QRect windowGeometry() const; static QWaylandWindow *fromWlSurface(::wl_surface *surface); diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index a8ee9a43a..6455b6fa9 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -147,9 +147,9 @@ public: { QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(m_context->context()); - QRect windowRect = window->window()->frameGeometry(); + QSize surfaceSize = window->surfaceSize(); int scale = window->scale() ; - glViewport(0, 0, windowRect.width() * scale, windowRect.height() * scale); + glViewport(0, 0, surfaceSize.width() * scale, surfaceSize.height() * scale); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); diff --git a/src/plugins/decorations/bradient/main.cpp b/src/plugins/decorations/bradient/main.cpp index 1bf67bbc3..96ad261b2 100644 --- a/src/plugins/decorations/bradient/main.cpp +++ b/src/plugins/decorations/bradient/main.cpp @@ -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); -- cgit v1.2.3