on xenial help sign in
merge ../satelliteWindow/
commit5e5d7b5d1a199c70e3166f13205d4f52d2fe489f authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateFri 24 Mar 2017, 11:02 (10 years ago) parent46bca5f682d937
6 files changed+63−6
qml/Stage/ChildWindow.qml+10−2 qml/Stage/ChildWindowRepeater.qml+12−1 qml/Stage/ChildWindowTree.qml+16−2 qml/Stage/Stage.qml+10−1 tests/mocks/Unity/Application/MirSurface.cpp+5 tests/qmltests/Stage/tst_DesktopStage.qml+10
qml/Stage/ChildWindow.qml+10−2
@@ -18,8 +18,9 @@ import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919import Unity.Application 0.1
2020
21−Item {
21+FocusScope {
2222 id: root
23+ objectName: "childWindow"
2324
2425 // Set from outside.
2526 property var surface
@@ -43,6 +44,7 @@ Item {
4344 readonly property bool decorated: surface ? surface.type === Mir.UtilityType
4445 || surface.type === Mir.DialogType
4546 || surface.type === Mir.NormalType
47+ || surface.type === Mir.SatelliteType
4648 : false
4749
4850 readonly property bool moveable: decorated
@@ -100,7 +102,10 @@ Item {
100102 height: units.gu(3)
101103 title: root.surface ? root.surface.name : ""
102104 active: root.surface ? root.surface.focused : false
103− closeButtonVisible: false
105+ closeButtonVisible: root.surface ? root.surface.type === Mir.SatelliteType
106+ || root.surface.type === Mir.NormalType
107+ || root.surface.type === Mir.UtilityType
108+ : false
104109 minimizeButtonVisible: false
105110 maximizeButtonShown: false
106111 onPressed: root.surface.activate();
@@ -109,6 +114,7 @@ Item {
109114 d.moveHandler.handlePositionChanged(mouse);
110115 }
111116 onReleased: if (d.moveHandler) { d.moveHandler.handleReleased(); }
117+ onCloseClicked: root.surface.close();
112118 }
113119 }
114120 }
@@ -141,6 +147,8 @@ Item {
141147 // TODO ChildWindow parent will probably want to control those
142148 interactive: true
143149 consumesInput: true
150+
151+ focus: true
144152 }
145153
146154 Loader {
qml/Stage/ChildWindowRepeater.qml+12−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2016 Canonical, Ltd.
2+ * Copyright (C) 2016-2017 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -21,8 +21,19 @@ Repeater {
2121 id: root
2222 property Item boundsItem
2323 delegate: ChildWindowTree {
24+ id: childWindowTree
2425 surface: model.surface
2526 z: root.count - model.index
2627 boundsItem: root.boundsItem
28+ Connections {
29+ target: childWindowTree.surface
30+ onFocusedChanged: {
31+ if (childWindowTree.surface.focused) {
32+ childWindowTree.focus = true;
33+ // focus the Loader
34+ childWindowTree.parent.focus = true;
35+ }
36+ }
37+ }
2738 }
2839}
qml/Stage/ChildWindowTree.qml+16−2
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2016 Canonical, Ltd.
2+ * Copyright (C) 2016-2017 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@ import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919import Unity.Application 0.1
2020
21−Item {
21+FocusScope {
2222 id: root
2323
2424 property alias surface: childWindow.surface
@@ -100,6 +100,13 @@ Item {
100100 onFocusRequested: {
101101 root.surface.activate();
102102 }
103+ onFocusedChanged: {
104+ if (root.surface.focused) {
105+ childWindow.focus = true;
106+ // Propagate
107+ root.focus = true;
108+ }
109+ }
103110 }
104111
105112 // Using a loader here mainly to circunvent the "ChildWindowTree is instantiated recursively" error from the QML engine
@@ -119,5 +126,12 @@ Item {
119126 property: "boundsItem"
120127 value: root.boundsItem
121128 }
129+ onFocusChanged: {
130+ if (focus) {
131+ // A surface in some ChildWindowTree got focused.
132+ // Propagate
133+ root.focus = true;
134+ }
135+ }
122136 }
123137}
qml/Stage/Stage.qml+10−1
@@ -899,12 +899,13 @@ FocusScope {
899899 priv.updateMainAndSideStageIndexes();
900900 }
901901 appDelegate.focus = true;
902+ priv.focusedAppDelegate = appDelegate;
902903 }
903904
904905 function updateQmlFocusFromMirSurfaceFocus() {
905906 if (model.window.focused) {
906907 claimFocus();
907− priv.focusedAppDelegate = appDelegate;
908+ decoratedWindow.focus = true;
908909 }
909910 }
910911
@@ -1807,6 +1808,14 @@ FocusScope {
18071808 boundsItem: boundariesForWindowPlacement
18081809
18091810 z: childWindowRepeater.count - model.index
1811+
1812+ onFocusChanged: {
1813+ if (focus) {
1814+ // some child surface in this tree got focus.
1815+ // Ensure we also have it at the top-level hierarchy
1816+ appDelegate.claimFocus();
1817+ }
1818+ }
18101819 }
18111820 }
18121821 }
tests/mocks/Unity/Application/MirSurface.cpp+5
@@ -452,6 +452,11 @@ void MirSurface::setHeightIncrement(int value)
452452void MirSurface::close()
453453{
454454 DEBUG_MSG("");
455+
456+ for (int i = 0; i < m_childSurfaceList->count(); ++i) {
457+ m_childSurfaceList->get(i)->close();
458+ }
459+
455460 if (!m_zombieTimer.isActive()) {
456461 m_zombieTimer.start();
457462 Q_EMIT closeRequested();
tests/qmltests/Stage/tst_DesktopStage.qml+10
@@ -1057,5 +1057,15 @@ Item {
10571057 tap(maxButton);
10581058 tryCompare(appDelegate, "state", "maximized");
10591059 }
1060+
1061+ function test_childWindowGetsActiveFocus() {
1062+ var appDelegate = startApplication("kate");
1063+ appDelegate.surface.openDialog(units.gu(5), units.gu(5), units.gu(30), units.gu(30));
1064+ var childWindow = findChild(appDelegate, "childWindow");
1065+ verify(childWindow);
1066+ var surfaceItem = findChild(childWindow, "surfaceItem");
1067+ verify(surfaceItem);
1068+ tryCompare(surfaceItem, "activeFocus", true);
1069+ }
10601070 }
10611071}