Merge lp:~aacid/unity8/tab_focus_fence_dialogs into lp:unity8

Proposed by Albert Astals Cid
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
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

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
2747. By Albert Astals Cid

Test the focus fence in the shutdown dialog

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Some minor comments inline, otherwise the code looks good (haven't tested yet)

review: Needs Fixing (code-review)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Generally works fine but I can no longer press Esc to dismiss the logout/lock/reboot dialog.

review: Needs Fixing
Revision history for this message
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

review: Needs Fixing
2748. By Albert Astals Cid

New year

2749. By Albert Astals Cid

{}

2750. By Albert Astals Cid

oh no an empty line!

Revision history for this message
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.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
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

Revision history for this message
Albert Astals Cid (aacid) wrote :

> Generally works fine but I can no longer press Esc to dismiss the
> logout/lock/reboot dialog.

Fixed

Revision history for this message
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.

Revision history for this message
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

review: Approve
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2752
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2795/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3659
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2095
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2095
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3687
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3532
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3532/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3532
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3532/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3532
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3532/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3532
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3532/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3532
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3532/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3532
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3532/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2795/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
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

review: Approve
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2753
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2806/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3673
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2106
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2106
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3701
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3545
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3545/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3545
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3545/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3545
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3545/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3545
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3545/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3545
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3545/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3545
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3545/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2806/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/Utils/CMakeLists.txt'
--- plugins/Utils/CMakeLists.txt 2016-12-07 13:43:25 +0000
+++ plugins/Utils/CMakeLists.txt 2017-01-03 13:45:36 +0000
@@ -34,6 +34,7 @@
34 deviceconfigparser.cpp34 deviceconfigparser.cpp
35 globalfunctions.cpp35 globalfunctions.cpp
36 URLDispatcher.cpp36 URLDispatcher.cpp
37 tabfocusfence.cpp
37 plugin.cpp38 plugin.cpp
38 )39 )
3940
4041
=== modified file 'plugins/Utils/plugin.cpp'
--- plugins/Utils/plugin.cpp 2016-11-01 18:18:56 +0000
+++ plugins/Utils/plugin.cpp 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2012-2015 Canonical, Ltd.2 * Copyright (C) 2012-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40#include "globalfunctions.h"40#include "globalfunctions.h"
41#include "URLDispatcher.h"41#include "URLDispatcher.h"
42#include "appdrawerproxymodel.h"42#include "appdrawerproxymodel.h"
43#include "tabfocusfence.h"
4344
44static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)45static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
45{46{
@@ -84,4 +85,5 @@
84 qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions);85 qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions);
85 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");86 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
86 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");87 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
88 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
87}89}
8890
=== added file 'plugins/Utils/tabfocusfence.cpp'
--- plugins/Utils/tabfocusfence.cpp 1970-01-01 00:00:00 +0000
+++ plugins/Utils/tabfocusfence.cpp 2017-01-03 13:45:36 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright 2017 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#include "tabfocusfence.h"
18
19#include <private/qquickitem_p.h>
20
21TabFocusFenceItem::TabFocusFenceItem(QQuickItem *parent) : QQuickItem(parent)
22{
23 QQuickItemPrivate *d = QQuickItemPrivate::get(this);
24 d->isTabFence = true;
25 setFlag(ItemIsFocusScope);
26}
27
28void TabFocusFenceItem::keyPressEvent(QKeyEvent *event)
29{
30 // Needed so we eat Tab keys when there's only one item inside the fence
31 if (event->key() == Qt::Key_Tab) {
32 event->accept();
33 } else {
34 QQuickItem::keyPressEvent(event);
35 }
36}
37
38void TabFocusFenceItem::keyReleaseEvent(QKeyEvent *event)
39{
40 // Needed so we eat Tab keys when there's only one item inside the fence
41 if (event->key() == Qt::Key_Tab) {
42 event->accept();
43 } else {
44 QQuickItem::keyReleaseEvent(event);
45 }
46}
047
=== added file 'plugins/Utils/tabfocusfence.h'
--- plugins/Utils/tabfocusfence.h 1970-01-01 00:00:00 +0000
+++ plugins/Utils/tabfocusfence.h 2017-01-03 13:45:36 +0000
@@ -0,0 +1,35 @@
1/*
2 * Copyright 2017 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#ifndef TABFOCUSFENCE_H
18#define TABFOCUSFENCE_H
19
20#include <QQuickItem>
21
22// An item that restricts focus Tab travelling
23// to its children
24class TabFocusFenceItem : public QQuickItem
25{
26Q_OBJECT
27
28public:
29 TabFocusFenceItem(QQuickItem *parent = nullptr);
30
31 void keyPressEvent(QKeyEvent *event) override;
32 void keyReleaseEvent(QKeyEvent *event) override;
33};
34
35#endif
036
=== modified file 'qml/Components/Dialogs.qml'
--- qml/Components/Dialogs.qml 2017-01-03 13:45:36 +0000
+++ qml/Components/Dialogs.qml 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014-2016 Canonical, Ltd.2 * Copyright (C) 2014-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -149,6 +149,7 @@
149 title: i18n.ctr("Title: Lock/Log out dialog", "Log out")149 title: i18n.ctr("Title: Lock/Log out dialog", "Log out")
150 text: i18n.tr("Are you sure you want to log out?")150 text: i18n.tr("Are you sure you want to log out?")
151 Button {151 Button {
152 width: parent.width
152 text: i18n.ctr("Button: Lock the system", "Lock")153 text: i18n.ctr("Button: Lock the system", "Lock")
153 onClicked: {154 onClicked: {
154 LightDMService.greeter.showGreeter()155 LightDMService.greeter.showGreeter()
@@ -156,6 +157,7 @@
156 }157 }
157 }158 }
158 Button {159 Button {
160 width: parent.width
159 focus: true161 focus: true
160 text: i18n.ctr("Button: Log out from the system", "Log Out")162 text: i18n.ctr("Button: Log out from the system", "Log Out")
161 onClicked: {163 onClicked: {
@@ -164,6 +166,7 @@
164 }166 }
165 }167 }
166 Button {168 Button {
169 width: parent.width
167 text: i18n.tr("Cancel")170 text: i18n.tr("Cancel")
168 onClicked: {171 onClicked: {
169 logoutDialog.hide();172 logoutDialog.hide();
@@ -179,12 +182,14 @@
179 title: i18n.ctr("Title: Reboot dialog", "Reboot")182 title: i18n.ctr("Title: Reboot dialog", "Reboot")
180 text: i18n.tr("Are you sure you want to reboot?")183 text: i18n.tr("Are you sure you want to reboot?")
181 Button {184 Button {
185 width: parent.width
182 text: i18n.tr("No")186 text: i18n.tr("No")
183 onClicked: {187 onClicked: {
184 rebootDialog.hide();188 rebootDialog.hide();
185 }189 }
186 }190 }
187 Button {191 Button {
192 width: parent.width
188 focus: true193 focus: true
189 text: i18n.tr("Yes")194 text: i18n.tr("Yes")
190 onClicked: {195 onClicked: {
@@ -204,6 +209,7 @@
204 title: i18n.ctr("Title: Power off/Restart dialog", "Power")209 title: i18n.ctr("Title: Power off/Restart dialog", "Power")
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?")
206 Button {211 Button {
212 width: parent.width
207 focus: true213 focus: true
208 text: i18n.ctr("Button: Power off the system", "Power off")214 text: i18n.ctr("Button: Power off the system", "Power off")
209 onClicked: {215 onClicked: {
@@ -214,6 +220,7 @@
214 color: theme.palette.normal.negative220 color: theme.palette.normal.negative
215 }221 }
216 Button {222 Button {
223 width: parent.width
217 text: i18n.ctr("Button: Restart the system", "Restart")224 text: i18n.ctr("Button: Restart the system", "Restart")
218 onClicked: {225 onClicked: {
219 root.closeAllApps();226 root.closeAllApps();
@@ -222,6 +229,7 @@
222 }229 }
223 }230 }
224 Button {231 Button {
232 width: parent.width
225 text: i18n.tr("Cancel")233 text: i18n.tr("Cancel")
226 onClicked: {234 onClicked: {
227 powerDialog.hide();235 powerDialog.hide();
228236
=== modified file 'qml/Components/Lockscreen.qml'
--- qml/Components/Lockscreen.qml 2016-08-30 14:06:47 +0000
+++ qml/Components/Lockscreen.qml 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2013 Canonical, Ltd.2 * Copyright (C) 2013-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -240,8 +240,10 @@
240 property var dialogLoader // dummy to satisfy ShellDialog's context dependent prop240 property var dialogLoader // dummy to satisfy ShellDialog's context dependent prop
241241
242 Button {242 Button {
243 width: parent.width
243 objectName: "infoPopupOkButton"244 objectName: "infoPopupOkButton"
244 text: i18n.tr("OK")245 text: i18n.tr("OK")
246 focus: true
245 onClicked: {247 onClicked: {
246 PopupUtils.close(dialog)248 PopupUtils.close(dialog)
247 root.infoPopupConfirmed();249 root.infoPopupConfirmed();
248250
=== modified file 'qml/Components/ModeSwitchWarningDialog.qml'
--- qml/Components/ModeSwitchWarningDialog.qml 2016-05-17 20:46:51 +0000
+++ qml/Components/ModeSwitchWarningDialog.qml 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2015 Canonical, Ltd.2 * Copyright (C) 2015-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
29 signal forceClose();29 signal forceClose();
3030
31 Label {31 Label {
32 width: parent.width
32 text: i18n.tr("Apps may have unsaved data:")33 text: i18n.tr("Apps may have unsaved data:")
33 fontSize: "large"34 fontSize: "large"
34 color: "#5D5D5D"35 color: "#5D5D5D"
@@ -37,6 +38,7 @@
37 Repeater {38 Repeater {
38 id: appRepeater39 id: appRepeater
39 RowLayout {40 RowLayout {
41 width: parent.width
40 spacing: units.gu(2)42 spacing: units.gu(2)
41 Image {43 Image {
42 Layout.preferredHeight: units.gu(2)44 Layout.preferredHeight: units.gu(2)
@@ -54,20 +56,23 @@
54 }56 }
5557
56 Label {58 Label {
59 width: parent.width
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.")
58 wrapMode: Text.WordWrap61 wrapMode: Text.WordWrap
59 color: "#888888"62 color: "#888888"
60 }63 }
6164
62 Label {65 Label {
66 width: parent.width
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).")
64 wrapMode: Text.WordWrap68 wrapMode: Text.WordWrap
65 color: "#888888"69 color: "#888888"
66 }70 }
6771
68 ThinDivider {}72 ThinDivider { width: parent.width }
6973
70 RowLayout {74 RowLayout {
75 width: parent.width
71 Label {76 Label {
72 objectName: "reconnectLabel"77 objectName: "reconnectLabel"
73 Layout.fillWidth: true78 Layout.fillWidth: true
@@ -84,6 +89,7 @@
84 }89 }
8590
86 Button {91 Button {
92 focus: true
87 objectName: "forceCloseButton"93 objectName: "forceCloseButton"
88 text: i18n.tr("Close all")94 text: i18n.tr("Close all")
89 color: theme.palette.normal.negative95 color: theme.palette.normal.negative
9096
=== modified file 'qml/Components/ShellDialog.qml'
--- qml/Components/ShellDialog.qml 2016-03-29 03:47:39 +0000
+++ qml/Components/ShellDialog.qml 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical, Ltd.2 * Copyright (C) 2014-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
19import Ubuntu.Components 1.319import Ubuntu.Components 1.3
20import Ubuntu.Components.Themes 1.320import Ubuntu.Components.Themes 1.3
21import Ubuntu.Components.Popups 1.321import Ubuntu.Components.Popups 1.3
22import Utils 0.1
2223
23/*24/*
24 A Dialog configured for use as a proper in-scene Dialog25 A Dialog configured for use as a proper in-scene Dialog
@@ -32,6 +33,8 @@
32 // NB: PopupBase, Dialog's superclass, will check for the existence of this property33 // NB: PopupBase, Dialog's superclass, will check for the existence of this property
33 property bool reparentToRootItem: false34 property bool reparentToRootItem: false
3435
36 default property alias columnContents: column.data
37
35 onVisibleChanged: { if (!visible && dialogLoader) { dialogLoader.active = false; } }38 onVisibleChanged: { if (!visible && dialogLoader) { dialogLoader.active = false; } }
3639
37 Keys.onEscapePressed: hide()40 Keys.onEscapePressed: hide()
@@ -50,4 +53,15 @@
50 __foreground.theme = themeHack53 __foreground.theme = themeHack
51 show();54 show();
52 }55 }
56
57 TabFocusFence {
58 width: parent.width
59 height: column.height
60 focus: true
61 Column {
62 id: column
63 width: parent.width
64 spacing: units.gu(2)
65 }
66 }
53}67}
5468
=== modified file 'tests/mocks/Utils/CMakeLists.txt'
--- tests/mocks/Utils/CMakeLists.txt 2016-12-07 13:43:25 +0000
+++ tests/mocks/Utils/CMakeLists.txt 2017-01-03 13:45:36 +0000
@@ -25,6 +25,7 @@
25 ${CMAKE_SOURCE_DIR}/plugins/Utils/deviceconfigparser.cpp25 ${CMAKE_SOURCE_DIR}/plugins/Utils/deviceconfigparser.cpp
26 ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp26 ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp
27 ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp27 ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp
28 ${CMAKE_SOURCE_DIR}/plugins/Utils/tabfocusfence.cpp
28 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h29 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
29 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h30 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
30 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h31 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
3132
=== modified file 'tests/mocks/Utils/plugin.cpp'
--- tests/mocks/Utils/plugin.cpp 2016-11-01 18:18:56 +0000
+++ tests/mocks/Utils/plugin.cpp 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2015-2016 Canonical, Ltd.2 * Copyright (C) 2015-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@
41#include <deviceconfigparser.h>41#include <deviceconfigparser.h>
42#include <globalfunctions.h>42#include <globalfunctions.h>
43#include <appdrawerproxymodel.h>43#include <appdrawerproxymodel.h>
44#include <tabfocusfence.h>
4445
45static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)46static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
46{47{
@@ -84,4 +85,5 @@
84 qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions);85 qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions);
85 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");86 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
86 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");87 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
88 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
87}89}
8890
=== modified file 'tests/qmltests/tst_OrientedShell.qml'
--- tests/qmltests/tst_OrientedShell.qml 2016-12-12 16:45:09 +0000
+++ tests/qmltests/tst_OrientedShell.qml 2017-01-03 13:45:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2015-2016 Canonical, Ltd.2 * Copyright (C) 2015-2017 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * 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 by5 * it under the terms of the GNU General Public License as published by
@@ -1558,5 +1558,43 @@
1558 verify(surface);1558 verify(surface);
1559 return surface.activeFocus;1559 return surface.activeFocus;
1560 }1560 }
1561
1562 function test_tabCyclyingInShutdownDialog() {
1563 loadShell("mako");
1564
1565 testCase.showPowerDialog();
1566
1567 var dialogs = findChild(orientedShell, "dialogs");
1568 var buttons = findChildsByType(dialogs, "Button");
1569
1570 tryCompare(buttons[0], "activeFocus", true);
1571
1572 keyClick(Qt.Key_Tab);
1573 tryCompare(buttons[1], "activeFocus", true);
1574
1575 keyClick(Qt.Key_Tab);
1576 tryCompare(buttons[2], "activeFocus", true);
1577
1578 keyClick(Qt.Key_Tab);
1579 tryCompare(buttons[0], "activeFocus", true);
1580
1581 keyClick(Qt.Key_Escape);
1582
1583 var dialogLoader = findChild(orientedShell, "dialogLoader");
1584 tryCompare(dialogLoader, "item", null);
1585 }
1586
1587 function test_escColosesShutdownDialog() {
1588 loadShell("mako");
1589
1590 testCase.showPowerDialog();
1591
1592 var dialogLoader = findChild(orientedShell, "dialogLoader");
1593 tryCompareFunction(function() { return dialogLoader.item !== null }, true);
1594
1595 keyClick(Qt.Key_Escape);
1596
1597 tryCompare(dialogLoader, "item", null);
1598 }
1561 }1599 }
1562}1600}

Subscribers

People subscribed via source and target branches