Unity 8
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 
17 import QtQuick 2.0
18 import Powerd 0.1
19 
20 /*!
21  \brief A mapper for the physical keys on the device
22 
23  A mapper to handle events triggered by pressing physical keys on a device.
24  Keys included are
25  * Volume Decrease
26  * Volume Increase
27  * Power
28 
29  This allows for handling the following events
30  * Power dialog
31  * Volume Decreases/Increases
32  * Screenshots
33 
34 */
35 
36 Item {
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 
46  property int powerKeyLongPressTime: 2000
47 
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
51 
52  QtObject {
53  id: d
54 
55  property bool volumeDownKeyPressed: false
56  property bool volumeUpKeyPressed: false
57  property bool ignoreVolumeEvents: false
58 
59  property bool altPressed: false
60  property bool altTabPressed: false
61  }
62 
63  Timer {
64  id: powerKeyLongPressTimer
65  interval: root.powerKeyLongPressTime
66  onTriggered: root.powerKeyLongPressed();
67  }
68 
69  function onKeyPressed(event) {
70  if ((event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff)
71  && !event.isAutoRepeat) {
72 
73  // FIXME: We only consider power key presses if the screen is
74  // on because of bugs 1410830/1409003. The theory is that when
75  // those bugs are encountered, there is a >2s delay between the
76  // power press event and the power release event, which causes
77  // the shutdown dialog to appear on resume. So to avoid that
78  // symptom while we investigate the root cause, we simply won't
79  // initiate any dialogs when the screen is off.
80  if (Powerd.status === Powerd.On) {
81  powerKeyLongPressTimer.restart();
82  }
83  event.accepted = true;
84  } else if ((event.key == Qt.Key_MediaTogglePlayPause || event.key == Qt.Key_MediaPlay)
85  && !event.isAutoRepeat) {
86  event.accepted = callManager.handleMediaKey(false);
87  } else if (event.key == Qt.Key_VolumeDown) {
88  if (event.isAutoRepeat && !d.ignoreVolumeEvents) root.volumeDownTriggered();
89  else if (!event.isAutoRepeat) {
90  if (d.volumeUpKeyPressed) {
91  if (Powerd.status === Powerd.On) root.screenshotTriggered();
92  d.ignoreVolumeEvents = true;
93  }
94  d.volumeDownKeyPressed = true;
95  }
96  } else if (event.key == Qt.Key_VolumeUp) {
97  if (event.isAutoRepeat && !d.ignoreVolumeEvents) root.volumeUpTriggered();
98  else if (!event.isAutoRepeat) {
99  if (d.volumeDownKeyPressed) {
100  if (Powerd.status === Powerd.On) root.screenshotTriggered();
101  d.ignoreVolumeEvents = true;
102  }
103  d.volumeUpKeyPressed = true;
104  }
105  } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
106  d.altPressed = true;
107  } else if (event.key == Qt.Key_Tab) {
108  if (d.altPressed && !d.altTabPressed) {
109  d.altTabPressed = true;
110  event.accepted = true;
111  }
112  } else if (event.key == Qt.Key_Print) {
113  root.screenshotTriggered();
114  }
115  }
116 
117  function onKeyReleased(event) {
118  if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
119  powerKeyLongPressTimer.stop();
120  event.accepted = true;
121  } else if (event.key == Qt.Key_VolumeDown) {
122  if (!d.ignoreVolumeEvents) root.volumeDownTriggered();
123  d.volumeDownKeyPressed = false;
124  if (!d.volumeUpKeyPressed) d.ignoreVolumeEvents = false;
125  } else if (event.key == Qt.Key_VolumeUp) {
126  if (!d.ignoreVolumeEvents) root.volumeUpTriggered();
127  d.volumeUpKeyPressed = false;
128  if (!d.volumeDownKeyPressed) d.ignoreVolumeEvents = false;
129  } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
130  d.altPressed = false;
131  if (d.altTabPressed) {
132  d.altTabPressed = false;
133  event.accepted = true;
134  }
135  }
136  }
137 }