Skip to content

Commit

Permalink
Move screen maintenance functions from QPlatformIntegration to QWSI
Browse files Browse the repository at this point in the history
QWindowSystemInterface is the de facto API for any plumbing going from
the platform plugin to QtGui. Having the functions as protected members
of QPlatformIntegration was idiosyncratic, and resulted in awkward
workarounds to be able to call the functions from outside of the
QPlatformIntegration subclass.

The functions in QPlatformIntegration have been left in, but deprecated
so that platform plugins outside of qtbase have a chance to move over to
the new QWSI API before they are removed.

Change-Id: I327fec460db6b0faaf0ae2a151c20aa30dbe7182
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
  • Loading branch information
torarnv committed Mar 19, 2019
1 parent dc75337 commit 01e1df9
Show file tree
Hide file tree
Showing 38 changed files with 159 additions and 147 deletions.
58 changes: 9 additions & 49 deletions src/gui/kernel/qplatformintegration.cpp
Expand Up @@ -463,37 +463,16 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
}

/*!
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().
\deprecated Use QWindowSystemInterface::handleScreenAdded instead.
*/
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);
}
emit qGuiApp->screenAdded(screen);

if (isPrimary)
emit qGuiApp->primaryScreenChanged(screen);
QWindowSystemInterface::handleScreenAdded(ps, isPrimary);
}

/*!
Just removes the screen, call destroyScreen instead.
\sa destroyScreen()
\deprecated Use QWindowSystemInterface::handleScreenRemoved instead.
*/

void QPlatformIntegration::removeScreen(QScreen *screen)
{
const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list.at(0) == screen);
Expand All @@ -504,38 +483,19 @@ void QPlatformIntegration::removeScreen(QScreen *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.
\deprecated Use QWindowSystemInterface::handleScreenRemoved instead.
*/
void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
void QPlatformIntegration::destroyScreen(QPlatformScreen *platformScreen)
{
QScreen *qScreen = screen->screen();
removeScreen(qScreen);
delete qScreen;
delete screen;
QWindowSystemInterface::handleScreenRemoved(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.
*/

\deprecated Use QWindowSystemInterface::handlePrimaryScreenChanged instead.
*/
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.swap(0, idx);
emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
QWindowSystemInterface::handlePrimaryScreenChanged(newPrimary);
}

QStringList QPlatformIntegration::themeNames() const
Expand Down
12 changes: 8 additions & 4 deletions src/gui/kernel/qplatformintegration.h
Expand Up @@ -190,7 +190,9 @@ class Q_GUI_EXPORT QPlatformIntegration
#endif
virtual void setApplicationIcon(const QIcon &icon) const;

void removeScreen(QScreen *screen);
#if QT_DEPRECATED_SINCE(5, 12)
QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenRemoved") void removeScreen(QScreen *screen);
#endif

virtual void beep() const;

Expand All @@ -199,9 +201,11 @@ class Q_GUI_EXPORT QPlatformIntegration
#endif

protected:
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
void destroyScreen(QPlatformScreen *screen);
void setPrimaryScreen(QPlatformScreen *newPrimary);
#if QT_DEPRECATED_SINCE(5, 12)
QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenAdded") void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenRemoved") void destroyScreen(QPlatformScreen *screen);
QT_DEPRECATED_X("Use QWindowSystemInterface::handlePrimaryScreenChanged") void setPrimaryScreen(QPlatformScreen *newPrimary);
#endif
};

QT_END_NAMESPACE
Expand Down
5 changes: 4 additions & 1 deletion src/gui/kernel/qplatformscreen.cpp
Expand Up @@ -61,8 +61,11 @@ QPlatformScreen::~QPlatformScreen()
{
Q_D(QPlatformScreen);
if (d->screen) {
qWarning("Manually deleting a QPlatformScreen. Call QPlatformIntegration::destroyScreen instead.");
qWarning("Manually deleting a QPlatformScreen. Call QWindowSystemInterface::handleScreenRemoved instead.");
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
QT_WARNING_POP
delete d->screen;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/gui/kernel/qscreen.h
Expand Up @@ -169,6 +169,7 @@ class Q_GUI_EXPORT QScreen : public QObject
friend class QPlatformIntegration;
friend class QPlatformScreen;
friend class QHighDpiScaling;
friend class QWindowSystemInterface;
};

#ifndef QT_NO_DEBUG_STREAM
Expand Down
64 changes: 64 additions & 0 deletions src/gui/kernel/qwindowsysteminterface.cpp
Expand Up @@ -780,6 +780,70 @@ 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);

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)
{
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
QGuiApplicationPrivate::platformIntegration()->removeScreen(platformScreen->screen());
QT_WARNING_POP

// 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.swap(0, indexOfScreen);
emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
}

