diff --git a/CMakeLists.txt b/CMakeLists.txt index bdc3a8e39..cdbd61e5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,10 +39,10 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED find_package(KF5 ${KF5_MIN_VERSION} REQUIRED Bookmarks Completion Config ConfigWidgets - CoreAddons DocTools GuiAddons I18n IconThemes - Init KDELibs4Support KIO Notifications NotifyConfig + CoreAddons DocTools GuiAddons DBusAddons + I18n IconThemes Init KIO Notifications NotifyConfig Parts Pty Service TextWidgets WidgetsAddons - WindowSystem XmlGui + WindowSystem XmlGui DBusAddons ) find_package(X11) diff --git a/src/Application.cpp b/src/Application.cpp index 9d1358341..3cec2e02a 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -24,11 +24,12 @@ #include #include #include +#include +#include +#include // KDE #include -#include -#include // Konsole #include "SessionManager.h" @@ -42,28 +43,9 @@ using namespace Konsole; -Application::Application() : KUniqueApplication() -{ - init(); -} - -void Application::init() +Application::Application(QCommandLineParser &parser) : m_parser(parser) { _backgroundInstance = 0; - - // enable high dpi support - setAttribute(Qt::AA_UseHighDpiPixmaps, true); - -#if defined(Q_OS_MAC) - // this ensures that Ctrl and Meta are not swapped, so CTRL-C and friends - // will work correctly in the terminal - setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); - - // KDE's menuBar()->isTopLevel() hasn't worked in a while. - // For now, put menus inside Konsole window; this also make - // the keyboard shortcut to show menus look reasonable. - setAttribute(Qt::AA_DontUseNativeMenuBar); -#endif } Application::~Application() @@ -75,6 +57,7 @@ Application::~Application() MainWindow* Application::newMainWindow() { MainWindow* window = new MainWindow(); + window->setTransparency(!m_parser.isSet("notransparency")); connect(window, &Konsole::MainWindow::newWindowRequest, this, &Konsole::Application::createWindow); connect(window, &Konsole::MainWindow::viewDetached, this, &Konsole::Application::detachView); @@ -107,75 +90,67 @@ void Application::detachView(Session* session) int Application::newInstance() { - static bool firstInstance = true; - - KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); - // handle session management - if ((args->count() != 0) || !firstInstance || !isSessionRestored()) { - // check for arguments to print help or other information to the - // terminal, quit if such an argument was found - if (processHelpArgs(args)) - return 0; - // returns from processWindowArgs(args, createdNewMainWindow) - // if a new window was created - bool createdNewMainWindow = false; + // returns from processWindowArgs(args, createdNewMainWindow) + // if a new window was created + bool createdNewMainWindow = false; - // create a new window or use an existing one - MainWindow* window = processWindowArgs(args, createdNewMainWindow); + // check for arguments to print help or other information to the + // terminal, quit if such an argument was found + if (processHelpArgs()) + return 0; - if (args->isSet("tabs-from-file")) { - // create new session(s) as described in file - processTabsFromFileArgs(args, window); - } else { - // select profile to use - Profile::Ptr baseProfile = processProfileSelectArgs(args); + // create a new window or use an existing one + MainWindow* window = processWindowArgs(createdNewMainWindow); - // process various command-line options which cause a property of the - // selected profile to be changed - Profile::Ptr newProfile = processProfileChangeArgs(args, baseProfile); + if (m_parser.isSet("tabs-from-file")) { + // create new session(s) as described in file + processTabsFromFileArgs(window); + } else { + // select profile to use + Profile::Ptr baseProfile = processProfileSelectArgs(); - // create new session - Session* session = window->createSession(newProfile, QString()); + // process various command-line options which cause a property of the + // selected profile to be changed + Profile::Ptr newProfile = processProfileChangeArgs(baseProfile); - if (!args->isSet("close")) { - session->setAutoClose(false); - } - } + // create new session + Session* session = window->createSession(newProfile, QString()); - // if the background-mode argument is supplied, start the background - // session ( or bring to the front if it already exists ) - if (args->isSet("background-mode")) { - startBackgroundMode(window); - } else { - // Qt constrains top-level windows which have not been manually - // resized (via QWidget::resize()) to a maximum of 2/3rds of the - // screen size. - // - // This means that the terminal display might not get the width/ - // height it asks for. To work around this, the widget must be - // manually resized to its sizeHint(). - // - // This problem only affects the first time the application is run. - // run. After that KMainWindow will have manually resized the - // window to its saved size at this point (so the Qt::WA_Resized - // attribute will be set) - - - // If not restoring size from last time or only adding new tab, - // resize window to chosen profile size (see Bug:345403) - if (createdNewMainWindow){ - finalizeNewMainWindow(window); - } else{ - window->show(); - } + if (m_parser.isSet("noclose")) { + session->setAutoClose(false); } } - firstInstance = false; - args->clear(); - return 0; + // if the background-mode argument is supplied, start the background + // session ( or bring to the front if it already exists ) + if (m_parser.isSet("background-mode")) { + startBackgroundMode(window); + } else { + // Qt constrains top-level windows which have not been manually + // resized (via QWidget::resize()) to a maximum of 2/3rds of the + // screen size. + // + // This means that the terminal display might not get the width/ + // height it asks for. To work around this, the widget must be + // manually resized to its sizeHint(). + // + // This problem only affects the first time the application is run. + // run. After that KMainWindow will have manually resized the + // window to its saved size at this point (so the Qt::WA_Resized + // attribute will be set) + + // If not restoring size from last time or only adding new tab, + // resize window to chosen profile size (see Bug:345403) + if (createdNewMainWindow){ + finalizeNewMainWindow(window); + } else{ + window->show(); + } + } + + return 1; } /* Documentation for tab file: @@ -194,16 +169,15 @@ title: Top this!;; command: top command: ssh earth profile: Zsh */ -void Application::processTabsFromFileArgs(KCmdLineArgs* args, - MainWindow* window) +void Application::processTabsFromFileArgs(MainWindow* window) { // Open tab configuration file - const QString tabsFileName(args->getOption("tabs-from-file")); + const QString tabsFileName(m_parser.value("tabs-from-file")); QFile tabsFile(tabsFileName); if (!tabsFile.open(QFile::ReadOnly)) { qWarning() << "ERROR: Cannot open tabs file " << tabsFileName.toLocal8Bit().data(); - quit(); + return; } unsigned int sessions = 0; @@ -222,7 +196,7 @@ void Application::processTabsFromFileArgs(KCmdLineArgs* args, } // should contain at least one of 'command' and 'profile' if (lineTokens.contains(QLatin1String("command")) || lineTokens.contains(QStringLiteral("profile"))) { - createTabFromArgs(args, window, lineTokens); + createTabFromArgs(window, lineTokens); sessions++; } else { qWarning() << "Each line should contain at least one of 'command' and 'profile'."; @@ -233,11 +207,11 @@ void Application::processTabsFromFileArgs(KCmdLineArgs* args, if (sessions < 1) { qWarning() << "No valid lines found in " << tabsFileName.toLocal8Bit().data(); - quit(); + return; } } -void Application::createTabFromArgs(KCmdLineArgs* args, MainWindow* window, +void Application::createTabFromArgs(MainWindow* window, const QHash& tokens) { const QString& title = tokens["title"]; @@ -273,8 +247,8 @@ void Application::createTabFromArgs(KCmdLineArgs* args, MainWindow* window, shouldUseNewProfile = true; } - if (args->isSet("workdir")) { - newProfile->setProperty(Profile::Directory, args->getOption("workdir")); + if (m_parser.isSet("workdir")) { + newProfile->setProperty(Profile::Directory, m_parser.value("workdir")); shouldUseNewProfile = true; } @@ -287,7 +261,7 @@ void Application::createTabFromArgs(KCmdLineArgs* args, MainWindow* window, Profile::Ptr theProfile = shouldUseNewProfile ? newProfile : baseProfile; Session* session = window->createSession(theProfile, QString()); - if (!args->isSet("close")) { + if (m_parser.isSet("noclose")) { session->setAutoClose(false); } @@ -303,11 +277,13 @@ void Application::createTabFromArgs(KCmdLineArgs* args, MainWindow* window, window->hide(); } -MainWindow* Application::processWindowArgs(KCmdLineArgs* args, bool &createdNewMainWindow) +// Creates a new Konsole window. +// If --new-tab is given, use existing window. +MainWindow* Application::processWindowArgs(bool &createdNewMainWindow) { MainWindow* window = 0; - if (args->isSet("new-tab")) { - QListIterator iter(topLevelWidgets()); + if (m_parser.isSet("new-tab")) { + QListIterator iter(QApplication::topLevelWidgets()); iter.toBack(); while (iter.hasPrevious()) { window = qobject_cast(iter.previous()); @@ -321,24 +297,24 @@ MainWindow* Application::processWindowArgs(KCmdLineArgs* args, bool &createdNewM window = newMainWindow(); // override default menubar visibility - if (args->isSet("show-menubar")) { + if (m_parser.isSet("show-menubar")) { window->setMenuBarInitialVisibility(true); } - if (args->isSet("hide-menubar")) { + if (m_parser.isSet("hide-menubar")) { window->setMenuBarInitialVisibility(false); } - if (args->isSet("fullscreen")) { + if (m_parser.isSet("fullscreen")) { window->viewFullScreen(true); } // override default tabbbar visibility // FIXME: remove those magic number // see ViewContainer::NavigationVisibility - if (args->isSet("show-tabbar")) { + if (m_parser.isSet("show-tabbar")) { // always show window->setNavigationVisibility(0); } - if (args->isSet("hide-tabbar")) { + if (m_parser.isSet("hide-tabbar")) { // never show window->setNavigationVisibility(2); } @@ -346,16 +322,20 @@ MainWindow* Application::processWindowArgs(KCmdLineArgs* args, bool &createdNewM return window; } -Profile::Ptr Application::processProfileSelectArgs(KCmdLineArgs* args) +// Loads a profile. +// If --profile is given, loads profile . +// If --fallback-profile is given, loads profile FALLBACK/. +// Else loads the default profile. +Profile::Ptr Application::processProfileSelectArgs() { Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile(); - if (args->isSet("profile")) { + if (m_parser.isSet("profile")) { Profile::Ptr profile = ProfileManager::instance()->loadProfile( - args->getOption("profile")); + m_parser.value("profile")); if (profile) return profile; - } else if (args->isSet("fallback-profile")) { + } else if (m_parser.isSet("fallback-profile")) { Profile::Ptr profile = ProfileManager::instance()->loadProfile(QStringLiteral("FALLBACK/")); if (profile) return profile; @@ -364,12 +344,12 @@ Profile::Ptr Application::processProfileSelectArgs(KCmdLineArgs* args) return defaultProfile; } -bool Application::processHelpArgs(KCmdLineArgs* args) +bool Application::processHelpArgs() { - if (args->isSet("list-profiles")) { + if (m_parser.isSet("list-profiles")) { listAvailableProfiles(); return true; - } else if (args->isSet("list-profile-properties")) { + } else if (m_parser.isSet("list-profile-properties")) { listProfilePropertyInfo(); return true; } @@ -385,7 +365,7 @@ void Application::listAvailableProfiles() printf("%s\n", info.completeBaseName().toLocal8Bit().constData()); } - quit(); + return; } void Application::listProfilePropertyInfo() @@ -397,10 +377,10 @@ void Application::listProfilePropertyInfo() printf("%s\n", name.toLocal8Bit().constData()); } - quit(); + return; } -Profile::Ptr Application::processProfileChangeArgs(KCmdLineArgs* args, Profile::Ptr baseProfile) +Profile::Ptr Application::processProfileChangeArgs(Profile::Ptr baseProfile) { bool shouldUseNewProfile = false; @@ -408,13 +388,13 @@ Profile::Ptr Application::processProfileChangeArgs(KCmdLineArgs* args, Profile:: newProfile->setHidden(true); // change the initial working directory - if (args->isSet("workdir")) { - newProfile->setProperty(Profile::Directory, args->getOption("workdir")); + if (m_parser.isSet("workdir")) { + newProfile->setProperty(Profile::Directory, m_parser.value("workdir")); shouldUseNewProfile = true; } // temporary changes to profile options specified on the command line - foreach(const QString & value , args->getOptionList("p")) { + foreach(const QString & value , m_parser.values("p")) { ProfileCommandParser parser; QHashIterator iter(parser.parse(value)); @@ -427,22 +407,21 @@ Profile::Ptr Application::processProfileChangeArgs(KCmdLineArgs* args, Profile:: } // run a custom command - if (args->isSet("e")) { - QString commandExec = args->getOption("e"); + if (m_parser.isSet("e")) { + QString commandExec = m_parser.value("e"); QStringList commandArguments; - // Note: KCmdLineArgs::count() return the number of arguments - // that aren't options. - if (args->count() == 0 && QStandardPaths::findExecutable(commandExec).isEmpty()) { + if (m_parser.positionalArguments().count() == 0 && + QStandardPaths::findExecutable(commandExec).isEmpty()) { // Example: konsole -e "man ls" - ShellCommand shellCommand(args->getOption("e")); + ShellCommand shellCommand(m_parser.value("e")); commandExec = shellCommand.command(); commandArguments = shellCommand.arguments(); } else { // Example: konsole -e man ls commandArguments << commandExec; - for ( int i = 0 ; i < args->count() ; i++ ) - commandArguments << args->arg(i); + for ( int i = 0 ; i < m_parser.positionalArguments().count() ; i++ ) + commandArguments << m_parser.positionalArguments().at(i); } if (commandExec.startsWith(QLatin1String("./"))) @@ -494,6 +473,14 @@ void Application::toggleBackgroundInstance() } } +void Application::slotActivateRequested (const QStringList &args, const QString &workingDir) +{ + if (!args.isEmpty()) { + m_parser.parse(args); + } + newInstance(); +} + void Application::finalizeNewMainWindow(MainWindow* window) { if (!KonsoleSettings::saveGeometryOnExit()) diff --git a/src/Application.h b/src/Application.h index b7389ef3d..431071ef9 100644 --- a/src/Application.h +++ b/src/Application.h @@ -20,14 +20,13 @@ #ifndef APPLICATION_H #define APPLICATION_H -// KDE -#include +// Qt +#include +#include // Konsole #include "Profile.h" -class KCmdLineArgs; - namespace Konsole { class MainWindow; @@ -45,18 +44,18 @@ class Session; * The factory used to create new terminal sessions can be retrieved using * the sessionManager() accessor. */ -class Application : public KUniqueApplication +class Application : public QObject { Q_OBJECT public: /** Constructs a new Konsole application. */ - Application(); + Application(QCommandLineParser &parser); - virtual ~Application(); + ~Application(); /** Creates a new main window and opens a default terminal session */ - virtual int newInstance(); + int newInstance(); /** * Creates a new, empty main window and connects to its newSessionRequest() @@ -71,21 +70,23 @@ private slots: void toggleBackgroundInstance(); +public slots: + void slotActivateRequested (const QStringList &args, const QString &workingDir); + private: - void init(); void listAvailableProfiles(); void listProfilePropertyInfo(); void startBackgroundMode(MainWindow* window); - bool processHelpArgs(KCmdLineArgs* args); - MainWindow* processWindowArgs(KCmdLineArgs* args, bool &createdNewMainWindow); - Profile::Ptr processProfileSelectArgs(KCmdLineArgs* args); - Profile::Ptr processProfileChangeArgs(KCmdLineArgs* args, Profile::Ptr baseProfile); - void processTabsFromFileArgs(KCmdLineArgs* args, MainWindow* window); - void createTabFromArgs(KCmdLineArgs* args, MainWindow* window, - const QHash&); + bool processHelpArgs(); + MainWindow* processWindowArgs(bool &createdNewMainWindow); + Profile::Ptr processProfileSelectArgs(); + Profile::Ptr processProfileChangeArgs(Profile::Ptr baseProfile); + void processTabsFromFileArgs(MainWindow* window); + void createTabFromArgs(MainWindow* window, const QHash&); void finalizeNewMainWindow(MainWindow* window); MainWindow* _backgroundInstance; + QCommandLineParser &m_parser; }; } #endif // APPLICATION_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 205d88d3d..2a020b03f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,6 +117,7 @@ set(konsole_LIBS KF5::I18n KF5::Pty KF5::KIOWidgets + KF5::DBusAddons ) if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") @@ -169,7 +170,6 @@ target_link_libraries(kdeinit_konsole konsoleprivate KF5::XmlGui KF5::WindowSyst KF5::I18n KF5::KIOWidgets KF5::NotifyConfig - KF5::KDELibs4Support ) install(TARGETS kdeinit_konsole konsole diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index f9d0c44ef..8c6db272c 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -41,7 +40,6 @@ #include #include #include -#include #include // Konsole @@ -67,6 +65,7 @@ MainWindow::MainWindow() , _pluggedController(0) , _menuBarInitialVisibility(true) , _menuBarInitialVisibilityApplied(false) + , _useTransparency(false) { if (!KonsoleSettings::saveGeometryOnExit()) { // If we are not using the global Konsole save geometry on exit, @@ -131,9 +130,7 @@ MainWindow::MainWindow() void MainWindow::updateUseTransparency() { - const KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); - - bool useTranslucency = KWindowSystem::compositingActive() && args->isSet("transparency"); + bool useTranslucency = KWindowSystem::compositingActive() && _useTransparency; setAttribute(Qt::WA_TranslucentBackground, useTranslucency); setAttribute(Qt::WA_NoSystemBackground, false); @@ -769,6 +766,11 @@ void MainWindow::setShowQuickButtons(bool show) _viewManager->setShowQuickButtons(show); } +void MainWindow::setTransparency(bool useTransparency) +{ + _useTransparency = useTransparency; +} + void MainWindow::activateMenuBar() { const QList menuActions = menuBar()->actions(); diff --git a/src/MainWindow.h b/src/MainWindow.h index 500b39561..978bd9361 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -109,6 +109,7 @@ public: void setNavigationStyleSheetFromFile(const QUrl& stylesheetfile); void setNavigationBehavior(int behavior); void setShowQuickButtons(bool show); + void setTransparency(bool useTransparency); signals: @@ -210,6 +211,7 @@ private: bool _menuBarInitialVisibility; bool _menuBarInitialVisibilityApplied; + bool _useTransparency; }; } diff --git a/src/SessionController.cpp b/src/SessionController.cpp index 79db44479..b37937d27 100644 --- a/src/SessionController.cpp +++ b/src/SessionController.cpp @@ -1631,10 +1631,11 @@ void SessionController::zmodemUpload() bool SessionController::isKonsolePart() const { // Check to see if we are being called from Konsole or a KPart - if (QString(qApp->metaObject()->className()) == "Konsole::Application") + if (qApp->applicationName() == "konsole") { return false; - else + } else { return true; + } } SessionTask::SessionTask(QObject* parent) diff --git a/src/SessionController.h b/src/SessionController.h index 02f51d9db..32a9e7cc4 100644 --- a/src/SessionController.h +++ b/src/SessionController.h @@ -354,7 +354,7 @@ private: QStringList _bookmarkValidProgramsToClear; bool _isSearchBarEnabled; - QWeakPointer _editProfileDialog; + QPointer _editProfileDialog; QString _searchText; }; diff --git a/src/SessionListModel.cpp b/src/SessionListModel.cpp index fb28bb806..3aada35e1 100644 --- a/src/SessionListModel.cpp +++ b/src/SessionListModel.cpp @@ -40,13 +40,14 @@ SessionListModel::SessionListModel(QObject* parent) void SessionListModel::setSessions(const QList& sessions) { + beginResetModel(); _sessions = sessions; foreach(Session * session, sessions) { connect(session, &Konsole::Session::finished, this, &Konsole::SessionListModel::sessionFinished); } - reset(); + endResetModel(); } QVariant SessionListModel::data(const QModelIndex& index, int role) const diff --git a/src/autotests/PartTest.cpp b/src/autotests/PartTest.cpp index b3e7797bd..c5a4b4388 100644 --- a/src/autotests/PartTest.cpp +++ b/src/autotests/PartTest.cpp @@ -83,7 +83,7 @@ void PartTest::testFd() // as soon as it becomes available and the terminal will not display any output ptyProcess.pty()->setSuspended(true); - QWeakPointer dialog = new QDialog(); + QPointer dialog = new QDialog(); QVBoxLayout* layout = new QVBoxLayout(dialog.data()); layout->addWidget(new QLabel(QStringLiteral("Output of 'ping localhost' should appear in a terminal below for 5 seconds"))); layout->addWidget(terminalPart->widget()); diff --git a/src/main.cpp b/src/main.cpp index 5e1420e37..129a5cf0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,15 +24,17 @@ // OS specific #include +#include +#include #include +#include // KDE #include -#include #include -#include #include #include +#include using Konsole::Application; @@ -40,11 +42,11 @@ using Konsole::Application; void fillAboutData(KAboutData& aboutData); // fill the KCmdLineOptions object with konsole specific options. -void fillCommandLineOptions(KCmdLineOptions& options); +void fillCommandLineOptions(QCommandLineParser &parser); // check and report whether this konsole instance should use a new konsole // process, or re-use an existing konsole process. -bool shouldUseNewProcess(); +bool shouldUseNewProcess(int argc, char *argv[]); // restore sessions saved by KDE. void restoreSession(Application& app); @@ -52,8 +54,60 @@ void restoreSession(Application& app); // *** // Entry point into the Konsole terminal application. // *** -extern "C" int KDE_EXPORT kdemain(int argc, char** argv) +extern "C" int Q_DECL_EXPORT kdemain(int argc, char* argv[]) { + // Check if any of the arguments makes it impossible to re-use an existing process. + // We need to do this manually and before creating a QApplication, because + // QApplication takes/removes the Qt specific arguments that are incompatible. + KDBusService::StartupOption startupOption = KDBusService::Unique; + if (shouldUseNewProcess(argc, argv)) { + startupOption = KDBusService::Multiple; + } + + QApplication app(argc, argv); + + // enable high dpi support + app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); + +#if defined(Q_OS_MAC) + // this ensures that Ctrl and Meta are not swapped, so CTRL-C and friends + // will work correctly in the terminal + app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); + + // KDE's menuBar()->isTopLevel() hasn't worked in a while. + // For now, put menus inside Konsole window; this also make + // the keyboard shortcut to show menus look reasonable. + app.setAttribute(Qt::AA_DontUseNativeMenuBar); +#endif + + KLocalizedString::setApplicationDomain("konsole"); + + KAboutData about(QStringLiteral("konsole"), + i18nc("@title", "Konsole"), + QStringLiteral(KONSOLE_VERSION), + i18nc("@title", "Terminal emulator"), + KAboutLicense::GPL_V2, + i18n("(c) 1997-2015, The Konsole Developers"), + QStringLiteral(), + QStringLiteral("https://konsole.kde.org/")); + fillAboutData(about); + + KAboutData::setApplicationData(about); + + QCommandLineParser parser; + parser.setApplicationDescription(about.shortDescription()); + parser.addHelpOption(); + parser.addVersionOption(); + fillCommandLineOptions(parser); + about.setupCommandLine(&parser); + + parser.process(app); + about.processCommandLine(&parser); + + // Ensure that we only launch a new instance if we need to + // If there is already an instance running, we will quit here + KDBusService dbusService(startupOption); + Kdelibs4ConfigMigrator migrate(QStringLiteral("konsole")); migrate.setConfigFiles(QStringList() << QStringLiteral("konsolerc") << QStringLiteral("konsole.notifyrc")); migrate.setUiFiles(QStringList() << QStringLiteral("sessionui.rc") << QStringLiteral("partui.rc") << QStringLiteral("konsoleui.rc")); @@ -81,50 +135,27 @@ extern "C" int KDE_EXPORT kdemain(int argc, char** argv) } } - KLocalizedString::setApplicationDomain("konsole"); + // If we reach this location, there was no existing copy of Konsole + // running, so create a new instance. + Application konsoleApp(parser); - KAboutData about(QStringLiteral("konsole"), - i18nc("@title", "Konsole"), - QStringLiteral(KONSOLE_VERSION), - i18nc("@title", "Terminal emulator"), - KAboutLicense::GPL_V2, - i18n("(c) 1997-2015, The Konsole Developers"), - QStringLiteral(), - QStringLiteral("https://konsole.kde.org/")); - fillAboutData(about); + // The activateRequested() signal is emitted when a second instance + // of Konsole is started. + QObject::connect(&dbusService, SIGNAL(activateRequested(QStringList,QString)), + &konsoleApp, SLOT(slotActivateRequested(QStringList,QString))); - KCmdLineArgs::init(argc, - argv, - about.componentName().toUtf8(), - about.componentName().toUtf8(), - ki18nc("@title", "Konsole"), - about.version().toUtf8(), - ki18nc("@title", "Terminal emulator")); - - KCmdLineArgs::addStdCmdLineOptions(); // Qt and KDE options - KUniqueApplication::addCmdLineOptions(); // KUniqueApplication options - KCmdLineOptions konsoleOptions; // Konsole options - fillCommandLineOptions(konsoleOptions); - KCmdLineArgs::addCmdLineOptions(konsoleOptions); - - KUniqueApplication::StartFlags startFlags; - if (shouldUseNewProcess()) - startFlags = KUniqueApplication::NonUniqueInstance; - - // create a new application instance if there are no running Konsole - // instances, otherwise inform the existing Konsole process and exit - if (!KUniqueApplication::start(startFlags)) { - exit(0); + if (!konsoleApp.newInstance()) { + qDebug() << "konsoleApp::init failed"; + return 0; } - Application app; + if (app.isSessionRestored()) + restoreSession(konsoleApp); - KAboutData::setApplicationData(about); - - restoreSession(app); return app.exec(); } -bool shouldUseNewProcess() + +bool shouldUseNewProcess(int argc, char *argv[]) { // The "unique process" model of konsole is incompatible with some or all // Qt/KDE options. When those incompatible options are given, konsole must @@ -132,52 +163,46 @@ bool shouldUseNewProcess() // // TODO: make sure the existing list is OK and add more incompatible options. + // We need to manually parse the arguments because QApplication removes the + // Qt specific arguments (like --reverse) + QStringList arguments; + for (int i=0; i < argc; i++) { + arguments.append(QString::fromLocal8Bit(argv[i])); + } + // take Qt options into consideration - const KCmdLineArgs* qtArgs = KCmdLineArgs::parsedArgs("qt"); QStringList qtProblematicOptions; - qtProblematicOptions << "session" << "name" << "reverse" - << "stylesheet" << "graphicssystem"; + qtProblematicOptions << "--session" << "--name" << "--reverse" + << "--stylesheet" << "--graphicssystem"; #if HAVE_X11 - qtProblematicOptions << "display" << "visual"; + qtProblematicOptions << "--display" << "--visual"; #endif foreach(const QString& option, qtProblematicOptions) { - if ( qtArgs->isSet(option.toLocal8Bit()) ) { + if (arguments.contains(option)) { return true; } } // take KDE options into consideration - const KCmdLineArgs* kdeArgs = KCmdLineArgs::parsedArgs("kde"); QStringList kdeProblematicOptions; - kdeProblematicOptions << "config" << "style"; + kdeProblematicOptions << "--config" << "--style"; #if HAVE_X11 - kdeProblematicOptions << "waitforwm"; + kdeProblematicOptions << "--waitforwm"; #endif + foreach(const QString& option, kdeProblematicOptions) { - if ( kdeArgs->isSet(option.toLocal8Bit()) ) { + if (arguments.contains(option)) { return true; } } - const KCmdLineArgs* kUniqueAppArgs = KCmdLineArgs::parsedArgs("kuniqueapp"); - - // when user asks konsole to run in foreground through the --nofork option - // provided by KUniqueApplication, we must use new process. Otherwise, there - // will be no process for users to wait for finishing. - const bool shouldRunInForeground = !kUniqueAppArgs->isSet("fork"); - if (shouldRunInForeground) { - return true; - } - - const KCmdLineArgs* konsoleArgs = KCmdLineArgs::parsedArgs(); - // if users have explictly requested starting a new process - if (konsoleArgs->isSet("separate")) { + if (arguments.contains("--separate")) { return true; } // the only way to create new tab is to reuse existing Konsole process. - if (konsoleArgs->isSet("new-tab")) { + if (arguments.contains("--new-tab")) { return false; } @@ -195,49 +220,54 @@ bool shouldUseNewProcess() return hasControllingTTY; } -void fillCommandLineOptions(KCmdLineOptions& options) +void fillCommandLineOptions(QCommandLineParser &parser) { - options.add("profile ", - ki18nc("@info:shell", "Name of profile to use for new Konsole instance")); - options.add("fallback-profile", - ki18nc("@info:shell", "Use the internal FALLBACK profile")); - options.add("workdir ", - ki18nc("@info:shell", "Set the initial working directory of the new tab or" - " window to 'dir'")); - options.add("hold"); - options.add("noclose", - ki18nc("@info:shell", "Do not close the initial session automatically when it" - " ends.")); - options.add("new-tab", - ki18nc("@info:shell", "Create a new tab in an existing window rather than" - " creating a new window")); - options.add("tabs-from-file ", - ki18nc("@info:shell", "Create tabs as specified in given tabs configuration" - " file")); - options.add("background-mode", - ki18nc("@info:shell", "Start Konsole in the background and bring to the front" - " when Ctrl+Shift+F12 (by default) is pressed")); - options.add("separate", ki18n("Run in a separate process")); - options.add("show-menubar", ki18nc("@info:shell", "Show the menubar, overriding the default setting")); - options.add("hide-menubar", ki18nc("@info:shell", "Hide the menubar, overriding the default setting")); - options.add("show-tabbar", ki18nc("@info:shell", "Show the tabbar, overriding the default setting")); - options.add("hide-tabbar", ki18nc("@info:shell", "Hide the tabbar, overriding the default setting")); - options.add("fullscreen", ki18nc("@info:shell", "Start Konsole in fullscreen mode")); - options.add("notransparency", - ki18nc("@info:shell", "Disable transparent backgrounds, even if the system" - " supports them.")); - options.add("list-profiles", ki18nc("@info:shell", "List the available profiles")); - options.add("list-profile-properties", - ki18nc("@info:shell", "List all the profile properties names and their type" - " (for use with -p)")); - options.add("p ", - ki18nc("@info:shell", "Change the value of a profile property.")); - options.add("!e ", - ki18nc("@info:shell", "Command to execute. This option will catch all following" - " arguments, so use it as the last option.")); - options.add("+[args]", ki18nc("@info:shell", "Arguments passed to command")); - options.add("", ki18nc("@info:shell", "Use --nofork to run in the foreground (helpful" - " with the -e option).")); + parser.addOption(QCommandLineOption(QStringList() << "profile", + i18nc("@info:shell", "Name of profile to use for new Konsole instance"), + QStringLiteral("name"))); + parser.addOption(QCommandLineOption(QStringList() << "fallback-profile", + i18nc("@info:shell", "Use the internal FALLBACK profile"))); + parser.addOption(QCommandLineOption(QStringList() << "workdir", + i18nc("@info:shell", "Set the initial working directory of the new tab or" + " window to 'dir'"), + QStringLiteral("dir"))); + parser.addOption(QCommandLineOption(QStringList() << "hold" << "noclose", + i18nc("@info:shell", "Do not close the initial session automatically when it" + " ends."))); + parser.addOption(QCommandLineOption(QStringList() << "new-tab", + i18nc("@info:shell", "Create a new tab in an existing window rather than" + " creating a new window"))); + parser.addOption(QCommandLineOption(QStringList() << "tabs-from-file", + i18nc("@info:shell", "Create tabs as specified in given tabs configuration" + " file"), + QStringLiteral("file"))); + parser.addOption(QCommandLineOption(QStringList() << "background-mode", + i18nc("@info:shell", "Start Konsole in the background and bring to the front" + " when Ctrl+Shift+F12 (by default) is pressed"))); + parser.addOption(QCommandLineOption(QStringList() << "separate", i18n("Run in a separate process"))); + parser.addOption(QCommandLineOption(QStringList() << "show-menubar", i18nc("@info:shell", "Show the menubar, overriding the default setting"))); + parser.addOption(QCommandLineOption(QStringList() << "hide-menubar", i18nc("@info:shell", "Hide the menubar, overriding the default setting"))); + parser.addOption(QCommandLineOption(QStringList() << "show-tabbar", i18nc("@info:shell", "Show the tabbar, overriding the default setting"))); + parser.addOption(QCommandLineOption(QStringList() << "hide-tabbar", i18nc("@info:shell", "Hide the tabbar, overriding the default setting"))); + parser.addOption(QCommandLineOption(QStringList() << "fullscreen", i18nc("@info:shell", "Start Konsole in fullscreen mode"))); + parser.addOption(QCommandLineOption(QStringList() << "notransparency", + i18nc("@info:shell", "Disable transparent backgrounds, even if the system" + " supports them."))); + parser.addOption(QCommandLineOption(QStringList() << "list-profiles", + i18nc("@info:shell", "List the available profiles"))); + parser.addOption(QCommandLineOption(QStringList() << "list-profile-properties", + i18nc("@info:shell", "List all the profile properties names and their type" + " (for use with -p)"))); + parser.addOption(QCommandLineOption(QStringList() << "p", + i18nc("@info:shell", "Change the value of a profile property."), + QStringLiteral("property=value"))); + parser.addOption(QCommandLineOption(QStringList() << "e", + i18nc("@info:shell", "Command to execute. This option will catch all following" + " arguments, so use it as the last option."), + QStringLiteral("cmd"))); + parser.addPositionalArgument(QStringLiteral("[args]"), + i18nc("@info:shell", "Arguments passed to command")); + } void fillAboutData(KAboutData& aboutData) @@ -323,10 +353,8 @@ void fillAboutData(KAboutData& aboutData) void restoreSession(Application& app) { - if (app.isSessionRestored()) { - int n = 1; - while (KMainWindow::canBeRestored(n)) - app.newMainWindow()->restore(n++); - } + int n = 1; + while (KMainWindow::canBeRestored(n)) + app.newMainWindow()->restore(n++); } diff --git a/src/settings/ProfileSettings.cpp b/src/settings/ProfileSettings.cpp index d6dafbf17..5ecc019b1 100644 --- a/src/settings/ProfileSettings.cpp +++ b/src/settings/ProfileSettings.cpp @@ -330,7 +330,7 @@ void ProfileSettings::createProfile() newProfile->setProperty(Profile::UntranslatedName, "New Profile"); newProfile->setProperty(Profile::MenuIndex, QString("0")); - QWeakPointer dialog = new EditProfileDialog(this); + QPointer dialog = new EditProfileDialog(this); dialog.data()->setProfile(newProfile); dialog.data()->selectProfileName();