File indexing completed on 2024-10-06 04:59:05
0001 /* 0002 SPDX-FileCopyrightText: 2019 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 // local 0007 #include "modifiertracker.h" 0008 0009 // Qt 0010 #include <QDebug> 0011 #include <QKeySequence> 0012 0013 namespace Latte { 0014 namespace ShortcutsPart { 0015 0016 ModifierTracker::ModifierTracker(QObject *parent) 0017 : QObject(parent) 0018 { 0019 init(); 0020 } 0021 0022 ModifierTracker::~ModifierTracker() 0023 { 0024 } 0025 0026 void ModifierTracker::init() 0027 { 0028 m_metaPressedTimer.setSingleShot(true); 0029 m_metaPressedTimer.setInterval(700); 0030 0031 m_pressed[Qt::Key_Super_L] = false; 0032 m_pressed[Qt::Key_Control] = false; 0033 m_pressed[Qt::Key_Alt] = false; 0034 m_pressed[Qt::Key_Shift] = false; 0035 0036 connect(&m_metaPressedTimer, &QTimer::timeout, this, &ModifierTracker::metaModifierPressed); 0037 0038 connect(&m_modifierKeyInfo, &KModifierKeyInfo::keyPressed, this, [&](Qt::Key key, bool state) { 0039 Qt::Key nKey = normalizeKey(key); 0040 //! ignore modifiers that we do not take into account 0041 if (!modifierIsTracked(nKey)) { 0042 return; 0043 } 0044 0045 m_pressed[nKey] = state; 0046 0047 if (nKey == Qt::Key_Super_L) { 0048 bool singleKey{singleModifierPressed(Qt::Key_Super_L)}; 0049 if (state && singleKey) { 0050 m_metaPressedTimer.start(); 0051 } else if (!state || !singleKey) { 0052 cancelMetaPressed(); 0053 } 0054 } else { 0055 cancelMetaPressed(); 0056 } 0057 0058 emit modifiersChanged(); 0059 }); 0060 } 0061 0062 0063 bool ModifierTracker::modifierIsTracked(Qt::Key key) 0064 { 0065 if (m_blockedModifiers.contains(key)) { 0066 return false; 0067 } 0068 0069 return (key == Qt::Key_Super_L || key == Qt::Key_Super_R || key == Qt::Key_Control || key == Qt::Key_Alt || key == Qt::Key_Shift); 0070 } 0071 0072 void ModifierTracker::blockModifierTracking(Qt::Key key) 0073 { 0074 if (!m_blockedModifiers.contains(key)) { 0075 m_blockedModifiers.append(key); 0076 } 0077 } 0078 0079 void ModifierTracker::unblockModifierTracking(Qt::Key key) 0080 { 0081 if (m_blockedModifiers.contains(key)) { 0082 m_blockedModifiers.removeAll(key); 0083 } 0084 } 0085 0086 bool ModifierTracker::noModifierPressed() 0087 { 0088 for (const Qt::Key &modifier : m_pressed.keys()) { 0089 if ( m_pressed[modifier]) { 0090 return false; 0091 } 0092 } 0093 0094 return true; 0095 } 0096 0097 bool ModifierTracker::sequenceModifierPressed(const QKeySequence &seq) 0098 { 0099 if (seq.isEmpty()) { 0100 return false; 0101 } 0102 0103 int mod = seq[seq.count() - 1] & Qt::KeyboardModifierMask; 0104 0105 if ( ((mod & Qt::SHIFT) && m_pressed[Qt::Key_Shift]) 0106 || ((mod & Qt::CTRL) && m_pressed[Qt::Key_Control]) 0107 || ((mod & Qt::ALT) && m_pressed[Qt::Key_Alt]) 0108 || ((mod & Qt::META) && m_pressed[Qt::Key_Super_L])) { 0109 return true; 0110 } 0111 0112 return false; 0113 } 0114 0115 bool ModifierTracker::singleModifierPressed(Qt::Key key) 0116 { 0117 for (const Qt::Key &modifier : m_pressed.keys()) { 0118 if ( (modifier != key && m_pressed[modifier]) 0119 || (modifier == key && !m_pressed[modifier]) ) { 0120 return false; 0121 } 0122 } 0123 0124 return true; 0125 } 0126 0127 Qt::Key ModifierTracker::normalizeKey(Qt::Key key) 0128 { 0129 return ((key == Qt::Key_Super_L || key == Qt::Key_Super_R) ? Qt::Key_Super_L : key); 0130 } 0131 0132 void ModifierTracker::cancelMetaPressed() 0133 { 0134 m_metaPressedTimer.stop(); 0135 } 0136 0137 0138 } 0139 }