summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2019-01-22 14:38:44 +0100
committerJohan Helsing <johan.helsing@qt.io>2019-01-30 14:34:31 +0000
commitd0063d0972b29e9a2d4bdff837e3d4c23ac2e6cc (patch)
treefb312f0b51f042f73510be8ae6da22780d7caf4d
parent344e884d93bc35a8011427963f39575e56a5418a (diff)
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>
-rw-r--r--src/client/qwaylandabstractdecoration.cpp11
-rw-r--r--src/client/qwaylandwindow.cpp23
-rw-r--r--src/client/qwaylandwindow_p.h2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp4
-rw-r--r--src/plugins/decorations/bradient/main.cpp39
5 files changed, 51 insertions, 28 deletions
diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp
index 32fa6e1b..0f00b989 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 e81221fb..9e95b306 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 146767a1..0e573f35 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 a8ee9a43..6455b6fa 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 1bf67bbc..96ad261b 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);