summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-06-15 08:55:01 +0200
committerJohan Helsing <johan.helsing@qt.io>2018-06-19 12:43:05 +0000
commit0b397a6174db0d1c22c3a41de00479fe07ff3886 (patch)
treee99d650bd2a86cd983147b72562f8f658e00ea7c
parentcf86659c874fcb1d3f88a784cd88a51942e5926b (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.cpp92
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.h3
-rw-r--r--src/compositor/compositor_api/qwaylandoutput_p.h3
-rw-r--r--src/compositor/compositor_api/qwaylandoutputmode.cpp12
-rw-r--r--src/compositor/compositor_api/qwaylandoutputmode.h5
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);