kglobalaccel: format and indent

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2021-08-09 02:30:52 +03:00
parent 714bcacfe4
commit 15bdd54527
13 changed files with 664 additions and 943 deletions

View file

@ -66,49 +66,40 @@ static QString stringFromKeys(const QList<int> &keys)
namespace KdeDGlobalAccel {
Component::Component(
const QString &uniqueName,
const QString &friendlyName,
GlobalShortcutsRegistry *registry)
: _uniqueName(uniqueName)
,_friendlyName(friendlyName)
,_registry(registry)
{
Component::Component(const QString &uniqueName, const QString &friendlyName, GlobalShortcutsRegistry *registry)
: _uniqueName(uniqueName),
_friendlyName(friendlyName),
_registry(registry)
{
// Make sure we do no get uniquenames still containing the context
Q_ASSERT(uniqueName.indexOf("|")==-1);
// Register ourselve with the registry
if (_registry)
{
if (_registry) {
_registry->addComponent(this);
}
}
createGlobalShortcutContext("default", "Default Context");
_current = _contexts.value("default");
}
}
Component::~Component()
{
{
// Remove ourselve from the registry
if (_registry)
{
if (_registry) {
_registry->takeComponent(this);
}
}
// We delete all shortcuts from all contexts
qDeleteAll(_contexts);
}
}
bool Component::activateGlobalShortcutContext(
const QString &uniqueName)
{
if (!_contexts.value(uniqueName))
{
bool Component::activateGlobalShortcutContext(const QString &uniqueName)
{
if (!_contexts.value(uniqueName)) {
createGlobalShortcutContext(uniqueName, "TODO4");
return false;
}
}
// Deactivate the current contexts shortcuts
deactivateShortcuts();
@ -117,124 +108,99 @@ bool Component::activateGlobalShortcutContext(
_current = _contexts.value(uniqueName);
return true;
}
}
void Component::activateShortcuts()
{
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions)
{
{
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions) {
shortcut->setActive();
}
}
}
QList<GlobalShortcut*> Component::allShortcuts(const QString &contextName) const
{
{
GlobalShortcutContext *context = _contexts.value(contextName);
if (context)
{
if (context) {
return context->_actions.values();
}
else
{
} else {
Q_ASSERT(false); // Unknown context
return QList<GlobalShortcut*> ();
}
}
}
QList<KGlobalShortcutInfo> Component::allShortcutInfos(const QString &contextName) const
{
{
QList<KGlobalShortcutInfo> rc;
GlobalShortcutContext *context = _contexts.value(contextName);
if (!context)
{
if (!context) {
Q_ASSERT(false); // Unknown context
return rc;
}
}
return context->allShortcutInfos();
}
}
bool Component::cleanUp()
{
{
bool changed = false;;
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions)
{
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions) {
kDebug() << _current->_actions.size();
if (!shortcut->isPresent())
{
if (!shortcut->isPresent()) {
changed = true;
shortcut->unRegister();
}
}
}
if (changed)
{
if (changed) {
_registry->writeSettings();
// We could be destroyed after this call!
}
}
return changed;
}
}
bool Component::createGlobalShortcutContext(
const QString &uniqueName,
const QString &friendlyName)
{
if (_contexts.value(uniqueName))
{
bool Component::createGlobalShortcutContext(const QString &uniqueName, const QString &friendlyName)
{
if (_contexts.value(uniqueName)) {
kDebug() << "Shortcut Context " << uniqueName << "already exists for component " << _uniqueName;
return false;
}
}
_contexts.insert(uniqueName, new GlobalShortcutContext(uniqueName, friendlyName, this));
return true;
}
}
GlobalShortcutContext *Component::currentContext()
{
{
return _current;
}
}
QDBusObjectPath Component::dbusPath() const
{
{
QString dbusPath = _uniqueName;
// Clean up for dbus usage: any non-alphanumeric char should be turned into '_'
const int len = dbusPath.length();
for ( int i = 0; i < len; ++i )
{
if ( !dbusPath[i].isLetterOrNumber() )
for ( int i = 0; i < len; ++i ) {
if (!dbusPath[i].isLetterOrNumber())
dbusPath[i] = QLatin1Char('_');
}
// QDBusObjectPath could be a little bit easier to handle :-)
return QDBusObjectPath( _registry->dbusPath().path() + "component/" + dbusPath);
}
return QDBusObjectPath(_registry->dbusPath().path() + "component/" + dbusPath);
}
void Component::deactivateShortcuts(bool temporarily)
{
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions)
{
if (temporarily
&& uniqueName() == "kwin"
&& shortcut->uniqueName() == "Block Global Shortcuts")
{
{
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions) {
if (temporarily && uniqueName() == "kwin" && shortcut->uniqueName() == "Block Global Shortcuts") {
continue;
}
shortcut->setInactive();
}
shortcut->setInactive();
}
}
void Component::emitGlobalShortcutPressed( const GlobalShortcut &shortcut )
{
{
#ifdef Q_WS_X11
// pass X11 timestamp
long timestamp = QX11Info::appTime();
@ -248,242 +214,207 @@ void Component::emitGlobalShortcutPressed( const GlobalShortcut &shortcut )
#endif
// Make sure it is one of ours
if (shortcut.context()->component() != this)
{
if (shortcut.context()->component() != this) {
Q_ASSERT(shortcut.context()->component() == this);
// In production mode do nothing
return;
}
emit globalShortcutPressed(
shortcut.context()->component()->uniqueName(),
shortcut.uniqueName(),
timestamp);
}
emit globalShortcutPressed(shortcut.context()->component()->uniqueName(), shortcut.uniqueName(), timestamp);
}
void Component::invokeShortcut(const QString &shortcutName, const QString &context)
{
GlobalShortcut *shortcut = getShortcutByName(shortcutName, context);
if (shortcut) emitGlobalShortcutPressed(*shortcut);
{
GlobalShortcut *shortcut = getShortcutByName(shortcutName, context);
if (shortcut) {
emitGlobalShortcutPressed(*shortcut);
}
}
QString Component::friendlyName() const
{
if (_friendlyName.isEmpty())
{
if (_friendlyName.isEmpty()) {
return _uniqueName;
return _friendlyName;
}
return _friendlyName;
}
GlobalShortcut *Component::getShortcutByKey(int key) const
{
{
return _current->getShortcutByKey(key);
}
}
QList<GlobalShortcut *> Component::getShortcutsByKey(int key) const
{
{
QList <GlobalShortcut *> rc;
Q_FOREACH(GlobalShortcutContext *context, _contexts)
{
Q_FOREACH(GlobalShortcutContext *context, _contexts) {
GlobalShortcut *sc = context->getShortcutByKey(key);
if (sc) rc.append(sc);
if (sc) {
rc.append(sc);
}
return rc;
}
return rc;
}
GlobalShortcut *Component::getShortcutByName(const QString &uniqueName, const QString &context) const
{
if (!_contexts.value(context))
{
{
if (!_contexts.value(context)) {
return NULL;
}
}
return _contexts.value(context)->_actions.value(uniqueName);
}
}
QStringList Component::getShortcutContexts() const
{
{
return _contexts.keys();
}
}
bool Component::isActive() const
{
{
// The component is active if at least one of it's global shortcuts is
// present.
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions)
{
if (shortcut->isPresent()) return true;
Q_FOREACH (GlobalShortcut *shortcut, _current->_actions) {
if (shortcut->isPresent()) {
return true;
}
return false;
}
return false;
}
bool Component::isShortcutAvailable(
int key,
const QString &component,
const QString &context) const
{
bool Component::isShortcutAvailable(int key, const QString &component, const QString &context) const
{
kDebug() << QKeySequence(key).toString() << component;
// if this component asks for the key. only check the keys in the same
// context
if (component==uniqueName())
{
Q_FOREACH(GlobalShortcut *sc, shortcutContext(context)->_actions)
{
if (sc->keys().contains(key)) return false;
if (component==uniqueName()) {
Q_FOREACH(GlobalShortcut *sc, shortcutContext(context)->_actions) {
if (sc->keys().contains(key)) {
return false;
}
}
else
{
Q_FOREACH(GlobalShortcutContext *ctx, _contexts)
{
Q_FOREACH(GlobalShortcut *sc, ctx->_actions)
{
if (sc->keys().contains(key)) return false;
} else {
Q_FOREACH(GlobalShortcutContext *ctx, _contexts) {
Q_FOREACH(GlobalShortcut *sc, ctx->_actions) {
if (sc->keys().contains(key)) {
return false;
}
}
}
return true;
}
return true;
}
void Component::loadSettings(KConfigGroup &configGroup)
{
{
// GlobalShortcutsRegistry::loadSettings handles contexts.
Q_FOREACH (const QString &confKey, configGroup.keyList())
{
Q_FOREACH (const QString &confKey, configGroup.keyList()) {
const QStringList entry = configGroup.readEntry(confKey, QStringList());
if (entry.size() != 3)
{
if (entry.size() != 3) {
continue;
}
}
// The shortcut will register itself with us
GlobalShortcut *shortcut = new GlobalShortcut(
confKey,
entry[2],
_current);
GlobalShortcut *shortcut = new GlobalShortcut(confKey, entry[2], _current);
QList<int> keys = keysFromString(entry[0]);
shortcut->setDefaultKeys(keysFromString(entry[1]));
shortcut->setIsFresh(false);
Q_FOREACH (int key, keys)
{
if (key != 0)
{
if (GlobalShortcutsRegistry::self()->getShortcutByKey(key))
{
Q_FOREACH (int key, keys) {
if (key != 0) {
if (GlobalShortcutsRegistry::self()->getShortcutByKey(key)) {
// The shortcut is already used. The config file is
// broken. Ignore the request.
keys.removeAll(key);
kWarning() << "Shortcut found twice in kglobalshortcutsrc.";
}
}
}
shortcut->setKeys(keys);
}
shortcut->setKeys(keys);
}
}
void Component::setFriendlyName(const QString &name)
{
{
_friendlyName = name;
}
}
GlobalShortcutContext *Component::shortcutContext( const QString &contextName )
{
{
return _contexts.value(contextName);
}
}
GlobalShortcutContext const *Component::shortcutContext( const QString &contextName ) const
{
{
return _contexts.value(contextName);
}
}
QStringList Component::shortcutNames( const QString &contextName) const
{
{
GlobalShortcutContext *context = _contexts.value(contextName);
if (!context)
{
if (!context) {
Q_ASSERT(false); // Unknown context
return QStringList();
}
}
return context->_actions.keys();
}
}
bool Component::showKCM()
{
{
return KRun::runCommand("kcmshell4 keys", NULL);
}
}
QString Component::uniqueName() const
{
{
return _uniqueName;
}
}
void Component::unregisterShortcut(const QString &uniqueName)
{
{
// Now wrote all contexts
Q_FOREACH( GlobalShortcutContext *context, _contexts)
{
if (context->_actions.value(uniqueName))
{
Q_FOREACH( GlobalShortcutContext *context, _contexts) {
if (context->_actions.value(uniqueName)) {
delete context->takeShortcut(context->_actions.value(uniqueName));
}
}
}
}
void Component::writeSettings(KConfigGroup& configGroup) const
{
{
// If we don't delete the current content global shortcut
// registrations will never not deleted after forgetGlobalShortcut()
configGroup.deleteGroup();
// Now write all contexts
Q_FOREACH( GlobalShortcutContext *context, _contexts)
{
Q_FOREACH( GlobalShortcutContext *context, _contexts) {
KConfigGroup contextGroup;
if (context->uniqueName() == "default")
{
if (context->uniqueName() == "default") {
contextGroup = configGroup;
// Write the friendly name
contextGroup.writeEntry("_k_friendly_name", friendlyName());
}
else
{
} else {
contextGroup = KConfigGroup(&configGroup, context->uniqueName());
// Write the friendly name
contextGroup.writeEntry("_k_friendly_name", context->friendlyName());
}
}
// kDebug() << "writing group " << _uniqueName << ":" << context->uniqueName();
Q_FOREACH(const GlobalShortcut *shortcut, context->_actions)
{
Q_FOREACH(const GlobalShortcut *shortcut, context->_actions) {
// kDebug() << "writing" << shortcut->uniqueName();
// We do not write fresh shortcuts.
// We do not write session shortcuts
if (shortcut->isFresh() || shortcut->isSessionShortcut())
{
if (shortcut->isFresh() || shortcut->isSessionShortcut()) {
continue;
}
}
// kDebug() << "really writing" << shortcut->uniqueName();
QStringList entry(stringFromKeys(shortcut->keys()));
@ -491,9 +422,9 @@ void Component::writeSettings(KConfigGroup& configGroup) const
entry.append(shortcut->friendlyName());
contextGroup.writeEntry(shortcut->uniqueName(), entry);
}
}
}
}
#include "moc_component.cpp"

View file

@ -37,23 +37,17 @@ namespace KdeDGlobalAccel {
* @author Michael Jansen <kde@michael-jansen.biz>
*/
class Component : public QObject
{
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.kglobalaccel.Component")
Q_SCRIPTABLE Q_PROPERTY( QString friendlyName READ friendlyName )
Q_SCRIPTABLE Q_PROPERTY( QString uniqueName READ uniqueName )
public:
//! Creates a new component. The component will be registered with @p
//! registry if specified and registered with dbus.
Component(
const QString &uniqueName,
const QString &friendlyName,
GlobalShortcutsRegistry *registry = NULL);
Component(const QString &uniqueName, const QString &friendlyName, GlobalShortcutsRegistry *registry = NULL);
~Component();
bool activateGlobalShortcutContext(const QString &uniqueName);
@ -93,17 +87,12 @@ public:
//! Returns the shortcut by unique name. Only the active context is
//! searched.
GlobalShortcut *getShortcutByName(
const QString &uniqueName,
const QString &context = "default") const;
GlobalShortcut *getShortcutByName(const QString &uniqueName, const QString &context = "default") const;
/**
* Check if @a key is available for component @p component
*/
bool isShortcutAvailable(
int key,
const QString &component,
const QString &context) const;
bool isShortcutAvailable(int key, const QString &component, const QString &context) const;
//! Load the settings from config group @p config
void loadSettings(KConfigGroup &config);
@ -119,7 +108,6 @@ public:
void writeSettings(KConfigGroup &config) const;
public Q_SLOTS:
// For dbus Q_SCRIPTABLE has to be on slots. Scriptable methods are not
// exported.
@ -161,12 +149,10 @@ public Q_SLOTS:
Q_SCRIPTABLE void invokeShortcut(const QString &shortcutName, const QString &context = "default");
Q_SIGNALS:
//! Signals that a action for this component was triggered
Q_SCRIPTABLE void globalShortcutPressed(const QString &componentUnique, const QString &shortcutUnique, qlonglong timestamp);
private:
QString _uniqueName;
//the name as it would be found in a magazine article about the application,
//possibly localized if a localized name exists.
@ -176,9 +162,8 @@ private:
GlobalShortcutContext *_current;
QHash<QString, GlobalShortcutContext *> _contexts;
};
};
}
#endif /* #ifndef COMPONENT_H */

View file

@ -28,42 +28,37 @@
GlobalShortcut::GlobalShortcut()
: _isPresent(false)
,_isRegistered(false)
,_isFresh(true)
,_context(NULL)
,_uniqueName()
,_friendlyName()
,_keys()
,_defaultKeys()
{}
: _isPresent(false),
_isRegistered(false),
_isFresh(true),
_context(NULL),
_uniqueName(),
_friendlyName(),
_keys(),
_defaultKeys()
{
}
GlobalShortcut::GlobalShortcut(
const QString &uniqueName,
const QString &friendlyName,
GlobalShortcutContext *context)
: _isPresent(false)
,_isRegistered(false)
,_isFresh(true)
,_context(context)
,_uniqueName(uniqueName)
,_friendlyName(friendlyName)
,_keys()
,_defaultKeys()
{
GlobalShortcut::GlobalShortcut(const QString &uniqueName, const QString &friendlyName, GlobalShortcutContext *context)
: _isPresent(false),
_isRegistered(false),
_isFresh(true),
_context(context),
_uniqueName(uniqueName),
_friendlyName(friendlyName),
_keys(),
_defaultKeys()
{
context->addShortcut(this);
}
}
GlobalShortcut::~GlobalShortcut()
{
{
setInactive();
}
}
GlobalShortcut::operator KGlobalShortcutInfo () const
{
{
KGlobalShortcutInfo info;
info.d->uniqueName = _uniqueName;
info.d->friendlyName = _friendlyName;
@ -71,179 +66,144 @@ GlobalShortcut::operator KGlobalShortcutInfo () const
info.d->contextFriendlyName = context()->friendlyName();
info.d->componentUniqueName = context()->component()->uniqueName();
info.d->componentFriendlyName = context()->component()->friendlyName();
Q_FOREACH (int key, _keys)
{
Q_FOREACH (int key, _keys) {
info.d->keys.append(QKeySequence(key));
}
Q_FOREACH (int key, _defaultKeys)
{
info.d->defaultKeys.append(QKeySequence(key));
}
return info;
}
Q_FOREACH (int key, _defaultKeys) {
info.d->defaultKeys.append(QKeySequence(key));
}
return info;
}
bool GlobalShortcut::isActive() const
{
{
return _isRegistered;
}
}
bool GlobalShortcut::isFresh() const
{
{
return _isFresh;
}
}
bool GlobalShortcut::isPresent() const
{
{
return _isPresent;
}
}
bool GlobalShortcut::isSessionShortcut() const
{
{
return uniqueName().startsWith(QLatin1String("_k_session:"));
}
}
void GlobalShortcut::setIsFresh(bool value)
{
{
_isFresh = value;
}
}
void GlobalShortcut::setIsPresent(bool value)
{
{
// (de)activate depending on old/new value
_isPresent = value;
value
? setActive()
: setInactive();
}
value ? setActive() : setInactive();
}
GlobalShortcutContext *GlobalShortcut::context()
{
{
return _context;
}
}
GlobalShortcutContext const *GlobalShortcut::context() const
{
{
return _context;
}
}
QString GlobalShortcut::uniqueName() const
{
{
return _uniqueName;
}
}
void GlobalShortcut::unRegister()
{
{
return _context->component()->unregisterShortcut(uniqueName());
}
}
QString GlobalShortcut::friendlyName() const
{
{
return _friendlyName;
}
}
void GlobalShortcut::setFriendlyName(const QString &name)
{
{
_friendlyName = name;
}
}
QList<int> GlobalShortcut::keys() const
{
{
return _keys;
}
}
void GlobalShortcut::setKeys(const QList<int> newKeys)
{
{
bool active = _isRegistered;
if (active)
{
if (active) {
setInactive();
}
}
_keys = QList<int>();
Q_FOREACH(int key, newKeys)
{
if (key!=0 && !GlobalShortcutsRegistry::self()->getShortcutByKey(key))
{
Q_FOREACH(int key, newKeys) {
if (key !=0 && !GlobalShortcutsRegistry::self()->getShortcutByKey(key)) {
_keys.append(key);
}
else
{
kDebug() << _uniqueName << "skipping because key" << QKeySequence(key).toString() << "is already taken";
} else {
kDebug() << _uniqueName << "skipping because key" << QKeySequence(key).toString() << "(" << key << ") is already taken";
_keys.append(0);
}
}
if (active)
{
setActive();
}
}
if (active) {
setActive();
}
}
QList<int> GlobalShortcut::defaultKeys() const
{
{
return _defaultKeys;
}
}
void GlobalShortcut::setDefaultKeys(const QList<int> newKeys)
{
{
_defaultKeys = newKeys;
}
}
void GlobalShortcut::setActive()
{
if (!_isPresent || _isRegistered)
{
{
if (!_isPresent || _isRegistered) {
// The corresponding application is not present or the keys are
// already grabbed
return;
}
}
Q_FOREACH( int key, _keys)
{
if (key != 0 && !GlobalShortcutsRegistry::self()->registerKey(key, this))
{
Q_FOREACH (int key, _keys) {
if (key != 0 && !GlobalShortcutsRegistry::self()->registerKey(key, this)) {
kDebug() << uniqueName() << ": Failed to register " << QKeySequence(key).toString();
}
}
}
_isRegistered = true;
}
}
void GlobalShortcut::setInactive()
{
if (!_isRegistered)
{
{
if (!_isRegistered) {
// The keys are not grabbed currently
return;
}
Q_FOREACH( int key, _keys)
{
if (key != 0 && !GlobalShortcutsRegistry::self()->unregisterKey(key, this))
{
kDebug() << uniqueName() << ": Failed to unregister " << QKeySequence(key).toString();
}
}
_isRegistered = false;
}
Q_FOREACH (int key, _keys) {
if (key != 0 && !GlobalShortcutsRegistry::self()->unregisterKey(key, this)) {
kDebug() << uniqueName() << ": Failed to unregister " << QKeySequence(key).toString();
}
}
_isRegistered = false;
}

View file

@ -37,9 +37,8 @@ class GlobalShortcutContext;
* @author Michael Jansen <kde@michael-jansen.biz>
*/
class GlobalShortcut
{
{
public:
GlobalShortcut(const QString &uniqueName, const QString &friendlyName, GlobalShortcutContext *context);
GlobalShortcut();
@ -97,15 +96,14 @@ public:
void unRegister();
private:
//! means the associated application is present.
bool _isPresent:1;
bool _isPresent;
//! means the shortcut is registered with GlobalShortcutsRegistry
bool _isRegistered:1;
bool _isRegistered;
//! means the shortcut is new
bool _isFresh:1;
bool _isFresh;
//! The context the shortcut belongs too
GlobalShortcutContext *_context;
@ -115,7 +113,6 @@ private:
QList<int> _keys;
QList<int> _defaultKeys;
};
};
#endif /* #ifndef GLOBALSHORTCUT_H */

View file

@ -22,95 +22,79 @@
#include "kdebug.h"
GlobalShortcutContext::GlobalShortcutContext(
const QString &uniqueName,
const QString &friendlyName,
KdeDGlobalAccel::Component *component)
: _uniqueName(uniqueName),
_friendlyName(friendlyName),
_component(component),
_actions()
{}
GlobalShortcutContext::GlobalShortcutContext(const QString &uniqueName, const QString &friendlyName, KdeDGlobalAccel::Component *component)
: _uniqueName(uniqueName),
_friendlyName(friendlyName),
_component(component),
_actions()
{
}
GlobalShortcutContext::~GlobalShortcutContext()
{
{
qDeleteAll(_actions); _actions.clear();
}
}
void GlobalShortcutContext::addShortcut(GlobalShortcut *shortcut)
{
{
_actions.insert(shortcut->uniqueName(), shortcut);
}
}
QList<KGlobalShortcutInfo> GlobalShortcutContext::allShortcutInfos() const
{
{
QList<KGlobalShortcutInfo> rc;
Q_FOREACH (GlobalShortcut *shortcut, _actions)
{
Q_FOREACH (GlobalShortcut *shortcut, _actions) {
rc.append(static_cast<KGlobalShortcutInfo>(*shortcut));
}
return rc;
}
return rc;
}
KdeDGlobalAccel::Component const *GlobalShortcutContext::component() const
{
{
return _component;
}
}
KdeDGlobalAccel::Component *GlobalShortcutContext::component()
{
{
return _component;
}
}
QString GlobalShortcutContext::friendlyName() const
{
{
return _friendlyName;
}
}
GlobalShortcut *GlobalShortcutContext::getShortcutByKey(int key) const
{
{
// Qt triggers both shortcuts that include Shift+Backtab and Shift+Tab
// when user presses Shift+Tab. Do the same here.
int keySym = key & ~Qt::KeyboardModifierMask;
int keyMod = key & Qt::KeyboardModifierMask;
if ((keyMod & Qt::SHIFT) && (keySym == Qt::Key_Backtab ||
keySym == Qt::Key_Tab))
{
Q_FOREACH(GlobalShortcut *sc, _actions)
{
if ((keyMod & Qt::SHIFT) && (keySym == Qt::Key_Backtab || keySym == Qt::Key_Tab)) {
Q_FOREACH(GlobalShortcut *sc, _actions) {
if (sc->keys().contains(keyMod | Qt::Key_Tab) ||
sc->keys().contains(keyMod | Qt::Key_Backtab))
sc->keys().contains(keyMod | Qt::Key_Backtab)) {
return sc;
}
}
else
{
Q_FOREACH(GlobalShortcut *sc, _actions)
{
if (sc->keys().contains(key)) return sc;
} else {
Q_FOREACH(GlobalShortcut *sc, _actions) {
if (sc->keys().contains(key)) {
return sc;
}
}
return NULL;
}
return NULL;
}
GlobalShortcut *GlobalShortcutContext::takeShortcut(GlobalShortcut *shortcut)
{
{
// Try to take the shortcut. Result could be null if the shortcut doesn't
// belong to this component.
return _actions.take(shortcut->uniqueName());
}
}
QString GlobalShortcutContext::uniqueName() const
{
{
return _uniqueName;
}
}

View file

@ -33,16 +33,12 @@ class GlobalShortcut;
* @author Michael Jansen <kde@michael-jansen.biz>
*/
class GlobalShortcutContext
{
{
public:
/**
* Default constructor
*/
GlobalShortcutContext(
const QString &uniqueName,
const QString &friendlyName,
KdeDGlobalAccel::Component *component );
GlobalShortcutContext(const QString &uniqueName, const QString &friendlyName, KdeDGlobalAccel::Component *component );
/**
* Destructor
@ -87,5 +83,4 @@ private:
QHash<QString, GlobalShortcut*> _actions;
};
#endif /* #ifndef GLOBALSHORTCUTCONTEXT_H */

View file

@ -38,154 +38,132 @@
#endif
GlobalShortcutsRegistry::GlobalShortcutsRegistry()
: QObject()
,_active_keys()
,_components()
,_manager(new KGlobalAccelImpl(this))
,_config("kglobalshortcutsrc", KConfig::SimpleConfig)
{
: QObject(),
_active_keys(),
_components(),
_manager(new KGlobalAccelImpl(this)),
_config("kglobalshortcutsrc", KConfig::SimpleConfig)
{
_manager->setEnabled(true);
}
}
GlobalShortcutsRegistry::~GlobalShortcutsRegistry()
{
{
_manager->setEnabled(false);
// Ungrab all keys. We don't go over GlobalShortcuts because
// GlobalShortcutsRegistry::self() doesn't work anymore.
Q_FOREACH (const int key, _active_keys.keys())
{
Q_FOREACH (const int key, _active_keys.keys()) {
_manager->grabKey(key, false);
}
_active_keys.clear();
}
_active_keys.clear();
}
KdeDGlobalAccel::Component *GlobalShortcutsRegistry::addComponent(KdeDGlobalAccel::Component *component)
{
if (_components.value(component->uniqueName()))
{
{
if (_components.value(component->uniqueName())) {
Q_ASSERT_X(false, "GlobalShortcutsRegistry::addComponent", "component already registered?!?!");
return _components.value(component->uniqueName());
}
}
_components.insert(component->uniqueName(), component);
QDBusConnection conn(QDBusConnection::sessionBus());
conn.registerObject(
component->dbusPath().path(),
component,
QDBusConnection::ExportScriptableContents);
conn.registerObject(component->dbusPath().path(), component, QDBusConnection::ExportScriptableContents);
return component;
}
}
void GlobalShortcutsRegistry::activateShortcuts()
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
{
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components) {
component->activateShortcuts();
}
}
}
QList<KdeDGlobalAccel::Component*> GlobalShortcutsRegistry::allMainComponents() const
{
{
return _components.values();
}
}
void GlobalShortcutsRegistry::clear()
{
Q_FOREACH(KdeDGlobalAccel::Component *component, _components)
{
{
Q_FOREACH(KdeDGlobalAccel::Component *component, _components) {
delete component;
}
}
_components.clear();
// The shortcuts should have deregistered themselves
Q_ASSERT(_active_keys.isEmpty());
}
}
QDBusObjectPath GlobalShortcutsRegistry::dbusPath() const
{
{
return _dbusPath;
}
}
void GlobalShortcutsRegistry::deactivateShortcuts(bool temporarily)
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
{
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components) {
component->deactivateShortcuts(temporarily);
}
}
}
GlobalShortcut *GlobalShortcutsRegistry::getActiveShortcutByKey(int key) const
{
{
return _active_keys.value(key);
}
}
KdeDGlobalAccel::Component *GlobalShortcutsRegistry::getComponent(const QString &uniqueName)
{
{
return _components.value(uniqueName);
}
}
GlobalShortcut *GlobalShortcutsRegistry::getShortcutByKey(int key) const
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
{
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components) {
GlobalShortcut *rc = component->getShortcutByKey(key);
if (rc) return rc;
if (rc) {
return rc;
}
return NULL;
}
return NULL;
}
QList<GlobalShortcut*> GlobalShortcutsRegistry::getShortcutsByKey(int key) const
{
{
QList<GlobalShortcut *> rc;
Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components) {
rc = component->getShortcutsByKey(key);
if (!rc.isEmpty()) return rc;
if (!rc.isEmpty()) {
return rc;
}
return rc;
}
return rc;
}
bool GlobalShortcutsRegistry::isShortcutAvailable(
int shortcut,
const QString &componentName,
const QString &contextName) const
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components)
{
if (!component->isShortcutAvailable(shortcut, componentName, contextName))
bool GlobalShortcutsRegistry::isShortcutAvailable(int shortcut, const QString &componentName, const QString &contextName) const
{
Q_FOREACH (KdeDGlobalAccel::Component *component, _components) {
if (!component->isShortcutAvailable(shortcut, componentName, contextName)) {
return false;
}
return true;
}
return true;
}
GlobalShortcutsRegistry * GlobalShortcutsRegistry::self()
{
K_GLOBAL_STATIC( GlobalShortcutsRegistry, self );
{
K_GLOBAL_STATIC(GlobalShortcutsRegistry, self);
return self;
}
}
bool GlobalShortcutsRegistry::keyPressed(int keyQt)
{
{
GlobalShortcut *shortcut = getShortcutByKey(keyQt);
if (!shortcut)
{
if (!shortcut) {
// This can happen for example with the ALT-Print shortcut of kwin.
// ALT+PRINT is SYSREQ on my keyboard. So we grab something we think
// is ALT+PRINT but symXToKeyQt and modXToQt make ALT+SYSREQ of it
@ -194,14 +172,12 @@ bool GlobalShortcutsRegistry::keyPressed(int keyQt)
// In production mode just do nothing.
return false;
}
else if (!shortcut->isActive())
{
} else if (!shortcut->isActive()) {
kDebug() << "Got inactive key" << QKeySequence(keyQt).toString();
// In production mode just do nothing.
return false;
}
}
kDebug() << QKeySequence(keyQt).toString() << "=" << shortcut->uniqueName();
@ -221,15 +197,9 @@ bool GlobalShortcutsRegistry::keyPressed(int keyQt)
shortcut->context()->component()->emitGlobalShortcutPressed( *shortcut );
// Then do anything else
KNotification *notification = new KNotification(
"globalshortcutpressed",
KNotification::CloseOnTimeout);
notification->setText(
i18n("The global shortcut for %1 was issued.", shortcut->friendlyName()));
KNotification *notification = new KNotification("globalshortcutpressed", KNotification::CloseOnTimeout);
notification->setText(i18n("The global shortcut for %1 was issued.", shortcut->friendlyName()));
notification->addContext( "application", shortcut->context()->component()->friendlyName() );
notification->sendEvent();
return true;
@ -237,9 +207,8 @@ bool GlobalShortcutsRegistry::keyPressed(int keyQt)
void GlobalShortcutsRegistry::loadSettings()
{
foreach (const QString &groupName, _config.groupList())
{
{
Q_FOREACH (const QString &groupName, _config.groupList()) {
kDebug() << "Loading group " << groupName;
Q_ASSERT(groupName.indexOf('\x1d')==-1);
@ -254,103 +223,87 @@ void GlobalShortcutsRegistry::loadSettings()
// that
QString friendlyName;
KConfigGroup friendlyGroup(&configGroup, "Friendly Name");
if (friendlyGroup.isValid())
{
if (friendlyGroup.isValid()) {
friendlyName = friendlyGroup.readEntry("Friendly Name");
friendlyGroup.deleteGroup();
}
else
{
} else {
friendlyName = configGroup.readEntry("_k_friendly_name");
}
}
// Create the component
KdeDGlobalAccel::Component *component = new KdeDGlobalAccel::Component(
groupName,
friendlyName,
this);
KdeDGlobalAccel::Component *component = new KdeDGlobalAccel::Component(groupName, friendlyName, this);
// Now load the contexts
Q_FOREACH(const QString& context, configGroup.groupList())
{
Q_FOREACH(const QString& context, configGroup.groupList()) {
// Skip the friendly name group
if (context=="Friendly Name") continue;
if (context == "Friendly Name") {
continue;
}
KConfigGroup contextGroup(&configGroup, context);
QString contextFriendlyName = contextGroup.readEntry("_k_friendly_name");
component->createGlobalShortcutContext(context, contextFriendlyName);
component->activateGlobalShortcutContext(context);
component->loadSettings(contextGroup);
}
}
// Load the default context
component->activateGlobalShortcutContext("default");
component->loadSettings(configGroup);
}
}
}
void GlobalShortcutsRegistry::grabKeys()
{
{
activateShortcuts();
}
}
bool GlobalShortcutsRegistry::registerKey(int key, GlobalShortcut *shortcut)
{
if (key == 0)
{
{
if (key == 0) {
kDebug() << shortcut->uniqueName() << ": Key '" << QKeySequence(key).toString()
<< "' already taken by " << _active_keys.value(key)->uniqueName() << ".";
return false;
}
else if (_active_keys.value(key))
{
} else if (_active_keys.value(key)) {
kDebug() << shortcut->uniqueName() << ": Attempt to register key 0.";
return false;
}
}
kDebug() << "Registering key" << QKeySequence(key).toString() << "for"
<< shortcut->context()->component()->uniqueName() << ":" << shortcut->uniqueName();
_active_keys.insert(key, shortcut);
return _manager->grabKey(key, true);
}
}
void GlobalShortcutsRegistry::setAccelManager(KGlobalAccelImpl *manager)
{
{
_manager = manager;
}
}
void GlobalShortcutsRegistry::setDBusPath(const QDBusObjectPath &path)
{
{
_dbusPath = path;
}
}
KdeDGlobalAccel::Component *GlobalShortcutsRegistry::takeComponent(KdeDGlobalAccel::Component *component)
{
{
QDBusConnection conn(QDBusConnection::sessionBus());
conn.unregisterObject(component->dbusPath().path());
return _components.take(component->uniqueName());
}
}
void GlobalShortcutsRegistry::ungrabKeys()
{
{
deactivateShortcuts();
}
}
bool GlobalShortcutsRegistry::unregisterKey(int key, GlobalShortcut *shortcut)
{
if (_active_keys.value(key)!=shortcut)
{
{
if (_active_keys.value(key) != shortcut) {
// The shortcut doesn't own the key or the key isn't grabbed
return false;
}
}
kDebug() << "Unregistering key" << QKeySequence(key).toString() << "for"
<< shortcut->context()->component()->uniqueName() << ":" << shortcut->uniqueName();
@ -358,29 +311,21 @@ bool GlobalShortcutsRegistry::unregisterKey(int key, GlobalShortcut *shortcut)
_manager->grabKey(key, false);
_active_keys.take(key);
return true;
}
}
void GlobalShortcutsRegistry::writeSettings() const
{
Q_FOREACH(
const KdeDGlobalAccel::Component *component,
GlobalShortcutsRegistry::self()->allMainComponents())
{
{
Q_FOREACH(const KdeDGlobalAccel::Component *component, GlobalShortcutsRegistry::self()->allMainComponents()) {
KConfigGroup configGroup(&_config, component->uniqueName());
if (component->allShortcuts().isEmpty())
{
if (component->allShortcuts().isEmpty()) {
configGroup.deleteGroup();
delete component;
}
else
{
} else {
component->writeSettings(configGroup);
}
}
_config.sync();
}
_config.sync();
}
#include "moc_globalshortcutsregistry.cpp"

View file

@ -29,9 +29,9 @@ class GlobalShortcut;
class KGlobalAccelImpl;
namespace KdeDGlobalAccel
{
{
class Component;
}
}
/**
* Global Shortcut Registry.
@ -49,13 +49,11 @@ namespace KdeDGlobalAccel
* @author Michael Jansen <kde@michael-jansen.biz>
*/
class GlobalShortcutsRegistry : public QObject
{
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.KdedGlobalAccel.GlobalShortcutsRegistry")
public:
/**
* Activate all shortcuts having their application present.
*/
@ -76,7 +74,6 @@ public:
*/
void deactivateShortcuts(bool temporarily=false);
/**
* Get the shortcut corresponding to key. Only active shortcut are
* considered.
@ -110,10 +107,7 @@ public:
* It is available if not used by another component in any context or used
* by @p component only in not active contexts.
*/
bool isShortcutAvailable(
int shortcut,
const QString &component,
const QString &context) const;
bool isShortcutAvailable(int shortcut, const QString &component, const QString &context) const;
static GlobalShortcutsRegistry *self();
@ -126,7 +120,6 @@ public:
bool unregisterKey(int key, GlobalShortcut *shortcut);
public Q_SLOTS:
void clear();
void loadSettings();
@ -140,7 +133,6 @@ public Q_SLOTS:
void ungrabKeys();
private:
friend class KdeDGlobalAccel::Component;
friend class KGlobalAccelImpl;
@ -163,7 +155,7 @@ private:
mutable KConfig _config;
QDBusObjectPath _dbusPath;
};
};
#endif /* #ifndef GLOBALSHORTCUTSREGISTRY_H */

View file

@ -47,12 +47,12 @@
#include <fixx11h.h>
extern "C" {
static int XGrabErrorHandler( Display *, XErrorEvent *e ) {
if ( e->error_code != BadAccess ) {
kWarning() << "grabKey: got X error " << e->type << " instead of BadAccess\n";
}
return 1;
}
static int XGrabErrorHandler(Display *, XErrorEvent *e) {
if (e->error_code != BadAccess) {
kWarning() << "grabKey: got X error " << e->type << " instead of BadAccess";
}
return 1;
}
}
// g_keyModMaskXAccel
@ -66,219 +66,221 @@ static uint g_keyModMaskXOnOrOff = 0;
static void calculateGrabMasks()
{
g_keyModMaskXAccel = KKeyServer::accelModMaskX();
g_keyModMaskXOnOrOff =
KKeyServer::modXLock() |
KKeyServer::modXNumLock() |
KKeyServer::modXScrollLock() |
KKeyServer::modXModeSwitch();
//kDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel
// << "g_keyModMaskXOnOrOff = " << g_keyModMaskXOnOrOff << endl;
g_keyModMaskXAccel = KKeyServer::accelModMaskX();
g_keyModMaskXOnOrOff =
KKeyServer::modXLock() |
KKeyServer::modXNumLock() |
KKeyServer::modXScrollLock() |
KKeyServer::modXModeSwitch();
//kDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel
// << "g_keyModMaskXOnOrOff = " << g_keyModMaskXOnOrOff << endl;
}
//----------------------------------------------------
KGlobalAccelImpl::KGlobalAccelImpl(GlobalShortcutsRegistry *owner)
: m_owner(owner)
: m_owner(owner)
{
calculateGrabMasks();
calculateGrabMasks();
}
bool KGlobalAccelImpl::grabKey( int keyQt, bool grab )
bool KGlobalAccelImpl::grabKey(int keyQt, bool grab)
{
if( !keyQt ) {
if( !keyQt ) {
kDebug() << "Tried to grab key with null code.";
return false;
}
return false;
}
int keyCodeX;
uint keyModX;
uint keySymX;
int keyCodeX;
uint keyModX;
uint keySymX;
// Resolve the modifier
if( !KKeyServer::keyQtToModX(keyQt, &keyModX) ) {
kDebug() << "keyQt (0x" << hex << keyQt << ") failed to resolve to x11 modifier";
return false;
}
// Resolve the modifier
if (!KKeyServer::keyQtToModX(keyQt, &keyModX)) {
kDebug() << "keyQt (0x" << hex << keyQt << ") failed to resolve to x11 modifier";
return false;
}
// Resolve the X symbol
if( !KKeyServer::keyQtToSymX(keyQt, (int *)&keySymX) ) {
kDebug() << "keyQt (0x" << hex << keyQt << ") failed to resolve to x11 keycode";
return false;
}
// Resolve the X symbol
if (!KKeyServer::keyQtToSymX(keyQt, (int *)&keySymX) ) {
kDebug() << "keyQt (0x" << hex << keyQt << ") failed to resolve to x11 keycode";
return false;
}
keyCodeX = XKeysymToKeycode( QX11Info::display(), keySymX );
// Check if shift needs to be added to the grab since KKeySequenceWidget
// can remove shift for some keys. (all the %&* and such)
if( !(keyQt & Qt::SHIFT) &&
!KKeyServer::isShiftAsModifierAllowed( keyQt ) &&
keyCodeX = XKeysymToKeycode( QX11Info::display(), keySymX);
// Check if shift needs to be added to the grab since KKeySequenceWidget
// can remove shift for some keys. (all the %&* and such)
if( !(keyQt & Qt::SHIFT) && !KKeyServer::isShiftAsModifierAllowed(keyQt) &&
#ifdef HAVE_XKB
keySymX != XkbKeycodeToKeysym( QX11Info::display(), keyCodeX, 0, 0 ) &&
keySymX == XkbKeycodeToKeysym( QX11Info::display(), keyCodeX, 1, 0 ) )
keySymX != XkbKeycodeToKeysym(QX11Info::display(), keyCodeX, 0, 0) &&
keySymX == XkbKeycodeToKeysym(QX11Info::display(), keyCodeX, 1, 0))
#else
keySymX != XKeycodeToKeysym( QX11Info::display(), keyCodeX, 0 ) &&
keySymX == XKeycodeToKeysym( QX11Info::display(), keyCodeX, 1 ) )
keySymX != XKeycodeToKeysym(QX11Info::display(), keyCodeX, 0) &&
keySymX == XKeycodeToKeysym(QX11Info::display(), keyCodeX, 1))
#endif
{
kDebug() << "adding shift to the grab";
keyModX |= KKeyServer::modXShift();
}
{
kDebug() << "adding shift to the grab";
keyModX |= KKeyServer::modXShift();
}
keyModX &= g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod
keyModX &= g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod
if( !keyCodeX ) {
kDebug() << "keyQt (0x" << hex << keyQt << ") was resolved to x11 keycode 0";
return false;
}
if (!keyCodeX) {
kDebug() << "keyQt (0x" << hex << keyQt << ") was resolved to x11 keycode 0";
return false;
}
KXErrorHandler handler( XGrabErrorHandler );
KXErrorHandler handler(XGrabErrorHandler);
// We'll have to grab 8 key modifier combinations in order to cover all
// combinations of CapsLock, NumLock, ScrollLock.
// Does anyone with more X-savvy know how to set a mask on QX11Info::appRootWindow so that
// the irrelevant bits are always ignored and we can just make one XGrabKey
// call per accelerator? -- ellis
// We'll have to grab 8 key modifier combinations in order to cover all
// combinations of CapsLock, NumLock, ScrollLock.
// Does anyone with more X-savvy know how to set a mask on QX11Info::appRootWindow so that
// the irrelevant bits are always ignored and we can just make one XGrabKey
// call per accelerator? -- ellis
#ifndef NDEBUG
QString sDebug = QString("\tcode: 0x%1 state: 0x%2 | ").arg(keyCodeX,0,16).arg(keyModX,0,16);
QString sDebug = QString("\tcode: 0x%1 state: 0x%2 | ").arg(keyCodeX,0,16).arg(keyModX,0,16);
#endif
uint keyModMaskX = ~g_keyModMaskXOnOrOff;
for( uint irrelevantBitsMask = 0; irrelevantBitsMask <= 0xff; irrelevantBitsMask++ ) {
if( (irrelevantBitsMask & keyModMaskX) == 0 ) {
uint keyModMaskX = ~g_keyModMaskXOnOrOff;
for (uint irrelevantBitsMask = 0; irrelevantBitsMask <= 0xff; irrelevantBitsMask++) {
if ((irrelevantBitsMask & keyModMaskX) == 0) {
#ifndef NDEBUG
sDebug += QString("0x%3, ").arg(irrelevantBitsMask, 0, 16);
sDebug += QString("0x%3, ").arg(irrelevantBitsMask, 0, 16);
#endif
if( grab )
XGrabKey( QX11Info::display(), keyCodeX, keyModX | irrelevantBitsMask,
QX11Info::appRootWindow(), True, GrabModeAsync, GrabModeSync );
else
XUngrabKey( QX11Info::display(), keyCodeX, keyModX | irrelevantBitsMask, QX11Info::appRootWindow() );
}
}
if (grab) {
XGrabKey(QX11Info::display(), keyCodeX, keyModX | irrelevantBitsMask,
QX11Info::appRootWindow(), True, GrabModeAsync, GrabModeSync);
} else {
XUngrabKey(QX11Info::display(), keyCodeX, keyModX | irrelevantBitsMask, QX11Info::appRootWindow());
}
}
}
bool failed = false;
if( grab ) {
failed = handler.error( true ); // sync now
if( failed ) {
kDebug() << "grab failed!\n";
for( uint m = 0; m <= 0xff; m++ ) {
if(( m & keyModMaskX ) == 0 )
XUngrabKey( QX11Info::display(), keyCodeX, keyModX | m, QX11Info::appRootWindow() );
}
}
}
bool failed = false;
if (grab) {
failed = handler.error(true); // sync now
if (failed) {
kDebug() << "grab failed!";
for (uint m = 0; m <= 0xff; m++ ) {
if ((m & keyModMaskX) == 0) {
XUngrabKey(QX11Info::display(), keyCodeX, keyModX | m, QX11Info::appRootWindow());
}
}
}
}
return !failed;
return !failed;
}
bool KGlobalAccelImpl::x11Event( XEvent* event )
{
switch( event->type ) {
switch( event->type ) {
case MappingNotify: {
kDebug() << "Got XMappingNotify event";
XRefreshKeyboardMapping(&event->xmapping);
x11MappingNotify();
return true;
}
case XKeyPress: {
kDebug() << "Got XKeyPress event";
return x11KeyPress(event);
}
default: {
// We get all XEvents. Just ignore them.
return false;
}
}
case MappingNotify:
kDebug() << "Got XMappingNotify event";
XRefreshKeyboardMapping(&event->xmapping);
x11MappingNotify();
return true;
case XKeyPress:
kDebug() << "Got XKeyPress event";
return x11KeyPress(event);
default:
// We get all XEvents. Just ignore them.
return false;
}
Q_ASSERT(false);
return false;
Q_ASSERT(false);
return false;
}
void KGlobalAccelImpl::x11MappingNotify()
{
// Maybe the X modifier map has been changed.
// uint oldKeyModMaskXAccel = g_keyModMaskXAccel;
// uint oldKeyModMaskXOnOrOff = g_keyModMaskXOnOrOff;
// Maybe the X modifier map has been changed.
// uint oldKeyModMaskXAccel = g_keyModMaskXAccel;
// uint oldKeyModMaskXOnOrOff = g_keyModMaskXOnOrOff;
// First ungrab all currently grabbed keys. This is needed because we
// store the keys as qt keycodes and use KKeyServer to map them to x11 key
// codes. After calling KKeyServer::initializeMods() they could map to
// different keycodes.
m_owner->ungrabKeys();
// First ungrab all currently grabbed keys. This is needed because we
// store the keys as qt keycodes and use KKeyServer to map them to x11 key
// codes. After calling KKeyServer::initializeMods() they could map to
// different keycodes.
m_owner->ungrabKeys();
KKeyServer::initializeMods();
calculateGrabMasks();
KKeyServer::initializeMods();
calculateGrabMasks();
m_owner->grabKeys();
m_owner->grabKeys();
}
bool KGlobalAccelImpl::x11KeyPress( const XEvent *pEvent )
{
if (QWidget::keyboardGrabber() || QApplication::activePopupWidget()) {
kWarning() << "kglobalacceld should be popup and keyboard grabbing free!";
}
if (QWidget::keyboardGrabber() || QApplication::activePopupWidget()) {
kWarning() << "kglobalacceld should be popup and keyboard grabbing free!";
}
// Keyboard needs to be ungrabed after XGrabKey() activates the grab,
// otherwise it becomes frozen.
XUngrabKeyboard( QX11Info::display(), CurrentTime );
XFlush( QX11Info::display()); // avoid X(?) bug
// Keyboard needs to be ungrabed after XGrabKey() activates the grab,
// otherwise it becomes frozen.
XUngrabKeyboard(QX11Info::display(), CurrentTime);
XFlush(QX11Info::display()); // avoid X(?) bug
uchar keyCodeX = pEvent->xkey.keycode;
uint keyModX = pEvent->xkey.state & (g_keyModMaskXAccel | KKeyServer::MODE_SWITCH);
uchar keyCodeX = pEvent->xkey.keycode;
uint keyModX = pEvent->xkey.state & (g_keyModMaskXAccel | KKeyServer::MODE_SWITCH);
KeySym keySym;
XLookupString( (XKeyEvent*) pEvent, 0, 0, &keySym, 0 );
uint keySymX = (uint)keySym;
KeySym keySym;
XLookupString((XKeyEvent*)pEvent, 0, 0, &keySym, 0);
uint keySymX = (uint)keySym;
// If numlock is active and a keypad key is pressed, XOR the SHIFT state.
// e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left.
if( pEvent->xkey.state & KKeyServer::modXNumLock() ) {
// If numlock is active and a keypad key is pressed, XOR the SHIFT state.
// e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left.
if( pEvent->xkey.state & KKeyServer::modXNumLock() ) {
#ifdef HAVE_XKB
uint sym = XkbKeycodeToKeysym( QX11Info::display(), keyCodeX, 0, 0 );
uint sym = XkbKeycodeToKeysym(QX11Info::display(), keyCodeX, 0, 0);
#else
uint sym = XKeycodeToKeysym( QX11Info::display(), keyCodeX, 0 );
uint sym = XKeycodeToKeysym(QX11Info::display(), keyCodeX, 0);
#endif
// If this is a keypad key,
if( sym >= XK_KP_Space && sym <= XK_KP_9 ) {
switch( sym ) {
// If this is a keypad key,
if (sym >= XK_KP_Space && sym <= XK_KP_9) {
switch(sym) {
// Leave the following keys unaltered
// FIXME: The proper solution is to see which keysyms don't change when shifted.
case XK_KP_Multiply:
case XK_KP_Add:
case XK_KP_Subtract:
case XK_KP_Divide: {
break;
}
default: {
keyModX ^= KKeyServer::modXShift();
}
}
}
}
// Leave the following keys unaltered
// FIXME: The proper solution is to see which keysyms don't change when shifted.
case XK_KP_Multiply:
case XK_KP_Add:
case XK_KP_Subtract:
case XK_KP_Divide:
break;
int keyCodeQt;
int keyModQt;
KKeyServer::symXToKeyQt(keySymX, &keyCodeQt);
KKeyServer::modXToQt(keyModX, &keyModQt);
default:
keyModX ^= KKeyServer::modXShift();
}
}
}
if( keyModQt & Qt::SHIFT && !KKeyServer::isShiftAsModifierAllowed(keyCodeQt)) {
kDebug() << "removing shift modifier";
keyModQt &= ~Qt::SHIFT;
}
int keyCodeQt;
int keyModQt;
KKeyServer::symXToKeyQt(keySymX, &keyCodeQt);
KKeyServer::modXToQt(keyModX, &keyModQt);
int keyQt = keyCodeQt | keyModQt;
if( keyModQt & Qt::SHIFT && !KKeyServer::isShiftAsModifierAllowed( keyCodeQt ) ) {
kDebug() << "removing shift modifier";
keyModQt &= ~Qt::SHIFT;
}
int keyQt = keyCodeQt | keyModQt;
// All that work for this hey... argh...
return m_owner->keyPressed(keyQt);
// All that work for this hey... argh...
return m_owner->keyPressed(keyQt);
}
void KGlobalAccelImpl::setEnabled( bool enable )
void KGlobalAccelImpl::setEnabled(bool enable)
{
if (enable) {
kapp->installX11EventFilter( this );
} else
kapp->removeX11EventFilter( this );
if (enable) {
kapp->installX11EventFilter(this);
} else {
kapp->removeX11EventFilter(this);
}
}

View file

@ -31,41 +31,41 @@ class GlobalShortcutsRegistry;
*/
class KGlobalAccelImpl : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
KGlobalAccelImpl( GlobalShortcutsRegistry *owner);
KGlobalAccelImpl(GlobalShortcutsRegistry *owner);
public:
/**
* This function registers or unregisters a certain key for global capture,
* depending on \b grab.
*
* Before destruction, every grabbed key will be released, so this
* object does not need to do any tracking.
*
* \param key the Qt keycode to grab or release.
* \param grab true to grab they key, false to release the key.
*
* \return true if successful, otherwise false.
*/
bool grabKey(int key, bool grab);
/// Enable/disable all shortcuts. There will not be any grabbed shortcuts at this point.
void setEnabled(bool);
/**
* This function registers or unregisters a certain key for global capture,
* depending on \b grab.
*
* Before destruction, every grabbed key will be released, so this
* object does not need to do any tracking.
*
* \param key the Qt keycode to grab or release.
* \param grab true to grab they key, false to release the key.
*
* \return true if successful, otherwise false.
*/
bool grabKey(int key, bool grab);
/// Enable/disable all shortcuts. There will not be any grabbed shortcuts at this point.
void setEnabled(bool);
private:
/**
* Filters X11 events ev for key bindings in the accelerator dictionary.
* If a match is found the activated activated is emitted and the function
* returns true. Return false if the event is not processed.
*
* This is public for compatibility only. You do not need to call it.
*/
virtual bool x11Event( XEvent* );
void x11MappingNotify();
bool x11KeyPress( const XEvent *pEvent );
/**
* Filters X11 events ev for key bindings in the accelerator dictionary.
* If a match is found the activated activated is emitted and the function
* returns true. Return false if the event is not processed.
*
* This is public for compatibility only. You do not need to call it.
*/
virtual bool x11Event(XEvent*);
void x11MappingNotify();
bool x11KeyPress(const XEvent *pEvent);
GlobalShortcutsRegistry *m_owner;
};

View file

@ -40,12 +40,11 @@
struct KGlobalAccelDPrivate
{
{
KGlobalAccelDPrivate(KGlobalAccelD *q)
: q(q)
{}
{
}
GlobalShortcut *findAction(const QStringList &actionId) const;
@ -54,9 +53,7 @@ struct KGlobalAccelDPrivate
*
* @return the action or @c null if doesn't exist
*/
GlobalShortcut *findAction(
const QString &componentUnique,
const QString &shortcutUnique) const;
GlobalShortcut *findAction(const QString &componentUnique, const QString &shortcutUnique) const;
GlobalShortcut *addAction(const QStringList &actionId);
KdeDGlobalAccel::Component *component(const QStringList &actionId) const;
@ -67,21 +64,19 @@ struct KGlobalAccelDPrivate
void _k_newGlobalShortcutNotification();
void splitComponent(QString &component, QString &context) const
{
{
context = "default";
if (component.indexOf('|')!=-1)
{
if (component.indexOf('|')!=-1) {
QStringList tmp = component.split('|');
Q_ASSERT(tmp.size()==2);
component= tmp.at(0);
context= tmp.at(1);
}
}
}
enum ChangeType
{
enum ChangeType {
NewShortcut
};
};
// List if changed components for _k_globalShortcutNotification
QMap<QString, ChangeType> changedComponents;
@ -94,87 +89,70 @@ struct KGlobalAccelDPrivate
//! Our holder
KGlobalAccelD *q;
};
};
GlobalShortcut *KGlobalAccelDPrivate::findAction(const QStringList &actionId) const
{
{
// Check if actionId is valid
if (actionId.size() != 4)
{
if (actionId.size() != 4) {
kDebug() << "Invalid! '" << actionId << "'";
return NULL;
}
return findAction(
actionId.at(KGlobalAccel::ComponentUnique),
actionId.at(KGlobalAccel::ActionUnique));
}
return findAction(actionId.at(KGlobalAccel::ComponentUnique), actionId.at(KGlobalAccel::ActionUnique));
}
GlobalShortcut *KGlobalAccelDPrivate::findAction(
const QString &_componentUnique,
const QString &shortcutUnique) const
{
GlobalShortcut *KGlobalAccelDPrivate::findAction(const QString &_componentUnique, const QString &shortcutUnique) const
{
QString componentUnique = _componentUnique;
KdeDGlobalAccel::Component *component;
QString contextUnique;
if (componentUnique.indexOf('|')==-1)
{
if (componentUnique.indexOf('|')==-1) {
component = GlobalShortcutsRegistry::self()->getComponent( componentUnique);
if (component) contextUnique = component->currentContext()->uniqueName();
if (component) {
contextUnique = component->currentContext()->uniqueName();
}
else
{
} else{
splitComponent(componentUnique, contextUnique);
component = GlobalShortcutsRegistry::self()->getComponent( componentUnique);
}
}
if (!component)
{
if (!component) {
#ifdef KDEDGLOBALACCEL_TRACE
kDebug() << componentUnique << "not found";
#endif
return NULL;
}
}
GlobalShortcut *shortcut = component
? component->getShortcutByName(shortcutUnique, contextUnique)
: NULL;
GlobalShortcut *shortcut = component ? component->getShortcutByName(shortcutUnique, contextUnique) : NULL;
#ifdef KDEDGLOBALACCEL_TRACE
if (shortcut)
{
if (shortcut) {
kDebug() << componentUnique
<< contextUnique
<< shortcut->uniqueName();
}
else
{
} else {
kDebug() << "No match for" << shortcutUnique;
}
}
#endif
return shortcut;
}
}
KdeDGlobalAccel::Component *KGlobalAccelDPrivate::component(const QStringList &actionId) const
{
// Get the component for the action. If we have none create a new one
KdeDGlobalAccel::Component *component = GlobalShortcutsRegistry::self()->getComponent(actionId.at(KGlobalAccel::ComponentUnique));
if (!component)
{
if (!component) {
component = new KdeDGlobalAccel::Component(
actionId.at(KGlobalAccel::ComponentUnique),
actionId.at(KGlobalAccel::ComponentFriendly),
GlobalShortcutsRegistry::self());
Q_ASSERT(component);
}
}
return component;
}
GlobalShortcut *KGlobalAccelDPrivate::addAction(const QStringList &actionId)
{
Q_ASSERT(actionId.size() >= 4);
@ -205,7 +183,9 @@ GlobalShortcut *KGlobalAccelDPrivate::addAction(const QStringList &actionId)
Q_ASSERT(!component->getShortcutByName(componentUnique, contextUnique));
changedComponents.insert(actionId.at(KGlobalAccel::ComponentUnique), NewShortcut);
if (!popupTimer.isActive()) popupTimer.start(500);
if (!popupTimer.isActive()) {
popupTimer.start(500);
}
return new GlobalShortcut(
actionId.at(KGlobalAccel::ActionUnique),
@ -216,51 +196,40 @@ GlobalShortcut *KGlobalAccelDPrivate::addAction(const QStringList &actionId)
void KGlobalAccelDPrivate::_k_newGlobalShortcutNotification()
{
Q_FOREACH(const QString &uniqueName, changedComponents.keys())
{
Q_FOREACH(const QString &uniqueName, changedComponents.keys()) {
kDebug() << "Showing Notification for component" << uniqueName;
KdeDGlobalAccel::Component *component = GlobalShortcutsRegistry::self()->getComponent(uniqueName);
if (!component)
{
if (!component) {
// Can happen if a component is removed immediately after
// registering it. kdelibs/kdeui/tests/kglobalshortcuttests does
// it for example.
continue;
}
}
KNotification *notification = new KNotification(
"newshortcutregistered",
KNotification::CloseOnTimeout,
q->parent());
KNotification *notification = new KNotification("newshortcutregistered", KNotification::CloseOnTimeout, q->parent());
notification->setText(
i18n("The application %1 has registered a new global shortcut",
component->friendlyName()));
notification->setText(i18n("The application %1 has registered a new global shortcut", component->friendlyName()));
notification->setActions( QStringList( i18n( "Open Global Shortcuts Editor" ) ) );
notification->setActions(QStringList(i18n("Open Global Shortcuts Editor")));
notification->addContext( "application", component->friendlyName() );
notification->addContext("application", component->friendlyName());
QObject::connect(notification, SIGNAL(action1Activated()),
component, SLOT(showKCM()));
QObject::connect(notification, SIGNAL(action1Activated()), component, SLOT(showKCM()));
notification->sendEvent();
}
}
changedComponents.clear();
}
Q_DECLARE_METATYPE(QStringList)
KGlobalAccelD::KGlobalAccelD(QObject* parent)
: QObject(parent),
d(new KGlobalAccelDPrivate(this))
{}
: QObject(parent),
d(new KGlobalAccelDPrivate(this))
{
}
bool KGlobalAccelD::init()
{
@ -275,12 +244,10 @@ bool KGlobalAccelD::init()
Q_ASSERT(reg);
d->writeoutTimer.setSingleShot(true);
connect(&d->writeoutTimer, SIGNAL(timeout()),
reg, SLOT(writeSettings()));
connect(&d->writeoutTimer, SIGNAL(timeout()), reg, SLOT(writeSettings()));
d->popupTimer.setSingleShot(true);
connect(&d->popupTimer, SIGNAL(timeout()),
this, SLOT(_k_newGlobalShortcutNotification()));
connect(&d->popupTimer, SIGNAL(timeout()), this, SLOT(_k_newGlobalShortcutNotification()));
if (!QDBusConnection::sessionBus().registerService(QLatin1String("org.kde.kglobalaccel"))) {
kWarning() << "Failed to register service org.kde.kglobalaccel";
@ -298,13 +265,11 @@ bool KGlobalAccelD::init()
GlobalShortcutsRegistry::self()->setDBusPath(QDBusObjectPath("/"));
GlobalShortcutsRegistry::self()->loadSettings();
connect(KGlobalSettings::self(), SIGNAL(blockShortcuts(int)),
SLOT(blockGlobalShortcuts(int)));
connect(KGlobalSettings::self(), SIGNAL(blockShortcuts(int)), SLOT(blockGlobalShortcuts(int)));
return true;
}
KGlobalAccelD::~KGlobalAccelD()
{
GlobalShortcutsRegistry::self()->deactivateShortcuts();
@ -329,7 +294,6 @@ QList<QStringList> KGlobalAccelD::allMainComponents() const
return ret;
}
QList<QStringList> KGlobalAccelD::allActionsForComponent(const QStringList &actionId) const
{
//### Would it be advantageous to sort the actions by unique name?
@ -360,7 +324,6 @@ QList<QStringList> KGlobalAccelD::allActionsForComponent(const QStringList &acti
return ret;
}
QStringList KGlobalAccelD::action(int key) const
{
GlobalShortcut *shortcut = GlobalShortcutsRegistry::self()->getShortcutByKey(key);
@ -374,48 +337,41 @@ QStringList KGlobalAccelD::action(int key) const
return ret;
}
void KGlobalAccelD::activateGlobalShortcutContext(
const QString &component,
const QString &uniqueName)
void KGlobalAccelD::activateGlobalShortcutContext( const QString &component, const QString &uniqueName)
{
KdeDGlobalAccel::Component *const comp =
GlobalShortcutsRegistry::self()->getComponent(component);
if (comp)
KdeDGlobalAccel::Component *const comp = GlobalShortcutsRegistry::self()->getComponent(component);
if (comp) {
comp->activateGlobalShortcutContext(uniqueName);
}
}
QList<QDBusObjectPath> KGlobalAccelD::allComponents() const
{
{
QList<QDBusObjectPath> allComp;
Q_FOREACH (const KdeDGlobalAccel::Component *component,
GlobalShortcutsRegistry::self()->allMainComponents())
{
Q_FOREACH (const KdeDGlobalAccel::Component *component, GlobalShortcutsRegistry::self()->allMainComponents()) {
allComp.append(component->dbusPath());
}
return allComp;
}
return allComp;
}
void KGlobalAccelD::blockGlobalShortcuts(int block)
{
{
#ifdef KDEDGLOBALACCEL_TRACE
kDebug() << block;
#endif
block
? GlobalShortcutsRegistry::self()->deactivateShortcuts(true)
: GlobalShortcutsRegistry::self()->activateShortcuts();
}
}
QList<int> KGlobalAccelD::shortcut(const QStringList &action) const
{
GlobalShortcut *shortcut = d->findAction(action);
if (shortcut)
if (shortcut) {
return shortcut->keys();
}
return QList<int>();
}
@ -423,8 +379,9 @@ QList<int> KGlobalAccelD::shortcut(const QStringList &action) const
QList<int> KGlobalAccelD::defaultShortcut(const QStringList &action) const
{
GlobalShortcut *shortcut = d->findAction(action);
if (shortcut)
if (shortcut) {
return shortcut->defaultKeys();
}
return QList<int>();
}
@ -460,69 +417,60 @@ void KGlobalAccelD::doRegister(const QStringList &actionId)
}
}
QDBusObjectPath KGlobalAccelD::getComponent(const QString &componentUnique)
{
{
#ifdef KDEDGLOBALACCEL_TRACE
kDebug() << componentUnique;
#endif
KdeDGlobalAccel::Component *component =
GlobalShortcutsRegistry::self()->getComponent(componentUnique);
KdeDGlobalAccel::Component *component = GlobalShortcutsRegistry::self()->getComponent(componentUnique);
if (component)
{
if (component) {
return component->dbusPath();
}
else
{
} else {
sendErrorReply("org.kde.kglobalaccel.NoSuchComponent", QString("The component '%1' doesn't exist.").arg(componentUnique));
return QDBusObjectPath("/");
}
}
}
QList<KGlobalShortcutInfo> KGlobalAccelD::getGlobalShortcutsByKey(int key) const
{
{
#ifdef KDEDGLOBALACCEL_TRACE
kDebug() << key;
#endif
QList<GlobalShortcut*> shortcuts =
GlobalShortcutsRegistry::self()->getShortcutsByKey(key);
QList<GlobalShortcut*> shortcuts = GlobalShortcutsRegistry::self()->getShortcutsByKey(key);
QList<KGlobalShortcutInfo> rc;
Q_FOREACH(const GlobalShortcut *sc, shortcuts)
{
Q_FOREACH(const GlobalShortcut *sc, shortcuts) {
#ifdef KDEDGLOBALACCEL_TRACE
kDebug() << sc->context()->uniqueName() << sc->uniqueName();
kDebug() << sc->context()->uniqueName() << sc->uniqueName();
#endif
rc.append(static_cast<KGlobalShortcutInfo>(*sc));
}
return rc;
}
return rc;
}
bool KGlobalAccelD::isGlobalShortcutAvailable(int shortcut, const QString &component) const
{
{
QString realComponent = component;
QString context;
d->splitComponent(realComponent, context);
return GlobalShortcutsRegistry::self()->isShortcutAvailable(shortcut, realComponent, context);
}
}
void KGlobalAccelD::setInactive(const QStringList &actionId)
{
{
#ifdef KDEDGLOBALACCEL_TRACE
kDebug() << actionId;
#endif
GlobalShortcut *shortcut = d->findAction(actionId);
if (shortcut)
if (shortcut) {
shortcut->setIsPresent(false);
}
}
bool KGlobalAccelD::unregister(const QString &componentUnique, const QString &shortcutUnique)
{
@ -538,7 +486,6 @@ bool KGlobalAccelD::unregister(const QString &componentUnique, const QString &sh
}
return shortcut;
}
@ -557,9 +504,7 @@ void KGlobalAccelD::unRegister(const QStringList &actionId)
}
QList<int> KGlobalAccelD::setShortcut(const QStringList &actionId,
const QList<int> &keys, uint flags)
QList<int> KGlobalAccelD::setShortcut(const QStringList &actionId, const QList<int> &keys, uint flags)
{
//spare the DBus framework some work
const bool setPresent = (flags & SetPresent);
@ -616,20 +561,20 @@ void KGlobalAccelD::setForeignShortcut(const QStringList &actionId, const QList<
#endif
GlobalShortcut *shortcut = d->findAction(actionId);
if (!shortcut)
if (!shortcut) {
return;
}
QList<int> newKeys = setShortcut(actionId, keys, NoAutoloading);
emit yourShortcutGotChanged(actionId, newKeys);
}
void KGlobalAccelD::scheduleWriteSettings() const
{
{
if (!d->writeoutTimer.isActive())
d->writeoutTimer.start(500);
}
}
#include "moc_kglobalacceld.cpp"

View file

@ -41,9 +41,7 @@ class KGlobalAccelD : public QObject, protected QDBusContext
Q_ENUMS(SetShortcutFlag)
public:
enum SetShortcutFlag
{
enum SetShortcutFlag {
SetPresent = 2,
NoAutoloading = 4,
IsDefault = 8
@ -56,7 +54,6 @@ public:
bool init();
public Q_SLOTS:
/**
* Get the dbus path for all known components.
*
@ -86,8 +83,7 @@ public Q_SLOTS:
Q_SCRIPTABLE QDBusObjectPath getComponent(const QString &componentUnique);
//to be called by main components owning the action
Q_SCRIPTABLE QList<int> setShortcut(const QStringList &actionId,
const QList<int> &keys, uint flags);
Q_SCRIPTABLE QList<int> setShortcut(const QStringList &actionId, const QList<int> &keys, uint flags);
//this is used if application A wants to change shortcuts of application B
Q_SCRIPTABLE void setForeignShortcut(const QStringList &actionId, const QList<int> &keys);
@ -101,9 +97,7 @@ public Q_SLOTS:
//! @see unregister
Q_SCRIPTABLE KDE_DEPRECATED void unRegister(const QStringList &actionId);
Q_SCRIPTABLE void activateGlobalShortcutContext(
const QString &component,
const QString &context);
Q_SCRIPTABLE void activateGlobalShortcutContext(const QString &component, const QString &context);
/**
@ -117,9 +111,7 @@ public Q_SLOTS:
/**
* Return true if the @p shortcut is available for @p component.
*/
Q_SCRIPTABLE bool isGlobalShortcutAvailable(
int key,
const QString &component) const;
Q_SCRIPTABLE bool isGlobalShortcutAvailable(int key, const QString &component) const;
/**
* Delete the shortcut with @a component and @name.
@ -132,21 +124,16 @@ public Q_SLOTS:
*
* @return @c true if the shortcuts was deleted, @c false if it didn't * exist.
*/
Q_SCRIPTABLE bool unregister(
const QString &componentUnique,
const QString &shortcutUnique);
Q_SCRIPTABLE bool unregister(const QString &componentUnique, const QString &shortcutUnique);
Q_SIGNALS:
Q_SCRIPTABLE void yourShortcutGotChanged(const QStringList &actionId, const QList<int> &newKeys);
private Q_SLOTS:
void blockGlobalShortcuts(int);
private:
Q_PRIVATE_SLOT(d, void _k_newGlobalShortcutNotification() )
void scheduleWriteSettings() const;

View file

@ -32,10 +32,10 @@
#include <signal.h>
static bool isEnabled()
{
{
// TODO: Check if kglobalaccel can be disabled
return true;
}
}
static void sighandler(int /*sig*/)
@ -46,7 +46,7 @@ static void sighandler(int /*sig*/)
int main(int argc, char **argv)
{
{
// Disable Session Management the right way (C)
//
// ksmserver has global shortcuts. disableSessionManagement() does not prevent Qt from
@ -72,17 +72,15 @@ int main(int argc, char **argv)
KUniqueApplication::addCmdLineOptions();
// check if kglobalaccel is disabled
if (!isEnabled())
{
if (!isEnabled()) {
kDebug() << "kglobalaccel is disabled!";
return 0;
}
}
if (!KUniqueApplication::start())
{
if (!KUniqueApplication::start()) {
kDebug() << "kglobalaccel is already running!";
return (0);
}
}
// As in the KUniqueApplication example only create a instance AFTER
// calling KUniqueApplication::start()
@ -106,4 +104,4 @@ int main(int argc, char **argv)
}
return app.exec();
}
}