diff --git a/src/ui/form/opt/pages/optionspage.cpp b/src/ui/form/opt/pages/optionspage.cpp index 17d537d9..86ec70b7 100644 --- a/src/ui/form/opt/pages/optionspage.cpp +++ b/src/ui/form/opt/pages/optionspage.cpp @@ -152,6 +152,7 @@ void OptionsPage::onRetranslateUi() m_gbStartup->setTitle(tr("Startup")); m_gbTraffic->setTitle(tr("Traffic")); m_gbGlobal->setTitle(tr("Global")); + m_gbHotKeys->setTitle(tr("Hot Keys")); m_gbProtection->setTitle(tr("Self Protection")); m_gbTray->setTitle(tr("Tray")); m_gbConfirmations->setTitle(tr("Action Confirmations")); @@ -172,10 +173,11 @@ void OptionsPage::onRetranslateUi() retranslateComboFilterMode(); m_cbExplorerMenu->setText(tr("Windows Explorer integration")); - m_cbHotKeys->setText(tr("Hot Keys")); - m_labelLanguage->setText(tr("Language:")); + m_cbHotKeysEnabled->setText(tr("Enabled")); + m_cbHotKeysGlobal->setText(tr("Global")); + m_cbBootFilter->setText(tr("Stop traffic when Fort Firewall is not running")); m_cbFilterLocals->setText(tr("Filter Local Addresses")); m_cbFilterLocals->setToolTip( @@ -358,6 +360,10 @@ QLayout *OptionsPage::setupColumn1() setupGlobalBox(); layout->addWidget(m_gbGlobal); + // Hot Keys Group Box + setupHotKeysBox(); + layout->addWidget(m_gbHotKeys); + // Protection Group Box setupProtectionBox(); layout->addWidget(m_gbProtection); @@ -464,23 +470,37 @@ void OptionsPage::setupGlobalBox() }); m_cbExplorerMenu->setEnabled(settings()->hasMasterAdmin()); - m_cbHotKeys = ControlUtil::createCheckBox(iniUser()->hotKeyEnabled(), [&](bool checked) { - iniUser()->setHotKeyEnabled(checked); - ctrl()->setIniUserEdited(/*flagsChanged=*/true); - }); - // Language Row auto langLayout = setupLangLayout(); auto layout = new QVBoxLayout(); layout->addWidget(m_cbExplorerMenu); - layout->addWidget(m_cbHotKeys); layout->addLayout(langLayout); m_gbGlobal = new QGroupBox(); m_gbGlobal->setLayout(layout); } +void OptionsPage::setupHotKeysBox() +{ + m_cbHotKeysEnabled = ControlUtil::createCheckBox(iniUser()->hotKeyEnabled(), [&](bool checked) { + iniUser()->setHotKeyEnabled(checked); + ctrl()->setIniUserEdited(true); + }); + + m_cbHotKeysGlobal = ControlUtil::createCheckBox(iniUser()->hotKeyGlobal(), [&](bool checked) { + iniUser()->setHotKeyGlobal(checked); + ctrl()->setIniUserEdited(true); + }); + + auto layout = new QVBoxLayout(); + layout->addWidget(m_cbHotKeysEnabled); + layout->addWidget(m_cbHotKeysGlobal); + + m_gbHotKeys = new QGroupBox(); + m_gbHotKeys->setLayout(layout); +} + QLayout *OptionsPage::setupLangLayout() { m_labelLanguage = ControlUtil::createLabel(); @@ -669,7 +689,7 @@ QLayout *OptionsPage::setupTrayActionLayout() const TrayIcon::ActionType actionType = static_cast(index); TrayIcon::setClickEventActionType(iniUser(), clickType, actionType); - ctrl()->setIniUserEdited(/*flagsChanged=*/true); + ctrl()->setIniUserEdited(true); }); m_comboTrayAction->setFixedWidth(200); diff --git a/src/ui/form/opt/pages/optionspage.h b/src/ui/form/opt/pages/optionspage.h index ec618e76..ba675286 100644 --- a/src/ui/form/opt/pages/optionspage.h +++ b/src/ui/form/opt/pages/optionspage.h @@ -42,6 +42,7 @@ private: void setupTrafficBox(); QLayout *setupFilterModeLayout(); void setupGlobalBox(); + void setupHotKeysBox(); QLayout *setupLangLayout(); void setupComboLanguage(); void setupProtectionBox(); @@ -69,6 +70,7 @@ private: QGroupBox *m_gbStartup = nullptr; QGroupBox *m_gbTraffic = nullptr; QGroupBox *m_gbGlobal = nullptr; + QGroupBox *m_gbHotKeys = nullptr; QGroupBox *m_gbProtection = nullptr; QGroupBox *m_gbTray = nullptr; QGroupBox *m_gbConfirmations = nullptr; @@ -84,7 +86,8 @@ private: QLabel *m_labelFilterMode = nullptr; QComboBox *m_comboFilterMode = nullptr; QCheckBox *m_cbExplorerMenu = nullptr; - QCheckBox *m_cbHotKeys = nullptr; + QCheckBox *m_cbHotKeysEnabled = nullptr; + QCheckBox *m_cbHotKeysGlobal = nullptr; QLabel *m_labelLanguage = nullptr; QComboBox *m_comboLanguage = nullptr; QCheckBox *m_cbBootFilter = nullptr; diff --git a/src/ui/form/tray/trayicon.cpp b/src/ui/form/tray/trayicon.cpp index 341089a8..a6e47150 100644 --- a/src/ui/form/tray/trayicon.cpp +++ b/src/ui/form/tray/trayicon.cpp @@ -636,7 +636,7 @@ void TrayIcon::addHotKey(QAction *action, const QString &shortcutText) void TrayIcon::updateHotKeys() { - hotKeyManager()->setEnabled(iniUser()->hotKeyEnabled()); + hotKeyManager()->initialize(iniUser()->hotKeyEnabled(), iniUser()->hotKeyGlobal()); } void TrayIcon::removeHotKeys() diff --git a/src/ui/manager/hotkeymanager.cpp b/src/ui/manager/hotkeymanager.cpp index 77cc5d05..87a2df75 100644 --- a/src/ui/manager/hotkeymanager.cpp +++ b/src/ui/manager/hotkeymanager.cpp @@ -11,12 +11,15 @@ HotKeyManager::HotKeyManager(QObject *parent) : QObject(parent) { } -void HotKeyManager::setEnabled(bool v) +void HotKeyManager::initialize(bool enabled, bool global) { - if (m_enabled != v) { - m_enabled = v; - updateActions(); - } + if (m_enabled == enabled && m_global == global) + return; + + m_enabled = enabled; + m_global = global; + + updateActions(); } void HotKeyManager::setUp() @@ -54,12 +57,14 @@ void HotKeyManager::removeActions() void HotKeyManager::updateActions() { - IoC()->unregisterHotKeys(); + auto eventFilter = IoC(); + + eventFilter->unregisterHotKeys(); for (QAction *action : qAsConst(m_actions)) { action->setShortcutVisibleInContextMenu(enabled()); - if (enabled()) { - registerHotKey(action); + if (enabled() && global()) { + registerHotKey(eventFilter, action); } } } @@ -79,7 +84,7 @@ void HotKeyManager::onHotKeyPressed(int hotKeyId) } } -void HotKeyManager::registerHotKey(QAction *action) const +void HotKeyManager::registerHotKey(NativeEventFilter *eventFilter, QAction *action) const { const QKeySequence shortcut = action->shortcut(); const int hotKeyId = action->data().toInt(); @@ -87,5 +92,5 @@ void HotKeyManager::registerHotKey(QAction *action) const const auto keyCombination = shortcut[0]; const int key = keyCombination.toCombined(); - IoC()->registerHotKey(hotKeyId, key); + eventFilter->registerHotKey(hotKeyId, key); } diff --git a/src/ui/manager/hotkeymanager.h b/src/ui/manager/hotkeymanager.h index 711def1f..00c6f3a7 100644 --- a/src/ui/manager/hotkeymanager.h +++ b/src/ui/manager/hotkeymanager.h @@ -16,7 +16,9 @@ public: explicit HotKeyManager(QObject *parent = nullptr); bool enabled() const { return m_enabled; } - void setEnabled(bool v); + bool global() const { return m_global; } + + void initialize(bool enabled, bool global); void setUp() override; void tearDown() override; @@ -31,10 +33,11 @@ private slots: private: void updateActions(); - void registerHotKey(QAction *action) const; + void registerHotKey(NativeEventFilter *eventFilter, QAction *action) const; private: bool m_enabled = false; + bool m_global = false; QList m_actions; }; diff --git a/src/ui/manager/nativeeventfilter.cpp b/src/ui/manager/nativeeventfilter.cpp index d0836429..6595ffe0 100644 --- a/src/ui/manager/nativeeventfilter.cpp +++ b/src/ui/manager/nativeeventfilter.cpp @@ -107,14 +107,16 @@ NativeEventFilter::~NativeEventFilter() } bool NativeEventFilter::registerHotKey( - int hotKeyId, Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRepeat) + int hotKeyId, Qt::Key keyCode, Qt::KeyboardModifiers modifiers) { Q_ASSERT(uint(hotKeyId) <= 0xBFFF); - const quint32 nativeMod = nativeModifiers(modifiers, autoRepeat); + const quint32 nativeMod = nativeModifiers(modifiers); const quint32 nativeKey = nativeKeyCode(keyCode); - if (!RegisterHotKey(nullptr, 0, nativeMod, nativeKey)) + const quint32 nativeModifiers = nativeMod | autoRepeatModifier(/*autoRepeat=*/true); + + if (!RegisterHotKey(nullptr, 0, nativeModifiers, nativeKey)) return false; setKeyId(hotKeyId, nativeMod, nativeKey); @@ -122,17 +124,10 @@ bool NativeEventFilter::registerHotKey( return true; } -bool NativeEventFilter::registerHotKey(int hotKeyId, int key, bool autoRepeat) +bool NativeEventFilter::registerHotKey(int hotKeyId, int key) { return registerHotKey(hotKeyId, Qt::Key(key & ~Qt::KeyboardModifierMask), - Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask), autoRepeat); -} - -void NativeEventFilter::unregisterHotKey(int hotKeyId) -{ - UnregisterHotKey(nullptr, hotKeyId); - - removeKeyId(hotKeyId); + Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask)); } void NativeEventFilter::unregisterHotKeys() @@ -164,11 +159,11 @@ void NativeEventFilter::setKeyId(int hotKeyId, quint32 nativeMod, quint32 native m_keyIdMap.insert(nativeKeyMod, hotKeyId); } -void NativeEventFilter::removeKeyId(int hotKeyId) +bool NativeEventFilter::removeKeyId(int hotKeyId) { const quint32 nativeKeyMod = m_keyIdMap.key(hotKeyId); - m_keyIdMap.remove(nativeKeyMod); + return m_keyIdMap.remove(nativeKeyMod); } int NativeEventFilter::getKeyId(quint32 nativeMod, quint32 nativeKey) const @@ -221,10 +216,15 @@ quint32 NativeEventFilter::nativeKeyCode(Qt::Key keyCode) return g_keyTbl.value(keyCode, 0); } -quint32 NativeEventFilter::nativeModifiers(Qt::KeyboardModifiers modifiers, bool autoRepeat) +quint32 NativeEventFilter::nativeModifiers(Qt::KeyboardModifiers modifiers) { - return (autoRepeat ? MOD_NOREPEAT : 0) | ((modifiers & Qt::ShiftModifier) ? MOD_SHIFT : 0) + return ((modifiers & Qt::ShiftModifier) ? MOD_SHIFT : 0) | ((modifiers & Qt::ControlModifier) ? MOD_CONTROL : 0) | ((modifiers & Qt::AltModifier) ? MOD_ALT : 0) | ((modifiers & Qt::MetaModifier) ? MOD_WIN : 0); } + +quint32 NativeEventFilter::autoRepeatModifier(bool autoRepeat) +{ + return (autoRepeat ? 0 : MOD_NOREPEAT); +} diff --git a/src/ui/manager/nativeeventfilter.h b/src/ui/manager/nativeeventfilter.h index ca62b96c..e7fc6a80 100644 --- a/src/ui/manager/nativeeventfilter.h +++ b/src/ui/manager/nativeeventfilter.h @@ -19,11 +19,9 @@ public: bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; - bool registerHotKey(int hotKeyId, Qt::Key keyCode, Qt::KeyboardModifiers modifiers, - bool autoRepeat = false); - bool registerHotKey(int hotKeyId, int key, bool autoRepeat = false); + bool registerHotKey(int hotKeyId, Qt::Key keyCode, Qt::KeyboardModifiers modifiers); + bool registerHotKey(int hotKeyId, int key); - void unregisterHotKey(int hotKeyId); void unregisterHotKeys(); bool registerSessionNotification(quintptr winId); @@ -36,11 +34,12 @@ signals: private: void setKeyId(int hotKeyId, quint32 nativeMod, quint32 nativeKey); - void removeKeyId(int hotKeyId); + bool removeKeyId(int hotKeyId); int getKeyId(quint32 nativeMod, quint32 nativeKey) const; static quint32 nativeKeyCode(Qt::Key keyCode); - static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool autoRepeat = false); + static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); + static quint32 autoRepeatModifier(bool autoRepeat = false); private: QHash m_keyIdMap; diff --git a/src/ui/user/iniuser.h b/src/ui/user/iniuser.h index 038ca894..b1378bd3 100644 --- a/src/ui/user/iniuser.h +++ b/src/ui/user/iniuser.h @@ -17,6 +17,9 @@ public: bool hotKeyEnabled() const { return valueBool("hotKey/enabled"); } void setHotKeyEnabled(bool v) { setValue("hotKey/enabled", v); } + bool hotKeyGlobal() const { return valueBool("hotKey/global", true); } + void setHotKeyGlobal(bool v) { setValue("hotKey/global", v, true); } + QString hotKeyHome() const { return valueText("hotKey/home"); } QString hotKeyPrograms() const { return valueText("hotKey/programs"); } QString hotKeyOptions() const { return valueText("hotKey/options"); }