summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-04-04 23:01:17 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2019-04-04 23:01:17 +0000
commited485243b594a730cebee4d76847e0f556d369f4 (patch)
tree545dd98a3138782df786f742cac02bc63113eaf6 /src/gui/kernel
parent8d7c97d428cdf89c3419a4e13b62a9849feefce9 (diff)
parenteb606d85b3f1548445cfd1fee43f882da88fb6e7 (diff)
Merge "Merge remote-tracking branch 'origin/5.13' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qplatformgraphicsbuffer.h2
-rw-r--r--src/gui/kernel/qplatformintegration.cpp81
-rw-r--r--src/gui/kernel/qplatformintegration.h6
-rw-r--r--src/gui/kernel/qplatformscreen.cpp3
-rw-r--r--src/gui/kernel/qplatformwindow.cpp7
-rw-r--r--src/gui/kernel/qscreen.cpp20
-rw-r--r--src/gui/kernel/qscreen.h1
-rw-r--r--src/gui/kernel/qwindow.cpp14
-rw-r--r--src/gui/kernel/qwindow_p.h10
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp61
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h4
11 files changed, 106 insertions, 103 deletions
diff --git a/src/gui/kernel/qplatformgraphicsbuffer.h b/src/gui/kernel/qplatformgraphicsbuffer.h
index 65c24bebc9..9004116ea4 100644
--- a/src/gui/kernel/qplatformgraphicsbuffer.h
+++ b/src/gui/kernel/qplatformgraphicsbuffer.h
@@ -71,12 +71,14 @@ public:
TextureAccess = 0x04,
HWCompositor = 0x08
};
+ Q_ENUM(AccessType);
Q_DECLARE_FLAGS(AccessTypes, AccessType);
enum Origin {
OriginBottomLeft,
OriginTopLeft
};
+ Q_ENUM(Origin);
~QPlatformGraphicsBuffer();
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 199ef0de07..490cfc6178 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -462,87 +462,6 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
return QList<int>();
}
-/*!
- Should be called by the implementation whenever a new screen is added.
-
- The first screen added will be the primary screen, used for default-created
- windows, GL contexts, and other resources unless otherwise specified.
-
- This adds the screen to QGuiApplication::screens(), and emits the
- QGuiApplication::screenAdded() signal.
-
- The screen should be deleted by calling QPlatformIntegration::destroyScreen().
-*/
-void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
-{
- QScreen *screen = new QScreen(ps);
-
- if (isPrimary) {
- QGuiApplicationPrivate::screen_list.prepend(screen);
- } else {
- QGuiApplicationPrivate::screen_list.append(screen);
- }
-
- QGuiApplicationPrivate::resetCachedDevicePixelRatio();
-
- emit qGuiApp->screenAdded(screen);
-
- if (isPrimary)
- emit qGuiApp->primaryScreenChanged(screen);
-}
-
-/*!
- Just removes the screen, call destroyScreen instead.
-
- \sa destroyScreen()
-*/
-
-void QPlatformIntegration::removeScreen(QScreen *screen)
-{
- const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list.at(0) == screen);
- QGuiApplicationPrivate::screen_list.removeOne(screen);
-
- QGuiApplicationPrivate::resetCachedDevicePixelRatio();
-
- if (wasPrimary && qGuiApp && !QGuiApplicationPrivate::screen_list.isEmpty())
- emit qGuiApp->primaryScreenChanged(QGuiApplicationPrivate::screen_list.at(0));
-}
-
-/*!
- Should be called by the implementation whenever a screen is removed.
-
- This removes the screen from QGuiApplication::screens(), and deletes it.
-
- Failing to call this and manually deleting the QPlatformScreen instead may
- lead to a crash due to a pure virtual call.
-*/
-void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
-{
- QScreen *qScreen = screen->screen();
- removeScreen(qScreen);
- delete qScreen;
- delete screen;
-}
-
-/*!
- Should be called whenever the primary screen changes.
-
- When the screen specified as primary changes, this method will notify
- QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
- */
-
-void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary)
-{
- QScreen* newPrimaryScreen = newPrimary->screen();
- int idx = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
- Q_ASSERT(idx >= 0);
- if (idx == 0)
- return;
-
- QGuiApplicationPrivate::screen_list.swapItemsAt(0, idx);
- emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
-}
-
QStringList QPlatformIntegration::themeNames() const
{
return QStringList();
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 8ece390420..b764bd2617 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -192,8 +192,6 @@ public:
#endif
virtual void setApplicationIcon(const QIcon &icon) const;
- void removeScreen(QScreen *screen);
-
virtual void beep() const;
#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
@@ -202,10 +200,6 @@ public:
protected:
QPlatformIntegration() = default;
-
- void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
- void destroyScreen(QPlatformScreen *screen);
- void setPrimaryScreen(QPlatformScreen *newPrimary);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index b7b312e89e..9c5876550a 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -61,8 +61,7 @@ QPlatformScreen::~QPlatformScreen()
{
Q_D(QPlatformScreen);
if (d->screen) {
- qWarning("Manually deleting a QPlatformScreen. Call QPlatformIntegration::destroyScreen instead.");
- QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
+ qWarning("Manually deleting a QPlatformScreen. Call QWindowSystemInterface::handleScreenRemoved instead.");
delete d->screen;
}
}
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index d6f90c9254..562289a8c9 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -708,10 +708,11 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QScreen *screen = effectiveScreen(w);
if (!screen)
return initialGeometry;
+ const auto *wp = qt_window_private(const_cast<QWindow*>(w));
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
- rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
- if (qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
- && w->type() != Qt::Popup) {
+ if (wp->resizeAutomatic)
+ rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
+ if (wp->positionAutomatic && w->type() != Qt::Popup) {
const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen).
if (rect.height() < (availableGeometry.height() * 8) / 9
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index f208eb02be..952023dd1b 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -106,9 +106,18 @@ void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
*/
QScreen::~QScreen()
{
- if (!qApp)
+ // Remove screen
+ const bool wasPrimary = QGuiApplication::primaryScreen() == this;
+ QGuiApplicationPrivate::screen_list.removeOne(this);
+ QGuiApplicationPrivate::resetCachedDevicePixelRatio();
+
+ if (!qGuiApp)
return;
+ QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
+ if (wasPrimary && newPrimaryScreen)
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+
// Allow clients to manage windows that are affected by the screen going
// away, before we fall back to moving them to the primary screen.
emit qApp->screenRemoved(this);
@@ -116,11 +125,8 @@ QScreen::~QScreen()
if (QGuiApplication::closingDown())
return;
- QScreen *primaryScreen = QGuiApplication::primaryScreen();
- if (this == primaryScreen)
- return;
-
- bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle());
+ bool movingFromVirtualSibling = newPrimaryScreen
+ && newPrimaryScreen->handle()->virtualSiblings().contains(handle());
// Move any leftover windows to the primary screen
const auto allWindows = QGuiApplication::allWindows();
@@ -129,7 +135,7 @@ QScreen::~QScreen()
continue;
const bool wasVisible = window->isVisible();
- window->setScreen(primaryScreen);
+ window->setScreen(newPrimaryScreen);
// Re-show window if moved from a virtual sibling screen. Otherwise
// leave it up to the application developer to show the window.
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index 8c9b16e08e..14392d3036 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -169,6 +169,7 @@ private:
friend class QPlatformIntegration;
friend class QPlatformScreen;
friend class QHighDpiScaling;
+ friend class QWindowSystemInterface;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 6e0c2de240..19a5d39ad5 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1922,9 +1922,6 @@ void QWindowPrivate::destroy()
resizeEventPending = true;
receivedExpose = false;
exposed = false;
-
- if (wasVisible)
- maybeQuitOnLastWindowClosed();
}
/*!
@@ -2313,8 +2310,17 @@ bool QWindow::event(QEvent *ev)
#endif
case QEvent::Close:
- if (ev->isAccepted())
+ if (ev->isAccepted()) {
+ Q_D(QWindow);
+ bool wasVisible = isVisible();
destroy();
+ if (wasVisible) {
+ // FIXME: This check for visibility is a workaround for both QWidgetWindow
+ // and QWindow having logic to emit lastWindowClosed, and possibly quit the
+ // application. We should find a better way to handle this.
+ d->maybeQuitOnLastWindowClosed();
+ }
+ }
break;
case QEvent::Expose:
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 1098321135..cc1cc24525 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -90,6 +90,7 @@ public:
, receivedExpose(false)
, positionPolicy(WindowFrameExclusive)
, positionAutomatic(true)
+ , resizeAutomatic(true)
, contentOrientation(Qt::PrimaryOrientation)
, opacity(qreal(1.0))
, minimumSize(0, 0)
@@ -156,11 +157,15 @@ public:
virtual void processSafeAreaMarginsChanged() {};
bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; }
+ void setAutomaticPositionAndResizeEnabled(bool a)
+ { positionAutomatic = resizeAutomatic = a; }
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
static Qt::WindowState effectiveState(Qt::WindowStates);
+ virtual bool allowClickThrough(const QPoint &) const { return true; }
+
QWindow::SurfaceType surfaceType;
Qt::WindowFlags windowFlags;
QWindow *parentWindow;
@@ -179,6 +184,11 @@ public:
bool receivedExpose;
PositionPolicy positionPolicy;
bool positionAutomatic;
+ // resizeAutomatic suppresses resizing by QPlatformWindow::initialGeometry().
+ // It also indicates that width/height=0 is acceptable (for example, for
+ // the QRollEffect widget) and is thus not cleared in setGeometry().
+ // An alternative approach might be using -1,-1 as a default size.
+ bool resizeAutomatic;
Qt::ScreenOrientation contentOrientation;
qreal opacity;
QRegion mask;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 8e6e3ce618..6f3edb10b4 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -780,6 +780,67 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleTouchCancelEvent, QWindow *window, ulong
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
+/*!
+ Should be called by the implementation whenever a new screen is added.
+
+ The first screen added will be the primary screen, used for default-created
+ windows, GL contexts, and other resources unless otherwise specified.
+
+ This adds the screen to QGuiApplication::screens(), and emits the
+ QGuiApplication::screenAdded() signal.
+
+ The screen should be deleted by calling QWindowSystemInterface::handleScreenRemoved().
+*/
+void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrimary)
+{
+ QScreen *screen = new QScreen(ps);
+
+ if (isPrimary)
+ QGuiApplicationPrivate::screen_list.prepend(screen);
+ else
+ QGuiApplicationPrivate::screen_list.append(screen);
+
+ QGuiApplicationPrivate::resetCachedDevicePixelRatio();
+
+ emit qGuiApp->screenAdded(screen);
+
+ if (isPrimary)
+ emit qGuiApp->primaryScreenChanged(screen);
+}
+
+/*!
+ Should be called by the implementation whenever a screen is removed.
+
+ This removes the screen from QGuiApplication::screens(), and deletes it.
+
+ Failing to call this and manually deleting the QPlatformScreen instead may
+ lead to a crash due to a pure virtual call.
+*/
+void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
+{
+ // Important to keep this order since the QSceen doesn't own the platform screen
+ delete platformScreen->screen();
+ delete platformScreen;
+}
+
+/*!
+ Should be called whenever the primary screen changes.
+
+ When the screen specified as primary changes, this method will notify
+ QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
+ */
+void QWindowSystemInterface::handlePrimaryScreenChanged(QPlatformScreen *newPrimary)
+{
+ QScreen *newPrimaryScreen = newPrimary->screen();
+ int indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
+ Q_ASSERT(indexOfScreen >= 0);
+ if (indexOfScreen == 0)
+ return;
+
+ QGuiApplicationPrivate::screen_list.swapItemsAt(0, indexOfScreen);
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+}
+
void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
{
QWindowSystemInterfacePrivate::ScreenOrientationEvent *e =
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 03b3bd16f0..fd70eda9ff 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -237,6 +237,10 @@ public:
#endif
// Changes to the screen
+ static void handleScreenAdded(QPlatformScreen *screen, bool isPrimary = false);
+ static void handleScreenRemoved(QPlatformScreen *screen);
+ static void handlePrimaryScreenChanged(QPlatformScreen *newPrimary);
+
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation);
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry);
static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY);