File indexing completed on 2023-09-24 09:32:41
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-only 0003 SPDX-FileCopyrightText: 1999-2001 Lubos Lunak <l.lunak@kde.org> 0004 */ 0005 0006 #include "kded.h" 0007 0008 #include "action_data/action_data_group.h" 0009 #include "action_data/menuentry_shortcut_action_data.h" 0010 #include "actions/actions.h" 0011 0012 #include "shortcuts_handler.h" 0013 0014 #include "triggers/gestures.h" 0015 0016 #include <QDebug> 0017 #include <kglobalaccel.h> 0018 #include <kpluginfactory.h> 0019 #include <kpluginloader.h> 0020 0021 #include <unistd.h> 0022 0023 #define COMPONENT_NAME "khotkeys" 0024 0025 K_PLUGIN_FACTORY_WITH_JSON(KHotKeysModuleFactory, "khotkeys.json", registerPlugin<KHotKeysModule>();) 0026 0027 using namespace KHotKeys; 0028 0029 // KhotKeysModule 0030 0031 KHotKeysModule::KHotKeysModule(QObject *parent, const QList<QVariant> &) 0032 : KDEDModule(parent) 0033 , actions_root(nullptr) 0034 , _settingsDirty(false) 0035 , _settings() 0036 , _initialized(false) 0037 { 0038 // initialize 0039 qDebug() << "Installing the delayed initialization callback."; 0040 QMetaObject::invokeMethod(this, "initialize", Qt::QueuedConnection); 0041 } 0042 0043 void KHotKeysModule::initialize() 0044 { 0045 if (_initialized) { 0046 return; 0047 } 0048 0049 qDebug() << "Delayed initialization."; 0050 _initialized = true; 0051 0052 // Initialize the global data, grab keys 0053 KHotKeys::init_global_data(true, this); 0054 0055 // If a shortcut was changed (global shortcuts kcm), save 0056 connect(keyboard_handler.data(), SIGNAL(shortcutChanged()), this, SLOT(scheduleSave())); 0057 0058 // Read the configuration from file khotkeysrc 0059 reread_configuration(); 0060 0061 KGlobalAccel::cleanComponent(COMPONENT_NAME); 0062 0063 if (_settings.update()) { 0064 save(); 0065 } 0066 } 0067 0068 KHotKeysModule::~KHotKeysModule() 0069 { 0070 // actions_root belongs to _settings. 0071 actions_root = nullptr; 0072 } 0073 0074 void KHotKeysModule::reread_configuration() 0075 { 0076 qDebug() << "Reloading the khotkeys configuration"; 0077 0078 // Stop listening 0079 actions_root = nullptr; // Disables the dbus interface effectively 0080 KHotKeys::khotkeys_set_active(false); 0081 0082 // Load the settings 0083 _settings.reread_settings(true); 0084 0085 KHotKeys::gesture_handler->set_mouse_button(_settings.gestureMouseButton()); 0086 KHotKeys::gesture_handler->set_timeout(_settings.gestureTimeOut()); 0087 qDebug() << _settings.areGesturesDisabled(); 0088 KHotKeys::gesture_handler->enable(!_settings.areGesturesDisabled()); 0089 KHotKeys::gesture_handler->set_exclude(_settings.gesturesExclude()); 0090 actions_root = _settings.actions(); 0091 KHotKeys::khotkeys_set_active(true); 0092 } 0093 0094 SimpleActionData *KHotKeysModule::menuentry_action(const QString &storageId) 0095 { 0096 ActionDataGroup *menuentries = _settings.get_system_group(ActionDataGroup::SYSTEM_MENUENTRIES); 0097 0098 // Now try to find the action 0099 Q_FOREACH (ActionDataBase *element, menuentries->children()) { 0100 SimpleActionData *actionData = dynamic_cast<SimpleActionData *>(element); 0101 0102 if (actionData && actionData->action()) { 0103 MenuEntryAction *action = dynamic_cast<MenuEntryAction *>(actionData->action()); 0104 if (action && action->service() && (action->service()->storageId() == storageId)) { 0105 return actionData; 0106 } 0107 } 0108 } 0109 0110 return nullptr; 0111 } 0112 0113 QString KHotKeysModule::get_menuentry_shortcut(const QString &storageId) 0114 { 0115 SimpleActionData *actionData = menuentry_action(storageId); 0116 0117 // No action found 0118 if (actionData == nullptr) 0119 return ""; 0120 0121 // The action must have a shortcut trigger. but don't assume to much 0122 ShortcutTrigger *shortcutTrigger = dynamic_cast<ShortcutTrigger *>(actionData->trigger()); 0123 0124 Q_ASSERT(shortcutTrigger); 0125 if (shortcutTrigger == nullptr) 0126 return ""; 0127 0128 qDebug() << shortcutTrigger->primaryShortcut(); 0129 0130 return shortcutTrigger->primaryShortcut(); 0131 } 0132 0133 QString KHotKeysModule::register_menuentry_shortcut(const QString &storageId, const QString &sequence) 0134 { 0135 qDebug() << storageId << "(" << sequence << ")"; 0136 0137 // Check the service we got. If it is invalid there is no need to 0138 // continue. 0139 KService::Ptr wantedService = KService::serviceByStorageId(storageId); 0140 if (!wantedService) { 0141 qCritical() << "Storage Id " << storageId << "not valid"; 0142 return ""; 0143 } 0144 0145 // Look for the action 0146 SimpleActionData *actionData = menuentry_action(storageId); 0147 0148 // No action found. Create on if sequence is != "" 0149 if (actionData == nullptr) { 0150 qDebug() << "No action found"; 0151 0152 // If the sequence is empty there is no need to create a action. 0153 if (sequence.isEmpty()) 0154 return ""; 0155 0156 qDebug() << "Creating a new action"; 0157 0158 // Create the action 0159 ActionDataGroup *menuentries = _settings.get_system_group(ActionDataGroup::SYSTEM_MENUENTRIES); 0160 0161 MenuEntryShortcutActionData *newAction = 0162 new MenuEntryShortcutActionData(menuentries, wantedService->name(), storageId, QKeySequence(sequence), storageId); 0163 0164 newAction->enable(); 0165 0166 _settings.write(); 0167 0168 // Return the real shortcut 0169 return newAction->trigger()->primaryShortcut(); 0170 } 0171 // We found a action 0172 else { 0173 if (sequence.isEmpty()) { 0174 qDebug() << "Deleting the action"; 0175 actionData->aboutToBeErased(); 0176 delete actionData; 0177 _settings.write(); 0178 return ""; 0179 } else { 0180 qDebug() << "Changing the action"; 0181 // The action must have a shortcut trigger. but don't assume to much 0182 ShortcutTrigger *shortcutTrigger = dynamic_cast<ShortcutTrigger *>(actionData->trigger()); 0183 Q_ASSERT(shortcutTrigger); 0184 if (shortcutTrigger == nullptr) 0185 return ""; 0186 0187 // Change the actionData 0188 shortcutTrigger->set_key_sequence(sequence); 0189 _settings.write(); 0190 0191 // Remove the resulting real shortcut 0192 return shortcutTrigger->primaryShortcut(); 0193 } 0194 } 0195 0196 Q_ASSERT(false); 0197 return ""; 0198 } 0199 0200 void KHotKeysModule::quit() 0201 { 0202 deleteLater(); 0203 } 0204 0205 void KHotKeysModule::scheduleSave() 0206 { 0207 if (!_settingsDirty) { 0208 _settingsDirty = true; 0209 QMetaObject::invokeMethod(this, "save", Qt::QueuedConnection); 0210 } 0211 } 0212 0213 void KHotKeysModule::save() 0214 { 0215 _settingsDirty = false; 0216 KHotKeys::khotkeys_set_active(false); 0217 _settings.write(); 0218 KHotKeys::khotkeys_set_active(true); 0219 } 0220 0221 void KHotKeysModule::declareConfigOutdated() 0222 { 0223 Settings::isOutdated = true; 0224 } 0225 0226 #include "kded.moc"