~aacid/unity-2d/dash_close_panel_focus

« back to all changes in this revision

Viewing changes to libunity-2d-private/src/keyboardmodifiersmonitor.cpp

[lib] Kill keyboardmodifiersmonitor, and integrate its functionality into keymonitor

This helps to prevent wrong HUD triggers on ultrafast alt+key presses. Fixes: https://bugs.launchpad.net/bugs/968840. Approved by Gerry Boland.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * This file is part of unity-2d
3
 
 *
4
 
 * Copyright 2011 Canonical Ltd.
5
 
 *
6
 
 * Authors:
7
 
 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8
 
 *
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.
12
 
 *
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.
17
 
 *
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/>.
20
 
 */
21
 
 
22
 
// Self
23
 
#include "keyboardmodifiersmonitor.h"
24
 
 
25
 
// Local
26
 
#include <hotmodifier.h>
27
 
#include <debug_p.h>
28
 
 
29
 
// Qt
30
 
#include <QX11Info>
31
 
 
32
 
// X11
33
 
#include <X11/Xlib.h>
34
 
#include <X11/XKBlib.h>
35
 
#include <X11/extensions/XKB.h>
36
 
 
37
 
static int sXkbBaseEventType = 0;
38
 
 
39
 
static void setupXkb()
40
 
{
41
 
    int opcode, error;
42
 
    XkbQueryExtension(QX11Info::display(), &opcode, &sXkbBaseEventType,  &error, NULL, NULL);
43
 
    XkbSelectEvents(QX11Info::display(), XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
44
 
}
45
 
 
46
 
struct KeyboardModifiersMonitorPrivate
47
 
{
48
 
    KeyboardModifiersMonitorPrivate()
49
 
    : m_modifiers(0)
50
 
    {}
51
 
 
52
 
    int m_modifiers;
53
 
};
54
 
 
55
 
KeyboardModifiersMonitor::KeyboardModifiersMonitor(QObject *parent)
56
 
: QObject(parent)
57
 
, d(new KeyboardModifiersMonitorPrivate)
58
 
{
59
 
    if (sXkbBaseEventType == 0) {
60
 
        setupXkb();
61
 
    }
62
 
 
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.";
68
 
    } else {
69
 
        application->installX11EventFilter(this);
70
 
    }
71
 
}
72
 
 
73
 
KeyboardModifiersMonitor::~KeyboardModifiersMonitor()
74
 
{
75
 
    delete d;
76
 
}
77
 
 
78
 
KeyboardModifiersMonitor* KeyboardModifiersMonitor::instance()
79
 
{
80
 
    static KeyboardModifiersMonitor* monitor = new KeyboardModifiersMonitor();
81
 
    return monitor;
82
 
}
83
 
 
84
 
bool KeyboardModifiersMonitor::x11EventFilter(XEvent* event)
85
 
{
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);
92
 
 
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 */
97
 
                    continue;
98
 
                }
99
 
                hotModifier->onModifiersChanged(modifiers);
100
 
            }
101
 
        }
102
 
    }
103
 
    return false;
104
 
}
105
 
 
106
 
Qt::KeyboardModifiers KeyboardModifiersMonitor::keyboardModifiers() const
107
 
{
108
 
    Qt::KeyboardModifiers value = 0;
109
 
    if (d->m_modifiers & ShiftMask) {
110
 
        value |= Qt::ShiftModifier;
111
 
    }
112
 
    if (d->m_modifiers & ControlMask) {
113
 
        value |= Qt::ControlModifier;
114
 
    }
115
 
    if (d->m_modifiers & Mod1Mask) {
116
 
        value |= Qt::AltModifier;
117
 
    }
118
 
    if (d->m_modifiers & Mod4Mask) {
119
 
        value |= Qt::MetaModifier;
120
 
    }
121
 
    return value;
122
 
}
123
 
 
124
 
HotModifier*
125
 
KeyboardModifiersMonitor::getHotModifierFor(Qt::KeyboardModifiers modifiers)
126
 
{
127
 
    Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) {
128
 
        if (hotModifier->modifiers() == modifiers) {
129
 
            return hotModifier;
130
 
        }
131
 
    }
132
 
 
133
 
    HotModifier *hotModifier = new HotModifier(modifiers, this);
134
 
    m_hotModifiers.append(hotModifier);
135
 
    return hotModifier;
136
 
}
137
 
 
138
 
void
139
 
KeyboardModifiersMonitor::disableModifiers(Qt::KeyboardModifiers modifiers)
140
 
{
141
 
    m_disabledModifiers |= modifiers;
142
 
    Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) {
143
 
        if (hotModifier->modifiers() & m_disabledModifiers) {
144
 
            hotModifier->disable();
145
 
        }
146
 
    }
147
 
}
148
 
 
149
 
void
150
 
KeyboardModifiersMonitor::enableModifiers(Qt::KeyboardModifiers modifiers)
151
 
{
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());
158
 
        }
159
 
    }
160
 
}
161
 
 
162
 
#include "keyboardmodifiersmonitor.moc"