delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / runtime / kdedglobalaccel / globalshortcutsregistry.cpp
blob9c8fdd637ebed5a4f9a9940b11d075cdd6fdd724
1 /* Copyright (C) 2008 Michael Jansen <kde@michael-jansen.biz>
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
8 This library 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 GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "globalshortcutsregistry.h"
20 #include "component.h"
21 #include "globalshortcut.h"
22 #include "globalshortcutcontext.h"
24 #include "kdebug.h"
25 #include "kglobal.h"
27 #include <QtGui/QKeySequence>
28 #include <QDBusConnection>
30 #ifdef Q_WS_X11
31 #include "kglobalaccel_x11.h"
32 #include <QtGui/QX11Info>
33 #include <QtGui/QApplication>
34 #elif defined(Q_WS_MACX)
35 #include "kglobalaccel_mac.h"
36 #elif defined(Q_WS_WIN)
37 #include "kglobalaccel_win.h"
38 #else
39 #include "kglobalaccel_qws.h"
40 #endif
42 GlobalShortcutsRegistry::GlobalShortcutsRegistry()
43 : QObject()
44 ,_active_keys()
45 ,_components()
46 ,_manager(new KGlobalAccelImpl(this))
47 ,_config("kglobalshortcutsrc", KConfig::SimpleConfig)
49 _manager->setEnabled(true);
53 GlobalShortcutsRegistry::~GlobalShortcutsRegistry()
55 _manager->setEnabled(false);
59 KdeDGlobalAccel::Component *GlobalShortcutsRegistry::addComponent(KdeDGlobalAccel::Component *component)
61 if (_components.value(component->uniqueName()))
63 Q_ASSERT_X(false, "GlobalShortcutsRegistry::addComponent", "component already registered?!?!");
64 return _components.value(component->uniqueName());
67 _components.insert(component->uniqueName(), component);
68 QDBusConnection conn(QDBusConnection::sessionBus());
70 conn.registerObject(
71 component->dbusPath().path(),
72 component,
73 QDBusConnection::ExportScriptableContents);
74 return component;
78 void GlobalShortcutsRegistry::activateShortcuts()
80 Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
82 component->activateShortcuts();
87 QList<KdeDGlobalAccel::Component*> GlobalShortcutsRegistry::allMainComponents() const
89 return _components.values();
93 QDBusObjectPath GlobalShortcutsRegistry::dbusPath() const
95 return _dbusPath;
99 void GlobalShortcutsRegistry::deactivateShortcuts(bool temporarily)
101 Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
103 component->deactivateShortcuts(temporarily);
108 GlobalShortcut *GlobalShortcutsRegistry::getActiveShortcutByKey(int key) const
110 return _active_keys.value(key);
114 KdeDGlobalAccel::Component *GlobalShortcutsRegistry::getComponent(const QString &uniqueName)
116 return _components.value(uniqueName);
120 GlobalShortcut *GlobalShortcutsRegistry::getShortcutByKey(int key) const
122 Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
124 GlobalShortcut *rc = component->getShortcutByKey(key);
125 if (rc) return rc;
127 return NULL;
131 QList<GlobalShortcut*> GlobalShortcutsRegistry::getShortcutsByKey(int key) const
133 QList<GlobalShortcut *> rc;
135 Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
137 rc = component->getShortcutsByKey(key);
138 if (!rc.isEmpty()) return rc;
140 return rc;
144 bool GlobalShortcutsRegistry::isShortcutAvailable(
145 int shortcut,
146 const QString &componentName,
147 const QString &contextName) const
149 Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
151 if (!component->isShortcutAvailable(shortcut, componentName, contextName))
152 return false;
154 return true;
158 GlobalShortcutsRegistry * GlobalShortcutsRegistry::self()
160 K_GLOBAL_STATIC( GlobalShortcutsRegistry, self );
161 return self;
165 bool GlobalShortcutsRegistry::keyPressed(int keyQt)
167 // Check if keyQt is one of out global shortcuts. Because other kded
168 // modules could receive key events too that is not guaranteed.
169 GlobalShortcut *shortcut = getShortcutByKey(keyQt);
170 if (!shortcut || !shortcut->isActive())
172 // We ungrab keys when deactivating shortcuts.
173 if (shortcut)
175 Q_ASSERT(shortcut->isActive());
178 // Not one of ours. Or one of ours but not active. It's meant for some
179 // other kded module most likely.
180 return false;
183 // Never print out the received key if it is not one of our active global
184 // shortcuts. We could end up printing out kpasswdservers password.
185 kDebug() << QKeySequence(keyQt).toString() << "=" << shortcut->uniqueName();
187 QStringList data(shortcut->context()->component()->uniqueName());
188 data.append(shortcut->uniqueName());
189 data.append(shortcut->context()->component()->friendlyName());
190 data.append(shortcut->friendlyName());
191 #ifdef Q_WS_X11
192 // pass X11 timestamp
193 long timestamp = QX11Info::appTime();
194 // Make sure kded has ungrabbed the keyboard after receiving the keypress,
195 // otherwise actions in application that try to grab the keyboard (e.g. in kwin)
196 // may fail to do so. There is still a small race condition with this being out-of-process.
197 qApp->syncX();
198 #else
199 long timestamp = 0;
200 #endif
201 emit invokeAction(data, timestamp);
202 return true;
206 void GlobalShortcutsRegistry::loadSettings()
208 foreach (const QString &groupName, _config.groupList())
211 Q_ASSERT(groupName.indexOf('\x1d')==-1);
212 #if 0
213 // Skip the subgroups [Friendly Name] and contexts
214 if (groupName.indexOf('\x1d')!=-1)
216 continue;
218 #endif
220 kDebug() << "Loading group " << groupName;
222 // loadSettings isn't designed to be called in between. Only at the
223 // beginning.
224 Q_ASSERT(!getComponent(groupName));
226 KConfigGroup configGroup(&_config, groupName);
228 // We previously stored the friendly name in a separate group. migrate
229 // that
230 QString friendlyName;
231 KConfigGroup friendlyGroup(&configGroup, "Friendly Name");
232 if (friendlyGroup.isValid())
234 friendlyName = friendlyGroup.readEntry("Friendly Name");
235 friendlyGroup.deleteGroup();
237 else
239 friendlyName = configGroup.readEntry("_k_friendly_name");
242 // Create the component
243 KdeDGlobalAccel::Component *component = new KdeDGlobalAccel::Component(
244 groupName,
245 friendlyName,
246 this);
248 // Now load the contexts
249 Q_FOREACH(const QString& context, configGroup.groupList())
251 // Skip the friendly name group
252 if (context=="Friendly Name") continue;
254 KConfigGroup contextGroup(&configGroup, context);
255 QString contextFriendlyName = contextGroup.readEntry("_k_friendly_name");
256 component->createGlobalShortcutContext(context, contextFriendlyName);
257 component->activateGlobalShortcutContext(context);
258 component->loadSettings(contextGroup);
261 // Load the default context
262 component->activateGlobalShortcutContext("default");
263 component->loadSettings(configGroup);
268 bool GlobalShortcutsRegistry::registerKey(int key, GlobalShortcut *shortcut)
270 if (key == 0)
272 kDebug() << shortcut->uniqueName() << ": Key '" << QKeySequence(key).toString()
273 << "' already taken by " << _active_keys.value(key)->uniqueName() << ".";
274 return false;
276 else if (_active_keys.value(key))
278 kDebug() << shortcut->uniqueName() << ": Attempt to register key 0.";
279 return false;
282 kDebug() << "Registering key" << QKeySequence(key).toString() << "for"
283 << shortcut->context()->component()->uniqueName() << ":" << shortcut->uniqueName();
285 _active_keys.insert(key, shortcut);
286 return _manager->grabKey(key, true);
290 void GlobalShortcutsRegistry::setAccelManager(KGlobalAccelImpl *manager)
292 _manager = manager;
296 void GlobalShortcutsRegistry::setDBusPath(const QDBusObjectPath &path)
298 _dbusPath = path;
302 KdeDGlobalAccel::Component *GlobalShortcutsRegistry::takeComponent(KdeDGlobalAccel::Component *component)
304 QDBusConnection conn(QDBusConnection::sessionBus());
305 conn.unregisterObject(component->dbusPath().path());
306 return _components.take(component->uniqueName());
310 bool GlobalShortcutsRegistry::unregisterKey(int key, GlobalShortcut *shortcut)
312 if (_active_keys.value(key)!=shortcut)
314 // The shortcut doesn't own the key or the key isn't grabbed
315 return false;
318 kDebug() << "Unregistering key" << QKeySequence(key).toString() << "for"
319 << shortcut->context()->component()->uniqueName() << ":" << shortcut->uniqueName();
321 _manager->grabKey(key, false);
322 _active_keys.take(key);
323 return true;
327 void GlobalShortcutsRegistry::writeSettings() const
329 Q_FOREACH(
330 const KdeDGlobalAccel::Component *component,
331 GlobalShortcutsRegistry::self()->allMainComponents())
333 KConfigGroup configGroup(&_config, component->uniqueName());
334 if (component->allShortcuts().isEmpty())
336 configGroup.deleteGroup();
337 delete component;
339 else
341 component->writeSettings(configGroup);
345 _config.sync();
349 #include "moc_globalshortcutsregistry.cpp"