2
* Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU Library General Public License version 2 as
6
* published by the Free Software Foundation
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details
13
* You should have received a copy of the GNU Library General Public
14
* License along with this program; if not, write to the
15
* Free Software Foundation, Inc.,
16
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
#include "krunnerapp.h"
29
#include <QtDBus/QtDBus>
33
#include <KActionCollection>
36
#include <KAuthorized>
37
#include <KGlobalAccel>
38
#include <KGlobalSettings>
40
#include <KMessageBox>
41
#include <KWindowSystem>
43
#include <Plasma/RunnerManager>
44
#include <Plasma/AbstractRunner>
46
#include "kworkspace/kdisplaymanager.h"
47
#include "panelshadows.h"
49
#include "appadaptor.h"
50
#include "kworkspace.h"
51
#include "ksystemactivitydialog.h"
52
#include "interfaces/default/interface.h"
53
#include "interfaces/quicksand/qs_dialog.h"
55
#include "startupid.h"
57
#include "klaunchsettings.h"
58
#include "krunnersettings.h"
61
#include <X11/extensions/Xrender.h>
64
KRunnerApp* KRunnerApp::self()
67
return new KRunnerApp();
70
return qobject_cast<KRunnerApp*>(kapp);
73
KRunnerApp::KRunnerApp()
74
: KUniqueApplication(),
76
m_shadows(new PanelShadows(this)),
82
connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanUp()));
85
KRunnerApp::~KRunnerApp()
89
void KRunnerApp::cleanUp()
91
disconnect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
92
kDebug() << "deleting interface";
96
delete m_runnerManager;
102
KGlobal::config()->sync();
105
KActionCollection* KRunnerApp::actionCollection()
107
return m_actionCollection;
110
void KRunnerApp::initialize()
112
setWindowIcon(KIcon(QLatin1String("system-run")));
114
setQuitOnLastWindowClosed(false);
115
KCrash::setFlags(KCrash::AutoRestart);
116
initializeStartupNotification();
118
connect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
120
m_runnerManager = new Plasma::RunnerManager;
122
new AppAdaptor(this);
123
QDBusConnection::sessionBus().registerObject(QLatin1String("/App"), this);
126
m_actionCollection = new KActionCollection(this);
129
if (KAuthorized::authorize(QLatin1String("run_command"))) {
130
a = m_actionCollection->addAction(QLatin1String("Run Command"));
131
a->setText(i18n("Run Command"));
132
a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::Key_F2));
133
connect(a, SIGNAL(triggered(bool)), SLOT(displayOrHide()));
135
a = m_actionCollection->addAction(QLatin1String("Run Command on clipboard contents"));
136
a->setText(i18n("Run Command on clipboard contents"));
137
a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::SHIFT+Qt::Key_F2));
138
connect(a, SIGNAL(triggered(bool)), SLOT(displayWithClipboardContents()));
141
a = m_actionCollection->addAction(QLatin1String("Show System Activity"));
142
a->setText(i18n("Show System Activity"));
143
a->setGlobalShortcut(KShortcut(Qt::CTRL+Qt::Key_Escape));
144
connect(a, SIGNAL(triggered(bool)), SLOT(showTaskManager()));
146
if (KAuthorized::authorize(QLatin1String("switch_user"))) {
147
a = m_actionCollection->addAction(QLatin1String("Switch User"));
148
a->setText(i18n("Switch User"));
149
a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_Insert));
150
connect(a, SIGNAL(triggered(bool)), SLOT(switchUser()));
153
//FIXME: lock/logout should be in the session management runner which also provides similar
156
if (KAuthorized::authorize(QLatin1String("lock_screen"))) {
157
a = m_actionCollection->addAction(QLatin1String("Lock Session"));
158
a->setText(i18n("Lock Session"));
159
a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_L));
160
connect(a, SIGNAL(triggered(bool)), &m_saver, SLOT(Lock()));
164
//Setup the interface after we have set up the actions
165
//TODO: if !KAuthorized::authorize("run_comand") (and !"switch_user" i suppose?)
166
// then we probably don't need the interface at all. would be another place
167
// for some small improvements in footprint in that case
168
switch (KRunnerSettings::interface()) {
170
case KRunnerSettings::EnumInterface::CommandOriented:
171
m_interface = new Interface(m_runnerManager);
173
case KRunnerSettings::EnumInterface::TaskOriented:
174
m_interface = new QsDialog(m_runnerManager);
178
m_shadows->addWindow(m_interface);
181
//FIXME: if argb visuals enabled Qt will always set WM_CLASS as "qt-subapplication" no matter what
182
//the application name is we set the proper XClassHint here, hopefully won't be necessary anymore when
183
//qapplication will manage apps with argvisuals in a better way
184
XClassHint classHint;
185
classHint.res_name = const_cast<char*>("krunner");
186
classHint.res_class = const_cast<char*>("krunner");
187
XSetClassHint(QX11Info::display(), m_interface->winId(), &classHint);
191
m_actionCollection->readSettings();
192
if (KAuthorized::authorize(QLatin1String("run_command"))) {
193
//m_runnerManager->setAllowedRunners(QStringList() << "shell");
194
m_runnerManager->reloadConfiguration(); // pre-load the runners
196
// Single runner mode actions shortcuts
198
foreach (const QString &runnerId, m_runnerManager->singleModeAdvertisedRunnerIds()) {
199
a = m_actionCollection->addAction(runnerId);
200
a->setText(i18nc("Run krunner restricting the search only to runner %1", "Run Command (runner \"%1\" only)",
201
m_runnerManager->runnerName(runnerId)));
202
a->setGlobalShortcut(KShortcut());
203
connect(a, SIGNAL(triggered(bool)), SLOT(singleRunnerModeActionTriggered()));
208
void KRunnerApp::singleRunnerModeActionTriggered()
210
KAction * action = qobject_cast<KAction*>(sender());
212
displaySingleRunner(action->objectName());
216
void KRunnerApp::querySingleRunner(const QString& runnerId, const QString &term)
218
if (!KAuthorized::authorize(QLatin1String("run_command"))) {
222
m_runnerManager->setSingleModeRunnerId(runnerId);
223
m_runnerManager->setSingleMode(!runnerId.isEmpty());
225
if (m_runnerManager->singleMode()) {
226
m_interface->display(term);
230
QStringList KRunnerApp::singleModeAdvertisedRunnerIds() const
232
return m_runnerManager->singleModeAdvertisedRunnerIds();
235
void KRunnerApp::initializeStartupNotification()
237
// Startup notification
238
KLaunchSettings::self()->readConfig();
240
if (!KLaunchSettings::busyCursor()) {
244
if (m_startupId == NULL ) {
245
m_startupId = new StartupId;
248
m_startupId->configure();
253
void KRunnerApp::showTaskManager()
255
showTaskManagerWithFilter(QString());
257
void KRunnerApp::showTaskManagerWithFilter(const QString &filterText)
260
//kDebug(1204) << "Launching KSysGuard...";
262
m_tasks = new KSystemActivityDialog;
263
connect(m_tasks, SIGNAL(finished()),
264
this, SLOT(taskDialogFinished()));
267
m_tasks->setFilterText(filterText);
271
void KRunnerApp::display()
273
if (!KAuthorized::authorize(QLatin1String("run_command"))) {
277
m_runnerManager->setSingleMode(false);
278
m_interface->display();
281
void KRunnerApp::displaySingleRunner(const QString &runnerId)
283
if (!KAuthorized::authorize(QLatin1String("run_command"))) {
287
m_runnerManager->setSingleModeRunnerId(runnerId);
288
m_runnerManager->setSingleMode(!runnerId.isEmpty());
289
m_interface->display();
292
void KRunnerApp::displayOrHide()
294
if (!KAuthorized::authorize(QLatin1String("run_command"))) {
299
if (!m_interface->isVisible()) {
300
m_runnerManager->setSingleMode(false);
303
if (m_interface->freeFloating()) {
304
if (m_interface->isVisible()) {
307
m_interface->display();
309
} else if (m_interface->isActiveWindow()) {
312
m_interface->display();
316
void KRunnerApp::query(const QString &term)
318
if (!KAuthorized::authorize(QLatin1String("run_command"))) {
322
m_interface->display(term);
325
void KRunnerApp::displayWithClipboardContents()
327
if (!KAuthorized::authorize(QLatin1String("run_command"))) {
331
QString clipboardData = QApplication::clipboard()->text(QClipboard::Selection);
332
m_interface->display(clipboardData);
335
void KRunnerApp::switchUser()
337
const KService::Ptr service = KService::serviceByStorageId(QLatin1String("plasma-runner-sessions.desktop"));
338
KPluginInfo info(service);
340
if (info.isValid()) {
343
dm.localSessions(sessions);
345
if (sessions.isEmpty()) {
346
// no sessions to switch between, let's just start up another session directly
347
Plasma::AbstractRunner *sessionRunner = m_runnerManager->runner(info.pluginName());
349
Plasma::QueryMatch switcher(sessionRunner);
350
sessionRunner->run(*m_runnerManager->searchContext(), switcher);
353
m_runnerManager->setSingleModeRunnerId(info.pluginName());
354
m_runnerManager->setSingleMode(true);
355
m_interface->display();
356
//TODO: ugh, magic strings. See sessions/sessionrunner.cpp
357
m_runnerManager->launchQuery(QLatin1String("SESSIONS"), info.pluginName());
362
void KRunnerApp::clearHistory()
364
m_interface->clearHistory();
367
void KRunnerApp::taskDialogFinished()
370
m_tasks->deleteLater();
375
int KRunnerApp::newInstance()
383
return KUniqueApplication::newInstance();
387
bool KRunnerApp::hasCompositeManager() const
390
return KWindowSystem::compositingActive();
396
void KRunnerApp::reloadConfig()
398
//Prevent Interface destructor from triggering this method
399
disconnect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
401
const int interface = KRunnerSettings::interface();
402
if (!qobject_cast<QsDialog*>(m_interface) &&
403
interface == KRunnerSettings::EnumInterface::TaskOriented) {
404
m_interface->deleteLater();
405
m_interface = new QsDialog(m_runnerManager);
406
} else if (!qobject_cast<Interface*>(m_interface) &&
407
interface == KRunnerSettings::EnumInterface::CommandOriented) {
408
m_interface->deleteLater();
409
m_interface = new Interface(m_runnerManager);
412
m_interface->setFreeFloating(KRunnerSettings::freeFloating());
413
connect(KRunnerSettings::self(), SIGNAL(configChanged()), this, SLOT(reloadConfig()));
417
#include "krunnerapp.moc"