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)

Approved by: Lukáš Tinkl, Unity8 CI Bot

commit748ab6c3a862c6a6f186a25cf0ebbc901bbea1aa authorAndrea Azzarone <azzaronea@gmail.com> dateTue 29 Nov 2016, 09:38 (10 years ago) parentec3af51d13a52a
6 files changed+124−2
qml/Stage/MoveHandler.qml+8 tests/mocks/Unity/Application/CMakeLists.txt+1 tests/mocks/Unity/Application/MirMock.cpp+49 tests/mocks/Unity/Application/MirMock.h+39 tests/mocks/Unity/Application/plugin.cpp+11−2 tests/qmltests/Stage/tst_DesktopStage.qml+16
qml/Stage/MoveHandler.qml+8
@@ -54,6 +54,11 @@ QtObject {
5454 property bool nearBottomLeftCorner: target.maximizedBottomLeft
5555 property bool nearBottomRightCorner: target.maximizedBottomRight
5656
57+ property Timer mouseDownTimer: Timer {
58+ interval: 175
59+ onTriggered: Mir.cursorName = "grabbing"
60+ }
61+
5762 function resetEdges() {
5863 nearLeftEdge = false;
5964 nearRightEdge = false;
@@ -93,14 +98,17 @@ QtObject {
9398 }
9499
95100 priv.dragging = true;
101+ priv.mouseDownTimer.start();
96102 } else {
97103 priv.dragging = false;
104+ priv.mouseDownTimer.stop();
98105 Mir.cursorName = "";
99106 }
100107 }
101108
102109 function handlePositionChanged(mouse, sensingPoints) {
103110 if (priv.dragging) {
111+ priv.mouseDownTimer.stop();
104112 Mir.cursorName = "grabbing";
105113
106114 // 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
55 MirSurface.cpp
66 MirSurfaceItem.cpp
77 MirSurfaceListModel.cpp
8+ MirMock.cpp
89 ObjectListModel.h
910 SurfaceManager.cpp
1011 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 @@
1717#include "plugin.h"
1818#include "ApplicationInfo.h"
1919#include "ApplicationManager.h"
20+#include "MirMock.h"
2021#include "MirSurfaceItem.h"
2122#include "SurfaceManager.h"
2223
@@ -38,6 +39,9 @@ void createUnityApplicationSharedSingletons()
3839 if (!SurfaceManager::instance()) {
3940 new SurfaceManager;
4041 }
42+ if (!MirMock::instance()) {
43+ new MirMock;
44+ }
4145}
4246
4347QObject* applicationManagerSingleton(QQmlEngine*, QJSEngine*)
@@ -46,6 +50,12 @@ QObject* applicationManagerSingleton(QQmlEngine*, QJSEngine*)
4650 return new ApplicationManager;
4751}
4852
53+QObject* mirSingleton(QQmlEngine*, QJSEngine*)
54+{
55+ createUnityApplicationSharedSingletons();
56+ return MirMock::instance();
57+}
58+
4959QObject* surfaceManagerSingleton(QQmlEngine*, QJSEngine*)
5060{
5161 createUnityApplicationSharedSingletons();
@@ -78,9 +88,8 @@ void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
7888 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
7989
8090 qmlRegisterSingletonType<ApplicationManager>(uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
91+ qmlRegisterSingletonType<MirMock>(uri, 0, 1, "Mir", mirSingleton);
8192 qmlRegisterSingletonType<SurfaceManager>(uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
82−
83− qmlRegisterUncreatableType<Mir>(uri, 0, 1, "Mir", "Mir provides enum values, it can't be instantiated");
8493}
8594
8695void FakeUnityApplicationQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
tests/qmltests/Stage/tst_DesktopStage.qml+16
@@ -789,5 +789,21 @@ Item {
789789
790790 tryCompare(dialerAppDelegate, "state", "maximized");
791791 }
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+ }
792808 }
793809}