Merge lp:~ci-train-bot/unity8/unity8-ubuntu-xenial-landing-064 into lp:unity8
- unity8-ubuntu-xenial-landing-064
- Merge into trunk
Proposed by
Michał Sawicz
Status: | Merged | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 2274 | ||||||||||||||||||||||||||||||||||||
Proposed branch: | lp:~ci-train-bot/unity8/unity8-ubuntu-xenial-landing-064 | ||||||||||||||||||||||||||||||||||||
Merge into: | lp:unity8 | ||||||||||||||||||||||||||||||||||||
Diff against target: |
10220 lines (+4844/-1194) 151 files modified
CMakeLists.txt (+1/-1) cmake/modules/QmlTest.cmake (+1/-1) data/com.canonical.Unity8.gschema.xml (+11/-0) data/unity8-dash.conf (+1/-0) debian/changelog (+91/-0) debian/control (+7/-6) debian/unity8-common.udev (+2/-0) debian/unity8-doc.install (+1/-0) doc/devices.conf (+30/-0) plugins/AccountsService/AccountsService.cpp (+244/-397) plugins/AccountsService/AccountsService.h (+26/-21) plugins/AccountsService/AccountsServiceDBusAdaptor.cpp (+11/-4) plugins/AccountsService/AccountsServiceDBusAdaptor.h (+5/-6) plugins/Dash/AudioProgressBar.qml (+1/-0) plugins/Dash/CardCreator.js (+69/-34) plugins/Dash/CardCreatorCache.qml (+3/-3) plugins/Dash/plugin.cpp (+6/-6) plugins/GlobalShortcut/globalshortcutregistry.cpp (+4/-4) plugins/IntegratedLightDM/liblightdm/CMakeLists.txt (+16/-3) plugins/IntegratedLightDM/liblightdm/UsersModel.cpp (+4/-18) plugins/IntegratedLightDM/liblightdm/UsersModel.h (+1/-1) plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp (+44/-10) plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h (+15/-3) plugins/Unity/Indicators/indicatorsmanager.cpp (+2/-2) plugins/Unity/Indicators/rootstateparser.h (+1/-0) plugins/Unity/Launcher/desktopfilehandler.cpp (+2/-2) plugins/Unity/Launcher/launcheritem.cpp (+1/-0) plugins/Unity/Launcher/launcheritem.h (+1/-1) plugins/Unity/Launcher/launchermodel.cpp (+15/-5) plugins/Unity/Launcher/launchermodel.h (+1/-1) plugins/Utils/CMakeLists.txt (+1/-0) plugins/Utils/deviceconfigparser.cpp (+150/-0) plugins/Utils/deviceconfigparser.h (+62/-0) plugins/Utils/plugin.cpp (+2/-0) po/unity8.pot (+29/-27) qml/Components/EdgeBarrier.qml (+1/-1) qml/Components/InputMethod.qml (+1/-9) qml/Components/Lockscreen.qml (+86/-100) qml/Components/ModeSwitchWarningDialog.qml (+1/-1) qml/Components/PassphraseLockscreen.qml (+5/-4) qml/Components/PhysicalKeysMapper.qml (+24/-0) qml/Components/PinLockscreen.qml (+22/-1) qml/Components/ShellDialog.qml (+8/-0) qml/Dash/CardCarousel.qml (+0/-1) qml/Dash/CardGrid.qml (+0/-1) qml/Dash/CardHorizontalList.qml (+0/-1) qml/Dash/CardTool.qml (+2/-26) qml/Dash/CardVerticalJournal.qml (+0/-1) qml/Dash/Dash.qml (+11/-11) qml/Dash/GenericScopeView.qml (+2/-0) qml/Dash/Previews/PreviewHeader.qml (+37/-9) qml/Dash/Previews/PreviewOverlay.qml (+1/-1) qml/Dash/Previews/PreviewSharing.qml (+17/-7) qml/Dash/ScopesListCategoryItem.qml (+8/-4) qml/DeviceConfiguration.qml (+56/-18) qml/DisabledScreenNotice.qml (+44/-20) qml/Greeter/CoverPage.qml (+13/-2) qml/Greeter/Infographics.qml (+2/-1) qml/Greeter/NarrowView.qml (+14/-1) qml/Launcher/Launcher.qml (+144/-11) qml/Launcher/LauncherDelegate.qml (+55/-20) qml/Launcher/LauncherPanel.qml (+122/-51) qml/Launcher/graphics/launcher-app-focus-ring.svg (+12/-0) qml/Notifications/Notification.qml (+6/-2) qml/OrientedShell.qml (+26/-1) qml/Panel/Handle.qml (+2/-2) qml/Panel/Indicators/MenuItemFactory.qml (+0/-1) qml/Panel/IndicatorsMenu.qml (+1/-1) qml/Panel/Panel.qml (+5/-1) qml/ScopeTool.qml (+0/-8) qml/Shell.qml (+51/-1) qml/Stages/AbstractStage.qml (+3/-1) qml/Stages/DesktopSpread.qml (+64/-17) qml/Stages/DesktopSpreadDelegate.qml (+15/-1) qml/Stages/DesktopStage.qml (+34/-34) qml/Stages/PhoneStage.qml (+77/-3) qml/Stages/SpreadDelegate.qml (+20/-0) qml/Stages/TabletStage.qml (+83/-3) qml/Stages/WindowResizeArea.qml (+8/-5) src/CMakeLists.txt (+1/-1) src/CachingNetworkManagerFactory.cpp (+2/-2) src/CachingNetworkManagerFactory.h (+3/-2) src/Dash/CMakeLists.txt (+1/-1) tests/autopilot/unity8/dash.py (+1/-2) tests/autopilot/unity8/shell/tests/test_helpers.py (+0/-2) tests/mocks/GSettings.1.0/fake_gsettings.cpp (+64/-0) tests/mocks/GSettings.1.0/fake_gsettings.h (+18/-0) tests/mocks/IntegratedLightDM/liblightdm/UsersModel.cpp (+0/-14) tests/mocks/Unity/Application/MirSurface.cpp (+6/-2) tests/mocks/Unity/Application/MirSurface.h (+2/-1) tests/mocks/Unity/Application/SurfaceManager.cpp (+8/-9) tests/mocks/Unity/Application/SurfaceManager.h (+3/-3) tests/mocks/Unity/Application/VirtualKeyboard.cpp (+3/-2) tests/mocks/Unity/Application/VirtualKeyboard.h (+1/-1) tests/mocks/Unity/Application/plugin.cpp (+2/-1) tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+2/-0) tests/mocks/Utils/CMakeLists.txt (+1/-0) tests/mocks/Utils/plugin.cpp (+2/-0) tests/plugins/AccountsService/CMakeLists.txt (+5/-0) tests/plugins/AccountsService/PropertiesServer.cpp (+16/-4) tests/plugins/AccountsService/PropertiesServer.h (+2/-1) tests/plugins/AccountsService/UscServer.cpp (+28/-0) tests/plugins/AccountsService/UscServer.h (+39/-0) tests/plugins/AccountsService/client.cpp (+63/-9) tests/plugins/AccountsService/interfaces.xml (+16/-0) tests/plugins/AccountsService/server.cpp (+12/-0) tests/plugins/Dash/cardcreator/1.res (+4/-6) tests/plugins/Dash/cardcreator/1.res.cardcreator (+119/-0) tests/plugins/Dash/cardcreator/10.res (+3/-5) tests/plugins/Dash/cardcreator/10.res.cardcreator (+137/-0) tests/plugins/Dash/cardcreator/11.res (+5/-7) tests/plugins/Dash/cardcreator/11.res.cardcreator (+210/-0) tests/plugins/Dash/cardcreator/2.res (+3/-5) tests/plugins/Dash/cardcreator/2.res.cardcreator (+136/-0) tests/plugins/Dash/cardcreator/3.res (+3/-5) tests/plugins/Dash/cardcreator/3.res.cardcreator (+137/-0) tests/plugins/Dash/cardcreator/4.res (+3/-5) tests/plugins/Dash/cardcreator/4.res.cardcreator (+109/-0) tests/plugins/Dash/cardcreator/5.res (+5/-7) tests/plugins/Dash/cardcreator/5.res.cardcreator (+156/-0) tests/plugins/Dash/cardcreator/6.res (+2/-4) tests/plugins/Dash/cardcreator/6.res.cardcreator (+126/-0) tests/plugins/Dash/cardcreator/7.res (+3/-5) tests/plugins/Dash/cardcreator/7.res.cardcreator (+149/-0) tests/plugins/Dash/cardcreator/8.res (+3/-5) tests/plugins/Dash/cardcreator/8.res.cardcreator (+107/-0) tests/plugins/Dash/cardcreator/9.res (+4/-5) tests/plugins/Dash/cardcreator/9.res.cardcreator (+119/-0) tests/plugins/Dash/cardcreatortest.cpp (+35/-25) tests/plugins/Dash/cardcreatortest.qml (+4/-4) tests/plugins/IntegratedLightDM/CMakeLists.txt (+25/-0) tests/plugins/IntegratedLightDM/integrated.cpp (+91/-0) tests/plugins/Utils/CMakeLists.txt (+7/-1) tests/plugins/Utils/DeviceConfigParserTest.cpp (+70/-0) tests/qmltests/CMakeLists.txt (+1/-0) tests/qmltests/Components/tst_Lockscreen.qml (+14/-7) tests/qmltests/Dash/Previews/tst_PreviewHeader.qml (+18/-1) tests/qmltests/Dash/Previews/tst_PreviewSharing.qml (+17/-3) tests/qmltests/Dash/tst_CardTool.qml (+4/-4) tests/qmltests/Dash/tst_Dash.qml (+89/-0) tests/qmltests/Greeter/tst_NarrowView.qml (+9/-0) tests/qmltests/Launcher/tst_Launcher.qml (+254/-18) tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml (+2/-4) tests/qmltests/Stages/tst_DesktopStage.qml (+2/-1) tests/qmltests/Stages/tst_PhoneStage.qml (+19/-6) tests/qmltests/Stages/tst_SpreadDelegate.qml (+7/-0) tests/qmltests/Stages/tst_TabletStage.qml (+19/-1) tests/qmltests/tst_DeviceConfiguration.qml (+49/-0) tests/qmltests/tst_DisabledScreenNotice.qml (+76/-2) tests/qmltests/tst_OrientedShell.qml (+1/-1) tests/qmltests/tst_Shell.qml (+243/-61) |
||||||||||||||||||||||||||||||||||||
To merge this branch: | bzr merge lp:~ci-train-bot/unity8/unity8-ubuntu-xenial-landing-064 | ||||||||||||||||||||||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+288755@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2016-02-12 00:12:30 +0000 |
3 | +++ CMakeLists.txt 2016-03-11 11:34:41 +0000 |
4 | @@ -131,7 +131,7 @@ |
5 | set(STDOUT_LOGGER "-o" "-,txt") |
6 | endif() |
7 | |
8 | -execute_process(COMMAND arch OUTPUT_VARIABLE ARCH) |
9 | +execute_process(COMMAND dpkg-architecture -qDEB_HOST_ARCH OUTPUT_VARIABLE ARCH) |
10 | if (NOT ARCH MATCHES "arm*") |
11 | set(ENABLE_TOUCH_EMULATION true) |
12 | add_definitions(-DUNITY8_ENABLE_TOUCH_EMULATION) |
13 | |
14 | === modified file 'cmake/modules/QmlTest.cmake' |
15 | --- cmake/modules/QmlTest.cmake 2015-05-21 20:24:47 +0000 |
16 | +++ cmake/modules/QmlTest.cmake 2016-03-11 11:34:41 +0000 |
17 | @@ -183,7 +183,7 @@ |
18 | cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN}) |
19 | mangle_arguments() |
20 | |
21 | - bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768) |
22 | + bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768,3800) |
23 | |
24 | set(qmltry_command |
25 | $<TARGET_FILE:${TARGET}> |
26 | |
27 | === modified file 'data/com.canonical.Unity8.gschema.xml' |
28 | --- data/com.canonical.Unity8.gschema.xml 2015-11-24 17:44:18 +0000 |
29 | +++ data/com.canonical.Unity8.gschema.xml 2016-03-11 11:34:41 +0000 |
30 | @@ -27,6 +27,17 @@ |
31 | <summary>Maximum push needed to overcome edge barrier</summary> |
32 | <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description> |
33 | </key> |
34 | + <key type="b" name="autohide-launcher"> |
35 | + <default>true</default> |
36 | + <summary>Autohide the launcher</summary> |
37 | + <description>This will only be applied in windowed mode. In staged mode, the launcher will always hide.</description> |
38 | + </key> |
39 | + <key type="u" name="launcher-width"> |
40 | + <default>8</default> |
41 | + <range min="6" max="12"/> |
42 | + <summary>Width of the launcher in grid units.</summary> |
43 | + <description>Changes the width of the launcher in all usage modes.</description> |
44 | + </key> |
45 | </schema> |
46 | |
47 | <schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8"> |
48 | |
49 | === modified file 'data/unity8-dash.conf' |
50 | --- data/unity8-dash.conf 2015-04-21 15:41:09 +0000 |
51 | +++ data/unity8-dash.conf 2016-03-11 11:34:41 +0000 |
52 | @@ -14,6 +14,7 @@ |
53 | oom score 50 |
54 | |
55 | respawn |
56 | +respawn limit unlimited |
57 | |
58 | env APP_ID=unity8-dash |
59 | |
60 | |
61 | === modified file 'debian/changelog' |
62 | --- debian/changelog 2016-03-08 20:59:35 +0000 |
63 | +++ debian/changelog 2016-03-11 11:34:41 +0000 |
64 | @@ -1,3 +1,94 @@ |
65 | +unity8 (8.11+16.04.20160310.4-0ubuntu1) xenial; urgency=medium |
66 | + |
67 | + [ Albert Astals Cid ] |
68 | + * Add context for Re-dock as asked by translators (LP: #1534608) |
69 | + * Add emblem to the preview header widget (LP: #1424720) |
70 | + * Add haptics to ScopesListCategoryItem buttons |
71 | + * Audio Cards: Make some of the image loading async (LP: #1533432) |
72 | + * Do not create fallback code for the card tool fake card (LP: |
73 | + #1545865) |
74 | + * Fix resizing the dash bringing temp scopes size out of sync (LP: |
75 | + #1543130) |
76 | + * Minor fixes for unity-scope-tool |
77 | + * Resolve title alignment on card creator time instead of on runtime |
78 | + * Use fixedHeaderHeight only in the non cardtool cards |
79 | + * Use the new undeprecated connectivityqt::Connectivity |
80 | + * asynchronous is only false on the fake card in cardtool |
81 | + * clazy fixes |
82 | + |
83 | + [ Albert Astals Cid, CI Train Bot ] |
84 | + * click scope: Add the else branch so we reset the card size in all |
85 | + situations |
86 | + |
87 | + [ Andrea Cimitan ] |
88 | + * PreviewSharing widget now accepts both string and array of |
89 | + widgetData["share-data"]["uri"] (LP: #1549056) |
90 | + * Update AP tests for new single preview |
91 | + * Use Text.Wrap for body notification text (LP: #1544909) |
92 | + |
93 | + [ Andrea Cimitan, Lukáš Tinkl, Michael Zanetti, Nick Dedekind ] |
94 | + * some fixes for the new palette (LP: #1554616) |
95 | + |
96 | + [ CI Train Bot ] |
97 | + * Resync trunk. |
98 | + * Update translation template |
99 | + |
100 | + [ CI Train Bot, Daniel d'Andrada ] |
101 | + * Ensure the QML engine doesn't delete our mock MirSurfaces on its |
102 | + own. |
103 | + |
104 | + [ Daniel d'Andrada ] |
105 | + * tst_Shell: Remove unused qml items |
106 | + |
107 | + [ Josh Arenson ] |
108 | + * Allow the shell to blacklist input devices and force the OSK shown. |
109 | + (LP: #1542224) |
110 | + |
111 | + [ Lukáš Tinkl ] |
112 | + * Disallow resizing windows up, past the Panel (LP: #1544766) |
113 | + * Elide the window title not to let it overflow into the indicators |
114 | + area (LP: #1535767) |
115 | + * Enable the PIN lockscreen to be used with a HW keyboard (LP: |
116 | + #1550359) |
117 | + * Fix tiny windows when switching stages |
118 | + * Provide a range of ports to QML JS Debugger |
119 | + * Watch for launcher item icon changes (LP: #1543290) |
120 | + |
121 | + [ Michael Terry ] |
122 | + * Proxy more mouse and touchpad properties to USC (LP: #1540398) (LP: |
123 | + #1543344, #1540398) |
124 | + * Refactor the AccountsService plugin and make it slightly faster. |
125 | + * To let the user log in if a mouse is connected, hide the greeter |
126 | + cover page on a mouse click (but NOT a touch click). (LP: #1540497) |
127 | + * Watch AccountsService for changes to the user's real name. This was |
128 | + preventing us from noticing when the user set their name in the |
129 | + welcome wizard. |
130 | + |
131 | + [ Michael Zanetti ] |
132 | + * Allow alt+tabbing in staged mode too (LP: #1540502) |
133 | + * Allow invoking the staged mode spreads by mouse right edge pushes |
134 | + too (LP: #1540392) |
135 | + * Allow loading the device configuration from an external file |
136 | + * Implement Launcher's keyboard navigation and updated pip design |
137 | + * Make launcher scalable, allow it locking (LP: #1511015) |
138 | + * Properly parent launcher items in all cases (LP: #1495732) |
139 | + * Read inputMethod surface from the new property int QtMir (LP: |
140 | + #1545286) |
141 | + * Some visual updates and rotation lock for the virtual touchpad (LP: |
142 | + #1549087) |
143 | + * Visual updates for the windowed spread (LP: #1488148) |
144 | + * stabilize swipeAwayGreeter() |
145 | + |
146 | + [ Michał Sawicz ] |
147 | + * Add udev rules to make sure we have access to uinput |
148 | + * Make dash respawn indefinitely (LP: #1550056) |
149 | + * Use dpkg-architecture, not arch, to disable touch emulation |
150 | + |
151 | + [ Vesa Rautiainen ] |
152 | + * Fixing the vertical position of desktop spread item icon. |
153 | + |
154 | + -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 10 Mar 2016 22:44:16 +0000 |
155 | + |
156 | unity8 (8.11+16.04.20160308-0ubuntu1) xenial; urgency=medium |
157 | |
158 | [ Albert Astals Cid ] |
159 | |
160 | === modified file 'debian/control' |
161 | --- debian/control 2016-03-04 21:03:43 +0000 |
162 | +++ debian/control 2016-03-11 11:34:41 +0000 |
163 | @@ -13,7 +13,7 @@ |
164 | libandroid-properties-dev, |
165 | graphviz, |
166 | gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815), |
167 | - libconnectivity-qt1-dev, |
168 | + libconnectivity-qt1-dev (>= 0.7.1), |
169 | libevdev-dev, |
170 | libgl1-mesa-dev[!armhf] | libgl-dev[!armhf], |
171 | libgl1-mesa-dri, |
172 | @@ -55,7 +55,7 @@ |
173 | qtdeclarative5-qtmultimedia-plugin (>= 5.4.1-1ubuntu19~overlay2), |
174 | qtdeclarative5-ubuntu-content1, |
175 | qtdeclarative5-ubuntu-settings-components (>= 0.7), |
176 | - qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1796) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1796), |
177 | + qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845), |
178 | qtdeclarative5-ubuntu-web-plugin, |
179 | ttf-ubuntu-font-family, |
180 | Standards-Version: 3.9.4 |
181 | @@ -70,7 +70,7 @@ |
182 | Package: indicators-client |
183 | Architecture: amd64 armhf i386 |
184 | Depends: qmenumodel-qml (>= 0.2.9), |
185 | - qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1796) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1796), |
186 | + qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845), |
187 | unity8 (= ${binary:Version}), |
188 | ${misc:Depends}, |
189 | ${shlibs:Depends}, |
190 | @@ -101,7 +101,6 @@ |
191 | qml-module-qt-labs-folderlistmodel, |
192 | qml-module-qtquick-xmllistmodel, |
193 | qml-module-qtsysteminfo, |
194 | - qtdeclarative5-gsettings1.0, |
195 | qtdeclarative5-qtmir-plugin (>= 0.4.5), |
196 | qtdeclarative5-ubuntu-telephony0.1, |
197 | qtdeclarative5-ubuntu-web-plugin, |
198 | @@ -128,7 +127,7 @@ |
199 | Depends: qml-module-qtquick-layouts, |
200 | qtdeclarative5-ubuntu-settings-components (>= 0.7), |
201 | qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl, |
202 | - qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1796) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1796), |
203 | + qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845), |
204 | qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl, |
205 | ubuntu-thumbnailer-impl-0, |
206 | unity-application-impl-13, |
207 | @@ -158,7 +157,7 @@ |
208 | python3-fixtures, |
209 | python3-gi, |
210 | qttestability-autopilot (>= 1.4), |
211 | - ubuntu-ui-toolkit-autopilot (>= 1.3.1796), |
212 | + ubuntu-ui-toolkit-autopilot (>= 1.3.1845), |
213 | unity-scope-click, |
214 | unity8 (= ${source:Version}), |
215 | unity8-fake-env (= ${source:Version}), |
216 | @@ -192,6 +191,8 @@ |
217 | libhardware2, |
218 | pay-service, |
219 | unity-schemas (>= 7.3.1+14.10.20140915), |
220 | + qtdeclarative5-gsettings1.0, |
221 | + qml-module-qtmultimedia, |
222 | ${misc:Depends}, |
223 | ${shlibs:Depends}, |
224 | Provides: unity-launcher-impl, |
225 | |
226 | === added file 'debian/unity8-common.udev' |
227 | --- debian/unity8-common.udev 1970-01-01 00:00:00 +0000 |
228 | +++ debian/unity8-common.udev 2016-03-11 11:34:41 +0000 |
229 | @@ -0,0 +1,2 @@ |
230 | +# Make local foreground session able to inject input |
231 | +KERNEL=="uinput", SUBSYSTEM=="misc", TAG+="uaccess" |
232 | |
233 | === modified file 'debian/unity8-doc.install' |
234 | --- debian/unity8-doc.install 2014-01-30 22:32:37 +0000 |
235 | +++ debian/unity8-doc.install 2016-03-11 11:34:41 +0000 |
236 | @@ -1,1 +1,2 @@ |
237 | +doc/devices.conf usr/share/doc/unity8/ |
238 | usr/share/doc/unity8/* |
239 | |
240 | === added file 'doc/devices.conf' |
241 | --- doc/devices.conf 1970-01-01 00:00:00 +0000 |
242 | +++ doc/devices.conf 2016-03-11 11:34:41 +0000 |
243 | @@ -0,0 +1,30 @@ |
244 | +# This file can hold multiple device configs. Devices are separated by sections. |
245 | +# |
246 | +# SupportedOrientations holds a list of all enabled orientations. A standard |
247 | +# phone will usually have Portrait,Landcape,InvertedLandscape in order to |
248 | +# disable upside down usage. |
249 | +# |
250 | +# PrimaryOrientation gives the orientation the device will start up with |
251 | +# when there is no orientations sensor input available (yet) or lock to |
252 | +# when an application specifies to be locked to PrimaryOrientation. |
253 | +# |
254 | +# The other Orientation settings can be used to re-map the orientations. |
255 | +# A device might be used with different orientations than how the screen |
256 | +# is physically mounted on the hardware. |
257 | +# |
258 | +# Category can be phone, tablet, or desktop. This option determines |
259 | +# whether the side stage is shown (tablet) or not (phone). Using |
260 | +# desktop will load the shell in windowed mode. Note that the user |
261 | +# can override/change this by connecting input hardware or change |
262 | +# user settings. |
263 | +# |
264 | +# Any options not listed will default to the values of the example below. |
265 | + |
266 | +[devicename] |
267 | +SupportedOrientations=Portrait,InvertedPortrait,Landscape,InvertedLandscape |
268 | +PrimaryOrientation=PrimaryOrienation |
269 | +PortraitOrientation=Portrait |
270 | +InvertedPortraitOrientation=InvertedPortrait |
271 | +LandscapeOrientation=Landscape |
272 | +InvertedLandscapeOrientation=InvertedLandscape |
273 | +Category=phone |
274 | |
275 | === modified file 'plugins/AccountsService/AccountsService.cpp' |
276 | --- plugins/AccountsService/AccountsService.cpp 2016-01-21 21:04:00 +0000 |
277 | +++ plugins/AccountsService/AccountsService.cpp 2016-03-11 11:34:41 +0000 |
278 | @@ -24,17 +24,52 @@ |
279 | #include <QStringList> |
280 | #include <QDebug> |
281 | |
282 | +#define IFACE_ACCOUNTS_USER QStringLiteral("org.freedesktop.Accounts.User") |
283 | +#define IFACE_LOCATION_HERE QStringLiteral("com.ubuntu.location.providers.here.AccountsService") |
284 | +#define IFACE_UBUNTU_INPUT QStringLiteral("com.ubuntu.AccountsService.Input") |
285 | +#define IFACE_UBUNTU_SECURITY QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy") |
286 | +#define IFACE_UBUNTU_SECURITY_OLD QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy") |
287 | +#define IFACE_UNITY QStringLiteral("com.canonical.unity.AccountsService") |
288 | +#define IFACE_UNITY_PRIVATE QStringLiteral("com.canonical.unity.AccountsService.Private") |
289 | + |
290 | +#define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile") |
291 | +#define PROP_DEMO_EDGES QStringLiteral("demo-edges") |
292 | +#define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked") |
293 | +#define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked") |
294 | +#define PROP_FAILED_LOGINS QStringLiteral("FailedLogins") |
295 | +#define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted") |
296 | +#define PROP_LICENSE_BASE_PATH QStringLiteral("LicenseBasePath") |
297 | +#define PROP_MOUSE_CURSOR_SPEED QStringLiteral("MouseCursorSpeed") |
298 | +#define PROP_MOUSE_DOUBLE_CLICK_SPEED QStringLiteral("MouseDoubleClickSpeed") |
299 | +#define PROP_MOUSE_PRIMARY_BUTTON QStringLiteral("MousePrimaryButton") |
300 | +#define PROP_MOUSE_SCROLL_SPEED QStringLiteral("MouseScrollSpeed") |
301 | +#define PROP_PASSWORD_DISPLAY_HINT QStringLiteral("PasswordDisplayHint") |
302 | +#define PROP_STATS_WELCOME_SCREEN QStringLiteral("StatsWelcomeScreen") |
303 | +#define PROP_TOUCHPAD_CURSOR_SPEED QStringLiteral("TouchpadCursorSpeed") |
304 | +#define PROP_TOUCHPAD_DISABLE_WHILE_TYPING QStringLiteral("TouchpadDisableWhileTyping") |
305 | +#define PROP_TOUCHPAD_DISABLE_WITH_MOUSE QStringLiteral("TouchpadDisableWithMouse") |
306 | +#define PROP_TOUCHPAD_DOUBLE_CLICK_SPEED QStringLiteral("TouchpadDoubleClickSpeed") |
307 | +#define PROP_TOUCHPAD_PRIMARY_BUTTON QStringLiteral("TouchpadPrimaryButton") |
308 | +#define PROP_TOUCHPAD_SCROLL_SPEED QStringLiteral("TouchpadScrollSpeed") |
309 | +#define PROP_TOUCHPAD_TAP_TO_CLICK QStringLiteral("TouchpadTapToClick") |
310 | +#define PROP_TOUCHPAD_TWO_FINGER_SCROLL QStringLiteral("TouchpadTwoFingerScroll") |
311 | + |
312 | + |
313 | +QVariant primaryButtonConverter(const QVariant &value) |
314 | +{ |
315 | + QString stringValue = value.toString(); |
316 | + if (stringValue == "left") { |
317 | + return QVariant::fromValue(0); |
318 | + } else if (stringValue == "right") { |
319 | + return QVariant::fromValue(1); // Mir is less clear on this -- any non-zero value is the same |
320 | + } else { |
321 | + return QVariant::fromValue(0); // default to left |
322 | + } |
323 | +} |
324 | + |
325 | AccountsService::AccountsService(QObject* parent, const QString &user) |
326 | - : QObject(parent), |
327 | - m_service(new AccountsServiceDBusAdaptor(this)), |
328 | - m_demoEdges(false), |
329 | - m_enableLauncherWhileLocked(false), |
330 | - m_enableIndicatorsWhileLocked(false), |
331 | - m_statsWelcomeScreen(false), |
332 | - m_passwordDisplayHint(Keyboard), |
333 | - m_failedLogins(0), |
334 | - m_hereEnabled(false), |
335 | - m_hereLicensePath() // null means not set yet |
336 | + : QObject(parent) |
337 | + , m_service(new AccountsServiceDBusAdaptor(this)) |
338 | { |
339 | m_unityInput = new QDBusInterface(QStringLiteral("com.canonical.Unity.Input"), |
340 | QStringLiteral("/com/canonical/Unity/Input"), |
341 | @@ -44,6 +79,43 @@ |
342 | connect(m_service, &AccountsServiceDBusAdaptor::propertiesChanged, this, &AccountsService::onPropertiesChanged); |
343 | connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, this, &AccountsService::onMaybeChanged); |
344 | |
345 | + registerProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE, QStringLiteral("backgroundFileChanged")); |
346 | + registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, QStringLiteral("hereEnabledChanged")); |
347 | + registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH, QStringLiteral("hereLicensePathChanged")); |
348 | + registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral("enableLauncherWhileLockedChanged")); |
349 | + registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral("enableIndicatorsWhileLockedChanged")); |
350 | + registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral("passwordDisplayHintChanged")); |
351 | + registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral("statsWelcomeScreenChanged")); |
352 | + registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral("demoEdgesChanged")); |
353 | + registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral("failedLoginsChanged")); |
354 | + |
355 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED, |
356 | + m_unityInput, QStringLiteral("setMouseCursorSpeed")); |
357 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_DOUBLE_CLICK_SPEED, |
358 | + m_unityInput, QStringLiteral("setMouseDoubleClickSpeed")); |
359 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_PRIMARY_BUTTON, |
360 | + m_unityInput, QStringLiteral("setMousePrimaryButton"), |
361 | + primaryButtonConverter); |
362 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_SCROLL_SPEED, |
363 | + m_unityInput, QStringLiteral("setMouseScrollSpeed")); |
364 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_CURSOR_SPEED, |
365 | + m_unityInput, QStringLiteral("setTouchpadCursorSpeed")); |
366 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_SCROLL_SPEED, |
367 | + m_unityInput, QStringLiteral("setTouchpadScrollSpeed")); |
368 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WHILE_TYPING, |
369 | + m_unityInput, QStringLiteral("setTouchpadDisableWhileTyping")); |
370 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DISABLE_WITH_MOUSE, |
371 | + m_unityInput, QStringLiteral("setTouchpadDisableWithMouse")); |
372 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_DOUBLE_CLICK_SPEED, |
373 | + m_unityInput, QStringLiteral("setTouchpadDoubleClickSpeed")); |
374 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_PRIMARY_BUTTON, |
375 | + m_unityInput, QStringLiteral("setTouchpadPrimaryButton"), |
376 | + primaryButtonConverter); |
377 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TAP_TO_CLICK, |
378 | + m_unityInput, QStringLiteral("setTouchpadTapToClick")); |
379 | + registerProxy(IFACE_UBUNTU_INPUT, PROP_TOUCHPAD_TWO_FINGER_SCROLL, |
380 | + m_unityInput, QStringLiteral("setTouchpadTwoFingerScroll")); |
381 | + |
382 | setUser(!user.isEmpty() ? user : QString::fromUtf8(qgetenv("USER"))); |
383 | } |
384 | |
385 | @@ -57,410 +129,200 @@ |
386 | if (user.isEmpty() || m_user == user) |
387 | return; |
388 | |
389 | + bool wasEmpty = m_user.isEmpty(); |
390 | + |
391 | m_user = user; |
392 | Q_EMIT userChanged(); |
393 | |
394 | - updateDemoEdges(false); |
395 | - updateEnableLauncherWhileLocked(false); |
396 | - updateEnableIndicatorsWhileLocked(false); |
397 | - updateBackgroundFile(false); |
398 | - updateMouseCursorSpeed(); |
399 | - updateTouchpadCursorSpeed(); |
400 | - updateStatsWelcomeScreen(false); |
401 | - updatePasswordDisplayHint(false); |
402 | - updateFailedLogins(false); |
403 | - updateHereEnabled(false); |
404 | - updateHereLicensePath(false); |
405 | + // Do the first update synchronously, as a cheap way to block rendering |
406 | + // until we have the right values on bootup. |
407 | + refresh(!wasEmpty); |
408 | } |
409 | |
410 | bool AccountsService::demoEdges() const |
411 | { |
412 | - return m_demoEdges; |
413 | + auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES); |
414 | + return value.toBool(); |
415 | } |
416 | |
417 | void AccountsService::setDemoEdges(bool demoEdges) |
418 | { |
419 | - if (m_demoEdges != demoEdges) { |
420 | - m_demoEdges = demoEdges; |
421 | - m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService"), QStringLiteral("demo-edges"), demoEdges); |
422 | - |
423 | - Q_EMIT demoEdgesChanged(); |
424 | - } |
425 | + setProperty(IFACE_UNITY, PROP_DEMO_EDGES, demoEdges); |
426 | } |
427 | |
428 | bool AccountsService::enableLauncherWhileLocked() const |
429 | { |
430 | - return m_enableLauncherWhileLocked; |
431 | + auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED); |
432 | + return value.toBool(); |
433 | } |
434 | |
435 | bool AccountsService::enableIndicatorsWhileLocked() const |
436 | { |
437 | - return m_enableIndicatorsWhileLocked; |
438 | + auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED); |
439 | + return value.toBool(); |
440 | } |
441 | |
442 | QString AccountsService::backgroundFile() const |
443 | { |
444 | - return m_backgroundFile; |
445 | + auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_BACKGROUND_FILE); |
446 | + return value.toString(); |
447 | } |
448 | |
449 | bool AccountsService::statsWelcomeScreen() const |
450 | { |
451 | - return m_statsWelcomeScreen; |
452 | + auto value = getProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN); |
453 | + return value.toBool(); |
454 | } |
455 | |
456 | AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const |
457 | { |
458 | - return m_passwordDisplayHint; |
459 | + auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT); |
460 | + return (PasswordDisplayHint)value.toInt(); |
461 | } |
462 | |
463 | bool AccountsService::hereEnabled() const |
464 | { |
465 | - return m_hereEnabled; |
466 | + auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED); |
467 | + return value.toBool(); |
468 | } |
469 | |
470 | void AccountsService::setHereEnabled(bool enabled) |
471 | { |
472 | - if (m_hereEnabled != enabled) { |
473 | - m_hereEnabled = enabled; |
474 | - m_service->setUserPropertyAsync(m_user, QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), QStringLiteral("LicenseAccepted"), enabled); |
475 | - |
476 | - Q_EMIT hereEnabledChanged(); |
477 | - } |
478 | + setProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, enabled); |
479 | } |
480 | |
481 | QString AccountsService::hereLicensePath() const |
482 | { |
483 | - return m_hereLicensePath; |
484 | + auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH); |
485 | + QString hereLicensePath = value.toString(); |
486 | + if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath)) |
487 | + hereLicensePath = QStringLiteral(""); |
488 | + return hereLicensePath; |
489 | } |
490 | |
491 | bool AccountsService::hereLicensePathValid() const |
492 | { |
493 | - return !m_hereLicensePath.isNull(); |
494 | -} |
495 | - |
496 | -void AccountsService::updateDemoEdges(bool async) |
497 | -{ |
498 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
499 | - QStringLiteral("com.canonical.unity.AccountsService"), |
500 | - QStringLiteral("demo-edges")); |
501 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
502 | - |
503 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
504 | - this, [this](QDBusPendingCallWatcher* watcher) { |
505 | - |
506 | - QDBusPendingReply<QDBusVariant> reply = *watcher; |
507 | - watcher->deleteLater(); |
508 | - if (reply.isError()) { |
509 | - qWarning() << "Failed to get 'demo-edges' property - " << reply.error().message(); |
510 | - return; |
511 | - } |
512 | - |
513 | - auto demoEdges = reply.value().variant().toBool(); |
514 | - if (m_demoEdges != demoEdges) { |
515 | - m_demoEdges = demoEdges; |
516 | - Q_EMIT demoEdgesChanged(); |
517 | - } |
518 | - }); |
519 | - if (!async) { |
520 | - watcher->waitForFinished(); |
521 | - delete watcher; |
522 | - } |
523 | -} |
524 | - |
525 | -void AccountsService::updateEnableLauncherWhileLocked(bool async) |
526 | -{ |
527 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
528 | - QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"), |
529 | - QStringLiteral("EnableLauncherWhileLocked")); |
530 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
531 | - |
532 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
533 | - this, [this](QDBusPendingCallWatcher* watcher) { |
534 | - |
535 | - QDBusPendingReply<QVariant> reply = *watcher; |
536 | - watcher->deleteLater(); |
537 | - if (reply.isError()) { |
538 | - qWarning() << "Failed to get 'EnableLauncherWhileLocked' property - " << reply.error().message(); |
539 | - return; |
540 | - } |
541 | - |
542 | - const bool enableLauncherWhileLocked = reply.value().toBool(); |
543 | - if (m_enableLauncherWhileLocked != enableLauncherWhileLocked) { |
544 | - m_enableLauncherWhileLocked = enableLauncherWhileLocked; |
545 | - Q_EMIT enableLauncherWhileLockedChanged(); |
546 | - } |
547 | - }); |
548 | - if (!async) { |
549 | - watcher->waitForFinished(); |
550 | - delete watcher; |
551 | - } |
552 | -} |
553 | - |
554 | -void AccountsService::updateEnableIndicatorsWhileLocked(bool async) |
555 | -{ |
556 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
557 | - QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"), |
558 | - QStringLiteral("EnableIndicatorsWhileLocked")); |
559 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
560 | - |
561 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
562 | - this, [this](QDBusPendingCallWatcher* watcher) { |
563 | - |
564 | - QDBusPendingReply<QVariant> reply = *watcher; |
565 | - watcher->deleteLater(); |
566 | - if (reply.isError()) { |
567 | - qWarning() << "Failed to get 'EnableIndicatorsWhileLocked' property - " << reply.error().message(); |
568 | - return; |
569 | - } |
570 | - |
571 | - const bool enableIndicatorsWhileLocked = reply.value().toBool(); |
572 | - if (m_enableIndicatorsWhileLocked != enableIndicatorsWhileLocked) { |
573 | - m_enableIndicatorsWhileLocked = enableIndicatorsWhileLocked; |
574 | - Q_EMIT enableIndicatorsWhileLockedChanged(); |
575 | - } |
576 | - }); |
577 | - if (!async) { |
578 | - watcher->waitForFinished(); |
579 | - delete watcher; |
580 | - } |
581 | -} |
582 | - |
583 | -void AccountsService::updateBackgroundFile(bool async) |
584 | -{ |
585 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
586 | - QStringLiteral("org.freedesktop.Accounts.User"), |
587 | - QStringLiteral("BackgroundFile")); |
588 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
589 | - |
590 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
591 | - this, [this](QDBusPendingCallWatcher* watcher) { |
592 | - |
593 | - QDBusPendingReply<QVariant> reply = *watcher; |
594 | - watcher->deleteLater(); |
595 | - if (reply.isError()) { |
596 | - qWarning() << "Failed to get 'BackgroundFile' property - " << reply.error().message(); |
597 | - return; |
598 | - } |
599 | - |
600 | - const QString backgroundFile = reply.value().toString(); |
601 | - if (m_backgroundFile != backgroundFile) { |
602 | - m_backgroundFile = backgroundFile; |
603 | - Q_EMIT backgroundFileChanged(); |
604 | - } |
605 | - }); |
606 | - if (!async) { |
607 | - watcher->waitForFinished(); |
608 | - delete watcher; |
609 | - } |
610 | -} |
611 | - |
612 | -void AccountsService::updateMouseCursorSpeed() |
613 | -{ |
614 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
615 | - QStringLiteral("com.ubuntu.AccountsService.Input"), |
616 | - QStringLiteral("MouseCursorSpeed")); |
617 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
618 | - |
619 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
620 | - this, [this](QDBusPendingCallWatcher* watcher) { |
621 | - |
622 | - QDBusPendingReply<QVariant> reply = *watcher; |
623 | - watcher->deleteLater(); |
624 | - if (reply.isError()) { |
625 | - qWarning() << "Failed to get 'MouseCursorSpeed' property - " << reply.error().message(); |
626 | - return; |
627 | - } |
628 | - |
629 | - // Merely proxy this along to USC. We don't care about keeping a copy |
630 | - // or exporting it internally. |
631 | - m_unityInput->asyncCall(QStringLiteral("setMouseCursorSpeed"), reply.value()); |
632 | - }); |
633 | -} |
634 | - |
635 | -void AccountsService::updateTouchpadCursorSpeed() |
636 | -{ |
637 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
638 | - QStringLiteral("com.ubuntu.AccountsService.Input"), |
639 | - QStringLiteral("TouchpadCursorSpeed")); |
640 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
641 | - |
642 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
643 | - this, [this](QDBusPendingCallWatcher* watcher) { |
644 | - |
645 | - QDBusPendingReply<QVariant> reply = *watcher; |
646 | - watcher->deleteLater(); |
647 | - if (reply.isError()) { |
648 | - qWarning() << "Failed to get 'TouchpadCursorSpeed' property - " << reply.error().message(); |
649 | - return; |
650 | - } |
651 | - |
652 | - // Merely proxy this along to USC. We don't care about keeping a copy |
653 | - // or exporting it internally. |
654 | - m_unityInput->asyncCall(QStringLiteral("setTouchpadCursorSpeed"), reply.value()); |
655 | - }); |
656 | -} |
657 | - |
658 | -void AccountsService::updateStatsWelcomeScreen(bool async) |
659 | -{ |
660 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
661 | - QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy"), |
662 | - QStringLiteral("StatsWelcomeScreen")); |
663 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
664 | - |
665 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
666 | - this, [this](QDBusPendingCallWatcher* watcher) { |
667 | - |
668 | - QDBusPendingReply<QVariant> reply = *watcher; |
669 | - watcher->deleteLater(); |
670 | - if (reply.isError()) { |
671 | - qWarning() << "Failed to get 'StatsWelcomeScreen' property - " << reply.error().message(); |
672 | - return; |
673 | - } |
674 | - |
675 | - const bool statsWelcomeScreen = reply.value().toBool(); |
676 | - if (m_statsWelcomeScreen != statsWelcomeScreen) { |
677 | - m_statsWelcomeScreen = statsWelcomeScreen; |
678 | - Q_EMIT statsWelcomeScreenChanged(); |
679 | - } |
680 | - }); |
681 | - if (!async) { |
682 | - watcher->waitForFinished(); |
683 | - delete watcher; |
684 | - } |
685 | -} |
686 | - |
687 | -void AccountsService::updatePasswordDisplayHint(bool async) |
688 | -{ |
689 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
690 | - QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy"), |
691 | - QStringLiteral("PasswordDisplayHint")); |
692 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
693 | - |
694 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
695 | - this, [this](QDBusPendingCallWatcher* watcher) { |
696 | - |
697 | - QDBusPendingReply<QVariant> reply = *watcher; |
698 | - watcher->deleteLater(); |
699 | - if (reply.isError()) { |
700 | - qWarning() << "Failed to get 'PasswordDisplayHint' property - " << reply.error().message(); |
701 | - return; |
702 | - } |
703 | - |
704 | - const PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)reply.value().toInt(); |
705 | - if (m_passwordDisplayHint != passwordDisplayHint) { |
706 | - m_passwordDisplayHint = passwordDisplayHint; |
707 | - Q_EMIT passwordDisplayHintChanged(); |
708 | - } |
709 | - }); |
710 | - if (!async) { |
711 | - watcher->waitForFinished(); |
712 | - delete watcher; |
713 | - } |
714 | -} |
715 | - |
716 | -void AccountsService::updateFailedLogins(bool async) |
717 | -{ |
718 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
719 | - QStringLiteral("com.canonical.unity.AccountsService.Private"), |
720 | - QStringLiteral("FailedLogins")); |
721 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
722 | - |
723 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
724 | - this, [this](QDBusPendingCallWatcher* watcher) { |
725 | - |
726 | - QDBusPendingReply<QVariant> reply = *watcher; |
727 | - watcher->deleteLater(); |
728 | - if (reply.isError()) { |
729 | - qWarning() << "Failed to get 'FailedLogins' property - " << reply.error().message(); |
730 | - return; |
731 | - } |
732 | - |
733 | - const uint failedLogins = reply.value().toUInt(); |
734 | - if (m_failedLogins != failedLogins) { |
735 | - m_failedLogins = failedLogins; |
736 | - Q_EMIT failedLoginsChanged(); |
737 | - } |
738 | - }); |
739 | - if (!async) { |
740 | - watcher->waitForFinished(); |
741 | - delete watcher; |
742 | - } |
743 | -} |
744 | - |
745 | -void AccountsService::updateHereEnabled(bool async) |
746 | -{ |
747 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
748 | - QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), |
749 | - QStringLiteral("LicenseAccepted")); |
750 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
751 | - |
752 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
753 | - this, [this](QDBusPendingCallWatcher* watcher) { |
754 | - |
755 | - QDBusPendingReply<QVariant> reply = *watcher; |
756 | - watcher->deleteLater(); |
757 | - if (reply.isError()) { |
758 | - qWarning() << "Failed to get 'LicenseAccepted' property - " << reply.error().message(); |
759 | - return; |
760 | - } |
761 | - |
762 | - const bool hereEnabled = reply.value().toBool(); |
763 | - if (m_hereEnabled != hereEnabled) { |
764 | - m_hereEnabled = hereEnabled; |
765 | - Q_EMIT hereEnabledChanged(); |
766 | - } |
767 | - }); |
768 | - if (!async) { |
769 | - watcher->waitForFinished(); |
770 | - delete watcher; |
771 | - } |
772 | -} |
773 | - |
774 | -void AccountsService::updateHereLicensePath(bool async) |
775 | -{ |
776 | - QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
777 | - QStringLiteral("com.ubuntu.location.providers.here.AccountsService"), |
778 | - QStringLiteral("LicenseBasePath")); |
779 | - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
780 | - |
781 | - connect(watcher, &QDBusPendingCallWatcher::finished, |
782 | - this, [this](QDBusPendingCallWatcher* watcher) { |
783 | - |
784 | - QDBusPendingReply<QVariant> reply = *watcher; |
785 | - watcher->deleteLater(); |
786 | - if (reply.isError()) { |
787 | - qWarning() << "Failed to get 'LicenseBasePath' property - " << reply.error().message(); |
788 | - return; |
789 | - } |
790 | - |
791 | - QString hereLicensePath = reply.value().toString(); |
792 | - if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath)) |
793 | - hereLicensePath = QLatin1String(""); |
794 | - |
795 | - if (m_hereLicensePath.isNull() || m_hereLicensePath != hereLicensePath) { |
796 | - m_hereLicensePath = hereLicensePath; |
797 | - Q_EMIT hereLicensePathChanged(); |
798 | - } |
799 | - }); |
800 | - if (!async) { |
801 | - watcher->waitForFinished(); |
802 | - delete watcher; |
803 | - } |
804 | + auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH); |
805 | + return !value.toString().isNull(); |
806 | } |
807 | |
808 | uint AccountsService::failedLogins() const |
809 | { |
810 | - return m_failedLogins; |
811 | + return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS).toUInt(); |
812 | } |
813 | |
814 | void AccountsService::setFailedLogins(uint failedLogins) |
815 | { |
816 | - if (m_failedLogins != failedLogins) { |
817 | - m_failedLogins = failedLogins; |
818 | - m_service->setUserPropertyAsync(m_user, QStringLiteral("com.canonical.unity.AccountsService.Private"), QStringLiteral("FailedLogins"), failedLogins); |
819 | - |
820 | - Q_EMIT failedLoginsChanged(); |
821 | - } |
822 | + setProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, failedLogins); |
823 | +} |
824 | + |
825 | +// ==================================================== |
826 | +// Everything below this line is generic helper methods |
827 | +// ==================================================== |
828 | + |
829 | +void AccountsService::emitChangedForProperty(const QString &interface, const QString &property) |
830 | +{ |
831 | + QString signalName = m_properties[interface][property].signal; |
832 | + QMetaObject::invokeMethod(this, signalName.toUtf8().data()); |
833 | +} |
834 | + |
835 | +QVariant AccountsService::getProperty(const QString &interface, const QString &property) const |
836 | +{ |
837 | + return m_properties[interface][property].value; |
838 | +} |
839 | + |
840 | +void AccountsService::setProperty(const QString &interface, const QString &property, const QVariant &value) |
841 | +{ |
842 | + if (m_properties[interface][property].value != value) { |
843 | + m_properties[interface][property].value = value; |
844 | + m_service->setUserPropertyAsync(m_user, interface, property, value); |
845 | + emitChangedForProperty(interface, property); |
846 | + } |
847 | +} |
848 | + |
849 | +void AccountsService::updateCache(const QString &interface, const QString &property, const QVariant &value) |
850 | +{ |
851 | + PropertyInfo &info = m_properties[interface][property]; |
852 | + |
853 | + if (info.proxyInterface) { |
854 | + QVariant finalValue; |
855 | + if (info.proxyConverter) { |
856 | + finalValue = info.proxyConverter(value); |
857 | + } else { |
858 | + finalValue = value; |
859 | + } |
860 | + info.proxyInterface->asyncCall(info.proxyMethod, finalValue); |
861 | + return; // don't bother saving a copy |
862 | + } |
863 | + |
864 | + if (info.value != value) { |
865 | + info.value = value; |
866 | + emitChangedForProperty(interface, property); |
867 | + } |
868 | +} |
869 | + |
870 | +void AccountsService::updateProperty(const QString &interface, const QString &property) |
871 | +{ |
872 | + QDBusPendingCall pendingReply = m_service->getUserPropertyAsync(m_user, |
873 | + interface, |
874 | + property); |
875 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
876 | + |
877 | + connect(watcher, &QDBusPendingCallWatcher::finished, |
878 | + this, [this, interface, property](QDBusPendingCallWatcher* watcher) { |
879 | + |
880 | + QDBusPendingReply<QVariant> reply = *watcher; |
881 | + watcher->deleteLater(); |
882 | + if (reply.isError()) { |
883 | + qWarning() << "Failed to get '" << property << "' property:" << reply.error().message(); |
884 | + return; |
885 | + } |
886 | + |
887 | + updateCache(interface, property, reply.value()); |
888 | + }); |
889 | +} |
890 | + |
891 | +void AccountsService::updateAllProperties(const QString &interface, bool async) |
892 | +{ |
893 | + QDBusPendingCall pendingReply = m_service->getAllPropertiesAsync(m_user, |
894 | + interface); |
895 | + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
896 | + |
897 | + connect(watcher, &QDBusPendingCallWatcher::finished, |
898 | + this, [this, interface](QDBusPendingCallWatcher* watcher) { |
899 | + |
900 | + QDBusPendingReply< QHash<QString, QVariant> > reply = *watcher; |
901 | + watcher->deleteLater(); |
902 | + if (reply.isError()) { |
903 | + qWarning() << "Failed to get all properties for" << interface << ":" << reply.error().message(); |
904 | + return; |
905 | + } |
906 | + |
907 | + auto valueHash = reply.value(); |
908 | + auto i = valueHash.constBegin(); |
909 | + while (i != valueHash.constEnd()) { |
910 | + updateCache(interface, i.key(), i.value()); |
911 | + ++i; |
912 | + } |
913 | + }); |
914 | + if (!async) { |
915 | + watcher->waitForFinished(); |
916 | + } |
917 | +} |
918 | + |
919 | +void AccountsService::registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter) |
920 | +{ |
921 | + registerProperty(interface, property, nullptr); |
922 | + |
923 | + m_properties[interface][property].proxyInterface = iface; |
924 | + m_properties[interface][property].proxyMethod = method; |
925 | + m_properties[interface][property].proxyConverter = converter; |
926 | +} |
927 | + |
928 | +void AccountsService::registerProperty(const QString &interface, const QString &property, const QString &signal) |
929 | +{ |
930 | + m_properties[interface][property] = PropertyInfo(); |
931 | + m_properties[interface][property].signal = signal; |
932 | } |
933 | |
934 | void AccountsService::onPropertiesChanged(const QString &user, const QString &interface, const QStringList &changed) |
935 | @@ -469,42 +331,13 @@ |
936 | return; |
937 | } |
938 | |
939 | - if (interface == QLatin1String("com.canonical.unity.AccountsService")) { |
940 | - if (changed.contains(QStringLiteral("demo-edges"))) { |
941 | - updateDemoEdges(); |
942 | - } |
943 | - } else if (interface == QLatin1String("com.canonical.unity.AccountsService.Private")) { |
944 | - if (changed.contains(QStringLiteral("FailedLogins"))) { |
945 | - updateFailedLogins(); |
946 | - } |
947 | - } else if (interface == QLatin1String("com.ubuntu.AccountsService.Input")) { |
948 | - if (changed.contains(QStringLiteral("MouseCursorSpeed"))) { |
949 | - updateMouseCursorSpeed(); |
950 | - } |
951 | - if (changed.contains(QStringLiteral("TouchpadCursorSpeed"))) { |
952 | - updateTouchpadCursorSpeed(); |
953 | - } |
954 | - } else if (interface == QLatin1String("com.ubuntu.touch.AccountsService.SecurityPrivacy")) { |
955 | - if (changed.contains(QStringLiteral("StatsWelcomeScreen"))) { |
956 | - updateStatsWelcomeScreen(); |
957 | - } |
958 | - } else if (interface == QLatin1String("com.ubuntu.AccountsService.SecurityPrivacy")) { |
959 | - if (changed.contains(QStringLiteral("PasswordDisplayHint"))) { |
960 | - updatePasswordDisplayHint(); |
961 | - } |
962 | - if (changed.contains(QStringLiteral("EnableLauncherWhileLocked"))) { |
963 | - updateEnableLauncherWhileLocked(); |
964 | - } |
965 | - if (changed.contains(QStringLiteral("EnableIndicatorsWhileLocked"))) { |
966 | - updateEnableIndicatorsWhileLocked(); |
967 | - } |
968 | - } else if (interface == QLatin1String("com.ubuntu.location.providers.here.AccountsService")) { |
969 | - if (changed.contains(QStringLiteral("LicenseAccepted"))) { |
970 | - updateHereEnabled(); |
971 | - } |
972 | - if (changed.contains(QStringLiteral("LicenseBasePath"))) { |
973 | - updateHereLicensePath(); |
974 | - } |
975 | + auto propHash = m_properties.value(interface); |
976 | + auto i = propHash.constBegin(); |
977 | + while (i != propHash.constEnd()) { |
978 | + if (changed.contains(i.key())) { |
979 | + updateProperty(interface, i.key()); |
980 | + } |
981 | + ++i; |
982 | } |
983 | } |
984 | |
985 | @@ -514,6 +347,20 @@ |
986 | return; |
987 | } |
988 | |
989 | - // Standard properties might have changed |
990 | - updateBackgroundFile(); |
991 | + // Any of the standard properties might have changed! |
992 | + auto propHash = m_properties.value(IFACE_ACCOUNTS_USER); |
993 | + auto i = propHash.constBegin(); |
994 | + while (i != propHash.constEnd()) { |
995 | + updateProperty(IFACE_ACCOUNTS_USER, i.key()); |
996 | + ++i; |
997 | + } |
998 | +} |
999 | + |
1000 | +void AccountsService::refresh(bool async) |
1001 | +{ |
1002 | + auto i = m_properties.constBegin(); |
1003 | + while (i != m_properties.constEnd()) { |
1004 | + updateAllProperties(i.key(), async); |
1005 | + ++i; |
1006 | + } |
1007 | } |
1008 | |
1009 | === modified file 'plugins/AccountsService/AccountsService.h' |
1010 | --- plugins/AccountsService/AccountsService.h 2016-01-21 21:04:00 +0000 |
1011 | +++ plugins/AccountsService/AccountsService.h 2016-03-11 11:34:41 +0000 |
1012 | @@ -19,8 +19,10 @@ |
1013 | #ifndef UNITY_ACCOUNTSSERVICE_H |
1014 | #define UNITY_ACCOUNTSSERVICE_H |
1015 | |
1016 | +#include <QHash> |
1017 | #include <QObject> |
1018 | #include <QString> |
1019 | +#include <QVariant> |
1020 | |
1021 | class AccountsServiceDBusAdaptor; |
1022 | class QDBusInterface; |
1023 | @@ -109,30 +111,33 @@ |
1024 | void onMaybeChanged(const QString &user); |
1025 | |
1026 | private: |
1027 | - void updateDemoEdges(bool async = true); |
1028 | - void updateEnableLauncherWhileLocked(bool async = true); |
1029 | - void updateEnableIndicatorsWhileLocked(bool async = true); |
1030 | - void updateBackgroundFile(bool async = true); |
1031 | - void updateMouseCursorSpeed(); |
1032 | - void updateTouchpadCursorSpeed(); |
1033 | - void updateStatsWelcomeScreen(bool async = true); |
1034 | - void updatePasswordDisplayHint(bool async = true); |
1035 | - void updateFailedLogins(bool async = true); |
1036 | - void updateHereEnabled(bool async = true); |
1037 | - void updateHereLicensePath(bool async = true); |
1038 | - |
1039 | + typedef QVariant (*ProxyConverter)(const QVariant &); |
1040 | + |
1041 | + void refresh(bool async); |
1042 | + void registerProperty(const QString &interface, const QString &property, const QString &signal); |
1043 | + void registerProxy(const QString &interface, const QString &property, QDBusInterface *iface, const QString &method, ProxyConverter converter = nullptr); |
1044 | + |
1045 | + void updateAllProperties(const QString &interface, bool async); |
1046 | + void updateProperty(const QString &interface, const QString &property); |
1047 | + void updateCache(const QString &interface, const QString &property, const QVariant &value); |
1048 | + |
1049 | + void setProperty(const QString &interface, const QString &property, const QVariant &value); |
1050 | + QVariant getProperty(const QString &interface, const QString &property) const; |
1051 | + |
1052 | + void emitChangedForProperty(const QString &interface, const QString &property); |
1053 | + |
1054 | + struct PropertyInfo { |
1055 | + QVariant value{}; |
1056 | + QString signal{}; |
1057 | + QDBusInterface *proxyInterface{}; |
1058 | + QString proxyMethod{}; |
1059 | + ProxyConverter proxyConverter{}; |
1060 | + }; |
1061 | + typedef QHash< QString, QHash<QString, PropertyInfo> > PropertyHash; |
1062 | + PropertyHash m_properties; |
1063 | AccountsServiceDBusAdaptor *m_service; |
1064 | QDBusInterface *m_unityInput; |
1065 | QString m_user; |
1066 | - bool m_demoEdges; |
1067 | - bool m_enableLauncherWhileLocked; |
1068 | - bool m_enableIndicatorsWhileLocked; |
1069 | - QString m_backgroundFile; |
1070 | - bool m_statsWelcomeScreen; |
1071 | - PasswordDisplayHint m_passwordDisplayHint; |
1072 | - uint m_failedLogins; |
1073 | - bool m_hereEnabled; |
1074 | - QString m_hereLicensePath; |
1075 | }; |
1076 | |
1077 | #endif |
1078 | |
1079 | === modified file 'plugins/AccountsService/AccountsServiceDBusAdaptor.cpp' |
1080 | --- plugins/AccountsService/AccountsServiceDBusAdaptor.cpp 2015-10-26 14:05:14 +0000 |
1081 | +++ plugins/AccountsService/AccountsServiceDBusAdaptor.cpp 2016-03-11 11:34:41 +0000 |
1082 | @@ -1,5 +1,5 @@ |
1083 | /* |
1084 | - * Copyright (C) 2013 Canonical, Ltd. |
1085 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
1086 | * |
1087 | * This program is free software; you can redistribute it and/or modify |
1088 | * it under the terms of the GNU General Public License as published by |
1089 | @@ -12,8 +12,6 @@ |
1090 | * |
1091 | * You should have received a copy of the GNU General Public License |
1092 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1093 | - * |
1094 | - * Author: Michael Terry <michael.terry@canonical.com> |
1095 | */ |
1096 | |
1097 | #include "AccountsServiceDBusAdaptor.h" |
1098 | @@ -37,6 +35,15 @@ |
1099 | connection, this); |
1100 | } |
1101 | |
1102 | +QDBusPendingReply<QVariantMap> AccountsServiceDBusAdaptor::getAllPropertiesAsync(const QString &user, const QString &interface) |
1103 | +{ |
1104 | + QDBusInterface *iface = getUserInterface(user); |
1105 | + if (iface != nullptr && iface->isValid()) { |
1106 | + return iface->asyncCall(QStringLiteral("GetAll"), interface); |
1107 | + } |
1108 | + return QDBusPendingReply<QVariantMap>(QDBusMessage::createError(QDBusError::Other, QStringLiteral("Invalid Interface"))); |
1109 | +} |
1110 | + |
1111 | QDBusPendingReply<QVariant> AccountsServiceDBusAdaptor::getUserPropertyAsync(const QString &user, const QString &interface, const QString &property) |
1112 | { |
1113 | QDBusInterface *iface = getUserInterface(user); |
1114 | @@ -80,7 +87,7 @@ |
1115 | m_ignoreNextChanged = false; |
1116 | } |
1117 | |
1118 | -QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path) |
1119 | +QString AccountsServiceDBusAdaptor::getUserForPath(const QString &path) const |
1120 | { |
1121 | QMap<QString, QDBusInterface *>::const_iterator i; |
1122 | for (i = m_users.constBegin(); i != m_users.constEnd(); ++i) { |
1123 | |
1124 | === modified file 'plugins/AccountsService/AccountsServiceDBusAdaptor.h' |
1125 | --- plugins/AccountsService/AccountsServiceDBusAdaptor.h 2015-10-26 14:05:14 +0000 |
1126 | +++ plugins/AccountsService/AccountsServiceDBusAdaptor.h 2016-03-11 11:34:41 +0000 |
1127 | @@ -1,5 +1,5 @@ |
1128 | /* |
1129 | - * Copyright (C) 2013 Canonical, Ltd. |
1130 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
1131 | * |
1132 | * This program is free software; you can redistribute it and/or modify |
1133 | * it under the terms of the GNU General Public License as published by |
1134 | @@ -12,8 +12,6 @@ |
1135 | * |
1136 | * You should have received a copy of the GNU General Public License |
1137 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1138 | - * |
1139 | - * Authors: Michael Terry <michael.terry@canonical.com> |
1140 | */ |
1141 | |
1142 | #ifndef UNITY_ACCOUNTSSERVICEDBUSADAPTOR_H |
1143 | @@ -35,8 +33,9 @@ |
1144 | explicit AccountsServiceDBusAdaptor(QObject *parent = 0); |
1145 | ~AccountsServiceDBusAdaptor() = default; |
1146 | |
1147 | - Q_INVOKABLE QDBusPendingReply<QVariant> getUserPropertyAsync(const QString &user, const QString &interface, const QString &property); |
1148 | - Q_INVOKABLE QDBusPendingCall setUserPropertyAsync(const QString &user, const QString &interface, const QString &property, const QVariant &value); |
1149 | + QDBusPendingReply<QVariantMap> getAllPropertiesAsync(const QString &user, const QString &interface); |
1150 | + QDBusPendingReply<QVariant> getUserPropertyAsync(const QString &user, const QString &interface, const QString &property); |
1151 | + QDBusPendingCall setUserPropertyAsync(const QString &user, const QString &interface, const QString &property, const QVariant &value); |
1152 | |
1153 | Q_SIGNALS: |
1154 | void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed); |
1155 | @@ -48,7 +47,7 @@ |
1156 | |
1157 | private: |
1158 | QDBusInterface *getUserInterface(const QString &user); |
1159 | - QString getUserForPath(const QString &path); |
1160 | + QString getUserForPath(const QString &path) const; |
1161 | |
1162 | QDBusInterface *m_accountsManager; |
1163 | QMap<QString, QDBusInterface *> m_users; |
1164 | |
1165 | === modified file 'plugins/Dash/AudioProgressBar.qml' |
1166 | --- plugins/Dash/AudioProgressBar.qml 2015-12-03 14:44:08 +0000 |
1167 | +++ plugins/Dash/AudioProgressBar.qml 2016-03-11 11:34:41 +0000 |
1168 | @@ -31,6 +31,7 @@ |
1169 | anchors { left: parent.left; right: parent.right } |
1170 | height: units.dp(6) |
1171 | source: "graphics/music_progress_bg.png" |
1172 | + asynchronous: true |
1173 | sourceSize.width: width |
1174 | sourceSize.height: height |
1175 | } |
1176 | |
1177 | === modified file 'plugins/Dash/CardCreator.js' |
1178 | --- plugins/Dash/CardCreator.js 2016-02-12 00:11:52 +0000 |
1179 | +++ plugins/Dash/CardCreator.js 2016-03-11 11:34:41 +0000 |
1180 | @@ -18,12 +18,13 @@ |
1181 | |
1182 | // %1 is the template["card-background"]["elements"][0] |
1183 | // %2 is the template["card-background"]["elements"][1] |
1184 | -// %3 is the template["card-background"] string |
1185 | +// %3 is whether the loader should be asynchronous or not |
1186 | +// %4 is the template["card-background"] string |
1187 | var kBackgroundLoaderCode = 'Loader {\n\ |
1188 | id: backgroundLoader; \n\ |
1189 | objectName: "backgroundLoader"; \n\ |
1190 | anchors.fill: parent; \n\ |
1191 | - asynchronous: root.asynchronous; \n\ |
1192 | + asynchronous: %3; \n\ |
1193 | visible: status == Loader.Ready; \n\ |
1194 | sourceComponent: UbuntuShape { \n\ |
1195 | objectName: "background"; \n\ |
1196 | @@ -46,7 +47,7 @@ |
1197 | objectName: "backgroundImage"; \n\ |
1198 | source: { \n\ |
1199 | if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\ |
1200 | - else return %3; \n\ |
1201 | + else return %4; \n\ |
1202 | } \n\ |
1203 | } \n\ |
1204 | function getColor(index) { \n\ |
1205 | @@ -63,8 +64,9 @@ |
1206 | // %3 is used as image height |
1207 | // %4 is used for artShapeSource.hideSource and inner Loader visible |
1208 | // %5 is used as aspect ratio fallback |
1209 | -// %6 is injected as code to artImage |
1210 | -// %7 is used as image fallback |
1211 | +// %6 is whether the loader should be asynchronous or not |
1212 | +// %7 is injected as code to artImage |
1213 | +// %8 is used as image fallback |
1214 | var kArtShapeHolderCode = 'Item { \n\ |
1215 | id: artShapeHolder; \n\ |
1216 | height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\ |
1217 | @@ -73,9 +75,9 @@ |
1218 | Loader { \n\ |
1219 | id: artShapeLoader; \n\ |
1220 | objectName: "artShapeLoader"; \n\ |
1221 | - readonly property string cardArt: cardData && cardData["art"] || %7; \n\ |
1222 | + readonly property string cardArt: cardData && cardData["art"] || %8; \n\ |
1223 | active: cardArt != ""; \n\ |
1224 | - asynchronous: root.asynchronous; \n\ |
1225 | + asynchronous: %6; \n\ |
1226 | visible: status == Loader.Ready; \n\ |
1227 | sourceComponent: Item { \n\ |
1228 | id: artShape; \n\ |
1229 | @@ -132,10 +134,10 @@ |
1230 | id: artImage; \n\ |
1231 | objectName: "artImage"; \n\ |
1232 | source: artShapeLoader.cardArt; \n\ |
1233 | - asynchronous: root.asynchronous; \n\ |
1234 | + asynchronous: %6; \n\ |
1235 | width: %2; \n\ |
1236 | height: %3; \n\ |
1237 | - %6 \n\ |
1238 | + %7 \n\ |
1239 | } \n\ |
1240 | } \n\ |
1241 | } \n\ |
1242 | @@ -144,6 +146,7 @@ |
1243 | // %1 is anchors.fill |
1244 | // %2 is width |
1245 | // %3 is height |
1246 | +// %4 is whether the icon should be asynchronous or not |
1247 | var kAudioButtonCode = 'AbstractButton { \n\ |
1248 | id: audioButton; \n\ |
1249 | anchors.fill: %1; \n\ |
1250 | @@ -169,6 +172,7 @@ |
1251 | opacity: 0.9; \n\ |
1252 | name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start"; \n\ |
1253 | color: "white"; \n\ |
1254 | + asynchronous: %4; \n\ |
1255 | } \n\ |
1256 | onClicked: { \n\ |
1257 | if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) { \n\ |
1258 | @@ -187,12 +191,14 @@ |
1259 | } \n\ |
1260 | }'; |
1261 | |
1262 | +// %1 is whether the loader should be asynchronous or not |
1263 | +// %2 is the header height code |
1264 | var kOverlayLoaderCode = 'Loader { \n\ |
1265 | id: overlayLoader; \n\ |
1266 | - readonly property real overlayHeight: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\ |
1267 | + readonly property real overlayHeight: %2 + units.gu(2); \n\ |
1268 | anchors.fill: artShapeHolder; \n\ |
1269 | active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\ |
1270 | - asynchronous: root.asynchronous; \n\ |
1271 | + asynchronous: %1; \n\ |
1272 | visible: showHeader && status == Loader.Ready; \n\ |
1273 | sourceComponent: UbuntuShapeOverlay { \n\ |
1274 | id: overlay; \n\ |
1275 | @@ -211,17 +217,19 @@ |
1276 | objectName: "outerRow"; \n\ |
1277 | property real margins: units.gu(1); \n\ |
1278 | spacing: margins; \n\ |
1279 | - height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\ |
1280 | + %2\ |
1281 | anchors { %1 } \n\ |
1282 | anchors.right: parent.right; \n\ |
1283 | anchors.margins: margins; \n\ |
1284 | anchors.rightMargin: 0; \n\ |
1285 | data: [ \n\ |
1286 | - %2 \n\ |
1287 | + %3 \n\ |
1288 | ] \n\ |
1289 | }\n'; |
1290 | var args = Array.prototype.slice.call(arguments); |
1291 | - var code = kHeaderRowCodeTemplate.arg(args.shift()).arg(args.join(',\n')); |
1292 | + var isCardTool = args.shift(); |
1293 | + var heightCode = isCardTool ? "" : "height: root.fixedHeaderHeight; \n"; |
1294 | + var code = kHeaderRowCodeTemplate.arg(args.shift()).arg(heightCode).arg(args.join(',\n')); |
1295 | return code; |
1296 | } |
1297 | |
1298 | @@ -242,10 +250,11 @@ |
1299 | } |
1300 | |
1301 | // %1 is used as anchors of mascotShapeLoader |
1302 | +// %2 is whether the loader should be asynchronous or not |
1303 | var kMascotShapeLoaderCode = 'Loader { \n\ |
1304 | id: mascotShapeLoader; \n\ |
1305 | objectName: "mascotShapeLoader"; \n\ |
1306 | - asynchronous: root.asynchronous; \n\ |
1307 | + asynchronous: %2; \n\ |
1308 | active: mascotImage.status === Image.Ready; \n\ |
1309 | visible: showHeader && active && status == Loader.Ready; \n\ |
1310 | width: units.gu(6); \n\ |
1311 | @@ -275,6 +284,7 @@ |
1312 | // %2 is used as color of titleLabel |
1313 | // %3 is used as extra condition for visible of titleLabel |
1314 | // %4 is used as title width |
1315 | +// %5 is used as horizontal alignment |
1316 | var kTitleLabelCode = 'Label { \n\ |
1317 | id: titleLabel; \n\ |
1318 | objectName: "titleLabel"; \n\ |
1319 | @@ -289,7 +299,7 @@ |
1320 | width: %4; \n\ |
1321 | text: root.title; \n\ |
1322 | font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal; \n\ |
1323 | - horizontalAlignment: root.titleAlignment; \n\ |
1324 | + horizontalAlignment: %5; \n\ |
1325 | }\n'; |
1326 | |
1327 | // %1 is used as extra anchors of emblemIcon |
1328 | @@ -398,7 +408,7 @@ |
1329 | return colorString; |
1330 | } |
1331 | |
1332 | -function cardString(template, components) { |
1333 | +function cardString(template, components, isCardTool) { |
1334 | var code; |
1335 | |
1336 | var templateInteractive = (template == null ? true : (template["non-interactive"] !== undefined ? !template["non-interactive"] : true)) ? "true" : "false"; |
1337 | @@ -410,16 +420,16 @@ |
1338 | property string backgroundShapeStyle: "inset"; \n\ |
1339 | property real fontScale: 1.0; \n\ |
1340 | property var scopeStyle: null; \n\ |
1341 | - property int titleAlignment: Text.AlignLeft; \n\ |
1342 | - property int fixedHeaderHeight: -1; \n\ |
1343 | + %2\ |
1344 | property size fixedArtShapeSize: Qt.size(-1, -1); \n\ |
1345 | readonly property string title: cardData && cardData["title"] || ""; \n\ |
1346 | - property bool asynchronous: true; \n\ |
1347 | property bool showHeader: true; \n\ |
1348 | implicitWidth: childrenRect.width; \n\ |
1349 | enabled: %1; \n\ |
1350 | \n'.arg(templateInteractive); |
1351 | |
1352 | + code = code.arg(isCardTool ? "" : "property int fixedHeaderHeight: -1; \n"); |
1353 | + |
1354 | var hasArt = components["art"] && components["art"]["field"] || false; |
1355 | var hasSummary = components["summary"] || false; |
1356 | var isConciergeMode = components["art"] && components["art"]["conciergeMode"] || false; |
1357 | @@ -435,6 +445,7 @@ |
1358 | var hasHeaderRow = hasMascot && hasTitle; |
1359 | var hasAttributes = hasTitle && components["attributes"] && components["attributes"]["field"] || false; |
1360 | var isAudio = template["quick-preview-type"] === "audio"; |
1361 | + var asynchronous = isCardTool ? "false" : "true"; |
1362 | |
1363 | if (isAudio) { |
1364 | // For now we only support audio cards with [optional] art, title, subtitle |
1365 | @@ -468,7 +479,7 @@ |
1366 | backgroundElements1 = '"%1"'.arg(element1); |
1367 | } |
1368 | } |
1369 | - code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(templateCardBackground); |
1370 | + code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(asynchronous).arg(templateCardBackground); |
1371 | } |
1372 | |
1373 | if (hasArt) { |
1374 | @@ -497,23 +508,31 @@ |
1375 | if (isNaN(aspectRatio)) { |
1376 | aspectRatio = 1; |
1377 | } |
1378 | - var fallback = components["art"] && components["art"]["fallback"] || ""; |
1379 | + var fallback = !isCardTool && components["art"] && components["art"]["fallback"] || ""; |
1380 | fallback = encodeURI(fallback); |
1381 | var fallbackStatusCode = ""; |
1382 | var fallbackURICode = '""'; |
1383 | if (fallback !== "") { |
1384 | // fallbackStatusCode has %6 in it because we want to substitute it for fallbackURICode |
1385 | - // which in kArtShapeHolderCode is %7 |
1386 | - fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %7;'; |
1387 | + // which in kArtShapeHolderCode is %8 |
1388 | + fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %8;'; |
1389 | fallbackURICode = 'decodeURI("%1")'.arg(fallback); |
1390 | } |
1391 | - code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode).arg(isConciergeMode ? "false" : "true").arg(aspectRatio).arg(fallbackStatusCode).arg(fallbackURICode); |
1392 | + code += kArtShapeHolderCode.arg(artAnchors) |
1393 | + .arg(widthCode) |
1394 | + .arg(heightCode) |
1395 | + .arg(isConciergeMode ? "false" : "true") |
1396 | + .arg(aspectRatio) |
1397 | + .arg(asynchronous) |
1398 | + .arg(fallbackStatusCode) |
1399 | + .arg(fallbackURICode); |
1400 | } else { |
1401 | code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n' |
1402 | } |
1403 | |
1404 | if (headerAsOverlay) { |
1405 | - code += kOverlayLoaderCode; |
1406 | + var headerHeightCode = isCardTool ? "headerHeight" : "root.fixedHeaderHeight"; |
1407 | + code += kOverlayLoaderCode.arg(asynchronous).arg(headerHeightCode); |
1408 | } |
1409 | |
1410 | var headerVerticalAnchors; |
1411 | @@ -595,11 +614,11 @@ |
1412 | } |
1413 | |
1414 | if (useMascotShape) { |
1415 | - mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors); |
1416 | + mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors).arg(asynchronous); |
1417 | } |
1418 | |
1419 | var mascotImageVisible = useMascotShape ? 'false' : 'showHeader'; |
1420 | - var fallback = components["mascot"] && components["mascot"]["fallback"] || ""; |
1421 | + var fallback = !isCardTool && components["mascot"] && components["mascot"]["fallback"] || ""; |
1422 | fallback = encodeURI(fallback); |
1423 | var fallbackStatusCode = ""; |
1424 | var fallbackURICode = '""'; |
1425 | @@ -715,9 +734,24 @@ |
1426 | } |
1427 | } |
1428 | |
1429 | + var titleAlignment = "Text.AlignHCenter"; |
1430 | + if (template["card-layout"] === "horizontal" |
1431 | + || typeof components["title"] !== "object" |
1432 | + || components["title"]["align"] === "left") titleAlignment = "Text.AlignLeft"; |
1433 | + var keys = ["mascot", "emblem", "subtitle", "attributes", "summary"]; |
1434 | + for (var key in keys) { |
1435 | + key = keys[key]; |
1436 | + try { |
1437 | + if (typeof components[key] === "string" |
1438 | + || typeof components[key]["field"] === "string") titleAlignment = "Text.AlignLeft"; |
1439 | + } catch (e) { |
1440 | + continue; |
1441 | + } |
1442 | + } |
1443 | + |
1444 | // code for different elements |
1445 | var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': ''); |
1446 | - var titleCode = kTitleLabelCode.arg(titleAnchors).arg(titleColor).arg(titleLabelVisibleExtra).arg(titleWidth); |
1447 | + var titleCode = kTitleLabelCode.arg(titleAnchors).arg(titleColor).arg(titleLabelVisibleExtra).arg(titleWidth).arg(titleAlignment); |
1448 | var subtitleCode; |
1449 | var attributesCode; |
1450 | |
1451 | @@ -759,7 +793,7 @@ |
1452 | if (mascotShapeCode != '') { |
1453 | rowCode.unshift(mascotShapeCode); |
1454 | } |
1455 | - code += kHeaderRowCodeGenerator(headerVerticalAnchors + headerLeftAnchor, rowCode) |
1456 | + code += kHeaderRowCodeGenerator(isCardTool, headerVerticalAnchors + headerLeftAnchor, rowCode) |
1457 | } else { |
1458 | code += mascotShapeCode + mascotCode + titleSubtitleCode; |
1459 | } |
1460 | @@ -783,9 +817,10 @@ |
1461 | } else { |
1462 | audioButtonAnchorsFill = 'undefined'; |
1463 | audioButtonWidth = 'height'; |
1464 | - audioButtonHeight = '(root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1)'; |
1465 | + audioButtonHeight = isCardTool ? 'headerHeight + 2 * units.gu(1)' |
1466 | + : 'root.fixedHeaderHeight + 2 * units.gu(1)'; |
1467 | } |
1468 | - code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight); |
1469 | + code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight).arg(asynchronous); |
1470 | } |
1471 | |
1472 | if (hasSummary) { |
1473 | @@ -854,13 +889,13 @@ |
1474 | return code; |
1475 | } |
1476 | |
1477 | -function createCardComponent(parent, template, components, identifier) { |
1478 | +function createCardComponent(parent, template, components, isCardTool, identifier) { |
1479 | var imports = 'import QtQuick 2.4; \n\ |
1480 | import Ubuntu.Components 1.3; \n\ |
1481 | import Ubuntu.Settings.Components 0.1; \n\ |
1482 | import Dash 0.1;\n\ |
1483 | import Utils 0.1;\n'; |
1484 | - var card = cardString(template, components); |
1485 | + var card = cardString(template, components, isCardTool); |
1486 | var code = imports + 'Component {\n' + card + '}\n'; |
1487 | |
1488 | try { |
1489 | |
1490 | === modified file 'plugins/Dash/CardCreatorCache.qml' |
1491 | --- plugins/Dash/CardCreatorCache.qml 2016-01-21 17:56:08 +0000 |
1492 | +++ plugins/Dash/CardCreatorCache.qml 2016-03-11 11:34:41 +0000 |
1493 | @@ -23,16 +23,16 @@ |
1494 | |
1495 | property var cache: new Object(); |
1496 | |
1497 | - function getCardComponent(template, components) { |
1498 | + function getCardComponent(template, components, isCardTool) { |
1499 | if (template === undefined || components === undefined) |
1500 | return undefined; |
1501 | |
1502 | var tString = JSON.stringify(template); |
1503 | var cString = JSON.stringify(components); |
1504 | - var allString = tString + cString; |
1505 | + var allString = tString + cString + isCardTool; |
1506 | var component = cache[allString]; |
1507 | if (component === undefined) { |
1508 | - component = CardCreator.createCardComponent(root, template, components, allString); |
1509 | + component = CardCreator.createCardComponent(root, template, components, isCardTool, allString); |
1510 | cache[allString] = component; |
1511 | } |
1512 | return component; |
1513 | |
1514 | === modified file 'plugins/Dash/plugin.cpp' |
1515 | --- plugins/Dash/plugin.cpp 2015-09-18 07:44:50 +0000 |
1516 | +++ plugins/Dash/plugin.cpp 2016-03-11 11:34:41 +0000 |
1517 | @@ -28,12 +28,12 @@ |
1518 | static QUrl oauthCleanedUrl(QUrl u) |
1519 | { |
1520 | QUrlQuery q(u); |
1521 | - q.removeQueryItem("oauth_nonce"); |
1522 | - q.removeQueryItem("oauth_timestamp"); |
1523 | - q.removeQueryItem("oauth_consumer_key"); |
1524 | - q.removeQueryItem("oauth_signature_method"); |
1525 | - q.removeQueryItem("oauth_version"); |
1526 | - q.removeQueryItem("oauth_signature"); |
1527 | + q.removeQueryItem(QStringLiteral("oauth_nonce")); |
1528 | + q.removeQueryItem(QStringLiteral("oauth_timestamp")); |
1529 | + q.removeQueryItem(QStringLiteral("oauth_consumer_key")); |
1530 | + q.removeQueryItem(QStringLiteral("oauth_signature_method")); |
1531 | + q.removeQueryItem(QStringLiteral("oauth_version")); |
1532 | + q.removeQueryItem(QStringLiteral("oauth_signature")); |
1533 | u.setQuery(q); |
1534 | return u; |
1535 | } |
1536 | |
1537 | === modified file 'plugins/GlobalShortcut/globalshortcutregistry.cpp' |
1538 | --- plugins/GlobalShortcut/globalshortcutregistry.cpp 2015-11-20 15:01:39 +0000 |
1539 | +++ plugins/GlobalShortcut/globalshortcutregistry.cpp 2016-03-11 11:34:41 +0000 |
1540 | @@ -35,13 +35,13 @@ |
1541 | |
1542 | bool GlobalShortcutRegistry::hasShortcut(const QVariant &seq) const |
1543 | { |
1544 | - return m_shortcuts.keys().contains(seq); |
1545 | + return m_shortcuts.contains(seq); |
1546 | } |
1547 | |
1548 | void GlobalShortcutRegistry::addShortcut(const QVariant &seq, GlobalShortcut *sc) |
1549 | { |
1550 | if (sc) { |
1551 | - if (!m_shortcuts.keys().contains(seq)) { // create a new entry |
1552 | + if (!m_shortcuts.contains(seq)) { // create a new entry |
1553 | m_shortcuts.insert(seq, {sc}); |
1554 | } else { // append to an existing one |
1555 | auto shortcuts = m_shortcuts[seq]; |
1556 | @@ -75,8 +75,8 @@ |
1557 | |
1558 | if (event->type() == QEvent::KeyPress) { |
1559 | QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); |
1560 | - QKeySequence seq = QKeySequence(keyEvent->key() + keyEvent->modifiers()); |
1561 | - if (m_shortcuts.keys().contains(seq)) { |
1562 | + int seq = keyEvent->key() + keyEvent->modifiers(); |
1563 | + if (m_shortcuts.contains(seq)) { |
1564 | const auto shortcuts = m_shortcuts.value(seq); |
1565 | Q_FOREACH(const auto &shortcut, shortcuts) { |
1566 | if (shortcut) { |
1567 | |
1568 | === modified file 'plugins/IntegratedLightDM/liblightdm/CMakeLists.txt' |
1569 | --- plugins/IntegratedLightDM/liblightdm/CMakeLists.txt 2016-02-01 15:15:09 +0000 |
1570 | +++ plugins/IntegratedLightDM/liblightdm/CMakeLists.txt 2016-03-11 11:34:41 +0000 |
1571 | @@ -5,13 +5,16 @@ |
1572 | UsersModel.cpp |
1573 | GreeterPrivate.cpp |
1574 | UsersModelPrivate.cpp |
1575 | + ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp |
1576 | ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp |
1577 | ) |
1578 | |
1579 | add_library(integratedLightDM STATIC ${LibLightDM_SOURCES}) |
1580 | +add_library(integratedLightDMSession STATIC ${LibLightDM_SOURCES}) |
1581 | add_library(MockLightDM-demo-shared SHARED ${LibLightDM_SOURCES}) |
1582 | |
1583 | include_directories( |
1584 | + ${CMAKE_SOURCE_DIR}/plugins/AccountsService |
1585 | ${CMAKE_CURRENT_BINARY_DIR} |
1586 | ${GLIB_INCLUDE_DIRS} |
1587 | ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS} |
1588 | @@ -22,17 +25,27 @@ |
1589 | ${LIBUSERMETRICSOUTPUT_LDFLAGS} |
1590 | -lpam |
1591 | ) |
1592 | +target_link_libraries(integratedLightDMSession |
1593 | + ${GLIB_LIBRARIES} |
1594 | + ${LIBUSERMETRICSOUTPUT_LDFLAGS} |
1595 | + -lpam |
1596 | +) |
1597 | target_link_libraries(MockLightDM-demo-shared |
1598 | ${GLIB_LIBRARIES} |
1599 | ${LIBUSERMETRICSOUTPUT_LDFLAGS} |
1600 | -lpam |
1601 | ) |
1602 | |
1603 | -qt5_use_modules(integratedLightDM Concurrent Gui) |
1604 | -qt5_use_modules(MockLightDM-demo-shared Concurrent Gui) |
1605 | +qt5_use_modules(integratedLightDM Concurrent DBus Gui) |
1606 | +qt5_use_modules(integratedLightDMSession Concurrent DBus Gui) |
1607 | +qt5_use_modules(MockLightDM-demo-shared Concurrent DBus Gui) |
1608 | |
1609 | -set_target_properties(integratedLightDM PROPERTIES COMPILE_FLAGS -fPIC) |
1610 | +set_target_properties(integratedLightDM PROPERTIES |
1611 | + COMPILE_FLAGS "-DSM_BUSNAME=systemBus -fPIC") |
1612 | +set_target_properties(integratedLightDMSession PROPERTIES |
1613 | + COMPILE_FLAGS "-DSM_BUSNAME=sessionBus -fPIC") |
1614 | set_target_properties(MockLightDM-demo-shared PROPERTIES |
1615 | + COMPILE_FLAGS "-DSM_BUSNAME=systemBus" |
1616 | OUTPUT_NAME lightdm-qt5-2) |
1617 | |
1618 | install(TARGETS MockLightDM-demo-shared |
1619 | |
1620 | === modified file 'plugins/IntegratedLightDM/liblightdm/UsersModel.cpp' |
1621 | --- plugins/IntegratedLightDM/liblightdm/UsersModel.cpp 2015-09-14 09:11:08 +0000 |
1622 | +++ plugins/IntegratedLightDM/liblightdm/UsersModel.cpp 2016-03-11 11:34:41 +0000 |
1623 | @@ -54,24 +54,10 @@ |
1624 | roles[ImagePathRole] = "imagePath"; |
1625 | setRoleNames(roles); |
1626 | |
1627 | - // Now modify our mock user backgrounds |
1628 | - QDir bgdir = QDir(QStringLiteral("/usr/share/demo-assets/shell/backgrounds/")); |
1629 | - QStringList backgrounds = bgdir.entryList(QDir::Files | QDir::NoDotAndDotDot); |
1630 | - |
1631 | - for (int i = 0, j = 0; i < d->entries.size(); i++) { |
1632 | - Entry &entry = d->entries[i]; |
1633 | - if (entry.background.isNull() && !backgrounds.isEmpty()) { |
1634 | - entry.background = bgdir.filePath(backgrounds[j++]); |
1635 | - if (j >= backgrounds.length()) { |
1636 | - j = 0; |
1637 | - } |
1638 | - } |
1639 | - } |
1640 | -} |
1641 | - |
1642 | -UsersModel::~UsersModel() |
1643 | -{ |
1644 | - delete d_ptr; |
1645 | + connect(d_ptr, &UsersModelPrivate::dataChanged, this, [this](int i) { |
1646 | + QModelIndex index = createIndex(i, 0); |
1647 | + Q_EMIT dataChanged(index, index); |
1648 | + }); |
1649 | } |
1650 | |
1651 | int UsersModel::rowCount(const QModelIndex &parent) const |
1652 | |
1653 | === modified file 'plugins/IntegratedLightDM/liblightdm/UsersModel.h' |
1654 | --- plugins/IntegratedLightDM/liblightdm/UsersModel.h 2015-04-30 09:31:51 +0000 |
1655 | +++ plugins/IntegratedLightDM/liblightdm/UsersModel.h 2016-03-11 11:34:41 +0000 |
1656 | @@ -41,7 +41,7 @@ |
1657 | |
1658 | public: |
1659 | explicit UsersModel(QObject *parent = 0); |
1660 | - virtual ~UsersModel(); |
1661 | + virtual ~UsersModel() = default; |
1662 | |
1663 | enum UserModelRoles {NameRole = Qt::UserRole, |
1664 | RealNameRole, |
1665 | |
1666 | === modified file 'plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp' |
1667 | --- plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp 2016-02-04 14:10:42 +0000 |
1668 | +++ plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp 2016-03-11 11:34:41 +0000 |
1669 | @@ -18,7 +18,11 @@ |
1670 | |
1671 | #include "UsersModelPrivate.h" |
1672 | |
1673 | +#include "AccountsServiceDBusAdaptor.h" |
1674 | +#include "UsersModel.h" |
1675 | + |
1676 | #include <glib.h> |
1677 | +#include <QDebug> |
1678 | #include <QDir> |
1679 | #include <QSettings> |
1680 | #include <QStringList> |
1681 | @@ -27,7 +31,9 @@ |
1682 | { |
1683 | |
1684 | UsersModelPrivate::UsersModelPrivate(UsersModel* parent) |
1685 | - : q_ptr(parent) |
1686 | + : QObject(parent), |
1687 | + q_ptr(parent), |
1688 | + m_service(new AccountsServiceDBusAdaptor(this)) |
1689 | { |
1690 | QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo"); |
1691 | QString currentUser = g_get_user_name(); |
1692 | @@ -43,15 +49,43 @@ |
1693 | entries.append({user, name, 0, 0, false, false, 0, 0}); |
1694 | } |
1695 | } else { |
1696 | - // If we were using the actual liblightdm, we could just ask it |
1697 | - // for the user's real name. But we aren't. We *should* ask |
1698 | - // AccountsService for the real name, like liblightdm does internally, |
1699 | - // but this is close enough since AS and passwd are always in sync. |
1700 | - QString realName = QString::fromUtf8(g_get_real_name()); // gets name from passwd entry |
1701 | - if (realName == QStringLiteral("Unknown")) { // glib doesn't translate this string |
1702 | - realName.clear(); |
1703 | - } |
1704 | - entries.append({currentUser, realName, 0, 0, false, false, 0, 0}); |
1705 | + entries.append({currentUser, 0, 0, 0, false, false, 0, 0}); |
1706 | + |
1707 | + connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged, |
1708 | + this, [this](const QString &user) { |
1709 | + if (user == entries[0].username) { |
1710 | + updateName(true); |
1711 | + } |
1712 | + }); |
1713 | + updateName(false); |
1714 | + } |
1715 | +} |
1716 | + |
1717 | +void UsersModelPrivate::updateName(bool async) |
1718 | +{ |
1719 | + auto pendingReply = m_service->getUserPropertyAsync(entries[0].username, |
1720 | + QStringLiteral("org.freedesktop.Accounts.User"), |
1721 | + QStringLiteral("RealName")); |
1722 | + auto *watcher = new QDBusPendingCallWatcher(pendingReply, this); |
1723 | + |
1724 | + connect(watcher, &QDBusPendingCallWatcher::finished, |
1725 | + this, [this](QDBusPendingCallWatcher* watcher) { |
1726 | + |
1727 | + QDBusPendingReply<QVariant> reply = *watcher; |
1728 | + watcher->deleteLater(); |
1729 | + if (reply.isError()) { |
1730 | + qWarning() << "Failed to get 'RealName' property - " << reply.error().message(); |
1731 | + return; |
1732 | + } |
1733 | + |
1734 | + const QString realName = reply.value().toString(); |
1735 | + if (entries[0].real_name != realName) { |
1736 | + entries[0].real_name = realName; |
1737 | + Q_EMIT dataChanged(0); |
1738 | + } |
1739 | + }); |
1740 | + if (!async) { |
1741 | + watcher->waitForFinished(); |
1742 | } |
1743 | } |
1744 | |
1745 | |
1746 | === modified file 'plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h' |
1747 | --- plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h 2015-01-20 11:50:19 +0000 |
1748 | +++ plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h 2016-03-11 11:34:41 +0000 |
1749 | @@ -19,8 +19,11 @@ |
1750 | #ifndef UNITY_MOCK_USERSMODEL_PRIVATE_H |
1751 | #define UNITY_MOCK_USERSMODEL_PRIVATE_H |
1752 | |
1753 | -#include <QtCore/QList> |
1754 | -#include <QtCore/QString> |
1755 | +#include <QList> |
1756 | +#include <QObject> |
1757 | +#include <QString> |
1758 | + |
1759 | +class AccountsServiceDBusAdaptor; |
1760 | |
1761 | namespace QLightDM |
1762 | { |
1763 | @@ -39,19 +42,28 @@ |
1764 | QString infographic; |
1765 | }; |
1766 | |
1767 | -class UsersModelPrivate |
1768 | +class UsersModelPrivate : public QObject |
1769 | { |
1770 | + Q_OBJECT |
1771 | + |
1772 | public: |
1773 | explicit UsersModelPrivate(UsersModel *parent = 0); |
1774 | virtual ~UsersModelPrivate() = default; |
1775 | |
1776 | QList<Entry> entries; |
1777 | |
1778 | +Q_SIGNALS: |
1779 | + void dataChanged(int); |
1780 | + |
1781 | protected: |
1782 | UsersModel * const q_ptr; |
1783 | |
1784 | private: |
1785 | Q_DECLARE_PUBLIC(UsersModel) |
1786 | + |
1787 | + void updateName(bool async); |
1788 | + |
1789 | + AccountsServiceDBusAdaptor *m_service; |
1790 | }; |
1791 | |
1792 | } |
1793 | |
1794 | === modified file 'plugins/Unity/Indicators/indicatorsmanager.cpp' |
1795 | --- plugins/Unity/Indicators/indicatorsmanager.cpp 2015-12-02 12:02:50 +0000 |
1796 | +++ plugins/Unity/Indicators/indicatorsmanager.cpp 2016-03-11 11:34:41 +0000 |
1797 | @@ -116,7 +116,7 @@ |
1798 | QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this); |
1799 | const QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString(); |
1800 | |
1801 | - if (m_platform.isPC() && name == "indicator-keyboard") { |
1802 | + if (m_platform.isPC() && name == QLatin1String("indicator-keyboard")) { |
1803 | return; // convergence: skip this indicator until it works in Mir |
1804 | } |
1805 | |
1806 | @@ -293,7 +293,7 @@ |
1807 | // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs) |
1808 | if ((new_indicator->identifier() == QStringLiteral("indicator-session") && m_platform.isMultiSession()) |
1809 | || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) { |
1810 | - new_indicator->setProfile("desktop"); |
1811 | + new_indicator->setProfile(QStringLiteral("desktop")); |
1812 | } else { |
1813 | new_indicator->setProfile(m_profile); |
1814 | } |
1815 | |
1816 | === modified file 'plugins/Unity/Indicators/rootstateparser.h' |
1817 | --- plugins/Unity/Indicators/rootstateparser.h 2014-11-11 15:28:13 +0000 |
1818 | +++ plugins/Unity/Indicators/rootstateparser.h 2016-03-11 11:34:41 +0000 |
1819 | @@ -23,6 +23,7 @@ |
1820 | |
1821 | class UNITYINDICATORS_EXPORT RootStateParser : public ActionStateParser |
1822 | { |
1823 | +Q_OBJECT |
1824 | public: |
1825 | RootStateParser(QObject* parent = nullptr); |
1826 | virtual QVariant toQVariant(GVariant* state) const override; |
1827 | |
1828 | === modified file 'plugins/Unity/Launcher/desktopfilehandler.cpp' |
1829 | --- plugins/Unity/Launcher/desktopfilehandler.cpp 2015-09-30 12:43:53 +0000 |
1830 | +++ plugins/Unity/Launcher/desktopfilehandler.cpp 2016-03-11 11:34:41 +0000 |
1831 | @@ -146,9 +146,9 @@ |
1832 | QString iconString = settings.value(QStringLiteral("Icon")).toString(); |
1833 | QString pathString = settings.value(QStringLiteral("Path")).toString(); |
1834 | |
1835 | - if (QFileInfo(iconString).exists()) { |
1836 | + if (QFileInfo::exists(iconString)) { |
1837 | return QFileInfo(iconString).absoluteFilePath(); |
1838 | - } else if (QFileInfo(pathString + '/' + iconString).exists()) { |
1839 | + } else if (QFileInfo::exists(pathString + '/' + iconString)) { |
1840 | return pathString + '/' + iconString; |
1841 | } |
1842 | return "image://theme/" + iconString; |
1843 | |
1844 | === modified file 'plugins/Unity/Launcher/launcheritem.cpp' |
1845 | --- plugins/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000 |
1846 | +++ plugins/Unity/Launcher/launcheritem.cpp 2016-03-11 11:34:41 +0000 |
1847 | @@ -37,6 +37,7 @@ |
1848 | m_alerting(false), |
1849 | m_quickList(new QuickListModel(this)) |
1850 | { |
1851 | + Q_ASSERT(parent != nullptr); |
1852 | QuickListEntry nameAction; |
1853 | nameAction.setActionId(QStringLiteral("launch_item")); |
1854 | nameAction.setText(m_name); |
1855 | |
1856 | === modified file 'plugins/Unity/Launcher/launcheritem.h' |
1857 | --- plugins/Unity/Launcher/launcheritem.h 2015-07-23 14:13:57 +0000 |
1858 | +++ plugins/Unity/Launcher/launcheritem.h 2016-03-11 11:34:41 +0000 |
1859 | @@ -32,7 +32,7 @@ |
1860 | { |
1861 | Q_OBJECT |
1862 | public: |
1863 | - LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent = 0); |
1864 | + LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent); |
1865 | |
1866 | QString appId() const override; |
1867 | QString name() const override; |
1868 | |
1869 | === modified file 'plugins/Unity/Launcher/launchermodel.cpp' |
1870 | --- plugins/Unity/Launcher/launchermodel.cpp 2015-09-14 09:11:08 +0000 |
1871 | +++ plugins/Unity/Launcher/launchermodel.cpp 2016-03-11 11:34:41 +0000 |
1872 | @@ -103,7 +103,7 @@ |
1873 | LauncherItem *item = m_list.at(index); |
1874 | if (!item->focused()) { |
1875 | item->setAlerting(alerting); |
1876 | - Q_EMIT dataChanged(modelIndex, modelIndex, QVector<int>() << RoleAlerting); |
1877 | + Q_EMIT dataChanged(modelIndex, modelIndex, {RoleAlerting}); |
1878 | } |
1879 | } |
1880 | } |
1881 | @@ -389,7 +389,8 @@ |
1882 | if (countVisible && desktopFile.isValid()) { |
1883 | LauncherItem *item = new LauncherItem(appId, |
1884 | desktopFile.displayName(), |
1885 | - desktopFile.icon()); |
1886 | + desktopFile.icon(), |
1887 | + this); |
1888 | item->setCountVisible(true); |
1889 | beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); |
1890 | m_list.append(item); |
1891 | @@ -414,10 +415,19 @@ |
1892 | } else { |
1893 | int idx = m_list.indexOf(item); |
1894 | item->setName(desktopFile.displayName()); |
1895 | - item->setIcon(desktopFile.icon()); |
1896 | item->setPinned(item->pinned()); // update pinned text if needed |
1897 | item->setRunning(item->running()); |
1898 | - Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleIcon, RoleRunning}); |
1899 | + Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning}); |
1900 | + |
1901 | + const QString oldIcon = item->icon(); |
1902 | + if (oldIcon == desktopFile.icon()) { // same icon file, perhaps different contents, simulate changing the icon name to force reload |
1903 | + item->setIcon(QString()); |
1904 | + Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon}); |
1905 | + } |
1906 | + |
1907 | + // now set the icon for real |
1908 | + item->setIcon(desktopFile.icon()); |
1909 | + Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon}); |
1910 | } |
1911 | } |
1912 | |
1913 | @@ -489,7 +499,7 @@ |
1914 | if (idx >= 0) { |
1915 | LauncherItem *item = m_list.at(idx); |
1916 | setAlerting(item->appId(), true); |
1917 | - Q_EMIT dataChanged(index(idx), index(idx), QVector<int>() << RoleAlerting); |
1918 | + Q_EMIT dataChanged(index(idx), index(idx), {RoleAlerting}); |
1919 | } |
1920 | } |
1921 | |
1922 | |
1923 | === modified file 'plugins/Unity/Launcher/launchermodel.h' |
1924 | --- plugins/Unity/Launcher/launchermodel.h 2015-07-29 12:32:57 +0000 |
1925 | +++ plugins/Unity/Launcher/launchermodel.h 2016-03-11 11:34:41 +0000 |
1926 | @@ -38,7 +38,7 @@ |
1927 | Q_OBJECT |
1928 | |
1929 | public: |
1930 | - LauncherModel(QObject *parent = 0); |
1931 | + LauncherModel(QObject *parent = nullptr); |
1932 | ~LauncherModel(); |
1933 | |
1934 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; |
1935 | |
1936 | === modified file 'plugins/Utils/CMakeLists.txt' |
1937 | --- plugins/Utils/CMakeLists.txt 2016-02-08 09:37:48 +0000 |
1938 | +++ plugins/Utils/CMakeLists.txt 2016-03-11 11:34:41 +0000 |
1939 | @@ -23,6 +23,7 @@ |
1940 | windowstatestorage.cpp |
1941 | timezoneFormatter.cpp |
1942 | inputeventgenerator.cpp |
1943 | + deviceconfigparser.cpp |
1944 | plugin.cpp |
1945 | ) |
1946 | |
1947 | |
1948 | === added file 'plugins/Utils/deviceconfigparser.cpp' |
1949 | --- plugins/Utils/deviceconfigparser.cpp 1970-01-01 00:00:00 +0000 |
1950 | +++ plugins/Utils/deviceconfigparser.cpp 2016-03-11 11:34:41 +0000 |
1951 | @@ -0,0 +1,150 @@ |
1952 | +/* |
1953 | + * Copyright 2016 Canonical Ltd. |
1954 | + * |
1955 | + * This program is free software; you can redistribute it and/or modify |
1956 | + * it under the terms of the GNU Lesser General Public License as published by |
1957 | + * the Free Software Foundation; version 3. |
1958 | + * |
1959 | + * This program is distributed in the hope that it will be useful, |
1960 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1961 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1962 | + * GNU Lesser General Public License for more details. |
1963 | + * |
1964 | + * You should have received a copy of the GNU Lesser General Public License |
1965 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1966 | + */ |
1967 | + |
1968 | +#include "deviceconfigparser.h" |
1969 | + |
1970 | +#include <QSettings> |
1971 | +#include <QFileInfo> |
1972 | +#include <QDebug> |
1973 | +#include <QStandardPaths> |
1974 | + |
1975 | +DeviceConfigParser::DeviceConfigParser(QObject *parent): QObject(parent) |
1976 | +{ |
1977 | + QString path; |
1978 | + Q_FOREACH (const QString &standardPath, QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation)) { |
1979 | + if (QFileInfo(standardPath + "/devices.conf").exists()) { |
1980 | + path = standardPath + "/devices.conf"; |
1981 | + break; |
1982 | + } |
1983 | + } |
1984 | + |
1985 | + if (path.isEmpty()) { |
1986 | + path = "/etc/ubuntu/devices.conf"; |
1987 | + } |
1988 | + qDebug() << "Using" << path << "as device configuration file"; |
1989 | + m_config = new QSettings(path, QSettings::IniFormat, this); |
1990 | +} |
1991 | + |
1992 | +QString DeviceConfigParser::name() const |
1993 | +{ |
1994 | + return m_name; |
1995 | +} |
1996 | + |
1997 | +void DeviceConfigParser::setName(const QString &name) |
1998 | +{ |
1999 | + if (m_name == name) { |
2000 | + return; |
2001 | + } |
2002 | + m_name = name; |
2003 | + Q_EMIT changed(); |
2004 | +} |
2005 | + |
2006 | +Qt::ScreenOrientation DeviceConfigParser::primaryOrientation() const |
2007 | +{ |
2008 | + return stringToOrientation(readOrientationFromConfig("PrimaryOrientation"), Qt::PrimaryOrientation); |
2009 | +} |
2010 | + |
2011 | +Qt::ScreenOrientations DeviceConfigParser::supportedOrientations() const |
2012 | +{ |
2013 | + QStringList values = readOrientationsFromConfig("SupportedOrientations"); |
2014 | + if (values.isEmpty()) { |
2015 | + return Qt::PortraitOrientation |
2016 | + | Qt::InvertedPortraitOrientation |
2017 | + | Qt::LandscapeOrientation |
2018 | + | Qt::InvertedLandscapeOrientation; |
2019 | + } |
2020 | + |
2021 | + Qt::ScreenOrientations ret = Qt::PrimaryOrientation; |
2022 | + Q_FOREACH(const QString &orientationString, values) { |
2023 | + ret |= stringToOrientation(orientationString, Qt::PrimaryOrientation); |
2024 | + } |
2025 | + return ret; |
2026 | +} |
2027 | + |
2028 | +Qt::ScreenOrientation DeviceConfigParser::landscapeOrientation() const |
2029 | +{ |
2030 | + return stringToOrientation(readOrientationFromConfig("LandscapeOrientation"), Qt::LandscapeOrientation); |
2031 | +} |
2032 | + |
2033 | +Qt::ScreenOrientation DeviceConfigParser::invertedLandscapeOrientation() const |
2034 | +{ |
2035 | + return stringToOrientation(readOrientationFromConfig("InvertedLandscapeOrientation"), Qt::InvertedLandscapeOrientation); |
2036 | +} |
2037 | + |
2038 | +Qt::ScreenOrientation DeviceConfigParser::portraitOrientation() const |
2039 | +{ |
2040 | + return stringToOrientation(readOrientationFromConfig("PortraitOrientation"), Qt::PortraitOrientation); |
2041 | +} |
2042 | + |
2043 | +Qt::ScreenOrientation DeviceConfigParser::invertedPortraitOrientation() const |
2044 | +{ |
2045 | + return stringToOrientation(readOrientationFromConfig("InvertedPortraitOrientation"), Qt::InvertedPortraitOrientation); |
2046 | +} |
2047 | + |
2048 | +QString DeviceConfigParser::category() const |
2049 | +{ |
2050 | + QStringList supportedValues = {"phone", "tablet", "desktop"}; |
2051 | + m_config->beginGroup(m_name); |
2052 | + QString value = m_config->value("Category", "phone").toString(); |
2053 | + if (!supportedValues.contains(value)) { |
2054 | + qWarning().nospace().noquote() << "Unknown option \"" << value << "\" in " << m_config->fileName() |
2055 | + << ". Supported options are: " << supportedValues.join(", ") << "."; |
2056 | + return "phone"; |
2057 | + } |
2058 | + m_config->endGroup(); |
2059 | + return value; |
2060 | +} |
2061 | + |
2062 | +QStringList DeviceConfigParser::readOrientationsFromConfig(const QString &key) const |
2063 | +{ |
2064 | + m_config->beginGroup(m_name); |
2065 | + |
2066 | + QStringList ret; |
2067 | + if (m_config->contains(key)) { |
2068 | + ret = m_config->value(key).toStringList(); |
2069 | + } |
2070 | + |
2071 | + m_config->endGroup(); |
2072 | + return ret; |
2073 | +} |
2074 | + |
2075 | +QString DeviceConfigParser::readOrientationFromConfig(const QString &key) const |
2076 | +{ |
2077 | + QStringList ret = readOrientationsFromConfig(key); |
2078 | + return ret.count() > 0 ? ret.first() : QString(); |
2079 | +} |
2080 | + |
2081 | +Qt::ScreenOrientation DeviceConfigParser::stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const |
2082 | +{ |
2083 | + if (orientationString == "Landscape") { |
2084 | + return Qt::LandscapeOrientation; |
2085 | + } |
2086 | + if (orientationString == "InvertedLandscape") { |
2087 | + return Qt::InvertedLandscapeOrientation; |
2088 | + } |
2089 | + if (orientationString == "Portrait") { |
2090 | + return Qt::PortraitOrientation; |
2091 | + } |
2092 | + if (orientationString == "InvertedPortrait") { |
2093 | + return Qt::InvertedPortraitOrientation; |
2094 | + } |
2095 | + if (!orientationString.isEmpty()) { |
2096 | + // Some option we don't know. Give some hint on what went wrong. |
2097 | + qWarning().nospace().noquote() << "Unknown option \"" << orientationString << "\" in " << m_config->fileName() |
2098 | + << ". Supported options are: Landscape, InvertedLandscape, Portrait and InvertedPortrait."; |
2099 | + } |
2100 | + return defaultValue; |
2101 | +} |
2102 | |
2103 | === added file 'plugins/Utils/deviceconfigparser.h' |
2104 | --- plugins/Utils/deviceconfigparser.h 1970-01-01 00:00:00 +0000 |
2105 | +++ plugins/Utils/deviceconfigparser.h 2016-03-11 11:34:41 +0000 |
2106 | @@ -0,0 +1,62 @@ |
2107 | +/* |
2108 | + * Copyright 2016 Canonical Ltd. |
2109 | + * |
2110 | + * This program is free software; you can redistribute it and/or modify |
2111 | + * it under the terms of the GNU Lesser General Public License as published by |
2112 | + * the Free Software Foundation; version 3. |
2113 | + * |
2114 | + * This program is distributed in the hope that it will be useful, |
2115 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2116 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2117 | + * GNU Lesser General Public License for more details. |
2118 | + * |
2119 | + * You should have received a copy of the GNU Lesser General Public License |
2120 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2121 | + */ |
2122 | + |
2123 | +#ifndef DEVICECONFIGPARSER_H |
2124 | +#define DEVICECONFIGPARSER_H |
2125 | + |
2126 | +#include <QObject> |
2127 | +#include <QSettings> |
2128 | + |
2129 | +class DeviceConfigParser: public QObject |
2130 | +{ |
2131 | + Q_OBJECT |
2132 | + Q_PROPERTY(QString name READ name WRITE setName NOTIFY changed) |
2133 | + |
2134 | + Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY changed) |
2135 | + Q_PROPERTY(Qt::ScreenOrientations supportedOrientations READ supportedOrientations NOTIFY changed) |
2136 | + Q_PROPERTY(Qt::ScreenOrientation landscapeOrientation READ landscapeOrientation NOTIFY changed) |
2137 | + Q_PROPERTY(Qt::ScreenOrientation invertedLandscapeOrientation READ invertedLandscapeOrientation NOTIFY changed) |
2138 | + Q_PROPERTY(Qt::ScreenOrientation portraitOrientation READ portraitOrientation NOTIFY changed) |
2139 | + Q_PROPERTY(Qt::ScreenOrientation invertedPortraitOrientation READ invertedPortraitOrientation NOTIFY changed) |
2140 | + Q_PROPERTY(QString category READ category NOTIFY changed) |
2141 | + |
2142 | +public: |
2143 | + DeviceConfigParser(QObject *parent = nullptr); |
2144 | + |
2145 | + QString name() const; |
2146 | + void setName(const QString &name); |
2147 | + |
2148 | + Qt::ScreenOrientation primaryOrientation() const; |
2149 | + Qt::ScreenOrientations supportedOrientations() const; |
2150 | + Qt::ScreenOrientation landscapeOrientation() const; |
2151 | + Qt::ScreenOrientation invertedLandscapeOrientation() const; |
2152 | + Qt::ScreenOrientation portraitOrientation() const; |
2153 | + Qt::ScreenOrientation invertedPortraitOrientation() const; |
2154 | + QString category() const; |
2155 | + |
2156 | +Q_SIGNALS: |
2157 | + void changed(); |
2158 | + |
2159 | +private: |
2160 | + QString m_name; |
2161 | + QSettings *m_config; |
2162 | + |
2163 | + QStringList readOrientationsFromConfig(const QString &key) const; |
2164 | + QString readOrientationFromConfig(const QString &key) const; |
2165 | + Qt::ScreenOrientation stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const; |
2166 | +}; |
2167 | + |
2168 | +#endif |
2169 | |
2170 | === modified file 'plugins/Utils/plugin.cpp' |
2171 | --- plugins/Utils/plugin.cpp 2016-01-29 11:52:14 +0000 |
2172 | +++ plugins/Utils/plugin.cpp 2016-03-11 11:34:41 +0000 |
2173 | @@ -37,6 +37,7 @@ |
2174 | #include "timezoneFormatter.h" |
2175 | #include "applicationsfiltermodel.h" |
2176 | #include "inputeventgenerator.h" |
2177 | +#include "deviceconfigparser.h" |
2178 | |
2179 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) |
2180 | { |
2181 | @@ -70,6 +71,7 @@ |
2182 | qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger"); |
2183 | qmlRegisterType<ApplicationsFilterModel>(uri, 0, 1, "ApplicationsFilterModel"); |
2184 | qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator"); |
2185 | + qmlRegisterType<DeviceConfigParser>(uri, 0, 1, "DeviceConfigParser"); |
2186 | } |
2187 | |
2188 | void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) |
2189 | |
2190 | === modified file 'po/unity8.pot' |
2191 | --- po/unity8.pot 2016-03-08 21:04:17 +0000 |
2192 | +++ po/unity8.pot 2016-03-11 11:34:41 +0000 |
2193 | @@ -8,7 +8,7 @@ |
2194 | msgstr "" |
2195 | "Project-Id-Version: unity8\n" |
2196 | "Report-Msgid-Bugs-To: \n" |
2197 | -"POT-Creation-Date: 2016-03-08 21:04+0000\n" |
2198 | +"POT-Creation-Date: 2016-03-10 22:48+0000\n" |
2199 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
2200 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
2201 | "Language-Team: LANGUAGE <LL@li.org>\n" |
2202 | @@ -22,16 +22,16 @@ |
2203 | msgid "Password: " |
2204 | msgstr "" |
2205 | |
2206 | -#: plugins/Unity/Launcher/launcheritem.cpp:47 |
2207 | -#: plugins/Unity/Launcher/launcheritem.cpp:106 |
2208 | +#: plugins/Unity/Launcher/launcheritem.cpp:48 |
2209 | +#: plugins/Unity/Launcher/launcheritem.cpp:107 |
2210 | msgid "Pin shortcut" |
2211 | msgstr "" |
2212 | |
2213 | -#: plugins/Unity/Launcher/launcheritem.cpp:52 |
2214 | +#: plugins/Unity/Launcher/launcheritem.cpp:53 |
2215 | msgid "Quit" |
2216 | msgstr "" |
2217 | |
2218 | -#: plugins/Unity/Launcher/launcheritem.cpp:106 |
2219 | +#: plugins/Unity/Launcher/launcheritem.cpp:107 |
2220 | msgid "Unpin shortcut" |
2221 | msgstr "" |
2222 | |
2223 | @@ -135,15 +135,15 @@ |
2224 | msgid "Restart" |
2225 | msgstr "" |
2226 | |
2227 | -#: qml/Components/Lockscreen.qml:245 |
2228 | +#: qml/Components/Lockscreen.qml:231 |
2229 | msgid "Return to Call" |
2230 | msgstr "" |
2231 | |
2232 | -#: qml/Components/Lockscreen.qml:245 |
2233 | +#: qml/Components/Lockscreen.qml:231 |
2234 | msgid "Emergency Call" |
2235 | msgstr "" |
2236 | |
2237 | -#: qml/Components/Lockscreen.qml:277 |
2238 | +#: qml/Components/Lockscreen.qml:263 |
2239 | msgid "OK" |
2240 | msgstr "" |
2241 | |
2242 | @@ -152,6 +152,8 @@ |
2243 | msgstr "" |
2244 | |
2245 | #: qml/Components/ModeSwitchWarningDialog.qml:57 |
2246 | +msgctxt "" |
2247 | +"Re-dock means connect the device again to an external screen/mouse/keyboard" |
2248 | msgid "Re-dock, save your work and close these apps to continue." |
2249 | msgstr "" |
2250 | |
2251 | @@ -194,15 +196,15 @@ |
2252 | msgid "Add to Favorites" |
2253 | msgstr "" |
2254 | |
2255 | -#: qml/Dash/GenericScopeView.qml:565 qml/Dash/GenericScopeView.qml:723 |
2256 | +#: qml/Dash/GenericScopeView.qml:567 qml/Dash/GenericScopeView.qml:725 |
2257 | msgid "See less" |
2258 | msgstr "" |
2259 | |
2260 | -#: qml/Dash/GenericScopeView.qml:565 |
2261 | +#: qml/Dash/GenericScopeView.qml:567 |
2262 | msgid "See all" |
2263 | msgstr "" |
2264 | |
2265 | -#: qml/Dash/GenericScopeView.qml:627 |
2266 | +#: qml/Dash/GenericScopeView.qml:629 |
2267 | msgctxt "Label: Hint for dash search line edit" |
2268 | msgid "Search" |
2269 | msgstr "" |
2270 | @@ -228,7 +230,7 @@ |
2271 | msgid "Add a review" |
2272 | msgstr "" |
2273 | |
2274 | -#: qml/Dash/Previews/PreviewSharing.qml:50 |
2275 | +#: qml/Dash/Previews/PreviewSharing.qml:66 |
2276 | msgid "Preview Share Item" |
2277 | msgstr "" |
2278 | |
2279 | @@ -256,13 +258,13 @@ |
2280 | msgid "Also installed" |
2281 | msgstr "" |
2282 | |
2283 | -#: qml/DisabledScreenNotice.qml:87 |
2284 | +#: qml/DisabledScreenNotice.qml:104 |
2285 | msgid "" |
2286 | "Your device is now connected to an external display. Use this screen as a " |
2287 | -"touch pad to interact with the mouse." |
2288 | +"touch pad to interact with the pointer." |
2289 | msgstr "" |
2290 | |
2291 | -#: qml/Greeter/CoverPage.qml:107 |
2292 | +#: qml/Greeter/CoverPage.qml:118 |
2293 | msgid "Unlock" |
2294 | msgstr "" |
2295 | |
2296 | @@ -341,62 +343,62 @@ |
2297 | msgid "Conference" |
2298 | msgstr "" |
2299 | |
2300 | -#: qml/Panel/Indicators/MenuItemFactory.qml:753 |
2301 | +#: qml/Panel/Indicators/MenuItemFactory.qml:752 |
2302 | msgid "Nothing is playing" |
2303 | msgstr "" |
2304 | |
2305 | -#: qml/Panel/Indicators/MenuItemFactory.qml:882 |
2306 | +#: qml/Panel/Indicators/MenuItemFactory.qml:881 |
2307 | #, qt-format |
2308 | msgid "%1 hour" |
2309 | msgid_plural "%1 hours" |
2310 | msgstr[0] "" |
2311 | msgstr[1] "" |
2312 | |
2313 | -#: qml/Panel/Indicators/MenuItemFactory.qml:886 |
2314 | +#: qml/Panel/Indicators/MenuItemFactory.qml:885 |
2315 | #, qt-format |
2316 | msgid "%1 minute" |
2317 | msgid_plural "%1 minutes" |
2318 | msgstr[0] "" |
2319 | msgstr[1] "" |
2320 | |
2321 | -#: qml/Panel/Indicators/MenuItemFactory.qml:891 |
2322 | +#: qml/Panel/Indicators/MenuItemFactory.qml:890 |
2323 | #, qt-format |
2324 | msgid "%1 second" |
2325 | msgid_plural "%1 seconds" |
2326 | msgstr[0] "" |
2327 | msgstr[1] "" |
2328 | |
2329 | -#: qml/Panel/Indicators/MenuItemFactory.qml:894 |
2330 | +#: qml/Panel/Indicators/MenuItemFactory.qml:893 |
2331 | msgid "0 seconds" |
2332 | msgstr "" |
2333 | |
2334 | #. Translators: String like "1 hour, 2 minutes, 3 seconds remaining" |
2335 | -#: qml/Panel/Indicators/MenuItemFactory.qml:896 |
2336 | +#: qml/Panel/Indicators/MenuItemFactory.qml:895 |
2337 | #, qt-format |
2338 | msgid "%1 remaining" |
2339 | msgstr "" |
2340 | |
2341 | -#: qml/Panel/Indicators/MenuItemFactory.qml:902 |
2342 | +#: qml/Panel/Indicators/MenuItemFactory.qml:901 |
2343 | msgid "In queue…" |
2344 | msgstr "" |
2345 | |
2346 | -#: qml/Panel/Indicators/MenuItemFactory.qml:906 |
2347 | +#: qml/Panel/Indicators/MenuItemFactory.qml:905 |
2348 | msgid "Downloading" |
2349 | msgstr "" |
2350 | |
2351 | -#: qml/Panel/Indicators/MenuItemFactory.qml:908 |
2352 | +#: qml/Panel/Indicators/MenuItemFactory.qml:907 |
2353 | msgid "Paused, tap to resume" |
2354 | msgstr "" |
2355 | |
2356 | -#: qml/Panel/Indicators/MenuItemFactory.qml:910 |
2357 | +#: qml/Panel/Indicators/MenuItemFactory.qml:909 |
2358 | msgid "Canceled" |
2359 | msgstr "" |
2360 | |
2361 | -#: qml/Panel/Indicators/MenuItemFactory.qml:912 |
2362 | +#: qml/Panel/Indicators/MenuItemFactory.qml:911 |
2363 | msgid "Finished" |
2364 | msgstr "" |
2365 | |
2366 | -#: qml/Panel/Indicators/MenuItemFactory.qml:914 |
2367 | +#: qml/Panel/Indicators/MenuItemFactory.qml:913 |
2368 | msgid "Failed, tap to retry" |
2369 | msgstr "" |
2370 | |
2371 | |
2372 | === modified file 'qml/Components/EdgeBarrier.qml' |
2373 | --- qml/Components/EdgeBarrier.qml 2015-11-24 17:44:18 +0000 |
2374 | +++ qml/Components/EdgeBarrier.qml 2016-03-11 11:34:41 +0000 |
2375 | @@ -105,7 +105,7 @@ |
2376 | }, |
2377 | Transition { |
2378 | from: "resisting"; to: "passed" |
2379 | - UbuntuNumberAnimation { target: materialContainer; property: "opacity" } |
2380 | + UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration; target: materialContainer; property: "opacity" } |
2381 | } |
2382 | ] |
2383 | } |
2384 | |
2385 | === modified file 'qml/Components/InputMethod.qml' |
2386 | --- qml/Components/InputMethod.qml 2015-12-02 10:34:31 +0000 |
2387 | +++ qml/Components/InputMethod.qml 2016-03-11 11:34:41 +0000 |
2388 | @@ -22,15 +22,6 @@ |
2389 | Item { |
2390 | id: root |
2391 | |
2392 | - Connections { |
2393 | - target: SurfaceManager |
2394 | - onSurfaceCreated: { |
2395 | - if (surface.type == Mir.InputMethodType) { |
2396 | - surfaceItem.surface = surface; |
2397 | - } |
2398 | - } |
2399 | - } |
2400 | - |
2401 | property int transitionDuration: UbuntuAnimation.FastDuration |
2402 | |
2403 | MirSurfaceItem { |
2404 | @@ -41,6 +32,7 @@ |
2405 | |
2406 | surfaceWidth: width |
2407 | surfaceHeight: height |
2408 | + surface: SurfaceManager.inputMethodSurface |
2409 | |
2410 | onLiveChanged: { |
2411 | if (surface !== null && !live) { |
2412 | |
2413 | === modified file 'qml/Components/Lockscreen.qml' |
2414 | --- qml/Components/Lockscreen.qml 2015-07-15 15:07:19 +0000 |
2415 | +++ qml/Components/Lockscreen.qml 2016-03-11 11:34:41 +0000 |
2416 | @@ -121,107 +121,93 @@ |
2417 | opacity: root.darkenBackground |
2418 | } |
2419 | |
2420 | - MouseArea { |
2421 | - anchors.fill: root |
2422 | - onClicked: { |
2423 | - if (pinPadLoader.item) |
2424 | - pinPadLoader.item.forceActiveFocus() |
2425 | - } |
2426 | - } |
2427 | - |
2428 | - FocusScope { |
2429 | - id: loaderScope |
2430 | + Loader { |
2431 | + id: pinPadLoader |
2432 | + objectName: "pinPadLoader" |
2433 | anchors.fill: parent |
2434 | - |
2435 | - Loader { |
2436 | - id: pinPadLoader |
2437 | - objectName: "pinPadLoader" |
2438 | - anchors.fill: parent |
2439 | - property bool resetting: false |
2440 | - property bool waiting: false |
2441 | - property bool showWrongText: false |
2442 | - |
2443 | - source: { |
2444 | - if (resetting || !root.required) { |
2445 | - return "" |
2446 | - } else if (root.delayMinutes > 0) { |
2447 | - return "DelayedLockscreen.qml" |
2448 | - } else if (root.alphaNumeric) { |
2449 | - return "PassphraseLockscreen.qml" |
2450 | - } else { |
2451 | - return "PinLockscreen.qml" |
2452 | - } |
2453 | - } |
2454 | - onSourceChanged: { |
2455 | - waiting = false |
2456 | - showWrongText = false |
2457 | - if (loaderScope.activeFocus && pinPadLoader.item) |
2458 | - pinPadLoader.item.forceActiveFocus() |
2459 | - } |
2460 | - |
2461 | - Connections { |
2462 | - target: pinPadLoader.item |
2463 | - |
2464 | - onEntered: { |
2465 | - pinPadLoader.waiting = true |
2466 | - root.entered(passphrase); |
2467 | - } |
2468 | - |
2469 | - onCancel: { |
2470 | - root.cancel() |
2471 | - } |
2472 | - } |
2473 | - |
2474 | - Binding { |
2475 | - target: pinPadLoader.item |
2476 | - property: "minPinLength" |
2477 | - value: root.minPinLength |
2478 | - } |
2479 | - Binding { |
2480 | - target: pinPadLoader.item |
2481 | - property: "maxPinLength" |
2482 | - value: root.maxPinLength |
2483 | - } |
2484 | - Binding { |
2485 | - target: pinPadLoader.item |
2486 | - property: "infoText" |
2487 | - value: root.infoText |
2488 | - } |
2489 | - Binding { |
2490 | - target: pinPadLoader.item |
2491 | - property: "retryText" |
2492 | - value: root.retryText |
2493 | - } |
2494 | - Binding { |
2495 | - target: pinPadLoader.item |
2496 | - property: "errorText" |
2497 | - value: pinPadLoader.showWrongText ? root.errorText : "" |
2498 | - } |
2499 | - Binding { |
2500 | - target: pinPadLoader.item |
2501 | - property: "entryEnabled" |
2502 | - value: !pinPadLoader.waiting |
2503 | - } |
2504 | - Binding { |
2505 | - target: pinPadLoader.item |
2506 | - property: "alphaNumeric" |
2507 | - value: root.alphaNumeric |
2508 | - } |
2509 | - Binding { |
2510 | - target: pinPadLoader.item |
2511 | - property: "delayMinutes" |
2512 | - value: root.delayMinutes |
2513 | - } |
2514 | - Binding { |
2515 | - target: pinPadLoader.item |
2516 | - property: "showCancelButton" |
2517 | - value: root.showCancelButton |
2518 | - } |
2519 | - Binding { |
2520 | - target: pinPadLoader.item |
2521 | - property: "foregroundColor" |
2522 | - value: root.foregroundColor |
2523 | - } |
2524 | + property bool resetting: false |
2525 | + property bool waiting: false |
2526 | + property bool showWrongText: false |
2527 | + focus: true |
2528 | + |
2529 | + source: { |
2530 | + if (resetting || !root.required) { |
2531 | + return "" |
2532 | + } else if (root.delayMinutes > 0) { |
2533 | + return "DelayedLockscreen.qml" |
2534 | + } else if (root.alphaNumeric) { |
2535 | + return "PassphraseLockscreen.qml" |
2536 | + } else { |
2537 | + return "PinLockscreen.qml" |
2538 | + } |
2539 | + } |
2540 | + onSourceChanged: { |
2541 | + waiting = false |
2542 | + showWrongText = false |
2543 | + } |
2544 | + |
2545 | + Connections { |
2546 | + target: pinPadLoader.item |
2547 | + |
2548 | + onEntered: { |
2549 | + pinPadLoader.waiting = true |
2550 | + root.entered(passphrase); |
2551 | + } |
2552 | + |
2553 | + onCancel: { |
2554 | + root.cancel() |
2555 | + } |
2556 | + } |
2557 | + |
2558 | + Binding { |
2559 | + target: pinPadLoader.item |
2560 | + property: "minPinLength" |
2561 | + value: root.minPinLength |
2562 | + } |
2563 | + Binding { |
2564 | + target: pinPadLoader.item |
2565 | + property: "maxPinLength" |
2566 | + value: root.maxPinLength |
2567 | + } |
2568 | + Binding { |
2569 | + target: pinPadLoader.item |
2570 | + property: "infoText" |
2571 | + value: root.infoText |
2572 | + } |
2573 | + Binding { |
2574 | + target: pinPadLoader.item |
2575 | + property: "retryText" |
2576 | + value: root.retryText |
2577 | + } |
2578 | + Binding { |
2579 | + target: pinPadLoader.item |
2580 | + property: "errorText" |
2581 | + value: pinPadLoader.showWrongText ? root.errorText : "" |
2582 | + } |
2583 | + Binding { |
2584 | + target: pinPadLoader.item |
2585 | + property: "entryEnabled" |
2586 | + value: !pinPadLoader.waiting |
2587 | + } |
2588 | + Binding { |
2589 | + target: pinPadLoader.item |
2590 | + property: "alphaNumeric" |
2591 | + value: root.alphaNumeric |
2592 | + } |
2593 | + Binding { |
2594 | + target: pinPadLoader.item |
2595 | + property: "delayMinutes" |
2596 | + value: root.delayMinutes |
2597 | + } |
2598 | + Binding { |
2599 | + target: pinPadLoader.item |
2600 | + property: "showCancelButton" |
2601 | + value: root.showCancelButton |
2602 | + } |
2603 | + Binding { |
2604 | + target: pinPadLoader.item |
2605 | + property: "foregroundColor" |
2606 | + value: root.foregroundColor |
2607 | } |
2608 | } |
2609 | |
2610 | |
2611 | === modified file 'qml/Components/ModeSwitchWarningDialog.qml' |
2612 | --- qml/Components/ModeSwitchWarningDialog.qml 2015-11-25 13:57:34 +0000 |
2613 | +++ qml/Components/ModeSwitchWarningDialog.qml 2016-03-11 11:34:41 +0000 |
2614 | @@ -54,7 +54,7 @@ |
2615 | } |
2616 | |
2617 | Label { |
2618 | - text: i18n.tr("Re-dock, save your work and close these apps to continue.") |
2619 | + 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.") |
2620 | wrapMode: Text.WordWrap |
2621 | color: "#888888" |
2622 | } |
2623 | |
2624 | === modified file 'qml/Components/PassphraseLockscreen.qml' |
2625 | --- qml/Components/PassphraseLockscreen.qml 2015-07-15 15:07:19 +0000 |
2626 | +++ qml/Components/PassphraseLockscreen.qml 2016-03-11 11:34:41 +0000 |
2627 | @@ -18,10 +18,11 @@ |
2628 | import Ubuntu.Components 1.3 |
2629 | import "../Components" |
2630 | |
2631 | -Item { |
2632 | +FocusScope { |
2633 | id: root |
2634 | y: units.gu(4) |
2635 | height: shakeContainer.height |
2636 | + focus: true |
2637 | |
2638 | property string infoText |
2639 | property string errorText |
2640 | @@ -42,8 +43,6 @@ |
2641 | } |
2642 | } |
2643 | |
2644 | - onActiveFocusChanged: if (activeFocus) pinentryField.forceActiveFocus() |
2645 | - |
2646 | Column { |
2647 | id: shakeContainer |
2648 | anchors.horizontalCenter: parent.horizontalCenter |
2649 | @@ -59,14 +58,16 @@ |
2650 | text: root.infoText |
2651 | } |
2652 | |
2653 | - Item { |
2654 | + FocusScope { |
2655 | id: entryContainer |
2656 | anchors { left: parent.left; right: parent.right; margins: units.gu(2) } |
2657 | height: units.gu(4) |
2658 | + focus: true |
2659 | |
2660 | TextInput { |
2661 | id: pinentryField |
2662 | objectName: "pinentryField" |
2663 | + focus: true |
2664 | |
2665 | property bool incorrectOverride: false |
2666 | |
2667 | |
2668 | === modified file 'qml/Components/PhysicalKeysMapper.qml' |
2669 | --- qml/Components/PhysicalKeysMapper.qml 2016-01-13 18:43:34 +0000 |
2670 | +++ qml/Components/PhysicalKeysMapper.qml 2016-03-11 11:34:41 +0000 |
2671 | @@ -42,12 +42,15 @@ |
2672 | signal screenshotTriggered; |
2673 | |
2674 | readonly property bool altTabPressed: d.altTabPressed |
2675 | + readonly property bool superPressed: d.superPressed |
2676 | + readonly property bool superTabPressed: d.superTabPressed |
2677 | |
2678 | property int powerKeyLongPressTime: 2000 |
2679 | |
2680 | // For testing. If running windowed (e.g. tryShell), Alt+Tab is taken by the |
2681 | // running desktop, set this to true to use Ctrl+Tab instead. |
2682 | property bool controlInsteadOfAlt: false |
2683 | + property bool controlInsteadOfSuper: false |
2684 | |
2685 | QtObject { |
2686 | id: d |
2687 | @@ -59,6 +62,9 @@ |
2688 | property bool altPressed: false |
2689 | property bool altTabPressed: false |
2690 | |
2691 | + property bool superPressed: false |
2692 | + property bool superTabPressed: false |
2693 | + |
2694 | property var powerButtonPressStart: 0 |
2695 | |
2696 | // We need to eat ALT presses until we know what they're for (Alt+Tab or going to the app?) |
2697 | @@ -119,11 +125,23 @@ |
2698 | event.accepted = true; |
2699 | d.altPressInjected = false; |
2700 | } |
2701 | + |
2702 | + // Adding MetaModifier here because that's what keyboards do. Pressing Super_L actually gives |
2703 | + // Super_L + MetaModifier. This helps to make sure we only invoke superPressed if no other |
2704 | + // Modifier is pressed too. |
2705 | + } else if (((event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R) && event.modifiers === Qt.MetaModifier) |
2706 | + || (root.controlInsteadOfSuper && event.key == Qt.Key_Control) |
2707 | + ) { |
2708 | + d.superPressed = true; |
2709 | } else if (event.key == Qt.Key_Tab) { |
2710 | if (d.altPressed && !d.altTabPressed) { |
2711 | d.altTabPressed = true; |
2712 | event.accepted = true; |
2713 | } |
2714 | + if (d.superPressed && !d.superTabPressed) { |
2715 | + d.superTabPressed = true; |
2716 | + event.accepted = true; |
2717 | + } |
2718 | } |
2719 | } |
2720 | |
2721 | @@ -154,6 +172,12 @@ |
2722 | if (d.altTabPressed) { |
2723 | event.accepted = true; |
2724 | } |
2725 | + } else if (event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)) { |
2726 | + d.superPressed = false; |
2727 | + if (d.superTabPressed) { |
2728 | + d.superTabPressed = false; |
2729 | + event.accepted = true; |
2730 | + } |
2731 | } |
2732 | } |
2733 | } |
2734 | |
2735 | === modified file 'qml/Components/PinLockscreen.qml' |
2736 | --- qml/Components/PinLockscreen.qml 2015-07-15 15:07:19 +0000 |
2737 | +++ qml/Components/PinLockscreen.qml 2016-03-11 11:34:41 +0000 |
2738 | @@ -19,8 +19,9 @@ |
2739 | import Ubuntu.Components.ListItems 1.3 |
2740 | import "../Components" |
2741 | |
2742 | -Item { |
2743 | +FocusScope { |
2744 | id: root |
2745 | + focus: true |
2746 | |
2747 | property string infoText |
2748 | property string retryText |
2749 | @@ -45,6 +46,24 @@ |
2750 | } |
2751 | } |
2752 | |
2753 | + Keys.onPressed: { |
2754 | + if (pinentryField.text.length == root.maxPinLength) |
2755 | + return; |
2756 | + |
2757 | + if (event.key === Qt.Key_Backspace) { |
2758 | + pinentryField.backspace(); |
2759 | + } else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Escape) { |
2760 | + closeButton.clicked() |
2761 | + } else if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { |
2762 | + confirmButton.clicked() |
2763 | + } else { |
2764 | + var digit = parseInt(event.text); |
2765 | + if (!isNaN(digit) && typeof digit == "number") { |
2766 | + pinentryField.appendNumber(digit); |
2767 | + } |
2768 | + } |
2769 | + } |
2770 | + |
2771 | Column { |
2772 | anchors { |
2773 | left: parent.left; |
2774 | @@ -204,6 +223,7 @@ |
2775 | width: numbersGrid.buttonWidth |
2776 | } |
2777 | PinPadButton { |
2778 | + id: closeButton |
2779 | iconName: "close" |
2780 | height: units.gu(5) // visual spec has this row a little closer in |
2781 | width: numbersGrid.buttonWidth |
2782 | @@ -216,6 +236,7 @@ |
2783 | width: numbersGrid.buttonWidth |
2784 | } |
2785 | PinPadButton { |
2786 | + id: confirmButton |
2787 | iconName: "tick" |
2788 | objectName: "confirmButton" |
2789 | height: units.gu(5) |
2790 | |
2791 | === modified file 'qml/Components/ShellDialog.qml' |
2792 | --- qml/Components/ShellDialog.qml 2015-11-06 10:06:58 +0000 |
2793 | +++ qml/Components/ShellDialog.qml 2016-03-11 11:34:41 +0000 |
2794 | @@ -37,7 +37,15 @@ |
2795 | |
2796 | focus: true |
2797 | |
2798 | + // FIXME: this is a hack because Dialog subtheming seems broken atm |
2799 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1555548 |
2800 | + ThemeSettings { |
2801 | + id: themeHack |
2802 | + name: "Ubuntu.Components.Themes.Ambiance" |
2803 | + } |
2804 | + |
2805 | Component.onCompleted: { |
2806 | + __foreground.theme = themeHack |
2807 | show(); |
2808 | } |
2809 | } |
2810 | |
2811 | === modified file 'qml/Dash/CardCarousel.qml' |
2812 | --- qml/Dash/CardCarousel.qml 2016-01-28 14:11:14 +0000 |
2813 | +++ qml/Dash/CardCarousel.qml 2016-03-11 11:34:41 +0000 |
2814 | @@ -66,7 +66,6 @@ |
2815 | item.cardData = Qt.binding(function() { return model; }); |
2816 | item.fontScale = Qt.binding(function() { return carousel.fontScale; }); |
2817 | item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; }); |
2818 | - item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; }); |
2819 | item.artShapeStyle = "shadow"; |
2820 | item.scopeStyle = cardCarousel.scopeStyle; |
2821 | } |
2822 | |
2823 | === modified file 'qml/Dash/CardGrid.qml' |
2824 | --- qml/Dash/CardGrid.qml 2016-02-02 08:47:07 +0000 |
2825 | +++ qml/Dash/CardGrid.qml 2016-03-11 11:34:41 +0000 |
2826 | @@ -70,7 +70,6 @@ |
2827 | item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; }); |
2828 | item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; }); |
2829 | item.cardData = Qt.binding(function() { return model; }); |
2830 | - item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; }); |
2831 | item.scopeStyle = root.scopeStyle; |
2832 | item.artShapeStyle = root.artShapeStyle; |
2833 | item.backgroundShapeStyle = root.backgroundShapeStyle; |
2834 | |
2835 | === modified file 'qml/Dash/CardHorizontalList.qml' |
2836 | --- qml/Dash/CardHorizontalList.qml 2016-01-28 14:11:14 +0000 |
2837 | +++ qml/Dash/CardHorizontalList.qml 2016-03-11 11:34:41 +0000 |
2838 | @@ -53,7 +53,6 @@ |
2839 | item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; }); |
2840 | item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; }); |
2841 | item.cardData = Qt.binding(function() { return model; }); |
2842 | - item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; }); |
2843 | item.scopeStyle = root.scopeStyle; |
2844 | } |
2845 | Connections { |
2846 | |
2847 | === modified file 'qml/Dash/CardTool.qml' |
2848 | --- qml/Dash/CardTool.qml 2016-01-28 14:11:14 +0000 |
2849 | +++ qml/Dash/CardTool.qml 2016-03-11 11:34:41 +0000 |
2850 | @@ -66,7 +66,7 @@ |
2851 | return layout; |
2852 | } |
2853 | |
2854 | - property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components); |
2855 | + property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, false); |
2856 | |
2857 | // FIXME: Saviq |
2858 | // Only way for the card below to actually be laid out completely. |
2859 | @@ -139,29 +139,6 @@ |
2860 | readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0 |
2861 | property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0 |
2862 | |
2863 | - /*! |
2864 | - \brief Desired alignment of title |
2865 | - */ |
2866 | - readonly property int titleAlignment: { |
2867 | - if (template["card-layout"] === "horizontal" |
2868 | - || typeof components["title"] !== "object" |
2869 | - || components["title"]["align"] === "left") return Text.AlignLeft; |
2870 | - |
2871 | - var keys = ["mascot", "emblem", "subtitle", "attributes", "summary"]; |
2872 | - |
2873 | - for (var key in keys) { |
2874 | - key = keys[key]; |
2875 | - try { |
2876 | - if (typeof components[key] === "string" |
2877 | - || typeof components[key]["field"] === "string") return Text.AlignLeft; |
2878 | - } catch (e) { |
2879 | - continue; |
2880 | - } |
2881 | - } |
2882 | - |
2883 | - return Text.AlignHCenter; |
2884 | - } |
2885 | - |
2886 | QtObject { |
2887 | id: carouselTool |
2888 | |
2889 | @@ -216,10 +193,9 @@ |
2890 | "summary": "—\n—\n—\n—\n—", |
2891 | "attributes": attributesModel.model |
2892 | } |
2893 | - sourceComponent: cardTool.cardComponent |
2894 | + sourceComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, true); |
2895 | onLoaded: { |
2896 | item.objectName = "cardToolCard"; |
2897 | - item.asynchronous = false; |
2898 | item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; }); |
2899 | item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; }); |
2900 | } |
2901 | |
2902 | === modified file 'qml/Dash/CardVerticalJournal.qml' |
2903 | --- qml/Dash/CardVerticalJournal.qml 2016-01-28 14:11:14 +0000 |
2904 | +++ qml/Dash/CardVerticalJournal.qml 2016-03-11 11:34:41 +0000 |
2905 | @@ -72,7 +72,6 @@ |
2906 | item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; }); |
2907 | item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; }); |
2908 | item.cardData = Qt.binding(function() { return model; }); |
2909 | - item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; }); |
2910 | item.scopeStyle = root.scopeStyle; |
2911 | } |
2912 | Connections { |
2913 | |
2914 | === modified file 'qml/Dash/Dash.qml' |
2915 | --- qml/Dash/Dash.qml 2015-11-19 16:55:31 +0000 |
2916 | +++ qml/Dash/Dash.qml 2016-03-11 11:34:41 +0000 |
2917 | @@ -37,6 +37,7 @@ |
2918 | } |
2919 | |
2920 | property bool windowActive: window.active |
2921 | + property bool showOverlayScope: false |
2922 | |
2923 | DashCommunicatorService { |
2924 | objectName: "dashCommunicatorService" |
2925 | @@ -80,7 +81,7 @@ |
2926 | return |
2927 | } |
2928 | |
2929 | - closeOverlayScope(); |
2930 | + dash.showOverlayScope = false; |
2931 | |
2932 | dashContent.closePreview(); |
2933 | |
2934 | @@ -93,12 +94,6 @@ |
2935 | dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset) |
2936 | } |
2937 | |
2938 | - function closeOverlayScope() { |
2939 | - if (dashContent.x != 0) { |
2940 | - dashContent.x = 0; |
2941 | - } |
2942 | - } |
2943 | - |
2944 | Scopes { |
2945 | id: scopes |
2946 | } |
2947 | @@ -133,12 +128,13 @@ |
2948 | height: dash.height |
2949 | scopes: scopes |
2950 | visible: x != -width |
2951 | + x: dash.showOverlayScope ? -width : 0 |
2952 | onGotoScope: { |
2953 | dash.setCurrentScope(scopeId, true, false); |
2954 | } |
2955 | onOpenScope: { |
2956 | scopeItem.scope = scope; |
2957 | - x = -width; |
2958 | + dash.showOverlayScope = true; |
2959 | } |
2960 | Behavior on x { |
2961 | UbuntuNumberAnimation { |
2962 | @@ -207,7 +203,7 @@ |
2963 | bottomEdgeController.enableAnimation = true; |
2964 | bottomEdgeController.progress = 0; |
2965 | scopeItem.scope = scope; |
2966 | - dashContent.x = -dashContent.width; |
2967 | + dash.showOverlayScope = true; |
2968 | } |
2969 | onGotoScope: { |
2970 | bottomEdgeController.enableAnimation = true; |
2971 | @@ -226,7 +222,7 @@ |
2972 | id: scopeItem |
2973 | objectName: "dashTempScopeItem" |
2974 | |
2975 | - x: dashContent.x + width |
2976 | + x: dash.showOverlayScope ? 0 : width |
2977 | y: dashContent.y |
2978 | width: parent.width |
2979 | height: parent.height |
2980 | @@ -234,7 +230,7 @@ |
2981 | hasBackAction: true |
2982 | isCurrent: visible |
2983 | onBackClicked: { |
2984 | - closeOverlayScope(); |
2985 | + dash.showOverlayScope = false; |
2986 | closePreview(); |
2987 | } |
2988 | |
2989 | @@ -250,6 +246,10 @@ |
2990 | scopes.closeScope(oldScope); |
2991 | } |
2992 | } |
2993 | + |
2994 | + Behavior on x { |
2995 | + UbuntuNumberAnimation { } |
2996 | + } |
2997 | } |
2998 | |
2999 | Rectangle { |
3000 | |
3001 | === modified file 'qml/Dash/GenericScopeView.qml' |
3002 | --- qml/Dash/GenericScopeView.qml 2016-02-19 11:50:12 +0000 |
3003 | +++ qml/Dash/GenericScopeView.qml 2016-03-11 11:34:41 +0000 |
3004 | @@ -370,6 +370,8 @@ |
3005 | } else { |
3006 | cardTool.cardWidth = units.gu(10); |
3007 | } |
3008 | + } else { |
3009 | + cardTool.cardWidth = units.gu(12); |
3010 | } |
3011 | item.minimumHorizontalSpacing = item.defaultMinimumHorizontalSpacing; |
3012 | } |
3013 | |
3014 | === modified file 'qml/Dash/Previews/PreviewHeader.qml' |
3015 | --- qml/Dash/Previews/PreviewHeader.qml 2016-01-08 14:19:08 +0000 |
3016 | +++ qml/Dash/Previews/PreviewHeader.qml 2016-03-11 11:34:41 +0000 |
3017 | @@ -25,6 +25,7 @@ |
3018 | * The mascot fall back image comes in widgetData["fallback"] |
3019 | * The subtitle comes in widgetData["subtitle"] |
3020 | * The attributes comes in widgetData["attributes"] |
3021 | + * The emblem comes in widgetData["emblem"] |
3022 | */ |
3023 | |
3024 | PreviewWidget { |
3025 | @@ -40,6 +41,7 @@ |
3026 | readonly property string title: root.widgetData["title"] || "" |
3027 | readonly property string subtitle: root.widgetData["subtitle"] || "" |
3028 | readonly property var attributes: root.widgetData["attributes"] || null |
3029 | + readonly property url emblem: root.widgetData["emblem"] || "" |
3030 | readonly property color fontColor: root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText |
3031 | |
3032 | // Rewire the source since we may have unwired it on onStatusChanged |
3033 | @@ -98,16 +100,42 @@ |
3034 | spacing: units.dp(2) |
3035 | anchors.verticalCenter: parent.verticalCenter |
3036 | |
3037 | - Label { |
3038 | - id: titleLabel |
3039 | - objectName: "titleLabel" |
3040 | + Item { |
3041 | anchors { left: parent.left; right: parent.right } |
3042 | - elide: Text.ElideRight |
3043 | - font.weight: Font.Normal |
3044 | - fontSize: "large" |
3045 | - wrapMode: Text.Wrap |
3046 | - color: headerRoot.fontColor |
3047 | - text: headerRoot.title |
3048 | + height: titleLabel.height |
3049 | + |
3050 | + Label { |
3051 | + id: titleLabel |
3052 | + objectName: "titleLabel" |
3053 | + anchors { |
3054 | + left: parent.left; |
3055 | + right: iconLoader.right |
3056 | + rightMargin: iconLoader.width > 0 ? units.gu(0.5) : 0 |
3057 | + } |
3058 | + elide: Text.ElideRight |
3059 | + font.weight: Font.Normal |
3060 | + fontSize: "large" |
3061 | + wrapMode: Text.Wrap |
3062 | + color: headerRoot.fontColor |
3063 | + text: headerRoot.title |
3064 | + } |
3065 | + |
3066 | + Loader { |
3067 | + id: iconLoader |
3068 | + active: headerRoot.emblem != "" |
3069 | + anchors { |
3070 | + bottom: titleLabel.baseline |
3071 | + right: parent.right |
3072 | + } |
3073 | + sourceComponent: Icon { |
3074 | + objectName: "emblemIcon" |
3075 | + source: headerRoot.emblem |
3076 | + color: headerRoot.fontColor |
3077 | + height: source != "" ? titleLabel.font.pixelSize : 0 |
3078 | + // FIXME Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293 |
3079 | + width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth |
3080 | + } |
3081 | + } |
3082 | } |
3083 | |
3084 | Loader { |
3085 | |
3086 | === modified file 'qml/Dash/Previews/PreviewOverlay.qml' |
3087 | --- qml/Dash/Previews/PreviewOverlay.qml 2015-07-15 15:07:19 +0000 |
3088 | +++ qml/Dash/Previews/PreviewOverlay.qml 2016-03-11 11:34:41 +0000 |
3089 | @@ -158,7 +158,7 @@ |
3090 | anchors.centerIn: parent |
3091 | width: units.gu(2.5) |
3092 | height: width |
3093 | - color: theme.palette.normal.foregroundText |
3094 | + color: "white" |
3095 | name: "close" |
3096 | } |
3097 | } |
3098 | |
3099 | === modified file 'qml/Dash/Previews/PreviewSharing.qml' |
3100 | --- qml/Dash/Previews/PreviewSharing.qml 2015-12-17 15:42:39 +0000 |
3101 | +++ qml/Dash/Previews/PreviewSharing.qml 2016-03-11 11:34:41 +0000 |
3102 | @@ -44,6 +44,22 @@ |
3103 | } |
3104 | } |
3105 | |
3106 | + function createExportedItems(url) { |
3107 | + var items = new Array(); |
3108 | + if (typeof url === "string") { |
3109 | + var exportItem = exportItemComponent.createObject(); |
3110 | + exportItem.url = url; |
3111 | + items.push(exportItem); |
3112 | + } else { |
3113 | + for (var i = 0; i < url.length; i++) { |
3114 | + var exportItem = exportItemComponent.createObject(); |
3115 | + exportItem.url = url[i]; |
3116 | + items.push(exportItem); |
3117 | + } |
3118 | + } |
3119 | + return items; |
3120 | + } |
3121 | + |
3122 | Component { |
3123 | id: exportItemComponent |
3124 | ContentItem { |
3125 | @@ -76,13 +92,7 @@ |
3126 | onPeerSelected: { |
3127 | var transfer = peer.request(); |
3128 | if (transfer.state === ContentTransfer.InProgress) { |
3129 | - var items = new Array(); |
3130 | - for (var i = 0; i < url.length; i++) { |
3131 | - var exportItem = exportItemComponent.createObject(); |
3132 | - exportItem.url = url[i]; |
3133 | - items.push(exportItem); |
3134 | - } |
3135 | - transfer.items = items; |
3136 | + transfer.items = createExportedItems(url); |
3137 | transfer.state = ContentTransfer.Charged; |
3138 | } |
3139 | peerPicker.visible = false; |
3140 | |
3141 | === modified file 'qml/Dash/ScopesListCategoryItem.qml' |
3142 | --- qml/Dash/ScopesListCategoryItem.qml 2015-11-04 14:57:13 +0000 |
3143 | +++ qml/Dash/ScopesListCategoryItem.qml 2016-03-11 11:34:41 +0000 |
3144 | @@ -18,7 +18,7 @@ |
3145 | import QtQuick.Layouts 1.1 |
3146 | import Ubuntu.Components 1.3 |
3147 | |
3148 | -MouseArea { |
3149 | +AbstractButton { |
3150 | id: root |
3151 | |
3152 | signal requestFavorite(string scopeId, bool favorite) |
3153 | @@ -84,15 +84,19 @@ |
3154 | visible: text != "" |
3155 | } |
3156 | } |
3157 | - MouseArea { |
3158 | + AbstractButton { |
3159 | id: starArea |
3160 | objectName: "starArea" |
3161 | height: parent.height |
3162 | width: height |
3163 | anchors.right: parent.right |
3164 | onClicked: if (!editMode) root.requestFavorite(model.scopeId, !isFavorite); |
3165 | - onPressed: if (editMode) root.handlePressed(starArea); |
3166 | - onReleased: if (editMode) root.handleReleased(starArea); |
3167 | + onPressedChanged: { |
3168 | + if (editMode) { |
3169 | + if (pressed) root.handlePressed(starArea.__mouseArea); |
3170 | + else root.handleReleased(starArea.__mouseArea); |
3171 | + } |
3172 | + } |
3173 | visible: editMode || showStar |
3174 | Icon { |
3175 | id: star |
3176 | |
3177 | === modified file 'qml/DeviceConfiguration.qml' |
3178 | --- qml/DeviceConfiguration.qml 2015-12-01 13:56:54 +0000 |
3179 | +++ qml/DeviceConfiguration.qml 2016-03-11 11:34:41 +0000 |
3180 | @@ -1,5 +1,5 @@ |
3181 | /* |
3182 | - * Copyright (C) 2015 Canonical, Ltd. |
3183 | + * Copyright (C) 2015-2016 Canonical, Ltd. |
3184 | * |
3185 | * This program is free software; you can redistribute it and/or modify |
3186 | * it under the terms of the GNU General Public License as published by |
3187 | @@ -15,6 +15,7 @@ |
3188 | */ |
3189 | |
3190 | import QtQuick 2.4 |
3191 | +import Utils 0.1 |
3192 | |
3193 | QtObject { |
3194 | id: root |
3195 | @@ -34,57 +35,83 @@ |
3196 | |
3197 | readonly property alias category: priv.category |
3198 | |
3199 | + readonly property var deviceConfigParser: DeviceConfigParser { |
3200 | + name: root.name |
3201 | + } |
3202 | + |
3203 | readonly property var priv: StateGroup { |
3204 | id: priv |
3205 | |
3206 | - property int primaryOrientation: root.useNativeOrientation |
3207 | - |
3208 | - property int supportedOrientations: Qt.PortraitOrientation |
3209 | - | Qt.InvertedPortraitOrientation |
3210 | - | Qt.LandscapeOrientation |
3211 | - | Qt.InvertedLandscapeOrientation |
3212 | - |
3213 | - property int landscapeOrientation: Qt.LandscapeOrientation |
3214 | - property int invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation |
3215 | - property int portraitOrientation: Qt.PortraitOrientation |
3216 | - property int invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3217 | - |
3218 | - // Supported values so far: |
3219 | - // "phone", "tablet" or "desktop" |
3220 | - property string category: "phone" |
3221 | + property int primaryOrientation: deviceConfigParser.primaryOrientation == Qt.PrimaryOrientation ? |
3222 | + root.useNativeOrientation : deviceConfigParser.primaryOrientation |
3223 | + |
3224 | + property int supportedOrientations: deviceConfigParser.supportedOrientations |
3225 | + |
3226 | + property int landscapeOrientation: deviceConfigParser.landscapeOrientation |
3227 | + property int invertedLandscapeOrientation: deviceConfigParser.invertedLandscapeOrientation |
3228 | + property int portraitOrientation: deviceConfigParser.portraitOrientation |
3229 | + property int invertedPortraitOrientation: deviceConfigParser.invertedPortraitOrientation |
3230 | + property string category: deviceConfigParser.category |
3231 | |
3232 | states: [ |
3233 | State { |
3234 | name: "mako" |
3235 | PropertyChanges { |
3236 | target: priv |
3237 | + primaryOrientation: root.useNativeOrientation |
3238 | supportedOrientations: Qt.PortraitOrientation |
3239 | | Qt.LandscapeOrientation |
3240 | | Qt.InvertedLandscapeOrientation |
3241 | + landscapeOrientation: Qt.LandscapeOrientation |
3242 | + invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation |
3243 | + portraitOrientation: Qt.PortraitOrientation |
3244 | + invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3245 | + category: "phone" |
3246 | } |
3247 | }, |
3248 | State { |
3249 | name: "krillin" |
3250 | PropertyChanges { |
3251 | target: priv |
3252 | + primaryOrientation: root.useNativeOrientation |
3253 | supportedOrientations: Qt.PortraitOrientation |
3254 | | Qt.LandscapeOrientation |
3255 | | Qt.InvertedLandscapeOrientation |
3256 | + landscapeOrientation: Qt.LandscapeOrientation |
3257 | + invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation |
3258 | + portraitOrientation: Qt.PortraitOrientation |
3259 | + invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3260 | + category: "phone" |
3261 | } |
3262 | }, |
3263 | State { |
3264 | name: "arale" |
3265 | PropertyChanges { |
3266 | target: priv |
3267 | + primaryOrientation: root.useNativeOrientation |
3268 | supportedOrientations: Qt.PortraitOrientation |
3269 | | Qt.LandscapeOrientation |
3270 | | Qt.InvertedLandscapeOrientation |
3271 | + landscapeOrientation: Qt.LandscapeOrientation |
3272 | + invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation |
3273 | + portraitOrientation: Qt.PortraitOrientation |
3274 | + invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3275 | + category: "phone" |
3276 | } |
3277 | }, |
3278 | State { |
3279 | name: "manta" |
3280 | PropertyChanges { |
3281 | target: priv |
3282 | + primaryOrientation: root.useNativeOrientation |
3283 | + supportedOrientations: Qt.PortraitOrientation |
3284 | + | Qt.InvertedPortraitOrientation |
3285 | + | Qt.LandscapeOrientation |
3286 | + | Qt.InvertedLandscapeOrientation |
3287 | + landscapeOrientation: Qt.LandscapeOrientation |
3288 | + invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation |
3289 | + portraitOrientation: Qt.PortraitOrientation |
3290 | + invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3291 | category: "tablet" |
3292 | } |
3293 | }, |
3294 | @@ -92,9 +119,15 @@ |
3295 | name: "flo" |
3296 | PropertyChanges { |
3297 | target: priv |
3298 | + primaryOrientation: Qt.InvertedLandscapeOrientation |
3299 | + supportedOrientations: Qt.PortraitOrientation |
3300 | + | Qt.InvertedPortraitOrientation |
3301 | + | Qt.LandscapeOrientation |
3302 | + | Qt.InvertedLandscapeOrientation |
3303 | landscapeOrientation: Qt.InvertedLandscapeOrientation |
3304 | invertedLandscapeOrientation: Qt.LandscapeOrientation |
3305 | - primaryOrientation: Qt.InvertedLandscapeOrientation |
3306 | + portraitOrientation: Qt.PortraitOrientation |
3307 | + invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3308 | category: "tablet" |
3309 | } |
3310 | }, |
3311 | @@ -102,8 +135,13 @@ |
3312 | name: "desktop" |
3313 | PropertyChanges { |
3314 | target: priv |
3315 | + primaryOrientation: root.useNativeOrientation |
3316 | + supportedOrientations: root.useNativeOrientation |
3317 | + landscapeOrientation: Qt.LandscapeOrientation |
3318 | + invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation |
3319 | + portraitOrientation: Qt.PortraitOrientation |
3320 | + invertedPortraitOrientation: Qt.InvertedPortraitOrientation |
3321 | category: "desktop" |
3322 | - supportedOrientations: root.useNativeOrientation |
3323 | } |
3324 | } |
3325 | ] |
3326 | |
3327 | === modified file 'qml/DisabledScreenNotice.qml' |
3328 | --- qml/DisabledScreenNotice.qml 2016-01-26 15:29:54 +0000 |
3329 | +++ qml/DisabledScreenNotice.qml 2016-03-11 11:34:41 +0000 |
3330 | @@ -17,6 +17,7 @@ |
3331 | import QtQuick 2.4 |
3332 | import QtQuick.Layouts 1.1 |
3333 | import Ubuntu.Components 1.3 |
3334 | +import Unity.Session 0.1 |
3335 | import QtQuick.Window 2.2 |
3336 | import "Components" |
3337 | |
3338 | @@ -25,19 +26,36 @@ |
3339 | |
3340 | property bool infoNoteDisplayed: true |
3341 | |
3342 | - WallpaperResolver { |
3343 | - width: root.width |
3344 | - id: wallpaperResolver |
3345 | + // For testing |
3346 | + property var screen: Screen |
3347 | + property var orientationLock: OrientationLock |
3348 | + |
3349 | + DeviceConfiguration { |
3350 | + id: deviceConfiguration |
3351 | + name: applicationArguments.deviceName |
3352 | } |
3353 | |
3354 | Item { |
3355 | id: contentContainer |
3356 | + objectName: "contentContainer" |
3357 | anchors.centerIn: parent |
3358 | height: rotation == 90 || rotation == 270 ? parent.width : parent.height |
3359 | width: rotation == 90 || rotation == 270 ? parent.height : parent.width |
3360 | |
3361 | + property int savedOrientation: deviceConfiguration.primaryOrientation == deviceConfiguration.useNativeOrientation |
3362 | + ? (root.width > root.height ? Qt.LandscapeOrientation : Qt.PortraitOrientation) |
3363 | + : deviceConfiguration.primaryOrientation |
3364 | + |
3365 | rotation: { |
3366 | - switch (Screen.orientation) { |
3367 | + var usedOrientation = root.screen.orientation; |
3368 | + |
3369 | + if (root.orientationLock.enabled) { |
3370 | + usedOrientation = savedOrientation; |
3371 | + } |
3372 | + |
3373 | + savedOrientation = usedOrientation; |
3374 | + |
3375 | + switch (usedOrientation) { |
3376 | case Qt.PortraitOrientation: |
3377 | return 0; |
3378 | case Qt.LandscapeOrientation: |
3379 | @@ -47,6 +65,8 @@ |
3380 | case Qt.InvertedLandscapeOrientation: |
3381 | return 90; |
3382 | } |
3383 | + |
3384 | + return 0; |
3385 | } |
3386 | transformOrigin: Item.Center |
3387 | |
3388 | @@ -60,9 +80,9 @@ |
3389 | } |
3390 | } |
3391 | |
3392 | - Image { |
3393 | + Rectangle { |
3394 | anchors.fill: parent |
3395 | - source: wallpaperResolver.background |
3396 | + color: "#3b3b3b" |
3397 | } |
3398 | |
3399 | Item { |
3400 | @@ -74,22 +94,26 @@ |
3401 | UbuntuNumberAnimation { } |
3402 | } |
3403 | |
3404 | - Rectangle { |
3405 | - anchors.fill: parent |
3406 | - color: "black" |
3407 | - opacity: 0.4 |
3408 | - } |
3409 | - |
3410 | - Label { |
3411 | - id: text |
3412 | + Column { |
3413 | anchors.centerIn: parent |
3414 | width: parent.width - units.gu(8) |
3415 | - text: i18n.tr("Your device is now connected to an external display. Use this screen as a touch pad to interact with the mouse.") |
3416 | - color: "white" |
3417 | - horizontalAlignment: Text.AlignHCenter |
3418 | - verticalAlignment: Text.AlignVCenter |
3419 | - fontSize: "x-large" |
3420 | - wrapMode: Text.Wrap |
3421 | + spacing: units.gu(4) |
3422 | + |
3423 | + Label { |
3424 | + id: text |
3425 | + text: i18n.tr("Your device is now connected to an external display. Use this screen as a touch pad to interact with the pointer.") |
3426 | + color: "white" |
3427 | + width: parent.width |
3428 | + fontSize: "large" |
3429 | + wrapMode: Text.Wrap |
3430 | + } |
3431 | + Icon { |
3432 | + height: units.gu(8) |
3433 | + width: height |
3434 | + name: "input-touchpad-symbolic" |
3435 | + color: "white" |
3436 | + anchors.horizontalCenter: parent.horizontalCenter |
3437 | + } |
3438 | } |
3439 | } |
3440 | |
3441 | |
3442 | === modified file 'qml/Greeter/CoverPage.qml' |
3443 | --- qml/Greeter/CoverPage.qml 2015-07-15 15:07:19 +0000 |
3444 | +++ qml/Greeter/CoverPage.qml 2016-03-11 11:34:41 +0000 |
3445 | @@ -1,5 +1,5 @@ |
3446 | /* |
3447 | - * Copyright (C) 2013,2014,2015 Canonical, Ltd. |
3448 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
3449 | * |
3450 | * This program is free software; you can redistribute it and/or modify |
3451 | * it under the terms of the GNU General Public License as published by |
3452 | @@ -34,6 +34,7 @@ |
3453 | readonly property real showProgress: MathUtils.clamp((width - Math.abs(x)) / width, 0, 1) |
3454 | |
3455 | signal tease() |
3456 | + signal clicked() |
3457 | |
3458 | function hideRight() { |
3459 | d.forceRightOnNextHideAnimation = true; |
3460 | @@ -55,7 +56,17 @@ |
3461 | // instead, we can get a little extra horizontal push by using transforms. |
3462 | transform: Translate { id: translation; x: root.draggable ? launcherOffset : 0 } |
3463 | |
3464 | - MouseArea { anchors.fill: parent; } |
3465 | + // Eat events elsewhere on the coverpage, except mouse clicks which we pass |
3466 | + // up (they are used in the NarrowView to hide the cover page) |
3467 | + MouseArea { |
3468 | + anchors.fill: parent |
3469 | + onClicked: root.clicked() |
3470 | + |
3471 | + MultiPointTouchArea { |
3472 | + anchors.fill: parent |
3473 | + mouseEnabled: false |
3474 | + } |
3475 | + } |
3476 | |
3477 | Rectangle { |
3478 | // In case background fails to load |
3479 | |
3480 | === modified file 'qml/Greeter/Infographics.qml' |
3481 | --- qml/Greeter/Infographics.qml 2015-09-29 12:28:10 +0000 |
3482 | +++ qml/Greeter/Infographics.qml 2016-03-11 11:34:41 +0000 |
3483 | @@ -1,5 +1,5 @@ |
3484 | /* |
3485 | - * Copyright (C) 2013 Canonical, Ltd. |
3486 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
3487 | * |
3488 | * This program is free software; you can redistribute it and/or modify |
3489 | * it under the terms of the GNU General Public License as published by |
3490 | @@ -402,6 +402,7 @@ |
3491 | |
3492 | MouseArea { |
3493 | anchors.fill: dataCircle |
3494 | + enabled: notification.text != "" |
3495 | |
3496 | onDoubleClicked: { |
3497 | if (!d.animating) { |
3498 | |
3499 | === modified file 'qml/Greeter/NarrowView.qml' |
3500 | --- qml/Greeter/NarrowView.qml 2015-11-19 16:55:31 +0000 |
3501 | +++ qml/Greeter/NarrowView.qml 2016-03-11 11:34:41 +0000 |
3502 | @@ -1,5 +1,5 @@ |
3503 | /* |
3504 | - * Copyright (C) 2015 Canonical, Ltd. |
3505 | + * Copyright (C) 2015-2016 Canonical, Ltd. |
3506 | * |
3507 | * This program is free software; you can redistribute it and/or modify |
3508 | * it under the terms of the GNU General Public License as published by |
3509 | @@ -125,6 +125,18 @@ |
3510 | onCancel: coverPage.show() |
3511 | onEmergencyCall: root.emergencyCall() |
3512 | |
3513 | + onEnabledChanged: { |
3514 | + if (enabled) { |
3515 | + lockscreen.forceActiveFocus(); |
3516 | + } |
3517 | + } |
3518 | + |
3519 | + onVisibleChanged: { |
3520 | + if (visible) { |
3521 | + lockscreen.forceActiveFocus(); |
3522 | + } |
3523 | + } |
3524 | + |
3525 | function maybeShow() { |
3526 | if (root.locked && !shown) { |
3527 | showNow(); |
3528 | @@ -145,6 +157,7 @@ |
3529 | width: parent.width |
3530 | background: root.background |
3531 | onTease: root.tease() |
3532 | + onClicked: hide() |
3533 | |
3534 | onShowProgressChanged: { |
3535 | if (showProgress === 1) { |
3536 | |
3537 | === modified file 'qml/Launcher/Launcher.qml' |
3538 | --- qml/Launcher/Launcher.qml 2016-01-19 15:26:15 +0000 |
3539 | +++ qml/Launcher/Launcher.qml 2016-03-11 11:34:41 +0000 |
3540 | @@ -19,21 +19,26 @@ |
3541 | import Ubuntu.Components 1.3 |
3542 | import Ubuntu.Gestures 0.1 |
3543 | import Unity.Launcher 0.1 |
3544 | +import GlobalShortcut 1.0 |
3545 | |
3546 | -Item { |
3547 | +FocusScope { |
3548 | id: root |
3549 | |
3550 | property bool autohideEnabled: false |
3551 | + property bool lockedVisible: false |
3552 | property bool available: true // can be used to disable all interactions |
3553 | property alias inverted: panel.inverted |
3554 | property bool shadeBackground: true // can be used to disable background shade when launcher is visible |
3555 | |
3556 | - property int panelWidth: units.gu(8) |
3557 | + property int panelWidth: units.gu(10) |
3558 | property int dragAreaWidth: units.gu(1) |
3559 | property int minimizeDistance: units.gu(26) |
3560 | property real progress: dragArea.dragging && dragArea.touchX > panelWidth ? |
3561 | (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0 |
3562 | |
3563 | + property bool superPressed: false |
3564 | + property bool superTabPressed: false |
3565 | + |
3566 | readonly property bool dragging: dragArea.dragging |
3567 | readonly property real dragDistance: dragArea.dragging ? dragArea.touchX : 0 |
3568 | readonly property real visibleWidth: panel.width + panel.x |
3569 | @@ -57,12 +62,55 @@ |
3570 | } |
3571 | } |
3572 | |
3573 | + onSuperPressedChanged: { |
3574 | + if (superPressed) { |
3575 | + superPressTimer.start(); |
3576 | + superLongPressTimer.start(); |
3577 | + } else { |
3578 | + superPressTimer.stop(); |
3579 | + superLongPressTimer.stop(); |
3580 | + launcher.switchToNextState(""); |
3581 | + panel.shortcutHintsShown = false; |
3582 | + } |
3583 | + } |
3584 | + |
3585 | + onSuperTabPressedChanged: { |
3586 | + if (superTabPressed) { |
3587 | + switchToNextState("visible") |
3588 | + panel.highlightIndex = -1; |
3589 | + root.focus = true; |
3590 | + superPressTimer.stop(); |
3591 | + superLongPressTimer.stop(); |
3592 | + } else { |
3593 | + if (panel.highlightIndex == -1) { |
3594 | + showDashHome(); |
3595 | + } else if (panel.highlightIndex >= 0){ |
3596 | + launcherApplicationSelected(LauncherModel.get(panel.highlightIndex).appId); |
3597 | + } |
3598 | + panel.highlightIndex = -2; |
3599 | + switchToNextState(""); |
3600 | + root.focus = false; |
3601 | + } |
3602 | + } |
3603 | + |
3604 | + onLockedVisibleChanged: { |
3605 | + if (lockedVisible && state == "") { |
3606 | + panel.dismissTimer.stop(); |
3607 | + fadeOutAnimation.stop(); |
3608 | + switchToNextState("visible") |
3609 | + } else if (!lockedVisible && state == "visible") { |
3610 | + hide(); |
3611 | + } |
3612 | + } |
3613 | + |
3614 | function hide() { |
3615 | switchToNextState("") |
3616 | } |
3617 | |
3618 | function fadeOut() { |
3619 | - fadeOutAnimation.start(); |
3620 | + if (!root.lockedVisible) { |
3621 | + fadeOutAnimation.start(); |
3622 | + } |
3623 | } |
3624 | |
3625 | function switchToNextState(state) { |
3626 | @@ -90,6 +138,77 @@ |
3627 | } |
3628 | } |
3629 | |
3630 | + function openForKeyboardNavigation() { |
3631 | + panel.highlightIndex = -1; // The BFB |
3632 | + root.focus = true; |
3633 | + switchToNextState("visible") |
3634 | + } |
3635 | + |
3636 | + Keys.onPressed: { |
3637 | + switch (event.key) { |
3638 | + case Qt.Key_Backtab: |
3639 | + panel.highlightPrevious(); |
3640 | + event.accepted = true; |
3641 | + break; |
3642 | + case Qt.Key_Up: |
3643 | + if (root.inverted) { |
3644 | + panel.highlightNext() |
3645 | + } else { |
3646 | + panel.highlightPrevious(); |
3647 | + } |
3648 | + event.accepted = true; |
3649 | + break; |
3650 | + case Qt.Key_Tab: |
3651 | + panel.highlightNext(); |
3652 | + event.accepted = true; |
3653 | + break; |
3654 | + case Qt.Key_Down: |
3655 | + if (root.inverted) { |
3656 | + panel.highlightPrevious(); |
3657 | + } else { |
3658 | + panel.highlightNext(); |
3659 | + } |
3660 | + event.accepted = true; |
3661 | + break; |
3662 | + case Qt.Key_Right: |
3663 | + panel.openQuicklist(panel.highlightIndex) |
3664 | + event.accepted = true; |
3665 | + break; |
3666 | + case Qt.Key_Escape: |
3667 | + panel.highlightIndex = -2; |
3668 | + // Falling through intentionally |
3669 | + case Qt.Key_Enter: |
3670 | + case Qt.Key_Return: |
3671 | + case Qt.Key_Space: |
3672 | + if (panel.highlightIndex == -1) { |
3673 | + showDashHome(); |
3674 | + } else if (panel.highlightIndex >= 0) { |
3675 | + launcherApplicationSelected(LauncherModel.get(panel.highlightIndex).appId); |
3676 | + } |
3677 | + root.hide(); |
3678 | + panel.highlightIndex = -2 |
3679 | + event.accepted = true; |
3680 | + root.focus = false; |
3681 | + } |
3682 | + } |
3683 | + |
3684 | + Timer { |
3685 | + id: superPressTimer |
3686 | + interval: 200 |
3687 | + onTriggered: { |
3688 | + switchToNextState("visible") |
3689 | + } |
3690 | + } |
3691 | + |
3692 | + Timer { |
3693 | + id: superLongPressTimer |
3694 | + interval: 1000 |
3695 | + onTriggered: { |
3696 | + switchToNextState("visible") |
3697 | + panel.shortcutHintsShown = true; |
3698 | + } |
3699 | + } |
3700 | + |
3701 | Timer { |
3702 | id: teaseTimer |
3703 | interval: mode == "teasing" ? 200 : 300 |
3704 | @@ -106,6 +225,13 @@ |
3705 | interval: 1 |
3706 | property string nextState: "" |
3707 | onTriggered: { |
3708 | + if (root.lockedVisible && nextState == "") { |
3709 | + // Due to binding updates when switching between modes |
3710 | + // it could happen that our request to show will be overwritten |
3711 | + // with a hide request. Rewrite it when we know hiding is not allowed. |
3712 | + nextState = "visible" |
3713 | + } |
3714 | + |
3715 | // switching to an intermediate state here to make sure all the |
3716 | // values are restored, even if we were already in the target state |
3717 | root.state = "tmp" |
3718 | @@ -151,7 +277,7 @@ |
3719 | |
3720 | MouseArea { |
3721 | id: launcherDragArea |
3722 | - enabled: root.available && (root.state == "visible" || root.state == "visibleTemporary") |
3723 | + enabled: root.available && (root.state == "visible" || root.state == "visibleTemporary") && !root.lockedVisible |
3724 | anchors.fill: panel |
3725 | anchors.rightMargin: -units.gu(2) |
3726 | drag { |
3727 | @@ -172,9 +298,10 @@ |
3728 | InverseMouseArea { |
3729 | id: closeMouseArea |
3730 | anchors.fill: panel |
3731 | - enabled: root.shadeBackground && root.state == "visible" |
3732 | + enabled: root.shadeBackground && root.state == "visible" && (!root.lockedVisible || panel.highlightIndex >= -1) |
3733 | visible: enabled |
3734 | onPressed: { |
3735 | + panel.highlightIndex = -2 |
3736 | root.hide(); |
3737 | } |
3738 | } |
3739 | @@ -183,7 +310,7 @@ |
3740 | id: backgroundShade |
3741 | anchors.fill: parent |
3742 | color: "black" |
3743 | - opacity: root.shadeBackground && root.state == "visible" ? 0.6 : 0 |
3744 | + opacity: root.shadeBackground && root.state == "visible" && !root.lockedVisible ? 0.6 : 0 |
3745 | |
3746 | Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.BriskDuration } } |
3747 | } |
3748 | @@ -202,8 +329,8 @@ |
3749 | rotation: -90 |
3750 | anchors.centerIn: parent |
3751 | gradient: Gradient { |
3752 | - GradientStop { position: 0.0; color: panel.color} |
3753 | - GradientStop { position: 1.0; color: Qt.rgba(panel.r,panel.g,panel.b,0)} |
3754 | + GradientStop { position: 0.0; color: Qt.rgba(panel.color.r, panel.color.g, panel.color.b, .5)} |
3755 | + GradientStop { position: 1.0; color: Qt.rgba(panel.color.r,panel.color.g,panel.color.b,0)} |
3756 | } |
3757 | } |
3758 | } |
3759 | @@ -227,7 +354,7 @@ |
3760 | Connections { |
3761 | target: panel.dismissTimer |
3762 | onTriggered: { |
3763 | - if (root.autohideEnabled) { |
3764 | + if (root.autohideEnabled && !root.lockedVisible) { |
3765 | if (!panel.preventHiding) { |
3766 | root.state = "" |
3767 | } else { |
3768 | @@ -240,11 +367,11 @@ |
3769 | property bool animate: true |
3770 | |
3771 | onApplicationSelected: { |
3772 | - root.state = "" |
3773 | + root.hide(); |
3774 | launcherApplicationSelected(appId) |
3775 | } |
3776 | onShowDashHome: { |
3777 | - root.state = "" |
3778 | + root.hide(); |
3779 | root.showDashHome(); |
3780 | } |
3781 | |
3782 | @@ -254,6 +381,12 @@ |
3783 | } |
3784 | } |
3785 | |
3786 | + onKbdNavigationCancelled: { |
3787 | + panel.highlightIndex = -2; |
3788 | + root.hide(); |
3789 | + root.focus = false; |
3790 | + } |
3791 | + |
3792 | Behavior on x { |
3793 | enabled: !dragArea.dragging && !launcherDragArea.drag.active && panel.animate; |
3794 | NumberAnimation { |
3795 | |
3796 | === modified file 'qml/Launcher/LauncherDelegate.qml' |
3797 | --- qml/Launcher/LauncherDelegate.qml 2015-11-19 16:55:31 +0000 |
3798 | +++ qml/Launcher/LauncherDelegate.qml 2016-03-11 11:34:41 +0000 |
3799 | @@ -20,6 +20,7 @@ |
3800 | Item { |
3801 | id: root |
3802 | |
3803 | + property int itemIndex: 0 |
3804 | property string iconName |
3805 | property int count: 0 |
3806 | property bool countVisible: false |
3807 | @@ -29,10 +30,12 @@ |
3808 | property real maxAngle: 0 |
3809 | property bool inverted: false |
3810 | property bool alerting: false |
3811 | - readonly property alias wiggling: wiggleAnim.running |
3812 | + property bool highlighted: false |
3813 | + property bool shortcutHintShown: false |
3814 | |
3815 | readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight |
3816 | readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight |
3817 | + readonly property alias wiggling: wiggleAnim.running |
3818 | |
3819 | property int itemWidth |
3820 | property int itemHeight |
3821 | @@ -121,20 +124,32 @@ |
3822 | |
3823 | Item { |
3824 | id: iconItem |
3825 | - width: parent.itemWidth + units.gu(1) |
3826 | + width: root.width |
3827 | height: parent.itemHeight + units.gu(1) |
3828 | anchors.centerIn: parent |
3829 | |
3830 | + Image { |
3831 | + objectName: "focusRing" |
3832 | + anchors.centerIn: iconShape |
3833 | + height: width * 15 / 16 |
3834 | + width: iconShape.width + units.gu(1) |
3835 | + source: "graphics/launcher-app-focus-ring.svg" |
3836 | + sourceSize.width: width |
3837 | + sourceSize.height: height |
3838 | + visible: root.highlighted |
3839 | + } |
3840 | + |
3841 | ProportionalShape { |
3842 | id: iconShape |
3843 | anchors.centerIn: parent |
3844 | - width: parent.width - units.gu(2) |
3845 | + width: root.itemWidth |
3846 | aspect: UbuntuShape.DropShadow |
3847 | source: Image { |
3848 | id: iconImage |
3849 | sourceSize.width: iconShape.width |
3850 | sourceSize.height: iconShape.height |
3851 | source: root.iconName |
3852 | + cache: false // see lpbug#1543290 why no cache |
3853 | } |
3854 | } |
3855 | |
3856 | @@ -144,7 +159,8 @@ |
3857 | anchors { |
3858 | right: parent.right |
3859 | bottom: parent.bottom |
3860 | - margins: units.dp(3) |
3861 | + rightMargin: (iconItem.width - root.itemWidth) / 2 - units.dp(2) |
3862 | + margins: units.dp(5) |
3863 | } |
3864 | width: Math.min(root.itemWidth, Math.max(units.gu(2), countLabel.implicitWidth + units.gu(1))) |
3865 | height: units.gu(2) |
3866 | @@ -172,16 +188,11 @@ |
3867 | id: progressOverlay |
3868 | objectName: "progressOverlay" |
3869 | |
3870 | - anchors { |
3871 | - left: iconItem.left |
3872 | - right: iconItem.right |
3873 | - verticalCenter: parent.verticalCenter |
3874 | - leftMargin: units.gu(1.5) |
3875 | - rightMargin: units.gu(1.5) |
3876 | - } |
3877 | + anchors.centerIn: parent |
3878 | + width: root.itemWidth * .8 |
3879 | height: units.gu(1) |
3880 | visible: root.progress > -1 |
3881 | - color: UbuntuColors.darkGrey |
3882 | + backgroundColor: UbuntuColors.darkGrey |
3883 | borderSource: "none" |
3884 | |
3885 | Item { |
3886 | @@ -199,32 +210,56 @@ |
3887 | top: parent.top |
3888 | bottom: parent.bottom |
3889 | } |
3890 | - color: "white" |
3891 | + backgroundColor: "white" |
3892 | borderSource: "none" |
3893 | width: progressOverlay.width |
3894 | } |
3895 | } |
3896 | } |
3897 | |
3898 | - Image { |
3899 | - objectName: "runningHighlight" |
3900 | + Column { |
3901 | anchors { |
3902 | left: parent.left |
3903 | verticalCenter: parent.verticalCenter |
3904 | } |
3905 | - visible: root.itemRunning |
3906 | - rotation: 180 |
3907 | - source: "graphics/focused_app_arrow.png" |
3908 | + spacing: units.gu(.5) |
3909 | + Repeater { |
3910 | + model: 1 // TODO: This should be "Math.min(3, app.surfaceCount)" once we have multiple surfaces |
3911 | + Rectangle { |
3912 | + objectName: "runningHighlight" + index |
3913 | + width: units.gu(0.25) |
3914 | + height: units.gu(.5) |
3915 | + color: "white" |
3916 | + visible: root.itemRunning |
3917 | + } |
3918 | + } |
3919 | } |
3920 | |
3921 | - Image { |
3922 | + Rectangle { |
3923 | objectName: "focusedHighlight" |
3924 | anchors { |
3925 | right: parent.right |
3926 | verticalCenter: parent.verticalCenter |
3927 | } |
3928 | + width: units.gu(0.25) |
3929 | + height: units.gu(.5) |
3930 | + color: "white" |
3931 | visible: root.itemFocused |
3932 | - source: "graphics/focused_app_arrow.png" |
3933 | + } |
3934 | + |
3935 | + Rectangle { |
3936 | + objectName: "shortcutHint" |
3937 | + anchors.centerIn: parent |
3938 | + width: units.gu(3) |
3939 | + height: width |
3940 | + color: "#E0292929" |
3941 | + visible: root.shortcutHintShown |
3942 | + Label { |
3943 | + anchors.centerIn: parent |
3944 | + text: (itemIndex + 1) % 10 |
3945 | + color: "white" |
3946 | + font.weight: Font.DemiBold |
3947 | + } |
3948 | } |
3949 | } |
3950 | |
3951 | |
3952 | === modified file 'qml/Launcher/LauncherPanel.qml' |
3953 | --- qml/Launcher/LauncherPanel.qml 2016-01-11 17:38:19 +0000 |
3954 | +++ qml/Launcher/LauncherPanel.qml 2016-03-11 11:34:41 +0000 |
3955 | @@ -19,12 +19,13 @@ |
3956 | import Ubuntu.Components.ListItems 1.3 as ListItems |
3957 | import Unity.Launcher 0.1 |
3958 | import Ubuntu.Components.Popups 1.3 |
3959 | +import GlobalShortcut 1.0 |
3960 | import "../Components/ListItems" |
3961 | import "../Components/" |
3962 | |
3963 | Rectangle { |
3964 | id: root |
3965 | - color: "#B2000000" |
3966 | + color: "#E0292929" |
3967 | |
3968 | rotation: inverted ? 180 : 0 |
3969 | |
3970 | @@ -33,11 +34,13 @@ |
3971 | property bool dragging: false |
3972 | property bool moving: launcherListView.moving || launcherListView.flicking |
3973 | property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed |
3974 | - || mouseEventEater.containsMouse || dashItem.hovered |
3975 | - property int highlightIndex: -1 |
3976 | + || mouseEventEater.containsMouse || dashItem.hovered |
3977 | + property int highlightIndex: -2 |
3978 | + property bool shortcutHintsShown: false |
3979 | |
3980 | signal applicationSelected(string appId) |
3981 | signal showDashHome() |
3982 | + signal kbdNavigationCancelled() |
3983 | |
3984 | onXChanged: { |
3985 | if (quickList.state == "open") { |
3986 | @@ -45,6 +48,26 @@ |
3987 | } |
3988 | } |
3989 | |
3990 | + function highlightNext() { |
3991 | + highlightIndex++; |
3992 | + if (highlightIndex >= launcherListView.count) { |
3993 | + highlightIndex = -1; |
3994 | + } |
3995 | + launcherListView.moveToIndex(Math.max(highlightIndex, 0)); |
3996 | + } |
3997 | + function highlightPrevious() { |
3998 | + highlightIndex--; |
3999 | + if (highlightIndex <= -2) { |
4000 | + highlightIndex = launcherListView.count - 1; |
4001 | + } |
4002 | + launcherListView.moveToIndex(Math.max(highlightIndex, 0)); |
4003 | + } |
4004 | + function openQuicklist(index) { |
4005 | + quickList.open(index); |
4006 | + quickList.selectedIndex = 0; |
4007 | + quickList.focus = true; |
4008 | + } |
4009 | + |
4010 | MouseArea { |
4011 | id: mouseEventEater |
4012 | anchors.fill: parent |
4013 | @@ -57,24 +80,16 @@ |
4014 | fill: parent |
4015 | } |
4016 | |
4017 | - Item { |
4018 | + Rectangle { |
4019 | objectName: "buttonShowDashHome" |
4020 | width: parent.width |
4021 | - height: units.gu(7) |
4022 | - clip: true |
4023 | - |
4024 | - UbuntuShape { |
4025 | - anchors { |
4026 | - fill: parent |
4027 | - topMargin: -units.gu(2) |
4028 | - } |
4029 | - aspect: UbuntuShape.Flat |
4030 | - backgroundColor: UbuntuColors.orange |
4031 | - } |
4032 | + height: width * .9 |
4033 | + color: UbuntuColors.orange |
4034 | + readonly property bool highlighted: root.highlightIndex == -1; |
4035 | |
4036 | Image { |
4037 | objectName: "dashItem" |
4038 | - width: units.gu(5) |
4039 | + width: parent.width * .6 |
4040 | height: width |
4041 | anchors.centerIn: parent |
4042 | source: "graphics/home.png" |
4043 | @@ -85,6 +100,14 @@ |
4044 | anchors.fill: parent |
4045 | onClicked: root.showDashHome() |
4046 | } |
4047 | + Rectangle { |
4048 | + objectName: "bfbFocusHighlight" |
4049 | + anchors.fill: parent |
4050 | + border.color: "white" |
4051 | + border.width: units.dp(1) |
4052 | + color: "transparent" |
4053 | + visible: parent.highlighted |
4054 | + } |
4055 | } |
4056 | |
4057 | Item { |
4058 | @@ -102,10 +125,8 @@ |
4059 | objectName: "launcherListView" |
4060 | anchors { |
4061 | fill: parent |
4062 | - topMargin: -extensionSize + units.gu(0.5) |
4063 | - bottomMargin: -extensionSize + units.gu(1) |
4064 | - leftMargin: units.gu(0.5) |
4065 | - rightMargin: units.gu(0.5) |
4066 | + topMargin: -extensionSize + width * .15 |
4067 | + bottomMargin: -extensionSize + width * .15 |
4068 | } |
4069 | topMargin: extensionSize |
4070 | bottomMargin: extensionSize |
4071 | @@ -140,11 +161,11 @@ |
4072 | } |
4073 | |
4074 | // The height of the area where icons start getting folded |
4075 | - property int foldingStartHeight: units.gu(6.5) |
4076 | + property int foldingStartHeight: itemHeight |
4077 | // The height of the area where the items reach the final folding angle |
4078 | property int foldingStopHeight: foldingStartHeight - itemHeight - spacing |
4079 | - property int itemWidth: units.gu(7) |
4080 | - property int itemHeight: units.gu(6.5) |
4081 | + property int itemWidth: width * .75 |
4082 | + property int itemHeight: itemWidth * 15 / 16 + units.gu(1) |
4083 | property int clickFlickSpeed: units.gu(60) |
4084 | property int draggedIndex: dndArea.draggedIndex |
4085 | property real realContentY: contentY - originY + topMargin |
4086 | @@ -172,12 +193,24 @@ |
4087 | |
4088 | UbuntuNumberAnimation { |
4089 | id: moveAnimation |
4090 | + objectName: "moveAnimation" |
4091 | target: launcherListView |
4092 | property: "contentY" |
4093 | function moveTo(contentY) { |
4094 | from = launcherListView.contentY; |
4095 | to = contentY; |
4096 | - start(); |
4097 | + restart(); |
4098 | + } |
4099 | + } |
4100 | + function moveToIndex(index) { |
4101 | + var totalItemHeight = launcherListView.itemHeight + launcherListView.spacing |
4102 | + var itemPosition = index * totalItemHeight; |
4103 | + var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin |
4104 | + var distanceToEnd = index == 0 || index == launcherListView.count - 1 ? 0 : totalItemHeight |
4105 | + if (itemPosition + totalItemHeight + distanceToEnd > launcherListView.contentY + launcherListView.originY + launcherListView.topMargin + height) { |
4106 | + moveAnimation.moveTo(itemPosition + launcherListView.itemHeight - launcherListView.topMargin - height + distanceToEnd - launcherListView.originY); |
4107 | + } else if (itemPosition - distanceToEnd < launcherListView.contentY - launcherListView.originY + launcherListView.topMargin) { |
4108 | + moveAnimation.moveTo(itemPosition - distanceToEnd - launcherListView.topMargin + launcherListView.originY); |
4109 | } |
4110 | } |
4111 | |
4112 | @@ -192,9 +225,10 @@ |
4113 | // the right app when running autopilot tests for |
4114 | // multiple apps. |
4115 | readonly property string appId: model.appId |
4116 | + itemIndex: index |
4117 | itemHeight: launcherListView.itemHeight |
4118 | itemWidth: launcherListView.itemWidth |
4119 | - width: itemWidth |
4120 | + width: parent.width |
4121 | height: itemHeight |
4122 | iconName: model.icon |
4123 | count: model.count |
4124 | @@ -204,6 +238,8 @@ |
4125 | itemFocused: model.focused |
4126 | inverted: root.inverted |
4127 | alerting: model.alerting |
4128 | + highlighted: root.highlightIndex == index |
4129 | + shortcutHintShown: root.shortcutHintsShown && index <= 9 |
4130 | z: -Math.abs(offset) |
4131 | maxAngle: 55 |
4132 | property bool dragging: false |
4133 | @@ -241,14 +277,7 @@ |
4134 | onAlertingChanged: { |
4135 | if(alerting) { |
4136 | if (!dragging && (launcherListView.peekingIndex === -1 || launcher.visibleWidth > 0)) { |
4137 | - var itemPosition = index * launcherListView.itemHeight; |
4138 | - var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin |
4139 | - var distanceToEnd = index == 0 || index == launcherListView.count - 1 ? 0 : launcherListView.itemHeight |
4140 | - if (itemPosition + launcherListView.itemHeight + distanceToEnd > launcherListView.contentY + launcherListView.topMargin + height) { |
4141 | - moveAnimation.moveTo(itemPosition + launcherListView.itemHeight - launcherListView.topMargin - height + distanceToEnd); |
4142 | - } else if (itemPosition - distanceToEnd < launcherListView.contentY + launcherListView.topMargin) { |
4143 | - moveAnimation.moveTo(itemPosition - distanceToEnd - launcherListView.topMargin); |
4144 | - } |
4145 | + launcherListView.moveToIndex(index) |
4146 | if (!dragging && launcher.state !== "visible") { |
4147 | peekingAnimation.start() |
4148 | } |
4149 | @@ -402,10 +431,7 @@ |
4150 | |
4151 | if (mouse.button & Qt.RightButton) { // context menu |
4152 | // Opening QuickList |
4153 | - quickList.item = clickedItem; |
4154 | - quickList.model = launcherListView.model.get(index).quickList; |
4155 | - quickList.appId = launcherListView.model.get(index).appId; |
4156 | - quickList.state = "open"; |
4157 | + quickList.open(index); |
4158 | return; |
4159 | } |
4160 | |
4161 | @@ -413,10 +439,8 @@ |
4162 | |
4163 | // First/last item do the scrolling at more than 12 degrees |
4164 | if (index == 0 || index == launcherListView.count - 1) { |
4165 | - if (clickedItem.angle > 12) { |
4166 | - launcherListView.flick(0, -launcherListView.clickFlickSpeed); |
4167 | - } else if (clickedItem.angle < -12) { |
4168 | - launcherListView.flick(0, launcherListView.clickFlickSpeed); |
4169 | + if (clickedItem.angle > 12 || clickedItem.angle < -12) { |
4170 | + launcherListView.moveToIndex(index); |
4171 | } else { |
4172 | root.applicationSelected(LauncherModel.get(index).appId); |
4173 | } |
4174 | @@ -424,10 +448,8 @@ |
4175 | } |
4176 | |
4177 | // the rest launches apps up to an angle of 30 degrees |
4178 | - if (clickedItem.angle > 30) { |
4179 | - launcherListView.flick(0, -launcherListView.clickFlickSpeed); |
4180 | - } else if (clickedItem.angle < -30) { |
4181 | - launcherListView.flick(0, launcherListView.clickFlickSpeed); |
4182 | + if (clickedItem.angle > 30 || clickedItem.angle < -30) { |
4183 | + launcherListView.moveToIndex(index); |
4184 | } else { |
4185 | root.applicationSelected(LauncherModel.get(index).appId); |
4186 | } |
4187 | @@ -481,11 +503,7 @@ |
4188 | |
4189 | draggedIndex = Math.floor((mouse.y + launcherListView.realContentY) / launcherListView.realItemHeight); |
4190 | |
4191 | - // Opening QuickList |
4192 | - quickList.item = selectedItem; |
4193 | - quickList.model = launcherListView.model.get(draggedIndex).quickList; |
4194 | - quickList.appId = launcherListView.model.get(draggedIndex).appId; |
4195 | - quickList.state = "open"; |
4196 | + quickList.open(draggedIndex) |
4197 | |
4198 | launcherListView.interactive = false |
4199 | |
4200 | @@ -644,7 +662,9 @@ |
4201 | enabled: quickList.state == "open" || pressed |
4202 | |
4203 | onClicked: { |
4204 | - quickList.state = "" |
4205 | + quickList.state = ""; |
4206 | + quickList.focus = false; |
4207 | + root.kbdNavigationCancelled(); |
4208 | } |
4209 | |
4210 | // Forward for dragging to work when quickList is open |
4211 | @@ -693,12 +713,60 @@ |
4212 | property var model |
4213 | property string appId |
4214 | property var item |
4215 | + property int selectedIndex: -1 |
4216 | + |
4217 | + Keys.onPressed: { |
4218 | + switch (event.key) { |
4219 | + case Qt.Key_Down: |
4220 | + selectedIndex++; |
4221 | + if (selectedIndex >= popoverRepeater.count) { |
4222 | + selectedIndex = 0; |
4223 | + } |
4224 | + event.accepted = true; |
4225 | + break; |
4226 | + case Qt.Key_Up: |
4227 | + selectedIndex--; |
4228 | + if (selectedIndex < 0) { |
4229 | + selectedIndex = popoverRepeater.count - 1; |
4230 | + } |
4231 | + event.accepted = true; |
4232 | + break; |
4233 | + case Qt.Key_Left: |
4234 | + case Qt.Key_Escape: |
4235 | + quickList.selectedIndex = -1; |
4236 | + quickList.focus = false; |
4237 | + quickList.state = "" |
4238 | + event.accepted = true; |
4239 | + break; |
4240 | + case Qt.Key_Enter: |
4241 | + case Qt.Key_Return: |
4242 | + case Qt.Key_Space: |
4243 | + if (quickList.selectedIndex >= 0) { |
4244 | + LauncherModel.quickListActionInvoked(quickList.appId, quickList.selectedIndex) |
4245 | + } |
4246 | + quickList.selectedIndex = -1; |
4247 | + quickList.focus = false; |
4248 | + quickList.state = "" |
4249 | + root.kbdNavigationCancelled(); |
4250 | + event.accepted = true; |
4251 | + break; |
4252 | + } |
4253 | + } |
4254 | |
4255 | // internal |
4256 | property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) + quickList.item.offset : units.gu(1) |
4257 | property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height : |
4258 | itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0 |
4259 | |
4260 | + function open(index) { |
4261 | + var itemPosition = index * launcherListView.itemHeight; |
4262 | + var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin |
4263 | + item = launcherListView.itemAt(launcherListView.width / 2, itemPosition + launcherListView.itemHeight / 2); |
4264 | + quickList.model = launcherListView.model.get(index).quickList; |
4265 | + quickList.appId = launcherListView.model.get(index).appId; |
4266 | + quickList.state = "open"; |
4267 | + } |
4268 | + |
4269 | Column { |
4270 | id: quickListColumn |
4271 | width: parent.width |
4272 | @@ -712,6 +780,7 @@ |
4273 | objectName: "quickListEntry" + index |
4274 | text: (model.clickable ? "" : "<b>") + model.label + (model.clickable ? "" : "</b>") |
4275 | highlightWhenPressed: model.clickable |
4276 | + selected: index === quickList.selectedIndex |
4277 | |
4278 | // FIXME: This is a workaround for the theme not being context sensitive. I.e. the |
4279 | // ListItems don't know that they are sitting in a themed Popover where the color |
4280 | @@ -727,6 +796,8 @@ |
4281 | // Unsetting model to prevent showing changing entries during fading out |
4282 | // that may happen because of triggering an action. |
4283 | LauncherModel.quickListActionInvoked(quickList.appId, index); |
4284 | + quickList.focus = false; |
4285 | + root.kbdNavigationCancelled(); |
4286 | quickList.model = undefined; |
4287 | } |
4288 | } |
4289 | |
4290 | === added file 'qml/Launcher/graphics/launcher-app-focus-ring.svg' |
4291 | --- qml/Launcher/graphics/launcher-app-focus-ring.svg 1970-01-01 00:00:00 +0000 |
4292 | +++ qml/Launcher/graphics/launcher-app-focus-ring.svg 2016-03-11 11:34:41 +0000 |
4293 | @@ -0,0 +1,12 @@ |
4294 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
4295 | +<svg width="172px" height="163px" viewBox="0 0 172 163" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"> |
4296 | + <!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch --> |
4297 | + <title>Shape</title> |
4298 | + <desc>Created with Sketch.</desc> |
4299 | + <defs></defs> |
4300 | + <g id="•-Launcher" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"> |
4301 | + <g id="Artboard-9" sketch:type="MSArtboardGroup" transform="translate(-163.000000, -1436.000000)" fill="#E95420"> |
4302 | + <path d="M221.983432,1440 L221.983432,1440 C195.6127,1440 184.708233,1442.4723 177.107949,1450.10734 C169.476819,1457.77336 167,1468.79245 167,1495.3481 L167,1538.9019 C167,1565.45755 169.476819,1576.47664 177.107949,1584.14266 C184.708233,1591.7777 195.6127,1594.25 221.983432,1594.25 L276.016868,1594.25 C302.387595,1594.25 313.291998,1591.77771 320.892221,1584.14264 C328.523252,1576.47663 331,1565.45769 331,1538.9019 L331,1495.3481 C331,1468.79231 328.523252,1457.77337 320.892221,1450.10736 C313.291998,1442.47229 302.387595,1440 276.016868,1440 L221.983432,1440 Z M221.983432,1436 L276.016868,1436 C302.345315,1436 314.848953,1438.36655 323.727108,1447.2854 C332.633306,1456.23243 335,1468.85167 335,1495.3481 L335,1538.9019 C335,1565.39833 332.633306,1578.01757 323.727108,1586.9646 C314.848953,1595.88345 302.345315,1598.25 276.016868,1598.25 L221.983432,1598.25 C195.654985,1598.25 183.151291,1595.88345 174.273077,1586.96463 C165.366772,1578.0176 163,1565.39822 163,1538.9019 L163,1495.3481 C163,1468.85178 165.366772,1456.2324 174.273077,1447.28537 C183.151291,1438.36655 195.654985,1436 221.983432,1436 L221.983432,1436 Z" id="Shape" sketch:type="MSShapeGroup"></path> |
4303 | + </g> |
4304 | + </g> |
4305 | +</svg> |
4306 | \ No newline at end of file |
4307 | |
4308 | === modified file 'qml/Notifications/Notification.qml' |
4309 | --- qml/Notifications/Notification.qml 2016-02-29 11:31:46 +0000 |
4310 | +++ qml/Notifications/Notification.qml 2016-03-11 11:34:41 +0000 |
4311 | @@ -23,7 +23,7 @@ |
4312 | import Utils 0.1 |
4313 | import "../Components" |
4314 | |
4315 | -Item { |
4316 | +StyledItem { |
4317 | id: notification |
4318 | |
4319 | property alias iconSource: icon.fileSource |
4320 | @@ -58,6 +58,10 @@ |
4321 | color: (type === Notification.Confirmation && notificationList.useModal && !greeter.shown) || darkOnBright ? sdLightGrey : Qt.rgba(0.132, 0.117, 0.109, 0.97) |
4322 | opacity: 1 - (x / notification.width) // FIXME: non-zero initially because of LP: #1354406 workaround, we want this to start at 0 upon creation eventually |
4323 | |
4324 | + theme: ThemeSettings { |
4325 | + name: "Ubuntu.Components.Themes.Ambiance" |
4326 | + } |
4327 | + |
4328 | state: { |
4329 | var result = ""; |
4330 | |
4331 | @@ -297,7 +301,7 @@ |
4332 | visible: body != "" && type !== Notification.Confirmation |
4333 | fontSize: "small" |
4334 | color: darkOnBright ? sdFontColor : theme.palette.normal.backgroundText |
4335 | - wrapMode: Text.WordWrap |
4336 | + wrapMode: Text.Wrap |
4337 | maximumLineCount: type == Notification.SnapDecision ? 12 : 2 |
4338 | elide: Text.ElideRight |
4339 | textFormat: Text.PlainText |
4340 | |
4341 | === modified file 'qml/OrientedShell.qml' |
4342 | --- qml/OrientedShell.qml 2016-01-28 11:31:48 +0000 |
4343 | +++ qml/OrientedShell.qml 2016-03-11 11:34:41 +0000 |
4344 | @@ -19,6 +19,7 @@ |
4345 | import Unity.InputInfo 0.1 |
4346 | import Unity.Session 0.1 |
4347 | import Unity.Screens 0.1 |
4348 | +import Utils 0.1 |
4349 | import GSettings 1.0 |
4350 | import "Components" |
4351 | import "Rotation" |
4352 | @@ -77,6 +78,8 @@ |
4353 | InputDeviceModel { |
4354 | id: keyboardsModel |
4355 | deviceFilter: InputInfo.Keyboard |
4356 | + onDeviceAdded: forceOSKEnabled = autopilotDevicePresent(); |
4357 | + onDeviceRemoved: forceOSKEnabled = autopilotDevicePresent(); |
4358 | } |
4359 | |
4360 | InputDeviceModel { |
4361 | @@ -84,6 +87,27 @@ |
4362 | deviceFilter: InputInfo.TouchScreen |
4363 | } |
4364 | |
4365 | + /* FIXME: This exposes the NameRole as a work arround for lp:1542224. |
4366 | + * When QInputInfo exposes NameRole to QML, this should be removed. |
4367 | + */ |
4368 | + property bool forceOSKEnabled: false |
4369 | + property var autopilotEmulatedDeviceNames: ["py-evdev-uinput"] |
4370 | + UnitySortFilterProxyModel { |
4371 | + id: autopilotDevices |
4372 | + model: keyboardsModel |
4373 | + } |
4374 | + |
4375 | + function autopilotDevicePresent() { |
4376 | + for(var i = 0; i < autopilotDevices.count; i++) { |
4377 | + var device = autopilotDevices.get(i); |
4378 | + if (autopilotEmulatedDeviceNames.indexOf(device.name) != -1) { |
4379 | + console.warn("Forcing the OSK to be enabled as there is an autopilot eumlated device present.") |
4380 | + return true; |
4381 | + } |
4382 | + } |
4383 | + return false; |
4384 | + } |
4385 | + |
4386 | Screens { |
4387 | id: screens |
4388 | } |
4389 | @@ -195,7 +219,8 @@ |
4390 | // have multiple keyboards around. For now we only enable one keyboard at a time |
4391 | // thus hiding it here if there is a physical one around or if we have a second |
4392 | // screen (the virtual touchpad & osk on the phone) attached. |
4393 | - oskEnabled: keyboardsModel.count === 0 && screens.count === 1 |
4394 | + oskEnabled: (keyboardsModel.count === 0 && screens.count === 1) || |
4395 | + forceOSKEnabled |
4396 | |
4397 | // TODO: Factor in the connected input devices (eg: physical keyboard, mouse, touchscreen), |
4398 | // what's the output device (eg: big TV, desktop monitor, phone display), etc. |
4399 | |
4400 | === modified file 'qml/Panel/Handle.qml' |
4401 | --- qml/Panel/Handle.qml 2016-03-08 20:59:14 +0000 |
4402 | +++ qml/Panel/Handle.qml 2016-03-11 11:34:41 +0000 |
4403 | @@ -19,7 +19,7 @@ |
4404 | |
4405 | Rectangle { |
4406 | id: handle |
4407 | - color: UbuntuColors.slate |
4408 | + color: theme.palette.normal.foreground |
4409 | height: units.gu(2) |
4410 | property bool active: false |
4411 | |
4412 | @@ -35,7 +35,7 @@ |
4413 | id: dot |
4414 | width: units.dp(3) |
4415 | height: width |
4416 | - color: handle.active ? UbuntuColors.orange : UbuntuColors.ash |
4417 | + color: handle.active ? theme.palette.highlighted.foreground : theme.palette.normal.raised |
4418 | radius: units.dp(1) |
4419 | } |
4420 | } |
4421 | |
4422 | === modified file 'qml/Panel/Indicators/MenuItemFactory.qml' |
4423 | --- qml/Panel/Indicators/MenuItemFactory.qml 2016-03-08 20:59:14 +0000 |
4424 | +++ qml/Panel/Indicators/MenuItemFactory.qml 2016-03-11 11:34:41 +0000 |
4425 | @@ -228,7 +228,6 @@ |
4426 | text: menuData && menuData.label || "" |
4427 | iconSource: menuData && menuData.icon || "" |
4428 | value : menuData && menuData.actionState || 0.0 |
4429 | - enabled: menuData && menuData.sensitive || false |
4430 | highlightWhenPressed: false |
4431 | } |
4432 | } |
4433 | |
4434 | === modified file 'qml/Panel/IndicatorsMenu.qml' |
4435 | --- qml/Panel/IndicatorsMenu.qml 2016-03-08 20:59:14 +0000 |
4436 | +++ qml/Panel/IndicatorsMenu.qml 2016-03-11 11:34:41 +0000 |
4437 | @@ -38,7 +38,7 @@ |
4438 | property bool enableHint: true |
4439 | property bool contentEnabled: true |
4440 | property bool showOnClick: true |
4441 | - property color panelColor: theme.palette.normal.background |
4442 | + property color panelColor: UbuntuColors.jet |
4443 | |
4444 | signal showTapped(point position) |
4445 | |
4446 | |
4447 | === modified file 'qml/Panel/Panel.qml' |
4448 | --- qml/Panel/Panel.qml 2016-03-08 20:59:14 +0000 |
4449 | +++ qml/Panel/Panel.qml 2016-03-11 11:34:41 +0000 |
4450 | @@ -89,7 +89,7 @@ |
4451 | |
4452 | Rectangle { |
4453 | id: indicatorAreaBackground |
4454 | - color: callHint.visible ? UbuntuColors.green : theme.palette.normal.background |
4455 | + color: callHint.visible ? UbuntuColors.green : indicators.panelColor |
4456 | anchors { |
4457 | top: parent.top |
4458 | left: parent.left |
4459 | @@ -169,8 +169,10 @@ |
4460 | objectName: "windowDecorationTitle" |
4461 | anchors { |
4462 | left: parent.left |
4463 | + right: __indicators.left |
4464 | top: parent.top |
4465 | leftMargin: units.gu(1) |
4466 | + rightMargin: units.gu(1) |
4467 | topMargin: units.gu(0.5) |
4468 | bottomMargin: units.gu(0.5) |
4469 | } |
4470 | @@ -181,6 +183,8 @@ |
4471 | fontSize: "medium" |
4472 | font.weight: Font.Normal |
4473 | text: PanelState.title |
4474 | + elide: Text.ElideRight |
4475 | + maximumLineCount: 1 |
4476 | } |
4477 | |
4478 | // TODO here would the Locally integrated menus come |
4479 | |
4480 | === modified file 'qml/ScopeTool.qml' |
4481 | --- qml/ScopeTool.qml 2015-07-15 15:07:19 +0000 |
4482 | +++ qml/ScopeTool.qml 2016-03-11 11:34:41 +0000 |
4483 | @@ -52,14 +52,6 @@ |
4484 | color: "#FCFCFC" |
4485 | } |
4486 | |
4487 | - Image { |
4488 | - anchors.fill: dashContent |
4489 | - source: root.width > root.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png" |
4490 | - fillMode: Image.PreserveAspectCrop |
4491 | - horizontalAlignment: Image.AlignRight |
4492 | - verticalAlignment: Image.AlignTop |
4493 | - } |
4494 | - |
4495 | DashContent { |
4496 | id: dashContent |
4497 | |
4498 | |
4499 | === modified file 'qml/Shell.qml' |
4500 | --- qml/Shell.qml 2016-03-08 20:59:08 +0000 |
4501 | +++ qml/Shell.qml 2016-03-11 11:34:41 +0000 |
4502 | @@ -25,6 +25,7 @@ |
4503 | import Unity.Connectivity 0.1 |
4504 | import Unity.Launcher 0.1 |
4505 | import GlobalShortcut 1.0 // has to be before Utils, because of WindowKeysFilter |
4506 | +import GSettings 1.0 |
4507 | import Utils 0.1 |
4508 | import Powerd 0.1 |
4509 | import SessionBroadcast 0.1 |
4510 | @@ -187,6 +188,11 @@ |
4511 | } |
4512 | } |
4513 | |
4514 | + GSettings { |
4515 | + id: settings |
4516 | + schema.id: "com.canonical.Unity8" |
4517 | + } |
4518 | + |
4519 | Item { |
4520 | id: stages |
4521 | objectName: "stages" |
4522 | @@ -343,6 +349,11 @@ |
4523 | property: "altTabPressed" |
4524 | value: physicalKeysMapper.altTabPressed |
4525 | } |
4526 | + Binding { |
4527 | + target: applicationsDisplayLoader.item |
4528 | + property: "leftMargin" |
4529 | + value: shell.usageScenario == "desktop" && !settings.autohideLauncher ? launcher.panelWidth: 0 |
4530 | + } |
4531 | } |
4532 | |
4533 | Tutorial { |
4534 | @@ -373,7 +384,11 @@ |
4535 | InputMethod { |
4536 | id: inputMethod |
4537 | objectName: "inputMethod" |
4538 | - anchors { fill: parent; topMargin: panel.panelHeight } |
4539 | + anchors { |
4540 | + fill: parent |
4541 | + topMargin: panel.panelHeight |
4542 | + leftMargin: launcher.lockedVisible ? launcher.panelWidth : 0 |
4543 | + } |
4544 | z: notifications.useModal || panel.indicators.shown || wizard.active ? overlay.z + 1 : overlay.z - 1 |
4545 | } |
4546 | |
4547 | @@ -557,6 +572,10 @@ |
4548 | && !greeter.hasLockedApp |
4549 | inverted: shell.usageScenario !== "desktop" |
4550 | shadeBackground: !tutorial.running |
4551 | + superPressed: physicalKeysMapper.superPressed |
4552 | + superTabPressed: physicalKeysMapper.superTabPressed |
4553 | + panelWidth: units.gu(settings.launcherWidth) |
4554 | + lockedVisible: shell.usageScenario == "desktop" && !settings.autohideLauncher && !panel.fullscreenMode |
4555 | |
4556 | onShowDashHome: showHome() |
4557 | onDash: showDash() |
4558 | @@ -576,6 +595,37 @@ |
4559 | panel.indicators.hide() |
4560 | } |
4561 | } |
4562 | + onFocusChanged: { |
4563 | + if (!focus) { |
4564 | + applicationsDisplayLoader.focus = true; |
4565 | + } |
4566 | + } |
4567 | + |
4568 | + GlobalShortcut { |
4569 | + shortcut: Qt.AltModifier | Qt.Key_F1 |
4570 | + onTriggered: { |
4571 | + launcher.openForKeyboardNavigation(); |
4572 | + } |
4573 | + } |
4574 | + GlobalShortcut { |
4575 | + shortcut: Qt.MetaModifier | Qt.Key_0 |
4576 | + onTriggered: { |
4577 | + if (LauncherModel.get(9)) { |
4578 | + activateApplication(LauncherModel.get(9).appId); |
4579 | + } |
4580 | + } |
4581 | + } |
4582 | + Repeater { |
4583 | + model: 9 |
4584 | + GlobalShortcut { |
4585 | + shortcut: Qt.MetaModifier | (Qt.Key_1 + index) |
4586 | + onTriggered: { |
4587 | + if (LauncherModel.get(index)) { |
4588 | + activateApplication(LauncherModel.get(index).appId); |
4589 | + } |
4590 | + } |
4591 | + } |
4592 | + } |
4593 | } |
4594 | |
4595 | Wizard { |
4596 | |
4597 | === modified file 'qml/Stages/AbstractStage.qml' |
4598 | --- qml/Stages/AbstractStage.qml 2016-01-14 13:03:20 +0000 |
4599 | +++ qml/Stages/AbstractStage.qml 2016-03-11 11:34:41 +0000 |
4600 | @@ -21,7 +21,7 @@ |
4601 | Rectangle { |
4602 | id: root |
4603 | |
4604 | - color: "#111111" |
4605 | + color: "#060606" |
4606 | |
4607 | // Controls to be set from outside |
4608 | property bool altTabPressed |
4609 | @@ -39,6 +39,8 @@ |
4610 | property int shellOrientationAngle |
4611 | property bool spreadEnabled: true // If false, animations and right edge will be disabled |
4612 | property bool suspended |
4613 | + // A Stage should paint a wallpaper etc over its full size but not use the margins for window placement |
4614 | + property int leftMargin: 0 |
4615 | |
4616 | // To be read from outside |
4617 | property var mainApp: null |
4618 | |
4619 | === modified file 'qml/Stages/DesktopSpread.qml' |
4620 | --- qml/Stages/DesktopSpread.qml 2015-11-24 17:44:18 +0000 |
4621 | +++ qml/Stages/DesktopSpread.qml 2016-03-11 11:34:41 +0000 |
4622 | @@ -19,6 +19,7 @@ |
4623 | import Ubuntu.Components 1.3 |
4624 | import Ubuntu.Gestures 0.1 |
4625 | import Unity.Application 0.1 |
4626 | +import "../Components" |
4627 | |
4628 | FocusScope { |
4629 | id: root |
4630 | @@ -26,8 +27,11 @@ |
4631 | property bool altTabPressed: false |
4632 | property Item workspace: null |
4633 | |
4634 | + readonly property alias ready: blurLayer.ready |
4635 | readonly property alias highlightedIndex: spreadRepeater.highlightedIndex |
4636 | |
4637 | + signal playFocusAnimation(int index) |
4638 | + |
4639 | function show() { |
4640 | spreadContainer.animateIn = true; |
4641 | root.state = "altTab"; |
4642 | @@ -91,6 +95,9 @@ |
4643 | |
4644 | function focusSelected() { |
4645 | if (spreadRepeater.highlightedIndex != -1) { |
4646 | + if (spreadContainer.visible) { |
4647 | + root.playFocusAnimation(spreadRepeater.highlightedIndex) |
4648 | + } |
4649 | var application = ApplicationManager.get(spreadRepeater.highlightedIndex); |
4650 | ApplicationManager.requestFocusApplication(application.appId); |
4651 | } |
4652 | @@ -101,6 +108,31 @@ |
4653 | state = "" |
4654 | } |
4655 | |
4656 | + BlurLayer { |
4657 | + id: blurLayer |
4658 | + anchors.fill: parent |
4659 | + source: root.workspace |
4660 | + visible: false |
4661 | + } |
4662 | + |
4663 | + Rectangle { |
4664 | + id: spreadBackground |
4665 | + anchors.fill: parent |
4666 | + color: "#B2000000" |
4667 | + visible: false |
4668 | + opacity: visible ? 1 : 0 |
4669 | + Behavior on opacity { |
4670 | + UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4671 | + } |
4672 | + } |
4673 | + |
4674 | + MouseArea { |
4675 | + id: eventEater |
4676 | + anchors.fill: parent |
4677 | + visible: spreadBackground.visible |
4678 | + enabled: visible |
4679 | + } |
4680 | + |
4681 | Item { |
4682 | id: spreadContainer |
4683 | objectName: "spreadContainer" |
4684 | @@ -226,13 +258,20 @@ |
4685 | Transition { |
4686 | from: "" |
4687 | to: "altTab" |
4688 | - PropertyAction { target: spreadDelegate; properties: "y,height,width,angle,z,itemScale,itemScaleOriginY,visible" } |
4689 | - PropertyAction { target: clippedSpreadDelegate; properties: "anchors.topMargin" } |
4690 | - PropertyAnimation { |
4691 | - target: spreadDelegate; properties: "x" |
4692 | - from: root.width |
4693 | - duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration :0 |
4694 | - easing: UbuntuAnimation.StandardEasing |
4695 | + SequentialAnimation { |
4696 | + ParallelAnimation { |
4697 | + PropertyAction { target: spreadDelegate; properties: "y,height,width,angle,z,itemScale,itemScaleOriginY,visible" } |
4698 | + PropertyAction { target: clippedSpreadDelegate; properties: "anchors.topMargin" } |
4699 | + PropertyAnimation { |
4700 | + target: spreadDelegate; properties: "x" |
4701 | + from: root.width |
4702 | + duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration :0 |
4703 | + easing: UbuntuAnimation.StandardEasing |
4704 | + } |
4705 | + UbuntuNumberAnimation { target: clippedSpreadDelegate; property: "shadowOpacity"; from: 0; to: spreadMaths.shadowOpacity; duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration : 0 } |
4706 | + UbuntuNumberAnimation { target: tileInfo; property: "opacity"; from: 0; to: spreadMaths.tileInfoOpacity; duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration : 0 } |
4707 | + } |
4708 | + PropertyAction { target: spreadSelectArea; property: "enabled" } |
4709 | } |
4710 | } |
4711 | ] |
4712 | @@ -240,7 +279,11 @@ |
4713 | MouseArea { |
4714 | id: tileInfo |
4715 | objectName: "tileInfo" |
4716 | - anchors { left: parent.left; top: clippedSpreadDelegate.bottom; topMargin: units.gu(5) } |
4717 | + anchors { |
4718 | + left: parent.left |
4719 | + top: clippedSpreadDelegate.bottom |
4720 | + topMargin: ((spreadMaths.sceneHeight - spreadDelegate.y) - clippedSpreadDelegate.height) * 0.2 |
4721 | + } |
4722 | property int nextItemX: spreadRepeater.count > index + 1 ? spreadRepeater.itemAt(index + 1).x : spreadDelegate.x + units.gu(30) |
4723 | width: Math.min(units.gu(30), nextItemX - spreadDelegate.x) |
4724 | height: titleInfoColumn.height |
4725 | @@ -262,12 +305,20 @@ |
4726 | anchors { left: parent.left; top: parent.top; right: parent.right } |
4727 | spacing: units.gu(1) |
4728 | |
4729 | - UbuntuShape { |
4730 | + UbuntuShapeForItem { |
4731 | Layout.preferredHeight: Math.min(units.gu(6), root.height * .05) |
4732 | Layout.preferredWidth: height * 8 / 7.6 |
4733 | image: Image { |
4734 | anchors.fill: parent |
4735 | source: model.icon |
4736 | + Rectangle { |
4737 | + anchors.fill: parent |
4738 | + color: "black" |
4739 | + opacity: clippedSpreadDelegate.highlightShown ? 0 : .1 |
4740 | + Behavior on opacity { |
4741 | + UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4742 | + } |
4743 | + } |
4744 | } |
4745 | } |
4746 | Label { |
4747 | @@ -420,7 +471,7 @@ |
4748 | |
4749 | property var source: ShaderEffectSource { |
4750 | id: shaderEffectSource |
4751 | - sourceItem: appContainer |
4752 | + sourceItem: root.workspace |
4753 | } |
4754 | |
4755 | fragmentShader: " |
4756 | @@ -494,20 +545,17 @@ |
4757 | from: "*" |
4758 | to: "altTab" |
4759 | SequentialAnimation { |
4760 | - PropertyAction { target: hoverMouseArea; property: "progressiveScrollingEnabled"; value: false } |
4761 | PropertyAction { target: spreadRepeater; property: "highlightedIndex"; value: Math.min(ApplicationManager.count - 1, 1) } |
4762 | - PauseAnimation { duration: 140 } |
4763 | + PauseAnimation { duration: spreadContainer.animateIn ? 0 : 140 } |
4764 | PropertyAction { target: workspaceSelector; property: "visible" } |
4765 | PropertyAction { target: spreadContainer; property: "visible" } |
4766 | ParallelAnimation { |
4767 | - UbuntuNumberAnimation { |
4768 | - target: blurLayer; properties: "saturation,blurRadius"; |
4769 | - duration: spreadContainer.animateIn ? UbuntuAnimation.FastDuration : 0 |
4770 | - } |
4771 | + UbuntuNumberAnimation { target: blurLayer; properties: "saturation,blurRadius"; duration: UbuntuAnimation.SnapDuration } |
4772 | PropertyAction { target: spreadFlickable; property: "visible" } |
4773 | PropertyAction { targets: [currentSelectedLabel,spreadBackground]; property: "visible" } |
4774 | PropertyAction { target: spreadFlickable; property: "contentX"; value: 0 } |
4775 | } |
4776 | + PropertyAction { target: hoverMouseArea; properties: "enabled,progressiveScrollingEnabled"; value: false } |
4777 | } |
4778 | }, |
4779 | Transition { |
4780 | @@ -518,6 +566,5 @@ |
4781 | PropertyAction { target: spreadRepeater; property: "highlightedIndex"; value: -1 } |
4782 | PropertyAction { target: spreadContainer; property: "animateIn"; value: false } |
4783 | } |
4784 | - |
4785 | ] |
4786 | } |
4787 | |
4788 | === modified file 'qml/Stages/DesktopSpreadDelegate.qml' |
4789 | --- qml/Stages/DesktopSpreadDelegate.qml 2015-12-01 12:17:24 +0000 |
4790 | +++ qml/Stages/DesktopSpreadDelegate.qml 2016-03-11 11:34:41 +0000 |
4791 | @@ -56,6 +56,11 @@ |
4792 | } |
4793 | ] |
4794 | |
4795 | + scale: highlightShown ? 1.025 : 1 |
4796 | + Behavior on scale { |
4797 | + UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4798 | + } |
4799 | + |
4800 | BorderImage { |
4801 | anchors { |
4802 | fill: root |
4803 | @@ -70,7 +75,7 @@ |
4804 | anchors.fill: parent |
4805 | anchors.margins: -units.gu(1) |
4806 | color: "white" |
4807 | - opacity: highlightShown ? 0.15 : 0 |
4808 | + opacity: highlightShown ? 0.55 : 0 |
4809 | antialiasing: true |
4810 | } |
4811 | |
4812 | @@ -108,4 +113,13 @@ |
4813 | ] |
4814 | } |
4815 | } |
4816 | + |
4817 | + Rectangle { |
4818 | + anchors.fill: parent |
4819 | + color: "black" |
4820 | + opacity: root.highlightShown ? 0 : .1 |
4821 | + Behavior on opacity { |
4822 | + UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } |
4823 | + } |
4824 | + } |
4825 | } |
4826 | |
4827 | === modified file 'qml/Stages/DesktopStage.qml' |
4828 | --- qml/Stages/DesktopStage.qml 2016-02-03 14:00:47 +0000 |
4829 | +++ qml/Stages/DesktopStage.qml 2016-03-11 11:34:41 +0000 |
4830 | @@ -224,6 +224,7 @@ |
4831 | PanelState.dropShadow = false; |
4832 | } |
4833 | |
4834 | + |
4835 | FocusScope { |
4836 | id: appContainer |
4837 | objectName: "appContainer" |
4838 | @@ -274,6 +275,7 @@ |
4839 | readonly property alias maximizedLeft: appDelegatePrivate.maximizedLeft |
4840 | readonly property alias maximizedRight: appDelegatePrivate.maximizedRight |
4841 | readonly property alias minimized: appDelegatePrivate.minimized |
4842 | + readonly property alias fullscreen: decoratedWindow.fullscreen |
4843 | |
4844 | readonly property string appId: model.appId |
4845 | property bool animationsEnabled: true |
4846 | @@ -293,6 +295,7 @@ |
4847 | visible: !visuallyMinimized && |
4848 | !greeter.fullyShown && |
4849 | (priv.foregroundMaximizedAppZ === -1 || priv.foregroundMaximizedAppZ <= z) || |
4850 | + decoratedWindow.fullscreen || |
4851 | (spread.state == "altTab" && index === spread.highlightedIndex) |
4852 | |
4853 | Binding { |
4854 | @@ -348,13 +351,26 @@ |
4855 | ApplicationManager.focusApplication(appId); |
4856 | } |
4857 | |
4858 | + function playFocusAnimation() { |
4859 | + focusAnimation.start() |
4860 | + } |
4861 | + |
4862 | + UbuntuNumberAnimation { |
4863 | + id: focusAnimation |
4864 | + target: appDelegate |
4865 | + property: "scale" |
4866 | + from: 0.98 |
4867 | + to: 1 |
4868 | + duration: UbuntuAnimation.SnapDuration |
4869 | + } |
4870 | + |
4871 | states: [ |
4872 | State { |
4873 | name: "fullscreen"; when: decoratedWindow.fullscreen |
4874 | - extend: "maximized" |
4875 | PropertyChanges { |
4876 | target: appDelegate; |
4877 | - y: -PanelState.panelHeight |
4878 | + x: 0; y: -PanelState.panelHeight |
4879 | + requestedWidth: appContainer.width; requestedHeight: appContainer.height; |
4880 | } |
4881 | }, |
4882 | State { |
4883 | @@ -371,21 +387,21 @@ |
4884 | name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized |
4885 | PropertyChanges { |
4886 | target: appDelegate; |
4887 | - x: 0; y: 0; |
4888 | - requestedWidth: root.width; requestedHeight: root.height; |
4889 | + x: root.leftMargin; y: 0; |
4890 | + requestedWidth: appContainer.width - root.leftMargin; requestedHeight: appContainer.height; |
4891 | visuallyMinimized: false; |
4892 | visuallyMaximized: true |
4893 | } |
4894 | }, |
4895 | State { |
4896 | name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized |
4897 | - PropertyChanges { target: appDelegate; x: 0; y: PanelState.panelHeight; |
4898 | - requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight } |
4899 | + PropertyChanges { target: appDelegate; x: root.leftMargin; y: PanelState.panelHeight; |
4900 | + requestedWidth: (appContainer.width - root.leftMargin)/2; requestedHeight: appContainer.height - PanelState.panelHeight } |
4901 | }, |
4902 | State { |
4903 | name: "maximizedRight"; when: appDelegate.maximizedRight && !appDelegate.minimized |
4904 | - PropertyChanges { target: appDelegate; x: root.width/2; y: PanelState.panelHeight; |
4905 | - requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight } |
4906 | + PropertyChanges { target: appDelegate; x: (appContainer.width + root.leftMargin)/2; y: PanelState.panelHeight; |
4907 | + requestedWidth: (appContainer.width - root.leftMargin)/2; requestedHeight: appContainer.height - PanelState.panelHeight } |
4908 | }, |
4909 | State { |
4910 | name: "minimized"; when: appDelegate.minimized |
4911 | @@ -438,7 +454,7 @@ |
4912 | target: appDelegate |
4913 | property: "z" |
4914 | value: ApplicationManager.count + 1 |
4915 | - when: index == spread.highlightedIndex && blurLayer.ready |
4916 | + when: index == spread.highlightedIndex && spread.ready |
4917 | } |
4918 | |
4919 | WindowResizeArea { |
4920 | @@ -448,8 +464,9 @@ |
4921 | minHeight: units.gu(10) |
4922 | borderThickness: units.gu(2) |
4923 | windowId: model.appId // FIXME: Change this to point to windowId once we have such a thing |
4924 | - screenWidth: root.width |
4925 | - screenHeight: root.height |
4926 | + screenWidth: appContainer.width |
4927 | + screenHeight: appContainer.height |
4928 | + leftMargin: root.leftMargin |
4929 | |
4930 | onPressed: { ApplicationManager.focusApplication(model.appId) } |
4931 | } |
4932 | @@ -473,27 +490,6 @@ |
4933 | } |
4934 | } |
4935 | |
4936 | - BlurLayer { |
4937 | - id: blurLayer |
4938 | - anchors.fill: parent |
4939 | - source: appContainer |
4940 | - visible: false |
4941 | - } |
4942 | - |
4943 | - Rectangle { |
4944 | - id: spreadBackground |
4945 | - anchors.fill: parent |
4946 | - color: "#55000000" |
4947 | - visible: false |
4948 | - } |
4949 | - |
4950 | - MouseArea { |
4951 | - id: eventEater |
4952 | - anchors.fill: parent |
4953 | - visible: spreadBackground.visible |
4954 | - enabled: visible |
4955 | - } |
4956 | - |
4957 | EdgeBarrier { |
4958 | id: edgeBarrier |
4959 | |
4960 | @@ -509,7 +505,7 @@ |
4961 | rotation: 90 |
4962 | anchors.centerIn: parent |
4963 | gradient: Gradient { |
4964 | - GradientStop { position: 0.0; color: Qt.rgba(0.16,0.16,0.16,0.7)} |
4965 | + GradientStop { position: 0.0; color: Qt.rgba(0.16,0.16,0.16,0.5)} |
4966 | GradientStop { position: 1.0; color: Qt.rgba(0.16,0.16,0.16,0)} |
4967 | } |
4968 | } |
4969 | @@ -527,9 +523,13 @@ |
4970 | DesktopSpread { |
4971 | id: spread |
4972 | objectName: "spread" |
4973 | - anchors.fill: parent |
4974 | + anchors.fill: appContainer |
4975 | workspace: appContainer |
4976 | focus: state == "altTab" |
4977 | altTabPressed: root.altTabPressed |
4978 | + |
4979 | + onPlayFocusAnimation: { |
4980 | + appRepeater.itemAt(index).playFocusAnimation(); |
4981 | + } |
4982 | } |
4983 | } |
4984 | |
4985 | === modified file 'qml/Stages/PhoneStage.qml' |
4986 | --- qml/Stages/PhoneStage.qml 2016-01-14 13:03:20 +0000 |
4987 | +++ qml/Stages/PhoneStage.qml 2016-03-11 11:34:41 +0000 |
4988 | @@ -44,6 +44,33 @@ |
4989 | } |
4990 | } |
4991 | |
4992 | + onAltTabPressedChanged: { |
4993 | + if (!spreadEnabled || !altTabEnabled) { |
4994 | + return; |
4995 | + } |
4996 | + if (altTabPressed) { |
4997 | + spreadView.snapToSpread(); |
4998 | + priv.highlightIndex = Math.min(spreadRepeater.count - 1, 1); |
4999 | + } else { |
5000 | + spreadView.snapTo(priv.highlightIndex) |
The diff has been truncated for viewing.