on xenial help sign in
Touch in windowed mode
commit9eb5ad21b2dfee6d5014628e34e5bed8c8cccb98 authorNick Dedekind <nick.dedekind@canonical.com> dateThu 27 Oct 2016, 15:54 (10 years ago) parentc5bdee8
4 files changed+191−290
qml/Components/WindowControlButtons.qml+21 qml/Panel/Panel.qml+143−275 qml/Stage/DecoratedWindow.qml+1−2 qml/Stage/WindowDecoration.qml+26−13
qml/Components/WindowControlButtons.qml+21
@@ -46,6 +46,13 @@ Row {
4646 onClicked: root.closeClicked()
4747 visible: root.closeButtonShown
4848
49+ // We dont want touch events to fall through to parent,
50+ // otherwise the containsMouse will not work.
51+ MouseArea {
52+ anchors.fill: parent
53+ propagateComposedEvents: true
54+ }
55+
4956 Rectangle {
5057 anchors.fill: parent
5158 anchors.margins: windowIsMaximized ? units.dp(3) : 0
@@ -69,6 +76,13 @@ Row {
6976 width: height
7077 onClicked: root.minimizeClicked()
7178
79+ // We dont want touch events to fall through to parent,
80+ // otherwise the containsMouse will not work.
81+ MouseArea {
82+ anchors.fill: parent
83+ propagateComposedEvents: true
84+ }
85+
7286 Rectangle {
7387 anchors.fill: parent
7488 anchors.margins: windowIsMaximized ? units.dp(3) : 0
@@ -102,6 +116,13 @@ Row {
102116 }
103117 }
104118
119+ // We dont want touch events to fall through to parent,
120+ // otherwise the containsMouse will not work.
121+ MouseArea {
122+ anchors.fill: parent
123+ propagateComposedEvents: true
124+ }
125+
105126 Rectangle {
106127 anchors.fill: parent
107128 anchors.margins: windowIsMaximized ? units.dp(3) : 0
qml/Panel/Panel.qml+143−275
@@ -42,7 +42,7 @@ Item {
4242 property real indicatorMenuWidth: width
4343 property real applicationMenuWidth: width
4444
45− property alias applicationMenus: fakeApplicationMenus
45+ property alias applicationMenus: __applicationMenus
4646 property alias indicators: __indicators
4747 property bool fullscreenMode: false
4848 property real indicatorAreaShowProgress: 1.0
@@ -55,9 +55,14 @@ Item {
5555 id: backMouseEater
5656 anchors.fill: parent
5757 anchors.topMargin: panelHeight
58− visible: __indicators.fullyOpened
58+ visible: __indicators.fullyOpened || __applicationMenus.fullyOpened
5959 enabled: visible
6060 hoverEnabled: true // should also eat hover events, otherwise they will pass through
61+
62+ onClicked: {
63+ __applicationMenus.hide();
64+ __indicators.hide();
65+ }
6166 }
6267
6368 Binding {
@@ -66,11 +71,6 @@ Item {
6671 value: minimizedPanelHeight
6772 }
6873
69− FakePanelMenu {
70− id: fakeApplicationMenus
71− model: registeredMenuModel.model
72− }
73−
7474 RegisteredApplicationMenuModel {
7575 id: registeredMenuModel
7676 persistentSurfaceId: PanelState.focusedPersistentSurfaceId
@@ -98,6 +98,16 @@ Item {
9898 source: "graphics/rectangular_dropshadow.sci"
9999 }
100100
101+ BorderImage {
102+ id: appmenuDropShadow
103+ anchors {
104+ fill: __applicationMenus
105+ margins: -units.gu(1)
106+ }
107+ visible: !__applicationMenus.fullyClosed
108+ source: "graphics/rectangular_dropshadow.sci"
109+ }
110+
101111 BorderImage {
102112 id: panelDropShadow
103113 anchors {
@@ -110,7 +120,7 @@ Item {
110120
111121 Rectangle {
112122 id: panelAreaBackground
113− color: theme.palette.normal.background
123+ color: callHint.visible ? theme.palette.normal.positive : theme.palette.normal.background
114124 anchors {
115125 top: parent.top
116126 left: parent.left
@@ -121,300 +131,148 @@ Item {
121131 Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } }
122132 }
123133
124− Loader {
125− id: apppMenuLoader
126− sourceComponent: mode == "staged" ? stagedLeftPanelComponent : windowedLeftPanelComponent
127− width: parent.width
134+ MouseArea {
135+ id: decorationMouseArea
136+ objectName: "windowControlArea"
137+ anchors {
138+ left: parent.left
139+ right: parent.right
140+ }
128141 height: minimizedPanelHeight
142+ hoverEnabled: !__indicators.shown
143+ onClicked: {
144+ if (callHint.visible) {
145+ callHint.showLiveCall();
146+ }
147+ }
129148
130− opacity: root.locked ? 0 : 1
131− visible: opacity != 0
132− Behavior on opacity { UbuntuNumberAnimation {} }
133− }
149+ onPressed: {
150+ if (!callHint.visible) {
151+ // let it fall through to the window decoration of the maximized window behind, if any
152+ mouse.accepted = false;
153+ }
154+ }
134155
135− Component {
136− id: stagedLeftPanelComponent
156+ property bool showWindowControls: (PanelState.decorationsVisible && (containsMouse || menuBarLoader.menusRequested)) || PanelState.decorationsAlwaysVisible
137157
138− MouseArea {
139− id: decorationMouseArea
140− objectName: "windowControlArea"
158+ // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/
159+ // cf. https://bugreports.qt.io/browse/QTBUG-32909
160+ WindowControlButtons {
161+ id: windowControlButtons
162+ objectName: "panelWindowControlButtons"
141163 anchors {
142164 left: parent.left
143− right: parent.right
144− }
145− height: minimizedPanelHeight
146− hoverEnabled: !__indicators.shown
147− onClicked: {
148− if (callHint.visible) {
149− callHint.showLiveCall();
150− }
165+ top: parent.top
151166 }
167+ height: indicators.minimizedPanelHeight
168+ opacity: decorationMouseArea.showWindowControls ? 1 : 0
169+ visible: opacity != 0
170+ Behavior on opacity { UbuntuNumberAnimation {} }
171+
172+ active: PanelState.decorationsVisible || PanelState.decorationsAlwaysVisible
173+ windowIsMaximized: true
174+ onCloseClicked: PanelState.closeClicked()
175+ onMinimizeClicked: PanelState.minimizeClicked()
176+ onMaximizeClicked: PanelState.restoreClicked()
177+ closeButtonShown: PanelState.closeButtonShown
178+ }
152179
153− BorderImage {
154− id: applicationMenusDropShadow
155− anchors {
156− fill: __applicationMenus
157− margins: -units.gu(1)
158− }
159− visible: !__applicationMenus.fullyClosed
160− source: "graphics/rectangular_dropshadow.sci"
180+ Loader {
181+ id: menuBarLoader
182+ anchors {
183+ left: windowControlButtons.right
184+ leftMargin: units.gu(3)
161185 }
186+ height: parent.height
187+ opacity: windowControlButtons.opacity
188+ visible: opacity != 0
189+ active: __applicationMenus.model
162190
163− PanelMenu {
164− id: __applicationMenus
165−
166− hides: fakeApplicationMenus.hides
167− model: fakeApplicationMenus.model
168−
169− width: root.applicationMenuWidth
170− minimizedPanelHeight: root.minimizedPanelHeight
171− expandedPanelHeight: root.expandedPanelHeight
172− openedHeight: root.height
173− enableHint: !callHint.active && !fullscreenMode
174− showOnClick: !callHint.visible
175− panelColor: callHint.visible ? theme.palette.normal.positive : theme.palette.normal.background
176− alignment: Qt.AlignLeft
177−
178− showRowTitle: !expanded
179− rowTitle: PanelState.title
180− rowItemDelegate: ActionItem {
181− id: actionItem
182− property int ownIndex: index
183−
184− width: _title.width + units.gu(2)
185− height: parent.height
186−
187− action: Action {
188− text: model.label.replace("_", "&")
189− }
190−
191− Label {
192− id: _title
193− anchors.centerIn: parent
194− text: actionItem.text
195− horizontalAlignment: Text.AlignLeft
196− color: enabled ? "white" : "#5d5d5d"
197− }
198− }
199−
200− pageDelegate: PanelMenuPage {
201− id: page
202− menuModel: __applicationMenus.model
203− submenuIndex: modelIndex
204−
205− factory: ApplicationMenuItemFactory {
206− rootModel: __applicationMenus.model
207− }
208− }
209−
210− enabled: !root.locked && model
211− opacity: !indicators.expanded ? 1 : 0
212− visible: opacity != 0
213− Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
191+ property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false
214192
215− onEnabledChanged: {
216− if (!enabled) hide();
217− }
218−
219− Binding {
220− target: fakeApplicationMenus
221− property: "expanded"
222− value: __applicationMenus.expanded
223− }
193+ sourceComponent: MenuBar {
194+ id: bar
195+ height: menuBarLoader.height
196+ enableKeyFilter: valid && PanelState.decorationsVisible
197+ unityMenuModel: registeredMenuModel.model
224198
225199 Connections {
226− target: fakeApplicationMenus
227− onHide: __applicationMenus.hide();
228− onShow: __applicationMenus.show();
200+ target: __applicationMenus
201+ onHide: bar.dismiss();
229202 }
230203 }
204+ }
231205
232− ActiveCallHint {
233− id: callHint
234− objectName: "callHint"
235−
236− x: __applicationMenus.x + __applicationMenus.barWidth
237− height: parent.height
206+ ActiveCallHint {
207+ id: callHint
208+ objectName: "callHint"
238209
239− visible: active && (indicators.state == "initial" && __applicationMenus.state == "initial")
240− greeterShown: root.greeterShown
241− }
210+ anchors.centerIn: parent
211+ height: minimizedPanelHeight
242212
243− Binding {
244− target: __indicators
245− property: "overFlowWidth"
246− value: {
247− var width = root.width;
248− if (callHint.visible) {
249− width -= callHint.width;
250− }
251− if (__applicationMenus.visible) {
252− width -= __applicationMenus.barWidth;
253− }
254− return Math.max(width, 0);
255− }
256− }
257− Binding {
258− target: panelAreaBackground
259− property: "color"
260− value: callHint.visible ? theme.palette.normal.positive : theme.palette.normal.background
261− }
262− Binding {
263− target: __indicators
264− property: "enableHint"
265− value: !callHint.active && !__indicators.fullscreenMode
266− }
267− Binding {
268− target: __indicators
269− property: "showOnClick"
270− value: !callHint.visible
271− }
272− Connections {
273− target: __indicators
274− onShowTapped: {
275− if (callHint.active) {
276− callHint.showLiveCall();
277− }
278− }
279− }
280− Binding {
281− target: backMouseEater
282− property: "visible"
283− value: true
284− when: __applicationMenus.fullyOpened
285− }
286− Connections {
287− target: backMouseEater
288− onClicked: __applicationMenus.hide();
289− }
213+ visible: active && indicators.state == "initial"
214+ greeterShown: root.greeterShown
290215 }
291216 }
292217
293− Component {
294− id: windowedLeftPanelComponent
218+ PanelMenu {
219+ id: __applicationMenus
295220
296− MouseArea {
297− id: decorationMouseArea
298− objectName: "windowControlArea"
299− anchors {
300− left: parent.left
301− right: parent.right
302− }
303− height: minimizedPanelHeight
304− hoverEnabled: !__indicators.shown
305− onClicked: if (callHint.visible) { callHint.showLiveCall(); }
221+ model: registeredMenuModel.model
222+ width: root.applicationMenuWidth
223+ minimizedPanelHeight: root.minimizedPanelHeight
224+ expandedPanelHeight: root.expandedPanelHeight
225+ openedHeight: root.height
226+ alignment: Qt.AlignLeft
227+ enableHint: !callHint.active && !fullscreenMode
228+ showOnClick: !callHint.visible
229+ panelColor: panelAreaBackground.color
306230
307− onPressed: {
308− if (!callHint.visible) {
309− // let it fall through to the window decoration of the maximized window behind, if any
310− mouse.accepted = false;
311− }
231+ onShowTapped: {
232+ if (callHint.active) {
233+ callHint.showLiveCall();
312234 }
235+ }
313236
314− property bool showWindowControls: (PanelState.decorationsVisible && (containsMouse || menuBarLoader.menusRequested)) || PanelState.decorationsAlwaysVisible
237+ showRowTitle: !expanded
238+ rowTitle: PanelState.title
239+ rowItemDelegate: ActionItem {
240+ id: actionItem
241+ property int ownIndex: index
315242
316− // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/
317− // cf. https://bugreports.qt.io/browse/QTBUG-32909
318− WindowControlButtons {
319− id: windowControlButtons
320− objectName: "panelWindowControlButtons"
321− anchors {
322− left: parent.left
323− top: parent.top
324− }
325− height: indicators.minimizedPanelHeight
326− opacity: decorationMouseArea.showWindowControls ? 1 : 0
327− visible: opacity != 0
328− Behavior on opacity { UbuntuNumberAnimation {} }
329−
330− active: PanelState.decorationsVisible || PanelState.decorationsAlwaysVisible
331− windowIsMaximized: true
332− onCloseClicked: PanelState.closeClicked()
333− onMinimizeClicked: PanelState.minimizeClicked()
334− onMaximizeClicked: PanelState.restoreClicked()
335− closeButtonShown: PanelState.closeButtonShown
336− }
243+ width: _title.width + units.gu(2)
244+ height: parent.height
337245
338− Loader {
339− id: menuBarLoader
340− anchors {
341− left: windowControlButtons.right
342− leftMargin: units.gu(3)
343− }
344− height: parent.height
345− opacity: windowControlButtons.opacity
346− visible: opacity != 0
347− active: fakeApplicationMenus.model
348−
349− property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false
350−
351− sourceComponent: MenuBar {
352− id: bar
353− height: menuBarLoader.height
354− enableKeyFilter: valid && PanelState.decorationsVisible
355− unityMenuModel: fakeApplicationMenus.model
356−
357− Connections {
358− target: fakeApplicationMenus
359− onHide: bar.dismiss();
360− }
361− }
246+ action: Action {
247+ text: model.label.replace("_", "&")
362248 }
363249
364250 Label {
365− id: titleLabel
366− objectName: "windowDecorationTitle"
367− anchors {
368− left: parent.left
369− leftMargin: units.gu(1)
370− verticalCenter: parent.verticalCenter
371− }
372− color: "white"
373− opacity: !decorationMouseArea.showWindowControls ? 1 : 0
374− visible: opacity != 0
375− verticalAlignment: Text.AlignVCenter
376− fontSize: "medium"
377− font.weight: PanelState.decorationsVisible ? Font.Light : Font.Medium
378− text: PanelState.title
379− elide: Text.ElideRight
380− maximumLineCount: 1
381− Behavior on opacity { UbuntuNumberAnimation {} }
251+ id: _title
252+ anchors.centerIn: parent
253+ text: actionItem.text
254+ horizontalAlignment: Text.AlignLeft
255+ color: enabled ? "white" : "#5d5d5d"
382256 }
257+ }
383258
384− ActiveCallHint {
385− id: callHint
386− objectName: "callHint"
387−
388− anchors.centerIn: parent
389− height: minimizedPanelHeight
259+ pageDelegate: PanelMenuPage {
260+ id: page
261+ menuModel: __applicationMenus.model
262+ submenuIndex: modelIndex
390263
391− visible: active && indicators.state == "initial"
392− greeterShown: root.greeterShown
264+ factory: ApplicationMenuItemFactory {
265+ rootModel: __applicationMenus.model
393266 }
267+ }
394268
395− Binding {
396− target: panelAreaBackground
397− property: "color"
398− value: callHint.visible ? theme.palette.normal.positive : theme.palette.normal.background
399− }
400− Binding {
401− target: __indicators
402− property: "enableHint"
403− value: !callHint.active && !__indicators.fullscreenMode
404− }
405− Binding {
406− target: __indicators
407− property: "showOnClick"
408− value: !callHint.visible
409− }
410− Connections {
411− target: __indicators
412− onShowTapped: {
413− if (callHint.active) {
414− callHint.showLiveCall();
415− }
416− }
417− }
269+ enabled: !root.locked && model
270+ opacity: !decorationMouseArea.showWindowControls && !indicators.expanded ? 1 : 0
271+ visible: opacity != 0
272+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
273+
274+ onEnabledChanged: {
275+ if (!enabled) hide();
418276 }
419277 }
420278
@@ -432,10 +290,16 @@ Item {
432290 openedHeight: root.height
433291
434292 overFlowWidth: root.width
435− enableHint: !fullscreenMode
436− showOnClick: true
293+ enableHint: !callHint.active && !fullscreenMode
294+ showOnClick: !callHint.visible
437295 panelColor: panelAreaBackground.color
438296
297+ onShowTapped: {
298+ if (callHint.active) {
299+ callHint.showLiveCall();
300+ }
301+ }
302+
439303 rowItemDelegate: IndicatorItem {
440304 id: indicatorItem
441305 objectName: identifier+"-panelItem"
@@ -492,10 +356,6 @@ Item {
492356 onEnabledChanged: {
493357 if (!enabled) hide();
494358 }
495− Connections {
496− target: backMouseEater
497− onClicked: __indicators.hide();
498− }
499359 }
500360 }
501361
@@ -523,13 +383,21 @@ Item {
523383 when: fullscreenMode
524384 PropertyChanges {
525385 target: indicatorArea;
526− anchors.topMargin: indicators.state === "initial" ? - minimizedPanelHeight : 0
527− opacity: indicators.fullyClosed ? 0.0 : 1.0
386+ anchors.topMargin: {
387+ if (indicators.state !== "initial") return 0;
388+ if (applicationMenus.state !== "initial") return 0;
389+ return -minimizedPanelHeight;
390+ }
391+ opacity: indicators.fullyClosed && applicationMenus.fullyClosed ? 0.0 : 1.0
528392 }
529393 PropertyChanges {
530394 target: indicators.showDragHandle;
531395 anchors.bottomMargin: -units.gu(1)
532396 }
397+ PropertyChanges {
398+ target: applicationMenus.showDragHandle;
399+ anchors.bottomMargin: -units.gu(1)
400+ }
533401 }
534402 ]
535403
qml/Stage/DecoratedWindow.qml+1−2
@@ -232,8 +232,7 @@ FocusScope {
232232 enableMenus: {
233233 return active &&
234234 surface &&
235− (PanelState.focusedPersistentSurfaceId !== surface.persistentId ||
236− (PanelState.focusedPersistentSurfaceId === surface.persistentId && !PanelState.focusedSurfaceMaximized))
235+ (PanelState.focusedPersistentSurfaceId === surface.persistentId && !PanelState.decorationsVisible)
237236 }
238237 menu: sharedAppModel.model
239238
qml/Stage/WindowDecoration.qml+26−13
@@ -22,7 +22,7 @@ import "../Components"
2222import "../Components/PanelState"
2323import "../ApplicationMenus"
2424
25−MouseArea {
25+Item {
2626 id: root
2727
2828 property Item target // appDelegate
@@ -35,23 +35,35 @@ MouseArea {
3535
3636 readonly property real buttonsWidth: buttons.width + row.spacing
3737
38− acceptedButtons: Qt.AllButtons // prevent leaking unhandled mouse events
39− hoverEnabled: true
40−
4138 signal closeClicked()
4239 signal minimizeClicked()
4340 signal maximizeClicked()
4441 signal maximizeHorizontallyClicked()
4542 signal maximizeVerticallyClicked()
4643
47− onDoubleClicked: {
48− if (target.canBeMaximized && mouse.button == Qt.LeftButton) {
49− root.maximizeClicked();
44+ MouseArea {
45+ id: hoverArea
46+ anchors.fill: parent
47+
48+ acceptedButtons: Qt.AllButtons // prevent leaking unhandled mouse events
49+ hoverEnabled: true
50+
51+ onDoubleClicked: {
52+ if (target.canBeMaximized && mouse.button == Qt.LeftButton) {
53+ root.maximizeClicked();
54+ }
5055 }
51− }
5256
53− // do not let unhandled wheel event pass thru the decoration
54− onWheel: wheel.accepted = true;
57+ // do not let unhandled wheel event pass thru the decoration
58+ onWheel: wheel.accepted = true;
59+
60+ // We dont want touch events to fall through to parent,
61+ // otherwise the containsMouse will not work.
62+ MouseArea {
63+ anchors.fill: parent
64+ propagateComposedEvents: true
65+ }
66+ }
5567
5668 QtObject {
5769 id: priv
@@ -60,7 +72,7 @@ MouseArea {
6072 property bool shouldShowMenus: root.enableMenus &&
6173 menuBar &&
6274 menuBar.valid &&
63− (menuBar.showRequested || root.containsMouse)
75+ (menuBar.showRequested || hoverArea.containsMouse)
6476 }
6577
6678 Rectangle {
@@ -108,6 +120,8 @@ MouseArea {
108120 onMaximizeHorizontallyClicked: if (root.target.canBeMaximizedHorizontally) root.maximizeHorizontallyClicked();
109121 onMaximizeVerticallyClicked: if (root.target.canBeMaximizedVertically) root.maximizeVerticallyClicked();
110122 closeButtonShown: root.target.appId !== "unity8-dash"
123+
124+ enabled: !PanelState.decorationsVisible
111125 }
112126
113127 Item {
@@ -140,7 +154,7 @@ MouseArea {
140154 sourceComponent: MenuBar {
141155 id: menuBar
142156 height: menuBarLoader.height
143− enableKeyFilter: valid && root.active && root.enableMenus && !PanelState.decorationsVisible
157+ enableKeyFilter: valid && root.active && root.enableMenus
144158 unityMenuModel: root.menu
145159 }
146160
@@ -150,5 +164,4 @@ MouseArea {
150164 }
151165 }
152166 }
153−
154167}