2 * Copyright (C) 2014-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/>.
22 \brief A mapper for the physical keys on the device
24 A mapper to handle events triggered by pressing physical keys on a device.
30 This allows for handling the following events
32 * Volume Decreases/Increases
39 signal powerKeyLongPressed;
40 signal volumeDownTriggered;
41 signal volumeUpTriggered;
42 signal screenshotTriggered;
44 readonly property bool altTabPressed: d.altTabPressed
45 readonly property bool superPressed: d.superPressed
46 readonly property bool superTabPressed: d.superTabPressed
48 property int powerKeyLongPressTime: 2000
50 // For testing. If running windowed (e.g. tryShell), Alt+Tab is taken by the
51 // running desktop, set this to true to use Ctrl+Tab instead.
52 property bool controlInsteadOfAlt: false
53 property bool controlInsteadOfSuper: false
58 property bool volumeDownKeyPressed: false
59 property bool volumeUpKeyPressed: false
60 property bool ignoreVolumeEvents: false
62 property bool altPressed: false
63 property bool altTabPressed: false
65 property bool superPressed: false
66 property bool superTabPressed: false
68 property var powerButtonPressStart: -1
72 id: inputEventGenerator
75 function onKeyPressed(event, currentEventTimestamp) {
76 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
77 if (event.isAutoRepeat) {
78 if (d.powerButtonPressStart != -1
79 && currentEventTimestamp - d.powerButtonPressStart >= powerKeyLongPressTime) {
80 d.powerButtonPressStart = -1;
81 root.powerKeyLongPressed();
84 d.powerButtonPressStart = currentEventTimestamp;
86 } else if ((event.key == Qt.Key_MediaTogglePlayPause || event.key == Qt.Key_MediaPlay) && !event.isAutoRepeat) {
87 event.accepted = callManager.handleMediaKey(false);
88 } else if (event.key == Qt.Key_VolumeDown) {
89 if (event.isAutoRepeat && !d.ignoreVolumeEvents) root.volumeDownTriggered();
90 else if (!event.isAutoRepeat) {
91 if (d.volumeUpKeyPressed) {
92 if (Powerd.status === Powerd.On) {
93 root.screenshotTriggered();
95 d.ignoreVolumeEvents = true;
97 d.volumeDownKeyPressed = true;
99 } else if (event.key == Qt.Key_VolumeUp) {
100 if (event.isAutoRepeat && !d.ignoreVolumeEvents) root.volumeUpTriggered();
101 else if (!event.isAutoRepeat) {
102 if (d.volumeDownKeyPressed) {
103 if (Powerd.status === Powerd.On) {
104 root.screenshotTriggered();
106 d.ignoreVolumeEvents = true;
108 d.volumeUpKeyPressed = true;
110 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
113 // Adding MetaModifier here because that's what keyboards do. Pressing Super_L actually gives
114 // Super_L + MetaModifier. This helps to make sure we only invoke superPressed if no other
115 // Modifier is pressed too.
116 } else if (((event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R) && event.modifiers === Qt.MetaModifier)
117 || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)
119 d.superPressed = true;
120 } else if (event.key == Qt.Key_Tab) {
121 if (d.altPressed && !d.altTabPressed) {
122 inputEventGenerator.generateKeyEvent(Qt.Key_Alt, false, Qt.NoModifier, currentEventTimestamp, 56);
123 d.altTabPressed = true;
124 event.accepted = true;
126 if (d.superPressed && !d.superTabPressed) {
127 d.superTabPressed = true;
128 event.accepted = true;
133 function onKeyReleased(event, currentEventTimestamp) {
134 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
135 d.powerButtonPressStart = -1;
136 event.accepted = true;
137 } else if (event.key == Qt.Key_VolumeDown) {
138 if (!d.ignoreVolumeEvents) root.volumeDownTriggered();
139 d.volumeDownKeyPressed = false;
140 if (!d.volumeUpKeyPressed) d.ignoreVolumeEvents = false;
141 } else if (event.key == Qt.Key_VolumeUp) {
142 if (!d.ignoreVolumeEvents) root.volumeUpTriggered();
143 d.volumeUpKeyPressed = false;
144 if (!d.volumeDownKeyPressed) d.ignoreVolumeEvents = false;
145 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
146 if (d.altTabPressed) {
147 d.altTabPressed = false;
148 event.accepted = true;
150 d.altPressed = false;
151 } else if (event.key == Qt.Key_Tab) {
152 if (d.altTabPressed) {
153 event.accepted = true;
155 } else if (event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)) {
156 d.superPressed = false;
157 if (d.superTabPressed) {
158 d.superTabPressed = false;
159 event.accepted = true;