From 46c9f4c212e374f957942f1d16d66f20b0a2949a Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 10 Aug 2011 15:36:51 +0200 Subject: Implement "quit on last window closed" logic for QWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ide33578ad60796f3e267b09be76cda87eaf873d0 Reviewed-on: http://codereview.qt.nokia.com/2827 Reviewed-by: Qt Sanity Bot Reviewed-by: Jørgen Lind --- src/gui/kernel/qguiapplication.cpp | 44 ++++++++++++++++++++++++++++++++++++++ src/gui/kernel/qguiapplication.h | 6 ++++++ src/gui/kernel/qguiapplication_p.h | 4 ++++ src/gui/kernel/qwindow.cpp | 32 +++++++++++++++++++++++++-- src/gui/kernel/qwindow_p.h | 4 ++++ 5 files changed, 88 insertions(+), 2 deletions(-) (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index f1edf52b0a..1bcbb3651b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -101,6 +101,8 @@ int QGuiApplicationPrivate::mousePressX = 0; int QGuiApplicationPrivate::mousePressY = 0; int QGuiApplicationPrivate::mouse_double_click_distance = 5; +bool QGuiApplicationPrivate::quitOnLastWindowClosed = true; + static Qt::LayoutDirection layout_direction = Qt::LeftToRight; static bool force_reverse = false; @@ -914,6 +916,48 @@ void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *) { } + +/*! + \property QGuiApplication::quitOnLastWindowClosed + + \brief whether the application implicitly quits when the last window is + closed. + + The default is true. + + If this property is true, the applications quits when the last visible + primary window (i.e. window with no parent) is closed. + + \sa quit(), QWindow::close() + */ + +void QGuiApplication::setQuitOnLastWindowClosed(bool quit) +{ + QGuiApplicationPrivate::quitOnLastWindowClosed = quit; +} + + + +bool QGuiApplication::quitOnLastWindowClosed() +{ + return QGuiApplicationPrivate::quitOnLastWindowClosed; +} + + + +void QGuiApplicationPrivate::emitLastWindowClosed() +{ + if (qGuiApp && qGuiApp->d_func()->in_exec) { + if (QGuiApplicationPrivate::quitOnLastWindowClosed) { + // get ready to quit, this event might be removed if the + // event loop is re-entered, however + QGuiApplication::postEvent(qApp, new QEvent(QEvent::Quit)); + } + emit qGuiApp->lastWindowClosed(); + } +} + + /*! \property QGuiApplication::layoutDirection \brief the default layout direction for this application diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 8338fa1f9a..871e314540 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -76,6 +76,8 @@ class Q_GUI_EXPORT QGuiApplication : public QCoreApplication Q_PROPERTY(int doubleClickInterval READ doubleClickInterval WRITE setDoubleClickInterval) Q_PROPERTY(int keyboardInputInterval READ keyboardInputInterval WRITE setKeyboardInputInterval) + Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed) + public: QGuiApplication(int &argc, char **argv, int = ApplicationFlags); virtual ~QGuiApplication(); @@ -123,12 +125,16 @@ public: static QPlatformNativeInterface *platformNativeInterface(); + static void setQuitOnLastWindowClosed(bool quit); + static bool quitOnLastWindowClosed(); + static int exec(); bool notify(QObject *, QEvent *); Q_SIGNALS: void fontDatabaseChanged(); void screenAdded(QScreen *screen); + void lastWindowClosed(); protected: bool event(QEvent *); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index fc6da6fd31..f7fa51208d 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -142,6 +142,8 @@ public: return alignment; } + static void emitLastWindowClosed(); + QPixmap getPixmapCursor(Qt::CursorShape cshape); static QGuiApplicationPrivate *instance() { return self; } @@ -170,6 +172,8 @@ public: static QList screen_list; static QFont *app_font; + + static bool quitOnLastWindowClosed; private: void init(); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 9eb011abb1..be96bebd0f 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -440,6 +440,7 @@ void QWindow::setWindowIcon(const QImage &icon) const void QWindow::destroy() { Q_D(QWindow); + setVisible(false); delete d->platformWindow; d->platformWindow = 0; } @@ -569,9 +570,13 @@ bool QWindow::event(QEvent *event) break; #endif - case QEvent::Close: + case QEvent::Close: { + Q_D(QWindow); + bool wasVisible = visible(); destroy(); - break; + if (wasVisible); + d->maybeQuitOnLastWindowClosed(); + break; } case QEvent::Expose: exposeEvent(static_cast(event)); @@ -630,4 +635,27 @@ Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window) return window->d_func(); } +void QWindowPrivate::maybeQuitOnLastWindowClosed() +{ + Q_Q(QWindow); + + // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent + bool quitOnClose = QGuiApplication::quitOnLastWindowClosed() && !q->parent(); + + if (quitOnClose) { + QWindowList list = QGuiApplication::topLevelWindows(); + bool lastWindowClosed = true; + for (int i = 0; i < list.size(); ++i) { + QWindow *w = list.at(i); + if (!w->visible() || w->parent()) + continue; + lastWindowClosed = false; + break; + } + if (lastWindowClosed) + QGuiApplicationPrivate::emitLastWindowClosed(); + } + +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 2016c42d7e..0a051ae965 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -56,6 +56,8 @@ QT_MODULE(Gui) class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate { + Q_DECLARE_PUBLIC(QWindow) + public: QWindowPrivate() : QObjectPrivate() @@ -77,6 +79,8 @@ public: { } + void maybeQuitOnLastWindowClosed(); + QWindow::SurfaceType surfaceType; Qt::WindowFlags windowFlags; QWindow *parentWindow; -- cgit v1.2.3