diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-06-15 08:55:01 +0200 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2018-06-19 12:43:05 +0000 |
commit | 0b397a6174db0d1c22c3a41de00479fe07ff3886 (patch) | |
tree | e99d650bd2a86cd983147b72562f8f658e00ea7c | |
parent | cf86659c874fcb1d3f88a784cd88a51942e5926b (diff) |
Fix WaylandOutput.sizeFollowsWindow when window changes screen
If a QWaylandOutput's QWindow is moved from one screen to another and that
causes the devicePixelRatio to change, it may result in a new pixel size,
but QWindow::width and height may stay unchanged (because they're not in pixel
coordinates). This is a problem because the sizeFollowsWindow functionality of
QWaylandOutput relied on the widthChanged and heightChanged signals, which are
then not fired, although the pixel size did change.
There's no QWindow::devicePixelRatioChanged signal we can attach to, so to fix
this, we attach to screenChanged instead and then compute the new pixelSize
using QWindow::devicePixelRatio() and call the handler if it changed.
This also removes some duplication between the old width and height handlers.
Change-Id: Ibcbf10489b83498b4a0fee2b520f528f94cb9ce3
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
-rw-r--r-- | src/compositor/compositor_api/qwaylandoutput.cpp | 92 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandoutput.h | 3 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandoutput_p.h | 3 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandoutputmode.cpp | 12 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandoutputmode.h | 5 |
5 files changed, 44 insertions, 71 deletions
diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index 545ef713e..b1ee9bbe0 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -165,6 +165,33 @@ void QWaylandOutputPrivate::sendModesInfo() } } +void QWaylandOutputPrivate::handleWindowPixelSizeChanged() +{ + Q_Q(QWaylandOutput); + Q_ASSERT(window); + if (sizeFollowsWindow && currentMode <= modes.size() - 1) { + if (currentMode >= 0) { + QWaylandOutputMode mode = modes.at(currentMode); + mode.setSize(windowPixelSize); + modes.replace(currentMode, mode); + emit q->geometryChanged(); + if (!availableGeometry.isValid()) + emit q->availableGeometryChanged(); + sendModesInfo(); + } else { + // We didn't add a mode during the initialization because the window + // size was invalid, let's add it now + int mHzRefreshRate = qFloor(window->screen()->refreshRate() * 1000); + QWaylandOutputMode mode(windowPixelSize, mHzRefreshRate); + if (mode.isValid()) { + modes.clear(); + q->addMode(mode, true); + q->setCurrentMode(mode); + } + } + } +} + void QWaylandOutputPrivate::addView(QWaylandView *view, QWaylandSurface *surface) { for (int i = 0; i < surfaceViews.size(); i++) { @@ -286,8 +313,9 @@ void QWaylandOutput::initialize() QWaylandCompositorPrivate::get(d->compositor)->addOutput(this); if (d->window) { - QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::handleSetWidth); - QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::handleSetHeight); + QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::handleMaybeWindowPixelSizeChanged); + QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::handleMaybeWindowPixelSizeChanged); + QObject::connect(d->window, &QWindow::screenChanged, this, &QWaylandOutput::handleMaybeWindowPixelSizeChanged); QObject::connect(d->window, &QObject::destroyed, this, &QWaylandOutput::handleWindowDestroyed); } @@ -920,66 +948,18 @@ void QWaylandOutput::surfaceLeave(QWaylandSurface *surface) /*! * \internal */ -void QWaylandOutput::handleSetWidth(int newWidth) +void QWaylandOutput::handleMaybeWindowPixelSizeChanged() { Q_D(QWaylandOutput); - if (!d->window || !d->sizeFollowsWindow) + if (!d->window) return; - if (d->currentMode <= d->modes.size() - 1) { - if (d->currentMode >= 0) { - QWaylandOutputMode mode = d->modes.at(d->currentMode); - mode.setWidth(newWidth * d->window->devicePixelRatio()); - d->modes.replace(d->currentMode, mode); - emit geometryChanged(); - if (!d->availableGeometry.isValid()) - emit availableGeometryChanged(); - d->sendModesInfo(); - } else { - // We didn't add a mode during the initialization because the window - // size was invalid, let's add it now - QWaylandOutputMode mode(d->window->size() * d->window->devicePixelRatio(), - qFloor(d->window->screen()->refreshRate() * 1000)); - if (mode.isValid()) { - d->modes.clear(); - addMode(mode, true); - setCurrentMode(mode); - } - } - } -} - -/*! - * \internal - */ -void QWaylandOutput::handleSetHeight(int newHeight) -{ - Q_D(QWaylandOutput); + const QSize pixelSize = d->window->size() * d->window->devicePixelRatio(); - if (!d->window || !d->sizeFollowsWindow) - return; - - if (d->currentMode <= d->modes.size() - 1) { - if (d->currentMode >= 0) { - QWaylandOutputMode mode = d->modes.at(d->currentMode); - mode.setHeight(newHeight * d->window->devicePixelRatio()); - d->modes.replace(d->currentMode, mode); - emit geometryChanged(); - if (!d->availableGeometry.isValid()) - emit availableGeometryChanged(); - d->sendModesInfo(); - } else { - // We didn't add a mode during the initialization because the window - // size was invalid, let's add it now - QWaylandOutputMode mode(d->window->size() * d->window->devicePixelRatio(), - qFloor(d->window->screen()->refreshRate() * 1000)); - if (mode.isValid()) { - d->modes.clear(); - addMode(mode, true); - setCurrentMode(mode); - } - } + if (pixelSize != d->windowPixelSize) { + d->windowPixelSize = pixelSize; + d->handleWindowPixelSizeChanged(); } } diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h index f0bea809e..c7f2973b6 100644 --- a/src/compositor/compositor_api/qwaylandoutput.h +++ b/src/compositor/compositor_api/qwaylandoutput.h @@ -181,8 +181,7 @@ Q_SIGNALS: void windowDestroyed(); private Q_SLOTS: - void handleSetWidth(int newWidth); - void handleSetHeight(int newHeight); + void handleMaybeWindowPixelSizeChanged(); void handleWindowDestroyed(); protected: diff --git a/src/compositor/compositor_api/qwaylandoutput_p.h b/src/compositor/compositor_api/qwaylandoutput_p.h index 38bb1ec6e..d8b2c9dfa 100644 --- a/src/compositor/compositor_api/qwaylandoutput_p.h +++ b/src/compositor/compositor_api/qwaylandoutput_p.h @@ -108,6 +108,8 @@ public: void sendMode(const Resource *resource, const QWaylandOutputMode &mode); void sendModesInfo(); + void handleWindowPixelSizeChanged(); + protected: void output_bind_resource(Resource *resource) override; @@ -128,6 +130,7 @@ private: int scaleFactor = 1; bool sizeFollowsWindow = false; bool initialized = false; + QSize windowPixelSize; Q_DECLARE_PUBLIC(QWaylandOutput) Q_DISABLE_COPY(QWaylandOutputPrivate) diff --git a/src/compositor/compositor_api/qwaylandoutputmode.cpp b/src/compositor/compositor_api/qwaylandoutputmode.cpp index 9ae285fd5..545871175 100644 --- a/src/compositor/compositor_api/qwaylandoutputmode.cpp +++ b/src/compositor/compositor_api/qwaylandoutputmode.cpp @@ -128,15 +128,7 @@ int QWaylandOutputMode::refreshRate() const /*! * \internal */ -void QWaylandOutputMode::setWidth(int width) +void QWaylandOutputMode::setSize(const QSize &size) { - d->size.setWidth(width); -} - -/*! - * \internal - */ -void QWaylandOutputMode::setHeight(int height) -{ - d->size.setHeight(height); + d->size = size; } diff --git a/src/compositor/compositor_api/qwaylandoutputmode.h b/src/compositor/compositor_api/qwaylandoutputmode.h index 7adb920e5..b03457929 100644 --- a/src/compositor/compositor_api/qwaylandoutputmode.h +++ b/src/compositor/compositor_api/qwaylandoutputmode.h @@ -64,10 +64,9 @@ public: private: class QWaylandOutputModePrivate *const d; - friend class QWaylandOutput; + friend class QWaylandOutputPrivate; - void setWidth(int width); - void setHeight(int height); + void setSize(const QSize &size); }; Q_DECLARE_TYPEINFO(QWaylandOutputMode, Q_MOVABLE_TYPE); |