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