diff options
author | Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> | 2015-02-24 09:35:56 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> | 2015-02-27 06:02:44 +0000 |
commit | 175b12beba7bb4d1bf150c217afffc3d88801272 (patch) | |
tree | a81b924c20f9e911778f7334b2f6b76fb1a70600 | |
parent | 4e966497ce3674286f38faab68679201ec6ca22e (diff) |
Prevent static functions of Q[Gui]Application from crashing if there is no instance.
Add tests.
Task-number: QTBUG-44499
Change-Id: I160b089ad3f23ab71a87519e50f8a2ef5d2a4a6f
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 15 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 10 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp | 38 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp | 24 |
4 files changed, 87 insertions, 0 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index d334bb72fa..b60ef4b8c1 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -105,6 +105,14 @@ QT_BEGIN_NAMESPACE +// Helper macro for static functions to check on the existence of the application class. +#define CHECK_QAPP_INSTANCE(...) \ + if (Q_LIKELY(QCoreApplication::instance())) { \ + } else { \ + qWarning("Must construct a QGuiApplication first."); \ + return __VA_ARGS__; \ + } + Q_GUI_EXPORT bool qt_is_gui_used = true; Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton; @@ -648,6 +656,7 @@ QString QGuiApplication::applicationDisplayName() */ QWindow *QGuiApplication::modalWindow() { + CHECK_QAPP_INSTANCE(Q_NULLPTR) if (QGuiApplicationPrivate::self->modalWindowList.isEmpty()) return 0; return QGuiApplicationPrivate::self->modalWindowList.first(); @@ -1430,6 +1439,7 @@ Qt::KeyboardModifiers QGuiApplication::keyboardModifiers() */ Qt::KeyboardModifiers QGuiApplication::queryKeyboardModifiers() { + CHECK_QAPP_INSTANCE(Qt::KeyboardModifiers(0)) QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); return pi->queryKeyboardModifiers(); } @@ -3167,6 +3177,7 @@ Qt::LayoutDirection QGuiApplication::layoutDirection() #ifndef QT_NO_CURSOR QCursor *QGuiApplication::overrideCursor() { + CHECK_QAPP_INSTANCE(Q_NULLPTR) return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first(); } @@ -3180,6 +3191,7 @@ QCursor *QGuiApplication::overrideCursor() */ void QGuiApplication::changeOverrideCursor(const QCursor &cursor) { + CHECK_QAPP_INSTANCE() if (qGuiApp->d_func()->cursor_list.isEmpty()) return; qGuiApp->d_func()->cursor_list.removeFirst(); @@ -3254,6 +3266,7 @@ static inline void applyWindowCursor(const QList<QWindow *> &l) */ void QGuiApplication::setOverrideCursor(const QCursor &cursor) { + CHECK_QAPP_INSTANCE() qGuiApp->d_func()->cursor_list.prepend(cursor); applyCursor(QGuiApplicationPrivate::window_list, cursor); } @@ -3271,6 +3284,7 @@ void QGuiApplication::setOverrideCursor(const QCursor &cursor) */ void QGuiApplication::restoreOverrideCursor() { + CHECK_QAPP_INSTANCE() if (qGuiApp->d_func()->cursor_list.isEmpty()) return; qGuiApp->d_func()->cursor_list.removeFirst(); @@ -3338,6 +3352,7 @@ bool QGuiApplication::desktopSettingsAware() */ QInputMethod *QGuiApplication::inputMethod() { + CHECK_QAPP_INSTANCE(Q_NULLPTR) if (!qGuiApp->d_func()->inputMethod) qGuiApp->d_func()->inputMethod = new QInputMethod(); return qGuiApp->d_func()->inputMethod; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index e761520228..78c842f7e1 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -117,6 +117,14 @@ static void initResources() QT_BEGIN_NAMESPACE +// Helper macro for static functions to check on the existence of the application class. +#define CHECK_QAPP_INSTANCE(...) \ + if (Q_LIKELY(QCoreApplication::instance())) { \ + } else { \ + qWarning("Must construct a QApplication first."); \ + return __VA_ARGS__; \ + } + Q_CORE_EXPORT void qt_call_post_routines(); QApplicationPrivate *QApplicationPrivate::self = 0; @@ -2855,6 +2863,7 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget) */ QDesktopWidget *QApplication::desktop() { + CHECK_QAPP_INSTANCE(Q_NULLPTR) if (!qt_desktopWidget || // not created yet !(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away qt_desktopWidget = new QDesktopWidget(); @@ -4110,6 +4119,7 @@ void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) */ bool QApplication::isEffectEnabled(Qt::UIEffect effect) { + CHECK_QAPP_INSTANCE(false) return QColormap::instance().depth() >= 16 && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect) && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect)); diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 3cf7803cfb..b921e1519f 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -77,6 +77,8 @@ private slots: void layoutDirection(); void globalShareContext(); + void staticFunctions(); + void settableStyleHints_data(); void settableStyleHints(); // Needs to run last as it changes style hints. }; @@ -966,6 +968,42 @@ void tst_QGuiApplication::globalShareContext() #endif } +// Test that static functions do not crash if there is no application instance. +void tst_QGuiApplication::staticFunctions() +{ + QGuiApplication::setApplicationDisplayName(QString()); + QGuiApplication::applicationDisplayName(); + QGuiApplication::allWindows(); + QGuiApplication::topLevelWindows(); + QGuiApplication::topLevelAt(QPoint(0, 0)); + QGuiApplication::setWindowIcon(QIcon()); + QGuiApplication::windowIcon(); + QGuiApplication::platformName(); + QGuiApplication::modalWindow(); + QGuiApplication::focusWindow(); + QGuiApplication::focusObject(); + QGuiApplication::primaryScreen(); + QGuiApplication::screens(); + QGuiApplication::overrideCursor(); + QGuiApplication::setOverrideCursor(QCursor()); + QGuiApplication::changeOverrideCursor(QCursor()); + QGuiApplication::restoreOverrideCursor(); + QGuiApplication::keyboardModifiers(); + QGuiApplication::queryKeyboardModifiers(); + QGuiApplication::mouseButtons(); + QGuiApplication::setLayoutDirection(Qt::LeftToRight); + QGuiApplication::layoutDirection(); + QGuiApplication::styleHints(); + QGuiApplication::setDesktopSettingsAware(true); + QGuiApplication::desktopSettingsAware(); + QGuiApplication::inputMethod(); + QGuiApplication::platformNativeInterface(); + QGuiApplication::platformFunction(QByteArrayLiteral("bla")); + QGuiApplication::setQuitOnLastWindowClosed(true); + QGuiApplication::quitOnLastWindowClosed(); + QGuiApplication::applicationState(); +} + void tst_QGuiApplication::settableStyleHints_data() { QTest::addColumn<bool>("appInstance"); diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index bab3337c0c..c3e8b51ccd 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -172,6 +172,8 @@ private slots: void abortQuitOnShow(); + void staticFunctions(); + void settableStyleHints_data(); void settableStyleHints(); // Needs to run last as it changes style hints. }; @@ -2299,6 +2301,28 @@ void tst_QApplication::abortQuitOnShow() QCOMPARE(app.exec(), 1); } +// Test that static functions do not crash if there is no application instance. +void tst_QApplication::staticFunctions() +{ + QApplication::setStyle(QStringLiteral("blub")); + QApplication::colorSpec(); + QApplication::setColorSpec(42); + QApplication::allWidgets(); + QApplication::topLevelWidgets(); + QApplication::desktop(); + QApplication::activePopupWidget(); + QApplication::activeModalWidget(); + QApplication::focusWidget(); + QApplication::activeWindow(); + QApplication::setActiveWindow(Q_NULLPTR); + QApplication::widgetAt(QPoint(0, 0)); + QApplication::topLevelAt(QPoint(0, 0)); + QApplication::setGlobalStrut(QSize(0, 0)); + QApplication::globalStrut(); + QApplication::isEffectEnabled(Qt::UI_General); + QApplication::setEffectEnabled(Qt::UI_General, false); +} + void tst_QApplication::settableStyleHints_data() { QTest::addColumn<bool>("appInstance"); |