void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
{
QWindowSystemInterfacePrivate::ScreenOrientationEvent *e =
Expand Down
4 changes: 4 additions & 0 deletions src/gui/kernel/qwindowsysteminterface.h
Expand Up @@ -233,6 +233,10 @@ class Q_GUI_EXPORT QWindowSystemInterface
static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);

// 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);
Expand Down
Expand Up @@ -173,7 +173,7 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
qFatal("Could not bind GL_ES API");

m_primaryScreen = new QAndroidPlatformScreen();
screenAdded(m_primaryScreen);
QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
m_primaryScreen->setSize(QSize(m_defaultScreenWidth, m_defaultScreenHeight));
m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/platforms/bsdfb/qbsdfbintegration.cpp
Expand Up @@ -53,6 +53,7 @@
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatforminputcontext.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qwindowsysteminterface.h>

#if QT_CONFIG(tslib)
#include <QtInputSupport/private/qtslib_p.h>
Expand All @@ -69,13 +70,13 @@ QBsdFbIntegration::QBsdFbIntegration(const QStringList &paramList)

QBsdFbIntegration::~QBsdFbIntegration()
{
destroyScreen(m_primaryScreen.take());
QWindowSystemInterface::handleScreenRemoved(m_primaryScreen.take());
}

void QBsdFbIntegration::initialize()
{
if (m_primaryScreen->initialize())
screenAdded(m_primaryScreen.data());
QWindowSystemInterface::handleScreenAdded(m_primaryScreen.data());
else
qWarning("bsdfb: Failed to initialize screen");

Expand Down
6 changes: 3 additions & 3 deletions src/plugins/platforms/cocoa/qcocoaintegration.mm
Expand Up @@ -244,7 +244,7 @@ static void logVersionInformation()

// Delete screens in reverse order to avoid crash in case of multiple screens
while (!mScreens.isEmpty()) {
destroyScreen(mScreens.takeLast());
QWindowSystemInterface::handleScreenRemoved(mScreens.takeLast());
}

clearToolbars();
Expand Down Expand Up @@ -304,7 +304,7 @@ static void logVersionInformation()
screen = new QCocoaScreen(i);
mScreens.append(screen);
qCDebug(lcQpaScreen) << "Adding" << screen;
screenAdded(screen);
QWindowSystemInterface::handleScreenAdded(screen);
}
siblings << screen;
}
Expand All @@ -321,7 +321,7 @@ static void logVersionInformation()
// Prevent stale references to NSScreen during destroy
screen->m_screenIndex = -1;
qCDebug(lcQpaScreen) << "Removing" << screen;
destroyScreen(screen);
QWindowSystemInterface::handleScreenRemoved(screen);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/platforms/directfb/qdirectfb_egl.cpp
Expand Up @@ -44,6 +44,7 @@

#include <QtGui/QOpenGLContext>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QScreen>

