From 0e0db0b8150e161c7cafb7e68991f4c120ca2617 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Thu, 9 May 2024 00:55:08 +0300 Subject: [PATCH] kdeui: move session management to KApplicaiton every comment about X11 and session management in general claims it was broken, not going to claim otherwise. everything that does not use KApplication shall not be involved into session management now and gets the middle finger (SIGTERM or SIGKILL) after 5 sec by klauncher when the session is done also session management has to be explicitly enabled by applications now, disabled by default Signed-off-by: Ivailo Monev --- includes/CMakeLists.txt | 1 - includes/KSessionManager | 1 - kdecore/kernel/kcmdlineargs.cpp | 3 +- kded/kded.cpp | 5 - kdeui/CMakeLists.txt | 13 +- .../kaboutapplicationpersonlistdelegate_p.cpp | 4 +- kdeui/dialogs/kdialog.cpp | 2 +- kdeui/kernel/kapplication.cpp | 282 +++++--------- kdeui/kernel/kapplication.h | 55 +-- kdeui/kernel/kapplication_adaptor.cpp | 71 ++++ kdeui/kernel/kapplication_adaptor.h | 48 +++ kdeui/kernel/ksessionmanager.cpp | 50 --- kdeui/kernel/ksessionmanager.h | 78 ---- kdeui/kernel/ktoolinvocation.cpp | 75 ++-- kdeui/kernel/ktoolinvocation.h | 365 ++++++++---------- kdeui/widgets/khelpmenu.cpp | 4 +- kdeui/widgets/kmainwindow.cpp | 83 +--- kdeui/widgets/kmainwindow.h | 2 +- kdeui/xmlgui/kxmlguiwindow.cpp | 1 - kinit/kioslave.cpp | 1 - kinit/klauncher.cpp | 20 - kinit/klauncher.h | 2 - kinit/klauncher_adaptor.h | 4 +- kio/kio/krun.cpp | 4 +- kio/misc/kmailservice.cpp | 2 +- kio/misc/ktelnetservice.cpp | 2 +- kutils/kcmultidialog.cpp | 2 +- 27 files changed, 469 insertions(+), 711 deletions(-) delete mode 100644 includes/KSessionManager create mode 100644 kdeui/kernel/kapplication_adaptor.cpp create mode 100644 kdeui/kernel/kapplication_adaptor.h delete mode 100644 kdeui/kernel/ksessionmanager.cpp delete mode 100644 kdeui/kernel/ksessionmanager.h diff --git a/includes/CMakeLists.txt b/includes/CMakeLists.txt index f20467ec..5ba97580 100644 --- a/includes/CMakeLists.txt +++ b/includes/CMakeLists.txt @@ -213,7 +213,6 @@ install( KServiceGroup KServiceType KServiceTypeTrader - KSessionManager KSharedConfig KSharedPtr KShell diff --git a/includes/KSessionManager b/includes/KSessionManager deleted file mode 100644 index 8f58d06b..00000000 --- a/includes/KSessionManager +++ /dev/null @@ -1 +0,0 @@ -#include "../ksessionmanager.h" diff --git a/kdecore/kernel/kcmdlineargs.cpp b/kdecore/kernel/kcmdlineargs.cpp index 50cb1504..6f6d57a9 100644 --- a/kdecore/kernel/kcmdlineargs.cpp +++ b/kdecore/kernel/kcmdlineargs.cpp @@ -262,7 +262,6 @@ KCmdLineArgsStatic::KCmdLineArgsStatic () { #ifdef Q_WS_X11 qt_options.add("display ", ki18n("Use the X-server display 'displayname'")); #endif - qt_options.add("session ", ki18n("Restore the application for the given 'sessionId'")); qt_options.add("nograb", ki18n("tells Katie to never grab the mouse or the keyboard")); qt_options.add("dograb", ki18n("running under a debugger can cause an implicit\n-nograb, use -dograb to override")); qt_options.add("sync", ki18n("switches to synchronous mode for debugging")); @@ -278,7 +277,7 @@ KCmdLineArgsStatic::KCmdLineArgsStatic () { kde_options.add("waitforwm", ki18n("Waits for a WM_NET compatible windowmanager")); #endif kde_options.add("geometry ", ki18n("sets the client geometry of the main widget - see man X for the argument format (usually WidthxHeight+XPos+YPos)")); - kde_options.add("smkey "); // this option is obsolete and exists only to allow smooth upgrades from sessions + kde_options.add("session ", ki18n("Restore the application for the given 'sessionId'")); kde_options.add("debugger", ki18n("Show debugger")); } diff --git a/kded/kded.cpp b/kded/kded.cpp index 8bb1c309..202b0a41 100644 --- a/kded/kded.cpp +++ b/kded/kded.cpp @@ -521,13 +521,8 @@ int main(int argc, char *argv[]) KComponentData componentData(&aboutData); KSharedConfig::Ptr config = componentData.config(); // Enable translations. - // NOTE: disables session manager entirely, for reference: - // https://www.x.org/releases/X11R7.7/doc/libSM/xsmp.html - ::unsetenv("SESSION_MANAGER"); - KApplication app; app.setQuitOnLastWindowClosed(false); - app.disableSessionManagement(); QDBusConnection session = QDBusConnection::sessionBus(); if (!session.isConnected()) { diff --git a/kdeui/CMakeLists.txt b/kdeui/CMakeLists.txt index c03cfcb2..1017446f 100644 --- a/kdeui/CMakeLists.txt +++ b/kdeui/CMakeLists.txt @@ -128,7 +128,6 @@ set(kdeui_LIB_SRCS jobs/kdynamicjobtracker.cpp kernel/kapplication.cpp kernel/kuniqueapplication.cpp - kernel/ksessionmanager.cpp kernel/kstyle.cpp kernel/kstartupinfo.cpp kernel/kglobalsettings.cpp @@ -219,6 +218,9 @@ set(kdeui_LIB_SRCS windowmanagement/kwindowsystem_x11.cpp windowmanagement/kwindowinfo_x11.cpp windowmanagement/netwm.cpp + kernel/kapplication_adaptor.cpp + # just so that it gets generated + ${CMAKE_CURRENT_BINARY_DIR}/org.kde.KApplication.xml ) if (X11_Xkb_FOUND AND X11_Xkbfile_FOUND) @@ -233,6 +235,8 @@ if (X11_Xkb_FOUND AND X11_Xkbfile_FOUND) ) endif() +qt4_generate_dbus_interface(kernel/kapplication_adaptor.h org.kde.KApplication.xml) + set_source_files_properties( ${CMAKE_SOURCE_DIR}/kdeui/kernel/kapplication.cpp ${CMAKE_SOURCE_DIR}/kdeui/kernel/kglobalsettings.cpp @@ -373,7 +377,6 @@ install( jobs/kdynamicjobtracker.h kernel/kapplication.h kernel/kuniqueapplication.h - kernel/ksessionmanager.h kernel/kstyle.h kernel/kstartupinfo.h kernel/kglobalsettings.h @@ -460,7 +463,6 @@ install( DESTINATION ${KDE4_INCLUDE_INSTALL_DIR} ) -# KDE 5 remove this install( FILES widgets/kratingpainter.h @@ -472,3 +474,8 @@ install( PROGRAMS preparetips DESTINATION ${KDE4_BIN_INSTALL_DIR} ) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.KApplication.xml + DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR} +) diff --git a/kdeui/dialogs/kaboutapplicationpersonlistdelegate_p.cpp b/kdeui/dialogs/kaboutapplicationpersonlistdelegate_p.cpp index 60dfc979..b76ad7cd 100644 --- a/kdeui/dialogs/kaboutapplicationpersonlistdelegate_p.cpp +++ b/kdeui/dialogs/kaboutapplicationpersonlistdelegate_p.cpp @@ -141,9 +141,9 @@ void KAboutApplicationPersonListDelegate::launchUrl( QAction *action ) const QString url = action->data().toString(); if( !url.isEmpty() ) { if( url.startsWith( "mailto:" ) ) - KToolInvocation::invokeMailer( KUrl( url ) ); + KToolInvocation::self()->invokeMailer( KUrl( url ) ); else - KToolInvocation::invokeBrowser( url ); + KToolInvocation::self()->invokeBrowser( url ); } } diff --git a/kdeui/dialogs/kdialog.cpp b/kdeui/dialogs/kdialog.cpp index c6aadba4..6ef070e2 100644 --- a/kdeui/dialogs/kdialog.cpp +++ b/kdeui/dialogs/kdialog.cpp @@ -929,7 +929,7 @@ void KDialog::slotButtonClicked(int button) case KDialog::Help: { emit helpClicked(); if (!d->mAnchor.isEmpty() || !d->mHelpApp.isEmpty()) { - KToolInvocation::invokeHelp( d->mAnchor, d->mHelpApp); + KToolInvocation::self()->invokeHelp( d->mAnchor, d->mHelpApp); } break; } diff --git a/kdeui/kernel/kapplication.cpp b/kdeui/kernel/kapplication.cpp index 54d4b25a..7f1e408c 100644 --- a/kdeui/kernel/kapplication.cpp +++ b/kdeui/kernel/kapplication.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,6 @@ #include "kicon.h" #include "kiconloader.h" #include "klocale.h" -#include "ksessionmanager.h" #include "kstandarddirs.h" #include "kstandardshortcut.h" #include "kurl.h" @@ -59,6 +57,7 @@ #include "kconfiggroup.h" #include "kactioncollection.h" #include "kdebugger.h" +#include "kapplication_adaptor.h" #include #include @@ -114,58 +113,78 @@ static void quit_handler(int sig) qApp->quit(); } +static void kRegisterSessionClient(const bool enable, const QString &serviceName) +{ + if (serviceName.isEmpty()) { + return; + } + QDBusInterface sessionManager( + "org.kde.plasma-desktop", "/App", "local.PlasmaApp", + QDBusConnection::sessionBus() + ); + if (sessionManager.isValid()) { + sessionManager.call(enable ? "registerClient" : "unregisterClient", serviceName); + } else { + kWarning() << "org.kde.plasma-desktop is not valid interface"; + } +} + /* - Private data to make keeping binary compatibility easier + Private data */ class KApplicationPrivate { public: KApplicationPrivate(KApplication* q, const QByteArray &cName) : q(q) + , adaptor(nullptr) , componentData(cName) , startup_id("0") , app_started_timer(nullptr) , session_save(false) , pSessionConfig(nullptr) - , bSessionManagement(true) + , bSessionManagement(false) , debugger(nullptr) { } KApplicationPrivate(KApplication* q, const KComponentData &cData) : q(q) + , adaptor(nullptr) , componentData(cData) , startup_id("0") , app_started_timer(nullptr) , session_save(false) , pSessionConfig(nullptr) - , bSessionManagement(true) + , bSessionManagement(false) , debugger(nullptr) { } KApplicationPrivate(KApplication *q) : q(q) + , adaptor(nullptr) , componentData(KCmdLineArgs::aboutData()) , startup_id("0") , app_started_timer(nullptr) , session_save(false) , pSessionConfig(nullptr) - , bSessionManagement(true) + , bSessionManagement(false) , debugger(nullptr) { } void _k_x11FilterDestroyed(); void _k_checkAppStartedSlot(); - void _k_disableAutorestartSlot(); + void _k_aboutToQuitSlot(); - QString sessionConfigName() const; void init(); void parseCommandLine( ); // Handle KDE arguments (Using KCmdLineArgs) KApplication *q; + KApplicationAdaptor* adaptor; + QString serviceName; KComponentData componentData; QByteArray startup_id; QTimer* app_started_timer; @@ -271,29 +290,6 @@ void KApplicationPrivate::_k_checkAppStartedSlot() } } -/* - Auxiliary function to calculate a a session config name used for the - instance specific config object. - Syntax: "session/_" - */ -QString KApplicationPrivate::sessionConfigName() const -{ -#ifdef QT_NO_SESSIONMANAGER -#error QT_NO_SESSIONMANAGER was set, this will not compile. Reconfigure Qt with Session management support. -#endif - QString sessKey = q->sessionKey(); - if ( sessKey.isEmpty() && !sessionKey.isEmpty() ) - sessKey = sessionKey; - return QString::fromLatin1("session/%1_%2_%3").arg(QCoreApplication::applicationName()).arg(q->sessionId()).arg(sessKey); -} - -#ifdef Q_WS_X11 -static SmcConn mySmcConnection = 0; -#else -// FIXME(E): Implement for Qt Embedded -// Possibly "steal" XFree86's libSM? -#endif - KApplication::KApplication() : QApplication(KCmdLineArgs::qtArgc(), KCmdLineArgs::qtArgv()), d(new KApplicationPrivate(this)) @@ -398,12 +394,13 @@ void KApplicationPrivate::init() reversedDomain.prepend(s); } const QString pidSuffix = QString::number( getpid() ).prepend( QLatin1String("-") ); - const QString serviceName = reversedDomain + QCoreApplication::applicationName() + pidSuffix; + serviceName = reversedDomain + QCoreApplication::applicationName() + pidSuffix; if ( bus->registerService(serviceName) == QDBusConnectionInterface::ServiceNotRegistered ) { kError() << "Couldn't register name '" << serviceName << "' with DBUS - another process owns it already!"; ::exit(126); } } + adaptor = new KApplicationAdaptor(q); sessionBus.registerObject(QLatin1String("/MainApplication"), q, QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportScriptableProperties | @@ -434,7 +431,7 @@ void KApplicationPrivate::init() // too late to restart if the application is about to quit (e.g. if QApplication::quit() was // called or SIGTERM was received) - q->connect(q, SIGNAL(aboutToQuit()), SLOT(_k_disableAutorestartSlot())); + q->connect(q, SIGNAL(aboutToQuit()), SLOT(_k_aboutToQuitSlot())); KApplication::quitOnSignal(); KApplication::quitOnDisconnected(); @@ -450,11 +447,63 @@ KApplication* KApplication::kApplication() KConfig* KApplication::sessionConfig() { - if (!d->pSessionConfig) // create an instance specific config object - d->pSessionConfig = new KConfig( d->sessionConfigName(), KConfig::SimpleConfig ); + if (!d->pSessionConfig) { + // create an instance specific config object + QString configName = d->sessionKey; + if (configName.isEmpty()) { + configName = QString::fromLatin1("%1_%2").arg(QCoreApplication::applicationName()).arg(QCoreApplication::applicationPid()); + } + d->pSessionConfig = new KConfig( + QString::fromLatin1("session/%1").arg(configName), + KConfig::SimpleConfig + ); + } return d->pSessionConfig; } +bool KApplication::saveSession() +{ + foreach (KMainWindow *window, KMainWindow::memberList()) { + if (!window->testAttribute(Qt::WA_WState_Hidden)) { + QCloseEvent e; + QApplication::sendEvent(window, &e); + if (!e.isAccepted()) { + return false; + } + } + } + foreach (QWidget* widget, QApplication::topLevelWidgets()) { + if (!widget || widget->isHidden() || widget->inherits("QMainWindow")) { + continue; + } + QCloseEvent e; + QApplication::sendEvent(widget, &e); + if (!e.isAccepted()) { + return false; + } + } + + d->session_save = true; + KConfig* config = KApplication::kApplication()->sessionConfig(); + if ( KMainWindow::memberList().count() ){ + // According to Jochen Wilhelmy , this + // hook is useful for better document orientation + KMainWindow::memberList().first()->saveGlobalProperties(config); + } + int n = 0; + foreach (KMainWindow* mw, KMainWindow::memberList()) { + n++; + mw->savePropertiesInternal(config, n); + } + KConfigGroup group( config, "Number" ); + group.writeEntry("NumberOfWindows", n ); + if ( d->pSessionConfig ) { + d->pSessionConfig->sync(); + } + d->session_save = false; + return true; +} + void KApplication::reparseConfiguration() { KGlobal::config()->reparseConfiguration(); @@ -465,133 +514,18 @@ void KApplication::quit() QApplication::quit(); } -void KApplication::disableSessionManagement() { - d->bSessionManagement = false; -} - -void KApplication::enableSessionManagement() { - d->bSessionManagement = true; -#ifdef Q_WS_X11 - // Session management support in Qt/KDE is awfully broken. - // If konqueror disables session management right after its startup, - // and enables it later (preloading stuff), it won't be properly - // saved on session shutdown. - // I'm not actually sure why it doesn't work, but saveState() - // doesn't seem to be called on session shutdown, possibly - // because disabling session management after konqueror startup - // disabled it somehow. Forcing saveState() here for this application - // seems to fix it. - if( mySmcConnection ) { - SmcRequestSaveYourself( mySmcConnection, SmSaveLocal, False, - SmInteractStyleAny, - False, False ); - - // flush the request - IceFlush(SmcGetIceConnection(mySmcConnection)); - } -#endif -} - -void KApplication::commitData( QSessionManager& sm ) +void KApplication::disableSessionManagement() { - d->session_save = true; - bool canceled = false; - - foreach (KSessionManager *it, KSessionManager::sessionClients()) { - if ( ( canceled = !it->commitData( sm ) ) ) - break; + if (d->bSessionManagement) { + kRegisterSessionClient(false, d->serviceName); } - - if ( canceled ) - sm.cancel(); - - if ( sm.allowsInteraction() ) { - QWidgetList donelist, todolist; - QWidget* w; - -commitDataRestart: - todolist = QApplication::topLevelWidgets(); - - for ( int i = 0; i < todolist.size(); ++i ) { - w = todolist.at( i ); - if( !w ) - break; - - if ( donelist.contains( w ) ) - continue; - - if ( !w->isHidden() && !w->inherits( "KMainWindow" ) ) { - QCloseEvent e; - sendEvent( w, &e ); - if ( !e.isAccepted() ) - break; //canceled - - donelist.append( w ); - - //grab the new list that was just modified by our closeevent - goto commitDataRestart; - } - } - } - - if ( !d->bSessionManagement ) - sm.setRestartHint( QSessionManager::RestartNever ); - else - sm.setRestartHint( QSessionManager::RestartIfRunning ); - d->session_save = false; + d->bSessionManagement = false; } -void KApplication::saveState( QSessionManager& sm ) +void KApplication::enableSessionManagement() { - d->session_save = true; -#ifdef Q_WS_X11 - static bool firstTime = true; - mySmcConnection = (SmcConn) sm.handle(); - - if ( !d->bSessionManagement ) { - sm.setRestartHint( QSessionManager::RestartNever ); - d->session_save = false; - return; - } else { - sm.setRestartHint( QSessionManager::RestartIfRunning ); - } - - if ( firstTime ) { - firstTime = false; - d->session_save = false; - return; // no need to save the state. - } - - // remove former session config if still existing, we want a new - // and fresh one. Note that we do not delete the config file here, - // this is done by the session manager when it executes the - // discard commands. In fact it would be harmful to remove the - // file here, as the session might be stored under a different - // name, meaning the user still might need it eventually. - delete d->pSessionConfig; - d->pSessionConfig = 0; - - // finally: do session management - bool canceled = false; - foreach(KSessionManager* it, KSessionManager::sessionClients()) { - if(canceled) break; - canceled = !it->saveState( sm ); - } - - // if we created a new session config object, register a proper discard command - if ( d->pSessionConfig ) { - d->pSessionConfig->sync(); - QStringList discard; - discard << QLatin1String("rm") << KStandardDirs::locateLocal("config", d->sessionConfigName()); - sm.setDiscardCommand( discard ); - } else { - sm.setDiscardCommand( QStringList( QLatin1String("") ) ); - } - - if ( canceled ) - sm.cancel(); -#endif - d->session_save = false; + kRegisterSessionClient(true, d->serviceName); + d->bSessionManagement = true; } bool KApplication::sessionSaving() const @@ -599,6 +533,11 @@ bool KApplication::sessionSaving() const return d->session_save; } +bool KApplication::isSessionRestored() const +{ + return !d->sessionKey.isEmpty(); +} + void KApplicationPrivate::parseCommandLine( ) { KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); @@ -655,8 +594,8 @@ void KApplicationPrivate::parseCommandLine( ) } #endif - if (args->isSet("smkey")) { - sessionKey = args->getOption("smkey"); + if (args->isSet("session")) { + sessionKey = args->getOption("session"); } if (args->isSet("debugger")) { @@ -671,12 +610,12 @@ KApplication::~KApplication() delete d->debugger; } + if (d->pSessionConfig) { + delete d->pSessionConfig; + } + delete d; KApp = 0; - -#ifdef Q_WS_X11 - mySmcConnection = 0; -#endif } @@ -740,18 +679,6 @@ unsigned long KApplication::userTimestamp() const #endif } -void KApplication::updateRemoteUserTimestamp( const QString& service, int time ) -{ -#if defined Q_WS_X11 - Q_ASSERT(service.contains('.')); - if( time == 0 ) - time = QX11Info::appUserTime(); - QDBusInterface(service, QLatin1String("/MainApplication"), - QString(QLatin1String("org.kde.KApplication"))) - .call(QLatin1String("updateUserTimestamp"), time); -#endif -} - void KApplication::quitOnSignal() { sigset_t handlermask; @@ -829,9 +756,12 @@ void KApplication::clearStartupId() d->startup_id = "0"; } -void KApplicationPrivate::_k_disableAutorestartSlot() +void KApplicationPrivate::_k_aboutToQuitSlot() { KCrash::setFlags(KCrash::flags() & ~KCrash::AutoRestart); + if (bSessionManagement) { + kRegisterSessionClient(false, serviceName); + } } #include "moc_kapplication.cpp" diff --git a/kdeui/kernel/kapplication.h b/kdeui/kernel/kapplication.h index a33ffd71..c00c3c80 100644 --- a/kdeui/kernel/kapplication.h +++ b/kdeui/kernel/kapplication.h @@ -63,7 +63,6 @@ class KApplicationPrivate; class KDEUI_EXPORT KApplication : public QApplication { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.KApplication") public: /** * This constructor is the one you should use. @@ -138,7 +137,6 @@ public: */ KConfig* sessionConfig(); - /** * Disables session management for this application. * @@ -155,20 +153,6 @@ public: */ void enableSessionManagement(); - /** - * Reimplemented for internal purposes, mainly the highlevel - * handling of session management with KSessionManager. - * @internal - */ - void commitData( QSessionManager& sm ); - - /** - * Reimplemented for internal purposes, mainly the highlevel - * handling of session management with KSessionManager. - * @internal - */ - void saveState( QSessionManager& sm ); - /** * Returns true if the application is currently saving its session * data (most probably before KDE logout). This is intended for use @@ -178,6 +162,12 @@ public: */ bool sessionSaving() const; + /** + * Returns true if the application is currently restoring its session + * + * @see KMainWindow::queryClose + */ + bool isSessionRestored() const; /** * Sets the top widget of the application. @@ -236,15 +226,6 @@ public: */ unsigned long userTimestamp() const; - /** - * Updates the last user action timestamp in the application registered to DBUS with id service - * to the given time, or to this application's user time, if 0 is given. - * Use before causing user interaction in the remote application, e.g. invoking a dialog - * in the application using a DCOP call. - * Consult focus stealing prevention section in kdebase/kwin/README. - */ - void updateRemoteUserTimestamp( const QString& service, int time = 0 ); - /** * Setups signal handler for SIGTERM, SIGHUP and SIGINT to call QApplication::quit() when such * signal is received. @@ -270,15 +251,18 @@ public: public Q_SLOTS: /** - * Updates the last user action timestamp to the given time, or to the current time, - * if 0 is given. Do not use unless you're really sure what you're doing. - * Consult focus stealing prevention section in kdebase/kwin/README. + * Updates the last user action timestamp to the given time, or to the current time, if 0 is + * given. Do not use unless you're really sure what you're doing. Consult focus stealing + * prevention section in kdebase/kwin/README. */ - Q_SCRIPTABLE void updateUserTimestamp( int time = 0 ); - - // D-Bus slots: - Q_SCRIPTABLE void reparseConfiguration(); - Q_SCRIPTABLE void quit(); + void updateUserTimestamp(int time = 0); + /** + * Saves the state of the application for the current session, the state will be restored on the + * next login + */ + virtual bool saveSession(); + void reparseConfiguration(); + void quit(); protected: /** @@ -290,8 +274,7 @@ protected: /** * @internal Used by KUniqueApplication */ - KApplication(Display *display, Qt::HANDLE visual, Qt::HANDLE colormap, - const KComponentData &cData); + KApplication(Display *display, Qt::HANDLE visual, Qt::HANDLE colormap, const KComponentData &cData); /** * Used to catch X11 events @@ -313,7 +296,7 @@ private: Q_PRIVATE_SLOT(d, void _k_x11FilterDestroyed()) Q_PRIVATE_SLOT(d, void _k_checkAppStartedSlot()) - Q_PRIVATE_SLOT(d, void _k_disableAutorestartSlot()) + Q_PRIVATE_SLOT(d, void _k_aboutToQuitSlot()) }; #endif diff --git a/kdeui/kernel/kapplication_adaptor.cpp b/kdeui/kernel/kapplication_adaptor.cpp new file mode 100644 index 00000000..98d89ca7 --- /dev/null +++ b/kdeui/kernel/kapplication_adaptor.cpp @@ -0,0 +1,71 @@ +/* + This file is part of the KDE libraries + Copyright (C) 2024 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kapplication_adaptor.h" +#include "kapplication.h" + +KApplicationAdaptor::KApplicationAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ +} + +QStringList KApplicationAdaptor::restartCommand() const +{ + QStringList result; + result.append(QCoreApplication::applicationFilePath()); + result.append("--session"); + result.append(QString::fromLatin1("%1_%2").arg(QCoreApplication::applicationName()).arg(QCoreApplication::applicationPid())); + return result; +} + +void KApplicationAdaptor::updateUserTimestamp(int time) +{ + if (kapp) { + kapp->updateUserTimestamp(time); + } +} + +void KApplicationAdaptor::saveSession() +{ + if (kapp) { + if (kapp->saveSession()) { + emit sessionSaved(); + } else { + emit sessionSaveCanceled(); + } + return; + } + emit sessionSaved(); +} + +void KApplicationAdaptor::reparseConfiguration() +{ + if (kapp) { + kapp->reparseConfiguration(); + } +} + +void KApplicationAdaptor::quit() +{ + if (kapp) { + kapp->quit(); + } +} + +#include "moc_kapplication_adaptor.cpp" diff --git a/kdeui/kernel/kapplication_adaptor.h b/kdeui/kernel/kapplication_adaptor.h new file mode 100644 index 00000000..3c10d89d --- /dev/null +++ b/kdeui/kernel/kapplication_adaptor.h @@ -0,0 +1,48 @@ +/* + This file is part of the KDE libraries + Copyright (C) 2024 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KAPPLICATION_ADAPTOR_H +#define KAPPLICATION_ADAPTOR_H + +#include + +class KApplicationAdaptor : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.KApplication") +public: + KApplicationAdaptor(QObject *parent); + +Q_SIGNALS: + void sessionSaved(); + void sessionSaveCanceled(); + +public Q_SLOTS: + QStringList restartCommand() const; + void updateUserTimestamp(int time = 0); + void saveSession(); + void reparseConfiguration(); + void quit(); + +private: + Q_DISABLE_COPY(KApplicationAdaptor); +}; + +#endif // KAPPLICATION_ADAPTOR_H + diff --git a/kdeui/kernel/ksessionmanager.cpp b/kdeui/kernel/ksessionmanager.cpp deleted file mode 100644 index cebecf0c..00000000 --- a/kdeui/kernel/ksessionmanager.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) - Copyright (c) 1998, 1999 KDE Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "ksessionmanager.h" - -KSessionManager::KSessionManager() -{ - sessionClients().removeAll( this ); - sessionClients().append( this ); -} - -KSessionManager::~KSessionManager() -{ - sessionClients().removeAll( this ); -} - -bool KSessionManager::saveState(QSessionManager&) -{ - return true; -} - -bool KSessionManager::commitData(QSessionManager&) -{ - return true; -} - -QList& KSessionManager::sessionClients() -{ - static QList session_clients; - return session_clients; -} - - diff --git a/kdeui/kernel/ksessionmanager.h b/kdeui/kernel/ksessionmanager.h deleted file mode 100644 index 823b3a85..00000000 --- a/kdeui/kernel/ksessionmanager.h +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) - Copyright (c) 1998, 1999 KDE Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KSESSIONMANAGER_H -#define KSESSIONMANAGER_H - -#include - -#include - -/** - Provides highlevel access to session management on a per-object - base. - - KSessionManager makes it possible to provide implementations for - QApplication::commitData() and QApplication::saveState(), without - subclassing KApplication. KMainWindow internally makes use of this. - - You don't need to do anything with this class when using - KMainWindow. Instead, use KMainWindow::saveProperties(), - KMainWindow::readProperties(), KMainWindow::queryClose(), - and friends. - - @short Highlevel access to session management. - @author Matthias Ettrich - */ -class KDEUI_EXPORT KSessionManager -{ -public: - KSessionManager(); - virtual ~KSessionManager(); - - /** - See QApplication::saveState() for documentation. - - This function is just a convenience version to avoid subclassing KApplication. - - Return true to indicate a successful state save or false to - indicate a problem and to halt the shutdown process (will - implicitly call sm.cancel() ). - */ - virtual bool saveState( QSessionManager& sm ); - /** - See QApplication::commitData() for documentation. - - This function is just a convenience version to avoid subclassing KApplication. - - Return true to indicate a successful commit of data or false to - indicate a problem and to halt the shutdown process (will - implicitly call sm.cancel() ). - */ - virtual bool commitData( QSessionManager& sm ); - - static QList& sessionClients(); - -private: - Q_DISABLE_COPY(KSessionManager) -}; - -#endif // KSESSIONMANAGER_H - diff --git a/kdeui/kernel/ktoolinvocation.cpp b/kdeui/kernel/ktoolinvocation.cpp index b9615daf..7bf0dadd 100644 --- a/kdeui/kernel/ktoolinvocation.cpp +++ b/kdeui/kernel/ktoolinvocation.cpp @@ -66,20 +66,22 @@ static inline QString getKLauncherError(const int result, const QString &app) static inline void printError(const QString &text, QString *error) { - if (error) + if (error) { *error = text; - else + } else { kError() << text; + } } -KToolInvocation *KToolInvocation::self() +K_GLOBAL_STATIC(KToolInvocation, kToolInvocation) + +KToolInvocation* KToolInvocation::self() { - K_GLOBAL_STATIC(KToolInvocation, s_self) - return s_self; + return kToolInvocation; } -KToolInvocation::KToolInvocation() - : QObject(0), +KToolInvocation::KToolInvocation(QObject *parent) + : QObject(parent), klauncherIface(nullptr) { klauncherIface = new QDBusInterface( @@ -89,16 +91,17 @@ KToolInvocation::KToolInvocation() QDBusConnection::sessionBus(), this ); + qAddPostRoutine(kToolInvocation.destroy); } KToolInvocation::~KToolInvocation() { - delete klauncherIface; + qRemovePostRoutine(kToolInvocation.destroy); } void KToolInvocation::setLaunchEnv(const QString &name, const QString &value) { - self()->klauncherIface->asyncCall(QString::fromLatin1("setLaunchEnv"), name, value); + klauncherIface->asyncCall(QString::fromLatin1("setLaunchEnv"), name, value); } int KToolInvocation::startServiceInternal(const char *_function, @@ -161,58 +164,48 @@ int KToolInvocation::startServiceInternal(const char *_function, } int KToolInvocation::startServiceByDesktopPath(const QString &name, const QString &URL, - QString *error, - const QByteArray &startup_id) + QString *error, const QByteArray &startup_id) { QStringList URLs; - if (!URL.isEmpty()) + if (!URL.isEmpty()) { URLs.append(URL); - return self()->startServiceInternal("start_service_by_desktop_path", - name, URLs, error, startup_id); + } + return startServiceInternal("start_service_by_desktop_path", name, URLs, error, startup_id); } int KToolInvocation::startServiceByDesktopPath(const QString &name, const QStringList &URLs, - QString *error, - const QByteArray &startup_id) + QString *error, const QByteArray &startup_id) { - return self()->startServiceInternal("start_service_by_desktop_path", - name, URLs, error, startup_id); + return startServiceInternal("start_service_by_desktop_path", name, URLs, error, startup_id); } int KToolInvocation::startServiceByDesktopName(const QString &name, const QString &URL, - QString *error, - const QByteArray &startup_id) + QString *error, const QByteArray &startup_id) { QStringList URLs; - if (!URL.isEmpty()) + if (!URL.isEmpty()) { URLs.append(URL); - return self()->startServiceInternal("start_service_by_desktop_name", - name, URLs, error, startup_id); + } + return startServiceInternal("start_service_by_desktop_name", name, URLs, error, startup_id); } int KToolInvocation::startServiceByDesktopName(const QString &name, const QStringList &URLs, - QString *error, - const QByteArray &startup_id) + QString *error, const QByteArray &startup_id) { - return self()->startServiceInternal("start_service_by_desktop_name", - name, URLs, error, startup_id); + return startServiceInternal("start_service_by_desktop_name", name, URLs, error, startup_id); } -int KToolInvocation::kdeinitExec(const QString &name, const QStringList &args, - QString *error, +int KToolInvocation::kdeinitExec(const QString &name, const QStringList &args, QString *error, const QByteArray &startup_id) { - return self()->startServiceInternal("kdeinit_exec", - name, args, error, startup_id); + return startServiceInternal("kdeinit_exec", name, args, error, startup_id); } -int KToolInvocation::kdeinitExecWait(const QString &name, const QStringList &args, - QString *error, +int KToolInvocation::kdeinitExecWait(const QString &name, const QStringList &args, QString *error, const QByteArray &startup_id) { - return self()->startServiceInternal("kdeinit_exec_wait", - name, args, error, startup_id); + return startServiceInternal("kdeinit_exec_wait", name, args, error, startup_id); } void KToolInvocation::invokeHelp(const QString &anchor, @@ -227,31 +220,29 @@ void KToolInvocation::invokeHelp(const QString &anchor, } else { appname = _appname; } - KService::Ptr service(KService::serviceByDesktopName(appname)); if (service) { docPath = service->docPath(); } - if (!docPath.isEmpty()) { url = KUrl(KUrl(QString::fromLatin1(KDE_HELP_URL)), docPath); } else { url = QString::fromLatin1(KDE_HELP_URL); } - if (!anchor.isEmpty()) { url.addQueryItem(QString::fromLatin1("anchor"), anchor); } - invokeBrowser(url.url()); } -void KToolInvocation::invokeMailer(const QString &address, const QString &subject, const QByteArray &startup_id) +void KToolInvocation::invokeMailer(const QString &address, const QString &subject, + const QByteArray &startup_id) { - invokeMailer(address, QString(), subject, QString(), QStringList(), startup_id ); + invokeMailer(address, QString(), subject, QString(), QStringList(), startup_id); } -void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray& startup_id, bool allowAttachments) +void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray &startup_id, + bool allowAttachments) { QString address = mailtoURL.path(); QString subject; diff --git a/kdeui/kernel/ktoolinvocation.h b/kdeui/kernel/ktoolinvocation.h index 34f46d60..0149e322 100644 --- a/kdeui/kernel/ktoolinvocation.h +++ b/kdeui/kernel/ktoolinvocation.h @@ -37,230 +37,193 @@ class KUrl; */ class KDECORE_EXPORT KToolInvocation : public QObject { - - Q_OBJECT + Q_OBJECT private: - KToolInvocation(); public: - // @internal + KToolInvocation(QObject *parent = nullptr); ~KToolInvocation(); + static KToolInvocation *self(); public Q_SLOTS: - /** - * Invokes the KHelpCenter HTML help viewer from docbook sources. - * - * @param anchor This has to be a defined anchor in your - * docbook sources. If empty the main index - * is loaded - * @param appname This allows you to show the help of another - * application. If empty the current name() is - * used - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - */ + /** + * Invokes the KHelpCenter HTML help viewer from docbook sources. + * + * @param anchor This has to be a defined anchor in your docbook sources. If empty the + * main index is loaded + * @param appname This allows you to show the help of another application. If empty the + * current name() is used + * @param startup_id For app startup notification, "0" for none + */ + void invokeHelp(const QString &anchor = QString(), const QString &appname = QString(), + const QByteArray &startup_id = QByteArray()); - static void invokeHelp(const QString &anchor = QString(), - const QString &appname = QString(), - const QByteArray &startup_id = QByteArray()); + /** + * Convenience method; invokes the standard email application. + * + * @param address The destination address + * @param subject Subject string. Can be QString(). + * @param startup_id Ffor app startup notification, "0" for none + */ + void invokeMailer(const QString &address, const QString &subject, + const QByteArray &startup_id = QByteArray()); - /** - * Convenience method; invokes the standard email application. - * - * @param address The destination address - * @param subject Subject string. Can be QString(). - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - */ - static void invokeMailer(const QString &address, const QString &subject, - const QByteArray &startup_id = QByteArray()); + /** + * Invokes the standard email application. + * + * @param mailtoURL A mailto URL. + * @param startup_id For app startup notification, "0" for none + * @param allowAttachments Whether attachments specified in mailtoURL should be honoured. The + * default is false; do not honor requests for attachments. + */ + void invokeMailer(const KUrl &mailtoURL, const QByteArray &startup_id = QByteArray(), + bool allowAttachments = false); - /** - * Invokes the standard email application. - * - * @param mailtoURL A mailto URL. - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @param allowAttachments whether attachments specified in mailtoURL should be honoured. - The default is false; do not honor requests for attachments. - */ - static void invokeMailer(const KUrl &mailtoURL, const QByteArray &startup_id = QByteArray(), - bool allowAttachments = false); + /** + * Convenience method; invokes the standard email application. + * + * All parameters are optional. + * + * @param to The destination address. + * @param cc The Cc field + * @param subject Subject string + * @param body A string containing the body of the mail + * @param attachURLs List of URLs to be attached to the mail. + * @param startup_id For app startup notification, "0" for none + */ + void invokeMailer(const QString &to, const QString &cc, const QString &subject, + const QString &body, const QStringList &attachURLs = QStringList(), + const QByteArray &startup_id = QByteArray()); - /** - * Convenience method; invokes the standard email application. - * - * All parameters are optional. - * - * @param to The destination address. - * @param cc The Cc field - * @param subject Subject string - * @param body A string containing the body of the mail - * @param attachURLs List of URLs to be attached to the mail. - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - */ - static void invokeMailer(const QString &to, const QString &cc, - const QString &subject, const QString &body, - const QStringList &attachURLs = QStringList(), - const QByteArray &startup_id = QByteArray()); + /** + * Invokes the user's preferred browser. Note that you should only do this when you know for + * sure that the browser can handle the URL (i.e. its mimetype). In doubt, if the URL can point + * to an image or anything else than HTML, prefer to use KRun. + * + * @param url The destination address + * @param startup_id For app startup notification, "0" for none + */ + void invokeBrowser(const QString &url, const QByteArray &startup_id = QByteArray()); - /** - * Invokes the user's preferred browser. - * Note that you should only do this when you know for sure that the browser can - * handle the URL (i.e. its mimetype). In doubt, if the URL can point to an image - * or anything else than HTML, prefer to use new KRun( url ). - * - * See also 0). + */ + int startServiceByDesktopPath(const QString &name, const QString &URL, + QString *error = nullptr, + const QByteArray &startup_id = QByteArray()); + + /** + * Starts a service based on the desktop path of the service, e..g. + * "Applications/konqueror.desktop" or "/home/user/bla/myfile.desktop" + * + * @param name The path of the desktop file + * @param URLs If not empty these URLs will be passed to the service + * @param error On failure, @p error contains a description of the error that occurred. + * If the pointer is null, the argument will be ignored + * @param startup_id For app startup notification, "0" for none + * @return an error code indicating success (== 0) or failure (> 0). + */ + int startServiceByDesktopPath(const QString &name, const QStringList &URLs = QStringList(), + QString *error = nullptr, + const QByteArray &startup_id = QByteArray()); /** - * Starts a service based on the desktop path of the service. - * E.g. "Applications/konqueror.desktop" or "/home/user/bla/myfile.desktop" + * Starts a service based on the desktop name of the service, e.g. "konqueror" * - * @param name the path of the desktop file - * @param URL if not empty this URL is passed to the service - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @return an error code indicating success (== 0) or failure (> 0). + * @param name The desktop name of the service + * @param URL If not empty this URL is passed to the service + * @param error On failure, @p error contains a description of the error that occurred. + * If the pointer is null, the argument will be ignored + * @param startup_id For app startup notification, "0" for none + * @return an error code indicating success (== 0) or failure (> 0) */ - static int startServiceByDesktopPath(const QString &name, const QString &URL, - QString *error = 0, - const QByteArray &startup_id = QByteArray()); + int startServiceByDesktopName(const QString &name, const QString &URL, + QString *error = nullptr, + const QByteArray &startup_id = QByteArray()); - /** - * Starts a service based on the desktop path of the service. - * E.g. "Applications/konqueror.desktop" or "/home/user/bla/myfile.desktop" - * - * @param name the path of the desktop file - * @param URLs if not empty these URLs will be passed to the service - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @return an error code indicating success (== 0) or failure (> 0). - */ - static int startServiceByDesktopPath(const QString &name, const QStringList &URLs = QStringList(), - QString *error = 0, - const QByteArray &startup_id = QByteArray()); + /** + * Starts a service based on the desktop name of the service, e.g. "konqueror" + * + * @param name The desktop name of the service + * @param URLs If not empty these URLs will be passed to the service + * @param error On failure, @p error contains a description of the error that occurred. + * If the pointer is null, the argument will be ignored + * @param startup_id For app startup notification, "0" for none + * @return an error code indicating success (== 0) or failure (> 0) + */ + int startServiceByDesktopName(const QString &name, const QStringList &URLs = QStringList(), + QString *error = nullptr, + const QByteArray &startup_id = QByteArray()); - /** - * Starts a service based on the desktop name of the service. - * E.g. "konqueror" - * - * @param name the desktop name of the service - * @param URL if not empty this URL is passed to the service - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @return an error code indicating success (== 0) or failure (> 0). - */ - static int startServiceByDesktopName(const QString &name, const QString &URL, - QString *error = 0, - const QByteArray &startup_id = QByteArray()); + /** + * Starts a program via kdeinit. + * + * @param name Name of the program to start + * @param args Arguments to pass to the program + * @param error On failure, @p error contains a description of the error that occurred + * If the pointer is null, the argument will be ignored + * @param startup_id For app startup notification, "0" for none + * @return an error code indicating success (== 0) or failure (> 0) + */ + int kdeinitExec(const QString &name, const QStringList &args = QStringList(), + QString *error = nullptr, const QByteArray &startup_id = QByteArray()); - /** - * Starts a service based on the desktop name of the service. - * E.g. "konqueror" - * - * @param name the desktop name of the service - * @param URLs if not empty these URLs will be passed to the service - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @return an error code indicating success (== 0) or failure (> 0). - */ - static int startServiceByDesktopName(const QString &name, const QStringList &URLs = QStringList(), - QString *error = 0, - const QByteArray &startup_id = QByteArray()); - - /** - * Starts a program via kdeinit. - * - * program name and arguments are converted to according to the - * local encoding and passed as is to kdeinit. - * - * @param name Name of the program to start - * @param args Arguments to pass to the program - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @return an error code indicating success (== 0) or failure (> 0). - */ - static int kdeinitExec(const QString &name, const QStringList &args = QStringList(), - QString *error = 0, const QByteArray &startup_id = QByteArray()); - - /** - * Starts a program via kdeinit and wait for it to finish. - * - * Like kdeinitExec(), but it waits till the program is finished. - * As such it behaves similar to the system(...) function. - * - * @param name Name of the program to start - * @param args Arguments to pass to the program - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param startup_id for app startup notification, "0" for none, - * "" ( empty string ) is the default - * @return an error code indicating success (== 0) or failure (> 0). - */ - static int kdeinitExecWait(const QString &name, const QStringList &args = QStringList(), - QString *error = 0, const QByteArray &startup_id = QByteArray()); + /** + * Starts a program via kdeinit and wait for it to finish, it behaves similar to the system() + * function. + * + * @param name Name of the program to start + * @param args Arguments to pass to the program + * @param error On failure, @p error contains a description of the error that occurred + * If the pointer is null, the argument will be ignored + * @param startup_id For app startup notification, "0" for none + * @return an error code indicating success (== 0) or failure (> 0) + */ + int kdeinitExecWait(const QString &name, const QStringList &args = QStringList(), + QString *error = nullptr, const QByteArray &startup_id = QByteArray()); private: - /** - * @internal - */ - int startServiceInternal(const char *_function, - const QString &name, const QStringList &URLs, - QString *error, - const QByteArray &startup_id, - const QString &workdir = QString()); + Q_DISABLE_COPY(KToolInvocation); - QDBusInterface *klauncherIface; + /** + * @internal + */ + int startServiceInternal(const char *_function, + const QString &name, const QStringList &URLs, + QString *error, + const QByteArray &startup_id, + const QString &workdir = QString()); + + QDBusInterface *klauncherIface; }; #endif diff --git a/kdeui/widgets/khelpmenu.cpp b/kdeui/widgets/khelpmenu.cpp index 2e917525..bf465ae4 100644 --- a/kdeui/widgets/khelpmenu.cpp +++ b/kdeui/widgets/khelpmenu.cpp @@ -236,7 +236,7 @@ QAction *KHelpMenu::action(MenuId id) const void KHelpMenu::appHelpActivated() { - KToolInvocation::invokeHelp(); + KToolInvocation::self()->invokeHelp(); } void KHelpMenu::aboutApplication() @@ -288,7 +288,7 @@ void KHelpMenu::aboutKDE() void KHelpMenu::reportBug() { - KToolInvocation::invokeBrowser(KDE_BUG_REPORT_URL); + KToolInvocation::self()->invokeBrowser(KDE_BUG_REPORT_URL); } diff --git a/kdeui/widgets/kmainwindow.cpp b/kdeui/widgets/kmainwindow.cpp index 2c81feaf..d4de7d8a 100644 --- a/kdeui/widgets/kmainwindow.cpp +++ b/kdeui/widgets/kmainwindow.cpp @@ -30,7 +30,6 @@ #include "ktoolbarhandler_p.h" #include "kcmdlineargs.h" #include "ktoggleaction.h" -#include "ksessionmanager.h" #include "kstandardaction.h" #include @@ -40,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -101,76 +99,6 @@ bool DockResizeListener::eventFilter(QObject *watched, QEvent *event) return QObject::eventFilter(watched, event); } -class KMWSessionManager : public KSessionManager -{ -public: - KMWSessionManager() - { - } - - bool dummyInit() { return true; } - bool saveState( QSessionManager& ) - { - KConfig* config = KApplication::kApplication()->sessionConfig(); - if ( KMainWindow::memberList().count() ){ - // According to Jochen Wilhelmy , this - // hook is useful for better document orientation - KMainWindow::memberList().first()->saveGlobalProperties(config); - } - - int n = 0; - foreach (KMainWindow* mw, KMainWindow::memberList()) { - n++; - mw->savePropertiesInternal(config, n); - } - - KConfigGroup group( config, "Number" ); - group.writeEntry("NumberOfWindows", n ); - return true; - } - - bool commitData( QSessionManager& sm ) - { - // not really a fast method but the only compatible one - if ( sm.allowsInteraction() ) { - bool canceled = false; - - foreach (KMainWindow *window, KMainWindow::memberList()) { - if ( !window->testAttribute( Qt::WA_WState_Hidden ) ) { - QCloseEvent e; - QApplication::sendEvent( window, &e ); - canceled = !e.isAccepted(); - if (canceled) - break; - /* Don't even think_about deleting widgets with - Qt::WDestructiveClose flag set at this point. We - are faking a close event, but we are *not*_ - closing the window. The purpose of the faked - close event is to prepare the application so it - can safely be quit without the user losing data - (possibly showing a message box "do you want to - save this or that?"). It is possible that the - session manager quits the application later - (emitting QApplication::aboutToQuit() when this - happens), but it is also possible that the user - cancels the shutdown, so the application will - continue to run. - */ - } - } - if (canceled) - return false; - - // else - return true; - } - - // the user wants it, the user gets it - return true; - } -}; - -K_GLOBAL_STATIC(KMWSessionManager, ksm) K_GLOBAL_STATIC(QList, sMemberList) static bool being_first = true; @@ -207,8 +135,8 @@ void KMainWindowPrivate::init(KMainWindow *_q) // So don't let the default Qt mechanism allow any toplevel widget to just quit the app on us. // Setting WA_QuitOnClose to false for all KMainWindows is not enough, any progress widget // or dialog box would still quit the app... - if (qApp) - qApp->setQuitOnLastWindowClosed(false); + if (kapp) + kapp->setQuitOnLastWindowClosed(false); helpMenu = 0; @@ -216,9 +144,6 @@ void KMainWindowPrivate::init(KMainWindow *_q) QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayStyleChanged()), q, SLOT(_k_slotStyleChanged())); - // force KMWSessionManager creation - someone a better idea? - ksm->dummyInit(); - sMemberList->append( q ); settingsDirty = false; @@ -460,7 +385,7 @@ KMenu* KMainWindow::customHelpMenu( bool showWhatsThis ) bool KMainWindow::canBeRestored( int number ) { - if ( !qApp->isSessionRestored() ) + if ( !kapp->isSessionRestored() ) return false; KConfig *config = kapp->sessionConfig(); if ( !config ) @@ -473,7 +398,7 @@ bool KMainWindow::canBeRestored( int number ) const QString KMainWindow::classNameOfToplevel( int number ) { - if ( !qApp->isSessionRestored() ) + if ( !kapp->isSessionRestored() ) return QString(); KConfig *config = kapp->sessionConfig(); if ( !config ) diff --git a/kdeui/widgets/kmainwindow.h b/kdeui/widgets/kmainwindow.h index cff0010a..03f74ae4 100644 --- a/kdeui/widgets/kmainwindow.h +++ b/kdeui/widgets/kmainwindow.h @@ -101,7 +101,7 @@ class KToolBar; class KDEUI_EXPORT KMainWindow : public QMainWindow { - friend class KMWSessionManager; + friend class KApplication; friend class DockResizeListener; KDEUI_DECLARE_PRIVATE(KMainWindow) Q_OBJECT diff --git a/kdeui/xmlgui/kxmlguiwindow.cpp b/kdeui/xmlgui/kxmlguiwindow.cpp index b0be5246..b5dfa03f 100644 --- a/kdeui/xmlgui/kxmlguiwindow.cpp +++ b/kdeui/xmlgui/kxmlguiwindow.cpp @@ -31,7 +31,6 @@ #include "kxmlguifactory.h" #include "kcmdlineargs.h" #include "ktoggleaction.h" -#include "ksessionmanager.h" #include "kstandardaction.h" #include diff --git a/kinit/kioslave.cpp b/kinit/kioslave.cpp index 885466b7..8a4c4871 100644 --- a/kinit/kioslave.cpp +++ b/kinit/kioslave.cpp @@ -32,7 +32,6 @@ int main(int argc, char **argv) } ::setlocale(LC_ALL, ""); - ::unsetenv("SESSION_MANAGER"); if (!argv[1]) { diff --git a/kinit/klauncher.cpp b/kinit/klauncher.cpp index 5800cde6..c3a016c1 100644 --- a/kinit/klauncher.cpp +++ b/kinit/klauncher.cpp @@ -45,17 +45,6 @@ KLauncher::~KLauncher() session.unregisterService("org.kde.klauncher"); } -void KLauncher::setSessionManager(const QByteArray &sessionmanager) -{ - const int equalindex = sessionmanager.indexOf('='); - kDebug() << "SESSION_MANAGER" << sessionmanager; - if (equalindex > 0) { - const QByteArray sessionmanagervalue = sessionmanager.mid(equalindex + 1, sessionmanager.size() - equalindex - 1); - kDebug() << "SESSION_MANAGER" << sessionmanager << sessionmanagervalue; - m_adaptor->setLaunchEnv(QString::fromLatin1("SESSION_MANAGER"), sessionmanagervalue); - } -} - int main(int argc, char *argv[]) { KAboutData aboutData( @@ -66,15 +55,8 @@ int main(int argc, char *argv[]) KCmdLineArgs::init(argc, argv, &aboutData); - const QByteArray sessionmanager = qgetenv("SESSION_MANAGER"); - - // NOTE: disables session manager entirely, for reference: - // https://www.x.org/releases/X11R7.7/doc/libSM/xsmp.html - ::unsetenv("SESSION_MANAGER"); - KApplication app; app.setQuitOnLastWindowClosed(false); - app.disableSessionManagement(); QDBusConnection session = QDBusConnection::sessionBus(); if (!session.isConnected()) { @@ -88,8 +70,6 @@ int main(int argc, char *argv[]) } KLauncher klauncher(&app); - klauncher.setSessionManager(sessionmanager); - return app.exec(); // keep running } diff --git a/kinit/klauncher.h b/kinit/klauncher.h index 2299d11a..27aecf74 100644 --- a/kinit/klauncher.h +++ b/kinit/klauncher.h @@ -30,8 +30,6 @@ public: KLauncher(QObject *parent = nullptr); ~KLauncher(); - void setSessionManager(const QByteArray &sessionmanager); - private: KLauncherAdaptor* m_adaptor; }; diff --git a/kinit/klauncher_adaptor.h b/kinit/klauncher_adaptor.h index 4216e23e..2bdc24b4 100644 --- a/kinit/klauncher_adaptor.h +++ b/kinit/klauncher_adaptor.h @@ -74,10 +74,10 @@ public: public: public Q_SLOTS: - // used by ksmserver + // used by plasma-desktop void autoStart(int phase); - // used by ksmserver and klauncher itself + // used by plasma-desktop and klauncher itself void exec_blind(const QString &name, const QStringList &arg_list); void cleanup(); diff --git a/kio/kio/krun.cpp b/kio/kio/krun.cpp index e13589df..45fb87fa 100644 --- a/kio/kio/krun.cpp +++ b/kio/kio/krun.cpp @@ -941,7 +941,7 @@ bool KRun::run(const KService& _service, const KUrl::List& _urls, QWidget* windo QString error; - int i = KToolInvocation::startServiceByDesktopPath( + int i = KToolInvocation::self()->startServiceByDesktopPath( _service.entryPath(), urls.toStringList(), &error, asn ); @@ -1100,7 +1100,7 @@ void KRun::init() if (service) { kDebug(7010) << "Helper protocol service is" << service->name() << service->entryPath(); QString errorstr; - if (KToolInvocation::startServiceByDesktopPath(service->entryPath(), d->m_strURL.url(), &errorstr, d->m_asn) == 0) { + if (KToolInvocation::self()->startServiceByDesktopPath(service->entryPath(), d->m_strURL.url(), &errorstr, d->m_asn) == 0) { d->m_bFinished = true; d->startTimer(); return; diff --git a/kio/misc/kmailservice.cpp b/kio/misc/kmailservice.cpp index 4ad1c87b..c1bacd90 100644 --- a/kio/misc/kmailservice.cpp +++ b/kio/misc/kmailservice.cpp @@ -38,7 +38,7 @@ int main( int argc, char **argv ) if ( args->count() != 1 ) return 1; - KToolInvocation::invokeMailer(KUrl(args->arg(0)), QByteArray(), true); + KToolInvocation::self()->invokeMailer(KUrl(args->arg(0)), QByteArray(), true); return 0; } diff --git a/kio/misc/ktelnetservice.cpp b/kio/misc/ktelnetservice.cpp index ed3ce764..233993a4 100644 --- a/kio/misc/ktelnetservice.cpp +++ b/kio/misc/ktelnetservice.cpp @@ -94,7 +94,7 @@ int main(int argc, char **argv) cmd << QString::number(url.port()); } - KToolInvocation::kdeinitExec(terminal, cmd); + KToolInvocation::self()->kdeinitExec(terminal, cmd); return 0; } diff --git a/kutils/kcmultidialog.cpp b/kutils/kcmultidialog.cpp index 03ded9de..ac91d694 100644 --- a/kutils/kcmultidialog.cpp +++ b/kutils/kcmultidialog.cpp @@ -327,7 +327,7 @@ void KCMultiDialog::slotHelpClicked() } moduleService = moduleService.replace(QLatin1String(".desktop"), QString()); - KToolInvocation::invokeHelp(QString(), moduleService); + KToolInvocation::self()->invokeHelp(QString(), moduleService); }