Warning, file /plasma/latte-dock/app/shortcuts/modifiertracker.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 *  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
0003 *
0004 *  This file is part of Latte-Dock
0005 *
0006 *  Latte-Dock is free software; you can redistribute it and/or
0007 *  modify it under the terms of the GNU General Public License as
0008 *  published by the Free Software Foundation; either version 2 of
0009 *  the License, or (at your option) any later version.
0010 *
0011 *  Latte-Dock is distributed in the hope that it will be useful,
0012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 *  GNU General Public License for more details.
0015 *
0016 *  You should have received a copy of the GNU General Public License
0017 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018 */
0019 
0020 // local
0021 #include "modifiertracker.h"
0022 
0023 // Qt
0024 #include <QDebug>
0025 #include <QKeySequence>
0026 
0027 namespace Latte {
0028 namespace ShortcutsPart {
0029 
0030 ModifierTracker::ModifierTracker(QObject *parent)
0031     : QObject(parent)
0032 {
0033     init();
0034 }
0035 
0036 ModifierTracker::~ModifierTracker()
0037 {
0038 }
0039 
0040 void ModifierTracker::init()
0041 {
0042     m_metaPressedTimer.setSingleShot(true);
0043     m_metaPressedTimer.setInterval(700);
0044 
0045     m_pressed[Qt::Key_Super_L] = false;
0046     m_pressed[Qt::Key_Control] = false;
0047     m_pressed[Qt::Key_Alt] = false;
0048     m_pressed[Qt::Key_Shift] = false;
0049 
0050     connect(&m_metaPressedTimer, &QTimer::timeout, this, &ModifierTracker::metaModifierPressed);
0051 
0052     connect(&m_modifierKeyInfo, &KModifierKeyInfo::keyPressed, this, [&](Qt::Key key, bool state) {
0053         Qt::Key nKey = normalizeKey(key);
0054         //! ignore modifiers that we do not take into account
0055         if (!modifierIsTracked(nKey)) {
0056             return;
0057         }
0058 
0059         m_pressed[nKey] = state;
0060 
0061         if (nKey == Qt::Key_Super_L) {
0062             bool singleKey{singleModifierPressed(Qt::Key_Super_L)};
0063             if (state && singleKey) {
0064                 m_metaPressedTimer.start();
0065             } else if (!state || !singleKey) {
0066                 cancelMetaPressed();
0067             }
0068         } else {
0069             cancelMetaPressed();
0070         }
0071 
0072         emit modifiersChanged();
0073     });
0074 }
0075 
0076 
0077 bool ModifierTracker::modifierIsTracked(Qt::Key key)
0078 {
0079     if (m_blockedModifiers.contains(key)) {
0080         return false;
0081     }
0082 
0083     return (key == Qt::Key_Super_L || key == Qt::Key_Super_R || key == Qt::Key_Control || key == Qt::Key_Alt || key == Qt::Key_Shift);
0084 }
0085 
0086 void ModifierTracker::blockModifierTracking(Qt::Key key)
0087 {
0088     if (!m_blockedModifiers.contains(key)) {
0089         m_blockedModifiers.append(key);
0090     }
0091 }
0092 
0093 void ModifierTracker::unblockModifierTracking(Qt::Key key)
0094 {
0095     if (m_blockedModifiers.contains(key)) {
0096         m_blockedModifiers.removeAll(key);
0097     }
0098 }
0099 
0100 bool ModifierTracker::noModifierPressed()
0101 {
0102     for (const Qt::Key &modifier : m_pressed.keys()) {
0103         if ( m_pressed[modifier]) {
0104             return false;
0105         }
0106     }
0107 
0108     return true;
0109 }
0110 
0111 bool ModifierTracker::sequenceModifierPressed(const QKeySequence &seq)
0112 {
0113     if (seq.isEmpty()) {
0114         return false;
0115     }
0116 
0117     int mod = seq[seq.count() - 1] & Qt::KeyboardModifierMask;
0118 
0119     if ( ((mod & Qt::SHIFT) && m_pressed[Qt::Key_Shift])
0120          || ((mod & Qt::CTRL) && m_pressed[Qt::Key_Control])
0121          || ((mod & Qt::ALT) && m_pressed[Qt::Key_Alt])
0122          || ((mod & Qt::META) && m_pressed[Qt::Key_Super_L])) {
0123         return true;
0124     }
0125 
0126     return false;
0127 }
0128 
0129 bool ModifierTracker::singleModifierPressed(Qt::Key key)
0130 {
0131     for (const Qt::Key &modifier : m_pressed.keys()) {
0132         if ( (modifier != key && m_pressed[modifier])
0133              || (modifier == key && !m_pressed[modifier]) ) {
0134             return false;
0135         }
0136     }
0137 
0138     return true;
0139 }
0140 
0141 Qt::Key ModifierTracker::normalizeKey(Qt::Key key)
0142 {
0143     return key == Qt::Key_Super_L || key == key == Qt::Key_Super_R ? Qt::Key_Super_L : key;
0144 }
0145 
0146 void ModifierTracker::cancelMetaPressed()
0147 {
0148     m_metaPressedTimer.stop();
0149 }
0150 
0151 
0152 }
0153 }