diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qguiapplication.cpp qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qguiapplication.cpp
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qguiapplication.cpp	2017-07-17 09:34:04.337040117 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qguiapplication.cpp	2017-07-17 09:34:09.216545729 -0300
@@ -2149,7 +2149,7 @@
         }
         // we may have changed scaling, so trigger resize event if needed
         if (window->handle()) {
-            QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect());
+            QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window));
             processGeometryChangeEvent(&gce);
         }
     }
@@ -2174,35 +2174,46 @@
     if (!window)
         return;

-    QRect newRect = e->newGeometry;
-    QRect oldRect = e->oldGeometry.isNull() ? window->d_func()->geometry : e->oldGeometry;
+    const QRect lastReportedGeometry = window->d_func()->geometry;
+    const QRect requestedGeometry = e->requestedGeometry;
+    const QRect actualGeometry = e->newGeometry;
+
+    // We send size and move events only if the geometry has changed from
+    // what was last reported, or if the user tried to set a new geometry,
+    // but the window manager responded by keeping the old geometry. In the
+    // latter case we send move/resize events with the same geometry as the
+    // last reported geometry, to indicate that the window wasn't moved or
+    // resized. Note that this logic does not apply to the property changes
+    // of the window, as we don't treat them as part of this request/response
+    // protocol of QWindow/QPA.
+    const bool isResize = actualGeometry.size() != lastReportedGeometry.size()
+        || requestedGeometry.size() != actualGeometry.size();
+    const bool isMove = actualGeometry.topLeft() != lastReportedGeometry.topLeft()
+        || requestedGeometry.topLeft() != actualGeometry.topLeft();

-    bool isResize = oldRect.size() != newRect.size();
-    bool isMove = oldRect.topLeft() != newRect.topLeft();
-
-    window->d_func()->geometry = newRect;
+    window->d_func()->geometry = actualGeometry;

     if (isResize || window->d_func()->resizeEventPending) {
-        QResizeEvent e(newRect.size(), oldRect.size());
+        QResizeEvent e(actualGeometry.size(), lastReportedGeometry.size());
         QGuiApplication::sendSpontaneousEvent(window, &e);

         window->d_func()->resizeEventPending = false;

-        if (oldRect.width() != newRect.width())
-            window->widthChanged(newRect.width());
-        if (oldRect.height() != newRect.height())
-            window->heightChanged(newRect.height());
+        if (actualGeometry.width() != lastReportedGeometry.width())
+            window->widthChanged(actualGeometry.width());
+        if (actualGeometry.height() != lastReportedGeometry.height())
+            window->heightChanged(actualGeometry.height());
     }

     if (isMove) {
         //### frame geometry
-        QMoveEvent e(newRect.topLeft(), oldRect.topLeft());
+        QMoveEvent e(actualGeometry.topLeft(), lastReportedGeometry.topLeft());
         QGuiApplication::sendSpontaneousEvent(window, &e);

-        if (oldRect.x() != newRect.x())
-            window->xChanged(newRect.x());
-        if (oldRect.y() != newRect.y())
-            window->yChanged(newRect.y());
+        if (actualGeometry.x() != lastReportedGeometry.x())
+            window->xChanged(actualGeometry.x());
+        if (actualGeometry.y() != lastReportedGeometry.y())
+            window->yChanged(actualGeometry.y());
     }
 }

diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qwindowsysteminterface.cpp qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qwindowsysteminterface.cpp
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qwindowsysteminterface.cpp	2017-07-17 09:34:04.337040117 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qwindowsysteminterface.cpp	2017-07-17 09:48:28.845228017 -0300
@@ -144,12 +144,17 @@
     QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
 }

-/*!
-  If \a oldRect is null, Qt will use the previously reported geometry instead.
- */
-void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect)
+QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *tlw, const QRect &newGeometry)
+    : WindowSystemEvent(GeometryChange)
+    , tlw(tlw)
+    , requestedGeometry(tlw->handle() ? tlw->handle()->QPlatformWindow::geometry() : QRect())
+    , newGeometry(newGeometry)
 {
-    QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw));
+}
+
+void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect)
+{
+    QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw));
     QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
 }

diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qwindowsysteminterface.h qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qwindowsysteminterface.h
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qwindowsysteminterface.h	2017-07-17 09:34:04.333040521 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qwindowsysteminterface.h	2017-07-17 09:38:53.318424542 -0300
@@ -139,7 +139,7 @@
     static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);

     // rect is relative to parent
-    static void handleGeometryChange(QWindow *w, const QRect &newRect, const QRect &oldRect = QRect());
+    static void handleGeometryChange(QWindow *w, const QRect &newRect);
     static void handleCloseEvent(QWindow *w, bool *accepted = Q_NULLPTR);
     static void handleEnterEvent(QWindow *w, const QPointF &local = QPointF(), const QPointF& global = QPointF());
     static void handleLeaveEvent(QWindow *w);
diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qwindowsysteminterface_p.h qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qwindowsysteminterface_p.h
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/gui/kernel/qwindowsysteminterface_p.h	2017-07-17 09:34:04.337040117 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/gui/kernel/qwindowsysteminterface_p.h	2017-07-17 09:47:16.829868654 -0300
@@ -130,12 +130,10 @@

     class GeometryChangeEvent : public WindowSystemEvent {
     public:
-        GeometryChangeEvent(QWindow *tlw, const QRect &newGeometry, const QRect &oldGeometry)
-            : WindowSystemEvent(GeometryChange), tlw(tlw), newGeometry(newGeometry), oldGeometry(oldGeometry)
-        { }
+        GeometryChangeEvent(QWindow *tlw, const QRect &newGeometry);
         QPointer<QWindow> tlw;
+        QRect requestedGeometry;
         QRect newGeometry;
-        QRect oldGeometry;
     };

     class EnterEvent : public WindowSystemEvent {
diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/plugins/platforms/eglfs/qeglfswindow.cpp qtbase-opensource-src-5.7.1+dfsg/src/plugins/platforms/eglfs/qeglfswindow.cpp
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/plugins/platforms/eglfs/qeglfswindow.cpp	2017-07-17 09:34:04.357038091 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/plugins/platforms/eglfs/qeglfswindow.cpp	2017-07-17 10:26:46.005777752 -0300
@@ -41,6 +41,7 @@
 #include <qpa/qwindowsysteminterface.h>
 #include <qpa/qplatformintegration.h>
 #include <private/qguiapplication_p.h>
+#include <private/qwindow_p.h>
 #include <QtGui/private/qopenglcontext_p.h>
 #include <QtGui/QOpenGLContext>
 #include <QtPlatformSupport/private/qeglconvenience_p.h>
@@ -217,18 +218,20 @@

 void QEglFSWindow::setGeometry(const QRect &r)
 {
-    QRect rect;
-    bool forceFullscreen = m_flags.testFlag(HasNativeWindow);
-    if (forceFullscreen)
+    // Persist the requested rect, like a normal setGeometry call
+    QPlatformWindow::setGeometry(r);
+
+    // Take care of WM behavior, constrain/modify geometry
+    QRect rect = r;
+    if (m_flags.testFlag(HasNativeWindow))
         rect = screen()->availableGeometry();
-    else
-        rect = r;

-    QPlatformWindow::setGeometry(rect);
+    // React to the setGeometry, as if from a WM callback
+    QRect lastReportedGeometry = qt_window_private(window())->geometry;
+    QWindowSystemInterface::handleGeometryChange(window(), rect);

-    // if we corrected the size, trigger a resize event
-    if (rect != r)
-        QWindowSystemInterface::handleGeometryChange(window(), rect, r);
+    if (rect != lastReportedGeometry)
+        QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
 }

 QRect QEglFSWindow::geometry() const
diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/plugins/platforms/ios/quiview.mm qtbase-opensource-src-5.7.1+dfsg/src/plugins/platforms/ios/quiview.mm
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/plugins/platforms/ios/quiview.mm	2017-07-17 09:34:04.357038091 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/plugins/platforms/ios/quiview.mm	2017-07-17 09:57:00.987866185 -0300
@@ -145,24 +145,13 @@
         qWarning() << m_qioswindow->window()
             << "is backed by a UIView that has a transform set. This is not supported.";

-    // The original geometry requested by setGeometry() might be different
-    // from what we end up with after applying window constraints.
-    QRect requestedGeometry = m_qioswindow->geometry();
-
-    QRect actualGeometry = fromCGRect(self.frame).toRect();
-
-    // Persist the actual/new geometry so that QWindow::geometry() can
-    // be queried on the resize event.
-    m_qioswindow->QPlatformWindow::setGeometry(actualGeometry);
-
-    QRect previousGeometry = requestedGeometry != actualGeometry ?
-            requestedGeometry : qt_window_private(m_qioswindow->window())->geometry;
-
     QWindow *window = m_qioswindow->window();
-    QWindowSystemInterface::handleGeometryChange(window, actualGeometry, previousGeometry);
+    QRect lastReportedGeometry = qt_window_private(window)->geometry;
+    QRect currentGeometry = fromCGRect(self.frame).toRect();
+    QWindowSystemInterface::handleGeometryChange(window, currentGeometry);
     QWindowSystemInterface::flushWindowSystemEvents(window->inherits("QWidgetWindow") ? QEventLoop::ExcludeUserInputEvents : QEventLoop::AllEvents);

-    if (actualGeometry.size() != previousGeometry.size()) {
+    if (currentGeometry.size() != lastReportedGeometry.size()) {
         // Trigger expose event on resize
         [self setNeedsDisplay];

diff -ru qtbase-opensource-src-5.7.1+dfsg.orig/src/plugins/platforms/xcb/qxcbwindow.cpp qtbase-opensource-src-5.7.1+dfsg/src/plugins/platforms/xcb/qxcbwindow.cpp
--- qtbase-opensource-src-5.7.1+dfsg.orig/src/plugins/platforms/xcb/qxcbwindow.cpp	2017-07-17 09:34:04.353038495 -0300
+++ qtbase-opensource-src-5.7.1+dfsg/src/plugins/platforms/xcb/qxcbwindow.cpp	2017-07-17 09:37:32.216925944 -0300
@@ -2116,10 +2116,6 @@
     // be queried in the resize event.
     QPlatformWindow::setGeometry(actualGeometry);

-    // FIXME: In the case of the requestedGeometry not matching the actualGeometry due
-    // to e.g. the window manager applying restrictions to the geometry, the application
-    // will never see a move/resize event if the actualGeometry is the same as the current
-    // geometry, and may think the requested geometry was fulfilled.
     QWindowSystemInterface::handleGeometryChange(window(), actualGeometry);

     // QPlatformScreen::screen() is updated asynchronously, so we can't compare it