#include <QtEglSupport/private/qeglplatformcontext_p.h>
Expand Down Expand Up @@ -248,7 +249,7 @@ QPlatformOpenGLContext *QDirectFbIntegrationEGL::createPlatformOpenGLContext(QOp
void QDirectFbIntegrationEGL::initializeScreen()
{
m_primaryScreen.reset(new QDirectFbScreenEGL(0));
screenAdded(m_primaryScreen.data());
QWindowSystemInterface::handleScreenAdded(m_primaryScreen.data());
}

bool QDirectFbIntegrationEGL::hasCapability(QPlatformIntegration::Capability cap) const
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/platforms/directfb/qdirectfbintegration.cpp
Expand Up @@ -56,6 +56,7 @@
#include <QtCore/QThread>
#include <QtCore/QAbstractEventDispatcher>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qwindowsysteminterface.h>

QT_BEGIN_NAMESPACE

Expand Down Expand Up @@ -113,7 +114,7 @@ void QDirectFbIntegration::initializeDirectFB()
void QDirectFbIntegration::initializeScreen()
{
m_primaryScreen.reset(new QDirectFbScreen(0));
screenAdded(m_primaryScreen.data());
QWindowSystemInterface::handleScreenAdded(m_primaryScreen.data());
}

void QDirectFbIntegration::initializeInput()
Expand Down
4 changes: 1 addition & 3 deletions src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
Expand Up @@ -200,10 +200,8 @@ void QEglFSDeviceIntegration::screenInit()
void QEglFSDeviceIntegration::screenDestroy()
{
QGuiApplication *app = qGuiApp;
QEglFSIntegration *platformIntegration = static_cast<QEglFSIntegration *>(
QGuiApplicationPrivate::platformIntegration());
while (!app->screens().isEmpty())
platformIntegration->removeScreen(app->screens().constLast()->handle());
QWindowSystemInterface::handleScreenRemoved(app->screens().constLast()->handle());
}

QSizeF QEglFSDeviceIntegration::physicalScreenSize() const
Expand Down
12 changes: 1 addition & 11 deletions src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
Expand Up @@ -120,16 +120,6 @@ QEglFSIntegration::QEglFSIntegration()
initResources();
}

void QEglFSIntegration::addScreen(QPlatformScreen *screen, bool isPrimary)
{
screenAdded(screen, isPrimary);
}

void QEglFSIntegration::removeScreen(QPlatformScreen *screen)
{
destroyScreen(screen);
}

void QEglFSIntegration::initialize()
{
qt_egl_device_integration()->platformInit();
Expand All @@ -147,7 +137,7 @@ void QEglFSIntegration::initialize()
m_vtHandler.reset(new QFbVtHandler);

if (qt_egl_device_integration()->usesDefaultScreen())
addScreen(new QEglFSScreen(display()));
QWindowSystemInterface::handleScreenAdded(new QEglFSScreen(display()));
else
qt_egl_device_integration()->screenInit();

Expand Down
3 changes: 0 additions & 3 deletions src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
Expand Up @@ -103,9 +103,6 @@ class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPl

QFbVtHandler *vtHandler() { return m_vtHandler.data(); }

void addScreen(QPlatformScreen *screen, bool isPrimary = false);
void removeScreen(QPlatformScreen *screen);

private:
EGLNativeDisplayType nativeDisplay() const;
void createInputHandlers();
Expand Down
Expand Up @@ -45,6 +45,8 @@
#include <QtEglSupport/private/qeglconvenience_p.h>
#include <QtEglSupport/private/qeglplatformcontext_p.h>

#include <qpa/qwindowsysteminterface.h>

#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonParseError>
Expand Down Expand Up @@ -80,8 +82,6 @@ bool QEglFSEmulatorIntegration::usesDefaultScreen()

void QEglFSEmulatorIntegration::screenInit()
{
QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());

// Use qgsGetDisplays() call to retrieve the available screens from the Emulator
if (getDisplays) {
QByteArray displaysInfo = getDisplays();
Expand All @@ -93,7 +93,7 @@ void QEglFSEmulatorIntegration::screenInit()
QJsonArray screenArray = displaysDocument.array();
for (auto screenValue : screenArray) {
if (screenValue.isObject())
integration->addScreen(new QEglFSEmulatorScreen(screenValue.toObject()));
QWindowSystemInterface::handleScreenAdded(new QEglFSEmulatorScreen(screenValue.toObject()));
}
}
} else {
Expand Down
Expand Up @@ -58,7 +58,7 @@ void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen,
QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen);
s->setVirtualPosition(virtualPos);
s->setVirtualSiblings(virtualSiblings);
static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->addScreen(s, isPrimary);
QWindowSystemInterface::handleScreenAdded(s, isPrimary);
}

QT_END_NAMESPACE

0 comments on commit 01e1df9

Please sign in to comment.