2
* This file is part of unity-2d
4
* Copyright 2011 Canonical Ltd.
7
* - Aurélien Gâteau <aurelien.gateau@canonical.com>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; version 3.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23
#include "keyboardmodifiersmonitor.h"
26
#include <hotmodifier.h>
34
#include <X11/XKBlib.h>
35
#include <X11/extensions/XKB.h>
37
static int sXkbBaseEventType = 0;
39
static void setupXkb()
42
XkbQueryExtension(QX11Info::display(), &opcode, &sXkbBaseEventType, &error, NULL, NULL);
43
XkbSelectEvents(QX11Info::display(), XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
46
struct KeyboardModifiersMonitorPrivate
48
KeyboardModifiersMonitorPrivate()
55
KeyboardModifiersMonitor::KeyboardModifiersMonitor(QObject *parent)
57
, d(new KeyboardModifiersMonitorPrivate)
59
if (sXkbBaseEventType == 0) {
63
Unity2dApplication* application = Unity2dApplication::instance();
64
if (application == NULL) {
65
/* This can happen for example when using qmlviewer to run the launcher */
66
UQ_WARNING << "The application is not an Unity2dApplication."
67
"Modifiers will not be monitored.";
69
application->installX11EventFilter(this);
73
KeyboardModifiersMonitor::~KeyboardModifiersMonitor()
78
KeyboardModifiersMonitor* KeyboardModifiersMonitor::instance()
80
static KeyboardModifiersMonitor* monitor = new KeyboardModifiersMonitor();
84
bool KeyboardModifiersMonitor::x11EventFilter(XEvent* event)
86
if (event->type == sXkbBaseEventType + XkbEventCode) {
87
XkbEvent *xkbEvent = (XkbEvent*)event;
88
if (xkbEvent->any.xkb_type == XkbStateNotify) {
89
d->m_modifiers = xkbEvent->state.mods;
90
Qt::KeyboardModifiers modifiers = keyboardModifiers();
91
keyboardModifiersChanged(modifiers);
93
Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) {
94
if (hotModifier->modifiers() & m_disabledModifiers) {
95
/* If any of the modifiers have been disabled, the
96
* hotModifier cannot be triggered */
99
hotModifier->onModifiersChanged(modifiers);
106
Qt::KeyboardModifiers KeyboardModifiersMonitor::keyboardModifiers() const
108
Qt::KeyboardModifiers value = 0;
109
if (d->m_modifiers & ShiftMask) {
110
value |= Qt::ShiftModifier;
112
if (d->m_modifiers & ControlMask) {
113
value |= Qt::ControlModifier;
115
if (d->m_modifiers & Mod1Mask) {
116
value |= Qt::AltModifier;
118
if (d->m_modifiers & Mod4Mask) {
119
value |= Qt::MetaModifier;
125
KeyboardModifiersMonitor::getHotModifierFor(Qt::KeyboardModifiers modifiers)
127
Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) {
128
if (hotModifier->modifiers() == modifiers) {
133
HotModifier *hotModifier = new HotModifier(modifiers, this);
134
m_hotModifiers.append(hotModifier);
139
KeyboardModifiersMonitor::disableModifiers(Qt::KeyboardModifiers modifiers)
141
m_disabledModifiers |= modifiers;
142
Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) {
143
if (hotModifier->modifiers() & m_disabledModifiers) {
144
hotModifier->disable();
150
KeyboardModifiersMonitor::enableModifiers(Qt::KeyboardModifiers modifiers)
152
Qt::KeyboardModifiers previouslyDisabled = m_disabledModifiers;
153
m_disabledModifiers &= ~modifiers;
154
Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) {
155
if (hotModifier->modifiers() & previouslyDisabled
156
&& !hotModifier->modifiers() & m_disabledModifiers) {
157
hotModifier->onModifiersChanged(keyboardModifiers());
162
#include "keyboardmodifiersmonitor.moc"