on xenial help sign in
Set Mir.cursorName to "grabbing" on first mouse press on a window decoration. Don't wait for press+motion. (LP: #1618078)
748ab6cAndrea Azzarone
qml/Stage/MoveHandler.qml+8
@@ -54,6 +54,11 @@ QtObject {
54 property bool nearBottomLeftCorner: target.maximizedBottomLeft
54 property bool nearBottomLeftCorner: target.maximizedBottomLeft
55 property bool nearBottomRightCorner: target.maximizedBottomRight
55 property bool nearBottomRightCorner: target.maximizedBottomRight
56
56
57+ property Timer mouseDownTimer: Timer {
58+ interval: 175
59+ onTriggered: Mir.cursorName = "grabbing"
60+ }
61+
57 function resetEdges() {
62 function resetEdges() {
58 nearLeftEdge = false;
63 nearLeftEdge = false;
59 nearRightEdge = false;
64 nearRightEdge = false;
@@ -93,14 +98,17 @@ QtObject {
93 }
98 }
94
99
95 priv.dragging = true;
100 priv.dragging = true;
101+ priv.mouseDownTimer.start();
96 } else {
102 } else {
97 priv.dragging = false;
103 priv.dragging = false;
104+ priv.mouseDownTimer.stop();
98 Mir.cursorName = "";
105 Mir.cursorName = "";
99 }
106 }
100 }
107 }
101
108
102 function handlePositionChanged(mouse, sensingPoints) {
109 function handlePositionChanged(mouse, sensingPoints) {
103 if (priv.dragging) {
110 if (priv.dragging) {
111+ priv.mouseDownTimer.stop();
104 Mir.cursorName = "grabbing";
112 Mir.cursorName = "grabbing";
105
113
106 // restore from maximized when dragging away from edges/corners; guard against inadvertent changes when going into maximized state
114 // restore from maximized when dragging away from edges/corners; guard against inadvertent changes when going into maximized state
tests/mocks/Unity/Application/CMakeLists.txt+1
@@ -5,6 +5,7 @@ set(FakeUnityApplicationQml_SOURCES
5 MirSurface.cpp
5 MirSurface.cpp
6 MirSurfaceItem.cpp
6 MirSurfaceItem.cpp
7 MirSurfaceListModel.cpp
7 MirSurfaceListModel.cpp
8+ MirMock.cpp
8 ObjectListModel.h
9 ObjectListModel.h
9 SurfaceManager.cpp
10 SurfaceManager.cpp
10 VirtualKeyboard.cpp
11 VirtualKeyboard.cpp
tests/mocks/Unity/Application/MirMock.cppnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "MirMock.h"
18+
19+MirMock *MirMock::the_mir = nullptr;
20+
21+MirMock *MirMock::instance()
22+{
23+ return the_mir;
24+}
25+
26+MirMock::MirMock()
27+{
28+ Q_ASSERT(the_mir == nullptr);
29+ the_mir = this;
30+}
31+
32+MirMock::~MirMock()
33+{
34+ Q_ASSERT(the_mir == this);
35+ the_mir = nullptr;
36+}
37+
38+void MirMock::setCursorName(const QString &cursorName)
39+{
40+ if (cursorName != m_cursorName) {
41+ m_cursorName = cursorName;
42+ Q_EMIT cursorNameChanged(m_cursorName);
43+ }
44+}
45+
46+QString MirMock::cursorName() const
47+{
48+ return m_cursorName;
49+}
tests/mocks/Unity/Application/MirMock.hnew file+39
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef MIR_MOCK_H
18+#define MIR_MOCK_H
19+
20+#include <unity/shell/application/Mir.h>
21+
22+class MirMock : public ::Mir
23+{
24+ Q_OBJECT
25+public:
26+ explicit MirMock();
27+ virtual ~MirMock();
28+
29+ static MirMock *instance();
30+
31+ void setCursorName(const QString &cursorName) override;
32+ QString cursorName() const override;
33+
34+private:
35+ static MirMock *the_mir;
36+ QString m_cursorName;
37+};
38+
39+#endif
tests/mocks/Unity/Application/plugin.cpp+11−2
@@ -17,6 +17,7 @@
17#include "plugin.h"
17#include "plugin.h"
18#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
19#include "ApplicationManager.h"
19#include "ApplicationManager.h"
20+#include "MirMock.h"
20#include "MirSurfaceItem.h"
21#include "MirSurfaceItem.h"
21#include "SurfaceManager.h"
22#include "SurfaceManager.h"
22
23
@@ -38,6 +39,9 @@ void createUnityApplicationSharedSingletons()
38 if (!SurfaceManager::instance()) {
39 if (!SurfaceManager::instance()) {
39 new SurfaceManager;
40 new SurfaceManager;
40 }
41 }
42+ if (!MirMock::instance()) {
43+ new MirMock;
44+ }
41}
45}
42
46
43QObject* applicationManagerSingleton(QQmlEngine*, QJSEngine*)
47QObject* applicationManagerSingleton(QQmlEngine*, QJSEngine*)
@@ -46,6 +50,12 @@ QObject* applicationManagerSingleton(QQmlEngine*, QJSEngine*)
46 return new ApplicationManager;
50 return new ApplicationManager;
47}
51}
48
52
53+QObject* mirSingleton(QQmlEngine*, QJSEngine*)
54+{
55+ createUnityApplicationSharedSingletons();
56+ return MirMock::instance();
57+}
58+
49QObject* surfaceManagerSingleton(QQmlEngine*, QJSEngine*)
59QObject* surfaceManagerSingleton(QQmlEngine*, QJSEngine*)
50{
60{
51 createUnityApplicationSharedSingletons();
61 createUnityApplicationSharedSingletons();
@@ -78,9 +88,8 @@ void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
78 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
88 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
79
89
80 qmlRegisterSingletonType<ApplicationManager>(uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
90 qmlRegisterSingletonType<ApplicationManager>(uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
91+ qmlRegisterSingletonType<MirMock>(uri, 0, 1, "Mir", mirSingleton);
81 qmlRegisterSingletonType<SurfaceManager>(uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
92 qmlRegisterSingletonType<SurfaceManager>(uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
82−
83− qmlRegisterUncreatableType<Mir>(uri, 0, 1, "Mir", "Mir provides enum values, it can't be instantiated");
84}
93}
85
94
86void FakeUnityApplicationQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
95void FakeUnityApplicationQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
tests/qmltests/Stage/tst_DesktopStage.qml+16
@@ -789,5 +789,21 @@ Item {
789
789
790 tryCompare(dialerAppDelegate, "state", "maximized");
790 tryCompare(dialerAppDelegate, "state", "maximized");
791 }
791 }
792+
793+ function test_grabbingCursorOnDecorationPress() {
794+ var appDelegate = startApplication("dialer-app");
795+ verify(appDelegate);
796+ var decoration = findChild(appDelegate, "appWindowDecoration");
797+ verify(decoration);
798+
799+ mousePress(decoration, decoration.width/2, decoration.height/2, Qt.LeftButton);
800+ tryCompare(Mir, "cursorName", "grabbing");
801+
802+ mouseMove(decoration, decoration.width/2 + 1, decoration.height/2 + 1);
803+ tryCompare(Mir, "cursorName", "grabbing");
804+
805+ mouseRelease(decoration);
806+ tryCompare(Mir, "cursorName", "");
807+ }
792 }
808 }
793}
809}