Unity 8
globalshortcutregistry.cpp
1 /*
2  * Copyright (C) 2015 Canonical, Ltd.
3  *
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.
7  *
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.
12  *
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/>.
15  */
16 
17 #include <QDebug>
18 #include <QGuiApplication>
19 #include <QKeyEvent>
20 #include <QKeySequence>
21 
22 #include "globalshortcutregistry.h"
23 
24 static qulonglong s_windowId = 0;
25 
26 GlobalShortcutRegistry::GlobalShortcutRegistry(QObject *parent)
27  : QObject(parent)
28 {
29 }
30 
31 GlobalShortcutList GlobalShortcutRegistry::shortcuts() const
32 {
33  return m_shortcuts;
34 }
35 
36 bool GlobalShortcutRegistry::hasShortcut(const QVariant &seq) const
37 {
38  return m_shortcuts.keys().contains(seq);
39 }
40 
42 {
43  if (sc) {
44  if (!m_shortcuts.keys().contains(seq)) { // create a new entry
45  m_shortcuts.insert(seq, {sc});
46  } else { // append to an existing one
47  auto shortcuts = m_shortcuts[seq];
48  shortcuts.append(sc);
49  m_shortcuts.insert(seq, shortcuts);
50  }
51 
52  connect(sc, &GlobalShortcut::destroyed, this, &GlobalShortcutRegistry::removeShortcut);
53  }
54 }
55 
56 void GlobalShortcutRegistry::removeShortcut(QObject *obj)
57 {
58  QMutableMapIterator<QVariant, QVector<QPointer<GlobalShortcut>>> it(m_shortcuts);
59  while (it.hasNext()) {
60  it.next();
61  GlobalShortcut * scObj = static_cast<GlobalShortcut *>(obj);
62  if (scObj && it.value().contains(scObj)) {
63  it.value().removeAll(scObj);
64  if (it.value().isEmpty()) {
65  it.remove();
66  }
67  }
68  }
69 }
70 
71 bool GlobalShortcutRegistry::eventFilter(QObject *obj, QEvent *event)
72 {
73  Q_ASSERT(m_filteredWindow);
74  Q_ASSERT(obj == static_cast<QObject*>(m_filteredWindow.data()));
75 
76  if (event->type() == QEvent::KeyPress) {
77  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
78  QKeySequence seq = QKeySequence(keyEvent->key() + keyEvent->modifiers());
79  if (m_shortcuts.keys().contains(seq)) {
80  const auto shortcuts = m_shortcuts.value(seq);
81  Q_FOREACH(const auto &shortcut, shortcuts) {
82  if (shortcut) {
83  qApp->sendEvent(shortcut, keyEvent);
84  event->accept();
85  }
86  }
87  }
88 
89  return event->isAccepted();
90  }
91 
92  return QObject::eventFilter(obj, event);
93 }
94 
96 {
97  if (wid == s_windowId) {
98  return;
99  }
100 
101  if (m_filteredWindow) {
102  m_filteredWindow->removeEventFilter(this);
103  m_filteredWindow.clear();
104  s_windowId = 0;
105  }
106 
107  for(QWindow *window: qApp->allWindows()) {
108  if (window && window->winId() == wid) {
109  m_filteredWindow = window;
110  window->installEventFilter(this);
111  s_windowId = wid;
112  break;
113  }
114  }
115 }
void addShortcut(const QVariant &seq, GlobalShortcut *sc)
void setupFilterOnWindow(qulonglong wid)
The GlobalShortcut class.
GlobalShortcutList shortcuts() const
bool hasShortcut(const QVariant &seq) const