File indexing completed on 2024-12-01 13:37:33
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2016, 2017 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "modifier_only_shortcuts.h" 0010 0011 #include <config-kwin.h> 0012 0013 #include "input_event.h" 0014 #include "options.h" 0015 #if KWIN_BUILD_SCREENLOCKER 0016 #include "screenlockerwatcher.h" 0017 #endif 0018 #include "wayland_server.h" 0019 #include "workspace.h" 0020 0021 #include <QDBusConnection> 0022 #include <QDBusMessage> 0023 #include <QDBusPendingCall> 0024 0025 namespace KWin 0026 { 0027 0028 ModifierOnlyShortcuts::ModifierOnlyShortcuts() 0029 : QObject() 0030 , InputEventSpy() 0031 { 0032 #if KWIN_BUILD_SCREENLOCKER 0033 connect(kwinApp()->screenLockerWatcher(), &ScreenLockerWatcher::locked, this, &ModifierOnlyShortcuts::reset); 0034 #endif 0035 } 0036 0037 ModifierOnlyShortcuts::~ModifierOnlyShortcuts() = default; 0038 0039 void ModifierOnlyShortcuts::keyEvent(KeyEvent *event) 0040 { 0041 if (event->isAutoRepeat()) { 0042 return; 0043 } 0044 if (event->type() == QEvent::KeyPress) { 0045 const bool wasEmpty = m_pressedKeys.isEmpty(); 0046 m_pressedKeys.insert(event->nativeScanCode()); 0047 if (wasEmpty && m_pressedKeys.size() == 1 && 0048 #if KWIN_BUILD_SCREENLOCKER 0049 !kwinApp()->screenLockerWatcher()->isLocked() && 0050 #endif 0051 m_pressedButtons == Qt::NoButton && m_cachedMods == Qt::NoModifier) { 0052 m_modifier = Qt::KeyboardModifier(int(event->modifiersRelevantForGlobalShortcuts())); 0053 } else { 0054 m_modifier = Qt::NoModifier; 0055 } 0056 } else if (!m_pressedKeys.isEmpty()) { 0057 m_pressedKeys.remove(event->nativeScanCode()); 0058 if (m_pressedKeys.isEmpty() && event->modifiersRelevantForGlobalShortcuts() == Qt::NoModifier && workspace() && !workspace()->globalShortcutsDisabled()) { 0059 if (m_modifier != Qt::NoModifier) { 0060 const auto list = options->modifierOnlyDBusShortcut(m_modifier); 0061 if (list.size() >= 4) { 0062 if (!waylandServer() || !waylandServer()->isKeyboardShortcutsInhibited()) { 0063 auto call = QDBusMessage::createMethodCall(list.at(0), list.at(1), list.at(2), list.at(3)); 0064 QVariantList args; 0065 for (int i = 4; i < list.size(); ++i) { 0066 args << list.at(i); 0067 } 0068 call.setArguments(args); 0069 QDBusConnection::sessionBus().asyncCall(call); 0070 } 0071 } 0072 } 0073 } 0074 m_modifier = Qt::NoModifier; 0075 } else { 0076 m_modifier = Qt::NoModifier; 0077 } 0078 m_cachedMods = event->modifiersRelevantForGlobalShortcuts(); 0079 } 0080 0081 void ModifierOnlyShortcuts::pointerEvent(MouseEvent *event) 0082 { 0083 if (event->type() == QEvent::MouseMove) { 0084 return; 0085 } 0086 m_pressedButtons = event->buttons(); 0087 reset(); 0088 } 0089 0090 void ModifierOnlyShortcuts::wheelEvent(WheelEvent *event) 0091 { 0092 reset(); 0093 } 0094 0095 }