on 19ca6e9 help sign in
unity8/qml/Components/PhysicalKeysMapper.qml
159 lines 6.3 kB history raw
1/*
2 * Copyright (C) 2014-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 */
17import QtQuick 2.4
18import Powerd 0.1
19import Utils 0.1
21/*!
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.
25 Keys included are
26 * Volume Decrease
27 * Volume Increase
28 * Power
30 This allows for handling the following events
31 * Power dialog
32 * Volume Decreases/Increases
33 * Screenshots
34*/
36Item {
37 id: root
39 signal powerKeyLongPressed;
40 signal volumeDownTriggered;
41 signal volumeUpTriggered;
42 signal screenshotTriggered;
44 readonly property bool altTabPressed: d.altTabPressed
46 property int powerKeyLongPressTime: 2000
48 // For testing. If running windowed (e.g. tryShell), Alt+Tab is taken by the
49 // running desktop, set this to true to use Ctrl+Tab instead.
50 property bool controlInsteadOfAlt: false
52 QtObject {
53 id: d
55 property bool volumeDownKeyPressed: false
56 property bool volumeUpKeyPressed: false
57 property bool ignoreVolumeEvents: false
59 property bool altPressed: false
60 property bool altTabPressed: false
62 property var powerButtonPressStart: 0
64 // We need to eat ALT presses until we know what they're for (Alt+Tab or going to the app?)
65 // Once we know if an ALT keypress is for the app, we need to re-inject the pressed event for it
66 // but we must only do that once.
67 property bool altPressInjected: false
68 }
70 InputEventGenerator {
71 id: inputEventGenerator
72 }
74 function onKeyPressed(event, currentEventTimestamp) {
75 if (d.altPressed && !d.altTabPressed && event.key !== Qt.Key_Tab && event.key !== Qt.Key_Alt && !d.altPressInjected) {
76 // ALT is pressed and another key that is not Tab has been received. Re-inject the alt pressed event
77 d.altPressInjected = true;
78 inputEventGenerator.generateKeyEvent(Qt.Key_Alt, true, Qt.NoModifier, currentEventTimestamp - 1, 56);
79 }
81 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
82 if (event.isAutoRepeat) {
83 if (d.powerButtonPressStart > 0
84 && currentEventTimestamp - d.powerButtonPressStart >= powerKeyLongPressTime) {
85 d.powerButtonPressStart = 0;
86 root.powerKeyLongPressed();
87 }
88 } else {
89 d.powerButtonPressStart = currentEventTimestamp;
90 }
91 } else if ((event.key == Qt.Key_MediaTogglePlayPause || event.key == Qt.Key_MediaPlay) && !event.isAutoRepeat) {
92 event.accepted = callManager.handleMediaKey(false);
93 } else if (event.key == Qt.Key_VolumeDown) {
94 if (event.isAutoRepeat && !d.ignoreVolumeEvents) root.volumeDownTriggered();
95 else if (!event.isAutoRepeat) {
96 if (d.volumeUpKeyPressed) {
97 if (Powerd.status === Powerd.On) {
98 root.screenshotTriggered();
99 }
100 d.ignoreVolumeEvents = true;
101 }
102 d.volumeDownKeyPressed = true;
103 }
104 } else if (event.key == Qt.Key_VolumeUp) {
105 if (event.isAutoRepeat && !d.ignoreVolumeEvents) root.volumeUpTriggered();
106 else if (!event.isAutoRepeat) {
107 if (d.volumeDownKeyPressed) {
108 if (Powerd.status === Powerd.On) {
109 root.screenshotTriggered();
110 }
111 d.ignoreVolumeEvents = true;
112 }
113 d.volumeUpKeyPressed = true;
114 }
115 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
116 if (!d.altPressed || event.isAutoRepeat) {
117 // Only eat it if it's the first time we receive alt pressed (or if it's the autorepeat of the first press)
118 d.altPressed = true;
119 event.accepted = true;
120 d.altPressInjected = false;
121 }
122 } else if (event.key == Qt.Key_Tab) {
123 if (d.altPressed && !d.altTabPressed) {
124 d.altTabPressed = true;
125 event.accepted = true;
126 }
127 }
128 }
130 function onKeyReleased(event, currentEventTimestamp) {
131 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
132 d.powerButtonPressStart = 0;
133 event.accepted = true;
134 } else if (event.key == Qt.Key_VolumeDown) {
135 if (!d.ignoreVolumeEvents) root.volumeDownTriggered();
136 d.volumeDownKeyPressed = false;
137 if (!d.volumeUpKeyPressed) d.ignoreVolumeEvents = false;
138 } else if (event.key == Qt.Key_VolumeUp) {
139 if (!d.ignoreVolumeEvents) root.volumeUpTriggered();
140 d.volumeUpKeyPressed = false;
141 if (!d.volumeDownKeyPressed) d.ignoreVolumeEvents = false;
142 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
143 if (d.altTabPressed) {
144 d.altTabPressed = false;
145 event.accepted = true;
146 } else if (d.altPressed && !d.altPressInjected) {
147 // Alt was released but nothing else. Let's inject a pressed event and also forward the release.
148 d.altPressInjected = true;
149 inputEventGenerator.generateKeyEvent(Qt.Key_Alt, true, Qt.AltModifer, currentEventTimestamp, 56);
150 d.altPressInjected = false;
151 }
152 d.altPressed = false;
153 } else if (event.key == Qt.Key_Tab) {
154 if (d.altTabPressed) {
155 event.accepted = true;
156 }
157 }
158 }