Lomiri
Loading...
Searching...
No Matches
PhysicalKeysMapper.qml
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 */
16
17import QtQuick 2.12
18import Powerd 0.1
19import Utils 0.1
20
21/*!
22 \brief A mapper for the physical keys on the device
23
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
29
30 This allows for handling the following events
31 * Power dialog
32 * Volume Decreases/Increases
33 * Screenshots
34*/
35
36Item {
37 id: root
38
39 signal powerKeyLongPressed;
40 signal volumeDownTriggered;
41 signal volumeUpTriggered;
42 signal screenshotTriggered;
43
44 readonly property bool altTabPressed: d.altTabPressed
45 readonly property bool superPressed: d.superPressed
46 readonly property bool superTabPressed: d.superTabPressed
47
48 property int powerKeyLongPressTime: 2000
49
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
54
55 QtObject {
56 id: d
57
58 property bool volumeDownKeyPressed: false
59 property bool volumeUpKeyPressed: false
60 property bool ignoreVolumeEvents: false
61
62 property bool altPressed: false
63 property bool altTabPressed: false
64
65 property bool superPressed: false
66 property bool superTabPressed: false
67
68 property var powerButtonPressStart: -1
69 }
70
71 InputEventGenerator {
72 id: inputEventGenerator
73 }
74
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();
82 }
83 } else {
84 d.powerButtonPressStart = currentEventTimestamp;
85 }
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();
94 }
95 d.ignoreVolumeEvents = true;
96 }
97 d.volumeDownKeyPressed = true;
98 }
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();
105 }
106 d.ignoreVolumeEvents = true;
107 }
108 d.volumeUpKeyPressed = true;
109 }
110 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
111 d.altPressed = true;
112
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)
118 ) {
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;
125 }
126 if (d.superPressed && !d.superTabPressed) {
127 d.superTabPressed = true;
128 event.accepted = true;
129 }
130 }
131 }
132
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;
149 }
150 d.altPressed = false;
151 } else if (event.key == Qt.Key_Tab) {
152 if (d.altTabPressed) {
153 event.accepted = true;
154 }
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;
160 }
161 }
162 }
163}