Relieve platform plugins of having to persist geometry on WM callbacks
We can offload this to QGuiApplication, just like the geometry of the QWindow is set. This ensures that all platforms behave the same, and that the documentation of QPlatformWindow::setGeometry is adhered. Change-Id: I19dbc32cb4fb146d716ec289c28030a547d3afaa Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
06904a7a77
commit
a4c8129d09
@ -105,10 +105,17 @@ QSurfaceFormat QPlatformWindow::format() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This function is called by Qt whenever a window is moved or the window is resized. The resize
|
This function is called by Qt whenever a window is moved or resized using the QWindow API.
|
||||||
can happen programatically(from ie. user application) or by the window manager. This means that
|
|
||||||
there is no need to call this function specifically from the window manager callback, instead
|
Unless you also override QPlatformWindow::geometry(), you need to call the baseclass
|
||||||
call QWindowSystemInterface::handleGeometryChange(QWindow *w, const QRect &newRect);
|
implementation of this function in any override of QPlatformWindow::setGeometry(), as
|
||||||
|
QWindow::geometry() is expected to report back the set geometry until a confirmation
|
||||||
|
(or rejection) of the new geometry comes back from the window manager and is reported
|
||||||
|
via handleGeometryChange().
|
||||||
|
|
||||||
|
Window move/resizes can also be triggered spontaneously by the window manager, or as a
|
||||||
|
response to an earlier requested move/resize via the Qt APIs. There is no need to call
|
||||||
|
this function from the window manager callback, instead call QPA::handleGeometryChange.
|
||||||
|
|
||||||
The position(x, y) part of the rect might be inclusive or exclusive of the window frame
|
The position(x, y) part of the rect might be inclusive or exclusive of the window frame
|
||||||
as returned by frameMargins(). You can detect this in the plugin by checking
|
as returned by frameMargins(). You can detect this in the plugin by checking
|
||||||
|
@ -278,7 +278,15 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState
|
|||||||
*/
|
*/
|
||||||
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect, const QRect &oldRect)
|
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect, const QRect &oldRect)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(window);
|
||||||
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, QHighDpi::fromNativePixels(newRect, window), QHighDpi::fromNativePixels(oldRect, window));
|
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, QHighDpi::fromNativePixels(newRect, window), QHighDpi::fromNativePixels(oldRect, window));
|
||||||
|
if (window->handle()) {
|
||||||
|
// Persist the new geometry so that QWindow::geometry() can be queried in the resize event
|
||||||
|
window->handle()->QPlatformWindow::setGeometry(newRect);
|
||||||
|
// FIXME: This does not work during platform window creation, where the QWindow does not
|
||||||
|
// have its handle set up yet. Platforms that deliver events during window creation need
|
||||||
|
// to handle the persistence manually, e.g. by overriding geometry().
|
||||||
|
}
|
||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,6 @@ void QAndroidPlatformWindow::raise()
|
|||||||
void QAndroidPlatformWindow::setGeometry(const QRect &rect)
|
void QAndroidPlatformWindow::setGeometry(const QRect &rect)
|
||||||
{
|
{
|
||||||
QWindowSystemInterface::handleGeometryChange(window(), rect);
|
QWindowSystemInterface::handleGeometryChange(window(), rect);
|
||||||
QPlatformWindow::setGeometry(rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAndroidPlatformWindow::setVisible(bool visible)
|
void QAndroidPlatformWindow::setVisible(bool visible)
|
||||||
|
@ -281,11 +281,11 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
|
|||||||
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setCocoaGeometry" << window() << rect;
|
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setCocoaGeometry" << window() << rect;
|
||||||
QMacAutoReleasePool pool;
|
QMacAutoReleasePool pool;
|
||||||
|
|
||||||
|
QPlatformWindow::setGeometry(rect);
|
||||||
|
|
||||||
if (m_viewIsEmbedded) {
|
if (m_viewIsEmbedded) {
|
||||||
if (!isForeignWindow()) {
|
if (!isForeignWindow()) {
|
||||||
[m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
|
[m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
|
||||||
} else {
|
|
||||||
QPlatformWindow::setGeometry(rect);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -297,9 +297,6 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
|
|||||||
[m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
|
[m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isForeignWindow())
|
|
||||||
QPlatformWindow::setGeometry(rect);
|
|
||||||
|
|
||||||
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
|
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,9 +294,6 @@ static QTouchDevice *touchDevice = 0;
|
|||||||
geometry = QRectF::fromCGRect(NSRectToCGRect([self frame])).toRect();
|
geometry = QRectF::fromCGRect(NSRectToCGRect([self frame])).toRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_platformWindow->isContentView() && geometry == m_platformWindow->geometry())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const bool isResize = geometry.size() != m_platformWindow->geometry().size();
|
const bool isResize = geometry.size() != m_platformWindow->geometry().size();
|
||||||
|
|
||||||
// It can happen that self.window is nil (if we are changing
|
// It can happen that self.window is nil (if we are changing
|
||||||
@ -308,11 +305,6 @@ static QTouchDevice *touchDevice = 0;
|
|||||||
qCDebug(lcQpaCocoaWindow) << "[QNSView udpateGeometry:]" << m_platformWindow->window()
|
qCDebug(lcQpaCocoaWindow) << "[QNSView udpateGeometry:]" << m_platformWindow->window()
|
||||||
<< "current" << m_platformWindow->geometry() << "new" << geometry;
|
<< "current" << m_platformWindow->geometry() << "new" << geometry;
|
||||||
|
|
||||||
// Call setGeometry on QPlatformWindow. (not on QCocoaWindow,
|
|
||||||
// doing that will initiate a geometry change it and possibly create
|
|
||||||
// an infinite loop when this notification is triggered again.)
|
|
||||||
m_platformWindow->QPlatformWindow::setGeometry(geometry);
|
|
||||||
|
|
||||||
// Don't send the geometry change if the QWindow is designated to be
|
// Don't send the geometry change if the QWindow is designated to be
|
||||||
// embedded in a foreign view hiearchy but has not actually been
|
// embedded in a foreign view hiearchy but has not actually been
|
||||||
// embedded yet - it's too early.
|
// embedded yet - it's too early.
|
||||||
|
@ -99,7 +99,6 @@ void QEglFSWindow::create()
|
|||||||
|
|
||||||
if (window()->type() == Qt::Desktop) {
|
if (window()->type() == Qt::Desktop) {
|
||||||
QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
|
QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
|
||||||
QPlatformWindow::setGeometry(fullscreenRect);
|
|
||||||
QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
|
QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,6 @@ void QHaikuWindow::haikuWindowMoved(const QPoint &pos)
|
|||||||
{
|
{
|
||||||
const QRect newGeometry(pos, geometry().size());
|
const QRect newGeometry(pos, geometry().size());
|
||||||
|
|
||||||
QPlatformWindow::setGeometry(newGeometry);
|
|
||||||
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
|
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
|
||||||
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
|
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
|
||||||
}
|
}
|
||||||
@ -318,7 +317,6 @@ void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress)
|
|||||||
{
|
{
|
||||||
const QRect newGeometry(geometry().topLeft(), size);
|
const QRect newGeometry(geometry().topLeft(), size);
|
||||||
|
|
||||||
QPlatformWindow::setGeometry(newGeometry);
|
|
||||||
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
|
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
|
||||||
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
|
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
|
||||||
|
|
||||||
|
@ -157,10 +157,6 @@
|
|||||||
|
|
||||||
QRect actualGeometry = QRectF::fromCGRect(self.frame).toRect();
|
QRect actualGeometry = QRectF::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 ?
|
QRect previousGeometry = requestedGeometry != actualGeometry ?
|
||||||
requestedGeometry : qt_window_private(m_qioswindow->window())->geometry;
|
requestedGeometry : qt_window_private(m_qioswindow->window())->geometry;
|
||||||
|
|
||||||
|
@ -516,7 +516,6 @@ UbuntuSurface::UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay displa
|
|||||||
|
|
||||||
// Assume that the buffer size matches the surface size at creation time
|
// Assume that the buffer size matches the surface size at creation time
|
||||||
mBufferSize = geom.size();
|
mBufferSize = geom.size();
|
||||||
platformWindow->QPlatformWindow::setGeometry(geom);
|
|
||||||
QWindowSystemInterface::handleGeometryChange(mWindow, geom);
|
QWindowSystemInterface::handleGeometryChange(mWindow, geom);
|
||||||
|
|
||||||
qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
|
qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
|
||||||
@ -636,7 +635,6 @@ void UbuntuSurface::onSwapBuffersDone()
|
|||||||
QRect newGeometry = mPlatformWindow->geometry();
|
QRect newGeometry = mPlatformWindow->geometry();
|
||||||
newGeometry.setSize(mBufferSize);
|
newGeometry.setSize(mBufferSize);
|
||||||
|
|
||||||
mPlatformWindow->QPlatformWindow::setGeometry(newGeometry);
|
|
||||||
QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
|
QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
|
qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
|
||||||
|
@ -1607,7 +1607,6 @@ void QWindowsWindow::handleGeometryChange()
|
|||||||
{
|
{
|
||||||
const QRect previousGeometry = m_data.geometry;
|
const QRect previousGeometry = m_data.geometry;
|
||||||
m_data.geometry = geometry_sys();
|
m_data.geometry = geometry_sys();
|
||||||
QPlatformWindow::setGeometry(m_data.geometry);
|
|
||||||
QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
|
QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
|
||||||
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
|
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
|
||||||
// expose events when shrinking, synthesize.
|
// expose events when shrinking, synthesize.
|
||||||
|
@ -2077,10 +2077,6 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
|
|||||||
if (!newScreen)
|
if (!newScreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Persist the actual geometry so that QWindow::geometry() can
|
|
||||||
// be queried in the resize event.
|
|
||||||
QPlatformWindow::setGeometry(actualGeometry);
|
|
||||||
|
|
||||||
// FIXME: In the case of the requestedGeometry not matching the actualGeometry due
|
// 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
|
// 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
|
// will never see a move/resize event if the actualGeometry is the same as the current
|
||||||
|
Loading…
Reference in New Issue
Block a user