Merge lp:~nick-dedekind/unity8/multi-monitor into lp:unity8
- multi-monitor
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~nick-dedekind/unity8/multi-monitor |
Merge into: | lp:unity8 |
Diff against target: |
3616 lines (+1262/-646) 73 files modified
debian/control (+1/-1) debian/unity8.install (+5/-0) plugins/Cursor/CMakeLists.txt (+1/-0) plugins/Cursor/InputDispatcherFilter.cpp (+175/-0) plugins/Cursor/InputDispatcherFilter.h (+62/-0) plugins/Cursor/MousePointer.cpp (+65/-80) plugins/Cursor/MousePointer.h (+5/-4) plugins/GlobalShortcut/globalshortcut.cpp (+0/-15) plugins/GlobalShortcut/globalshortcut.h (+0/-4) plugins/GlobalShortcut/globalshortcutregistry.cpp (+23/-15) plugins/GlobalShortcut/globalshortcutregistry.h (+2/-2) plugins/UInput/plugin.cpp (+7/-1) qml/ApplicationMenus/ApplicationMenuItemFactory.qml (+4/-4) qml/ApplicationMenus/MenuBar.qml (+5/-1) qml/ApplicationMenus/MenuItem.qml (+2/-0) qml/ApplicationMenus/MenuPopup.qml (+4/-1) qml/CMakeLists.txt (+1/-1) qml/Components/PanelState/PanelState.qml (+0/-1) qml/Components/PanelState/qmldir (+1/-1) qml/Components/VirtualTouchPad.qml (+13/-19) qml/DisabledScreenNotice.qml (+2/-1) qml/ErrorApplication.qml (+67/-0) qml/Greeter/Greeter.qml (+21/-3) qml/Greeter/SecondaryGreeter.qml (+75/-0) qml/OrientedShell.qml (+5/-7) qml/Panel/Panel.qml (+17/-15) qml/Shell.qml (+29/-11) qml/ShellApplication.qml (+52/-0) qml/ShellNotifier.qml (+30/-0) qml/ShellScreen.qml (+66/-0) qml/Stage/DecoratedWindow.qml (+3/-1) qml/Stage/FakeMaximizeDelegate.qml (+12/-11) qml/Stage/Stage.qml (+13/-10) qml/Stage/WindowDecoration.qml (+2/-0) qml/qmldir (+1/-0) src/ApplicationArguments.cpp (+12/-3) src/ApplicationArguments.h (+19/-17) src/CMakeLists.txt (+0/-2) src/SecondaryWindow.cpp (+0/-40) src/SecondaryWindow.h (+0/-30) src/ShellApplication.cpp (+30/-105) src/ShellApplication.h (+1/-13) src/ShellView.cpp (+0/-85) src/ShellView.h (+0/-34) src/UnityCommandLineParser.h (+1/-1) tests/mocks/Cursor/Cursor.qml (+50/-3) tests/mocks/GSettings.1.0/plugin.cpp (+12/-0) tests/mocks/GSettings.1.0/plugin.h (+1/-0) tests/mocks/UInput/plugin.cpp (+6/-1) tests/mocks/Unity/Application/SurfaceManager.cpp (+1/-1) tests/mocks/Unity/InputInfo/mockcontroller.cpp (+10/-0) tests/mocks/Unity/InputInfo/mockcontroller.h (+3/-1) tests/mocks/Unity/InputInfo/plugin.cpp (+1/-2) tests/mocks/Unity/Screens/CMakeLists.txt (+2/-1) tests/mocks/Unity/Screens/plugin.cpp (+14/-1) tests/mocks/Unity/Screens/screens.cpp (+52/-9) tests/mocks/Unity/Screens/screens.h (+87/-7) tests/mocks/Unity/Screens/screenwindow.cpp (+35/-0) tests/mocks/Unity/Screens/screenwindow.h (+42/-0) tests/plugins/GlobalShortcut/GlobalShortcutTest.cpp (+1/-0) tests/qmltests/ApplicationMenus/tst_MenuBar.qml (+2/-0) tests/qmltests/ApplicationMenus/tst_MenuPopup.qml (+2/-0) tests/qmltests/Components/tst_VirtualTouchPad.qml (+2/-2) tests/qmltests/Panel/tst_Panel.qml (+18/-14) tests/qmltests/Stage/tst_DecoratedWindow.qml (+5/-1) tests/qmltests/Stage/tst_DesktopStage.qml (+6/-4) tests/qmltests/Stage/tst_PhoneStage.qml (+2/-0) tests/qmltests/Stage/tst_WindowResizeArea.qml (+1/-8) tests/qmltests/Tutorial/tst_Tutorial.qml (+9/-17) tests/qmltests/tst_OrientedShell.qml (+25/-5) tests/qmltests/tst_Shell.qml (+30/-17) tests/qmltests/tst_ShellWithPin.qml (+7/-13) tests/uqmlscene/main.cpp (+2/-0) |
To merge this branch: | bzr merge lp:~nick-dedekind/unity8/multi-monitor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Unity Team | Pending | ||
Review via email: mp+314835@code.launchpad.net |
Commit message
multimonitor support
Description of the change
Prereq-archive: ppa:ci-
WIP - putting to needs review to get jenkins' opinion
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2787
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 2790. By Nick Dedekind
-
panelState fixes
- 2791. By Nick Dedekind
-
Fixed PhoneStage & ShellWithPin tests
- 2792. By Nick Dedekind
-
Stage fixes for panelState
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2792
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 2793. By Nick Dedekind
-
more test fixes
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2793
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2794
https:/
Executed test runs:
Click here to trigger a rebuild:
https:/
- 2794. By Nick Dedekind
-
Added requestActivate to view
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:2794
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2794
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 2795. By Nick Dedekind
-
merged with trunk
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2795
https:/
Executed test runs:
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2795
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 2795. By Nick Dedekind
-
merged with trunk
- 2794. By Nick Dedekind
-
Added requestActivate to view
- 2793. By Nick Dedekind
-
more test fixes
- 2792. By Nick Dedekind
-
Stage fixes for panelState
- 2791. By Nick Dedekind
-
Fixed PhoneStage & ShellWithPin tests
- 2790. By Nick Dedekind
-
panelState fixes
- 2789. By Nick Dedekind
-
Panel bidnings for app menus
- 2788. By Nick Dedekind
-
Fixed shortcuts parented to non QuickItems
- 2787. By Nick Dedekind
-
removed Unity.Debug import
- 2786. By Nick Dedekind
-
fixed surfaceManager in tstShell
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2017-03-20 10:19:11 +0000 | |||
3 | +++ debian/control 2017-03-31 15:02:41 +0000 | |||
4 | @@ -40,7 +40,7 @@ | |||
5 | 40 | libubuntugestures5-private-dev (>= 1.3.2030), | 40 | libubuntugestures5-private-dev (>= 1.3.2030), |
6 | 41 | libudev-dev, | 41 | libudev-dev, |
7 | 42 | libudm-common-dev, | 42 | libudm-common-dev, |
9 | 43 | libunity-api-dev (>= 8.6), | 43 | libunity-api-dev (>= 8.7), |
10 | 44 | libusermetricsoutput1-dev, | 44 | libusermetricsoutput1-dev, |
11 | 45 | # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop | 45 | # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop |
12 | 46 | libx11-dev[!arm64 !armhf], | 46 | libx11-dev[!arm64 !armhf], |
13 | 47 | 47 | ||
14 | === modified file 'debian/unity8.install' | |||
15 | --- debian/unity8.install 2016-10-04 16:21:38 +0000 | |||
16 | +++ debian/unity8.install 2017-03-31 15:02:41 +0000 | |||
17 | @@ -16,7 +16,12 @@ | |||
18 | 16 | usr/share/unity8/DeviceConfiguration.qml | 16 | usr/share/unity8/DeviceConfiguration.qml |
19 | 17 | usr/share/unity8/OrientedShell.qml | 17 | usr/share/unity8/OrientedShell.qml |
20 | 18 | usr/share/unity8/DisabledScreenNotice.qml | 18 | usr/share/unity8/DisabledScreenNotice.qml |
21 | 19 | usr/share/unity8/ErrorApplication.qml | ||
22 | 20 | usr/share/unity8/qmldir | ||
23 | 19 | usr/share/unity8/Shell.qml | 21 | usr/share/unity8/Shell.qml |
24 | 22 | usr/share/unity8/ShellApplication.qml | ||
25 | 23 | usr/share/unity8/ShellNotifier.qml | ||
26 | 24 | usr/share/unity8/ShellScreen.qml | ||
27 | 20 | usr/share/unity8/Stage | 25 | usr/share/unity8/Stage |
28 | 21 | usr/share/unity8/Tutorial | 26 | usr/share/unity8/Tutorial |
29 | 22 | usr/share/unity8/Wizard | 27 | usr/share/unity8/Wizard |
30 | 23 | 28 | ||
31 | === modified file 'plugins/Cursor/CMakeLists.txt' | |||
32 | --- plugins/Cursor/CMakeLists.txt 2016-11-28 09:57:06 +0000 | |||
33 | +++ plugins/Cursor/CMakeLists.txt 2017-03-31 15:02:41 +0000 | |||
34 | @@ -15,6 +15,7 @@ | |||
35 | 15 | CursorImageInfo.cpp | 15 | CursorImageInfo.cpp |
36 | 16 | CursorImageProvider.cpp | 16 | CursorImageProvider.cpp |
37 | 17 | MousePointer.cpp | 17 | MousePointer.cpp |
38 | 18 | InputDispatcherFilter.cpp | ||
39 | 18 | # We need to run moc on this header | 19 | # We need to run moc on this header |
40 | 19 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h | 20 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h |
41 | 20 | ) | 21 | ) |
42 | 21 | 22 | ||
43 | === added file 'plugins/Cursor/InputDispatcherFilter.cpp' | |||
44 | --- plugins/Cursor/InputDispatcherFilter.cpp 1970-01-01 00:00:00 +0000 | |||
45 | +++ plugins/Cursor/InputDispatcherFilter.cpp 2017-03-31 15:02:41 +0000 | |||
46 | @@ -0,0 +1,175 @@ | |||
47 | 1 | /* | ||
48 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
49 | 3 | * | ||
50 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
51 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
52 | 6 | * the Free Software Foundation. | ||
53 | 7 | * | ||
54 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
55 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
56 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
57 | 11 | * Lesser General Public License for more details. | ||
58 | 12 | * | ||
59 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
60 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
61 | 15 | */ | ||
62 | 16 | |||
63 | 17 | #include "InputDispatcherFilter.h" | ||
64 | 18 | #include "MousePointer.h" | ||
65 | 19 | |||
66 | 20 | #include <QEvent> | ||
67 | 21 | #include <QGuiApplication> | ||
68 | 22 | #include <QQuickWindow> | ||
69 | 23 | #include <QScreen> | ||
70 | 24 | #include <QtMath> | ||
71 | 25 | #include <qpa/qplatformnativeinterface.h> | ||
72 | 26 | #include <qpa/qplatformscreen.h> | ||
73 | 27 | |||
74 | 28 | InputDispatcherFilter *InputDispatcherFilter::instance() | ||
75 | 29 | { | ||
76 | 30 | static InputDispatcherFilter filter; | ||
77 | 31 | return &filter; | ||
78 | 32 | } | ||
79 | 33 | |||
80 | 34 | InputDispatcherFilter::InputDispatcherFilter(QObject *parent) | ||
81 | 35 | : QObject(parent) | ||
82 | 36 | , m_pushing(false) | ||
83 | 37 | { | ||
84 | 38 | QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); | ||
85 | 39 | m_inputDispatcher = static_cast<QObject*>(ni->nativeResourceForIntegration("InputDispatcher")); | ||
86 | 40 | if (m_inputDispatcher) { | ||
87 | 41 | m_inputDispatcher->installEventFilter(this); | ||
88 | 42 | } | ||
89 | 43 | } | ||
90 | 44 | |||
91 | 45 | void InputDispatcherFilter::registerPointer(MousePointer *pointer) | ||
92 | 46 | { | ||
93 | 47 | // allow first registered pointer to be visible. | ||
94 | 48 | m_pointers.insert(pointer); | ||
95 | 49 | } | ||
96 | 50 | |||
97 | 51 | void InputDispatcherFilter::unregisterPointer(MousePointer *pointer) | ||
98 | 52 | { | ||
99 | 53 | m_pointers.remove(pointer); | ||
100 | 54 | } | ||
101 | 55 | |||
102 | 56 | bool InputDispatcherFilter::eventFilter(QObject *o, QEvent *e) | ||
103 | 57 | { | ||
104 | 58 | if (o != m_inputDispatcher) return false; | ||
105 | 59 | |||
106 | 60 | switch (e->type()) { | ||
107 | 61 | case QEvent::MouseMove: | ||
108 | 62 | case QEvent::MouseButtonPress: | ||
109 | 63 | case QEvent::MouseButtonRelease: | ||
110 | 64 | { | ||
111 | 65 | // if we don't have any pointers, filter all mouse events. | ||
112 | 66 | auto pointer = currentPointer(); | ||
113 | 67 | if (!pointer) return true; | ||
114 | 68 | |||
115 | 69 | QMouseEvent* me = static_cast<QMouseEvent*>(e); | ||
116 | 70 | |||
117 | 71 | // Local position gives relative change of mouse pointer. | ||
118 | 72 | QPointF movement = me->localPos(); | ||
119 | 73 | |||
120 | 74 | // Adjust the position | ||
121 | 75 | QPointF oldPos = pointer->window()->geometry().topLeft() + pointer->position(); | ||
122 | 76 | QPointF newPos = adjustedPositionForMovement(oldPos, movement); | ||
123 | 77 | |||
124 | 78 | QScreen* currentScreen = screenAt(newPos); | ||
125 | 79 | if (currentScreen) { | ||
126 | 80 | QRect screenRect = currentScreen->geometry(); | ||
127 | 81 | qreal newX = (oldPos + movement).x(); | ||
128 | 82 | qreal newY = (oldPos + movement).y(); | ||
129 | 83 | |||
130 | 84 | if (newX <= screenRect.left() && newY < screenRect.top() + pointer->topBoundaryOffset()) { // top left corner | ||
131 | 85 | const auto distance = qSqrt(qPow(newX, 2) + qPow(newY- screenRect.top() - pointer->topBoundaryOffset(), 2)); | ||
132 | 86 | Q_EMIT pushedTopLeftCorner(currentScreen, qAbs(distance), me->buttons()); | ||
133 | 87 | m_pushing = true; | ||
134 | 88 | } else if (newX >= screenRect.right()-1 && newY < screenRect.top() + pointer->topBoundaryOffset()) { // top right corner | ||
135 | 89 | const auto distance = qSqrt(qPow(newX-screenRect.right(), 2) + qPow(newY - screenRect.top() - pointer->topBoundaryOffset(), 2)); | ||
136 | 90 | Q_EMIT pushedTopRightCorner(currentScreen, qAbs(distance), me->buttons()); | ||
137 | 91 | m_pushing = true; | ||
138 | 92 | } else if (newX < 0 && newY >= screenRect.bottom()-1) { // bottom left corner | ||
139 | 93 | const auto distance = qSqrt(qPow(newX, 2) + qPow(newY-screenRect.bottom(), 2)); | ||
140 | 94 | Q_EMIT pushedBottomLeftCorner(currentScreen, qAbs(distance), me->buttons()); | ||
141 | 95 | m_pushing = true; | ||
142 | 96 | } else if (newX >= screenRect.right()-1 && newY >= screenRect.bottom()-1) { // bottom right corner | ||
143 | 97 | const auto distance = qSqrt(qPow(newX-screenRect.right(), 2) + qPow(newY-screenRect.bottom(), 2)); | ||
144 | 98 | Q_EMIT pushedBottomRightCorner(currentScreen, qAbs(distance), me->buttons()); | ||
145 | 99 | m_pushing = true; | ||
146 | 100 | } else if (newX < screenRect.left()) { // left edge | ||
147 | 101 | Q_EMIT pushedLeftBoundary(currentScreen, qAbs(newX), me->buttons()); | ||
148 | 102 | m_pushing = true; | ||
149 | 103 | } else if (newX >= screenRect.right()) { // right edge | ||
150 | 104 | Q_EMIT pushedRightBoundary(currentScreen, newX - (screenRect.right() - 1), me->buttons()); | ||
151 | 105 | m_pushing = true; | ||
152 | 106 | } else if (newY < screenRect.top() + pointer->topBoundaryOffset()) { // top edge | ||
153 | 107 | Q_EMIT pushedTopBoundary(currentScreen, qAbs(newY - screenRect.top() - pointer->topBoundaryOffset()), me->buttons()); | ||
154 | 108 | m_pushing = true; | ||
155 | 109 | } else if (Q_LIKELY(newX > 0 && newX < screenRect.right()-1 && newY > 0 && newY < screenRect.bottom()-1)) { // normal pos, not pushing | ||
156 | 110 | if (m_pushing) { | ||
157 | 111 | Q_EMIT pushStopped(currentScreen); | ||
158 | 112 | m_pushing = false; | ||
159 | 113 | } | ||
160 | 114 | } | ||
161 | 115 | } | ||
162 | 116 | |||
163 | 117 | // Send the event | ||
164 | 118 | QMouseEvent eCopy(me->type(), me->localPos(), newPos, me->button(), me->buttons(), me->modifiers()); | ||
165 | 119 | eCopy.setTimestamp(me->timestamp()); | ||
166 | 120 | o->event(&eCopy); | ||
167 | 121 | return true; | ||
168 | 122 | } | ||
169 | 123 | default: | ||
170 | 124 | break; | ||
171 | 125 | } | ||
172 | 126 | return false; | ||
173 | 127 | } | ||
174 | 128 | |||
175 | 129 | QPointF InputDispatcherFilter::adjustedPositionForMovement(const QPointF &pt, const QPointF &movement) const | ||
176 | 130 | { | ||
177 | 131 | QPointF adjusted = pt + movement; | ||
178 | 132 | |||
179 | 133 | auto screen = screenAt(adjusted); // first check if our move was to a screen with an enabled pointer. | ||
180 | 134 | if (screen) { | ||
181 | 135 | return adjusted; | ||
182 | 136 | } else if ((screen = screenAt(pt))) { // then check if our old position was valid | ||
183 | 137 | QRectF screenBounds = screen->geometry(); | ||
184 | 138 | // bound the new position to the old screen geometry | ||
185 | 139 | adjusted.rx() = qMax(screenBounds.left(), qMin(adjusted.x(), screenBounds.right()-1)); | ||
186 | 140 | adjusted.ry() = qMax(screenBounds.top(), qMin(adjusted.y(), screenBounds.bottom()-1)); | ||
187 | 141 | } else { | ||
188 | 142 | auto screens = QGuiApplication::screens(); | ||
189 | 143 | |||
190 | 144 | // center of first screen with a pointer. | ||
191 | 145 | Q_FOREACH(QScreen* screen, screens) { | ||
192 | 146 | Q_FOREACH(MousePointer* pointer, m_pointers) { | ||
193 | 147 | if (pointer->isEnabled() && pointer->screen() == screen) { | ||
194 | 148 | return screen->geometry().center(); | ||
195 | 149 | } | ||
196 | 150 | } | ||
197 | 151 | } | ||
198 | 152 | } | ||
199 | 153 | return adjusted; | ||
200 | 154 | } | ||
201 | 155 | |||
202 | 156 | QScreen *InputDispatcherFilter::screenAt(const QPointF &pt) const | ||
203 | 157 | { | ||
204 | 158 | Q_FOREACH(MousePointer* pointer, m_pointers) { | ||
205 | 159 | if (!pointer->isEnabled()) continue; | ||
206 | 160 | |||
207 | 161 | QScreen* screen = pointer->screen(); | ||
208 | 162 | if (screen && screen->geometry().contains(pt.toPoint())) | ||
209 | 163 | return screen; | ||
210 | 164 | } | ||
211 | 165 | return nullptr; | ||
212 | 166 | } | ||
213 | 167 | |||
214 | 168 | MousePointer *InputDispatcherFilter::currentPointer() const | ||
215 | 169 | { | ||
216 | 170 | Q_FOREACH(MousePointer* pointer, m_pointers) { | ||
217 | 171 | if (!pointer->isEnabled()) continue; | ||
218 | 172 | return pointer; | ||
219 | 173 | } | ||
220 | 174 | return nullptr; | ||
221 | 175 | } | ||
222 | 0 | 176 | ||
223 | === added file 'plugins/Cursor/InputDispatcherFilter.h' | |||
224 | --- plugins/Cursor/InputDispatcherFilter.h 1970-01-01 00:00:00 +0000 | |||
225 | +++ plugins/Cursor/InputDispatcherFilter.h 2017-03-31 15:02:41 +0000 | |||
226 | @@ -0,0 +1,62 @@ | |||
227 | 1 | /* | ||
228 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
229 | 3 | * | ||
230 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
231 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
232 | 6 | * the Free Software Foundation. | ||
233 | 7 | * | ||
234 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
235 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
236 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
237 | 11 | * Lesser General Public License for more details. | ||
238 | 12 | * | ||
239 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
240 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
241 | 15 | */ | ||
242 | 16 | |||
243 | 17 | #ifndef INPUTDISPATCHERFILTER_H | ||
244 | 18 | #define INPUTDISPATCHERFILTER_H | ||
245 | 19 | |||
246 | 20 | #include <QObject> | ||
247 | 21 | #include <QPointF> | ||
248 | 22 | #include <QSet> | ||
249 | 23 | |||
250 | 24 | class MousePointer; | ||
251 | 25 | class QScreen; | ||
252 | 26 | |||
253 | 27 | class InputDispatcherFilter : public QObject | ||
254 | 28 | { | ||
255 | 29 | Q_OBJECT | ||
256 | 30 | public: | ||
257 | 31 | static InputDispatcherFilter *instance(); | ||
258 | 32 | |||
259 | 33 | void registerPointer(MousePointer* pointer); | ||
260 | 34 | void unregisterPointer(MousePointer* pointer); | ||
261 | 35 | |||
262 | 36 | Q_SIGNALS: | ||
263 | 37 | void pushedLeftBoundary(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
264 | 38 | void pushedRightBoundary(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
265 | 39 | void pushedTopBoundary(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
266 | 40 | void pushedTopLeftCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
267 | 41 | void pushedTopRightCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
268 | 42 | void pushedBottomLeftCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
269 | 43 | void pushedBottomRightCorner(QScreen* screen, qreal amount, Qt::MouseButtons buttons); | ||
270 | 44 | void pushStopped(QScreen* screen); | ||
271 | 45 | |||
272 | 46 | protected: | ||
273 | 47 | InputDispatcherFilter(QObject* parent = nullptr); | ||
274 | 48 | |||
275 | 49 | bool eventFilter(QObject *o, QEvent *e) override; | ||
276 | 50 | |||
277 | 51 | QPointF adjustedPositionForMovement(const QPointF& pt, const QPointF& movement) const; | ||
278 | 52 | QScreen* screenAt(const QPointF& pt) const; | ||
279 | 53 | |||
280 | 54 | MousePointer* currentPointer() const; | ||
281 | 55 | |||
282 | 56 | private: | ||
283 | 57 | QObject* m_inputDispatcher; | ||
284 | 58 | QSet<MousePointer*> m_pointers; | ||
285 | 59 | bool m_pushing; | ||
286 | 60 | }; | ||
287 | 61 | |||
288 | 62 | #endif // INPUTDISPATCHERFILTER_H | ||
289 | 0 | 63 | ||
290 | === modified file 'plugins/Cursor/MousePointer.cpp' | |||
291 | --- plugins/Cursor/MousePointer.cpp 2016-09-07 08:36:59 +0000 | |||
292 | +++ plugins/Cursor/MousePointer.cpp 2017-03-31 15:02:41 +0000 | |||
293 | @@ -16,84 +16,74 @@ | |||
294 | 16 | 16 | ||
295 | 17 | #include "MousePointer.h" | 17 | #include "MousePointer.h" |
296 | 18 | #include "CursorImageProvider.h" | 18 | #include "CursorImageProvider.h" |
297 | 19 | #include "InputDispatcherFilter.h" | ||
298 | 20 | |||
299 | 21 | #include <QQuickWindow> | ||
300 | 19 | 22 | ||
301 | 20 | // Unity API | 23 | // Unity API |
302 | 21 | #include <unity/shell/application/MirPlatformCursor.h> | 24 | #include <unity/shell/application/MirPlatformCursor.h> |
303 | 22 | 25 | ||
304 | 23 | #include <QQuickWindow> | ||
305 | 24 | #include <QGuiApplication> | ||
306 | 25 | #include <QtMath> | ||
307 | 26 | |||
308 | 27 | #include <qpa/qwindowsysteminterface.h> | ||
309 | 28 | |||
310 | 29 | MousePointer::MousePointer(QQuickItem *parent) | 26 | MousePointer::MousePointer(QQuickItem *parent) |
311 | 30 | : MirMousePointerInterface(parent) | 27 | : MirMousePointerInterface(parent) |
312 | 31 | , m_cursorName(QStringLiteral("left_ptr")) | 28 | , m_cursorName(QStringLiteral("left_ptr")) |
313 | 32 | , m_themeName(QStringLiteral("default")) | 29 | , m_themeName(QStringLiteral("default")) |
314 | 33 | { | 30 | { |
365 | 34 | } | 31 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedLeftBoundary, |
366 | 35 | 32 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { | |
367 | 36 | void MousePointer::handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons, | 33 | if (window() && window()->screen() == screen) { |
368 | 37 | Qt::KeyboardModifiers modifiers) | 34 | Q_EMIT pushedLeftBoundary(amount, buttons); |
369 | 38 | { | 35 | } |
370 | 39 | if (!parentItem()) { | 36 | }); |
371 | 40 | return; | 37 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedRightBoundary, |
372 | 41 | } | 38 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { |
373 | 42 | 39 | if (window() && window()->screen() == screen) { | |
374 | 43 | if (!movement.isNull()) { | 40 | Q_EMIT pushedRightBoundary(amount, buttons); |
375 | 44 | Q_EMIT mouseMoved(); | 41 | } |
376 | 45 | } | 42 | }); |
377 | 46 | 43 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedTopBoundary, | |
378 | 47 | m_accumulatedMovement += movement; | 44 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { |
379 | 48 | // don't apply the fractional part | 45 | if (window() && window()->screen() == screen) { |
380 | 49 | QPointF appliedMovement(int(m_accumulatedMovement.x()), int(m_accumulatedMovement.y())); | 46 | Q_EMIT pushedTopBoundary(amount, buttons); |
381 | 50 | m_accumulatedMovement -= appliedMovement; | 47 | } |
382 | 51 | 48 | }); | |
383 | 52 | qreal newX = x() + appliedMovement.x(); | 49 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedTopLeftCorner, |
384 | 53 | qreal newY = y() + appliedMovement.y(); | 50 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { |
385 | 54 | const qreal sceneWidth = parentItem()->width(); | 51 | if (window() && window()->screen() == screen) { |
386 | 55 | const qreal sceneHeight = parentItem()->height(); | 52 | Q_EMIT pushedTopLeftCorner(amount, buttons); |
387 | 56 | 53 | } | |
388 | 57 | if (newX <= 0 && newY < m_topBoundaryOffset) { // top left corner | 54 | }); |
389 | 58 | const auto distance = qSqrt(qPow(newX, 2) + qPow(newY-m_topBoundaryOffset, 2)); | 55 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedTopRightCorner, |
390 | 59 | Q_EMIT pushedTopLeftCorner(qAbs(distance), buttons); | 56 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { |
391 | 60 | m_pushing = true; | 57 | if (window() && window()->screen() == screen) { |
392 | 61 | } else if (newX >= sceneWidth-1 && newY < m_topBoundaryOffset) { // top right corner | 58 | Q_EMIT pushedTopRightCorner(amount, buttons); |
393 | 62 | const auto distance = qSqrt(qPow(newX-sceneWidth, 2) + qPow(newY-m_topBoundaryOffset, 2)); | 59 | } |
394 | 63 | Q_EMIT pushedTopRightCorner(qAbs(distance), buttons); | 60 | }); |
395 | 64 | m_pushing = true; | 61 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedBottomLeftCorner, |
396 | 65 | } else if (newX < 0 && newY >= sceneHeight-1) { // bottom left corner | 62 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { |
397 | 66 | const auto distance = qSqrt(qPow(newX, 2) + qPow(newY-sceneHeight, 2)); | 63 | if (window() && window()->screen() == screen) { |
398 | 67 | Q_EMIT pushedBottomLeftCorner(qAbs(distance), buttons); | 64 | Q_EMIT pushedBottomLeftCorner(amount, buttons); |
399 | 68 | m_pushing = true; | 65 | } |
400 | 69 | } else if (newX >= sceneWidth-1 && newY >= sceneHeight-1) { // bottom right corner | 66 | }); |
401 | 70 | const auto distance = qSqrt(qPow(newX-sceneWidth, 2) + qPow(newY-sceneHeight, 2)); | 67 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushedBottomRightCorner, |
402 | 71 | Q_EMIT pushedBottomRightCorner(qAbs(distance), buttons); | 68 | this, [this](QScreen* screen, qreal amount, Qt::MouseButtons buttons) { |
403 | 72 | m_pushing = true; | 69 | if (window() && window()->screen() == screen) { |
404 | 73 | } else if (newX < 0) { // left edge | 70 | Q_EMIT pushedBottomRightCorner(amount, buttons); |
405 | 74 | Q_EMIT pushedLeftBoundary(qAbs(newX), buttons); | 71 | } |
406 | 75 | m_pushing = true; | 72 | }); |
407 | 76 | } else if (newX >= sceneWidth) { // right edge | 73 | connect(InputDispatcherFilter::instance(), &InputDispatcherFilter::pushStopped, |
408 | 77 | Q_EMIT pushedRightBoundary(newX - (sceneWidth - 1), buttons); | 74 | this, [this](QScreen* screen) { |
409 | 78 | m_pushing = true; | 75 | if (window() && window()->screen() == screen) { |
360 | 79 | } else if (newY < m_topBoundaryOffset) { // top edge | ||
361 | 80 | Q_EMIT pushedTopBoundary(qAbs(newY - m_topBoundaryOffset), buttons); | ||
362 | 81 | m_pushing = true; | ||
363 | 82 | } else if (Q_LIKELY(newX > 0 && newX < sceneWidth-1 && newY > 0 && newY < sceneHeight-1)) { // normal pos, not pushing | ||
364 | 83 | if (m_pushing) { | ||
410 | 84 | Q_EMIT pushStopped(); | 76 | Q_EMIT pushStopped(); |
411 | 85 | m_pushing = false; | ||
412 | 86 | } | 77 | } |
423 | 87 | } | 78 | }); |
424 | 88 | 79 | ||
425 | 89 | applyItemConfinement(newX, newY); | 80 | InputDispatcherFilter::instance()->registerPointer(this); |
426 | 90 | 81 | } | |
427 | 91 | setX(qBound(0.0, newX, sceneWidth - 1)); | 82 | |
428 | 92 | setY(qBound(0.0, newY, sceneHeight - 1)); | 83 | MousePointer::~MousePointer() |
429 | 93 | 84 | { | |
430 | 94 | QPointF scenePosition = mapToItem(nullptr, QPointF(0, 0)); | 85 | registerScreen(nullptr); |
431 | 95 | QWindowSystemInterface::handleMouseEvent(window(), timestamp, scenePosition /*local*/, scenePosition /*global*/, | 86 | InputDispatcherFilter::instance()->unregisterPointer(this); |
422 | 96 | buttons, modifiers); | ||
432 | 97 | } | 87 | } |
433 | 98 | 88 | ||
434 | 99 | void MousePointer::applyItemConfinement(qreal &newX, qreal &newY) | 89 | void MousePointer::applyItemConfinement(qreal &newX, qreal &newY) |
435 | @@ -121,17 +111,6 @@ | |||
436 | 121 | } | 111 | } |
437 | 122 | } | 112 | } |
438 | 123 | 113 | ||
439 | 124 | void MousePointer::handleWheelEvent(ulong timestamp, QPoint angleDelta, Qt::KeyboardModifiers modifiers) | ||
440 | 125 | { | ||
441 | 126 | if (!parentItem()) { | ||
442 | 127 | return; | ||
443 | 128 | } | ||
444 | 129 | |||
445 | 130 | QPointF scenePosition = mapToItem(nullptr, QPointF(0, 0)); | ||
446 | 131 | QWindowSystemInterface::handleWheelEvent(window(), timestamp, scenePosition /* local */, scenePosition /* global */, | ||
447 | 132 | QPoint() /* pixelDelta */, angleDelta, modifiers, Qt::ScrollUpdate); | ||
448 | 133 | } | ||
449 | 134 | |||
450 | 135 | int MousePointer::topBoundaryOffset() const | 114 | int MousePointer::topBoundaryOffset() const |
451 | 136 | { | 115 | { |
452 | 137 | return m_topBoundaryOffset; | 116 | return m_topBoundaryOffset; |
453 | @@ -182,7 +161,7 @@ | |||
454 | 182 | if (m_registeredScreen) { | 161 | if (m_registeredScreen) { |
455 | 183 | auto previousCursor = dynamic_cast<MirPlatformCursor*>(m_registeredScreen->handle()->cursor()); | 162 | auto previousCursor = dynamic_cast<MirPlatformCursor*>(m_registeredScreen->handle()->cursor()); |
456 | 184 | if (previousCursor) { | 163 | if (previousCursor) { |
458 | 185 | previousCursor->setMousePointer(nullptr); | 164 | previousCursor->unregisterMousePointer(this); |
459 | 186 | } else { | 165 | } else { |
460 | 187 | qCritical("QPlatformCursor is not a MirPlatformCursor! Cursor module only works in a Mir server."); | 166 | qCritical("QPlatformCursor is not a MirPlatformCursor! Cursor module only works in a Mir server."); |
461 | 188 | } | 167 | } |
462 | @@ -193,7 +172,7 @@ | |||
463 | 193 | if (m_registeredScreen) { | 172 | if (m_registeredScreen) { |
464 | 194 | auto cursor = dynamic_cast<MirPlatformCursor*>(m_registeredScreen->handle()->cursor()); | 173 | auto cursor = dynamic_cast<MirPlatformCursor*>(m_registeredScreen->handle()->cursor()); |
465 | 195 | if (cursor) { | 174 | if (cursor) { |
467 | 196 | cursor->setMousePointer(this); | 175 | cursor->registerMousePointer(this); |
468 | 197 | } else { | 176 | } else { |
469 | 198 | qCritical("QPlaformCursor is not a MirPlatformCursor! Cursor module only works in Mir."); | 177 | qCritical("QPlaformCursor is not a MirPlatformCursor! Cursor module only works in Mir."); |
470 | 199 | } | 178 | } |
471 | @@ -216,6 +195,12 @@ | |||
472 | 216 | } | 195 | } |
473 | 217 | } | 196 | } |
474 | 218 | 197 | ||
475 | 198 | void MousePointer::moveTo(const QPoint &position) | ||
476 | 199 | { | ||
477 | 200 | setPosition(position); | ||
478 | 201 | Q_EMIT mouseMoved(); | ||
479 | 202 | } | ||
480 | 203 | |||
481 | 219 | void MousePointer::setCustomCursor(const QCursor &customCursor) | 204 | void MousePointer::setCustomCursor(const QCursor &customCursor) |
482 | 220 | { | 205 | { |
483 | 221 | CursorImageProvider::instance()->setCustomCursor(customCursor); | 206 | CursorImageProvider::instance()->setCustomCursor(customCursor); |
484 | 222 | 207 | ||
485 | === modified file 'plugins/Cursor/MousePointer.h' | |||
486 | --- plugins/Cursor/MousePointer.h 2016-09-07 08:36:59 +0000 | |||
487 | +++ plugins/Cursor/MousePointer.h 2017-03-31 15:02:41 +0000 | |||
488 | @@ -31,6 +31,7 @@ | |||
489 | 31 | Q_PROPERTY(int topBoundaryOffset READ topBoundaryOffset WRITE setTopBoundaryOffset NOTIFY topBoundaryOffsetChanged) | 31 | Q_PROPERTY(int topBoundaryOffset READ topBoundaryOffset WRITE setTopBoundaryOffset NOTIFY topBoundaryOffsetChanged) |
490 | 32 | public: | 32 | public: |
491 | 33 | MousePointer(QQuickItem *parent = nullptr); | 33 | MousePointer(QQuickItem *parent = nullptr); |
492 | 34 | ~MousePointer(); | ||
493 | 34 | 35 | ||
494 | 35 | void setCursorName(const QString &qtCursorName) override; | 36 | void setCursorName(const QString &qtCursorName) override; |
495 | 36 | QString cursorName() const override { return m_cursorName; } | 37 | QString cursorName() const override { return m_cursorName; } |
496 | @@ -38,6 +39,8 @@ | |||
497 | 38 | void setThemeName(const QString &themeName) override; | 39 | void setThemeName(const QString &themeName) override; |
498 | 39 | QString themeName() const override { return m_themeName; } | 40 | QString themeName() const override { return m_themeName; } |
499 | 40 | 41 | ||
500 | 42 | void moveTo(const QPoint& position) override; | ||
501 | 43 | |||
502 | 41 | void setCustomCursor(const QCursor &) override; | 44 | void setCustomCursor(const QCursor &) override; |
503 | 42 | 45 | ||
504 | 43 | QQuickItem* confiningItem() const; | 46 | QQuickItem* confiningItem() const; |
505 | @@ -46,10 +49,7 @@ | |||
506 | 46 | int topBoundaryOffset() const; | 49 | int topBoundaryOffset() const; |
507 | 47 | void setTopBoundaryOffset(int topBoundaryOffset); | 50 | void setTopBoundaryOffset(int topBoundaryOffset); |
508 | 48 | 51 | ||
513 | 49 | public Q_SLOTS: | 52 | QScreen* screen() const { return m_registeredScreen; } |
510 | 50 | void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons, | ||
511 | 51 | Qt::KeyboardModifiers modifiers) override; | ||
512 | 52 | void handleWheelEvent(ulong timestamp, QPoint angleDelta, Qt::KeyboardModifiers modifiers) override; | ||
514 | 53 | 53 | ||
515 | 54 | Q_SIGNALS: | 54 | Q_SIGNALS: |
516 | 55 | void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons); | 55 | void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons); |
517 | @@ -79,6 +79,7 @@ | |||
518 | 79 | QPointer<QScreen> m_registeredScreen; | 79 | QPointer<QScreen> m_registeredScreen; |
519 | 80 | QString m_cursorName; | 80 | QString m_cursorName; |
520 | 81 | QString m_themeName; | 81 | QString m_themeName; |
521 | 82 | bool m_active; | ||
522 | 82 | 83 | ||
523 | 83 | // Accumulated, unapplied, mouse movement. | 84 | // Accumulated, unapplied, mouse movement. |
524 | 84 | QPointF m_accumulatedMovement; | 85 | QPointF m_accumulatedMovement; |
525 | 85 | 86 | ||
526 | === modified file 'plugins/GlobalShortcut/globalshortcut.cpp' | |||
527 | --- plugins/GlobalShortcut/globalshortcut.cpp 2016-12-14 13:15:06 +0000 | |||
528 | +++ plugins/GlobalShortcut/globalshortcut.cpp 2017-03-31 15:02:41 +0000 | |||
529 | @@ -56,11 +56,6 @@ | |||
530 | 56 | Q_EMIT activeChanged(active); | 56 | Q_EMIT activeChanged(active); |
531 | 57 | } | 57 | } |
532 | 58 | 58 | ||
533 | 59 | void GlobalShortcut::componentComplete() | ||
534 | 60 | { | ||
535 | 61 | connect(this, &QQuickItem::windowChanged, this, &GlobalShortcut::setupFilterOnWindow); | ||
536 | 62 | } | ||
537 | 63 | |||
538 | 64 | void GlobalShortcut::keyPressEvent(QKeyEvent * event) | 59 | void GlobalShortcut::keyPressEvent(QKeyEvent * event) |
539 | 65 | { | 60 | { |
540 | 66 | if (!m_active) return; | 61 | if (!m_active) return; |
541 | @@ -76,13 +71,3 @@ | |||
542 | 76 | event->accept(); | 71 | event->accept(); |
543 | 77 | Q_EMIT released(m_shortcut.toString()); | 72 | Q_EMIT released(m_shortcut.toString()); |
544 | 78 | } | 73 | } |
545 | 79 | |||
546 | 80 | void GlobalShortcut::setupFilterOnWindow(QQuickWindow *window) | ||
547 | 81 | { | ||
548 | 82 | if (!window) { | ||
549 | 83 | // qWarning() << Q_FUNC_INFO << "Failed to setup filter on window"; | ||
550 | 84 | return; | ||
551 | 85 | } | ||
552 | 86 | |||
553 | 87 | registry->setupFilterOnWindow((qulonglong) window->winId()); | ||
554 | 88 | } | ||
555 | 89 | 74 | ||
556 | === modified file 'plugins/GlobalShortcut/globalshortcut.h' | |||
557 | --- plugins/GlobalShortcut/globalshortcut.h 2016-10-12 17:11:41 +0000 | |||
558 | +++ plugins/GlobalShortcut/globalshortcut.h 2017-03-31 15:02:41 +0000 | |||
559 | @@ -53,7 +53,6 @@ | |||
560 | 53 | void setActive(bool active); | 53 | void setActive(bool active); |
561 | 54 | 54 | ||
562 | 55 | protected: | 55 | protected: |
563 | 56 | void componentComplete() override; | ||
564 | 57 | void keyPressEvent(QKeyEvent * event) override; | 56 | void keyPressEvent(QKeyEvent * event) override; |
565 | 58 | void keyReleaseEvent(QKeyEvent * event) override; | 57 | void keyReleaseEvent(QKeyEvent * event) override; |
566 | 59 | 58 | ||
567 | @@ -69,9 +68,6 @@ | |||
568 | 69 | void released(const QString &shortcut); | 68 | void released(const QString &shortcut); |
569 | 70 | void activeChanged(bool active); | 69 | void activeChanged(bool active); |
570 | 71 | 70 | ||
571 | 72 | private Q_SLOTS: | ||
572 | 73 | void setupFilterOnWindow(QQuickWindow* window); | ||
573 | 74 | |||
574 | 75 | private: | 71 | private: |
575 | 76 | QVariant m_shortcut; | 72 | QVariant m_shortcut; |
576 | 77 | bool m_active = true; | 73 | bool m_active = true; |
577 | 78 | 74 | ||
578 | === modified file 'plugins/GlobalShortcut/globalshortcutregistry.cpp' | |||
579 | --- plugins/GlobalShortcut/globalshortcutregistry.cpp 2016-10-12 17:11:41 +0000 | |||
580 | +++ plugins/GlobalShortcut/globalshortcutregistry.cpp 2017-03-31 15:02:41 +0000 | |||
581 | @@ -21,11 +21,25 @@ | |||
582 | 21 | 21 | ||
583 | 22 | #include "globalshortcutregistry.h" | 22 | #include "globalshortcutregistry.h" |
584 | 23 | 23 | ||
586 | 24 | static qulonglong s_windowId = 0; | 24 | namespace { |
587 | 25 | QWindow* windowForShortcut(GlobalShortcut *sc) { | ||
588 | 26 | QObject* parent= sc; | ||
589 | 27 | while(parent) { | ||
590 | 28 | if (auto item = qobject_cast<QQuickItem*>(parent)) { | ||
591 | 29 | auto window = item->window(); | ||
592 | 30 | if (window) return window; | ||
593 | 31 | } | ||
594 | 32 | parent = parent->parent(); | ||
595 | 33 | } | ||
596 | 34 | return nullptr; | ||
597 | 35 | } | ||
598 | 36 | } // namespace | ||
599 | 25 | 37 | ||
600 | 26 | GlobalShortcutRegistry::GlobalShortcutRegistry(QObject *parent) | 38 | GlobalShortcutRegistry::GlobalShortcutRegistry(QObject *parent) |
601 | 27 | : QObject(parent) | 39 | : QObject(parent) |
602 | 28 | { | 40 | { |
603 | 41 | connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &GlobalShortcutRegistry::setupFilterOnWindow); | ||
604 | 42 | setupFilterOnWindow(qGuiApp->focusWindow()); | ||
605 | 29 | } | 43 | } |
606 | 30 | 44 | ||
607 | 31 | GlobalShortcutList GlobalShortcutRegistry::shortcuts() const | 45 | GlobalShortcutList GlobalShortcutRegistry::shortcuts() const |
608 | @@ -91,7 +105,10 @@ | |||
609 | 91 | const auto shortcuts = m_shortcuts.value(seq); | 105 | const auto shortcuts = m_shortcuts.value(seq); |
610 | 92 | Q_FOREACH(const auto &shortcut, shortcuts) { | 106 | Q_FOREACH(const auto &shortcut, shortcuts) { |
611 | 93 | if (shortcut) { | 107 | if (shortcut) { |
613 | 94 | qApp->sendEvent(shortcut, &eCopy); | 108 | auto window = windowForShortcut(shortcut); |
614 | 109 | if (!window || window == obj) { // accept shortcut if it's not attached to a window or it's window is active. | ||
615 | 110 | qApp->sendEvent(shortcut, &eCopy); | ||
616 | 111 | } | ||
617 | 95 | } | 112 | } |
618 | 96 | } | 113 | } |
619 | 97 | } | 114 | } |
620 | @@ -102,24 +119,15 @@ | |||
621 | 102 | return QObject::eventFilter(obj, event); | 119 | return QObject::eventFilter(obj, event); |
622 | 103 | } | 120 | } |
623 | 104 | 121 | ||
625 | 105 | void GlobalShortcutRegistry::setupFilterOnWindow(qulonglong wid) | 122 | void GlobalShortcutRegistry::setupFilterOnWindow(QWindow* window) |
626 | 106 | { | 123 | { |
627 | 107 | if (wid == s_windowId) { | ||
628 | 108 | return; | ||
629 | 109 | } | ||
630 | 110 | |||
631 | 111 | if (m_filteredWindow) { | 124 | if (m_filteredWindow) { |
632 | 112 | m_filteredWindow->removeEventFilter(this); | 125 | m_filteredWindow->removeEventFilter(this); |
633 | 113 | m_filteredWindow.clear(); | 126 | m_filteredWindow.clear(); |
634 | 114 | s_windowId = 0; | ||
635 | 115 | } | 127 | } |
636 | 116 | 128 | ||
644 | 117 | Q_FOREACH(QWindow *window, qApp->allWindows()) { | 129 | if (window) { |
645 | 118 | if (window && window->winId() == wid) { | 130 | m_filteredWindow = window; |
646 | 119 | m_filteredWindow = window; | 131 | window->installEventFilter(this); |
640 | 120 | window->installEventFilter(this); | ||
641 | 121 | s_windowId = wid; | ||
642 | 122 | break; | ||
643 | 123 | } | ||
647 | 124 | } | 132 | } |
648 | 125 | } | 133 | } |
649 | 126 | 134 | ||
650 | === modified file 'plugins/GlobalShortcut/globalshortcutregistry.h' | |||
651 | --- plugins/GlobalShortcut/globalshortcutregistry.h 2015-08-25 11:05:38 +0000 | |||
652 | +++ plugins/GlobalShortcut/globalshortcutregistry.h 2017-03-31 15:02:41 +0000 | |||
653 | @@ -52,9 +52,9 @@ | |||
654 | 52 | void addShortcut(const QVariant &seq, GlobalShortcut * sc); | 52 | void addShortcut(const QVariant &seq, GlobalShortcut * sc); |
655 | 53 | 53 | ||
656 | 54 | /** | 54 | /** |
658 | 55 | * Sets up key events filtering on window @p wid | 55 | * Sets up key events filtering on window @p window |
659 | 56 | */ | 56 | */ |
661 | 57 | void setupFilterOnWindow(qulonglong wid); | 57 | void setupFilterOnWindow(QWindow* window); |
662 | 58 | 58 | ||
663 | 59 | protected: | 59 | protected: |
664 | 60 | bool eventFilter(QObject *obj, QEvent *event) override; | 60 | bool eventFilter(QObject *obj, QEvent *event) override; |
665 | 61 | 61 | ||
666 | === modified file 'plugins/UInput/plugin.cpp' | |||
667 | --- plugins/UInput/plugin.cpp 2015-11-11 16:03:24 +0000 | |||
668 | +++ plugins/UInput/plugin.cpp 2017-03-31 15:02:41 +0000 | |||
669 | @@ -19,8 +19,14 @@ | |||
670 | 19 | 19 | ||
671 | 20 | #include <QtQml/qqml.h> | 20 | #include <QtQml/qqml.h> |
672 | 21 | 21 | ||
673 | 22 | |||
674 | 23 | QObject* uinputSingleton(QQmlEngine*, QJSEngine*) | ||
675 | 24 | { | ||
676 | 25 | return new UInput; | ||
677 | 26 | } | ||
678 | 27 | |||
679 | 22 | void UInputPlugin::registerTypes(const char *uri) | 28 | void UInputPlugin::registerTypes(const char *uri) |
680 | 23 | { | 29 | { |
681 | 24 | Q_ASSERT(uri == QLatin1String("UInput")); | 30 | Q_ASSERT(uri == QLatin1String("UInput")); |
683 | 25 | qmlRegisterType<UInput>(uri, 0, 1, "UInput"); | 31 | qmlRegisterSingletonType<UInput>(uri, 0, 1, "UInput", uinputSingleton); |
684 | 26 | } | 32 | } |
685 | 27 | 33 | ||
686 | === modified file 'qml/ApplicationMenus/ApplicationMenuItemFactory.qml' | |||
687 | --- qml/ApplicationMenus/ApplicationMenuItemFactory.qml 2016-11-28 16:32:56 +0000 | |||
688 | +++ qml/ApplicationMenus/ApplicationMenuItemFactory.qml 2017-03-31 15:02:41 +0000 | |||
689 | @@ -45,7 +45,7 @@ | |||
690 | 45 | 45 | ||
691 | 46 | Action { | 46 | Action { |
692 | 47 | id: action | 47 | id: action |
694 | 48 | text: menuData.label.replace("_", "&") | 48 | text: menuData && menuData.label.replace("_", "&") || "" |
695 | 49 | } | 49 | } |
696 | 50 | 50 | ||
697 | 51 | ListItemLayout { | 51 | ListItemLayout { |
698 | @@ -59,8 +59,8 @@ | |||
699 | 59 | } | 59 | } |
700 | 60 | 60 | ||
701 | 61 | Label { | 61 | Label { |
704 | 62 | text: menuData.shortcut | 62 | text: menuData && menuData.shortcut || "" |
705 | 63 | visible: menuData.shortcut && QuickUtils.keyboardAttached | 63 | visible: menuData && menuData.shortcut && QuickUtils.keyboardAttached |
706 | 64 | SlotsLayout.position: SlotsLayout.Trailing | 64 | SlotsLayout.position: SlotsLayout.Trailing |
707 | 65 | color: enabled ? theme.palette.normal.backgroundSecondaryText : | 65 | color: enabled ? theme.palette.normal.backgroundSecondaryText : |
708 | 66 | theme.palette.disabled.backgroundSecondaryText | 66 | theme.palette.disabled.backgroundSecondaryText |
709 | @@ -86,7 +86,7 @@ | |||
710 | 86 | 86 | ||
711 | 87 | Action { | 87 | Action { |
712 | 88 | id: action | 88 | id: action |
714 | 89 | text: menuData.label.replace("_", "&") | 89 | text: menuData && menuData.label.replace("_", "&") || "" |
715 | 90 | } | 90 | } |
716 | 91 | 91 | ||
717 | 92 | ListItemLayout { | 92 | ListItemLayout { |
718 | 93 | 93 | ||
719 | === modified file 'qml/ApplicationMenus/MenuBar.qml' | |||
720 | --- qml/ApplicationMenus/MenuBar.qml 2017-03-28 21:47:53 +0000 | |||
721 | +++ qml/ApplicationMenus/MenuBar.qml 2017-03-31 15:02:41 +0000 | |||
722 | @@ -19,6 +19,7 @@ | |||
723 | 19 | import Utils 0.1 | 19 | import Utils 0.1 |
724 | 20 | import Ubuntu.Components 1.3 | 20 | import Ubuntu.Components 1.3 |
725 | 21 | import GlobalShortcut 1.0 | 21 | import GlobalShortcut 1.0 |
726 | 22 | import "../Components/PanelState" | ||
727 | 22 | 23 | ||
728 | 23 | Item { | 24 | Item { |
729 | 24 | id: root | 25 | id: root |
730 | @@ -29,6 +30,7 @@ | |||
731 | 29 | property bool enableKeyFilter: false | 30 | property bool enableKeyFilter: false |
732 | 30 | property real overflowWidth: width | 31 | property real overflowWidth: width |
733 | 31 | property bool windowMoving: false | 32 | property bool windowMoving: false |
734 | 33 | property PanelState panelState | ||
735 | 32 | 34 | ||
736 | 33 | // read from outside | 35 | // read from outside |
737 | 34 | readonly property bool valid: rowRepeater.count > 0 | 36 | readonly property bool valid: rowRepeater.count > 0 |
738 | @@ -106,7 +108,9 @@ | |||
739 | 106 | 108 | ||
740 | 107 | Component { | 109 | Component { |
741 | 108 | id: menuComponent | 110 | id: menuComponent |
743 | 109 | MenuPopup { } | 111 | MenuPopup { |
744 | 112 | panelState: root.panelState | ||
745 | 113 | } | ||
746 | 110 | } | 114 | } |
747 | 111 | 115 | ||
748 | 112 | Repeater { | 116 | Repeater { |
749 | 113 | 117 | ||
750 | === modified file 'qml/ApplicationMenus/MenuItem.qml' | |||
751 | --- qml/ApplicationMenus/MenuItem.qml 2017-02-23 13:19:41 +0000 | |||
752 | +++ qml/ApplicationMenus/MenuItem.qml 2017-03-31 15:02:41 +0000 | |||
753 | @@ -17,6 +17,7 @@ | |||
754 | 17 | import QtQuick 2.4 | 17 | import QtQuick 2.4 |
755 | 18 | import QtQuick.Layouts 1.1 | 18 | import QtQuick.Layouts 1.1 |
756 | 19 | import Ubuntu.Components 1.3 | 19 | import Ubuntu.Components 1.3 |
757 | 20 | import "../Components/PanelState" | ||
758 | 20 | 21 | ||
759 | 21 | ActionItem { | 22 | ActionItem { |
760 | 22 | id: root | 23 | id: root |
761 | @@ -24,6 +25,7 @@ | |||
762 | 24 | implicitWidth: requiredWidth | 25 | implicitWidth: requiredWidth |
763 | 25 | 26 | ||
764 | 26 | property var menuData: undefined | 27 | property var menuData: undefined |
765 | 28 | property PanelState panelState | ||
766 | 27 | 29 | ||
767 | 28 | readonly property real requiredWidth: { | 30 | readonly property real requiredWidth: { |
768 | 29 | var val = 0; | 31 | var val = 0; |
769 | 30 | 32 | ||
770 | === modified file 'qml/ApplicationMenus/MenuPopup.qml' | |||
771 | --- qml/ApplicationMenus/MenuPopup.qml 2017-03-24 08:29:56 +0000 | |||
772 | +++ qml/ApplicationMenus/MenuPopup.qml 2017-03-31 15:02:41 +0000 | |||
773 | @@ -64,6 +64,7 @@ | |||
774 | 64 | } | 64 | } |
775 | 65 | 65 | ||
776 | 66 | property alias unityMenuModel: repeater.model | 66 | property alias unityMenuModel: repeater.model |
777 | 67 | property PanelState panelState | ||
778 | 67 | 68 | ||
779 | 68 | function show() { | 69 | function show() { |
780 | 69 | visible = true; | 70 | visible = true; |
781 | @@ -103,7 +104,7 @@ | |||
782 | 103 | property real __minimumWidth: units.gu(20) | 104 | property real __minimumWidth: units.gu(20) |
783 | 104 | property real __maximumWidth: ApplicationMenusLimits.screenWidth * 0.7 | 105 | property real __maximumWidth: ApplicationMenusLimits.screenWidth * 0.7 |
784 | 105 | property real __minimumHeight: units.gu(2) | 106 | property real __minimumHeight: units.gu(2) |
786 | 106 | property real __maximumHeight: ApplicationMenusLimits.screenHeight - PanelState.panelHeight | 107 | property real __maximumHeight: ApplicationMenusLimits.screenHeight - panelState.panelHeight |
787 | 107 | 108 | ||
788 | 108 | signal dismissAll() | 109 | signal dismissAll() |
789 | 109 | 110 | ||
790 | @@ -293,6 +294,7 @@ | |||
791 | 293 | // Parent will be loader | 294 | // Parent will be loader |
792 | 294 | id: menuItem | 295 | id: menuItem |
793 | 295 | menuData: parent.__menuData | 296 | menuData: parent.__menuData |
794 | 297 | panelState: root.panelState | ||
795 | 296 | objectName: parent.objectName + "-actionItem" | 298 | objectName: parent.objectName + "-actionItem" |
796 | 297 | 299 | ||
797 | 298 | width: MathUtils.clamp(implicitWidth, d.__minimumWidth, d.__maximumWidth) | 300 | width: MathUtils.clamp(implicitWidth, d.__minimumWidth, d.__maximumWidth) |
798 | @@ -492,6 +494,7 @@ | |||
799 | 492 | 494 | ||
800 | 493 | onLoaded: { | 495 | onLoaded: { |
801 | 494 | item.unityMenuModel = Qt.binding(function() { return submenuLoader.unityMenuModel; }); | 496 | item.unityMenuModel = Qt.binding(function() { return submenuLoader.unityMenuModel; }); |
802 | 497 | item.panelState = Qt.binding(function() { return root.panelState; }); | ||
803 | 495 | item.objectName = Qt.binding(function() { return submenuLoader.objectName + "menu"; }); | 498 | item.objectName = Qt.binding(function() { return submenuLoader.objectName + "menu"; }); |
804 | 496 | item.desiredX = Qt.binding(function() { return submenuLoader.desiredX; }); | 499 | item.desiredX = Qt.binding(function() { return submenuLoader.desiredX; }); |
805 | 497 | item.desiredY = Qt.binding(function() { return submenuLoader.desiredY; }); | 500 | item.desiredY = Qt.binding(function() { return submenuLoader.desiredY; }); |
806 | 498 | 501 | ||
807 | === modified file 'qml/CMakeLists.txt' | |||
808 | --- qml/CMakeLists.txt 2016-10-04 16:21:38 +0000 | |||
809 | +++ qml/CMakeLists.txt 2017-03-31 15:02:41 +0000 | |||
810 | @@ -1,4 +1,4 @@ | |||
812 | 1 | file(GLOB QML_JS_FILES *.qml *.js) | 1 | file(GLOB QML_JS_FILES *.qml *.js qmldir) |
813 | 2 | 2 | ||
814 | 3 | install(FILES ${QML_JS_FILES} | 3 | install(FILES ${QML_JS_FILES} |
815 | 4 | DESTINATION ${SHELL_APP_DIR} | 4 | DESTINATION ${SHELL_APP_DIR} |
816 | 5 | 5 | ||
817 | === modified file 'qml/Components/PanelState/PanelState.qml' | |||
818 | --- qml/Components/PanelState/PanelState.qml 2016-09-29 09:15:04 +0000 | |||
819 | +++ qml/Components/PanelState/PanelState.qml 2017-03-31 15:02:41 +0000 | |||
820 | @@ -14,7 +14,6 @@ | |||
821 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
822 | 15 | */ | 15 | */ |
823 | 16 | 16 | ||
824 | 17 | pragma Singleton | ||
825 | 18 | import QtQuick 2.4 | 17 | import QtQuick 2.4 |
826 | 19 | 18 | ||
827 | 20 | QtObject { | 19 | QtObject { |
828 | 21 | 20 | ||
829 | === modified file 'qml/Components/PanelState/qmldir' | |||
830 | --- qml/Components/PanelState/qmldir 2014-11-24 11:21:38 +0000 | |||
831 | +++ qml/Components/PanelState/qmldir 2017-03-31 15:02:41 +0000 | |||
832 | @@ -1,1 +1,1 @@ | |||
834 | 1 | singleton PanelState 1.0 PanelState.qml | 1 | PanelState 1.0 PanelState.qml |
835 | 2 | 2 | ||
836 | === modified file 'qml/Components/VirtualTouchPad.qml' | |||
837 | --- qml/Components/VirtualTouchPad.qml 2016-12-05 11:17:15 +0000 | |||
838 | +++ qml/Components/VirtualTouchPad.qml 2017-03-31 15:02:41 +0000 | |||
839 | @@ -24,16 +24,14 @@ | |||
840 | 24 | 24 | ||
841 | 25 | Item { | 25 | Item { |
842 | 26 | id: root | 26 | id: root |
843 | 27 | property var uinput: UInput { | ||
844 | 28 | Component.onCompleted: createMouse(); | ||
845 | 29 | Component.onDestruction: removeMouse(); | ||
846 | 30 | } | ||
847 | 31 | 27 | ||
848 | 32 | Component.onCompleted: { | 28 | Component.onCompleted: { |
849 | 29 | UInput.createMouse(); | ||
850 | 33 | if (!settings.touchpadTutorialHasRun) { | 30 | if (!settings.touchpadTutorialHasRun) { |
851 | 34 | root.runTutorial() | 31 | root.runTutorial() |
852 | 35 | } | 32 | } |
853 | 36 | } | 33 | } |
854 | 34 | Component.onDestruction: UInput.removeMouse() | ||
855 | 37 | 35 | ||
856 | 38 | function runTutorial() { | 36 | function runTutorial() { |
857 | 39 | // If the tutorial animation is started too early, e.g. in Component.onCompleted, | 37 | // If the tutorial animation is started too early, e.g. in Component.onCompleted, |
858 | @@ -85,7 +83,7 @@ | |||
859 | 85 | if (((point1.pressed && !point2.pressed) || (!point1.pressed && point2.pressed)) | 83 | if (((point1.pressed && !point2.pressed) || (!point1.pressed && point2.pressed)) |
860 | 86 | && clickTimer.running) { | 84 | && clickTimer.running) { |
861 | 87 | clickTimer.stop(); | 85 | clickTimer.stop(); |
863 | 88 | uinput.pressMouse(UInput.ButtonLeft) | 86 | UInput.pressMouse(UInput.ButtonLeft) |
864 | 89 | isDoubleClick = true; | 87 | isDoubleClick = true; |
865 | 90 | } | 88 | } |
866 | 91 | isClick = true; | 89 | isClick = true; |
867 | @@ -104,7 +102,7 @@ | |||
868 | 104 | 102 | ||
869 | 105 | onReleased: { | 103 | onReleased: { |
870 | 106 | if (isDoubleClick || isDrag) { | 104 | if (isDoubleClick || isDrag) { |
872 | 107 | uinput.releaseMouse(UInput.ButtonLeft) | 105 | UInput.releaseMouse(UInput.ButtonLeft) |
873 | 108 | isDoubleClick = false; | 106 | isDoubleClick = false; |
874 | 109 | } | 107 | } |
875 | 110 | if (isClick) { | 108 | if (isClick) { |
876 | @@ -120,8 +118,8 @@ | |||
877 | 120 | interval: 200 | 118 | interval: 200 |
878 | 121 | property int button: UInput.ButtonLeft | 119 | property int button: UInput.ButtonLeft |
879 | 122 | onTriggered: { | 120 | onTriggered: { |
882 | 123 | uinput.pressMouse(button); | 121 | UInput.pressMouse(button); |
883 | 124 | uinput.releaseMouse(button); | 122 | UInput.releaseMouse(button); |
884 | 125 | } | 123 | } |
885 | 126 | function scheduleClick(button) { | 124 | function scheduleClick(button) { |
886 | 127 | clickTimer.button = button; | 125 | clickTimer.button = button; |
887 | @@ -138,7 +136,7 @@ | |||
888 | 138 | isDrag = true; | 136 | isDrag = true; |
889 | 139 | } | 137 | } |
890 | 140 | 138 | ||
892 | 141 | uinput.moveMouse(tp.x - tp.previousX, tp.y - tp.previousY); | 139 | UInput.moveMouse(tp.x - tp.previousX, tp.y - tp.previousY); |
893 | 142 | } | 140 | } |
894 | 143 | 141 | ||
895 | 144 | function scroll(touchPoints) { | 142 | function scroll(touchPoints) { |
896 | @@ -166,7 +164,7 @@ | |||
897 | 166 | dh /= 2; | 164 | dh /= 2; |
898 | 167 | dv /= 2; | 165 | dv /= 2; |
899 | 168 | 166 | ||
901 | 169 | uinput.scrollMouse(dh, dv); | 167 | UInput.scrollMouse(dh, dv); |
902 | 170 | } | 168 | } |
903 | 171 | 169 | ||
904 | 172 | touchPoints: [ | 170 | touchPoints: [ |
905 | @@ -189,8 +187,8 @@ | |||
906 | 189 | objectName: "leftButton" | 187 | objectName: "leftButton" |
907 | 190 | Layout.fillWidth: true | 188 | Layout.fillWidth: true |
908 | 191 | Layout.fillHeight: true | 189 | Layout.fillHeight: true |
911 | 192 | onPressed: uinput.pressMouse(UInput.ButtonLeft); | 190 | onPressed: UInput.pressMouse(UInput.ButtonLeft); |
912 | 193 | onReleased: uinput.releaseMouse(UInput.ButtonLeft); | 191 | onReleased: UInput.releaseMouse(UInput.ButtonLeft); |
913 | 194 | property bool highlight: false | 192 | property bool highlight: false |
914 | 195 | UbuntuShape { | 193 | UbuntuShape { |
915 | 196 | anchors.fill: parent | 194 | anchors.fill: parent |
916 | @@ -204,8 +202,8 @@ | |||
917 | 204 | objectName: "rightButton" | 202 | objectName: "rightButton" |
918 | 205 | Layout.fillWidth: true | 203 | Layout.fillWidth: true |
919 | 206 | Layout.fillHeight: true | 204 | Layout.fillHeight: true |
922 | 207 | onPressed: uinput.pressMouse(UInput.ButtonRight); | 205 | onPressed: UInput.pressMouse(UInput.ButtonRight); |
923 | 208 | onReleased: uinput.releaseMouse(UInput.ButtonRight); | 206 | onReleased: UInput.releaseMouse(UInput.ButtonRight); |
924 | 209 | property bool highlight: false | 207 | property bool highlight: false |
925 | 210 | UbuntuShape { | 208 | UbuntuShape { |
926 | 211 | anchors.fill: parent | 209 | anchors.fill: parent |
927 | @@ -239,14 +237,10 @@ | |||
928 | 239 | } | 237 | } |
929 | 240 | } | 238 | } |
930 | 241 | 239 | ||
931 | 242 | Screens { | ||
932 | 243 | id: screens | ||
933 | 244 | } | ||
934 | 245 | |||
935 | 246 | InputMethod { | 240 | InputMethod { |
936 | 247 | id: inputMethod | 241 | id: inputMethod |
937 | 248 | // Don't resize when there is only one screen to avoid resize clashing with the InputMethod in the Shell. | 242 | // Don't resize when there is only one screen to avoid resize clashing with the InputMethod in the Shell. |
939 | 249 | enabled: screens.count > 1 && settings.oskEnabled && !tutorial.running | 243 | enabled: Screens.count > 1 && settings.oskEnabled && !tutorial.running |
940 | 250 | objectName: "inputMethod" | 244 | objectName: "inputMethod" |
941 | 251 | anchors.fill: parent | 245 | anchors.fill: parent |
942 | 252 | } | 246 | } |
943 | 253 | 247 | ||
944 | === modified file 'qml/DisabledScreenNotice.qml' | |||
945 | --- qml/DisabledScreenNotice.qml 2016-08-01 17:43:18 +0000 | |||
946 | +++ qml/DisabledScreenNotice.qml 2017-03-31 15:02:41 +0000 | |||
947 | @@ -28,8 +28,9 @@ | |||
948 | 28 | property var screen: Screen | 28 | property var screen: Screen |
949 | 29 | property var orientationLock: OrientationLock | 29 | property var orientationLock: OrientationLock |
950 | 30 | 30 | ||
951 | 31 | property alias deviceConfiguration: _deviceConfiguration | ||
952 | 31 | DeviceConfiguration { | 32 | DeviceConfiguration { |
954 | 32 | id: deviceConfiguration | 33 | id: _deviceConfiguration |
955 | 33 | name: applicationArguments.deviceName | 34 | name: applicationArguments.deviceName |
956 | 34 | } | 35 | } |
957 | 35 | 36 | ||
958 | 36 | 37 | ||
959 | === added file 'qml/ErrorApplication.qml' | |||
960 | --- qml/ErrorApplication.qml 1970-01-01 00:00:00 +0000 | |||
961 | +++ qml/ErrorApplication.qml 2017-03-31 15:02:41 +0000 | |||
962 | @@ -0,0 +1,67 @@ | |||
963 | 1 | /* | ||
964 | 2 | * Copyright (C) 2017 Canonical, Ltd. | ||
965 | 3 | * | ||
966 | 4 | * This program is free software; you can redistribute it and/or modify | ||
967 | 5 | * it under the terms of the GNU General Public License as published by | ||
968 | 6 | * the Free Software Foundation; version 3. | ||
969 | 7 | * | ||
970 | 8 | * This program is distributed in the hope that it will be useful, | ||
971 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
972 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
973 | 11 | * GNU General Public License for more details. | ||
974 | 12 | * | ||
975 | 13 | * You should have received a copy of the GNU General Public License | ||
976 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
977 | 15 | */ | ||
978 | 16 | |||
979 | 17 | import QtQuick 2.4 | ||
980 | 18 | import QtQuick.Window 2.2 | ||
981 | 19 | import Ubuntu.Components 1.3 | ||
982 | 20 | import Unity.Screens 0.1 | ||
983 | 21 | |||
984 | 22 | Instantiator { | ||
985 | 23 | id: root | ||
986 | 24 | model: Screens | ||
987 | 25 | |||
988 | 26 | ScreenWindow { | ||
989 | 27 | id: window | ||
990 | 28 | objectName: "screen"+index | ||
991 | 29 | screen: model.screen | ||
992 | 30 | visibility: applicationArguments.hasFullscreen ? Window.FullScreen : Window.Windowed | ||
993 | 31 | flags: applicationArguments.hasFrameless ? Qt.FramelessWindowHint : 0 | ||
994 | 32 | |||
995 | 33 | Binding { | ||
996 | 34 | when: applicationArguments.hasGeometry | ||
997 | 35 | target: window | ||
998 | 36 | property: "width" | ||
999 | 37 | value: applicationArguments.windowGeometry.width | ||
1000 | 38 | } | ||
1001 | 39 | Binding { | ||
1002 | 40 | when: applicationArguments.hasGeometry | ||
1003 | 41 | target: window | ||
1004 | 42 | property: "height" | ||
1005 | 43 | value: applicationArguments.windowGeometry.height | ||
1006 | 44 | } | ||
1007 | 45 | |||
1008 | 46 | Loader { | ||
1009 | 47 | width: window.width | ||
1010 | 48 | height: window.height | ||
1011 | 49 | |||
1012 | 50 | Rectangle { | ||
1013 | 51 | color: "white" | ||
1014 | 52 | Column { | ||
1015 | 53 | spacing: units.gu(1) | ||
1016 | 54 | |||
1017 | 55 | Label { | ||
1018 | 56 | text: "Unity encountered an unrecoverable error while loading:" | ||
1019 | 57 | fontSize: "large" | ||
1020 | 58 | } | ||
1021 | 59 | |||
1022 | 60 | Label { | ||
1023 | 61 | text: errorString | ||
1024 | 62 | } | ||
1025 | 63 | } | ||
1026 | 64 | } | ||
1027 | 65 | } | ||
1028 | 66 | } | ||
1029 | 67 | } | ||
1030 | 0 | 68 | ||
1031 | === modified file 'qml/Greeter/Greeter.qml' | |||
1032 | --- qml/Greeter/Greeter.qml 2017-03-22 20:14:44 +0000 | |||
1033 | +++ qml/Greeter/Greeter.qml 2017-03-31 15:02:41 +0000 | |||
1034 | @@ -24,6 +24,7 @@ | |||
1035 | 24 | import Unity.Session 0.1 | 24 | import Unity.Session 0.1 |
1036 | 25 | 25 | ||
1037 | 26 | import "." 0.1 | 26 | import "." 0.1 |
1038 | 27 | import ".." 0.1 | ||
1039 | 27 | import "../Components" | 28 | import "../Components" |
1040 | 28 | 29 | ||
1041 | 29 | Showable { | 30 | Showable { |
1042 | @@ -225,7 +226,7 @@ | |||
1043 | 225 | if (forcedUnlock && shown) { | 226 | if (forcedUnlock && shown) { |
1044 | 226 | hideView(); | 227 | hideView(); |
1045 | 227 | if (hideNow) { | 228 | if (hideNow) { |
1047 | 228 | root.hideNow(); // skip hide animation | 229 | ShellNotifier.greeter.hide(true); // skip hide animation |
1048 | 229 | } | 230 | } |
1049 | 230 | } | 231 | } |
1050 | 231 | } | 232 | } |
1051 | @@ -373,7 +374,7 @@ | |||
1052 | 373 | onEmergencyCall: root.emergencyCall() | 374 | onEmergencyCall: root.emergencyCall() |
1053 | 374 | onRequiredChanged: { | 375 | onRequiredChanged: { |
1054 | 375 | if (!loader.item.required) { | 376 | if (!loader.item.required) { |
1056 | 376 | root.hide(); | 377 | ShellNotifier.greeter.hide(false); |
1057 | 377 | } | 378 | } |
1058 | 378 | } | 379 | } |
1059 | 379 | } | 380 | } |
1060 | @@ -488,11 +489,28 @@ | |||
1061 | 488 | } | 489 | } |
1062 | 489 | 490 | ||
1063 | 490 | Connections { | 491 | Connections { |
1064 | 492 | target: ShellNotifier.greeter | ||
1065 | 493 | onHide: { | ||
1066 | 494 | if (now) { | ||
1067 | 495 | root.hideNow(); // skip hide animation | ||
1068 | 496 | } else { | ||
1069 | 497 | root.hide(); | ||
1070 | 498 | } | ||
1071 | 499 | } | ||
1072 | 500 | } | ||
1073 | 501 | |||
1074 | 502 | Binding { | ||
1075 | 503 | target: ShellNotifier.greeter | ||
1076 | 504 | property: "shown" | ||
1077 | 505 | value: root.shown | ||
1078 | 506 | } | ||
1079 | 507 | |||
1080 | 508 | Connections { | ||
1081 | 491 | target: DBusUnitySessionService | 509 | target: DBusUnitySessionService |
1082 | 492 | onLockRequested: root.forceShow() | 510 | onLockRequested: root.forceShow() |
1083 | 493 | onUnlocked: { | 511 | onUnlocked: { |
1084 | 494 | root.forcedUnlock = true; | 512 | root.forcedUnlock = true; |
1086 | 495 | root.hideNow(); | 513 | ShellNotifier.greeter.hide(true); |
1087 | 496 | } | 514 | } |
1088 | 497 | } | 515 | } |
1089 | 498 | 516 | ||
1090 | 499 | 517 | ||
1091 | === added file 'qml/Greeter/SecondaryGreeter.qml' | |||
1092 | --- qml/Greeter/SecondaryGreeter.qml 1970-01-01 00:00:00 +0000 | |||
1093 | +++ qml/Greeter/SecondaryGreeter.qml 2017-03-31 15:02:41 +0000 | |||
1094 | @@ -0,0 +1,75 @@ | |||
1095 | 1 | /* | ||
1096 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1097 | 3 | * | ||
1098 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1099 | 5 | * it under the terms of the GNU General Public License as published by | ||
1100 | 6 | * the Free Software Foundation; version 3. | ||
1101 | 7 | * | ||
1102 | 8 | * This program is distributed in the hope that it will be useful, | ||
1103 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1104 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1105 | 11 | * GNU General Public License for more details. | ||
1106 | 12 | * | ||
1107 | 13 | * You should have received a copy of the GNU General Public License | ||
1108 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1109 | 15 | */ | ||
1110 | 16 | |||
1111 | 17 | import QtQuick 2.4 | ||
1112 | 18 | import Ubuntu.Components 1.3 | ||
1113 | 19 | |||
1114 | 20 | import "../Components" | ||
1115 | 21 | import ".." 0.1 | ||
1116 | 22 | |||
1117 | 23 | Showable { | ||
1118 | 24 | id: root | ||
1119 | 25 | |||
1120 | 26 | readonly property bool active: required || hasLockedApp | ||
1121 | 27 | |||
1122 | 28 | readonly property bool hasLockedApp: lockedApp !== "" | ||
1123 | 29 | readonly property bool locked: false | ||
1124 | 30 | readonly property bool waiting: false | ||
1125 | 31 | readonly property bool fullyShown: shown | ||
1126 | 32 | |||
1127 | 33 | property string lockedApp: "" | ||
1128 | 34 | |||
1129 | 35 | function forceShow() { show(); } | ||
1130 | 36 | property var notifyAppFocusRequested: (function(appId) { return; }) | ||
1131 | 37 | property var notifyUserRequestedApp: (function(appId) { return; }) | ||
1132 | 38 | property var notifyShowingDashFromDrag: (function(appId) { return false; }) | ||
1133 | 39 | |||
1134 | 40 | showAnimation: StandardAnimation { property: "opacity"; to: 1 } | ||
1135 | 41 | hideAnimation: StandardAnimation { property: "opacity"; to: 0 } | ||
1136 | 42 | |||
1137 | 43 | shown: ShellNotifier.greeter.shown | ||
1138 | 44 | Component.onCompleted: opacity = shown ? 1 : 0 | ||
1139 | 45 | visible: opacity != 0 | ||
1140 | 46 | |||
1141 | 47 | Rectangle { | ||
1142 | 48 | anchors.fill: parent | ||
1143 | 49 | color: UbuntuColors.purple | ||
1144 | 50 | } | ||
1145 | 51 | |||
1146 | 52 | MouseArea { | ||
1147 | 53 | anchors.fill: parent | ||
1148 | 54 | acceptedButtons: Qt.AllButtons | ||
1149 | 55 | onWheel: wheel.accepted = true | ||
1150 | 56 | } | ||
1151 | 57 | |||
1152 | 58 | Connections { | ||
1153 | 59 | target: ShellNotifier.greeter | ||
1154 | 60 | onHide: { | ||
1155 | 61 | if (now) { | ||
1156 | 62 | root.hideNow(); // skip hide animation | ||
1157 | 63 | } else { | ||
1158 | 64 | root.hide(); | ||
1159 | 65 | } | ||
1160 | 66 | } | ||
1161 | 67 | onShownChanged: { | ||
1162 | 68 | if (ShellNotifier.greeter.shown) { | ||
1163 | 69 | root.show(); | ||
1164 | 70 | } else { | ||
1165 | 71 | root.hide(); | ||
1166 | 72 | } | ||
1167 | 73 | } | ||
1168 | 74 | } | ||
1169 | 75 | } | ||
1170 | 0 | 76 | ||
1171 | === modified file 'qml/OrientedShell.qml' | |||
1172 | --- qml/OrientedShell.qml 2017-03-21 10:51:57 +0000 | |||
1173 | +++ qml/OrientedShell.qml 2017-03-31 15:02:41 +0000 | |||
1174 | @@ -32,15 +32,17 @@ | |||
1175 | 32 | implicitWidth: units.gu(40) | 32 | implicitWidth: units.gu(40) |
1176 | 33 | implicitHeight: units.gu(71) | 33 | implicitHeight: units.gu(71) |
1177 | 34 | 34 | ||
1178 | 35 | property alias deviceConfiguration: _deviceConfiguration | ||
1179 | 36 | property alias orientations: d.orientations | ||
1180 | 37 | property alias surfaceManager: shell.surfaceManager | ||
1181 | 38 | |||
1182 | 35 | onWidthChanged: calculateUsageMode(); | 39 | onWidthChanged: calculateUsageMode(); |
1183 | 36 | 40 | ||
1184 | 37 | DeviceConfiguration { | 41 | DeviceConfiguration { |
1186 | 38 | id: deviceConfiguration | 42 | id: _deviceConfiguration |
1187 | 39 | name: applicationArguments.deviceName | 43 | name: applicationArguments.deviceName |
1188 | 40 | } | 44 | } |
1189 | 41 | 45 | ||
1190 | 42 | property alias orientations: d.orientations | ||
1191 | 43 | |||
1192 | 44 | Item { | 46 | Item { |
1193 | 45 | id: d | 47 | id: d |
1194 | 46 | 48 | ||
1195 | @@ -157,10 +159,6 @@ | |||
1196 | 157 | return false; | 159 | return false; |
1197 | 158 | } | 160 | } |
1198 | 159 | 161 | ||
1199 | 160 | Screens { | ||
1200 | 161 | id: screens | ||
1201 | 162 | } | ||
1202 | 163 | |||
1203 | 164 | property int orientation | 162 | property int orientation |
1204 | 165 | onPhysicalOrientationChanged: { | 163 | onPhysicalOrientationChanged: { |
1205 | 166 | if (!orientationLocked) { | 164 | if (!orientationLocked) { |
1206 | 167 | 165 | ||
1207 | === modified file 'qml/Panel/Panel.qml' | |||
1208 | --- qml/Panel/Panel.qml 2017-03-21 10:55:52 +0000 | |||
1209 | +++ qml/Panel/Panel.qml 2017-03-31 15:02:41 +0000 | |||
1210 | @@ -48,6 +48,7 @@ | |||
1211 | 48 | property bool hasKeyboard: false | 48 | property bool hasKeyboard: false |
1212 | 49 | 49 | ||
1213 | 50 | property string mode: "staged" | 50 | property string mode: "staged" |
1214 | 51 | property PanelState panelState | ||
1215 | 51 | 52 | ||
1216 | 52 | MouseArea { | 53 | MouseArea { |
1217 | 53 | id: backMouseEater | 54 | id: backMouseEater |
1218 | @@ -64,14 +65,14 @@ | |||
1219 | 64 | } | 65 | } |
1220 | 65 | 66 | ||
1221 | 66 | Binding { | 67 | Binding { |
1223 | 67 | target: PanelState | 68 | target: panelState |
1224 | 68 | property: "panelHeight" | 69 | property: "panelHeight" |
1225 | 69 | value: minimizedPanelHeight | 70 | value: minimizedPanelHeight |
1226 | 70 | } | 71 | } |
1227 | 71 | 72 | ||
1228 | 72 | RegisteredApplicationMenuModel { | 73 | RegisteredApplicationMenuModel { |
1229 | 73 | id: registeredMenuModel | 74 | id: registeredMenuModel |
1231 | 74 | persistentSurfaceId: PanelState.focusedPersistentSurfaceId | 75 | persistentSurfaceId: panelState.focusedPersistentSurfaceId |
1232 | 75 | } | 76 | } |
1233 | 76 | 77 | ||
1234 | 77 | QtObject { | 78 | QtObject { |
1235 | @@ -82,11 +83,11 @@ | |||
1236 | 82 | !indicators.shown && | 83 | !indicators.shown && |
1237 | 83 | (decorationMouseArea.containsMouse || menuBarLoader.menusRequested) | 84 | (decorationMouseArea.containsMouse || menuBarLoader.menusRequested) |
1238 | 84 | 85 | ||
1241 | 85 | property bool showWindowDecorationControls: (revealControls && PanelState.decorationsVisible) || | 86 | property bool showWindowDecorationControls: (revealControls && panelState.decorationsVisible) || |
1242 | 86 | PanelState.decorationsAlwaysVisible | 87 | panelState.decorationsAlwaysVisible |
1243 | 87 | 88 | ||
1244 | 88 | property bool showPointerMenu: revealControls && | 89 | property bool showPointerMenu: revealControls && |
1246 | 89 | (PanelState.decorationsVisible || mode == "staged") | 90 | (panelState.decorationsVisible || mode == "staged") |
1247 | 90 | 91 | ||
1248 | 91 | property bool enablePointerMenu: revealControls && | 92 | property bool enablePointerMenu: revealControls && |
1249 | 92 | applicationMenus.available && | 93 | applicationMenus.available && |
1250 | @@ -138,7 +139,7 @@ | |||
1251 | 138 | fill: panelAreaBackground | 139 | fill: panelAreaBackground |
1252 | 139 | bottomMargin: -units.gu(1) | 140 | bottomMargin: -units.gu(1) |
1253 | 140 | } | 141 | } |
1255 | 141 | visible: PanelState.dropShadow | 142 | visible: panelState.dropShadow |
1256 | 142 | source: "graphics/rectangular_dropshadow.sci" | 143 | source: "graphics/rectangular_dropshadow.sci" |
1257 | 143 | } | 144 | } |
1258 | 144 | 145 | ||
1259 | @@ -195,12 +196,12 @@ | |||
1260 | 195 | visible: opacity != 0 | 196 | visible: opacity != 0 |
1261 | 196 | Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } } | 197 | Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
1262 | 197 | 198 | ||
1264 | 198 | active: PanelState.decorationsVisible || PanelState.decorationsAlwaysVisible | 199 | active: panelState.decorationsVisible || panelState.decorationsAlwaysVisible |
1265 | 199 | windowIsMaximized: true | 200 | windowIsMaximized: true |
1270 | 200 | onCloseClicked: PanelState.closeClicked() | 201 | onCloseClicked: panelState.closeClicked() |
1271 | 201 | onMinimizeClicked: PanelState.minimizeClicked() | 202 | onMinimizeClicked: panelState.minimizeClicked() |
1272 | 202 | onMaximizeClicked: PanelState.restoreClicked() | 203 | onMaximizeClicked: panelState.restoreClicked() |
1273 | 203 | closeButtonShown: PanelState.closeButtonShown | 204 | closeButtonShown: panelState.closeButtonShown |
1274 | 204 | } | 205 | } |
1275 | 205 | 206 | ||
1276 | 206 | Loader { | 207 | Loader { |
1277 | @@ -220,11 +221,12 @@ | |||
1278 | 220 | sourceComponent: MenuBar { | 221 | sourceComponent: MenuBar { |
1279 | 221 | id: bar | 222 | id: bar |
1280 | 222 | objectName: "menuBar" | 223 | objectName: "menuBar" |
1282 | 223 | anchors.left: parent.left | 224 | anchors.left: menuBarLoader.left |
1283 | 224 | anchors.margins: units.gu(1) | 225 | anchors.margins: units.gu(1) |
1284 | 225 | height: menuBarLoader.height | 226 | height: menuBarLoader.height |
1286 | 226 | enableKeyFilter: valid && PanelState.decorationsVisible | 227 | enableKeyFilter: valid && panelState.decorationsVisible |
1287 | 227 | unityMenuModel: __applicationMenus.model | 228 | unityMenuModel: __applicationMenus.model |
1288 | 229 | panelState: root.panelState | ||
1289 | 228 | 230 | ||
1290 | 229 | Connections { | 231 | Connections { |
1291 | 230 | target: __applicationMenus | 232 | target: __applicationMenus |
1292 | @@ -236,7 +238,7 @@ | |||
1293 | 236 | onShownChanged: bar.dismiss(); | 238 | onShownChanged: bar.dismiss(); |
1294 | 237 | } | 239 | } |
1295 | 238 | 240 | ||
1297 | 239 | onDoubleClicked: PanelState.restoreClicked() | 241 | onDoubleClicked: panelState.restoreClicked() |
1298 | 240 | onPressed: mouse.accepted = false // let the parent mouse area handle this, so it can both unsnap window and show menu | 242 | onPressed: mouse.accepted = false // let the parent mouse area handle this, so it can both unsnap window and show menu |
1299 | 241 | } | 243 | } |
1300 | 242 | } | 244 | } |
1301 | @@ -343,7 +345,7 @@ | |||
1302 | 343 | opacity: __applicationMenus.visible && !__applicationMenus.expanded ? 1 : 0 | 345 | opacity: __applicationMenus.visible && !__applicationMenus.expanded ? 1 : 0 |
1303 | 344 | visible: opacity != 0 | 346 | visible: opacity != 0 |
1304 | 345 | Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } } | 347 | Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
1306 | 346 | text: PanelState.title | 348 | text: panelState.title |
1307 | 347 | } | 349 | } |
1308 | 348 | 350 | ||
1309 | 349 | PanelMenu { | 351 | PanelMenu { |
1310 | 350 | 352 | ||
1311 | === modified file 'qml/Shell.qml' | |||
1312 | --- qml/Shell.qml 2017-03-24 14:04:50 +0000 | |||
1313 | +++ qml/Shell.qml 2017-03-31 15:02:41 +0000 | |||
1314 | @@ -1,4 +1,4 @@ | |||
1316 | 1 | /* | 1 | /* |
1317 | 2 | * Copyright (C) 2013-2016 Canonical, Ltd. | 2 | * Copyright (C) 2013-2016 Canonical, Ltd. |
1318 | 3 | * | 3 | * |
1319 | 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
1320 | @@ -38,6 +38,7 @@ | |||
1321 | 38 | import "Stage" | 38 | import "Stage" |
1322 | 39 | import "Tutorial" | 39 | import "Tutorial" |
1323 | 40 | import "Wizard" | 40 | import "Wizard" |
1324 | 41 | import "Components/PanelState" | ||
1325 | 41 | import Unity.Notifications 1.0 as NotificationBackend | 42 | import Unity.Notifications 1.0 as NotificationBackend |
1326 | 42 | import Unity.Session 0.1 | 43 | import Unity.Session 0.1 |
1327 | 43 | import Unity.DashCommunicator 0.1 | 44 | import Unity.DashCommunicator 0.1 |
1328 | @@ -52,6 +53,7 @@ | |||
1329 | 52 | theme.name: "Ubuntu.Components.Themes.SuruDark" | 53 | theme.name: "Ubuntu.Components.Themes.SuruDark" |
1330 | 53 | 54 | ||
1331 | 54 | // to be set from outside | 55 | // to be set from outside |
1332 | 56 | property alias surfaceManager: topLevelSurfaceList.surfaceManager | ||
1333 | 55 | property int orientationAngle: 0 | 57 | property int orientationAngle: 0 |
1334 | 56 | property int orientation | 58 | property int orientation |
1335 | 57 | property Orientations orientations | 59 | property Orientations orientations |
1336 | @@ -267,21 +269,21 @@ | |||
1337 | 267 | schema.id: "com.canonical.Unity8" | 269 | schema.id: "com.canonical.Unity8" |
1338 | 268 | } | 270 | } |
1339 | 269 | 271 | ||
1340 | 272 | PanelState { | ||
1341 | 273 | id: panelState | ||
1342 | 274 | objectName: "panelState" | ||
1343 | 275 | } | ||
1344 | 276 | |||
1345 | 270 | Item { | 277 | Item { |
1346 | 271 | id: stages | 278 | id: stages |
1347 | 272 | objectName: "stages" | 279 | objectName: "stages" |
1348 | 273 | width: parent.width | 280 | width: parent.width |
1349 | 274 | height: parent.height | 281 | height: parent.height |
1350 | 275 | 282 | ||
1351 | 276 | SurfaceManager { | ||
1352 | 277 | id: surfaceMan | ||
1353 | 278 | objectName: "surfaceManager" | ||
1354 | 279 | } | ||
1355 | 280 | TopLevelWindowModel { | 283 | TopLevelWindowModel { |
1356 | 281 | id: topLevelSurfaceList | 284 | id: topLevelSurfaceList |
1357 | 282 | objectName: "topLevelSurfaceList" | 285 | objectName: "topLevelSurfaceList" |
1358 | 283 | applicationManager: ApplicationManager // it's a singleton | 286 | applicationManager: ApplicationManager // it's a singleton |
1359 | 284 | surfaceManager: surfaceMan | ||
1360 | 285 | } | 287 | } |
1361 | 286 | 288 | ||
1362 | 287 | Stage { | 289 | Stage { |
1363 | @@ -323,6 +325,7 @@ | |||
1364 | 323 | altTabPressed: physicalKeysMapper.altTabPressed | 325 | altTabPressed: physicalKeysMapper.altTabPressed |
1365 | 324 | oskEnabled: shell.oskEnabled | 326 | oskEnabled: shell.oskEnabled |
1366 | 325 | spreadEnabled: tutorial.spreadEnabled && (!greeter || (!greeter.hasLockedApp && !greeter.shown)) | 327 | spreadEnabled: tutorial.spreadEnabled && (!greeter || (!greeter.hasLockedApp && !greeter.shown)) |
1367 | 328 | panelState: panelState | ||
1368 | 326 | 329 | ||
1369 | 327 | onSpreadShownChanged: { | 330 | onSpreadShownChanged: { |
1370 | 328 | panel.indicators.hide(); | 331 | panel.indicators.hide(); |
1371 | @@ -377,8 +380,13 @@ | |||
1372 | 377 | objectName: "greeterLoader" | 380 | objectName: "greeterLoader" |
1373 | 378 | anchors.fill: parent | 381 | anchors.fill: parent |
1374 | 379 | anchors.topMargin: panel.panelHeight | 382 | anchors.topMargin: panel.panelHeight |
1377 | 380 | sourceComponent: shell.mode != "shell" ? integratedGreeter : | 383 | sourceComponent: { |
1378 | 381 | Qt.createComponent(Qt.resolvedUrl("Greeter/ShimGreeter.qml")); | 384 | if (shell.mode != "shell") { |
1379 | 385 | if (screenWindow.primary) return integratedGreeter; | ||
1380 | 386 | return secondaryGreeter; | ||
1381 | 387 | } | ||
1382 | 388 | return Qt.createComponent(Qt.resolvedUrl("Greeter/ShimGreeter.qml")); | ||
1383 | 389 | } | ||
1384 | 382 | onLoaded: { | 390 | onLoaded: { |
1385 | 383 | item.objectName = "greeter" | 391 | item.objectName = "greeter" |
1386 | 384 | } | 392 | } |
1387 | @@ -428,6 +436,13 @@ | |||
1388 | 428 | } | 436 | } |
1389 | 429 | } | 437 | } |
1390 | 430 | 438 | ||
1391 | 439 | Component { | ||
1392 | 440 | id: secondaryGreeter | ||
1393 | 441 | SecondaryGreeter { | ||
1394 | 442 | hides: [launcher, panel.indicators] | ||
1395 | 443 | } | ||
1396 | 444 | } | ||
1397 | 445 | |||
1398 | 431 | Timer { | 446 | Timer { |
1399 | 432 | // See powerConnection for why this is useful | 447 | // See powerConnection for why this is useful |
1400 | 433 | id: showGreeterDelayed | 448 | id: showGreeterDelayed |
1401 | @@ -545,6 +560,7 @@ | |||
1402 | 545 | || greeter.hasLockedApp | 560 | || greeter.hasLockedApp |
1403 | 546 | greeterShown: greeter && greeter.shown | 561 | greeterShown: greeter && greeter.shown |
1404 | 547 | hasKeyboard: shell.hasKeyboard | 562 | hasKeyboard: shell.hasKeyboard |
1405 | 563 | panelState: panelState | ||
1406 | 548 | } | 564 | } |
1407 | 549 | 565 | ||
1408 | 550 | Launcher { | 566 | Launcher { |
1409 | @@ -793,11 +809,11 @@ | |||
1410 | 793 | Cursor { | 809 | Cursor { |
1411 | 794 | id: cursor | 810 | id: cursor |
1412 | 795 | objectName: "cursor" | 811 | objectName: "cursor" |
1414 | 796 | visible: shell.hasMouse | 812 | |
1415 | 797 | z: itemGrabber.z + 1 | 813 | z: itemGrabber.z + 1 |
1416 | 798 | topBoundaryOffset: panel.panelHeight | 814 | topBoundaryOffset: panel.panelHeight |
1419 | 799 | 815 | enabled: shell.hasMouse && screenWindow.active | |
1420 | 800 | confiningItem: stage.itemConfiningMouseCursor | 816 | visible: enabled |
1421 | 801 | 817 | ||
1422 | 802 | property bool mouseNeverMoved: true | 818 | property bool mouseNeverMoved: true |
1423 | 803 | Binding { | 819 | Binding { |
1424 | @@ -809,6 +825,8 @@ | |||
1425 | 809 | when: cursor.mouseNeverMoved && cursor.visible | 825 | when: cursor.mouseNeverMoved && cursor.visible |
1426 | 810 | } | 826 | } |
1427 | 811 | 827 | ||
1428 | 828 | confiningItem: stage.itemConfiningMouseCursor | ||
1429 | 829 | |||
1430 | 812 | height: units.gu(3) | 830 | height: units.gu(3) |
1431 | 813 | 831 | ||
1432 | 814 | readonly property var previewRectangle: stage.previewRectangle.target && | 832 | readonly property var previewRectangle: stage.previewRectangle.target && |
1433 | 815 | 833 | ||
1434 | === added file 'qml/ShellApplication.qml' | |||
1435 | --- qml/ShellApplication.qml 1970-01-01 00:00:00 +0000 | |||
1436 | +++ qml/ShellApplication.qml 2017-03-31 15:02:41 +0000 | |||
1437 | @@ -0,0 +1,52 @@ | |||
1438 | 1 | /* | ||
1439 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1440 | 3 | * | ||
1441 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1442 | 5 | * it under the terms of the GNU General Public License as published by | ||
1443 | 6 | * the Free Software Foundation; version 3. | ||
1444 | 7 | * | ||
1445 | 8 | * This program is distributed in the hope that it will be useful, | ||
1446 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1447 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1448 | 11 | * GNU General Public License for more details. | ||
1449 | 12 | * | ||
1450 | 13 | * You should have received a copy of the GNU General Public License | ||
1451 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1452 | 15 | */ | ||
1453 | 16 | |||
1454 | 17 | import QtQuick 2.4 | ||
1455 | 18 | import QtQuick.Window 2.2 | ||
1456 | 19 | import Unity.Screens 0.1 | ||
1457 | 20 | import Unity.Application 0.1 | ||
1458 | 21 | |||
1459 | 22 | Instantiator { | ||
1460 | 23 | id: root | ||
1461 | 24 | model: Screens | ||
1462 | 25 | |||
1463 | 26 | property QtObject surfaceMan: SurfaceManager {} | ||
1464 | 27 | |||
1465 | 28 | ShellScreen { | ||
1466 | 29 | id: window | ||
1467 | 30 | objectName: "screen"+index | ||
1468 | 31 | screen: model.screen | ||
1469 | 32 | visibility: applicationArguments.hasFullscreen ? Window.FullScreen : Window.Windowed | ||
1470 | 33 | flags: applicationArguments.hasFrameless ? Qt.FramelessWindowHint : 0 | ||
1471 | 34 | surfaceManager: surfaceMan | ||
1472 | 35 | |||
1473 | 36 | Binding { | ||
1474 | 37 | when: applicationArguments.hasGeometry | ||
1475 | 38 | target: window | ||
1476 | 39 | property: "width" | ||
1477 | 40 | value: applicationArguments.windowGeometry.width | ||
1478 | 41 | } | ||
1479 | 42 | Binding { | ||
1480 | 43 | when: applicationArguments.hasGeometry | ||
1481 | 44 | target: window | ||
1482 | 45 | property: "height" | ||
1483 | 46 | value: applicationArguments.windowGeometry.height | ||
1484 | 47 | } | ||
1485 | 48 | |||
1486 | 49 | Component.onCompleted: screen.active = primary | ||
1487 | 50 | primary: index == 0 | ||
1488 | 51 | } | ||
1489 | 52 | } | ||
1490 | 0 | 53 | ||
1491 | === added file 'qml/ShellNotifier.qml' | |||
1492 | --- qml/ShellNotifier.qml 1970-01-01 00:00:00 +0000 | |||
1493 | +++ qml/ShellNotifier.qml 2017-03-31 15:02:41 +0000 | |||
1494 | @@ -0,0 +1,30 @@ | |||
1495 | 1 | /* | ||
1496 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1497 | 3 | * | ||
1498 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1499 | 5 | * it under the terms of the GNU General Public License as published by | ||
1500 | 6 | * the Free Software Foundation; version 3. | ||
1501 | 7 | * | ||
1502 | 8 | * This program is distributed in the hope that it will be useful, | ||
1503 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1504 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1505 | 11 | * GNU General Public License for more details. | ||
1506 | 12 | * | ||
1507 | 13 | * You should have received a copy of the GNU General Public License | ||
1508 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1509 | 15 | */ | ||
1510 | 16 | |||
1511 | 17 | /* | ||
1512 | 18 | Shared signals & properties on multi-window desktop | ||
1513 | 19 | */ | ||
1514 | 20 | |||
1515 | 21 | pragma Singleton | ||
1516 | 22 | import QtQuick 2.4 | ||
1517 | 23 | |||
1518 | 24 | QtObject { | ||
1519 | 25 | property var greeter: QtObject { | ||
1520 | 26 | signal hide(bool now) | ||
1521 | 27 | |||
1522 | 28 | property bool shown: true | ||
1523 | 29 | } | ||
1524 | 30 | } | ||
1525 | 0 | 31 | ||
1526 | === added file 'qml/ShellScreen.qml' | |||
1527 | --- qml/ShellScreen.qml 1970-01-01 00:00:00 +0000 | |||
1528 | +++ qml/ShellScreen.qml 2017-03-31 15:02:41 +0000 | |||
1529 | @@ -0,0 +1,66 @@ | |||
1530 | 1 | /* | ||
1531 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
1532 | 3 | * | ||
1533 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1534 | 5 | * it under the terms of the GNU General Public License as published by | ||
1535 | 6 | * the Free Software Foundation; version 3. | ||
1536 | 7 | * | ||
1537 | 8 | * This program is distributed in the hope that it will be useful, | ||
1538 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1539 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1540 | 11 | * GNU General Public License for more details. | ||
1541 | 12 | * | ||
1542 | 13 | * You should have received a copy of the GNU General Public License | ||
1543 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1544 | 15 | */ | ||
1545 | 16 | |||
1546 | 17 | import QtQuick 2.4 | ||
1547 | 18 | import Ubuntu.Components 1.3 | ||
1548 | 19 | import Unity.Screens 0.1 | ||
1549 | 20 | import Cursor 1.1 | ||
1550 | 21 | import "Components" | ||
1551 | 22 | |||
1552 | 23 | ScreenWindow { | ||
1553 | 24 | id: screenWindow | ||
1554 | 25 | |||
1555 | 26 | color: "black" | ||
1556 | 27 | title: "Unity8 Shell" | ||
1557 | 28 | property bool primary: false | ||
1558 | 29 | property QtObject surfaceManager: null | ||
1559 | 30 | |||
1560 | 31 | DeviceConfiguration { | ||
1561 | 32 | id: deviceConfiguration | ||
1562 | 33 | name: applicationArguments.deviceName | ||
1563 | 34 | } | ||
1564 | 35 | |||
1565 | 36 | Loader { | ||
1566 | 37 | id: loader | ||
1567 | 38 | width: screenWindow.width | ||
1568 | 39 | height: screenWindow.height | ||
1569 | 40 | |||
1570 | 41 | sourceComponent: { | ||
1571 | 42 | if (Screens.count > 1 && primary && deviceConfiguration.category !== "desktop") { | ||
1572 | 43 | return disabledScreenComponent; | ||
1573 | 44 | } | ||
1574 | 45 | return shellComponent; | ||
1575 | 46 | } | ||
1576 | 47 | } | ||
1577 | 48 | |||
1578 | 49 | Component { | ||
1579 | 50 | id: shellComponent | ||
1580 | 51 | OrientedShell { | ||
1581 | 52 | implicitWidth: screenWindow.width | ||
1582 | 53 | implicitHeight: screenWindow.height | ||
1583 | 54 | surfaceManager: screenWindow.surfaceManager | ||
1584 | 55 | |||
1585 | 56 | deviceConfiguration { | ||
1586 | 57 | name: Screens.count > 1 ? "desktop" : applicationArguments.deviceName | ||
1587 | 58 | } | ||
1588 | 59 | } | ||
1589 | 60 | } | ||
1590 | 61 | |||
1591 | 62 | Component { | ||
1592 | 63 | id: disabledScreenComponent | ||
1593 | 64 | DisabledScreenNotice {} | ||
1594 | 65 | } | ||
1595 | 66 | } | ||
1596 | 0 | 67 | ||
1597 | === modified file 'qml/Stage/DecoratedWindow.qml' | |||
1598 | --- qml/Stage/DecoratedWindow.qml 2017-03-24 14:04:50 +0000 | |||
1599 | +++ qml/Stage/DecoratedWindow.qml 2017-03-31 15:02:41 +0000 | |||
1600 | @@ -38,6 +38,7 @@ | |||
1601 | 38 | property alias maximizeButtonShown: decoration.maximizeButtonShown | 38 | property alias maximizeButtonShown: decoration.maximizeButtonShown |
1602 | 39 | property alias interactive: applicationWindow.interactive | 39 | property alias interactive: applicationWindow.interactive |
1603 | 40 | readonly property alias orientationChangesEnabled: applicationWindow.orientationChangesEnabled | 40 | readonly property alias orientationChangesEnabled: applicationWindow.orientationChangesEnabled |
1604 | 41 | property PanelState panelState | ||
1605 | 41 | 42 | ||
1606 | 42 | // Changing this will actually add/remove a decoration, meaning, requestedHeight will take the decoration into account. | 43 | // Changing this will actually add/remove a decoration, meaning, requestedHeight will take the decoration into account. |
1607 | 43 | property bool hasDecoration: true | 44 | property bool hasDecoration: true |
1608 | @@ -218,6 +219,7 @@ | |||
1609 | 218 | 219 | ||
1610 | 219 | title: applicationWindow.title | 220 | title: applicationWindow.title |
1611 | 220 | windowMoving: moveHandler.moving && !altDragHandler.dragging | 221 | windowMoving: moveHandler.moving && !altDragHandler.dragging |
1612 | 222 | panelState: root.panelState | ||
1613 | 221 | 223 | ||
1614 | 222 | opacity: root.hasDecoration ? Math.min(1, root.showDecoration) : 0 | 224 | opacity: root.hasDecoration ? Math.min(1, root.showDecoration) : 0 |
1615 | 223 | Behavior on opacity { UbuntuNumberAnimation { } } | 225 | Behavior on opacity { UbuntuNumberAnimation { } } |
1616 | @@ -241,7 +243,7 @@ | |||
1617 | 241 | enableMenus: { | 243 | enableMenus: { |
1618 | 242 | return active && | 244 | return active && |
1619 | 243 | surface && | 245 | surface && |
1621 | 244 | (PanelState.focusedPersistentSurfaceId === surface.persistentId && !PanelState.decorationsVisible) | 246 | (panelState.focusedPersistentSurfaceId === surface.persistentId && !panelState.decorationsVisible) |
1622 | 245 | } | 247 | } |
1623 | 246 | menu: sharedAppModel.model | 248 | menu: sharedAppModel.model |
1624 | 247 | 249 | ||
1625 | 248 | 250 | ||
1626 | === modified file 'qml/Stage/FakeMaximizeDelegate.qml' | |||
1627 | --- qml/Stage/FakeMaximizeDelegate.qml 2016-11-30 19:24:02 +0000 | |||
1628 | +++ qml/Stage/FakeMaximizeDelegate.qml 2017-03-31 15:02:41 +0000 | |||
1629 | @@ -35,6 +35,7 @@ | |||
1630 | 35 | property int leftMargin | 35 | property int leftMargin |
1631 | 36 | property real appContainerWidth | 36 | property real appContainerWidth |
1632 | 37 | property real appContainerHeight | 37 | property real appContainerHeight |
1633 | 38 | property PanelState panelState | ||
1634 | 38 | 39 | ||
1635 | 39 | readonly property real hintThreshold: 0.1 | 40 | readonly property real hintThreshold: 0.1 |
1636 | 40 | 41 | ||
1637 | @@ -178,7 +179,7 @@ | |||
1638 | 178 | ParallelAnimation { | 179 | ParallelAnimation { |
1639 | 179 | id: fakeMaximizeAnimation | 180 | id: fakeMaximizeAnimation |
1640 | 180 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } | 181 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } |
1642 | 181 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: PanelState.panelHeight } | 182 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: panelState.panelHeight } |
1643 | 182 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: appContainerWidth - leftMargin } | 183 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: appContainerWidth - leftMargin } |
1644 | 183 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight } | 184 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight } |
1645 | 184 | } | 185 | } |
1646 | @@ -186,39 +187,39 @@ | |||
1647 | 186 | ParallelAnimation { | 187 | ParallelAnimation { |
1648 | 187 | id: fakeMaximizeLeftAnimation | 188 | id: fakeMaximizeLeftAnimation |
1649 | 188 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } | 189 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } |
1651 | 189 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: PanelState.panelHeight } | 190 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: panelState.panelHeight } |
1652 | 190 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } | 191 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } |
1654 | 191 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight - PanelState.panelHeight } | 192 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight - panelState.panelHeight } |
1655 | 192 | } | 193 | } |
1656 | 193 | 194 | ||
1657 | 194 | ParallelAnimation { | 195 | ParallelAnimation { |
1658 | 195 | id: fakeMaximizeRightAnimation | 196 | id: fakeMaximizeRightAnimation |
1659 | 196 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth + leftMargin)/2 } | 197 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth + leftMargin)/2 } |
1661 | 197 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: PanelState.panelHeight } | 198 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: panelState.panelHeight } |
1662 | 198 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } | 199 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } |
1664 | 199 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight - PanelState.panelHeight } | 200 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight - panelState.panelHeight } |
1665 | 200 | } | 201 | } |
1666 | 201 | 202 | ||
1667 | 202 | ParallelAnimation { | 203 | ParallelAnimation { |
1668 | 203 | id: fakeMaximizeTopLeftAnimation | 204 | id: fakeMaximizeTopLeftAnimation |
1669 | 204 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } | 205 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } |
1671 | 205 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: PanelState.panelHeight } | 206 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: panelState.panelHeight } |
1672 | 206 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } | 207 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } |
1674 | 207 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight - PanelState.panelHeight)/2 } | 208 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight - panelState.panelHeight)/2 } |
1675 | 208 | } | 209 | } |
1676 | 209 | 210 | ||
1677 | 210 | ParallelAnimation { | 211 | ParallelAnimation { |
1678 | 211 | id: fakeMaximizeTopRightAnimation | 212 | id: fakeMaximizeTopRightAnimation |
1679 | 212 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth + leftMargin)/2 } | 213 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth + leftMargin)/2 } |
1681 | 213 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: PanelState.panelHeight } | 214 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: panelState.panelHeight } |
1682 | 214 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } | 215 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } |
1684 | 215 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight - PanelState.panelHeight)/2 } | 216 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight - panelState.panelHeight)/2 } |
1685 | 216 | } | 217 | } |
1686 | 217 | 218 | ||
1687 | 218 | ParallelAnimation { | 219 | ParallelAnimation { |
1688 | 219 | id: fakeMaximizeBottomLeftAnimation | 220 | id: fakeMaximizeBottomLeftAnimation |
1689 | 220 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } | 221 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: leftMargin } |
1691 | 221 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight + PanelState.panelHeight)/2 } | 222 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight + panelState.panelHeight)/2 } |
1692 | 222 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } | 223 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } |
1693 | 223 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight/2 } | 224 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight/2 } |
1694 | 224 | } | 225 | } |
1695 | @@ -226,7 +227,7 @@ | |||
1696 | 226 | ParallelAnimation { | 227 | ParallelAnimation { |
1697 | 227 | id: fakeMaximizeBottomRightAnimation | 228 | id: fakeMaximizeBottomRightAnimation |
1698 | 228 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth + leftMargin)/2 } | 229 | UbuntuNumberAnimation { target: fakeRectangle; properties: "x"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth + leftMargin)/2 } |
1700 | 229 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight + PanelState.panelHeight)/2 } | 230 | UbuntuNumberAnimation { target: fakeRectangle; properties: "y"; duration: UbuntuAnimation.BriskDuration; to: (appContainerHeight + panelState.panelHeight)/2 } |
1701 | 230 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } | 231 | UbuntuNumberAnimation { target: fakeRectangle; properties: "width"; duration: UbuntuAnimation.BriskDuration; to: (appContainerWidth - leftMargin)/2 } |
1702 | 231 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight/2 } | 232 | UbuntuNumberAnimation { target: fakeRectangle; properties: "height"; duration: UbuntuAnimation.BriskDuration; to: appContainerHeight/2 } |
1703 | 232 | } | 233 | } |
1704 | 233 | 234 | ||
1705 | === modified file 'qml/Stage/Stage.qml' | |||
1706 | --- qml/Stage/Stage.qml 2017-03-28 21:46:37 +0000 | |||
1707 | +++ qml/Stage/Stage.qml 2017-03-31 15:02:41 +0000 | |||
1708 | @@ -48,6 +48,7 @@ | |||
1709 | 48 | property rect inputMethodRect | 48 | property rect inputMethodRect |
1710 | 49 | property real rightEdgePushProgress: 0 | 49 | property real rightEdgePushProgress: 0 |
1711 | 50 | property Item availableDesktopArea | 50 | property Item availableDesktopArea |
1712 | 51 | property PanelState panelState | ||
1713 | 51 | 52 | ||
1714 | 52 | // Configuration | 53 | // Configuration |
1715 | 53 | property string mode: "staged" | 54 | property string mode: "staged" |
1716 | @@ -381,20 +382,20 @@ | |||
1717 | 381 | Component.onCompleted: priv.updateMainAndSideStageIndexes(); | 382 | Component.onCompleted: priv.updateMainAndSideStageIndexes(); |
1718 | 382 | 383 | ||
1719 | 383 | Connections { | 384 | Connections { |
1721 | 384 | target: PanelState | 385 | target: panelState |
1722 | 385 | onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } } | 386 | onCloseClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.close(); } } |
1723 | 386 | onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestMinimize(); } } | 387 | onMinimizeClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestMinimize(); } } |
1724 | 387 | onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestRestore(); } } | 388 | onRestoreClicked: { if (priv.focusedAppDelegate) { priv.focusedAppDelegate.requestRestore(); } } |
1725 | 388 | } | 389 | } |
1726 | 389 | 390 | ||
1727 | 390 | Binding { | 391 | Binding { |
1729 | 391 | target: PanelState | 392 | target: panelState |
1730 | 392 | property: "decorationsVisible" | 393 | property: "decorationsVisible" |
1731 | 393 | value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus | 394 | value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus |
1732 | 394 | } | 395 | } |
1733 | 395 | 396 | ||
1734 | 396 | Binding { | 397 | Binding { |
1736 | 397 | target: PanelState | 398 | target: panelState |
1737 | 398 | property: "title" | 399 | property: "title" |
1738 | 399 | value: { | 400 | value: { |
1739 | 400 | if (priv.focusedAppDelegate !== null) { | 401 | if (priv.focusedAppDelegate !== null) { |
1740 | @@ -409,7 +410,7 @@ | |||
1741 | 409 | } | 410 | } |
1742 | 410 | 411 | ||
1743 | 411 | Binding { | 412 | Binding { |
1745 | 412 | target: PanelState | 413 | target: panelState |
1746 | 413 | property: "focusedPersistentSurfaceId" | 414 | property: "focusedPersistentSurfaceId" |
1747 | 414 | value: { | 415 | value: { |
1748 | 415 | if (priv.focusedAppDelegate !== null) { | 416 | if (priv.focusedAppDelegate !== null) { |
1749 | @@ -423,21 +424,21 @@ | |||
1750 | 423 | } | 424 | } |
1751 | 424 | 425 | ||
1752 | 425 | Binding { | 426 | Binding { |
1754 | 426 | target: PanelState | 427 | target: panelState |
1755 | 427 | property: "dropShadow" | 428 | property: "dropShadow" |
1756 | 428 | value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null && mode == "windowed" | 429 | value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppDelegate !== null && mode == "windowed" |
1757 | 429 | } | 430 | } |
1758 | 430 | 431 | ||
1759 | 431 | Binding { | 432 | Binding { |
1761 | 432 | target: PanelState | 433 | target: panelState |
1762 | 433 | property: "closeButtonShown" | 434 | property: "closeButtonShown" |
1763 | 434 | value: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized && !priv.focusedAppDelegate.isDash | 435 | value: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized && !priv.focusedAppDelegate.isDash |
1764 | 435 | } | 436 | } |
1765 | 436 | 437 | ||
1766 | 437 | Component.onDestruction: { | 438 | Component.onDestruction: { |
1770 | 438 | PanelState.title = ""; | 439 | panelState.title = ""; |
1771 | 439 | PanelState.decorationsVisible = false; | 440 | panelState.decorationsVisible = false; |
1772 | 440 | PanelState.dropShadow = false; | 441 | panelState.dropShadow = false; |
1773 | 441 | } | 442 | } |
1774 | 442 | 443 | ||
1775 | 443 | Instantiator { | 444 | Instantiator { |
1776 | @@ -1606,7 +1607,7 @@ | |||
1777 | 1606 | ] | 1607 | ] |
1778 | 1607 | 1608 | ||
1779 | 1608 | Binding { | 1609 | Binding { |
1781 | 1609 | target: PanelState | 1610 | target: panelState |
1782 | 1610 | property: "decorationsAlwaysVisible" | 1611 | property: "decorationsAlwaysVisible" |
1783 | 1611 | value: appDelegate && appDelegate.maximized && touchControls.overlayShown | 1612 | value: appDelegate && appDelegate.maximized && touchControls.overlayShown |
1784 | 1612 | } | 1613 | } |
1785 | @@ -1652,6 +1653,7 @@ | |||
1786 | 1652 | highlightSize: windowInfoItem.iconMargin / 2 | 1653 | highlightSize: windowInfoItem.iconMargin / 2 |
1787 | 1653 | altDragEnabled: root.mode == "windowed" | 1654 | altDragEnabled: root.mode == "windowed" |
1788 | 1654 | boundsItem: root.availableDesktopArea | 1655 | boundsItem: root.availableDesktopArea |
1789 | 1656 | panelState: root.panelState | ||
1790 | 1655 | 1657 | ||
1791 | 1656 | requestedWidth: appDelegate.requestedWidth | 1658 | requestedWidth: appDelegate.requestedWidth |
1792 | 1657 | requestedHeight: appDelegate.requestedHeight | 1659 | requestedHeight: appDelegate.requestedHeight |
1793 | @@ -1860,6 +1862,7 @@ | |||
1794 | 1860 | leftMargin: root.availableDesktopArea.x | 1862 | leftMargin: root.availableDesktopArea.x |
1795 | 1861 | appContainerWidth: appContainer.width | 1863 | appContainerWidth: appContainer.width |
1796 | 1862 | appContainerHeight: appContainer.height | 1864 | appContainerHeight: appContainer.height |
1797 | 1865 | panelState: root.panelState | ||
1798 | 1863 | } | 1866 | } |
1799 | 1864 | 1867 | ||
1800 | 1865 | MouseArea { | 1868 | MouseArea { |
1801 | 1866 | 1869 | ||
1802 | === modified file 'qml/Stage/WindowDecoration.qml' | |||
1803 | --- qml/Stage/WindowDecoration.qml 2017-03-01 12:18:59 +0000 | |||
1804 | +++ qml/Stage/WindowDecoration.qml 2017-03-31 15:02:41 +0000 | |||
1805 | @@ -34,6 +34,7 @@ | |||
1806 | 34 | property var menu: undefined | 34 | property var menu: undefined |
1807 | 35 | property bool enableMenus: true | 35 | property bool enableMenus: true |
1808 | 36 | property bool windowMoving: false | 36 | property bool windowMoving: false |
1809 | 37 | property PanelState panelState | ||
1810 | 37 | 38 | ||
1811 | 38 | readonly property real buttonsWidth: buttons.width + row.spacing | 39 | readonly property real buttonsWidth: buttons.width + row.spacing |
1812 | 39 | 40 | ||
1813 | @@ -146,6 +147,7 @@ | |||
1814 | 146 | enableKeyFilter: valid && root.active && root.enableMenus | 147 | enableKeyFilter: valid && root.active && root.enableMenus |
1815 | 147 | unityMenuModel: root.menu | 148 | unityMenuModel: root.menu |
1816 | 148 | windowMoving: root.windowMoving | 149 | windowMoving: root.windowMoving |
1817 | 150 | panelState: root.panelState | ||
1818 | 149 | 151 | ||
1819 | 150 | onPressed: root.onPressed(mouse) | 152 | onPressed: root.onPressed(mouse) |
1820 | 151 | onPressedChangedEx: root.pressedChangedEx(pressed, pressedButtons, mouseX, mouseY) | 153 | onPressedChangedEx: root.pressedChangedEx(pressed, pressedButtons, mouseX, mouseY) |
1821 | 152 | 154 | ||
1822 | === added file 'qml/qmldir' | |||
1823 | --- qml/qmldir 1970-01-01 00:00:00 +0000 | |||
1824 | +++ qml/qmldir 2017-03-31 15:02:41 +0000 | |||
1825 | @@ -0,0 +1,1 @@ | |||
1826 | 1 | singleton ShellNotifier 0.1 ShellNotifier.qml | ||
1827 | 0 | 2 | ||
1828 | === modified file 'src/ApplicationArguments.cpp' | |||
1829 | --- src/ApplicationArguments.cpp 2015-03-06 04:44:11 +0000 | |||
1830 | +++ src/ApplicationArguments.cpp 2017-03-31 15:02:41 +0000 | |||
1831 | @@ -16,7 +16,16 @@ | |||
1832 | 16 | 16 | ||
1833 | 17 | #include "ApplicationArguments.h" | 17 | #include "ApplicationArguments.h" |
1834 | 18 | 18 | ||
1838 | 19 | ApplicationArguments::ApplicationArguments(QObject *parent) | 19 | ApplicationArguments::ApplicationArguments(QCoreApplication *app) |
1839 | 20 | : QObject(parent) | 20 | : QObject(app) |
1840 | 21 | { | 21 | , UnityCommandLineParser(*app) |
1841 | 22 | { | ||
1842 | 23 | } | ||
1843 | 24 | |||
1844 | 25 | void ApplicationArguments::setDeviceName(const QString &deviceName) | ||
1845 | 26 | { | ||
1846 | 27 | if (deviceName != m_deviceName) { | ||
1847 | 28 | m_deviceName = deviceName; | ||
1848 | 29 | Q_EMIT deviceNameChanged(m_deviceName); | ||
1849 | 30 | } | ||
1850 | 22 | } | 31 | } |
1851 | 23 | 32 | ||
1852 | === modified file 'src/ApplicationArguments.h' | |||
1853 | --- src/ApplicationArguments.h 2015-10-05 16:43:41 +0000 | |||
1854 | +++ src/ApplicationArguments.h 2017-03-31 15:02:41 +0000 | |||
1855 | @@ -23,31 +23,33 @@ | |||
1856 | 23 | #include <QSize> | 23 | #include <QSize> |
1857 | 24 | #include <QString> | 24 | #include <QString> |
1858 | 25 | 25 | ||
1860 | 26 | class ApplicationArguments : public QObject | 26 | #include "UnityCommandLineParser.h" |
1861 | 27 | |||
1862 | 28 | class ApplicationArguments : public QObject, | ||
1863 | 29 | public UnityCommandLineParser | ||
1864 | 27 | { | 30 | { |
1865 | 28 | Q_OBJECT | 31 | Q_OBJECT |
1866 | 29 | Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged) | 32 | Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged) |
1867 | 30 | Q_PROPERTY(QString mode READ mode CONSTANT) | 33 | Q_PROPERTY(QString mode READ mode CONSTANT) |
1868 | 34 | |||
1869 | 35 | Q_PROPERTY(bool hasGeometry READ hasGeometry CONSTANT) | ||
1870 | 36 | Q_PROPERTY(QSize windowGeometry READ windowGeometry CONSTANT) | ||
1871 | 37 | Q_PROPERTY(bool hasTestability READ hasTestability CONSTANT) | ||
1872 | 38 | Q_PROPERTY(bool hasFrameless READ hasFrameless CONSTANT) | ||
1873 | 39 | Q_PROPERTY(bool hasFullscreen READ hasFullscreen CONSTANT) | ||
1874 | 40 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION | ||
1875 | 41 | Q_PROPERTY(bool hasMouseToTouch READ hasMouseToTouch CONSTANT) | ||
1876 | 42 | #endif | ||
1877 | 43 | |||
1878 | 31 | public: | 44 | public: |
1891 | 32 | ApplicationArguments(QObject *parent = nullptr); | 45 | ApplicationArguments(QCoreApplication *app); |
1892 | 33 | 46 | ||
1893 | 34 | void setDeviceName(const QString &deviceName) { | 47 | void setDeviceName(const QString &deviceName); |
1894 | 35 | if (deviceName != m_deviceName) { | 48 | |
1895 | 36 | m_deviceName = deviceName; | 49 | bool hasGeometry() const { return m_windowGeometry.isValid(); } |
1884 | 37 | Q_EMIT deviceNameChanged(m_deviceName); | ||
1885 | 38 | } | ||
1886 | 39 | } | ||
1887 | 40 | QString deviceName() const { return m_deviceName; } | ||
1888 | 41 | |||
1889 | 42 | void setMode(const QString &mode) { m_mode = mode; } | ||
1890 | 43 | QString mode() const { return m_mode; } | ||
1896 | 44 | 50 | ||
1897 | 45 | Q_SIGNALS: | 51 | Q_SIGNALS: |
1898 | 46 | void deviceNameChanged(const QString&); | 52 | void deviceNameChanged(const QString&); |
1899 | 47 | |||
1900 | 48 | private: | ||
1901 | 49 | QString m_deviceName; | ||
1902 | 50 | QString m_mode; | ||
1903 | 51 | }; | 53 | }; |
1904 | 52 | 54 | ||
1905 | 53 | #endif // APPLICATION_ARGUMENTS_H | 55 | #endif // APPLICATION_ARGUMENTS_H |
1906 | 54 | 56 | ||
1907 | === modified file 'src/CMakeLists.txt' | |||
1908 | --- src/CMakeLists.txt 2017-03-28 21:45:14 +0000 | |||
1909 | +++ src/CMakeLists.txt 2017-03-31 15:02:41 +0000 | |||
1910 | @@ -29,9 +29,7 @@ | |||
1911 | 29 | ApplicationArguments.cpp | 29 | ApplicationArguments.cpp |
1912 | 30 | main.cpp | 30 | main.cpp |
1913 | 31 | CachingNetworkManagerFactory.cpp | 31 | CachingNetworkManagerFactory.cpp |
1914 | 32 | SecondaryWindow.cpp | ||
1915 | 33 | ShellApplication.cpp | 32 | ShellApplication.cpp |
1916 | 34 | ShellView.cpp | ||
1917 | 35 | UnityCommandLineParser.cpp | 33 | UnityCommandLineParser.cpp |
1918 | 36 | UnixSignalHandler.cpp | 34 | UnixSignalHandler.cpp |
1919 | 37 | DebuggingController.cpp | 35 | DebuggingController.cpp |
1920 | 38 | 36 | ||
1921 | === removed file 'src/SecondaryWindow.cpp' | |||
1922 | --- src/SecondaryWindow.cpp 2016-05-09 12:25:29 +0000 | |||
1923 | +++ src/SecondaryWindow.cpp 1970-01-01 00:00:00 +0000 | |||
1924 | @@ -1,40 +0,0 @@ | |||
1925 | 1 | /* | ||
1926 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
1927 | 3 | * | ||
1928 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1929 | 5 | * it under the terms of the GNU General Public License as published by | ||
1930 | 6 | * the Free Software Foundation; version 3. | ||
1931 | 7 | * | ||
1932 | 8 | * This program is distributed in the hope that it will be useful, | ||
1933 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1934 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1935 | 11 | * GNU General Public License for more details. | ||
1936 | 12 | * | ||
1937 | 13 | * You should have received a copy of the GNU General Public License | ||
1938 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1939 | 15 | */ | ||
1940 | 16 | |||
1941 | 17 | #include "SecondaryWindow.h" | ||
1942 | 18 | |||
1943 | 19 | // local | ||
1944 | 20 | #include <paths.h> | ||
1945 | 21 | |||
1946 | 22 | #include <QQmlContext> | ||
1947 | 23 | |||
1948 | 24 | SecondaryWindow::SecondaryWindow(QQmlEngine *engine) | ||
1949 | 25 | : QQuickView(engine, nullptr) | ||
1950 | 26 | { | ||
1951 | 27 | QByteArray pxpguEnv = qgetenv("GRID_UNIT_PX"); | ||
1952 | 28 | bool ok; | ||
1953 | 29 | int pxpgu = pxpguEnv.toInt(&ok); | ||
1954 | 30 | if (!ok) { | ||
1955 | 31 | pxpgu = 8; | ||
1956 | 32 | } | ||
1957 | 33 | engine->rootContext()->setContextProperty(QStringLiteral("internalGu"), pxpgu); | ||
1958 | 34 | setResizeMode(QQuickView::SizeRootObjectToView); | ||
1959 | 35 | setColor("black"); | ||
1960 | 36 | setTitle(QStringLiteral("Unity8 Shell - Secondary Screen")); | ||
1961 | 37 | |||
1962 | 38 | QUrl source(::qmlDirectory() + "/DisabledScreenNotice.qml"); | ||
1963 | 39 | setSource(source); | ||
1964 | 40 | } | ||
1965 | 41 | 0 | ||
1966 | === removed file 'src/SecondaryWindow.h' | |||
1967 | --- src/SecondaryWindow.h 2015-10-02 21:50:07 +0000 | |||
1968 | +++ src/SecondaryWindow.h 1970-01-01 00:00:00 +0000 | |||
1969 | @@ -1,30 +0,0 @@ | |||
1970 | 1 | /* | ||
1971 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
1972 | 3 | * | ||
1973 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1974 | 5 | * it under the terms of the GNU General Public License as published by | ||
1975 | 6 | * the Free Software Foundation; version 3. | ||
1976 | 7 | * | ||
1977 | 8 | * This program is distributed in the hope that it will be useful, | ||
1978 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1979 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1980 | 11 | * GNU General Public License for more details. | ||
1981 | 12 | * | ||
1982 | 13 | * You should have received a copy of the GNU General Public License | ||
1983 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1984 | 15 | */ | ||
1985 | 16 | |||
1986 | 17 | #ifndef UNITY_SECONDARY_WINDOW_H | ||
1987 | 18 | #define UNITY_SECONDARY_WINDOW_H | ||
1988 | 19 | |||
1989 | 20 | #include <QQuickView> | ||
1990 | 21 | |||
1991 | 22 | class SecondaryWindow : public QQuickView | ||
1992 | 23 | { | ||
1993 | 24 | Q_OBJECT | ||
1994 | 25 | |||
1995 | 26 | public: | ||
1996 | 27 | SecondaryWindow(QQmlEngine *engine); | ||
1997 | 28 | }; | ||
1998 | 29 | |||
1999 | 30 | #endif // UNITY_SECONDARY_WINDOW_H | ||
2000 | 31 | 0 | ||
2001 | === modified file 'src/ShellApplication.cpp' | |||
2002 | --- src/ShellApplication.cpp 2017-03-08 15:12:15 +0000 | |||
2003 | +++ src/ShellApplication.cpp 2017-03-31 15:02:41 +0000 | |||
2004 | @@ -20,6 +20,8 @@ | |||
2005 | 20 | #include <QLibrary> | 20 | #include <QLibrary> |
2006 | 21 | #include <QProcess> | 21 | #include <QProcess> |
2007 | 22 | #include <QScreen> | 22 | #include <QScreen> |
2008 | 23 | #include <QQmlContext> | ||
2009 | 24 | #include <QQmlComponent> | ||
2010 | 23 | 25 | ||
2011 | 24 | #include <QGSettings> | 26 | #include <QGSettings> |
2012 | 25 | 27 | ||
2013 | @@ -36,30 +38,22 @@ | |||
2014 | 36 | 38 | ||
2015 | 37 | ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer) | 39 | ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer) |
2016 | 38 | : QGuiApplication(argc, argv) | 40 | : QGuiApplication(argc, argv) |
2017 | 41 | , m_qmlArgs(this) | ||
2018 | 39 | { | 42 | { |
2019 | 40 | setApplicationName(QStringLiteral("unity8")); | 43 | setApplicationName(QStringLiteral("unity8")); |
2020 | 41 | setOrganizationName(QStringLiteral("Canonical")); | 44 | setOrganizationName(QStringLiteral("Canonical")); |
2021 | 42 | 45 | ||
2022 | 43 | connect(this, &QGuiApplication::screenAdded, this, &ShellApplication::onScreenAdded); | ||
2023 | 44 | |||
2024 | 45 | setupQmlEngine(isMirServer); | 46 | setupQmlEngine(isMirServer); |
2025 | 46 | 47 | ||
2031 | 47 | UnityCommandLineParser parser(*this); | 48 | if (m_qmlArgs.deviceName().isEmpty()) { |
2027 | 48 | |||
2028 | 49 | if (!parser.deviceName().isEmpty()) { | ||
2029 | 50 | m_deviceName = parser.deviceName(); | ||
2030 | 51 | } else { | ||
2032 | 52 | char buffer[200]; | 49 | char buffer[200]; |
2033 | 53 | property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/); | 50 | property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/); |
2035 | 54 | m_deviceName = QString(buffer); | 51 | m_qmlArgs.setDeviceName(QString(buffer)); |
2036 | 55 | } | 52 | } |
2037 | 56 | m_qmlArgs.setDeviceName(m_deviceName); | ||
2038 | 57 | |||
2039 | 58 | m_qmlArgs.setMode(parser.mode()); | ||
2040 | 59 | 53 | ||
2041 | 60 | // The testability driver is only loaded by QApplication but not by QGuiApplication. | 54 | // The testability driver is only loaded by QApplication but not by QGuiApplication. |
2042 | 61 | // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own. | 55 | // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own. |
2044 | 62 | if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) { | 56 | if (m_qmlArgs.hasTestability() || getenv("QT_LOAD_TESTABILITY")) { |
2045 | 63 | QLibrary testLib(QStringLiteral("qttestability")); | 57 | QLibrary testLib(QStringLiteral("qttestability")); |
2046 | 64 | if (testLib.load()) { | 58 | if (testLib.load()) { |
2047 | 65 | typedef void (*TasInitialize)(void); | 59 | typedef void (*TasInitialize)(void); |
2048 | @@ -80,57 +74,41 @@ | |||
2049 | 80 | QScopedPointer<QGSettings> gSettings(new QGSettings("com.canonical.Unity8")); | 74 | QScopedPointer<QGSettings> gSettings(new QGSettings("com.canonical.Unity8")); |
2050 | 81 | gSettings->reset(QStringLiteral("alwaysShowOsk")); | 75 | gSettings->reset(QStringLiteral("alwaysShowOsk")); |
2051 | 82 | 76 | ||
2063 | 83 | m_shellView = new ShellView(m_qmlEngine, &m_qmlArgs); | 77 | |
2064 | 84 | 78 | QByteArray pxpguEnv = qgetenv("GRID_UNIT_PX"); | |
2065 | 85 | if (parser.windowGeometry().isValid()) { | 79 | bool ok; |
2066 | 86 | m_shellView->setWidth(parser.windowGeometry().width()); | 80 | int pxpgu = pxpguEnv.toInt(&ok); |
2067 | 87 | m_shellView->setHeight(parser.windowGeometry().height()); | 81 | if (!ok) { |
2068 | 88 | } | 82 | pxpgu = 8; |
2069 | 89 | 83 | } | |
2070 | 90 | if (parser.hasFrameless()) { | 84 | m_qmlEngine->rootContext()->setContextProperty("internalGu", pxpgu); |
2071 | 91 | m_shellView->setFlags(Qt::FramelessWindowHint); | 85 | m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("applicationArguments"), &m_qmlArgs); |
2072 | 92 | } | 86 | m_qmlEngine->rootContext()->setContextProperty("DebuggingController", new DebuggingController(this)); |
2073 | 93 | 87 | ||
2074 | 88 | auto component(new QQmlComponent(m_qmlEngine, | ||
2075 | 89 | QUrl::fromLocalFile(::qmlDirectory() + "/ShellApplication.qml"))); | ||
2076 | 90 | component->create(); | ||
2077 | 91 | if (component->status() == QQmlComponent::Error) { | ||
2078 | 92 | m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("errorString"), component->errorString()); | ||
2079 | 93 | auto errorComponent(new QQmlComponent(m_qmlEngine, | ||
2080 | 94 | QUrl::fromLocalFile(::qmlDirectory() + "/ErrorApplication.qml"))); | ||
2081 | 95 | errorComponent->create(); | ||
2082 | 96 | qDebug() << errorComponent->errorString(); | ||
2083 | 97 | return; | ||
2084 | 98 | } | ||
2085 | 94 | 99 | ||
2086 | 95 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION | 100 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION |
2087 | 96 | // You will need this if you want to interact with touch-only components using a mouse | 101 | // You will need this if you want to interact with touch-only components using a mouse |
2088 | 97 | // Needed only when manually testing on a desktop. | 102 | // Needed only when manually testing on a desktop. |
2090 | 98 | if (parser.hasMouseToTouch()) { | 103 | if (m_qmlArgs.hasMouseToTouch()) { |
2091 | 99 | m_mouseTouchAdaptor = MouseTouchAdaptor::instance(); | 104 | m_mouseTouchAdaptor = MouseTouchAdaptor::instance(); |
2092 | 100 | } | 105 | } |
2093 | 101 | #endif | 106 | #endif |
2094 | 102 | 107 | ||
2119 | 103 | new DebuggingController(this); | 108 | if (m_qmlArgs.mode().compare("greeter") == 0) { |
2096 | 104 | |||
2097 | 105 | // Some hard-coded policy for now. | ||
2098 | 106 | // NB: We don't support more than two screens at the moment | ||
2099 | 107 | // | ||
2100 | 108 | // TODO: Support an arbitrary number of screens and different policies | ||
2101 | 109 | // (eg cloned desktop, several desktops, etc) | ||
2102 | 110 | if (isMirServer && screens().count() == 2) { | ||
2103 | 111 | m_shellView->setScreen(screens().at(1)); | ||
2104 | 112 | m_qmlArgs.setDeviceName(QStringLiteral("desktop")); | ||
2105 | 113 | |||
2106 | 114 | m_secondaryWindow = new SecondaryWindow(m_qmlEngine); | ||
2107 | 115 | m_secondaryWindow->setScreen(screens().at(0)); | ||
2108 | 116 | // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that! | ||
2109 | 117 | m_secondaryWindow->setWindowState(Qt::WindowFullScreen); | ||
2110 | 118 | m_secondaryWindow->setVisible(true); | ||
2111 | 119 | } | ||
2112 | 120 | |||
2113 | 121 | if (parser.mode().compare("greeter") == 0) { | ||
2114 | 122 | QSize primaryScreenSize = this->primaryScreen()->size(); | ||
2115 | 123 | m_shellView->setHeight(primaryScreenSize.height()); | ||
2116 | 124 | m_shellView->setWidth(primaryScreenSize.width()); | ||
2117 | 125 | m_shellView->show(); | ||
2118 | 126 | m_shellView->requestActivate(); | ||
2120 | 127 | if (!QProcess::startDetached("initctl emit --no-wait unity8-greeter-started")) { | 109 | if (!QProcess::startDetached("initctl emit --no-wait unity8-greeter-started")) { |
2121 | 128 | qDebug() << "Unable to send unity8-greeter-started event to Upstart"; | 110 | qDebug() << "Unable to send unity8-greeter-started event to Upstart"; |
2122 | 129 | } | 111 | } |
2123 | 130 | } else if (isMirServer || parser.hasFullscreen()) { | ||
2124 | 131 | m_shellView->showFullScreen(); | ||
2125 | 132 | } else { | ||
2126 | 133 | m_shellView->show(); | ||
2127 | 134 | } | 112 | } |
2128 | 135 | } | 113 | } |
2129 | 136 | 114 | ||
2130 | @@ -141,14 +119,6 @@ | |||
2131 | 141 | 119 | ||
2132 | 142 | void ShellApplication::destroyResources() | 120 | void ShellApplication::destroyResources() |
2133 | 143 | { | 121 | { |
2134 | 144 | // Deletion order is important. Don't use QScopedPointers and the like | ||
2135 | 145 | // Otherwise the process will hang on shutdown (bug somewhere I guess). | ||
2136 | 146 | delete m_shellView; | ||
2137 | 147 | m_shellView = nullptr; | ||
2138 | 148 | |||
2139 | 149 | delete m_secondaryWindow; | ||
2140 | 150 | m_secondaryWindow = nullptr; | ||
2141 | 151 | |||
2142 | 152 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION | 122 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION |
2143 | 153 | delete m_mouseTouchAdaptor; | 123 | delete m_mouseTouchAdaptor; |
2144 | 154 | m_mouseTouchAdaptor = nullptr; | 124 | m_mouseTouchAdaptor = nullptr; |
2145 | @@ -174,48 +144,3 @@ | |||
2146 | 174 | 144 | ||
2147 | 175 | QObject::connect(m_qmlEngine, &QQmlEngine::quit, this, &QGuiApplication::quit); | 145 | QObject::connect(m_qmlEngine, &QQmlEngine::quit, this, &QGuiApplication::quit); |
2148 | 176 | } | 146 | } |
2149 | 177 | |||
2150 | 178 | void ShellApplication::onScreenAdded(QScreen * /*screen*/) | ||
2151 | 179 | { | ||
2152 | 180 | // TODO: Support an arbitrary number of screens and different policies | ||
2153 | 181 | // (eg cloned desktop, several desktops, etc) | ||
2154 | 182 | if (screens().count() == 2) { | ||
2155 | 183 | m_shellView->setScreen(screens().at(1)); | ||
2156 | 184 | m_qmlArgs.setDeviceName(QStringLiteral("desktop")); | ||
2157 | 185 | // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having | ||
2158 | 186 | // its backing QPlatformWindow recreated). So lets refocus it. | ||
2159 | 187 | m_shellView->requestActivate(); | ||
2160 | 188 | // QWindow::destroy() is called when it changes between screens. We have to manually make it visible again | ||
2161 | 189 | // <dandrader> This bug is supposedly fixed in Qt 5.5.1, although I can still reproduce it there. :-/ | ||
2162 | 190 | m_shellView->setVisible(true); | ||
2163 | 191 | |||
2164 | 192 | m_secondaryWindow = new SecondaryWindow(m_qmlEngine); | ||
2165 | 193 | m_secondaryWindow->setScreen(screens().at(0)); | ||
2166 | 194 | |||
2167 | 195 | // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that! | ||
2168 | 196 | m_secondaryWindow->setWindowState(Qt::WindowFullScreen); | ||
2169 | 197 | m_secondaryWindow->setVisible(true); | ||
2170 | 198 | } | ||
2171 | 199 | } | ||
2172 | 200 | |||
2173 | 201 | void ShellApplication::onScreenAboutToBeRemoved(QScreen *screen) | ||
2174 | 202 | { | ||
2175 | 203 | // TODO: Support an arbitrary number of screens and different policies | ||
2176 | 204 | // (eg cloned desktop, several desktops, etc) | ||
2177 | 205 | if (screen == m_shellView->screen()) { | ||
2178 | 206 | const QList<QScreen *> allScreens = screens(); | ||
2179 | 207 | Q_ASSERT(allScreens.count() > 1); | ||
2180 | 208 | Q_ASSERT(allScreens.at(0) != screen); | ||
2181 | 209 | Q_ASSERT(m_secondaryWindow); | ||
2182 | 210 | delete m_secondaryWindow; | ||
2183 | 211 | m_secondaryWindow = nullptr; | ||
2184 | 212 | m_shellView->setScreen(allScreens.first()); | ||
2185 | 213 | m_qmlArgs.setDeviceName(m_deviceName); | ||
2186 | 214 | // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having | ||
2187 | 215 | // its backing QPlatformWindow recreated). So lets refocus it. | ||
2188 | 216 | m_shellView->requestActivate(); | ||
2189 | 217 | // QWindow::destroy() is called when it changes between screens. We have to manually make it visible again | ||
2190 | 218 | // <dandrader> This bug is supposedly fixed in Qt 5.5.1, although I can still reproduce it there. :-/ | ||
2191 | 219 | m_shellView->setVisible(true); | ||
2192 | 220 | } | ||
2193 | 221 | } | ||
2194 | 222 | 147 | ||
2195 | === modified file 'src/ShellApplication.h' | |||
2196 | --- src/ShellApplication.h 2015-12-16 13:58:39 +0000 | |||
2197 | +++ src/ShellApplication.h 2017-03-31 15:02:41 +0000 | |||
2198 | @@ -18,7 +18,7 @@ | |||
2199 | 18 | #define SHELLAPPLICATION_H | 18 | #define SHELLAPPLICATION_H |
2200 | 19 | 19 | ||
2201 | 20 | #include <QGuiApplication> | 20 | #include <QGuiApplication> |
2203 | 21 | #include <QQmlEngine> | 21 | #include <QQmlApplicationEngine> |
2204 | 22 | #include <QQuickView> | 22 | #include <QQuickView> |
2205 | 23 | #include <QScopedPointer> | 23 | #include <QScopedPointer> |
2206 | 24 | 24 | ||
2207 | @@ -28,9 +28,6 @@ | |||
2208 | 28 | #include "MouseTouchAdaptor.h" | 28 | #include "MouseTouchAdaptor.h" |
2209 | 29 | #endif | 29 | #endif |
2210 | 30 | 30 | ||
2211 | 31 | #include "SecondaryWindow.h" | ||
2212 | 32 | #include "ShellView.h" | ||
2213 | 33 | |||
2214 | 34 | class ShellApplication : public QGuiApplication | 31 | class ShellApplication : public QGuiApplication |
2215 | 35 | { | 32 | { |
2216 | 36 | Q_OBJECT | 33 | Q_OBJECT |
2217 | @@ -39,19 +36,10 @@ | |||
2218 | 39 | virtual ~ShellApplication(); | 36 | virtual ~ShellApplication(); |
2219 | 40 | 37 | ||
2220 | 41 | void destroyResources(); | 38 | void destroyResources(); |
2221 | 42 | public Q_SLOTS: | ||
2222 | 43 | // called by qtmir | ||
2223 | 44 | void onScreenAboutToBeRemoved(QScreen *screen); | ||
2224 | 45 | |||
2225 | 46 | private Q_SLOTS: | ||
2226 | 47 | void onScreenAdded(QScreen*); | ||
2227 | 48 | 39 | ||
2228 | 49 | private: | 40 | private: |
2229 | 50 | void setupQmlEngine(bool isMirServer); | 41 | void setupQmlEngine(bool isMirServer); |
2230 | 51 | QString m_deviceName; | ||
2231 | 52 | ApplicationArguments m_qmlArgs; | 42 | ApplicationArguments m_qmlArgs; |
2232 | 53 | ShellView *m_shellView{nullptr}; | ||
2233 | 54 | SecondaryWindow *m_secondaryWindow{nullptr}; | ||
2234 | 55 | 43 | ||
2235 | 56 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION | 44 | #ifdef UNITY8_ENABLE_TOUCH_EMULATION |
2236 | 57 | MouseTouchAdaptor *m_mouseTouchAdaptor{nullptr}; | 45 | MouseTouchAdaptor *m_mouseTouchAdaptor{nullptr}; |
2237 | 58 | 46 | ||
2238 | === removed file 'src/ShellView.cpp' | |||
2239 | --- src/ShellView.cpp 2017-02-15 14:31:20 +0000 | |||
2240 | +++ src/ShellView.cpp 1970-01-01 00:00:00 +0000 | |||
2241 | @@ -1,85 +0,0 @@ | |||
2242 | 1 | /* | ||
2243 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
2244 | 3 | * | ||
2245 | 4 | * This program is free software; you can redistribute it and/or modify | ||
2246 | 5 | * it under the terms of the GNU General Public License as published by | ||
2247 | 6 | * the Free Software Foundation; version 3. | ||
2248 | 7 | * | ||
2249 | 8 | * This program is distributed in the hope that it will be useful, | ||
2250 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2251 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2252 | 11 | * GNU General Public License for more details. | ||
2253 | 12 | * | ||
2254 | 13 | * You should have received a copy of the GNU General Public License | ||
2255 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2256 | 15 | */ | ||
2257 | 16 | |||
2258 | 17 | #include "ShellView.h" | ||
2259 | 18 | |||
2260 | 19 | // Qt | ||
2261 | 20 | #include <QQmlContext> | ||
2262 | 21 | #include <QQuickItem> | ||
2263 | 22 | #include <QtQuick/private/qquickitem_p.h> | ||
2264 | 23 | #include <QtQuick/private/qquickrectangle_p.h> | ||
2265 | 24 | #include <QtQuick/private/qquicktext_p.h> | ||
2266 | 25 | |||
2267 | 26 | // local | ||
2268 | 27 | #include <paths.h> | ||
2269 | 28 | |||
2270 | 29 | ShellView::ShellView(QQmlEngine *engine, QObject *qmlArgs) | ||
2271 | 30 | : QQuickView(engine, nullptr) | ||
2272 | 31 | { | ||
2273 | 32 | setResizeMode(QQuickView::SizeRootObjectToView); | ||
2274 | 33 | setColor("black"); | ||
2275 | 34 | setTitle(QStringLiteral("Unity8")); | ||
2276 | 35 | |||
2277 | 36 | rootContext()->setContextProperty(QStringLiteral("applicationArguments"), qmlArgs); | ||
2278 | 37 | |||
2279 | 38 | connect(this, &QQuickView::statusChanged, this, [this] { | ||
2280 | 39 | if (status() == QQuickView::Error) { | ||
2281 | 40 | QQuickRectangle *rect = new QQuickRectangle(contentItem()); | ||
2282 | 41 | rect->setColor(Qt::white); | ||
2283 | 42 | QQuickItemPrivate::get(rect)->anchors()->setFill(contentItem()); | ||
2284 | 43 | |||
2285 | 44 | QString errorsString; | ||
2286 | 45 | for(const QQmlError &e: errors()) { | ||
2287 | 46 | errorsString += e.toString() + "\n"; | ||
2288 | 47 | } | ||
2289 | 48 | QQuickText *text = new QQuickText(rect); | ||
2290 | 49 | text->setColor(Qt::black); | ||
2291 | 50 | text->setWrapMode(QQuickText::Wrap); | ||
2292 | 51 | text->setText(QString("There was an error loading Unity8:\n%1").arg(errorsString)); | ||
2293 | 52 | QQuickItemPrivate::get(text)->anchors()->setFill(rect); | ||
2294 | 53 | } | ||
2295 | 54 | } | ||
2296 | 55 | ); | ||
2297 | 56 | |||
2298 | 57 | QUrl source(::qmlDirectory() + "/OrientedShell.qml"); | ||
2299 | 58 | setSource(source); | ||
2300 | 59 | |||
2301 | 60 | connect(this, &QWindow::widthChanged, this, &ShellView::onWidthChanged); | ||
2302 | 61 | connect(this, &QWindow::heightChanged, this, &ShellView::onHeightChanged); | ||
2303 | 62 | } | ||
2304 | 63 | |||
2305 | 64 | void ShellView::onWidthChanged(int w) | ||
2306 | 65 | { | ||
2307 | 66 | // For good measure in case SizeRootObjectToView doesn't fulfill its promise. | ||
2308 | 67 | // | ||
2309 | 68 | // There's at least one situation that's know to leave the root object with an outdated size. | ||
2310 | 69 | // (really looks like Qt bug) | ||
2311 | 70 | // Happens when starting unity8 with an external monitor already connected. | ||
2312 | 71 | // The QResizeEvent we get still has the size of the first screen and since the resize move is triggered | ||
2313 | 72 | // from the resize event handler, the root item doesn't get resized. | ||
2314 | 73 | // TODO: Confirm the Qt bug and submit a patch upstream | ||
2315 | 74 | if (rootObject()) { | ||
2316 | 75 | rootObject()->setWidth(w); | ||
2317 | 76 | } | ||
2318 | 77 | } | ||
2319 | 78 | |||
2320 | 79 | void ShellView::onHeightChanged(int h) | ||
2321 | 80 | { | ||
2322 | 81 | // See comment in ShellView::onWidthChanged() | ||
2323 | 82 | if (rootObject()) { | ||
2324 | 83 | rootObject()->setHeight(h); | ||
2325 | 84 | } | ||
2326 | 85 | } | ||
2327 | 86 | 0 | ||
2328 | === removed file 'src/ShellView.h' | |||
2329 | --- src/ShellView.h 2015-10-16 16:56:14 +0000 | |||
2330 | +++ src/ShellView.h 1970-01-01 00:00:00 +0000 | |||
2331 | @@ -1,34 +0,0 @@ | |||
2332 | 1 | /* | ||
2333 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
2334 | 3 | * | ||
2335 | 4 | * This program is free software; you can redistribute it and/or modify | ||
2336 | 5 | * it under the terms of the GNU General Public License as published by | ||
2337 | 6 | * the Free Software Foundation; version 3. | ||
2338 | 7 | * | ||
2339 | 8 | * This program is distributed in the hope that it will be useful, | ||
2340 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2341 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2342 | 11 | * GNU General Public License for more details. | ||
2343 | 12 | * | ||
2344 | 13 | * You should have received a copy of the GNU General Public License | ||
2345 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2346 | 15 | */ | ||
2347 | 16 | |||
2348 | 17 | #ifndef UNITY_SHELL_VIEW_H | ||
2349 | 18 | #define UNITY_SHELL_VIEW_H | ||
2350 | 19 | |||
2351 | 20 | #include <QQuickView> | ||
2352 | 21 | |||
2353 | 22 | class ShellView : public QQuickView | ||
2354 | 23 | { | ||
2355 | 24 | Q_OBJECT | ||
2356 | 25 | |||
2357 | 26 | public: | ||
2358 | 27 | ShellView(QQmlEngine *engine, QObject *qmlArgs); | ||
2359 | 28 | |||
2360 | 29 | private Q_SLOTS: | ||
2361 | 30 | void onWidthChanged(int); | ||
2362 | 31 | void onHeightChanged(int); | ||
2363 | 32 | }; | ||
2364 | 33 | |||
2365 | 34 | #endif // UNITY_SHELL_VIEW_H | ||
2366 | 35 | 0 | ||
2367 | === modified file 'src/UnityCommandLineParser.h' | |||
2368 | --- src/UnityCommandLineParser.h 2015-12-16 13:58:39 +0000 | |||
2369 | +++ src/UnityCommandLineParser.h 2017-03-31 15:02:41 +0000 | |||
2370 | @@ -36,8 +36,8 @@ | |||
2371 | 36 | bool hasFullscreen() const { return m_hasFullscreen; } | 36 | bool hasFullscreen() const { return m_hasFullscreen; } |
2372 | 37 | QString deviceName() const { return m_deviceName; } | 37 | QString deviceName() const { return m_deviceName; } |
2373 | 38 | QString mode() const { return m_mode; } | 38 | QString mode() const { return m_mode; } |
2374 | 39 | private: | ||
2375 | 40 | 39 | ||
2376 | 40 | protected: | ||
2377 | 41 | int parsePixelsValue(const QString &str); | 41 | int parsePixelsValue(const QString &str); |
2378 | 42 | static float getenvFloat(const char* name, float defaultValue); | 42 | static float getenvFloat(const char* name, float defaultValue); |
2379 | 43 | void resolveMode(QCommandLineParser &parser, QCommandLineOption &modeOption); | 43 | void resolveMode(QCommandLineParser &parser, QCommandLineOption &modeOption); |
2380 | 44 | 44 | ||
2381 | === modified file 'tests/mocks/Cursor/Cursor.qml' | |||
2382 | --- tests/mocks/Cursor/Cursor.qml 2016-10-03 11:15:27 +0000 | |||
2383 | +++ tests/mocks/Cursor/Cursor.qml 2017-03-31 15:02:41 +0000 | |||
2384 | @@ -15,8 +15,11 @@ | |||
2385 | 15 | */ | 15 | */ |
2386 | 16 | 16 | ||
2387 | 17 | import QtQuick 2.4 | 17 | import QtQuick 2.4 |
2390 | 18 | 18 | import UInput 0.1 | |
2391 | 19 | Item { | 19 | |
2392 | 20 | Canvas { | ||
2393 | 21 | id: root | ||
2394 | 22 | |||
2395 | 20 | property int topBoundaryOffset // effectively panel height | 23 | property int topBoundaryOffset // effectively panel height |
2396 | 21 | property Item confiningItem | 24 | property Item confiningItem |
2397 | 22 | 25 | ||
2398 | @@ -30,5 +33,49 @@ | |||
2399 | 30 | signal pushStopped() | 33 | signal pushStopped() |
2400 | 31 | signal mouseMoved() | 34 | signal mouseMoved() |
2401 | 32 | 35 | ||
2403 | 33 | onMouseMoved: opacity = 1; | 36 | width: units.gu(2) |
2404 | 37 | height: units.gu(2) | ||
2405 | 38 | antialiasing: true | ||
2406 | 39 | |||
2407 | 40 | onPaint: { | ||
2408 | 41 | var ctx = getContext("2d"); | ||
2409 | 42 | ctx.save(); | ||
2410 | 43 | ctx.clearRect(0,0,width, height); | ||
2411 | 44 | ctx.strokeStyle = "#000000"; | ||
2412 | 45 | ctx.lineWidth = 1 | ||
2413 | 46 | ctx.fillStyle = "#ffffff"; | ||
2414 | 47 | ctx.globalAlpha = 1.0; | ||
2415 | 48 | ctx.lineJoin = "round"; | ||
2416 | 49 | ctx.beginPath(); | ||
2417 | 50 | |||
2418 | 51 | // put rectangle in the middle | ||
2419 | 52 | // draw the rectangle | ||
2420 | 53 | ctx.moveTo(width/2,height); | ||
2421 | 54 | ctx.lineTo(width, height/2); | ||
2422 | 55 | ctx.lineTo(0,0); | ||
2423 | 56 | |||
2424 | 57 | ctx.closePath(); | ||
2425 | 58 | ctx.fill(); | ||
2426 | 59 | ctx.stroke(); | ||
2427 | 60 | ctx.restore(); | ||
2428 | 61 | } | ||
2429 | 62 | |||
2430 | 63 | Connections { | ||
2431 | 64 | target: UInput | ||
2432 | 65 | onMouseMoved: { | ||
2433 | 66 | var newX = root.x; | ||
2434 | 67 | newX += dx; | ||
2435 | 68 | if (newX < 0) newX = 0; | ||
2436 | 69 | else if (newX >= parent.width) newX = parent.width-1; | ||
2437 | 70 | |||
2438 | 71 | var newY = root.y; | ||
2439 | 72 | newY += dy; | ||
2440 | 73 | if (newY < 0) newY = 0; | ||
2441 | 74 | else if (newY >= parent.height) newY = parent.height-1; | ||
2442 | 75 | |||
2443 | 76 | root.x = newX; | ||
2444 | 77 | root.y = newY; | ||
2445 | 78 | root.mouseMoved(); | ||
2446 | 79 | } | ||
2447 | 80 | } | ||
2448 | 34 | } | 81 | } |
2449 | 35 | 82 | ||
2450 | === modified file 'tests/mocks/GSettings.1.0/plugin.cpp' | |||
2451 | --- tests/mocks/GSettings.1.0/plugin.cpp 2015-04-15 14:09:06 +0000 | |||
2452 | +++ tests/mocks/GSettings.1.0/plugin.cpp 2017-03-31 15:02:41 +0000 | |||
2453 | @@ -18,6 +18,8 @@ | |||
2454 | 18 | #include "fake_gsettings.h" | 18 | #include "fake_gsettings.h" |
2455 | 19 | 19 | ||
2456 | 20 | #include <QtQml/qqml.h> | 20 | #include <QtQml/qqml.h> |
2457 | 21 | #include <QQmlEngine> | ||
2458 | 22 | #include <QQmlContext> | ||
2459 | 21 | 23 | ||
2460 | 22 | static QObject* controllerProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */) | 24 | static QObject* controllerProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */) |
2461 | 23 | { | 25 | { |
2462 | @@ -31,3 +33,13 @@ | |||
2463 | 31 | qmlRegisterUncreatableType<GSettingsSchemaQml>(uri, 1, 0, "GSettingsSchema", | 33 | qmlRegisterUncreatableType<GSettingsSchemaQml>(uri, 1, 0, "GSettingsSchema", |
2464 | 32 | "GSettingsSchema can only be used inside of a GSettings component"); | 34 | "GSettingsSchema can only be used inside of a GSettings component"); |
2465 | 33 | } | 35 | } |
2466 | 36 | |||
2467 | 37 | void FakeGSettingsQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri) | ||
2468 | 38 | { | ||
2469 | 39 | QQmlExtensionPlugin::initializeEngine(engine, uri); | ||
2470 | 40 | |||
2471 | 41 | QString usageType = qgetenv("UNITY_MOCK_DESKTOP"); | ||
2472 | 42 | if (!usageType.isEmpty()) { | ||
2473 | 43 | GSettingsControllerQml::instance()->setUsageMode("Windowed"); | ||
2474 | 44 | } | ||
2475 | 45 | } | ||
2476 | 34 | 46 | ||
2477 | === modified file 'tests/mocks/GSettings.1.0/plugin.h' | |||
2478 | --- tests/mocks/GSettings.1.0/plugin.h 2015-04-30 09:31:51 +0000 | |||
2479 | +++ tests/mocks/GSettings.1.0/plugin.h 2017-03-31 15:02:41 +0000 | |||
2480 | @@ -26,6 +26,7 @@ | |||
2481 | 26 | 26 | ||
2482 | 27 | public: | 27 | public: |
2483 | 28 | void registerTypes(const char *uri) override; | 28 | void registerTypes(const char *uri) override; |
2484 | 29 | void initializeEngine(QQmlEngine *engine, const char *uri) override; | ||
2485 | 29 | }; | 30 | }; |
2486 | 30 | 31 | ||
2487 | 31 | #endif // PLUGIN_H | 32 | #endif // PLUGIN_H |
2488 | 32 | 33 | ||
2489 | === modified file 'tests/mocks/UInput/plugin.cpp' | |||
2490 | --- tests/mocks/UInput/plugin.cpp 2015-11-23 16:50:26 +0000 | |||
2491 | +++ tests/mocks/UInput/plugin.cpp 2017-03-31 15:02:41 +0000 | |||
2492 | @@ -19,8 +19,13 @@ | |||
2493 | 19 | 19 | ||
2494 | 20 | #include <QtQml/qqml.h> | 20 | #include <QtQml/qqml.h> |
2495 | 21 | 21 | ||
2496 | 22 | QObject* uinputSingleton(QQmlEngine*, QJSEngine*) | ||
2497 | 23 | { | ||
2498 | 24 | return new MockUInput; | ||
2499 | 25 | } | ||
2500 | 26 | |||
2501 | 22 | void MockUInputPlugin::registerTypes(const char *uri) | 27 | void MockUInputPlugin::registerTypes(const char *uri) |
2502 | 23 | { | 28 | { |
2503 | 24 | Q_ASSERT(uri == QLatin1String("UInput")); | 29 | Q_ASSERT(uri == QLatin1String("UInput")); |
2505 | 25 | qmlRegisterType<MockUInput>(uri, 0, 1, "UInput"); | 30 | qmlRegisterSingletonType<MockUInput>(uri, 0, 1, "UInput", uinputSingleton); |
2506 | 26 | } | 31 | } |
2507 | 27 | 32 | ||
2508 | === modified file 'tests/mocks/Unity/Application/SurfaceManager.cpp' | |||
2509 | --- tests/mocks/Unity/Application/SurfaceManager.cpp 2017-02-07 16:21:09 +0000 | |||
2510 | +++ tests/mocks/Unity/Application/SurfaceManager.cpp 2017-03-31 15:02:41 +0000 | |||
2511 | @@ -21,7 +21,7 @@ | |||
2512 | 21 | 21 | ||
2513 | 22 | #include <paths.h> | 22 | #include <paths.h> |
2514 | 23 | 23 | ||
2516 | 24 | #define SURFACEMANAGER_DEBUG 0 | 24 | #define SURFACEMANAGER_DEBUG 1 |
2517 | 25 | 25 | ||
2518 | 26 | #if SURFACEMANAGER_DEBUG | 26 | #if SURFACEMANAGER_DEBUG |
2519 | 27 | #define DEBUG_MSG(params) qDebug().nospace() << "SurfaceManager[" << (void*)this << "]::" << __func__ << params | 27 | #define DEBUG_MSG(params) qDebug().nospace() << "SurfaceManager[" << (void*)this << "]::" << __func__ << params |
2520 | 28 | 28 | ||
2521 | === modified file 'tests/mocks/Unity/InputInfo/mockcontroller.cpp' | |||
2522 | --- tests/mocks/Unity/InputInfo/mockcontroller.cpp 2015-11-09 09:23:23 +0000 | |||
2523 | +++ tests/mocks/Unity/InputInfo/mockcontroller.cpp 2017-03-31 15:02:41 +0000 | |||
2524 | @@ -18,10 +18,20 @@ | |||
2525 | 18 | 18 | ||
2526 | 19 | #include "qinputdeviceinfo_mock_p.h" | 19 | #include "qinputdeviceinfo_mock_p.h" |
2527 | 20 | 20 | ||
2528 | 21 | #include <QQuickView> | ||
2529 | 22 | #include <QQmlComponent> | ||
2530 | 23 | #include <QQuickItem> | ||
2531 | 24 | #include <paths.h> | ||
2532 | 25 | |||
2533 | 21 | MockController::MockController(QObject *parent): | 26 | MockController::MockController(QObject *parent): |
2534 | 22 | QObject(parent) | 27 | QObject(parent) |
2535 | 23 | { | 28 | { |
2536 | 29 | } | ||
2537 | 24 | 30 | ||
2538 | 31 | MockController *MockController::instance() | ||
2539 | 32 | { | ||
2540 | 33 | static MockController* controller = new MockController(); | ||
2541 | 34 | return controller; | ||
2542 | 25 | } | 35 | } |
2543 | 26 | 36 | ||
2544 | 27 | QInputDevice *MockController::addMockDevice(const QString &devicePath, QInputDevice::InputType type) | 37 | QInputDevice *MockController::addMockDevice(const QString &devicePath, QInputDevice::InputType type) |
2545 | 28 | 38 | ||
2546 | === modified file 'tests/mocks/Unity/InputInfo/mockcontroller.h' | |||
2547 | --- tests/mocks/Unity/InputInfo/mockcontroller.h 2015-11-02 15:55:58 +0000 | |||
2548 | +++ tests/mocks/Unity/InputInfo/mockcontroller.h 2017-03-31 15:02:41 +0000 | |||
2549 | @@ -24,9 +24,11 @@ | |||
2550 | 24 | { | 24 | { |
2551 | 25 | Q_OBJECT | 25 | Q_OBJECT |
2552 | 26 | public: | 26 | public: |
2554 | 27 | MockController(QObject *parent = 0); | 27 | MockController(QObject *parent = nullptr); |
2555 | 28 | ~MockController() = default; | 28 | ~MockController() = default; |
2556 | 29 | 29 | ||
2557 | 30 | static MockController *instance(); | ||
2558 | 31 | |||
2559 | 30 | Q_INVOKABLE QInputDevice* addMockDevice(const QString &devicePath, QInputDevice::InputType type); | 32 | Q_INVOKABLE QInputDevice* addMockDevice(const QString &devicePath, QInputDevice::InputType type); |
2560 | 31 | Q_INVOKABLE void removeDevice(const QString &devicePath); | 33 | Q_INVOKABLE void removeDevice(const QString &devicePath); |
2561 | 32 | }; | 34 | }; |
2562 | 33 | 35 | ||
2563 | === modified file 'tests/mocks/Unity/InputInfo/plugin.cpp' | |||
2564 | --- tests/mocks/Unity/InputInfo/plugin.cpp 2015-11-02 15:55:58 +0000 | |||
2565 | +++ tests/mocks/Unity/InputInfo/plugin.cpp 2017-03-31 15:02:41 +0000 | |||
2566 | @@ -26,9 +26,8 @@ | |||
2567 | 26 | 26 | ||
2568 | 27 | static QObject *backendProvider(QQmlEngine *engine, QJSEngine *scriptEngine) | 27 | static QObject *backendProvider(QQmlEngine *engine, QJSEngine *scriptEngine) |
2569 | 28 | { | 28 | { |
2570 | 29 | Q_UNUSED(engine) | ||
2571 | 30 | Q_UNUSED(scriptEngine) | 29 | Q_UNUSED(scriptEngine) |
2573 | 31 | return new MockController(engine); | 30 | return MockController::instance(); |
2574 | 32 | } | 31 | } |
2575 | 33 | 32 | ||
2576 | 34 | void InputInfoPlugin::registerTypes(const char *uri) | 33 | void InputInfoPlugin::registerTypes(const char *uri) |
2577 | 35 | 34 | ||
2578 | === modified file 'tests/mocks/Unity/Screens/CMakeLists.txt' | |||
2579 | --- tests/mocks/Unity/Screens/CMakeLists.txt 2016-10-25 10:10:08 +0000 | |||
2580 | +++ tests/mocks/Unity/Screens/CMakeLists.txt 2017-03-31 15:02:41 +0000 | |||
2581 | @@ -5,10 +5,11 @@ | |||
2582 | 5 | set(MockScreens_SOURCES | 5 | set(MockScreens_SOURCES |
2583 | 6 | plugin.cpp | 6 | plugin.cpp |
2584 | 7 | screens.cpp | 7 | screens.cpp |
2585 | 8 | screenwindow.cpp | ||
2586 | 8 | ) | 9 | ) |
2587 | 9 | 10 | ||
2588 | 10 | add_library(MockScreensPlugin MODULE ${MockScreens_SOURCES}) | 11 | add_library(MockScreensPlugin MODULE ${MockScreens_SOURCES}) |
2589 | 11 | 12 | ||
2591 | 12 | qt5_use_modules(MockScreensPlugin Gui Qml) | 13 | qt5_use_modules(MockScreensPlugin Gui Qml Quick) |
2592 | 13 | 14 | ||
2593 | 14 | add_unity8_mock(Unity.Screens 0.1 Unity/Screens PREFIX mocks TARGETS MockScreensPlugin) | 15 | add_unity8_mock(Unity.Screens 0.1 Unity/Screens PREFIX mocks TARGETS MockScreensPlugin) |
2594 | 15 | 16 | ||
2595 | === modified file 'tests/mocks/Unity/Screens/plugin.cpp' | |||
2596 | --- tests/mocks/Unity/Screens/plugin.cpp 2015-12-02 13:23:45 +0000 | |||
2597 | +++ tests/mocks/Unity/Screens/plugin.cpp 2017-03-31 15:02:41 +0000 | |||
2598 | @@ -16,14 +16,27 @@ | |||
2599 | 16 | 16 | ||
2600 | 17 | #include "plugin.h" | 17 | #include "plugin.h" |
2601 | 18 | #include "screens.h" | 18 | #include "screens.h" |
2602 | 19 | #include "screenwindow.h" | ||
2603 | 19 | 20 | ||
2604 | 20 | #include <QScreen> | 21 | #include <QScreen> |
2605 | 21 | 22 | ||
2606 | 23 | namespace { | ||
2607 | 24 | QObject* screensSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) { | ||
2608 | 25 | Q_UNUSED(engine); | ||
2609 | 26 | Q_UNUSED(scriptEngine); | ||
2610 | 27 | return new Screens(); | ||
2611 | 28 | } | ||
2612 | 29 | } | ||
2613 | 30 | |||
2614 | 22 | void UnityScreensPlugin::registerTypes(const char* uri) | 31 | void UnityScreensPlugin::registerTypes(const char* uri) |
2615 | 23 | { | 32 | { |
2616 | 24 | Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Screens")); | 33 | Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Screens")); |
2617 | 25 | 34 | ||
2618 | 26 | qRegisterMetaType<QScreen*>("QScreen*"); | 35 | qRegisterMetaType<QScreen*>("QScreen*"); |
2619 | 36 | qRegisterMetaType<ScreenMode*>("ScreenMode*"); | ||
2620 | 37 | qmlRegisterUncreatableType<ScreenMode>(uri, 0, 1, "ScreenMode", "ScreenMode is not creatable."); | ||
2621 | 27 | 38 | ||
2623 | 28 | qmlRegisterType<Screens>(uri, 0, 1, "Screens"); | 39 | qmlRegisterSingletonType<Screens>(uri, 0, 1, "Screens", screensSingleton); |
2624 | 40 | qmlRegisterType<ScreenWindow>(uri, 0, 1, "ScreenWindow"); | ||
2625 | 41 | qmlRegisterRevision<QWindow,1>(uri, 0, 1); | ||
2626 | 29 | } | 42 | } |
2627 | 30 | 43 | ||
2628 | === modified file 'tests/mocks/Unity/Screens/screens.cpp' | |||
2629 | --- tests/mocks/Unity/Screens/screens.cpp 2016-12-23 11:04:53 +0000 | |||
2630 | +++ tests/mocks/Unity/Screens/screens.cpp 2017-03-31 15:02:41 +0000 | |||
2631 | @@ -18,16 +18,30 @@ | |||
2632 | 18 | 18 | ||
2633 | 19 | // Qt | 19 | // Qt |
2634 | 20 | #include <QGuiApplication> | 20 | #include <QGuiApplication> |
2635 | 21 | #include <QScreen> | ||
2636 | 22 | #include <QDebug> | 21 | #include <QDebug> |
2637 | 23 | 22 | ||
2638 | 24 | Q_DECLARE_METATYPE(QScreen*) | ||
2639 | 25 | |||
2640 | 26 | Screens::Screens(QObject *parent) : | 23 | Screens::Screens(QObject *parent) : |
2641 | 27 | QAbstractListModel(parent) | 24 | QAbstractListModel(parent) |
2642 | 28 | { | 25 | { |
2645 | 29 | // start with one screen attached | 26 | bool ok = false; |
2646 | 30 | m_screenList.append(new Screen()); | 27 | int screenCount = qEnvironmentVariableIntValue("UNITY_MOCK_SCREEN_COUNT", &ok); |
2647 | 28 | if (!ok) screenCount = 1; | ||
2648 | 29 | QPoint lastPoint(0,0); | ||
2649 | 30 | for (int i = 0; i < screenCount; ++i) { | ||
2650 | 31 | auto screen = new Screen(); | ||
2651 | 32 | screen->m_active = i == 0; | ||
2652 | 33 | screen->m_name = QString("Monitor %1").arg(i); | ||
2653 | 34 | screen->m_position = QPoint(lastPoint.x(), lastPoint.y()); | ||
2654 | 35 | screen->m_sizes.append(new ScreenMode(50, QSize(640,480))); | ||
2655 | 36 | screen->m_sizes.append(new ScreenMode(60, QSize(1280,1024))); | ||
2656 | 37 | screen->m_sizes.append(new ScreenMode(60, QSize(1440,900))); | ||
2657 | 38 | screen->m_sizes.append(new ScreenMode(60, QSize(1920,1080))); | ||
2658 | 39 | screen->m_currentModeIndex = 3; | ||
2659 | 40 | screen->m_physicalSize = QSize(300,200); | ||
2660 | 41 | m_screenList.append(screen); | ||
2661 | 42 | |||
2662 | 43 | lastPoint.rx() += screen->m_sizes[screen->m_currentModeIndex]->size.width(); | ||
2663 | 44 | } | ||
2664 | 31 | } | 45 | } |
2665 | 32 | 46 | ||
2666 | 33 | Screens::~Screens() noexcept | 47 | Screens::~Screens() noexcept |
2667 | @@ -40,7 +54,6 @@ | |||
2668 | 40 | { | 54 | { |
2669 | 41 | QHash<int, QByteArray> roles; | 55 | QHash<int, QByteArray> roles; |
2670 | 42 | roles[ScreenRole] = "screen"; | 56 | roles[ScreenRole] = "screen"; |
2671 | 43 | roles[OutputTypeRole] = "outputType"; | ||
2672 | 44 | return roles; | 57 | return roles; |
2673 | 45 | } | 58 | } |
2674 | 46 | 59 | ||
2675 | @@ -52,9 +65,7 @@ | |||
2676 | 52 | 65 | ||
2677 | 53 | switch(role) { | 66 | switch(role) { |
2678 | 54 | case ScreenRole: | 67 | case ScreenRole: |
2682 | 55 | return QVariant::fromValue(m_screenList.at(index.row())->qScreen); | 68 | return QVariant::fromValue(m_screenList.at(index.row())); |
2680 | 56 | case OutputTypeRole: | ||
2681 | 57 | return m_screenList.at(index.row())->outputTypes; | ||
2683 | 58 | } | 69 | } |
2684 | 59 | 70 | ||
2685 | 60 | return QVariant(); | 71 | return QVariant(); |
2686 | @@ -69,3 +80,35 @@ | |||
2687 | 69 | { | 80 | { |
2688 | 70 | return m_screenList.size(); | 81 | return m_screenList.size(); |
2689 | 71 | } | 82 | } |
2690 | 83 | |||
2691 | 84 | void Screens::activateScreen(int) | ||
2692 | 85 | { | ||
2693 | 86 | qWarning("Not Implemented"); | ||
2694 | 87 | } | ||
2695 | 88 | |||
2696 | 89 | Screen::Screen(QObject* parent) | ||
2697 | 90 | : QObject(parent) | ||
2698 | 91 | { | ||
2699 | 92 | } | ||
2700 | 93 | |||
2701 | 94 | Screen::~Screen() | ||
2702 | 95 | { | ||
2703 | 96 | qDeleteAll(m_sizes); | ||
2704 | 97 | m_sizes.clear(); | ||
2705 | 98 | } | ||
2706 | 99 | |||
2707 | 100 | QQmlListProperty<ScreenMode> Screen::availableModes() | ||
2708 | 101 | { | ||
2709 | 102 | return QQmlListProperty<ScreenMode>(this, m_sizes); | ||
2710 | 103 | } | ||
2711 | 104 | |||
2712 | 105 | Screen *Screen::beginConfiguration() | ||
2713 | 106 | { | ||
2714 | 107 | qWarning("Not Implemented"); | ||
2715 | 108 | return nullptr; | ||
2716 | 109 | } | ||
2717 | 110 | |||
2718 | 111 | void Screen::applyConfiguration() | ||
2719 | 112 | { | ||
2720 | 113 | qWarning("Not Implemented"); | ||
2721 | 114 | } | ||
2722 | 72 | 115 | ||
2723 | === modified file 'tests/mocks/Unity/Screens/screens.h' | |||
2724 | --- tests/mocks/Unity/Screens/screens.h 2016-12-23 11:04:53 +0000 | |||
2725 | +++ tests/mocks/Unity/Screens/screens.h 2017-03-31 15:02:41 +0000 | |||
2726 | @@ -19,6 +19,7 @@ | |||
2727 | 19 | 19 | ||
2728 | 20 | #include <QAbstractListModel> | 20 | #include <QAbstractListModel> |
2729 | 21 | #include <QScreen> | 21 | #include <QScreen> |
2730 | 22 | #include <QQmlListProperty> | ||
2731 | 22 | 23 | ||
2732 | 23 | class Screen; | 24 | class Screen; |
2733 | 24 | 25 | ||
2734 | @@ -31,7 +32,13 @@ | |||
2735 | 31 | public: | 32 | public: |
2736 | 32 | enum ItemRoles { | 33 | enum ItemRoles { |
2737 | 33 | ScreenRole = Qt::UserRole + 1, | 34 | ScreenRole = Qt::UserRole + 1, |
2739 | 34 | OutputTypeRole | 35 | OutputTypeRole, |
2740 | 36 | EnabledRole, | ||
2741 | 37 | NameRole, | ||
2742 | 38 | ScaleRole, | ||
2743 | 39 | FormFactorRole, | ||
2744 | 40 | GeometryRole, | ||
2745 | 41 | SizesRole | ||
2746 | 35 | }; | 42 | }; |
2747 | 36 | 43 | ||
2748 | 37 | enum OutputTypes { | 44 | enum OutputTypes { |
2749 | @@ -53,6 +60,15 @@ | |||
2750 | 53 | }; | 60 | }; |
2751 | 54 | Q_ENUM(OutputTypes) | 61 | Q_ENUM(OutputTypes) |
2752 | 55 | 62 | ||
2753 | 63 | enum FormFactor { | ||
2754 | 64 | FormFactorUnknown, | ||
2755 | 65 | FormFactorPhone, | ||
2756 | 66 | FormFactorTablet, | ||
2757 | 67 | FormFactorMonitor, | ||
2758 | 68 | FormFactorTV, | ||
2759 | 69 | FormFactorProjector, | ||
2760 | 70 | }; | ||
2761 | 71 | |||
2762 | 56 | explicit Screens(QObject *parent = 0); | 72 | explicit Screens(QObject *parent = 0); |
2763 | 57 | virtual ~Screens() noexcept; | 73 | virtual ~Screens() noexcept; |
2764 | 58 | 74 | ||
2765 | @@ -63,6 +79,9 @@ | |||
2766 | 63 | 79 | ||
2767 | 64 | int count() const; | 80 | int count() const; |
2768 | 65 | 81 | ||
2769 | 82 | public Q_SLOTS: | ||
2770 | 83 | void activateScreen(int index); | ||
2771 | 84 | |||
2772 | 66 | Q_SIGNALS: | 85 | Q_SIGNALS: |
2773 | 67 | void countChanged(); | 86 | void countChanged(); |
2774 | 68 | void screenAdded(QScreen *screen); | 87 | void screenAdded(QScreen *screen); |
2775 | @@ -72,11 +91,72 @@ | |||
2776 | 72 | QList<Screen *> m_screenList; | 91 | QList<Screen *> m_screenList; |
2777 | 73 | }; | 92 | }; |
2778 | 74 | 93 | ||
2785 | 75 | class Screen | 94 | class ScreenMode : public QObject |
2786 | 76 | { | 95 | { |
2787 | 77 | public: | 96 | Q_OBJECT |
2788 | 78 | Screens::OutputTypes outputTypes = Screens::Unknown; | 97 | Q_PROPERTY(qreal refreshRate MEMBER refreshRate CONSTANT) |
2789 | 79 | QScreen *qScreen = nullptr; | 98 | Q_PROPERTY(QSize size MEMBER size CONSTANT) |
2790 | 80 | }; | 99 | public: |
2791 | 100 | ScreenMode() {} | ||
2792 | 101 | ScreenMode(qreal refreshRate, QSize size):refreshRate(refreshRate),size(size) {} | ||
2793 | 102 | ScreenMode(const ScreenMode& other) | ||
2794 | 103 | : QObject(nullptr), | ||
2795 | 104 | refreshRate{other.refreshRate},size{other.size} | ||
2796 | 105 | {} | ||
2797 | 106 | |||
2798 | 107 | qreal refreshRate; | ||
2799 | 108 | QSize size; | ||
2800 | 109 | }; | ||
2801 | 110 | |||
2802 | 111 | class Screen : public QObject | ||
2803 | 112 | { | ||
2804 | 113 | Q_OBJECT | ||
2805 | 114 | |||
2806 | 115 | Q_PROPERTY(bool active MEMBER m_active NOTIFY activeChanged) | ||
2807 | 116 | |||
2808 | 117 | Q_PROPERTY(bool used MEMBER m_used NOTIFY usedChanged) | ||
2809 | 118 | Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged) | ||
2810 | 119 | Q_PROPERTY(Screens::OutputTypes outputType MEMBER m_outputType NOTIFY outputTypeChanged) | ||
2811 | 120 | Q_PROPERTY(float scale MEMBER m_scale NOTIFY scaleChanged) | ||
2812 | 121 | Q_PROPERTY(Screens::FormFactor formFactor MEMBER m_formFactor NOTIFY formFactorChanged) | ||
2813 | 122 | Q_PROPERTY(QPoint position MEMBER m_position NOTIFY positionChanged) | ||
2814 | 123 | Q_PROPERTY(uint currentModeIndex MEMBER m_currentModeIndex NOTIFY currentModeIndexChanged) | ||
2815 | 124 | Q_PROPERTY(QQmlListProperty<ScreenMode> availableModes READ availableModes NOTIFY availableModesChanged) | ||
2816 | 125 | Q_PROPERTY(QSizeF physicalSize MEMBER m_physicalSize NOTIFY physicalSizeChanged) | ||
2817 | 126 | public: | ||
2818 | 127 | Screen(QObject* parent = 0); | ||
2819 | 128 | ~Screen(); | ||
2820 | 129 | |||
2821 | 130 | QQmlListProperty<ScreenMode> availableModes(); | ||
2822 | 131 | |||
2823 | 132 | Q_INVOKABLE Screen* beginConfiguration(); | ||
2824 | 133 | Q_INVOKABLE void applyConfiguration(); | ||
2825 | 134 | |||
2826 | 135 | Q_SIGNALS: | ||
2827 | 136 | void activeChanged(); | ||
2828 | 137 | void usedChanged(); | ||
2829 | 138 | void nameChanged(); | ||
2830 | 139 | void outputTypeChanged(); | ||
2831 | 140 | void scaleChanged(); | ||
2832 | 141 | void formFactorChanged(); | ||
2833 | 142 | void positionChanged(); | ||
2834 | 143 | void currentModeIndexChanged(); | ||
2835 | 144 | void availableModesChanged(); | ||
2836 | 145 | void physicalSizeChanged(); | ||
2837 | 146 | |||
2838 | 147 | public: | ||
2839 | 148 | bool m_active{false}; | ||
2840 | 149 | bool m_used{true}; | ||
2841 | 150 | QString m_name; | ||
2842 | 151 | Screens::OutputTypes m_outputType{Screens::Unknown}; | ||
2843 | 152 | float m_scale{1.0}; | ||
2844 | 153 | Screens::FormFactor m_formFactor{Screens::FormFactorMonitor}; | ||
2845 | 154 | QPoint m_position; | ||
2846 | 155 | uint m_currentModeIndex{0}; | ||
2847 | 156 | QList<ScreenMode*> m_sizes; | ||
2848 | 157 | QSizeF m_physicalSize; | ||
2849 | 158 | }; | ||
2850 | 159 | |||
2851 | 160 | Q_DECLARE_METATYPE(ScreenMode) | ||
2852 | 81 | 161 | ||
2853 | 82 | #endif // SCREENS_H | 162 | #endif // SCREENS_H |
2854 | 83 | 163 | ||
2855 | === added file 'tests/mocks/Unity/Screens/screenwindow.cpp' | |||
2856 | --- tests/mocks/Unity/Screens/screenwindow.cpp 1970-01-01 00:00:00 +0000 | |||
2857 | +++ tests/mocks/Unity/Screens/screenwindow.cpp 2017-03-31 15:02:41 +0000 | |||
2858 | @@ -0,0 +1,35 @@ | |||
2859 | 1 | /* | ||
2860 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2861 | 3 | * | ||
2862 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
2863 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
2864 | 6 | * the Free Software Foundation. | ||
2865 | 7 | * | ||
2866 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
2867 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
2868 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
2869 | 11 | * Lesser General Public License for more details. | ||
2870 | 12 | * | ||
2871 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
2872 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2873 | 15 | */ | ||
2874 | 16 | |||
2875 | 17 | #include "screenwindow.h" | ||
2876 | 18 | |||
2877 | 19 | ScreenWindow::ScreenWindow(QWindow *parent) | ||
2878 | 20 | : QQuickWindow(parent) | ||
2879 | 21 | { | ||
2880 | 22 | } | ||
2881 | 23 | |||
2882 | 24 | Screen *ScreenWindow::screenWrapper() const | ||
2883 | 25 | { | ||
2884 | 26 | return m_screen.data(); | ||
2885 | 27 | } | ||
2886 | 28 | |||
2887 | 29 | void ScreenWindow::setScreenWrapper(Screen *screen) | ||
2888 | 30 | { | ||
2889 | 31 | if (m_screen != screen) { | ||
2890 | 32 | m_screen = screen; | ||
2891 | 33 | Q_EMIT screenWrapperChanged(); | ||
2892 | 34 | } | ||
2893 | 35 | } | ||
2894 | 0 | 36 | ||
2895 | === added file 'tests/mocks/Unity/Screens/screenwindow.h' | |||
2896 | --- tests/mocks/Unity/Screens/screenwindow.h 1970-01-01 00:00:00 +0000 | |||
2897 | +++ tests/mocks/Unity/Screens/screenwindow.h 2017-03-31 15:02:41 +0000 | |||
2898 | @@ -0,0 +1,42 @@ | |||
2899 | 1 | /* | ||
2900 | 2 | * Copyright (C) 2016 Canonical, Ltd. | ||
2901 | 3 | * | ||
2902 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
2903 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
2904 | 6 | * the Free Software Foundation. | ||
2905 | 7 | * | ||
2906 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
2907 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
2908 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
2909 | 11 | * Lesser General Public License for more details. | ||
2910 | 12 | * | ||
2911 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
2912 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2913 | 15 | */ | ||
2914 | 16 | |||
2915 | 17 | #ifndef SCREENWINDOW_H | ||
2916 | 18 | #define SCREENWINDOW_H | ||
2917 | 19 | |||
2918 | 20 | #include <QQuickWindow> | ||
2919 | 21 | #include <QPointer> | ||
2920 | 22 | |||
2921 | 23 | #include "screens.h" | ||
2922 | 24 | |||
2923 | 25 | class ScreenWindow : public QQuickWindow | ||
2924 | 26 | { | ||
2925 | 27 | Q_OBJECT | ||
2926 | 28 | Q_PROPERTY(Screen *screen READ screenWrapper WRITE setScreenWrapper NOTIFY screenWrapperChanged) | ||
2927 | 29 | public: | ||
2928 | 30 | ScreenWindow(QWindow *parent = 0); | ||
2929 | 31 | |||
2930 | 32 | Screen *screenWrapper() const; | ||
2931 | 33 | void setScreenWrapper(Screen *screen); | ||
2932 | 34 | |||
2933 | 35 | Q_SIGNALS: | ||
2934 | 36 | void screenWrapperChanged(); | ||
2935 | 37 | |||
2936 | 38 | private: | ||
2937 | 39 | QPointer<Screen> m_screen; | ||
2938 | 40 | }; | ||
2939 | 41 | |||
2940 | 42 | #endif // SCREENWINDOW_H | ||
2941 | 0 | 43 | ||
2942 | === modified file 'tests/plugins/GlobalShortcut/GlobalShortcutTest.cpp' | |||
2943 | --- tests/plugins/GlobalShortcut/GlobalShortcutTest.cpp 2016-04-22 20:19:57 +0000 | |||
2944 | +++ tests/plugins/GlobalShortcut/GlobalShortcutTest.cpp 2017-03-31 15:02:41 +0000 | |||
2945 | @@ -38,6 +38,7 @@ | |||
2946 | 38 | m_inactiveShortcut = dynamic_cast<GlobalShortcut*>(m_view->rootObject()->property("inactiveShortcut").value<QObject*>()); | 38 | m_inactiveShortcut = dynamic_cast<GlobalShortcut*>(m_view->rootObject()->property("inactiveShortcut").value<QObject*>()); |
2947 | 39 | QVERIFY(m_inactiveShortcut); | 39 | QVERIFY(m_inactiveShortcut); |
2948 | 40 | m_view->show(); | 40 | m_view->show(); |
2949 | 41 | m_view->requestActivate(); | ||
2950 | 41 | QTest::qWaitForWindowExposed(m_view); | 42 | QTest::qWaitForWindowExposed(m_view); |
2951 | 42 | } | 43 | } |
2952 | 43 | 44 | ||
2953 | 44 | 45 | ||
2954 | === modified file 'tests/qmltests/ApplicationMenus/tst_MenuBar.qml' | |||
2955 | --- tests/qmltests/ApplicationMenus/tst_MenuBar.qml 2017-03-28 21:47:53 +0000 | |||
2956 | +++ tests/qmltests/ApplicationMenus/tst_MenuBar.qml 2017-03-31 15:02:41 +0000 | |||
2957 | @@ -24,6 +24,7 @@ | |||
2958 | 24 | import Utils 0.1 | 24 | import Utils 0.1 |
2959 | 25 | 25 | ||
2960 | 26 | import "../../../qml/ApplicationMenus" | 26 | import "../../../qml/ApplicationMenus" |
2961 | 27 | import "../../../qml/Components/PanelState" | ||
2962 | 27 | import ".." | 28 | import ".." |
2963 | 28 | 29 | ||
2964 | 29 | Item { | 30 | Item { |
2965 | @@ -67,6 +68,7 @@ | |||
2966 | 67 | id: menuBackend | 68 | id: menuBackend |
2967 | 68 | modelData: appMenuData.generateTestData(10,5,2,3) | 69 | modelData: appMenuData.generateTestData(10,5,2,3) |
2968 | 69 | } | 70 | } |
2969 | 71 | panelState: PanelState {} | ||
2970 | 70 | } | 72 | } |
2971 | 71 | } | 73 | } |
2972 | 72 | 74 | ||
2973 | 73 | 75 | ||
2974 | === modified file 'tests/qmltests/ApplicationMenus/tst_MenuPopup.qml' | |||
2975 | --- tests/qmltests/ApplicationMenus/tst_MenuPopup.qml 2017-03-21 10:56:10 +0000 | |||
2976 | +++ tests/qmltests/ApplicationMenus/tst_MenuPopup.qml 2017-03-31 15:02:41 +0000 | |||
2977 | @@ -24,6 +24,7 @@ | |||
2978 | 24 | import Utils 0.1 | 24 | import Utils 0.1 |
2979 | 25 | 25 | ||
2980 | 26 | import "../../../qml/ApplicationMenus" | 26 | import "../../../qml/ApplicationMenus" |
2981 | 27 | import "../../../qml/Components/PanelState" | ||
2982 | 27 | import ".." | 28 | import ".." |
2983 | 28 | 29 | ||
2984 | 29 | Item { | 30 | Item { |
2985 | @@ -59,6 +60,7 @@ | |||
2986 | 59 | }} | 60 | }} |
2987 | 60 | ] | 61 | ] |
2988 | 61 | } | 62 | } |
2989 | 63 | panelState: PanelState {} | ||
2990 | 62 | } | 64 | } |
2991 | 63 | } | 65 | } |
2992 | 64 | 66 | ||
2993 | 65 | 67 | ||
2994 | === modified file 'tests/qmltests/Components/tst_VirtualTouchPad.qml' | |||
2995 | --- tests/qmltests/Components/tst_VirtualTouchPad.qml 2016-12-05 11:17:15 +0000 | |||
2996 | +++ tests/qmltests/Components/tst_VirtualTouchPad.qml 2017-03-31 15:02:41 +0000 | |||
2997 | @@ -39,11 +39,11 @@ | |||
2998 | 39 | 39 | ||
2999 | 40 | SignalSpy { | 40 | SignalSpy { |
3000 | 41 | id: mouseEventSpy1 | 41 | id: mouseEventSpy1 |
3002 | 42 | target: touchScreenPad.uinput | 42 | target: UInput |
3003 | 43 | } | 43 | } |
3004 | 44 | SignalSpy { | 44 | SignalSpy { |
3005 | 45 | id: mouseEventSpy2 | 45 | id: mouseEventSpy2 |
3007 | 46 | target: touchScreenPad.uinput | 46 | target: UInput |
3008 | 47 | } | 47 | } |
3009 | 48 | 48 | ||
3010 | 49 | UnityTestCase { | 49 | UnityTestCase { |
3011 | 50 | 50 | ||
3012 | === modified file 'tests/qmltests/Panel/tst_Panel.qml' | |||
3013 | --- tests/qmltests/Panel/tst_Panel.qml 2017-03-17 13:44:30 +0000 | |||
3014 | +++ tests/qmltests/Panel/tst_Panel.qml 2017-03-31 15:02:41 +0000 | |||
3015 | @@ -42,6 +42,8 @@ | |||
3016 | 42 | value: keyboardAttached.checked | 42 | value: keyboardAttached.checked |
3017 | 43 | } | 43 | } |
3018 | 44 | 44 | ||
3019 | 45 | readonly property alias panelState: panel.panelState | ||
3020 | 46 | |||
3021 | 45 | SurfaceManager { id: sMgr } | 47 | SurfaceManager { id: sMgr } |
3022 | 46 | ApplicationMenuDataLoader { | 48 | ApplicationMenuDataLoader { |
3023 | 47 | id: appMenuData | 49 | id: appMenuData |
3024 | @@ -99,6 +101,8 @@ | |||
3025 | 99 | model: root.indicatorsModel | 101 | model: root.indicatorsModel |
3026 | 100 | hides: [ panel.applicationMenus ] | 102 | hides: [ panel.applicationMenus ] |
3027 | 101 | } | 103 | } |
3028 | 104 | |||
3029 | 105 | panelState: PanelState {} | ||
3030 | 102 | } | 106 | } |
3031 | 103 | } | 107 | } |
3032 | 104 | } | 108 | } |
3033 | @@ -153,7 +157,7 @@ | |||
3034 | 153 | Layout.fillWidth: true | 157 | Layout.fillWidth: true |
3035 | 154 | CheckBox { | 158 | CheckBox { |
3036 | 155 | id: windowControlsCB | 159 | id: windowControlsCB |
3038 | 156 | onClicked: PanelState.decorationsVisible = checked | 160 | onClicked: panelState.decorationsVisible = checked |
3039 | 157 | } | 161 | } |
3040 | 158 | Label { | 162 | Label { |
3041 | 159 | text: "Show window decorations" | 163 | text: "Show window decorations" |
3042 | @@ -164,7 +168,7 @@ | |||
3043 | 164 | RowLayout { | 168 | RowLayout { |
3044 | 165 | Layout.fillWidth: true | 169 | Layout.fillWidth: true |
3045 | 166 | CheckBox { | 170 | CheckBox { |
3047 | 167 | onClicked: PanelState.title = checked ? "Fake window title" : "" | 171 | onClicked: panelState.title = checked ? "Fake window title" : "" |
3048 | 168 | } | 172 | } |
3049 | 169 | Label { | 173 | Label { |
3050 | 170 | text: "Show fake window title" | 174 | text: "Show fake window title" |
3051 | @@ -250,7 +254,7 @@ | |||
3052 | 250 | 254 | ||
3053 | 251 | SignalSpy { | 255 | SignalSpy { |
3054 | 252 | id: windowControlButtonsSpy | 256 | id: windowControlButtonsSpy |
3056 | 253 | target: PanelState | 257 | target: panelState |
3057 | 254 | signalName: "closeClicked" | 258 | signalName: "closeClicked" |
3058 | 255 | } | 259 | } |
3059 | 256 | 260 | ||
3060 | @@ -260,8 +264,8 @@ | |||
3061 | 260 | panel.fullscreenMode = false; | 264 | panel.fullscreenMode = false; |
3062 | 261 | callManager.foregroundCall = null; | 265 | callManager.foregroundCall = null; |
3063 | 262 | 266 | ||
3066 | 263 | PanelState.title = ""; | 267 | panelState.title = ""; |
3067 | 264 | PanelState.decorationsVisible = false; | 268 | panelState.decorationsVisible = false; |
3068 | 265 | 269 | ||
3069 | 266 | // Wait for the indicators to get into position. | 270 | // Wait for the indicators to get into position. |
3070 | 267 | // (switches between normal and fullscreen modes are animated) | 271 | // (switches between normal and fullscreen modes are animated) |
3071 | @@ -456,7 +460,7 @@ | |||
3072 | 456 | } | 460 | } |
3073 | 457 | 461 | ||
3074 | 458 | function test_hint(data) { | 462 | function test_hint(data) { |
3076 | 459 | PanelState.title = "Fake Title" | 463 | panelState.title = "Fake Title" |
3077 | 460 | panel.fullscreenMode = data.fullscreen; | 464 | panel.fullscreenMode = data.fullscreen; |
3078 | 461 | callManager.foregroundCall = data.call; | 465 | callManager.foregroundCall = data.call; |
3079 | 462 | 466 | ||
3080 | @@ -498,7 +502,7 @@ | |||
3081 | 498 | // menus, first by running the hint animation, then after dragging down will | 502 | // menus, first by running the hint animation, then after dragging down will |
3082 | 499 | // expose more of the panel. Releasing the touch will complete the show. | 503 | // expose more of the panel. Releasing the touch will complete the show. |
3083 | 500 | function test_drag_applicationMenu_down_shows_menu(data) { | 504 | function test_drag_applicationMenu_down_shows_menu(data) { |
3085 | 501 | PanelState.title = "Fake Title"; | 505 | panelState.title = "Fake Title"; |
3086 | 502 | panel.fullscreenMode = data.fullscreen; | 506 | panel.fullscreenMode = data.fullscreen; |
3087 | 503 | callManager.foregroundCall = data.call; | 507 | callManager.foregroundCall = data.call; |
3088 | 504 | 508 | ||
3089 | @@ -589,7 +593,7 @@ | |||
3090 | 589 | } | 593 | } |
3091 | 590 | 594 | ||
3092 | 591 | function test_darkenedAreaEatsAllApplicationMenuEvents() { | 595 | function test_darkenedAreaEatsAllApplicationMenuEvents() { |
3094 | 592 | PanelState.title = "Fake Title" | 596 | panelState.title = "Fake Title" |
3095 | 593 | 597 | ||
3096 | 594 | // The center of the area not covered by the indicators menu | 598 | // The center of the area not covered by the indicators menu |
3097 | 595 | // Ie, the visible darkened area behind the menu | 599 | // Ie, the visible darkened area behind the menu |
3098 | @@ -710,7 +714,7 @@ | |||
3099 | 710 | var windowControlArea = findChild(panel, "windowControlArea"); | 714 | var windowControlArea = findChild(panel, "windowControlArea"); |
3100 | 711 | verify(windowControlArea, "Window control area should have been created in windowed mode") | 715 | verify(windowControlArea, "Window control area should have been created in windowed mode") |
3101 | 712 | 716 | ||
3103 | 713 | PanelState.decorationsVisible = true; | 717 | panelState.decorationsVisible = true; |
3104 | 714 | // click in very topleft corner and verify the close button got clicked too | 718 | // click in very topleft corner and verify the close button got clicked too |
3105 | 715 | mouseMove(panel, 0, 0); | 719 | mouseMove(panel, 0, 0); |
3106 | 716 | mouseClick(panel, 0, 0, undefined /*button*/, undefined /*modifiers*/, 100 /*short delay*/); | 720 | mouseClick(panel, 0, 0, undefined /*button*/, undefined /*modifiers*/, 100 /*short delay*/); |
3107 | @@ -773,7 +777,7 @@ | |||
3108 | 773 | } | 777 | } |
3109 | 774 | 778 | ||
3110 | 775 | function test_stagedApplicationMenuBarShowOnMouseHover() { | 779 | function test_stagedApplicationMenuBarShowOnMouseHover() { |
3112 | 776 | PanelState.title = "Fake Title"; | 780 | panelState.title = "Fake Title"; |
3113 | 777 | panel.mode = "staged"; | 781 | panel.mode = "staged"; |
3114 | 778 | mouseEmulation.checked = false; | 782 | mouseEmulation.checked = false; |
3115 | 779 | 783 | ||
3116 | @@ -791,7 +795,7 @@ | |||
3117 | 791 | } | 795 | } |
3118 | 792 | 796 | ||
3119 | 793 | function test_windowedApplicationMenuShowOnMouseHoverWhenDecorationsShown() { | 797 | function test_windowedApplicationMenuShowOnMouseHoverWhenDecorationsShown() { |
3121 | 794 | PanelState.title = "Fake Title"; | 798 | panelState.title = "Fake Title"; |
3122 | 795 | panel.mode = "windowed"; | 799 | panel.mode = "windowed"; |
3123 | 796 | mouseEmulation.checked = false; | 800 | mouseEmulation.checked = false; |
3124 | 797 | 801 | ||
3125 | @@ -807,7 +811,7 @@ | |||
3126 | 807 | tryCompare(appTitle, "visible", true, undefined, "App title should still be visible on mouse hover when panel decorations are not visible"); | 811 | tryCompare(appTitle, "visible", true, undefined, "App title should still be visible on mouse hover when panel decorations are not visible"); |
3127 | 808 | tryCompare(appMenuBar, "visible", false, undefined, "App menu bar should be visible on mouse hover when panel decorations are not visible"); | 812 | tryCompare(appMenuBar, "visible", false, undefined, "App menu bar should be visible on mouse hover when panel decorations are not visible"); |
3128 | 809 | 813 | ||
3130 | 810 | PanelState.decorationsVisible = true; | 814 | panelState.decorationsVisible = true; |
3131 | 811 | 815 | ||
3132 | 812 | tryCompare(appTitle, "visible", false, undefined, "App title should still be visible on mouse hover when panel decorations are visible"); | 816 | tryCompare(appTitle, "visible", false, undefined, "App title should still be visible on mouse hover when panel decorations are visible"); |
3133 | 813 | tryCompare(appMenuBar, "visible", true, undefined, "App menu bar should be visible on mouse hover when panel decorations not visible"); | 817 | tryCompare(appMenuBar, "visible", true, undefined, "App menu bar should be visible on mouse hover when panel decorations not visible"); |
3134 | @@ -855,7 +859,7 @@ | |||
3135 | 855 | 859 | ||
3136 | 856 | var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar"); | 860 | var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar"); |
3137 | 857 | 861 | ||
3139 | 858 | PanelState.title = "Fake Title" | 862 | panelState.title = "Fake Title" |
3140 | 859 | pullDownApplicationsMenu(0 /*xPos*/); | 863 | pullDownApplicationsMenu(0 /*xPos*/); |
3141 | 860 | compare(aboutToShowCalledSpy.count, 1); | 864 | compare(aboutToShowCalledSpy.count, 1); |
3142 | 861 | 865 | ||
3143 | @@ -888,7 +892,7 @@ | |||
3144 | 888 | 892 | ||
3145 | 889 | var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar"); | 893 | var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar"); |
3146 | 890 | 894 | ||
3148 | 891 | PanelState.title = "Fake Title" | 895 | panelState.title = "Fake Title" |
3149 | 892 | pullDownApplicationsMenu(0 /*xPos*/); | 896 | pullDownApplicationsMenu(0 /*xPos*/); |
3150 | 893 | 897 | ||
3151 | 894 | tryCompare(indicatorsBar, "currentItemIndex", 0); | 898 | tryCompare(indicatorsBar, "currentItemIndex", 0); |
3152 | 895 | 899 | ||
3153 | === modified file 'tests/qmltests/Stage/tst_DecoratedWindow.qml' | |||
3154 | --- tests/qmltests/Stage/tst_DecoratedWindow.qml 2017-01-03 12:45:42 +0000 | |||
3155 | +++ tests/qmltests/Stage/tst_DecoratedWindow.qml 2017-03-31 15:02:41 +0000 | |||
3156 | @@ -52,6 +52,10 @@ | |||
3157 | 52 | surfaceManager: sMgr | 52 | surfaceManager: sMgr |
3158 | 53 | } | 53 | } |
3159 | 54 | 54 | ||
3160 | 55 | PanelState { | ||
3161 | 56 | id: panelState | ||
3162 | 57 | } | ||
3163 | 58 | |||
3164 | 55 | Item { | 59 | Item { |
3165 | 56 | id: fakeShell | 60 | id: fakeShell |
3166 | 57 | 61 | ||
3167 | @@ -99,7 +103,7 @@ | |||
3168 | 99 | surface: fakeApplication && fakeApplication.surfaceList.count > 0 ? fakeApplication.surfaceList.get(0) : null | 103 | surface: fakeApplication && fakeApplication.surfaceList.count > 0 ? fakeApplication.surfaceList.get(0) : null |
3169 | 100 | 104 | ||
3170 | 101 | Binding { | 105 | Binding { |
3172 | 102 | target: PanelState | 106 | target: panelState |
3173 | 103 | property: "focusedPersistentSurfaceId" | 107 | property: "focusedPersistentSurfaceId" |
3174 | 104 | value: decoratedWindow.surface ? decoratedWindow.surface.persistentId : "x" | 108 | value: decoratedWindow.surface ? decoratedWindow.surface.persistentId : "x" |
3175 | 105 | } | 109 | } |
3176 | 106 | 110 | ||
3177 | === modified file 'tests/qmltests/Stage/tst_DesktopStage.qml' | |||
3178 | --- tests/qmltests/Stage/tst_DesktopStage.qml 2017-03-24 14:04:50 +0000 | |||
3179 | +++ tests/qmltests/Stage/tst_DesktopStage.qml 2017-03-31 15:02:41 +0000 | |||
3180 | @@ -103,11 +103,12 @@ | |||
3181 | 103 | availableDesktopArea: availableDesktopAreaItem | 103 | availableDesktopArea: availableDesktopAreaItem |
3182 | 104 | interactive: true | 104 | interactive: true |
3183 | 105 | mode: "windowed" | 105 | mode: "windowed" |
3184 | 106 | panelState: PanelState {} | ||
3185 | 106 | 107 | ||
3186 | 107 | Item { | 108 | Item { |
3187 | 108 | id: availableDesktopAreaItem | 109 | id: availableDesktopAreaItem |
3188 | 109 | anchors.fill: parent | 110 | anchors.fill: parent |
3190 | 110 | anchors.topMargin: PanelState.panelHeight | 111 | anchors.topMargin: parent.panelState.panelHeight |
3191 | 111 | } | 112 | } |
3192 | 112 | } | 113 | } |
3193 | 113 | } | 114 | } |
3194 | @@ -180,6 +181,7 @@ | |||
3195 | 180 | 181 | ||
3196 | 181 | stage: stageLoader.status === Loader.Ready ? stageLoader.item : null | 182 | stage: stageLoader.status === Loader.Ready ? stageLoader.item : null |
3197 | 182 | topLevelSurfaceList: topSurfaceList | 183 | topLevelSurfaceList: topSurfaceList |
3198 | 184 | property var panelState: stage ? stage.panelState : null | ||
3199 | 183 | 185 | ||
3200 | 184 | function init() { | 186 | function init() { |
3201 | 185 | // wait until unity8-dash is up and running. | 187 | // wait until unity8-dash is up and running. |
3202 | @@ -638,19 +640,19 @@ | |||
3203 | 638 | maximizeDelegate(facebookAppDelegate); | 640 | maximizeDelegate(facebookAppDelegate); |
3204 | 639 | 641 | ||
3205 | 640 | // verify the drop shadow is still not visible | 642 | // verify the drop shadow is still not visible |
3207 | 641 | verify(PanelState.dropShadow == false); | 643 | verify(panelState.dropShadow == false); |
3208 | 642 | 644 | ||
3209 | 643 | // start a foreground app, not maximized | 645 | // start a foreground app, not maximized |
3210 | 644 | var dialerAppDelegate = startApplication("dialer-app"); | 646 | var dialerAppDelegate = startApplication("dialer-app"); |
3211 | 645 | 647 | ||
3212 | 646 | // verify the drop shadow becomes visible | 648 | // verify the drop shadow becomes visible |
3214 | 647 | tryCompareFunction(function() { return PanelState.dropShadow; }, true); | 649 | tryCompareFunction(function() { return panelState.dropShadow; }, true); |
3215 | 648 | 650 | ||
3216 | 649 | // close the maximized app | 651 | // close the maximized app |
3217 | 650 | ApplicationManager.stopApplication("facebook-webapp"); | 652 | ApplicationManager.stopApplication("facebook-webapp"); |
3218 | 651 | 653 | ||
3219 | 652 | // verify the drop shadow is gone | 654 | // verify the drop shadow is gone |
3221 | 653 | tryCompare(PanelState, "dropShadow", false); | 655 | tryCompare(panelState, "dropShadow", false); |
3222 | 654 | } | 656 | } |
3223 | 655 | 657 | ||
3224 | 656 | function test_threeFingerTapShowsWindowControls_data() { | 658 | function test_threeFingerTapShowsWindowControls_data() { |
3225 | 657 | 659 | ||
3226 | === modified file 'tests/qmltests/Stage/tst_PhoneStage.qml' | |||
3227 | --- tests/qmltests/Stage/tst_PhoneStage.qml 2017-03-24 14:04:50 +0000 | |||
3228 | +++ tests/qmltests/Stage/tst_PhoneStage.qml 2017-03-31 15:02:41 +0000 | |||
3229 | @@ -19,6 +19,7 @@ | |||
3230 | 19 | import Unity.Test 0.1 as UT | 19 | import Unity.Test 0.1 as UT |
3231 | 20 | import ".." | 20 | import ".." |
3232 | 21 | import "../../../qml/Components" | 21 | import "../../../qml/Components" |
3233 | 22 | import "../../../qml/Components/PanelState" | ||
3234 | 22 | import "../../../qml/Stage" | 23 | import "../../../qml/Stage" |
3235 | 23 | import Ubuntu.Components 1.3 | 24 | import Ubuntu.Components 1.3 |
3236 | 24 | import Unity.Application 0.1 | 25 | import Unity.Application 0.1 |
3237 | @@ -60,6 +61,7 @@ | |||
3238 | 60 | Component.onCompleted: { | 61 | Component.onCompleted: { |
3239 | 61 | ApplicationManager.startApplication("unity8-dash"); | 62 | ApplicationManager.startApplication("unity8-dash"); |
3240 | 62 | } | 63 | } |
3241 | 64 | panelState: PanelState {} | ||
3242 | 63 | } | 65 | } |
3243 | 64 | 66 | ||
3244 | 65 | Flickable { | 67 | Flickable { |
3245 | 66 | 68 | ||
3246 | === modified file 'tests/qmltests/Stage/tst_WindowResizeArea.qml' | |||
3247 | --- tests/qmltests/Stage/tst_WindowResizeArea.qml 2017-01-26 11:10:01 +0000 | |||
3248 | +++ tests/qmltests/Stage/tst_WindowResizeArea.qml 2017-03-31 15:02:41 +0000 | |||
3249 | @@ -19,7 +19,6 @@ | |||
3250 | 19 | import QtTest 1.0 | 19 | import QtTest 1.0 |
3251 | 20 | import Unity.Test 0.1 | 20 | import Unity.Test 0.1 |
3252 | 21 | import ".." | 21 | import ".." |
3253 | 22 | import "../../../qml/Components/PanelState" | ||
3254 | 23 | import "../../../qml/Stage" | 22 | import "../../../qml/Stage" |
3255 | 24 | import Ubuntu.Components 1.3 | 23 | import Ubuntu.Components 1.3 |
3256 | 25 | import Ubuntu.Components.ListItems 1.3 as ListItem | 24 | import Ubuntu.Components.ListItems 1.3 as ListItem |
3257 | @@ -31,12 +30,6 @@ | |||
3258 | 31 | height: units.gu(60) | 30 | height: units.gu(60) |
3259 | 32 | width: units.gu(85) | 31 | width: units.gu(85) |
3260 | 33 | 32 | ||
3261 | 34 | Binding { | ||
3262 | 35 | target: PanelState | ||
3263 | 36 | property: "panelHeight" | ||
3264 | 37 | value: units.gu(3) | ||
3265 | 38 | } | ||
3266 | 39 | |||
3267 | 40 | Component { | 33 | Component { |
3268 | 41 | id: fakeWindowComponent | 34 | id: fakeWindowComponent |
3269 | 42 | 35 | ||
3270 | @@ -362,7 +355,7 @@ | |||
3271 | 362 | 355 | ||
3272 | 363 | // Make sure it's again where we left it in normal state before destroying | 356 | // Make sure it's again where we left it in normal state before destroying |
3273 | 364 | compare(fakeWindow.requestedX >= 0, true) | 357 | compare(fakeWindow.requestedX >= 0, true) |
3275 | 365 | compare(fakeWindow.requestedY >= PanelState.panelHeight, true) | 358 | compare(fakeWindow.requestedY >= 0, true) |
3276 | 366 | compare(fakeWindow.requestedX + fakeWindow.width <= root.width, true) | 359 | compare(fakeWindow.requestedX + fakeWindow.width <= root.width, true) |
3277 | 367 | compare(fakeWindow.requestedY + fakeWindow.height <= root.height, true) | 360 | compare(fakeWindow.requestedY + fakeWindow.height <= root.height, true) |
3278 | 368 | 361 | ||
3279 | 369 | 362 | ||
3280 | === modified file 'tests/qmltests/Tutorial/tst_Tutorial.qml' | |||
3281 | --- tests/qmltests/Tutorial/tst_Tutorial.qml 2017-02-21 13:39:30 +0000 | |||
3282 | +++ tests/qmltests/Tutorial/tst_Tutorial.qml 2017-03-31 15:02:41 +0000 | |||
3283 | @@ -37,20 +37,10 @@ | |||
3284 | 37 | height: units.gu(71) | 37 | height: units.gu(71) |
3285 | 38 | 38 | ||
3286 | 39 | QtObject { | 39 | QtObject { |
3300 | 40 | id: applicationArguments | 40 | id: _screenWindow |
3301 | 41 | 41 | property bool primary: true | |
3289 | 42 | function hasGeometry() { | ||
3290 | 43 | return false; | ||
3291 | 44 | } | ||
3292 | 45 | |||
3293 | 46 | function width() { | ||
3294 | 47 | return 0; | ||
3295 | 48 | } | ||
3296 | 49 | |||
3297 | 50 | function height() { | ||
3298 | 51 | return 0; | ||
3299 | 52 | } | ||
3302 | 53 | } | 42 | } |
3303 | 43 | property alias screenWindow: _screenWindow | ||
3304 | 54 | 44 | ||
3305 | 55 | Telephony.CallEntry { | 45 | Telephony.CallEntry { |
3306 | 56 | id: phoneCall | 46 | id: phoneCall |
3307 | @@ -154,6 +144,10 @@ | |||
3308 | 154 | Component.onDestruction: { | 144 | Component.onDestruction: { |
3309 | 155 | shellLoader.itemDestroyed = true; | 145 | shellLoader.itemDestroyed = true; |
3310 | 156 | } | 146 | } |
3311 | 147 | SurfaceManager { | ||
3312 | 148 | id: surfaceMan | ||
3313 | 149 | } | ||
3314 | 150 | surfaceManager: surfaceMan | ||
3315 | 157 | } | 151 | } |
3316 | 158 | } | 152 | } |
3317 | 159 | } | 153 | } |
3318 | @@ -238,7 +232,7 @@ | |||
3319 | 238 | } | 232 | } |
3320 | 239 | 233 | ||
3321 | 240 | ItemSelector { | 234 | ItemSelector { |
3323 | 241 | id: modeSelector | 235 | id: modeSelector |
3324 | 242 | anchors { left: parent.left; right: parent.right } | 236 | anchors { left: parent.left; right: parent.right } |
3325 | 243 | activeFocusOnPress: false | 237 | activeFocusOnPress: false |
3326 | 244 | text: "Mode" | 238 | text: "Mode" |
3327 | @@ -327,9 +321,7 @@ | |||
3328 | 327 | } | 321 | } |
3329 | 328 | 322 | ||
3330 | 329 | function ensureInputMethodSurface() { | 323 | function ensureInputMethodSurface() { |
3334 | 330 | var surfaceManager = findInvisibleChild(shell, "surfaceManager"); | 324 | shell.surfaceManager.createInputMethodSurface(); |
3332 | 331 | verify(surfaceManager); | ||
3333 | 332 | surfaceManager.createInputMethodSurface(); | ||
3335 | 333 | 325 | ||
3336 | 334 | tryCompareFunction(function() { return topLevelSurfaceList.inputMethodSurface !== null }, true); | 326 | tryCompareFunction(function() { return topLevelSurfaceList.inputMethodSurface !== null }, true); |
3337 | 335 | } | 327 | } |
3338 | 336 | 328 | ||
3339 | === modified file 'tests/qmltests/tst_OrientedShell.qml' | |||
3340 | --- tests/qmltests/tst_OrientedShell.qml 2017-03-08 09:50:45 +0000 | |||
3341 | +++ tests/qmltests/tst_OrientedShell.qml 2017-03-31 15:02:41 +0000 | |||
3342 | @@ -30,7 +30,6 @@ | |||
3343 | 30 | 30 | ||
3344 | 31 | import "../../qml" | 31 | import "../../qml" |
3345 | 32 | import "../../qml/Components" | 32 | import "../../qml/Components" |
3346 | 33 | import "../../qml/Components/PanelState" | ||
3347 | 34 | import "Stage" | 33 | import "Stage" |
3348 | 35 | 34 | ||
3349 | 36 | Rectangle { | 35 | Rectangle { |
3350 | @@ -82,6 +81,12 @@ | |||
3351 | 82 | deviceFilter: InputInfo.Keyboard | 81 | deviceFilter: InputInfo.Keyboard |
3352 | 83 | } | 82 | } |
3353 | 84 | 83 | ||
3354 | 84 | QtObject { | ||
3355 | 85 | id: _screenWindow | ||
3356 | 86 | property bool primary: true | ||
3357 | 87 | } | ||
3358 | 88 | property alias screenWindow: _screenWindow | ||
3359 | 89 | |||
3360 | 85 | property int physicalOrientation0 | 90 | property int physicalOrientation0 |
3361 | 86 | property int physicalOrientation90 | 91 | property int physicalOrientation90 |
3362 | 87 | property int physicalOrientation180 | 92 | property int physicalOrientation180 |
3363 | @@ -174,6 +179,11 @@ | |||
3364 | 174 | Component.onDestruction: { | 179 | Component.onDestruction: { |
3365 | 175 | orientedShellLoader.itemDestroyed = true; | 180 | orientedShellLoader.itemDestroyed = true; |
3366 | 176 | } | 181 | } |
3367 | 182 | |||
3368 | 183 | SurfaceManager { | ||
3369 | 184 | id: surfaceMan | ||
3370 | 185 | } | ||
3371 | 186 | surfaceManager: surfaceMan | ||
3372 | 177 | } | 187 | } |
3373 | 178 | } | 188 | } |
3374 | 179 | } | 189 | } |
3375 | @@ -446,6 +456,15 @@ | |||
3376 | 446 | property Item orientedShell: orientedShellLoader.status === Loader.Ready ? orientedShellLoader.item : null | 456 | property Item orientedShell: orientedShellLoader.status === Loader.Ready ? orientedShellLoader.item : null |
3377 | 447 | property Item shell | 457 | property Item shell |
3378 | 448 | property QtObject topLevelSurfaceList | 458 | property QtObject topLevelSurfaceList |
3379 | 459 | property var panelState: undefined | ||
3380 | 460 | |||
3381 | 461 | onOrientedShellChanged: { | ||
3382 | 462 | if (orientedShell) { | ||
3383 | 463 | panelState = findInvisibleChild(orientedShell, "panelState"); | ||
3384 | 464 | } else { | ||
3385 | 465 | panelState = undefined; | ||
3386 | 466 | } | ||
3387 | 467 | } | ||
3388 | 449 | 468 | ||
3389 | 450 | SignalSpy { id: signalSpy } | 469 | SignalSpy { id: signalSpy } |
3390 | 451 | SignalSpy { id: signalSpy2 } | 470 | SignalSpy { id: signalSpy2 } |
3391 | @@ -1463,6 +1482,7 @@ | |||
3392 | 1463 | removeTimeConstraintsFromSwipeAreas(orientedShellLoader.item); | 1482 | removeTimeConstraintsFromSwipeAreas(orientedShellLoader.item); |
3393 | 1464 | 1483 | ||
3394 | 1465 | shell = findChild(orientedShell, "shell"); | 1484 | shell = findChild(orientedShell, "shell"); |
3395 | 1485 | verify(shell); | ||
3396 | 1466 | 1486 | ||
3397 | 1467 | topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList"); | 1487 | topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList"); |
3398 | 1468 | verify(topLevelSurfaceList); | 1488 | verify(topLevelSurfaceList); |
3399 | @@ -1512,13 +1532,13 @@ | |||
3400 | 1512 | print("exptectedAngle", expectedAngle, point.x, point.y) | 1532 | print("exptectedAngle", expectedAngle, point.x, point.y) |
3401 | 1513 | switch (expectedAngle) { | 1533 | switch (expectedAngle) { |
3402 | 1514 | case 0: | 1534 | case 0: |
3404 | 1515 | return point.x === 0 && point.y === PanelState.panelHeight; | 1535 | return point.x === 0 && point.y === panelState.panelHeight; |
3405 | 1516 | case 90: | 1536 | case 90: |
3407 | 1517 | return point.x === orientedShell.width - PanelState.panelHeight && point.y === 0; | 1537 | return point.x === orientedShell.width - panelState.panelHeight && point.y === 0; |
3408 | 1518 | case 180: | 1538 | case 180: |
3410 | 1519 | return point.x === orientedShell.width && point.y === orientedShell.height - PanelState.panelHeight; | 1539 | return point.x === orientedShell.width && point.y === orientedShell.height - panelState.panelHeight; |
3411 | 1520 | default: // 270 | 1540 | default: // 270 |
3413 | 1521 | return point.x === PanelState.panelHeight && point.y === orientedShell.height; | 1541 | return point.x === panelState.panelHeight && point.y === orientedShell.height; |
3414 | 1522 | } | 1542 | } |
3415 | 1523 | } | 1543 | } |
3416 | 1524 | 1544 | ||
3417 | 1525 | 1545 | ||
3418 | === modified file 'tests/qmltests/tst_Shell.qml' | |||
3419 | --- tests/qmltests/tst_Shell.qml 2017-03-24 11:08:11 +0000 | |||
3420 | +++ tests/qmltests/tst_Shell.qml 2017-03-31 15:02:41 +0000 | |||
3421 | @@ -38,7 +38,6 @@ | |||
3422 | 38 | 38 | ||
3423 | 39 | import "../../qml" | 39 | import "../../qml" |
3424 | 40 | import "../../qml/Components" | 40 | import "../../qml/Components" |
3425 | 41 | import "../../qml/Components/PanelState" | ||
3426 | 42 | import "Stage" | 41 | import "Stage" |
3427 | 43 | 42 | ||
3428 | 44 | Rectangle { | 43 | Rectangle { |
3429 | @@ -61,14 +60,23 @@ | |||
3430 | 61 | onShellChanged: { | 60 | onShellChanged: { |
3431 | 62 | if (shell) { | 61 | if (shell) { |
3432 | 63 | topLevelSurfaceList = testCase.findInvisibleChild(shell, "topLevelSurfaceList"); | 62 | topLevelSurfaceList = testCase.findInvisibleChild(shell, "topLevelSurfaceList"); |
3434 | 64 | appMenuData.surfaceManager = testCase.findInvisibleChild(shell, "surfaceManager"); | 63 | appMenuData.surfaceManager = shell.surfaceManager; |
3435 | 64 | panelState = testCase.findInvisibleChild(shell, "panelState"); | ||
3436 | 65 | } else { | 65 | } else { |
3437 | 66 | topLevelSurfaceList = null; | 66 | topLevelSurfaceList = null; |
3438 | 67 | appMenuData.surfaceManager = null; | 67 | appMenuData.surfaceManager = null; |
3439 | 68 | panelState = null; | ||
3440 | 68 | } | 69 | } |
3441 | 69 | } | 70 | } |
3442 | 70 | 71 | ||
3443 | 71 | property var topLevelSurfaceList: null | 72 | property var topLevelSurfaceList: null |
3444 | 73 | property var panelState: null | ||
3445 | 74 | |||
3446 | 75 | QtObject { | ||
3447 | 76 | id: _screenWindow | ||
3448 | 77 | property bool primary: true | ||
3449 | 78 | } | ||
3450 | 79 | property alias screenWindow: _screenWindow | ||
3451 | 72 | 80 | ||
3452 | 73 | Item { | 81 | Item { |
3453 | 74 | id: shellContainer | 82 | id: shellContainer |
3454 | @@ -144,6 +152,11 @@ | |||
3455 | 144 | Component.onDestruction: { | 152 | Component.onDestruction: { |
3456 | 145 | shellLoader.itemDestroyed = true; | 153 | shellLoader.itemDestroyed = true; |
3457 | 146 | } | 154 | } |
3458 | 155 | |||
3459 | 156 | SurfaceManager { | ||
3460 | 157 | id: surfaceMan | ||
3461 | 158 | } | ||
3462 | 159 | surfaceManager: surfaceMan | ||
3463 | 147 | } | 160 | } |
3464 | 148 | } | 161 | } |
3465 | 149 | } | 162 | } |
3466 | @@ -678,7 +691,7 @@ | |||
3467 | 678 | } | 691 | } |
3468 | 679 | 692 | ||
3469 | 680 | function ensureInputMethodSurface() { | 693 | function ensureInputMethodSurface() { |
3471 | 681 | var surfaceManager = findInvisibleChild(shell, "surfaceManager"); | 694 | var surfaceManager = shell.surfaceManager; |
3472 | 682 | verify(surfaceManager); | 695 | verify(surfaceManager); |
3473 | 683 | surfaceManager.createInputMethodSurface(); | 696 | surfaceManager.createInputMethodSurface(); |
3474 | 684 | 697 | ||
3475 | @@ -1885,21 +1898,21 @@ | |||
3476 | 1885 | var maximizeButton = findChild(appDelegate, "maximizeWindowButton"); | 1898 | var maximizeButton = findChild(appDelegate, "maximizeWindowButton"); |
3477 | 1886 | 1899 | ||
3478 | 1887 | tryCompare(appDelegate, "state", "normal"); | 1900 | tryCompare(appDelegate, "state", "normal"); |
3480 | 1888 | tryCompare(PanelState, "decorationsVisible", false) | 1901 | tryCompare(panelState, "decorationsVisible", false) |
3481 | 1889 | 1902 | ||
3482 | 1890 | mouseClick(maximizeButton, maximizeButton.width / 2, maximizeButton.height / 2); | 1903 | mouseClick(maximizeButton, maximizeButton.width / 2, maximizeButton.height / 2); |
3483 | 1891 | tryCompare(appDelegate, "state", "maximized"); | 1904 | tryCompare(appDelegate, "state", "maximized"); |
3485 | 1892 | tryCompare(PanelState, "decorationsVisible", true) | 1905 | tryCompare(panelState, "decorationsVisible", true) |
3486 | 1893 | 1906 | ||
3487 | 1894 | ApplicationManager.stopApplication(application.appId); | 1907 | ApplicationManager.stopApplication(application.appId); |
3489 | 1895 | tryCompare(PanelState, "decorationsVisible", false) | 1908 | tryCompare(panelState, "decorationsVisible", false) |
3490 | 1896 | 1909 | ||
3491 | 1897 | // wait until all zombie surfaces are gone. As MirSurfaceItems hold references over them. | 1910 | // wait until all zombie surfaces are gone. As MirSurfaceItems hold references over them. |
3492 | 1898 | // They won't be gone until those surface items are destroyed. | 1911 | // They won't be gone until those surface items are destroyed. |
3493 | 1899 | tryCompareFunction(function() { return application.surfaceList.count }, 0); | 1912 | tryCompareFunction(function() { return application.surfaceList.count }, 0); |
3494 | 1900 | 1913 | ||
3495 | 1901 | ApplicationManager.startApplication(application.appId); | 1914 | ApplicationManager.startApplication(application.appId); |
3497 | 1902 | tryCompare(PanelState, "decorationsVisible", true) | 1915 | tryCompare(panelState, "decorationsVisible", true) |
3498 | 1903 | } | 1916 | } |
3499 | 1904 | 1917 | ||
3500 | 1905 | function test_newAppHasValidGeometry() { | 1918 | function test_newAppHasValidGeometry() { |
3501 | @@ -1956,7 +1969,7 @@ | |||
3502 | 1956 | mousePress(appDelegate, appDelegate.width / 2, units.gu(1)) | 1969 | mousePress(appDelegate, appDelegate.width / 2, units.gu(1)) |
3503 | 1957 | mouseMove(appDelegate, appDelegate.width / 2, -units.gu(100)) | 1970 | mouseMove(appDelegate, appDelegate.width / 2, -units.gu(100)) |
3504 | 1958 | 1971 | ||
3506 | 1959 | compare(appDelegate.y >= PanelState.panelHeight, true); | 1972 | compare(appDelegate.y >= panelState.panelHeight, true); |
3507 | 1960 | } | 1973 | } |
3508 | 1961 | 1974 | ||
3509 | 1962 | function test_cantResizeWindowUnderPanel() { | 1975 | function test_cantResizeWindowUnderPanel() { |
3510 | @@ -1984,7 +1997,7 @@ | |||
3511 | 1984 | mouseMove(decoration, decoration.width/2, -units.gu(100)); | 1997 | mouseMove(decoration, decoration.width/2, -units.gu(100)); |
3512 | 1985 | 1998 | ||
3513 | 1986 | // verify we don't go past the panel | 1999 | // verify we don't go past the panel |
3515 | 1987 | compare(appDelegate.y >= PanelState.panelHeight, true); | 2000 | compare(appDelegate.y >= panelState.panelHeight, true); |
3516 | 1988 | } | 2001 | } |
3517 | 1989 | 2002 | ||
3518 | 1990 | function test_restoreWindowStateFixesIfUnderPanel() { | 2003 | function test_restoreWindowStateFixesIfUnderPanel() { |
3519 | @@ -2008,7 +2021,7 @@ | |||
3520 | 2008 | tryCompareFunction(function () { return topLevelSurfaceList.applicationAt(0).appId; }, application.appId); | 2021 | tryCompareFunction(function () { return topLevelSurfaceList.applicationAt(0).appId; }, application.appId); |
3521 | 2009 | 2022 | ||
3522 | 2010 | appDelegate = appRepeater.itemAt(0); | 2023 | appDelegate = appRepeater.itemAt(0); |
3524 | 2011 | compare(appDelegate.y >= PanelState.panelHeight, true); | 2024 | compare(appDelegate.y >= panelState.panelHeight, true); |
3525 | 2012 | } | 2025 | } |
3526 | 2013 | 2026 | ||
3527 | 2014 | function test_lifecyclePolicyForNonTouchApp_data() { | 2027 | function test_lifecyclePolicyForNonTouchApp_data() { |
3528 | @@ -2671,9 +2684,9 @@ | |||
3529 | 2671 | 2684 | ||
3530 | 2672 | function test_oskDisplacesWindow_data() { | 2685 | function test_oskDisplacesWindow_data() { |
3531 | 2673 | return [ | 2686 | return [ |
3535 | 2674 | {tag: "no need to displace", windowHeight: units.gu(10), windowY: units.gu(5), targetDisplacement: units.gu(5), oskEnabled: true}, | 2687 | {tag: "no need to displace", windowHeight: units.gu(10), windowY: units.gu(5), targetDisplacement: function() { return units.gu(5); }, oskEnabled: true}, |
3536 | 2675 | {tag: "displace to top", windowHeight: units.gu(50), windowY: units.gu(10), targetDisplacement: PanelState.panelHeight, oskEnabled: true}, | 2688 | {tag: "displace to top", windowHeight: units.gu(50), windowY: units.gu(10), targetDisplacement: function() { return panelState.panelHeight; }, oskEnabled: true}, |
3537 | 2676 | {tag: "osk not on this screen", windowHeight: units.gu(40), windowY: units.gu(10), targetDisplacement: units.gu(10), oskEnabled: false}, | 2689 | {tag: "osk not on this screen", windowHeight: units.gu(40), windowY: units.gu(10), targetDisplacement: function() { return units.gu(10); }, oskEnabled: false}, |
3538 | 2677 | ] | 2690 | ] |
3539 | 2678 | } | 2691 | } |
3540 | 2679 | 2692 | ||
3541 | @@ -2695,11 +2708,11 @@ | |||
3542 | 2695 | dashAppDelegate.windowedY = data.windowY; | 2708 | dashAppDelegate.windowedY = data.windowY; |
3543 | 2696 | topLevelSurfaceList.inputMethodSurface.setInputBounds(Qt.rect(0, 0, 0, 0)); | 2709 | topLevelSurfaceList.inputMethodSurface.setInputBounds(Qt.rect(0, 0, 0, 0)); |
3544 | 2697 | var initialY = dashAppDelegate.y; | 2710 | var initialY = dashAppDelegate.y; |
3547 | 2698 | print("intial", initialY, "panel", PanelState.panelHeight); | 2711 | print("intial", initialY, "panel", panelState.panelHeight); |
3548 | 2699 | verify(initialY > PanelState.panelHeight); | 2712 | verify(initialY > panelState.panelHeight); |
3549 | 2700 | 2713 | ||
3550 | 2701 | topLevelSurfaceList.inputMethodSurface.setInputBounds(Qt.rect(0, root.height / 2, root.width, root.height / 2)); | 2714 | topLevelSurfaceList.inputMethodSurface.setInputBounds(Qt.rect(0, root.height / 2, root.width, root.height / 2)); |
3552 | 2702 | tryCompare(dashAppDelegate, "y", data.targetDisplacement); | 2715 | tryCompare(dashAppDelegate, "y", data.targetDisplacement()); |
3553 | 2703 | 2716 | ||
3554 | 2704 | topLevelSurfaceList.inputMethodSurface.setInputBounds(Qt.rect(0, 0, 0, 0)); | 2717 | topLevelSurfaceList.inputMethodSurface.setInputBounds(Qt.rect(0, 0, 0, 0)); |
3555 | 2705 | tryCompare(dashAppDelegate, "y", initialY); | 2718 | tryCompare(dashAppDelegate, "y", initialY); |
3556 | @@ -3132,7 +3145,7 @@ | |||
3557 | 3132 | // double click the panel | 3145 | // double click the panel |
3558 | 3133 | var panel = findChild(shell, "panel"); | 3146 | var panel = findChild(shell, "panel"); |
3559 | 3134 | verify(panel); | 3147 | verify(panel); |
3561 | 3135 | mouseDoubleClickSequence(panel, panel.width/2, PanelState.panelHeight/2, Qt.LeftButton, Qt.NoModifier, 300); | 3148 | mouseDoubleClickSequence(panel, panel.width/2, panelState.panelHeight/2, Qt.LeftButton, Qt.NoModifier, 300); |
3562 | 3136 | tryCompare(appDelegate, "state", "restored"); | 3149 | tryCompare(appDelegate, "state", "restored"); |
3563 | 3137 | } | 3150 | } |
3564 | 3138 | 3151 | ||
3565 | 3139 | 3152 | ||
3566 | === modified file 'tests/qmltests/tst_ShellWithPin.qml' | |||
3567 | --- tests/qmltests/tst_ShellWithPin.qml 2017-03-22 20:14:44 +0000 | |||
3568 | +++ tests/qmltests/tst_ShellWithPin.qml 2017-03-31 15:02:41 +0000 | |||
3569 | @@ -40,20 +40,10 @@ | |||
3570 | 40 | } | 40 | } |
3571 | 41 | 41 | ||
3572 | 42 | QtObject { | 42 | QtObject { |
3586 | 43 | id: applicationArguments | 43 | id: _screenWindow |
3587 | 44 | 44 | property bool primary: true | |
3575 | 45 | function hasGeometry() { | ||
3576 | 46 | return false; | ||
3577 | 47 | } | ||
3578 | 48 | |||
3579 | 49 | function width() { | ||
3580 | 50 | return 0; | ||
3581 | 51 | } | ||
3582 | 52 | |||
3583 | 53 | function height() { | ||
3584 | 54 | return 0; | ||
3585 | 55 | } | ||
3588 | 56 | } | 45 | } |
3589 | 46 | property alias screenWindow: _screenWindow | ||
3590 | 57 | 47 | ||
3591 | 58 | Row { | 48 | Row { |
3592 | 59 | id: contentRow | 49 | id: contentRow |
3593 | @@ -72,6 +62,10 @@ | |||
3594 | 72 | Component.onDestruction: { | 62 | Component.onDestruction: { |
3595 | 73 | shellLoader.itemDestroyed = true | 63 | shellLoader.itemDestroyed = true |
3596 | 74 | } | 64 | } |
3597 | 65 | SurfaceManager { | ||
3598 | 66 | id: surfaceMan | ||
3599 | 67 | } | ||
3600 | 68 | surfaceManager: surfaceMan | ||
3601 | 75 | } | 69 | } |
3602 | 76 | } | 70 | } |
3603 | 77 | } | 71 | } |
3604 | 78 | 72 | ||
3605 | === modified file 'tests/uqmlscene/main.cpp' | |||
3606 | --- tests/uqmlscene/main.cpp 2017-01-10 14:46:09 +0000 | |||
3607 | +++ tests/uqmlscene/main.cpp 2017-03-31 15:02:41 +0000 | |||
3608 | @@ -479,6 +479,8 @@ | |||
3609 | 479 | // TODO: as soon as the engine construction completes, the debug service is | 479 | // TODO: as soon as the engine construction completes, the debug service is |
3610 | 480 | // listening for connections. But actually we aren't ready to debug anything. | 480 | // listening for connections. But actually we aren't ready to debug anything. |
3611 | 481 | QQmlEngine engine; | 481 | QQmlEngine engine; |
3612 | 482 | engine.rootContext()->setContextProperty("DebuggingController", new DebuggingController(&app)); | ||
3613 | 483 | |||
3614 | 482 | QQmlComponent *component = new QQmlComponent(&engine); | 484 | QQmlComponent *component = new QQmlComponent(&engine); |
3615 | 483 | for (int i = 0; i < imports.size(); ++i) | 485 | for (int i = 0; i < imports.size(); ++i) |
3616 | 484 | engine.addImportPath(imports.at(i)); | 486 | engine.addImportPath(imports.at(i)); |
FAILED: Continuous integration, rev:2787 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/3576/ /unity8- jenkins. ubuntu. com/job/ build/4738/ console /unity8- jenkins. ubuntu. com/job/ build-0- fetch/4766 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 4589/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= zesty/4589/ console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 4589/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= zesty/4589/ console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 4589/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= zesty/4589/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/3576/ rebuild
https:/