2 * Copyright (C) 2015 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include <QGuiApplication>
20#include <QKeySequence>
22#include "globalshortcutregistry.h"
25QWindow* windowForShortcut(GlobalShortcut *sc) {
28 if (auto item = qobject_cast<QQuickItem*>(parent)) {
29 auto window = item->window();
30 if (window) return window;
32 parent = parent->parent();
38GlobalShortcutRegistry::GlobalShortcutRegistry(QObject *parent)
41 connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &GlobalShortcutRegistry::setupFilterOnWindow);
42 setupFilterOnWindow(qGuiApp->focusWindow());
45GlobalShortcutList GlobalShortcutRegistry::shortcuts() const
50bool GlobalShortcutRegistry::hasShortcut(const QVariant &seq) const
52 return m_shortcuts.contains(seq);
55void GlobalShortcutRegistry::addShortcut(const QVariant &seq, GlobalShortcut *sc)
58 if (!m_shortcuts.contains(seq)) { // create a new entry
59 m_shortcuts.insert(seq, {sc});
60 } else { // append to an existing one
61 auto shortcuts = m_shortcuts[seq];
63 m_shortcuts.insert(seq, shortcuts);
66 connect(sc, &GlobalShortcut::destroyed, this, &GlobalShortcutRegistry::removeShortcut);
70void GlobalShortcutRegistry::removeShortcut(QObject *obj)
72 QMutableMapIterator<QVariant, QVector<QPointer<GlobalShortcut>>> it(m_shortcuts);
73 while (it.hasNext()) {
75 GlobalShortcut * scObj = static_cast<GlobalShortcut *>(obj);
76 if (scObj && it.value().contains(scObj)) {
77 it.value().removeAll(scObj);
78 if (it.value().isEmpty()) {
85bool GlobalShortcutRegistry::eventFilter(QObject *obj, QEvent *event)
87 Q_ASSERT(m_filteredWindow);
88 Q_ASSERT(obj == static_cast<QObject*>(m_filteredWindow.data()));
90 if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
92 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
94 // Make a copy of the event so we don't alter it for passing on.
95 QKeyEvent eCopy(keyEvent->type(),
97 keyEvent->modifiers(),
99 keyEvent->isAutoRepeat(),
103 int seq = keyEvent->key() + keyEvent->modifiers();
104 if (m_shortcuts.contains(seq)) {
105 const auto shortcuts = m_shortcuts.value(seq);
106 Q_FOREACH(const auto &shortcut, shortcuts) {
108 auto window = windowForShortcut(shortcut);
109 if (!window || window == obj) { // accept shortcut if it's not attached to a window or it's window is active.
110 qApp->sendEvent(shortcut, &eCopy);
116 return eCopy.isAccepted();
119 return QObject::eventFilter(obj, event);
122void GlobalShortcutRegistry::setupFilterOnWindow(QWindow* window)
124 if (m_filteredWindow) {
125 m_filteredWindow->removeEventFilter(this);
126 m_filteredWindow.clear();
130 m_filteredWindow = window;
131 window->installEventFilter(this);
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list