Merge lp:~mzanetti/unity8/screens-workspaces-switcher into lp:unity8

Proposed by Michael Zanetti
Status: Superseded
Proposed branch: lp:~mzanetti/unity8/screens-workspaces-switcher
Merge into: lp:unity8
Diff against target: 3354 lines (+1348/-504) (has conflicts)
61 files modified
plugins/Cursor/CMakeLists.txt (+1/-0)
plugins/Cursor/InputDispatcherFilter.cpp (+146/-0)
plugins/Cursor/InputDispatcherFilter.h (+57/-0)
plugins/Cursor/MousePointer.cpp (+45/-78)
plugins/Cursor/MousePointer.h (+4/-0)
plugins/UInput/plugin.cpp (+7/-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/Greeter/Greeter.qml (+21/-3)
qml/Greeter/SecondaryGreeter.qml (+75/-0)
qml/OrientedShell.qml (+7/-9)
qml/Panel/Panel.qml (+84/-1)
qml/Shell.qml (+32/-21)
qml/ShellApplication.qml (+51/-0)
qml/ShellNotifier.qml (+30/-0)
qml/ShellScreen.qml (+65/-0)
qml/Stage/DecoratedWindow.qml (+44/-0)
qml/Stage/FakeMaximizeDelegate.qml (+12/-11)
qml/Stage/MoveHandler.qml (+8/-7)
qml/Stage/Spread/ScreensAndWorkspaces.qml (+75/-0)
qml/Stage/Spread/Spread.qml (+5/-5)
qml/Stage/Stage.qml (+50/-20)
qml/Stage/SurfaceContainer.qml (+2/-0)
qml/Stage/WindowControlsOverlay.qml (+2/-0)
qml/qmldir (+1/-0)
src/ApplicationArguments.cpp (+12/-3)
src/ApplicationArguments.h (+18/-17)
src/CMakeLists.txt (+0/-2)
src/SecondaryWindow.cpp (+0/-40)
src/SecondaryWindow.h (+0/-30)
src/ShellApplication.cpp (+34/-78)
src/ShellApplication.h (+2/-14)
src/ShellView.cpp (+0/-63)
src/ShellView.h (+0/-34)
src/UnityCommandLineParser.h (+1/-1)
tests/mocks/Cursor/Cursor.qml (+51/-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/MirSurfaceItem.cpp (+5/-0)
tests/mocks/Unity/Application/SurfaceManager.cpp (+1/-1)
tests/mocks/Unity/InputInfo/InputWindow.qml (+68/-0)
tests/mocks/Unity/InputInfo/mockcontroller.cpp (+26/-4)
tests/mocks/Unity/InputInfo/mockcontroller.h (+5/-1)
tests/mocks/Unity/InputInfo/plugin.cpp (+1/-2)
tests/mocks/Unity/InputInfo/qmldir (+2/-0)
tests/mocks/Unity/Screens/CMakeLists.txt (+2/-1)
tests/mocks/Unity/Screens/plugin.cpp (+12/-1)
tests/mocks/Unity/Screens/screens.cpp (+40/-2)
tests/mocks/Unity/Screens/screens.h (+27/-1)
tests/mocks/Unity/Screens/screenwindow.cpp (+32/-0)
tests/mocks/Unity/Screens/screenwindow.h (+36/-0)
tests/qmltests/Components/tst_VirtualTouchPad.qml (+2/-2)
tests/qmltests/Panel/tst_Panel.qml (+35/-1)
tests/qmltests/Stage/tst_DesktopStage.qml (+8/-3)
tests/qmltests/Stage/tst_WindowResizeArea.qml (+1/-8)
tests/qmltests/tst_OrientedShell.qml (+24/-5)
tests/qmltests/tst_Shell.qml (+43/-7)
Text conflict in qml/Panel/Panel.qml
Text conflict in qml/Shell.qml
Text conflict in qml/Stage/DecoratedWindow.qml
Text conflict in qml/Stage/Stage.qml
Text conflict in src/ShellApplication.cpp
Text conflict in tests/mocks/Unity/Screens/screens.h
Text conflict in tests/qmltests/Panel/tst_Panel.qml
Text conflict in tests/qmltests/tst_Shell.qml
To merge this branch: bzr merge lp:~mzanetti/unity8/screens-workspaces-switcher
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+314838@code.launchpad.net

This proposal has been superseded by a proposal from 2017-01-16.

Commit message

screens and workspaces switcher

To post a comment you must log in.
2763. By Michael Zanetti

split it up

2764. By Michael Zanetti

merge prereq

2765. By Michael Zanetti

improve previews

2766. By Michael Zanetti

merge prereq

2767. By Michael Zanetti

merge prereq

2768. By Michael Zanetti

add hover item to screens

2769. By Michael Zanetti

drop empty line

2770. By Michael Zanetti

merge prereq

2771. By Michael Zanetti

merge prereq

2772. By Michael Zanetti

activate the other screen on timeout

2773. By Michael Zanetti

add icon, adjust visuals

2774. By Michael Zanetti

make workspaces a listview

2775. By Michael Zanetti

merge prereq

2776. By Michael Zanetti

make it a listview, update to latest api

2777. By Michael Zanetti

some more work on the workspace preview spread

2778. By Michael Zanetti

add drag and drop wor workspaces between screens

2779. By Michael Zanetti

play with the size

2780. By Michael Zanetti

merge prereq

2781. By Michael Zanetti

add scrolling areas

2782. By Michael Zanetti

merge trunk

2783. By Michael Zanetti

fix imports

2784. By Michael Zanetti

add support for dragging apps out of the spread

2785. By Michael Zanetti

improve dragging and hover scrolling

2786. By Michael Zanetti

optimize it a little

2787. By Michael Zanetti

merge new prereq

2788. By Michael Zanetti

merge new prereq

2789. By Michael Zanetti

make use of actual workspace model instead of dummy ListModels

2790. By Michael Zanetti

properly create and destroy workspaces

2791. By Michael Zanetti

merge prereq

2792. By Michael Zanetti

merge prereq

2793. By Michael Zanetti

update to latest backend code

2794. By Michael Zanetti

merge prereq

2795. By Michael Zanetti

merge prereq

2796. By Michael Zanetti

bump u-a-l version requirement

2797. By Michael Zanetti

merge prereq

2798. By Michael Zanetti

use a toplevelwindowmodel per workspace

2799. By Michael Zanetti

merge prereq

2800. By Michael Zanetti

merge prereq

2801. By Michael Zanetti

some improvements

2802. By Michael Zanetti

some more fixes

2803. By Michael Zanetti

add close button on hover

2804. By Michael Zanetti

fix workspace preview scaling

2805. By Michael Zanetti

add outputTypeName to Screen

2806. By Michael Zanetti

merge prereq

2807. By Michael Zanetti

minor tweaks

2808. By Michael Zanetti

merge prereq

2809. By Michael Zanetti

finalize drag and drop for apps to another workspace

(not working yet for some reason, likely in the backend stuff that's to be debugged still)

2810. By Michael Zanetti

fix drag and drop of applications

2811. By Michael Zanetti

highlight active workspace

2812. By Michael Zanetti

add feature to drop to the left/right of a workspace

2813. By Michael Zanetti

merge prereq

2814. By Michael Zanetti

add text to drop targets

2815. By Michael Zanetti

merge prereq

2816. By Michael Zanetti

merge prereq

2817. By Michael Zanetti

add missing graphics file

2818. By Michael Zanetti

cancel dnd operation properly

2819. By Michael Zanetti

use correct graphic

2820. By Michael Zanetti

merge prereq

2821. By Michael Zanetti

don't apply transitions if a delegate is created while we're in spread

2822. By Michael Zanetti

improve listview animations and handling

Unmerged revisions

2822. By Michael Zanetti

improve listview animations and handling

2821. By Michael Zanetti

don't apply transitions if a delegate is created while we're in spread

2820. By Michael Zanetti

merge prereq

2819. By Michael Zanetti

use correct graphic

2818. By Michael Zanetti

cancel dnd operation properly

2817. By Michael Zanetti

add missing graphics file

2816. By Michael Zanetti

merge prereq

2815. By Michael Zanetti

merge prereq

2814. By Michael Zanetti

add text to drop targets

2813. By Michael Zanetti

merge prereq

Preview Diff

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

Subscribers

People subscribed via source and target branches