File indexing completed on 2024-03-24 15:27:47

0001 /* This file is part of the KDE libraries
0002     Copyright (c) 1999 Preston Brown <pbrown@kde.org>
0003     Copyright (c) 2000-2001 Waldo Bastian <bastian@kde.org>
0004 
0005     This library is free software; you can redistribute it and/or
0006     modify it under the terms of the GNU Library General Public
0007     License as published by the Free Software Foundation; either
0008     version 2 of the License, or (at your option) any later version.
0009 
0010     This library is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013     Library General Public License for more details.
0014 
0015     You should have received a copy of the GNU Library General Public License
0016     along with this library; see the file COPYING.LIB.  If not, write to
0017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018     Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #ifndef KUNIQUEAPP_H
0022 #define KUNIQUEAPP_H
0023 
0024 #include <kdelibs4support_export.h>
0025 #include <kapplication.h>
0026 
0027 /**
0028  * KUniqueApplication is a KApplication which only uses a single process.  When
0029  * a KUniqueApplication is started, it attempts to contact an existing copy
0030  * of the application.  If successful, the program asks the
0031  * existing process to create a new instance by calling its newInstance() method
0032  * and then exits.  If there is no existing process then the program forks and
0033  * calls the newInstance() method.  When newInstance() is called, the application
0034  * will typically create a new window or activate an existing one.
0035  *
0036  * Instances of KUniqueApplication can be made to behave like a normal application by passing
0037  * the StartFlag::NonUniqueInstance flag to start().
0038  *
0039  * Please note that this supports only one process per KDE session. If
0040  * your application can only be opened once per user or once per host, you
0041  * need to ensure this independently of KUniqueApplication.
0042  *
0043  * The .desktop file for the application should state X-DBUS-StartupType=Unique,
0044  * see ktoolinvocation.h
0045  *
0046  * If you use command line options before start() is called, you MUST call addCmdLineOptions()
0047  * so that the KUniqueApplication-specific command-line options can still work.
0048  *
0049  * If your application is used to open files, it should also support the --tempfile
0050  * option (see KCmdLineArgs::addTempFileOption()), to delete tempfiles after use.
0051  * Add X-KDE-HasTempFileOption=true to the .desktop file to indicate this.
0052  *
0053  * @see KApplication
0054  * @author Preston Brown <pbrown@kde.org>
0055  */
0056 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KUniqueApplication : public KApplication
0057 {
0058     Q_OBJECT
0059 public:
0060     /**
0061      * Constructor. Takes command line arguments from KCmdLineArgs
0062      *
0063      * @param GUIenabled Set to false to disable all GUI stuff. This implies
0064      * no styles either.
0065      * @param configUnique If true, the uniqueness of the application will
0066      *                 depend on the value of the "MultipleInstances"
0067      *                 key in the "KDE" group of the application config file.
0068      */
0069     KDELIBS4SUPPORT_DEPRECATED explicit KUniqueApplication(bool GUIenabled = true,
0070                                 bool configUnique = false);
0071 
0072     /**
0073      * Adds command line options specific for KUniqueApplication.
0074      *
0075      * Should be called before calling KUniqueApplication constructor
0076      * and / or start().
0077      */
0078     static void addCmdLineOptions();
0079 
0080     /**
0081      * These flags can be used to specify how new instances of
0082      * unique applications are created.
0083      */
0084     enum StartFlag {
0085         /**
0086          * Create a new instance of the application in a new process and
0087          * do not attempt to re-use an existing process.
0088          *
0089          * With this flag set, the new instance of the application will
0090          * behave as if it were a plain KApplication rather than a KUniqueApplication.
0091          *
0092          * This is useful if you have an application where all instances are typically run
0093          * in a single process but under certain circumstances new instances may require
0094          * their own process.
0095          */
0096         NonUniqueInstance = 0x1
0097     };
0098     Q_DECLARE_FLAGS(StartFlags, StartFlag)
0099 
0100     /**
0101      * Forks and registers with D-Bus.
0102      *
0103      * The command line arguments are being sent via D-Bus to newInstance()
0104      * and will be received once the application enters the event loop.
0105      *
0106      * Typically this is used like:
0107      * \code
0108      * int main(int argc, char **argv) {
0109      *    KAboutData about("myappname", 0, ki18n("myAppName"), .....);
0110      *    KCmdLineArgs::init(argc, argv, &about);
0111      *    KCmdLineArgs::addCmdLineOptions( myCmdOptions );
0112      *    KUniqueApplication::addCmdLineOptions();
0113      *
0114      *    if (!KUniqueApplication::start()) {
0115      *       fprintf(stderr, "myAppName is already running!\n");
0116      *       return 0;
0117      *    }
0118      *    KUniqueApplication a;
0119      *    return a.exec();
0120      * }
0121      * \endcode
0122      * Note that it's not necessary to call start() explicitly. It will be
0123      * called automatically before creating KUniqueApplication if it hasn't
0124      * been called yet, without any performance impact.
0125      *
0126      * Also note that you MUST call KUniqueApplication::addCmdLineOptions(),
0127      * if you use command line options before start() is called.
0128      *
0129      * @param flags   Optional flags which control how a new instance
0130      *                of the application is started.
0131      * @return true if registration is successful.
0132      *         false if another process was already running.
0133      */
0134     static bool start(StartFlags flags);
0135     // BIC: merge with start(StartFlags flags = StartFlags())
0136     static bool start();
0137 
0138     /**
0139      * Destructor
0140      */
0141     ~KUniqueApplication() override;
0142 
0143     /**
0144      * Creates a new "instance" of the application.
0145      *
0146      * Usually this will involve making some calls into the GUI portion of your
0147      * application asking for a new window to be created, possibly with
0148      * some data already loaded based on the arguments received.
0149      *
0150      * Command line arguments have been passed to KCmdLineArgs before this
0151      * function is called and can be checked in the usual way.
0152      *
0153      * The default implementation ensures the mainwindow of the already
0154      * running instance is shown and activated if necessary. If your
0155      * application has only one mainwindow, you should call this default
0156      * implementation and only add your special handling if needed.
0157      *
0158      * Note that newInstance() is called also in the first started
0159      * application process.
0160      *
0161      * For applications that share one process for several mainwindows,
0162      * the reimplementation could be:
0163      * \code
0164       int MyApp::newInstance()
0165       {
0166       KCmdLineArgs::setCwd(QDir::currentPath().toUtf8());
0167       KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
0168       static bool first = true;
0169       if (args->count() > 0) {
0170           for (int i = 0; i < args->count(); ++i) {
0171               openWindow(args->url(i));
0172           }
0173       } else if( !first || !isSessionRestored()) {
0174           openWindow(KUrl()); // create a new window
0175       }
0176       first = false;
0177       args->clear();
0178       return 0;
0179       }
0180      * \endcode
0181      *
0182      * @return An exit value. The calling process will exit with this value.
0183      */
0184     virtual int newInstance();
0185 
0186     /**
0187      * Returns whether newInstance() is being called while session
0188      * restoration is in progress.
0189      */
0190     bool restoringSession();
0191 
0192     /**
0193      * @internal
0194      */
0195 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
0196     KDELIBS4SUPPORT_DEPRECATED static void setHandleAutoStarted();
0197 #endif
0198 
0199 private:
0200     friend class KUniqueApplicationAdaptor;
0201     class Private;
0202     Private *const d;
0203 
0204     Q_PRIVATE_SLOT(d, void _k_newInstanceNoFork())
0205 };
0206 Q_DECLARE_OPERATORS_FOR_FLAGS(KUniqueApplication::StartFlags)
0207 
0208 #endif