Merge lp:~aacid/unity8/tab_focus_fence_dialogs into lp:unity8
- tab_focus_fence_dialogs
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Lukáš Tinkl |
Approved revision: | 2753 |
Merged at revision: | 2772 |
Proposed branch: | lp:~aacid/unity8/tab_focus_fence_dialogs |
Merge into: | lp:unity8 |
Prerequisite: | lp:~aacid/unity8/focus_dialog_buttons |
Diff against target: |
419 lines (+163/-8) 11 files modified
plugins/Utils/CMakeLists.txt (+1/-0) plugins/Utils/plugin.cpp (+3/-1) plugins/Utils/tabfocusfence.cpp (+46/-0) plugins/Utils/tabfocusfence.h (+35/-0) qml/Components/Dialogs.qml (+9/-1) qml/Components/Lockscreen.qml (+3/-1) qml/Components/ModeSwitchWarningDialog.qml (+8/-2) qml/Components/ShellDialog.qml (+15/-1) tests/mocks/Utils/CMakeLists.txt (+1/-0) tests/mocks/Utils/plugin.cpp (+3/-1) tests/qmltests/tst_OrientedShell.qml (+39/-1) |
To merge this branch: | bzr merge lp:~aacid/unity8/tab_focus_fence_dialogs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Approve | |
Lukáš Tinkl (community) | Approve | ||
Review via email: mp+313681@code.launchpad.net |
Commit message
Limit tab-focus travelling on dialogs with a fence
Description of the change
* Are there any related MPs required for this MP to build/function as expected?
Prereq
* Did you perform an exploratory manual test run of your code change and any related functionality?
Only tests since unity8 is not runnable on zesty at the moment
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
* If you changed the UI, has there been a design review?
N/A
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
- 2747. By Albert Astals Cid
-
Test the focus fence in the shutdown dialog
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2747
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Lukáš Tinkl (lukas-kde) wrote : | # |
Some minor comments inline, otherwise the code looks good (haven't tested yet)
Lukáš Tinkl (lukas-kde) wrote : | # |
Generally works fine but I can no longer press Esc to dismiss the logout/lock/reboot dialog.
Lukáš Tinkl (lukas-kde) wrote : | # |
When in phone mode:
1. Press Ctrl+Alt+Delete to invoke the logout dialog
2. Press Tab
3. The task switcher gets activated instead
4. Subsequent Tab presses are correctly cycling thru the dialog's buttons
Point 3 needs fixing
- 2748. By Albert Astals Cid
-
New year
- 2749. By Albert Astals Cid
-
{}
- 2750. By Albert Astals Cid
-
oh no an empty line!
Albert Astals Cid (aacid) wrote : | # |
> What is this purpose of this, can't see it being used anywhere
It's a default property, the purpose is to make children of the parent children of the default property.
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2750
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 2751. By Albert Astals Cid
-
Merge
- 2752. By Albert Astals Cid
-
Beware of the evil double space!
- 2753. By Albert Astals Cid
-
Restore Esc to close dialog + test
Albert Astals Cid (aacid) wrote : | # |
> Generally works fine but I can no longer press Esc to dismiss the
> logout/lock/reboot dialog.
Fixed
Albert Astals Cid (aacid) wrote : | # |
> When in phone mode:
>
> 1. Press Ctrl+Alt+Delete to invoke the logout dialog
> 2. Press Tab
> 3. The task switcher gets activated instead
> 4. Subsequent Tab presses are correctly cycling thru the dialog's buttons
>
>
> Point 3 needs fixing
This seems to be a side effect of switching VTs, if you don't all is fine.
Lukáš Tinkl (lukas-kde) wrote : | # |
This branch alone works fine; the issue with the logout dialog breaking Alt+Tab will be dealt with in another branch.
Waiting with top approval for CI
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2752
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Lukáš Tinkl (lukas-kde) wrote : | # |
* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
* Did CI run pass? If not, please explain why.
Yes, with an exception of an unrelated failure
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:2753
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'plugins/Utils/CMakeLists.txt' | |||
2 | --- plugins/Utils/CMakeLists.txt 2016-12-07 13:43:25 +0000 | |||
3 | +++ plugins/Utils/CMakeLists.txt 2017-01-03 13:45:36 +0000 | |||
4 | @@ -34,6 +34,7 @@ | |||
5 | 34 | deviceconfigparser.cpp | 34 | deviceconfigparser.cpp |
6 | 35 | globalfunctions.cpp | 35 | globalfunctions.cpp |
7 | 36 | URLDispatcher.cpp | 36 | URLDispatcher.cpp |
8 | 37 | tabfocusfence.cpp | ||
9 | 37 | plugin.cpp | 38 | plugin.cpp |
10 | 38 | ) | 39 | ) |
11 | 39 | 40 | ||
12 | 40 | 41 | ||
13 | === modified file 'plugins/Utils/plugin.cpp' | |||
14 | --- plugins/Utils/plugin.cpp 2016-11-01 18:18:56 +0000 | |||
15 | +++ plugins/Utils/plugin.cpp 2017-01-03 13:45:36 +0000 | |||
16 | @@ -1,5 +1,5 @@ | |||
17 | 1 | /* | 1 | /* |
19 | 2 | * Copyright (C) 2012-2015 Canonical, Ltd. | 2 | * Copyright (C) 2012-2017 Canonical, Ltd. |
20 | 3 | * | 3 | * |
21 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
22 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
23 | @@ -40,6 +40,7 @@ | |||
24 | 40 | #include "globalfunctions.h" | 40 | #include "globalfunctions.h" |
25 | 41 | #include "URLDispatcher.h" | 41 | #include "URLDispatcher.h" |
26 | 42 | #include "appdrawerproxymodel.h" | 42 | #include "appdrawerproxymodel.h" |
27 | 43 | #include "tabfocusfence.h" | ||
28 | 43 | 44 | ||
29 | 44 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) | 45 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) |
30 | 45 | { | 46 | { |
31 | @@ -84,4 +85,5 @@ | |||
32 | 84 | qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions); | 85 | qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions); |
33 | 85 | qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher"); | 86 | qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher"); |
34 | 86 | qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel"); | 87 | qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel"); |
35 | 88 | qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence"); | ||
36 | 87 | } | 89 | } |
37 | 88 | 90 | ||
38 | === added file 'plugins/Utils/tabfocusfence.cpp' | |||
39 | --- plugins/Utils/tabfocusfence.cpp 1970-01-01 00:00:00 +0000 | |||
40 | +++ plugins/Utils/tabfocusfence.cpp 2017-01-03 13:45:36 +0000 | |||
41 | @@ -0,0 +1,46 @@ | |||
42 | 1 | /* | ||
43 | 2 | * Copyright 2017 Canonical Ltd. | ||
44 | 3 | * | ||
45 | 4 | * This program is free software; you can redistribute it and/or modify | ||
46 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
47 | 6 | * the Free Software Foundation; version 3. | ||
48 | 7 | * | ||
49 | 8 | * This program is distributed in the hope that it will be useful, | ||
50 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
51 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
52 | 11 | * GNU Lesser General Public License for more details. | ||
53 | 12 | * | ||
54 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
55 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
56 | 15 | */ | ||
57 | 16 | |||
58 | 17 | #include "tabfocusfence.h" | ||
59 | 18 | |||
60 | 19 | #include <private/qquickitem_p.h> | ||
61 | 20 | |||
62 | 21 | TabFocusFenceItem::TabFocusFenceItem(QQuickItem *parent) : QQuickItem(parent) | ||
63 | 22 | { | ||
64 | 23 | QQuickItemPrivate *d = QQuickItemPrivate::get(this); | ||
65 | 24 | d->isTabFence = true; | ||
66 | 25 | setFlag(ItemIsFocusScope); | ||
67 | 26 | } | ||
68 | 27 | |||
69 | 28 | void TabFocusFenceItem::keyPressEvent(QKeyEvent *event) | ||
70 | 29 | { | ||
71 | 30 | // Needed so we eat Tab keys when there's only one item inside the fence | ||
72 | 31 | if (event->key() == Qt::Key_Tab) { | ||
73 | 32 | event->accept(); | ||
74 | 33 | } else { | ||
75 | 34 | QQuickItem::keyPressEvent(event); | ||
76 | 35 | } | ||
77 | 36 | } | ||
78 | 37 | |||
79 | 38 | void TabFocusFenceItem::keyReleaseEvent(QKeyEvent *event) | ||
80 | 39 | { | ||
81 | 40 | // Needed so we eat Tab keys when there's only one item inside the fence | ||
82 | 41 | if (event->key() == Qt::Key_Tab) { | ||
83 | 42 | event->accept(); | ||
84 | 43 | } else { | ||
85 | 44 | QQuickItem::keyReleaseEvent(event); | ||
86 | 45 | } | ||
87 | 46 | } | ||
88 | 0 | 47 | ||
89 | === added file 'plugins/Utils/tabfocusfence.h' | |||
90 | --- plugins/Utils/tabfocusfence.h 1970-01-01 00:00:00 +0000 | |||
91 | +++ plugins/Utils/tabfocusfence.h 2017-01-03 13:45:36 +0000 | |||
92 | @@ -0,0 +1,35 @@ | |||
93 | 1 | /* | ||
94 | 2 | * Copyright 2017 Canonical Ltd. | ||
95 | 3 | * | ||
96 | 4 | * This program is free software; you can redistribute it and/or modify | ||
97 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
98 | 6 | * the Free Software Foundation; version 3. | ||
99 | 7 | * | ||
100 | 8 | * This program is distributed in the hope that it will be useful, | ||
101 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
102 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
103 | 11 | * GNU Lesser General Public License for more details. | ||
104 | 12 | * | ||
105 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
106 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
107 | 15 | */ | ||
108 | 16 | |||
109 | 17 | #ifndef TABFOCUSFENCE_H | ||
110 | 18 | #define TABFOCUSFENCE_H | ||
111 | 19 | |||
112 | 20 | #include <QQuickItem> | ||
113 | 21 | |||
114 | 22 | // An item that restricts focus Tab travelling | ||
115 | 23 | // to its children | ||
116 | 24 | class TabFocusFenceItem : public QQuickItem | ||
117 | 25 | { | ||
118 | 26 | Q_OBJECT | ||
119 | 27 | |||
120 | 28 | public: | ||
121 | 29 | TabFocusFenceItem(QQuickItem *parent = nullptr); | ||
122 | 30 | |||
123 | 31 | void keyPressEvent(QKeyEvent *event) override; | ||
124 | 32 | void keyReleaseEvent(QKeyEvent *event) override; | ||
125 | 33 | }; | ||
126 | 34 | |||
127 | 35 | #endif | ||
128 | 0 | 36 | ||
129 | === modified file 'qml/Components/Dialogs.qml' | |||
130 | --- qml/Components/Dialogs.qml 2017-01-03 13:45:36 +0000 | |||
131 | +++ qml/Components/Dialogs.qml 2017-01-03 13:45:36 +0000 | |||
132 | @@ -1,5 +1,5 @@ | |||
133 | 1 | /* | 1 | /* |
135 | 2 | * Copyright (C) 2014-2016 Canonical, Ltd. | 2 | * Copyright (C) 2014-2017 Canonical, Ltd. |
136 | 3 | * | 3 | * |
137 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
138 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
139 | @@ -149,6 +149,7 @@ | |||
140 | 149 | title: i18n.ctr("Title: Lock/Log out dialog", "Log out") | 149 | title: i18n.ctr("Title: Lock/Log out dialog", "Log out") |
141 | 150 | text: i18n.tr("Are you sure you want to log out?") | 150 | text: i18n.tr("Are you sure you want to log out?") |
142 | 151 | Button { | 151 | Button { |
143 | 152 | width: parent.width | ||
144 | 152 | text: i18n.ctr("Button: Lock the system", "Lock") | 153 | text: i18n.ctr("Button: Lock the system", "Lock") |
145 | 153 | onClicked: { | 154 | onClicked: { |
146 | 154 | LightDMService.greeter.showGreeter() | 155 | LightDMService.greeter.showGreeter() |
147 | @@ -156,6 +157,7 @@ | |||
148 | 156 | } | 157 | } |
149 | 157 | } | 158 | } |
150 | 158 | Button { | 159 | Button { |
151 | 160 | width: parent.width | ||
152 | 159 | focus: true | 161 | focus: true |
153 | 160 | text: i18n.ctr("Button: Log out from the system", "Log Out") | 162 | text: i18n.ctr("Button: Log out from the system", "Log Out") |
154 | 161 | onClicked: { | 163 | onClicked: { |
155 | @@ -164,6 +166,7 @@ | |||
156 | 164 | } | 166 | } |
157 | 165 | } | 167 | } |
158 | 166 | Button { | 168 | Button { |
159 | 169 | width: parent.width | ||
160 | 167 | text: i18n.tr("Cancel") | 170 | text: i18n.tr("Cancel") |
161 | 168 | onClicked: { | 171 | onClicked: { |
162 | 169 | logoutDialog.hide(); | 172 | logoutDialog.hide(); |
163 | @@ -179,12 +182,14 @@ | |||
164 | 179 | title: i18n.ctr("Title: Reboot dialog", "Reboot") | 182 | title: i18n.ctr("Title: Reboot dialog", "Reboot") |
165 | 180 | text: i18n.tr("Are you sure you want to reboot?") | 183 | text: i18n.tr("Are you sure you want to reboot?") |
166 | 181 | Button { | 184 | Button { |
167 | 185 | width: parent.width | ||
168 | 182 | text: i18n.tr("No") | 186 | text: i18n.tr("No") |
169 | 183 | onClicked: { | 187 | onClicked: { |
170 | 184 | rebootDialog.hide(); | 188 | rebootDialog.hide(); |
171 | 185 | } | 189 | } |
172 | 186 | } | 190 | } |
173 | 187 | Button { | 191 | Button { |
174 | 192 | width: parent.width | ||
175 | 188 | focus: true | 193 | focus: true |
176 | 189 | text: i18n.tr("Yes") | 194 | text: i18n.tr("Yes") |
177 | 190 | onClicked: { | 195 | onClicked: { |
178 | @@ -204,6 +209,7 @@ | |||
179 | 204 | title: i18n.ctr("Title: Power off/Restart dialog", "Power") | 209 | title: i18n.ctr("Title: Power off/Restart dialog", "Power") |
180 | 205 | text: i18n.tr("Are you sure you would like\nto power off?") | 210 | text: i18n.tr("Are you sure you would like\nto power off?") |
181 | 206 | Button { | 211 | Button { |
182 | 212 | width: parent.width | ||
183 | 207 | focus: true | 213 | focus: true |
184 | 208 | text: i18n.ctr("Button: Power off the system", "Power off") | 214 | text: i18n.ctr("Button: Power off the system", "Power off") |
185 | 209 | onClicked: { | 215 | onClicked: { |
186 | @@ -214,6 +220,7 @@ | |||
187 | 214 | color: theme.palette.normal.negative | 220 | color: theme.palette.normal.negative |
188 | 215 | } | 221 | } |
189 | 216 | Button { | 222 | Button { |
190 | 223 | width: parent.width | ||
191 | 217 | text: i18n.ctr("Button: Restart the system", "Restart") | 224 | text: i18n.ctr("Button: Restart the system", "Restart") |
192 | 218 | onClicked: { | 225 | onClicked: { |
193 | 219 | root.closeAllApps(); | 226 | root.closeAllApps(); |
194 | @@ -222,6 +229,7 @@ | |||
195 | 222 | } | 229 | } |
196 | 223 | } | 230 | } |
197 | 224 | Button { | 231 | Button { |
198 | 232 | width: parent.width | ||
199 | 225 | text: i18n.tr("Cancel") | 233 | text: i18n.tr("Cancel") |
200 | 226 | onClicked: { | 234 | onClicked: { |
201 | 227 | powerDialog.hide(); | 235 | powerDialog.hide(); |
202 | 228 | 236 | ||
203 | === modified file 'qml/Components/Lockscreen.qml' | |||
204 | --- qml/Components/Lockscreen.qml 2016-08-30 14:06:47 +0000 | |||
205 | +++ qml/Components/Lockscreen.qml 2017-01-03 13:45:36 +0000 | |||
206 | @@ -1,5 +1,5 @@ | |||
207 | 1 | /* | 1 | /* |
209 | 2 | * Copyright (C) 2013 Canonical, Ltd. | 2 | * Copyright (C) 2013-2017 Canonical, Ltd. |
210 | 3 | * | 3 | * |
211 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
212 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
213 | @@ -240,8 +240,10 @@ | |||
214 | 240 | property var dialogLoader // dummy to satisfy ShellDialog's context dependent prop | 240 | property var dialogLoader // dummy to satisfy ShellDialog's context dependent prop |
215 | 241 | 241 | ||
216 | 242 | Button { | 242 | Button { |
217 | 243 | width: parent.width | ||
218 | 243 | objectName: "infoPopupOkButton" | 244 | objectName: "infoPopupOkButton" |
219 | 244 | text: i18n.tr("OK") | 245 | text: i18n.tr("OK") |
220 | 246 | focus: true | ||
221 | 245 | onClicked: { | 247 | onClicked: { |
222 | 246 | PopupUtils.close(dialog) | 248 | PopupUtils.close(dialog) |
223 | 247 | root.infoPopupConfirmed(); | 249 | root.infoPopupConfirmed(); |
224 | 248 | 250 | ||
225 | === modified file 'qml/Components/ModeSwitchWarningDialog.qml' | |||
226 | --- qml/Components/ModeSwitchWarningDialog.qml 2016-05-17 20:46:51 +0000 | |||
227 | +++ qml/Components/ModeSwitchWarningDialog.qml 2017-01-03 13:45:36 +0000 | |||
228 | @@ -1,5 +1,5 @@ | |||
229 | 1 | /* | 1 | /* |
231 | 2 | * Copyright (C) 2015 Canonical, Ltd. | 2 | * Copyright (C) 2015-2017 Canonical, Ltd. |
232 | 3 | * | 3 | * |
233 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
234 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
235 | @@ -29,6 +29,7 @@ | |||
236 | 29 | signal forceClose(); | 29 | signal forceClose(); |
237 | 30 | 30 | ||
238 | 31 | Label { | 31 | Label { |
239 | 32 | width: parent.width | ||
240 | 32 | text: i18n.tr("Apps may have unsaved data:") | 33 | text: i18n.tr("Apps may have unsaved data:") |
241 | 33 | fontSize: "large" | 34 | fontSize: "large" |
242 | 34 | color: "#5D5D5D" | 35 | color: "#5D5D5D" |
243 | @@ -37,6 +38,7 @@ | |||
244 | 37 | Repeater { | 38 | Repeater { |
245 | 38 | id: appRepeater | 39 | id: appRepeater |
246 | 39 | RowLayout { | 40 | RowLayout { |
247 | 41 | width: parent.width | ||
248 | 40 | spacing: units.gu(2) | 42 | spacing: units.gu(2) |
249 | 41 | Image { | 43 | Image { |
250 | 42 | Layout.preferredHeight: units.gu(2) | 44 | Layout.preferredHeight: units.gu(2) |
251 | @@ -54,20 +56,23 @@ | |||
252 | 54 | } | 56 | } |
253 | 55 | 57 | ||
254 | 56 | Label { | 58 | Label { |
255 | 59 | width: parent.width | ||
256 | 57 | text: i18n.ctr("Re-dock means connect the device again to an external screen/mouse/keyboard", "Re-dock, save your work and close these apps to continue.") | 60 | text: i18n.ctr("Re-dock means connect the device again to an external screen/mouse/keyboard", "Re-dock, save your work and close these apps to continue.") |
257 | 58 | wrapMode: Text.WordWrap | 61 | wrapMode: Text.WordWrap |
258 | 59 | color: "#888888" | 62 | color: "#888888" |
259 | 60 | } | 63 | } |
260 | 61 | 64 | ||
261 | 62 | Label { | 65 | Label { |
262 | 66 | width: parent.width | ||
263 | 63 | text: i18n.tr("Or force close now (unsaved data will be lost).") | 67 | text: i18n.tr("Or force close now (unsaved data will be lost).") |
264 | 64 | wrapMode: Text.WordWrap | 68 | wrapMode: Text.WordWrap |
265 | 65 | color: "#888888" | 69 | color: "#888888" |
266 | 66 | } | 70 | } |
267 | 67 | 71 | ||
269 | 68 | ThinDivider {} | 72 | ThinDivider { width: parent.width } |
270 | 69 | 73 | ||
271 | 70 | RowLayout { | 74 | RowLayout { |
272 | 75 | width: parent.width | ||
273 | 71 | Label { | 76 | Label { |
274 | 72 | objectName: "reconnectLabel" | 77 | objectName: "reconnectLabel" |
275 | 73 | Layout.fillWidth: true | 78 | Layout.fillWidth: true |
276 | @@ -84,6 +89,7 @@ | |||
277 | 84 | } | 89 | } |
278 | 85 | 90 | ||
279 | 86 | Button { | 91 | Button { |
280 | 92 | focus: true | ||
281 | 87 | objectName: "forceCloseButton" | 93 | objectName: "forceCloseButton" |
282 | 88 | text: i18n.tr("Close all") | 94 | text: i18n.tr("Close all") |
283 | 89 | color: theme.palette.normal.negative | 95 | color: theme.palette.normal.negative |
284 | 90 | 96 | ||
285 | === modified file 'qml/Components/ShellDialog.qml' | |||
286 | --- qml/Components/ShellDialog.qml 2016-03-29 03:47:39 +0000 | |||
287 | +++ qml/Components/ShellDialog.qml 2017-01-03 13:45:36 +0000 | |||
288 | @@ -1,5 +1,5 @@ | |||
289 | 1 | /* | 1 | /* |
291 | 2 | * Copyright (C) 2014 Canonical, Ltd. | 2 | * Copyright (C) 2014-2017 Canonical, Ltd. |
292 | 3 | * | 3 | * |
293 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
294 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
295 | @@ -19,6 +19,7 @@ | |||
296 | 19 | import Ubuntu.Components 1.3 | 19 | import Ubuntu.Components 1.3 |
297 | 20 | import Ubuntu.Components.Themes 1.3 | 20 | import Ubuntu.Components.Themes 1.3 |
298 | 21 | import Ubuntu.Components.Popups 1.3 | 21 | import Ubuntu.Components.Popups 1.3 |
299 | 22 | import Utils 0.1 | ||
300 | 22 | 23 | ||
301 | 23 | /* | 24 | /* |
302 | 24 | A Dialog configured for use as a proper in-scene Dialog | 25 | A Dialog configured for use as a proper in-scene Dialog |
303 | @@ -32,6 +33,8 @@ | |||
304 | 32 | // NB: PopupBase, Dialog's superclass, will check for the existence of this property | 33 | // NB: PopupBase, Dialog's superclass, will check for the existence of this property |
305 | 33 | property bool reparentToRootItem: false | 34 | property bool reparentToRootItem: false |
306 | 34 | 35 | ||
307 | 36 | default property alias columnContents: column.data | ||
308 | 37 | |||
309 | 35 | onVisibleChanged: { if (!visible && dialogLoader) { dialogLoader.active = false; } } | 38 | onVisibleChanged: { if (!visible && dialogLoader) { dialogLoader.active = false; } } |
310 | 36 | 39 | ||
311 | 37 | Keys.onEscapePressed: hide() | 40 | Keys.onEscapePressed: hide() |
312 | @@ -50,4 +53,15 @@ | |||
313 | 50 | __foreground.theme = themeHack | 53 | __foreground.theme = themeHack |
314 | 51 | show(); | 54 | show(); |
315 | 52 | } | 55 | } |
316 | 56 | |||
317 | 57 | TabFocusFence { | ||
318 | 58 | width: parent.width | ||
319 | 59 | height: column.height | ||
320 | 60 | focus: true | ||
321 | 61 | Column { | ||
322 | 62 | id: column | ||
323 | 63 | width: parent.width | ||
324 | 64 | spacing: units.gu(2) | ||
325 | 65 | } | ||
326 | 66 | } | ||
327 | 53 | } | 67 | } |
328 | 54 | 68 | ||
329 | === modified file 'tests/mocks/Utils/CMakeLists.txt' | |||
330 | --- tests/mocks/Utils/CMakeLists.txt 2016-12-07 13:43:25 +0000 | |||
331 | +++ tests/mocks/Utils/CMakeLists.txt 2017-01-03 13:45:36 +0000 | |||
332 | @@ -25,6 +25,7 @@ | |||
333 | 25 | ${CMAKE_SOURCE_DIR}/plugins/Utils/deviceconfigparser.cpp | 25 | ${CMAKE_SOURCE_DIR}/plugins/Utils/deviceconfigparser.cpp |
334 | 26 | ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp | 26 | ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp |
335 | 27 | ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp | 27 | ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp |
336 | 28 | ${CMAKE_SOURCE_DIR}/plugins/Utils/tabfocusfence.cpp | ||
337 | 28 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h | 29 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h |
338 | 29 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h | 30 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h |
339 | 30 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h | 31 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h |
340 | 31 | 32 | ||
341 | === modified file 'tests/mocks/Utils/plugin.cpp' | |||
342 | --- tests/mocks/Utils/plugin.cpp 2016-11-01 18:18:56 +0000 | |||
343 | +++ tests/mocks/Utils/plugin.cpp 2017-01-03 13:45:36 +0000 | |||
344 | @@ -1,5 +1,5 @@ | |||
345 | 1 | /* | 1 | /* |
347 | 2 | * Copyright (C) 2015-2016 Canonical, Ltd. | 2 | * Copyright (C) 2015-2017 Canonical, Ltd. |
348 | 3 | * | 3 | * |
349 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
350 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
351 | @@ -41,6 +41,7 @@ | |||
352 | 41 | #include <deviceconfigparser.h> | 41 | #include <deviceconfigparser.h> |
353 | 42 | #include <globalfunctions.h> | 42 | #include <globalfunctions.h> |
354 | 43 | #include <appdrawerproxymodel.h> | 43 | #include <appdrawerproxymodel.h> |
355 | 44 | #include <tabfocusfence.h> | ||
356 | 44 | 45 | ||
357 | 45 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) | 46 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) |
358 | 46 | { | 47 | { |
359 | @@ -84,4 +85,5 @@ | |||
360 | 84 | qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions); | 85 | qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions); |
361 | 85 | qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher"); | 86 | qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher"); |
362 | 86 | qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel"); | 87 | qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel"); |
363 | 88 | qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence"); | ||
364 | 87 | } | 89 | } |
365 | 88 | 90 | ||
366 | === modified file 'tests/qmltests/tst_OrientedShell.qml' | |||
367 | --- tests/qmltests/tst_OrientedShell.qml 2016-12-12 16:45:09 +0000 | |||
368 | +++ tests/qmltests/tst_OrientedShell.qml 2017-01-03 13:45:36 +0000 | |||
369 | @@ -1,5 +1,5 @@ | |||
370 | 1 | /* | 1 | /* |
372 | 2 | * Copyright (C) 2015-2016 Canonical, Ltd. | 2 | * Copyright (C) 2015-2017 Canonical, Ltd. |
373 | 3 | * | 3 | * |
374 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
375 | 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
376 | @@ -1558,5 +1558,43 @@ | |||
377 | 1558 | verify(surface); | 1558 | verify(surface); |
378 | 1559 | return surface.activeFocus; | 1559 | return surface.activeFocus; |
379 | 1560 | } | 1560 | } |
380 | 1561 | |||
381 | 1562 | function test_tabCyclyingInShutdownDialog() { | ||
382 | 1563 | loadShell("mako"); | ||
383 | 1564 | |||
384 | 1565 | testCase.showPowerDialog(); | ||
385 | 1566 | |||
386 | 1567 | var dialogs = findChild(orientedShell, "dialogs"); | ||
387 | 1568 | var buttons = findChildsByType(dialogs, "Button"); | ||
388 | 1569 | |||
389 | 1570 | tryCompare(buttons[0], "activeFocus", true); | ||
390 | 1571 | |||
391 | 1572 | keyClick(Qt.Key_Tab); | ||
392 | 1573 | tryCompare(buttons[1], "activeFocus", true); | ||
393 | 1574 | |||
394 | 1575 | keyClick(Qt.Key_Tab); | ||
395 | 1576 | tryCompare(buttons[2], "activeFocus", true); | ||
396 | 1577 | |||
397 | 1578 | keyClick(Qt.Key_Tab); | ||
398 | 1579 | tryCompare(buttons[0], "activeFocus", true); | ||
399 | 1580 | |||
400 | 1581 | keyClick(Qt.Key_Escape); | ||
401 | 1582 | |||
402 | 1583 | var dialogLoader = findChild(orientedShell, "dialogLoader"); | ||
403 | 1584 | tryCompare(dialogLoader, "item", null); | ||
404 | 1585 | } | ||
405 | 1586 | |||
406 | 1587 | function test_escColosesShutdownDialog() { | ||
407 | 1588 | loadShell("mako"); | ||
408 | 1589 | |||
409 | 1590 | testCase.showPowerDialog(); | ||
410 | 1591 | |||
411 | 1592 | var dialogLoader = findChild(orientedShell, "dialogLoader"); | ||
412 | 1593 | tryCompareFunction(function() { return dialogLoader.item !== null }, true); | ||
413 | 1594 | |||
414 | 1595 | keyClick(Qt.Key_Escape); | ||
415 | 1596 | |||
416 | 1597 | tryCompare(dialogLoader, "item", null); | ||
417 | 1598 | } | ||
418 | 1561 | } | 1599 | } |
419 | 1562 | } | 1600 | } |
FAILED: Continuous integration, rev:2746 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2759/ /unity8- jenkins. ubuntu. com/job/ build/3617/ console /unity8- jenkins. ubuntu. com/job/ build-0- fetch/3645 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 3491/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= zesty/3491/ console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 3491/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= zesty/3491/ console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 3491/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= zesty/3491/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2759/ rebuild
https:/