diff --git a/kdecore/kernel/kglobal.cpp b/kdecore/kernel/kglobal.cpp index a030aa8..2ce71a4 100644 --- a/kdecore/kernel/kglobal.cpp +++ b/kdecore/kernel/kglobal.cpp @@ -258,6 +258,7 @@ QString KGlobal::caption() * the job progress widget with "keep open" checked, etc. */ static int s_refCount = 0; +static bool s_allowQuit = false; void KGlobal::ref() { @@ -269,9 +270,14 @@ void KGlobal::deref() { --s_refCount; //kDebug() << "KGlobal::deref() : refCount = " << s_refCount; - if (s_refCount <= 0) { + if (s_refCount <= 0 && s_allowQuit) { QCoreApplication::instance()->quit(); } } +void KGlobal::setAllowQuit(bool allowQuit) +{ + s_allowQuit = allowQuit; +} + #undef PRIVATE_DATA diff --git a/kdecore/kernel/kglobal.h b/kdecore/kernel/kglobal.h index 0fee17b..d706741 100644 --- a/kdecore/kernel/kglobal.h +++ b/kdecore/kernel/kglobal.h @@ -409,6 +409,16 @@ namespace KGlobal * "last window closed" event, but some events should outlive the last window closed * (e.g. a file copy for a file manager, or 'compacting folders on exit' for a mail client). * + * We have some corner cases that we want to take care of (the format is "action refcount"): + * - open window -> setAllowQuit(true) 1 ; close window 0 => EXIT + * - job start 1; job end 0 [don't exit yet]; open window -> setAllowQuit(true) 1 ; close window 0 => EXIT + * - job start 1; open window -> setAllowQuit(true) 2; close window 1; job end 0 => EXIT + * - job start 1; open window -> setAllowQuit(true) 2; job end 1; close window 0 => EXIT + * - open dialog 0; close dialog 0; => DO NOT EXIT + * - job start 1; job end 0; create two main objects 2; delete both main objects 0 => EXIT + * - open window -> setAllowQuit(true) 1; add systray icon 2; close window 1 => DO NOT EXIT + * - open window -> setAllowQuit(true) 1; add systray icon 2; remove systray icon 1; close window 0 => EXIT + * * Note that for this to happen you must call qApp->setQuitOnLastWindowClosed(false), * in main() for instance. */ @@ -421,6 +431,13 @@ namespace KGlobal KDECORE_EXPORT void deref(); /** + * If refcounting reaches 0 (or less), and @p allowQuit is true, the instance of the application + * will automatically be exited. Otherwise, the application will not exit automatically. + * @since 4.2 + */ + KDECORE_EXPORT void setAllowQuit(bool allowQuit); + + /** * The component currently active (useful in a multi-component * application, such as a KParts application). * Don't use this - it's mainly for KAboutDialog and KBugReport. diff --git a/kdeui/widgets/kmainwindow.cpp b/kdeui/widgets/kmainwindow.cpp index 9b87c86..c4b1424 100644 --- a/kdeui/widgets/kmainwindow.cpp +++ b/kdeui/widgets/kmainwindow.cpp @@ -226,6 +226,11 @@ void KMainWindowPrivate::init(KMainWindow *_q) { KGlobal::ref(); + // We set allow quit to true, so when the refcounting reaches 0 the application instance will + // be exited. This has a similar purpose than setQuitOnLastWindowClosed (from + // QApplication), but it honors (de)refing from KGlobal. + KGlobal::setAllowQuit(true); + q = _q; q->setAnimated(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects);