Merge lp:~ci-train-bot/unity8/unity8-ubuntu-yakkety-landing-059 into lp:unity8

Proposed by Michał Sawicz
Status: Merged
Merged at revision: 2440
Proposed branch: lp:~ci-train-bot/unity8/unity8-ubuntu-yakkety-landing-059
Merge into: lp:unity8
Diff against target: 14480 lines (+2342/-7398)
240 files modified
CMakeLists.txt (+13/-2)
debian/changelog (+65/-0)
debian/control (+5/-3)
debian/unity8-private.install (+0/-1)
libs/CMakeLists.txt (+0/-1)
libs/UbuntuGestures/CMakeLists.txt (+0/-41)
libs/UbuntuGestures/CandidateInactivityTimer.cpp (+0/-46)
libs/UbuntuGestures/CandidateInactivityTimer.h (+0/-51)
libs/UbuntuGestures/DebugHelpers.cpp (+0/-95)
libs/UbuntuGestures/DebugHelpers.h (+0/-31)
libs/UbuntuGestures/Pool.h (+0/-124)
libs/UbuntuGestures/TimeSource.cpp (+0/-49)
libs/UbuntuGestures/TimeSource.h (+0/-64)
libs/UbuntuGestures/Timer.cpp (+0/-152)
libs/UbuntuGestures/Timer.h (+0/-122)
libs/UbuntuGestures/TouchOwnershipEvent.cpp (+0/-35)
libs/UbuntuGestures/TouchOwnershipEvent.h (+0/-50)
libs/UbuntuGestures/TouchRegistry.cpp (+0/-553)
libs/UbuntuGestures/TouchRegistry.h (+0/-201)
libs/UbuntuGestures/UbuntuGesturesGlobal.h (+0/-23)
libs/UbuntuGestures/UnownedTouchEvent.cpp (+0/-39)
libs/UbuntuGestures/UnownedTouchEvent.h (+0/-45)
plugins/Cursor/CMakeLists.txt (+2/-1)
plugins/Cursor/Cursor.qml (+21/-5)
plugins/Cursor/Cursor.qmltypes (+0/-78)
plugins/Cursor/CursorImageInfo.cpp (+106/-0)
plugins/Cursor/CursorImageInfo.h (+76/-0)
plugins/Cursor/CursorImageProvider.cpp (+52/-23)
plugins/Cursor/CursorImageProvider.h (+12/-4)
plugins/Cursor/MousePointer.cpp (+29/-24)
plugins/Cursor/MousePointer.h (+5/-6)
plugins/Cursor/plugin.cpp (+4/-2)
plugins/Cursor/qmldir (+1/-1)
plugins/Dash/AudioProgressBar.qml (+1/-1)
plugins/Dash/CardCreator.js (+64/-48)
plugins/Dash/CardCreatorCache.qml (+2/-2)
plugins/Dash/ScopeStyle.qml (+1/-1)
plugins/Dash/listviewwithpageheader.cpp (+14/-17)
plugins/Ubuntu/Gestures/AxisVelocityCalculator.h (+1/-1)
plugins/Ubuntu/Gestures/CMakeLists.txt (+5/-5)
plugins/Ubuntu/Gestures/Damper.cpp (+0/-24)
plugins/Ubuntu/Gestures/Damper.h (+0/-89)
plugins/Ubuntu/Gestures/Direction.h (+1/-0)
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp (+0/-932)
plugins/Ubuntu/Gestures/DirectionalDragArea.h (+0/-143)
plugins/Ubuntu/Gestures/DirectionalDragArea_p.h (+0/-169)
plugins/Ubuntu/Gestures/Gestures.qmltypes (+0/-132)
plugins/Ubuntu/Gestures/MouseEventGenerator.cpp (+48/-134)
plugins/Ubuntu/Gestures/MouseEventGenerator.h (+23/-61)
plugins/Ubuntu/Gestures/PressedOutsideNotifier.h (+1/-1)
plugins/Ubuntu/Gestures/TouchGate.cpp (+2/-2)
plugins/Ubuntu/Gestures/TouchGestureArea.cpp (+9/-6)
plugins/Ubuntu/Gestures/TouchGestureArea.h (+2/-3)
plugins/Ubuntu/Gestures/plugin.cpp (+3/-5)
plugins/Unity/InputInfo/plugin.h (+1/-1)
plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.h (+3/-3)
plugins/Unity/Session/dbusunitysessionservice.cpp (+7/-0)
plugins/Utils/WindowInputMonitor.cpp (+8/-8)
plugins/Utils/WindowInputMonitor.h (+8/-2)
plugins/Utils/windowstatestorage.h (+13/-3)
po/unity8.pot (+22/-22)
qml/Components/Dialogs.qml (+2/-2)
qml/Components/DragHandle.qml (+44/-26)
qml/Components/FloatingFlickable.qml (+59/-0)
qml/Components/Header.qml (+0/-28)
qml/Components/ModeSwitchWarningDialog.qml (+1/-1)
qml/Components/PanelState/PanelState.qml (+3/-3)
qml/Components/Rating.qml (+1/-0)
qml/Components/RatingStyle.qml (+3/-0)
qml/Components/WindowControlButtons.qml (+18/-7)
qml/Dash/CardCarousel.qml (+0/-1)
qml/Dash/CardGrid.qml (+0/-2)
qml/Dash/CardTool.qml (+6/-2)
qml/Dash/Dash.qml (+3/-3)
qml/Dash/DashApplication.qml (+0/-3)
qml/Dash/DashCategoryBase.qml (+3/-11)
qml/Dash/DashPageHeader.qml (+32/-37)
qml/Dash/Filters/FilterOptionSelector.qml (+4/-0)
qml/Dash/Filters/FilterWidgetFactory.qml (+8/-0)
qml/Dash/GenericScopeView.qml (+14/-4)
qml/Dash/PageHeaderExtraPanel.qml (+35/-11)
qml/Dash/Previews/PreviewActions.qml (+1/-1)
qml/Dash/Previews/PreviewPayments.qml (+1/-1)
qml/Dash/Previews/PreviewRatingInput.qml (+42/-43)
qml/Dash/ScopesList.qml (+1/-13)
qml/Launcher/Launcher.qml (+16/-24)
qml/Launcher/LauncherDelegate.qml (+2/-2)
qml/Notifications/Notification.qml (+20/-5)
qml/Notifications/NotificationMenuItemFactory.qml (+3/-0)
qml/Notifications/Notifications.qml (+18/-9)
qml/Panel/Indicators/MessageMenuItemFactory.qml (+1/-5)
qml/Panel/IndicatorsMenu.qml (+17/-13)
qml/Panel/Panel.qml (+15/-5)
qml/Shell.qml (+4/-3)
qml/Stages/DecoratedWindow.qml (+11/-7)
qml/Stages/DesktopSpread.qml (+1/-1)
qml/Stages/DesktopSpreadDelegate.qml (+1/-1)
qml/Stages/DesktopStage.qml (+57/-45)
qml/Stages/PhoneStage.qml (+4/-4)
qml/Stages/SideStage.qml (+1/-2)
qml/Stages/Splash.qml (+6/-17)
qml/Stages/SpreadDelegate.qml (+1/-1)
qml/Stages/TabletStage.qml (+4/-4)
qml/Stages/WindowDecoration.qml (+12/-8)
qml/Stages/WindowResizeArea.qml (+25/-5)
qml/Tutorial/TutorialBottom.qml (+3/-3)
qml/Wizard/Pages/50-timezone.qml (+5/-2)
src/CMakeLists.txt (+1/-4)
src/Dash/CMakeLists.txt (+1/-0)
src/Dash/main.cpp (+6/-0)
src/UnixSignalHandler.cpp (+1/-1)
src/main.cpp (+6/-0)
tests/CMakeLists.txt (+0/-1)
tests/autopilot/unity8/dash.py (+2/-3)
tests/libs/CMakeLists.txt (+0/-1)
tests/libs/UbuntuGestures/CMakeLists.txt (+0/-16)
tests/libs/UbuntuGestures/tst_TouchRegistry.cpp (+0/-974)
tests/mocks/Cursor/qmldir (+1/-1)
tests/mocks/GSettings.1.0/fake_gsettings.cpp (+1/-0)
tests/mocks/GSettings.1.0/fake_gsettings.h (+2/-2)
tests/mocks/IntegratedLightDM/liblightdm/GreeterPrivate.h (+0/-1)
tests/mocks/QtMultimedia/audio.cpp (+3/-3)
tests/mocks/QtMultimedia/audio.h (+12/-6)
tests/mocks/Ubuntu/Payments/MockPayments.cpp (+1/-0)
tests/mocks/Ubuntu/SystemSettings/TimeDate/CMakeLists.txt (+1/-1)
tests/mocks/Ubuntu/SystemSettings/TimeDate/MockTimeDate.qml (+16/-4)
tests/mocks/Ubuntu/SystemSettings/TimeDate/qmldir (+1/-1)
tests/mocks/Unity/Application/ApplicationInfo.h (+1/-1)
tests/mocks/Unity/Application/MirSurface.h (+2/-2)
tests/mocks/Unity/Application/MirSurfaceItem.cpp (+1/-0)
tests/mocks/Unity/InputInfo/plugin.h (+1/-1)
tests/mocks/Unity/Screens/plugin.h (+1/-1)
tests/mocks/Unity/fake_scope.cpp (+6/-3)
tests/mocks/Unity/fake_scope.h (+1/-1)
tests/mocks/Unity/fake_scopes.cpp (+11/-0)
tests/mocks/Utils/plugin.h (+1/-1)
tests/mocks/Utils/windowstatestorage.h (+14/-3)
tests/mocks/libusermetrics/UserMetrics.cpp (+1/-1)
tests/plugins/CMakeLists.txt (+2/-1)
tests/plugins/Cursor/CMakeLists.txt (+8/-0)
tests/plugins/Cursor/TextEntry.qml (+34/-0)
tests/plugins/Cursor/tst_Cursor.qml (+144/-0)
tests/plugins/Dash/cardcreator/1.res (+8/-26)
tests/plugins/Dash/cardcreator/1.res.cardcreator (+8/-26)
tests/plugins/Dash/cardcreator/1.tst (+1/-0)
tests/plugins/Dash/cardcreator/10.res (+0/-9)
tests/plugins/Dash/cardcreator/10.res.cardcreator (+0/-9)
tests/plugins/Dash/cardcreator/10.tst (+1/-0)
tests/plugins/Dash/cardcreator/11.res (+11/-29)
tests/plugins/Dash/cardcreator/11.res.cardcreator (+10/-28)
tests/plugins/Dash/cardcreator/11.tst (+1/-0)
tests/plugins/Dash/cardcreator/12.res (+8/-26)
tests/plugins/Dash/cardcreator/12.res.cardcreator (+10/-28)
tests/plugins/Dash/cardcreator/12.tst (+1/-0)
tests/plugins/Dash/cardcreator/2.res (+0/-9)
tests/plugins/Dash/cardcreator/2.res.cardcreator (+0/-9)
tests/plugins/Dash/cardcreator/2.tst (+1/-0)
tests/plugins/Dash/cardcreator/3.res (+5/-33)
tests/plugins/Dash/cardcreator/3.res.cardcreator (+5/-33)
tests/plugins/Dash/cardcreator/3.tst (+1/-0)
tests/plugins/Dash/cardcreator/4.res (+1/-2)
tests/plugins/Dash/cardcreator/4.res.cardcreator (+1/-2)
tests/plugins/Dash/cardcreator/4.tst (+1/-0)
tests/plugins/Dash/cardcreator/5.res (+2/-35)
tests/plugins/Dash/cardcreator/5.res.cardcreator (+2/-35)
tests/plugins/Dash/cardcreator/5.tst (+1/-0)
tests/plugins/Dash/cardcreator/6.res (+1/-2)
tests/plugins/Dash/cardcreator/6.res.cardcreator (+1/-2)
tests/plugins/Dash/cardcreator/6.tst (+1/-0)
tests/plugins/Dash/cardcreator/7.res (+0/-9)
tests/plugins/Dash/cardcreator/7.res.cardcreator (+0/-9)
tests/plugins/Dash/cardcreator/7.tst (+1/-0)
tests/plugins/Dash/cardcreator/8.res (+1/-2)
tests/plugins/Dash/cardcreator/8.res.cardcreator (+1/-2)
tests/plugins/Dash/cardcreator/8.tst (+1/-0)
tests/plugins/Dash/cardcreator/9.res (+1/-2)
tests/plugins/Dash/cardcreator/9.res.cardcreator (+1/-2)
tests/plugins/Dash/cardcreator/9.tst (+1/-0)
tests/plugins/Dash/cardcreatortest.cpp (+9/-6)
tests/plugins/Dash/cardcreatortest.qml (+4/-4)
tests/plugins/Dash/listviewwithpageheadersectionexternalmodeltest.cpp (+2/-2)
tests/plugins/Dash/listviewwithpageheadersectiontest.cpp (+2/-2)
tests/plugins/Dash/listviewwithpageheadertest.cpp (+5/-0)
tests/plugins/Dash/listviewwithpageheadertestsection.qml (+3/-2)
tests/plugins/Dash/listviewwithpageheadertestsectionexternalmodel.qml (+2/-1)
tests/plugins/Dash/tst_ListViewWithPageHeaderQML.qml (+4/-2)
tests/plugins/Dash/tst_ScopeStyle.qml (+1/-1)
tests/plugins/Ubuntu/Gestures/CMakeLists.txt (+4/-4)
tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qml (+0/-72)
tests/plugins/Ubuntu/Gestures/GestureTest.cpp (+2/-2)
tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qml (+0/-76)
tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qml (+0/-76)
tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qml (+0/-76)
tests/plugins/Ubuntu/Gestures/tst_Damper.cpp (+0/-40)
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp (+0/-1250)
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.qml (+0/-76)
tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.cpp (+26/-19)
tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.qml (+1/-0)
tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp (+1/-1)
tests/plugins/Unity/Indicators/MenuContentActivatorTest.cpp (+1/-0)
tests/plugins/Unity/Session/sessionbackendtest.cpp (+0/-15)
tests/plugins/Utils/WindowInputMonitorTest.cpp (+51/-10)
tests/qmltests/Components/CMakeLists.txt (+6/-3)
tests/qmltests/Components/tst_DragHandle.cpp (+28/-24)
tests/qmltests/Components/tst_DragHandle.qml (+27/-9)
tests/qmltests/Components/tst_DragHandle/BottomEdgeShowable.qml (+108/-0)
tests/qmltests/Components/tst_DragHandle/RightEdgeShowable.qml (+108/-0)
tests/qmltests/Components/tst_DragHandle/TopEdgeShowable.qml (+7/-7)
tests/qmltests/Components/tst_EdgeDragEvaluator.cpp (+1/-1)
tests/qmltests/Dash/Previews/tst_Preview.qml (+0/-1)
tests/qmltests/Dash/Previews/tst_PreviewRatingEdit.qml (+5/-1)
tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml (+18/-6)
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml (+1/-1)
tests/qmltests/Dash/tst_Card.qml (+22/-10)
tests/qmltests/Dash/tst_CardTool.qml (+1/-1)
tests/qmltests/Dash/tst_Dash.qml (+76/-62)
tests/qmltests/Dash/tst_DashContent.qml (+65/-6)
tests/qmltests/Dash/tst_DashPageHeader.qml (+0/-24)
tests/qmltests/Dash/tst_DashShell.qml (+1/-1)
tests/qmltests/Dash/tst_GenericScopeView.qml (+2/-2)
tests/qmltests/Dash/tst_PreviewView.qml (+3/-3)
tests/qmltests/Greeter/tst_Greeter.qml (+1/-1)
tests/qmltests/Greeter/tst_NarrowView.qml (+1/-1)
tests/qmltests/Greeter/tst_WideView.qml (+1/-1)
tests/qmltests/Launcher/tst_Launcher.qml (+13/-1)
tests/qmltests/Notifications/tst_Notifications.qml (+89/-0)
tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qml (+1/-0)
tests/qmltests/Stages/tst_DesktopStage.qml (+31/-1)
tests/qmltests/Stages/tst_WindowResizeArea.qml (+16/-5)
tests/qmltests/Tutorial/tst_Tutorial.qml (+2/-2)
tests/qmltests/Wizard/tst_Wizard.qml (+4/-3)
tests/qmltests/tst_OrientedShell.qml (+1/-1)
tests/qmltests/tst_Shell.qml (+32/-5)
tests/qmltests/tst_ShellWithPin.qml (+1/-1)
tests/uqmlscene/main.cpp (+0/-1)
tests/utils/modules/Unity/Test/CMakeLists.txt (+4/-2)
tests/utils/modules/Unity/Test/UnityTestCase.qml (+34/-15)
tests/utils/modules/Unity/Test/testutil.cpp (+2/-2)
tools/CMakeLists.txt (+1/-1)
tools/scopetool.cpp (+1/-1)
To merge this branch: bzr merge lp:~ci-train-bot/unity8/unity8-ubuntu-yakkety-landing-059
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+296236@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-05-18 11:17:20 +0000
3+++ CMakeLists.txt 2016-06-01 16:58:47 +0000
4@@ -57,12 +57,24 @@
5 find_package(Qt5Concurrent 5.4 REQUIRED)
6 find_package(Qt5Sql 5.4 REQUIRED)
7
8-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=16)
9+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=17)
10 pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
11 pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
12 pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
13 pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
14
15+pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
16+
17+### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
18+find_path(UBUNTUGESTUREPRIV
19+ NAMES UbuntuGestures/private/damper_p.h UbuntuGestures/private/ucswipearea_p.h UbuntuGestures/private/ucswipearea_p_p.h
20+ PATHS ${UBUNTUGESTURES_INCLUDEDIR}/UbuntuGestures/${UBUNTUGESTURES_VERSION}
21+ NO_DEFAULT_PATH)
22+if (${UBUNTUGESTUREPRIV} STREQUAL UBUNTUGESTUREPRIV-NOTFOUND)
23+ message(FATAL_ERROR "UbuntuGestures private headers not found.")
24+endif()
25+# end of UbuntuGesture private headers check
26+
27 # Standard install paths
28 include(GNUInstallDirs)
29
30@@ -144,7 +156,6 @@
31
32 # add subdirectories to build
33 add_subdirectory(include)
34-add_subdirectory(libs)
35 add_subdirectory(src)
36 add_subdirectory(tools)
37 add_subdirectory(qml)
38
39=== modified file 'debian/changelog'
40--- debian/changelog 2016-05-20 08:44:19 +0000
41+++ debian/changelog 2016-06-01 16:58:47 +0000
42@@ -1,3 +1,68 @@
43+unity8 (8.12+16.10.20160527-0ubuntu1) yakkety; urgency=medium
44+
45+ [ Albert Astals Cid ]
46+ * Activate on click for SimpleMessages (LP: #1421696)
47+ * Add override
48+ * Change the art back to the cardData value if it changes from broken
49+ to valid image (LP: #1533577)
50+ * Concierge mode generated code optimization
51+ * Don't use context properties but properties of the delegates
52+ * Listen to contentItem::widthChanged instead of
53+ Flickable::contentWidthChanged (LP: #1565763)
54+ * Make some AP code faster
55+ * Make tests a bit more stable
56+ * Make unity8 and unity8-dash handle termination signals
57+ * Remove workaround not needed anymore (LP: #1475643)
58+ * Resolve cardArtStyle on compile time
59+ * Set the theme earlier (LP: #1574048)
60+
61+ [ Albert Astals Cid, Daniel d'Andrada ]
62+ * Remove DirectionalDragArea and libs/UbuntuGestures and port to SDK
63+ equivalents
64+
65+ [ Andrea Cimitan ]
66+ * Hide the preview review input field when a rating is required (LP:
67+ #1541971)
68+
69+ [ CI Train Bot ]
70+ * Resync trunk.
71+
72+ [ Daniel d'Andrada ]
73+ * Fix DragHandle so it works in all directions
74+ * Support animated cursors
75+ * WindowInputMonitor - also map Qt::Key_HomePage to our home key
76+ * plugins/Cursor: properly register to the screen's QPlatformCursor
77+ when screen changes (LP: #1579742)
78+
79+ [ Josh Arenson ]
80+ * Close the PageHeaderExtraPanel when a filter option is selected (LP:
81+ #1569498)
82+ * Wrap primaryFilter in a flickable to make it behave nicely. (LP:
83+ #1569492)
84+
85+ [ Lukáš Tinkl ]
86+ * First snap decision should always be expanded, unless user decides
87+ otherwise (LP: #1580090, #1575045)
88+ * Fullscreen notification bug fixes (LP: #1583944, #1581498, #1422711)
89+ * Implement maximizing windows horizontally/vertically
90+ * Lock the session when putting the laptop into sleep (LP: #1581063)
91+
92+ [ Lukáš Tinkl, Michael Terry ]
93+ * With a maximized window, "dragging" the panel down should restore it
94+
95+ [ Michael Terry ]
96+ * Change some dash button colors from orange to green. (LP: #1581047)
97+ * Use PageHeader instead Ambiance's PageHeadStyle
98+ * Use new setTimeZone method to set user-friendly timezone name in the
99+ wizard. (LP: #1566295)
100+
101+ [ Michael Zanetti ]
102+ * Remove the background dimming when the launcher is revealed by a
103+ drag (LP: #1575137)
104+ * reenable or drop disabled tests
105+
106+ -- Michael Terry <michael.terry@canonical.com> Fri, 27 May 2016 13:54:44 +0000
107+
108 unity8 (8.12+16.10.20160520.1-0ubuntu1) yakkety; urgency=medium
109
110 [ Lukáš Tinkl ]
111
112=== modified file 'debian/control'
113--- debian/control 2016-05-17 19:42:10 +0000
114+++ debian/control 2016-06-01 16:58:47 +0000
115@@ -29,8 +29,10 @@
116 libqt5svg5-dev,
117 libqt5xmlpatterns5-dev,
118 libsystemsettings-dev,
119+ libubuntugestures5-dev,
120+ libubuntugestures5-private-dev,
121 libudev-dev,
122- libunity-api-dev (>= 7.112),
123+ libunity-api-dev (>= 7.113),
124 libusermetricsoutput1-dev,
125 # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
126 libx11-dev[!armhf],
127@@ -106,7 +108,7 @@
128 qtdeclarative5-qtmir-plugin (>= 0.4.8),
129 qtdeclarative5-ubuntu-telephony0.1,
130 qtdeclarative5-ubuntu-web-plugin,
131- ubuntu-system-settings,
132+ ubuntu-system-settings (>= 0.4),
133 unity-launcher-impl-7,
134 unity8-common (= ${source:Version}),
135 unity8-private (= ${binary:Version}),
136@@ -133,7 +135,7 @@
137 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
138 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
139 ubuntu-thumbnailer-impl-0,
140- unity-application-impl-16,
141+ unity-application-impl-17,
142 unity-notifications-impl-3,
143 unity-plugin-scopes | unity-scopes-impl,
144 unity-scopes-impl-12,
145
146=== modified file 'debian/unity8-private.install'
147--- debian/unity8-private.install 2016-04-28 12:06:22 +0000
148+++ debian/unity8-private.install 2016-06-01 16:58:47 +0000
149@@ -1,5 +1,4 @@
150 usr/lib/*/libunity8-private.*
151-usr/lib/*/unity8/libUbuntuGestures*
152 usr/lib/*/unity8/qml/AccountsService
153 usr/lib/*/unity8/qml/Cursor
154 usr/lib/*/unity8/qml/Dash
155
156=== removed directory 'libs'
157=== removed file 'libs/CMakeLists.txt'
158--- libs/CMakeLists.txt 2014-10-01 13:20:32 +0000
159+++ libs/CMakeLists.txt 1970-01-01 00:00:00 +0000
160@@ -1,1 +0,0 @@
161-add_subdirectory(UbuntuGestures)
162
163=== removed directory 'libs/UbuntuGestures'
164=== removed file 'libs/UbuntuGestures/CMakeLists.txt'
165--- libs/UbuntuGestures/CMakeLists.txt 2015-04-10 21:16:37 +0000
166+++ libs/UbuntuGestures/CMakeLists.txt 1970-01-01 00:00:00 +0000
167@@ -1,41 +0,0 @@
168-# in order to include Qt's private headers
169-remove_definitions(-DQT_NO_KEYWORDS)
170-
171-set(UbuntuGestures_SOURCES
172- CandidateInactivityTimer.cpp
173- DebugHelpers.cpp
174- Timer.cpp
175- TimeSource.cpp
176- TouchOwnershipEvent.cpp
177- TouchRegistry.cpp
178- UnownedTouchEvent.cpp
179-)
180-
181-add_definitions(-DUBUNTUGESTURES_LIBRARY)
182-
183-add_library(UbuntuGestures SHARED ${UbuntuGestures_SOURCES})
184-
185-qt5_use_modules(UbuntuGestures Core Quick)
186-
187-# So that Foo.cpp can #include "Foo.moc"
188-include_directories(${CMAKE_CURRENT_BINARY_DIR})
189-
190-install(TARGETS UbuntuGestures
191- DESTINATION ${SHELL_PRIVATE_LIBDIR})
192-
193-
194-# There's no cmake var for v8 include path :-/ so create one
195-LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
196-if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0")
197- SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
198-else()
199- SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
200-endif()
201-
202-# DANGER! DANGER! Using Qt's private API!
203-include_directories(
204- ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
205- ${Qt5Quick_INCLUDE_DIRS}
206- ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
207- ${Qt5V8_PRIVATE_INCLUDE_DIR}
208-)
209
210=== removed file 'libs/UbuntuGestures/CandidateInactivityTimer.cpp'
211--- libs/UbuntuGestures/CandidateInactivityTimer.cpp 2015-04-17 18:31:12 +0000
212+++ libs/UbuntuGestures/CandidateInactivityTimer.cpp 1970-01-01 00:00:00 +0000
213@@ -1,46 +0,0 @@
214-/*
215- * Copyright (C) 2014 Canonical, Ltd.
216- *
217- * This program is free software; you can redistribute it and/or modify
218- * it under the terms of the GNU General Public License as published by
219- * the Free Software Foundation; version 3.
220- *
221- * This program is distributed in the hope that it will be useful,
222- * but WITHOUT ANY WARRANTY; without even the implied warranty of
223- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
224- * GNU General Public License for more details.
225- *
226- * You should have received a copy of the GNU General Public License
227- * along with this program. If not, see <http://www.gnu.org/licenses/>.
228- */
229-
230-#include "CandidateInactivityTimer.h"
231-
232-namespace UbuntuGestures {
233-
234-CandidateInactivityTimer::CandidateInactivityTimer(int touchId, QQuickItem *candidate,
235- AbstractTimer *timer, QObject *parent)
236- : QObject(parent)
237- , m_timer(timer)
238- , m_touchId(touchId)
239- , m_candidate(candidate)
240-{
241- connect(m_timer, &AbstractTimer::timeout,
242- this, &CandidateInactivityTimer::onTimeout);
243- m_timer->setInterval(durationMs);
244- m_timer->setSingleShot(true);
245- m_timer->start();
246-}
247-
248-CandidateInactivityTimer::~CandidateInactivityTimer()
249-{
250- delete m_timer;
251-}
252-
253-void CandidateInactivityTimer::onTimeout()
254-{
255- qWarning("[TouchRegistry] Candidate for touch %d defaulted!", m_touchId);
256- Q_EMIT candidateDefaulted(m_touchId, m_candidate);
257-}
258-
259-} // namespace UbuntuGestures
260
261=== removed file 'libs/UbuntuGestures/CandidateInactivityTimer.h'
262--- libs/UbuntuGestures/CandidateInactivityTimer.h 2015-04-17 18:31:12 +0000
263+++ libs/UbuntuGestures/CandidateInactivityTimer.h 1970-01-01 00:00:00 +0000
264@@ -1,51 +0,0 @@
265-/*
266- * Copyright (C) 2014 Canonical, Ltd.
267- *
268- * This program is free software; you can redistribute it and/or modify
269- * it under the terms of the GNU General Public License as published by
270- * the Free Software Foundation; version 3.
271- *
272- * This program is distributed in the hope that it will be useful,
273- * but WITHOUT ANY WARRANTY; without even the implied warranty of
274- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
275- * GNU General Public License for more details.
276- *
277- * You should have received a copy of the GNU General Public License
278- * along with this program. If not, see <http://www.gnu.org/licenses/>.
279- */
280-
281-#ifndef UBUNTUGESTURES_CANDIDATE_INACTIVITY_TIMER_H
282-#define UBUNTUGESTURES_CANDIDATE_INACTIVITY_TIMER_H
283-
284-#include <QObject>
285-
286-class QQuickItem;
287-
288-#include "Timer.h"
289-
290-namespace UbuntuGestures {
291-
292-class UBUNTUGESTURES_EXPORT CandidateInactivityTimer : public QObject {
293- Q_OBJECT
294-public:
295- CandidateInactivityTimer(int touchId, QQuickItem *candidate,
296- AbstractTimer *timer,
297- QObject *parent = nullptr);
298-
299- virtual ~CandidateInactivityTimer();
300-
301- const int durationMs = 1000;
302-
303-Q_SIGNALS:
304- void candidateDefaulted(int touchId, QQuickItem *candidate);
305-private Q_SLOTS:
306- void onTimeout();
307-private:
308- AbstractTimer *m_timer;
309- int m_touchId;
310- QQuickItem *m_candidate;
311-};
312-
313-} // namespace UbuntuGestures
314-
315-#endif // UBUNTUGESTURES_CANDIDATE_INACTIVITY_TIMER_H
316
317=== removed file 'libs/UbuntuGestures/DebugHelpers.cpp'
318--- libs/UbuntuGestures/DebugHelpers.cpp 2015-09-14 09:11:08 +0000
319+++ libs/UbuntuGestures/DebugHelpers.cpp 1970-01-01 00:00:00 +0000
320@@ -1,95 +0,0 @@
321-/*
322- * Copyright (C) 2014 Canonical, Ltd.
323- *
324- * This program is free software; you can redistribute it and/or modify
325- * it under the terms of the GNU General Public License as published by
326- * the Free Software Foundation; version 3.
327- *
328- * This program is distributed in the hope that it will be useful,
329- * but WITHOUT ANY WARRANTY; without even the implied warranty of
330- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
331- * GNU General Public License for more details.
332- *
333- * You should have received a copy of the GNU General Public License
334- * along with this program. If not, see <http://www.gnu.org/licenses/>.
335- */
336-
337-#include "DebugHelpers.h"
338-#include <QTouchEvent>
339-#include <QMouseEvent>
340-
341-QString touchPointStateToString(Qt::TouchPointState state)
342-{
343- switch (state) {
344- case Qt::TouchPointPressed:
345- return QStringLiteral("pressed");
346- case Qt::TouchPointMoved:
347- return QStringLiteral("moved");
348- case Qt::TouchPointStationary:
349- return QStringLiteral("stationary");
350- case Qt::TouchPointReleased:
351- return QStringLiteral("released");
352- default:
353- return QStringLiteral("INVALID_STATE");
354- }
355-}
356-
357-QString touchEventToString(const QTouchEvent *ev)
358-{
359- QString message;
360-
361- switch (ev->type()) {
362- case QEvent::TouchBegin:
363- message.append("TouchBegin ");
364- break;
365- case QEvent::TouchUpdate:
366- message.append("TouchUpdate ");
367- break;
368- case QEvent::TouchEnd:
369- message.append("TouchEnd ");
370- break;
371- case QEvent::TouchCancel:
372- message.append("TouchCancel ");
373- break;
374- default:
375- message.append("INVALID_TOUCH_EVENT_TYPE ");
376- }
377-
378- foreach(const QTouchEvent::TouchPoint& touchPoint, ev->touchPoints()) {
379- message.append(
380- QStringLiteral("(id:%1, state:%2, scenePos:(%3,%4)) ")
381- .arg(touchPoint.id())
382- .arg(touchPointStateToString(touchPoint.state()))
383- .arg(touchPoint.scenePos().x())
384- .arg(touchPoint.scenePos().y())
385- );
386- }
387-
388- return message;
389-}
390-
391-QString mouseEventToString(const QMouseEvent *ev)
392-{
393- QString message;
394-
395- switch (ev->type()) {
396- case QEvent::MouseButtonPress:
397- message.append("MouseButtonPress ");
398- break;
399- case QEvent::MouseButtonRelease:
400- message.append("MouseButtonRelease ");
401- break;
402- case QEvent::MouseButtonDblClick:
403- message.append("MouseButtonDblClick ");
404- break;
405- case QEvent::MouseMove:
406- message.append("MouseMove ");
407- break;
408- default:
409- message.append("INVALID_MOUSE_EVENT_TYPE ");
410- }
411-
412- message.append(QStringLiteral("pos(%1, %2)").arg(ev->x()).arg(ev->y()));
413-
414- return message;
415-}
416
417=== removed file 'libs/UbuntuGestures/DebugHelpers.h'
418--- libs/UbuntuGestures/DebugHelpers.h 2014-10-17 11:01:53 +0000
419+++ libs/UbuntuGestures/DebugHelpers.h 1970-01-01 00:00:00 +0000
420@@ -1,31 +0,0 @@
421-/*
422- * Copyright (C) 2014 Canonical, Ltd.
423- *
424- * This program is free software; you can redistribute it and/or modify
425- * it under the terms of the GNU General Public License as published by
426- * the Free Software Foundation; version 3.
427- *
428- * This program is distributed in the hope that it will be useful,
429- * but WITHOUT ANY WARRANTY; without even the implied warranty of
430- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
431- * GNU General Public License for more details.
432- *
433- * You should have received a copy of the GNU General Public License
434- * along with this program. If not, see <http://www.gnu.org/licenses/>.
435- */
436-
437-#ifndef UBUNTUGESTURES_DEBUG_HELPER_H
438-#define UBUNTUGESTURES_DEBUG_HELPER_H
439-
440-#include <QString>
441-
442-#include "UbuntuGesturesGlobal.h"
443-
444-class QMouseEvent;
445-class QTouchEvent;
446-
447-UBUNTUGESTURES_EXPORT QString touchPointStateToString(Qt::TouchPointState state);
448-UBUNTUGESTURES_EXPORT QString touchEventToString(const QTouchEvent *ev);
449-UBUNTUGESTURES_EXPORT QString mouseEventToString(const QMouseEvent *ev);
450-
451-#endif // UBUNTUGESTURES_DEBUG_HELPER_H
452
453=== removed file 'libs/UbuntuGestures/Pool.h'
454--- libs/UbuntuGestures/Pool.h 2015-11-20 15:01:39 +0000
455+++ libs/UbuntuGestures/Pool.h 1970-01-01 00:00:00 +0000
456@@ -1,124 +0,0 @@
457-/*
458- * Copyright (C) 2014 Canonical, Ltd.
459- *
460- * This program is free software; you can redistribute it and/or modify
461- * it under the terms of the GNU General Public License as published by
462- * the Free Software Foundation; version 3.
463- *
464- * This program is distributed in the hope that it will be useful,
465- * but WITHOUT ANY WARRANTY; without even the implied warranty of
466- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
467- * GNU General Public License for more details.
468- *
469- * You should have received a copy of the GNU General Public License
470- * along with this program. If not, see <http://www.gnu.org/licenses/>.
471- */
472-
473-#ifndef UBUNTUGESTURES_POOL_H
474-#define UBUNTUGESTURES_POOL_H
475-
476-#include <QVector>
477-
478-#include "UbuntuGesturesGlobal.h"
479-
480-/*
481- An object pool.
482- Avoids unnecessary creations/initializations and deletions/destructions of items. Useful
483- in a scenario where items are created and destroyed very frequently but the total number
484- of items at any given time remains small. They're stored in a unordered fashion.
485-
486- To be used in Pool, ItemType needs to have the following methods:
487-
488- - ItemType();
489-
490- A constructor that takes no parameters. An object contructed with it must return false if
491- isValid() is called.
492-
493- - bool isValid() const;
494-
495- Returns wheter the object holds a valid , "filled" state or is empty.
496- Used by Pool to check if the slot occupied by this object is actually available.
497-
498- - void reset();
499-
500- Resets the object to its initial, empty, state. After calling this method, isValid() must
501- return false.
502- */
503-template <class ItemType> class Pool
504-{
505-public:
506- Pool() : m_lastUsedIndex(-1) {
507- }
508-
509- class Iterator {
510- public:
511- Iterator() : index(-1), item(nullptr) {}
512- Iterator(int index, ItemType *item)
513- : index(index), item(item) {}
514-
515- ItemType *operator->() const { return item; }
516- ItemType &operator*() const { return *item; }
517- ItemType &value() const { return *item; }
518-
519- operator bool() const { return item != nullptr; }
520-
521- int index;
522- ItemType *item;
523- };
524-
525- ItemType &getEmptySlot() {
526- Q_ASSERT(m_lastUsedIndex < m_slots.size());
527-
528- // Look for an in-between vacancy first
529- for (int i = 0; i < m_lastUsedIndex; ++i) {
530- ItemType &item = m_slots[i];
531- if (!item.isValid()) {
532- return item;
533- }
534- }
535-
536- ++m_lastUsedIndex;
537- if (m_lastUsedIndex >= m_slots.size()) {
538- m_slots.resize(m_lastUsedIndex + 1);
539- }
540-
541- return m_slots[m_lastUsedIndex];
542- }
543-
544- void freeSlot(Iterator &iterator) {
545- m_slots[iterator.index].reset();
546- if (iterator.index == m_lastUsedIndex) {
547- do {
548- --m_lastUsedIndex;
549- } while (m_lastUsedIndex >= 0 && !m_slots.at(m_lastUsedIndex).isValid());
550- }
551- }
552-
553- // Iterates through all valid items (i.e. the occupied slots)
554- // calling the given function, with the option of ending the loop early.
555- //
556- // bool Func(Iterator& item)
557- //
558- // Returning true means it wants to continue the "for" loop, false
559- // terminates the loop.
560- template<typename Func> void forEach(Func func) {
561- Iterator it;
562- for (it.index = 0; it.index <= m_lastUsedIndex; ++it.index) {
563- it.item = &m_slots[it.index];
564- if (!it.item->isValid())
565- continue;
566-
567- if (!func(it))
568- break;
569- }
570- }
571-
572- bool isEmpty() const { return m_lastUsedIndex == -1; }
573-
574-
575-private:
576- QVector<ItemType> m_slots;
577- int m_lastUsedIndex;
578-};
579-
580-#endif // UBUNTUGESTURES_POOL_H
581
582=== removed file 'libs/UbuntuGestures/TimeSource.cpp'
583--- libs/UbuntuGestures/TimeSource.cpp 2015-04-10 21:16:37 +0000
584+++ libs/UbuntuGestures/TimeSource.cpp 1970-01-01 00:00:00 +0000
585@@ -1,49 +0,0 @@
586-/*
587- * Copyright (C) 2013 - Canonical Ltd.
588- *
589- * This program is free software: you can redistribute it and/or modify it
590- * under the terms of the GNU Lesser General Public License, as
591- * published by the Free Software Foundation; either version 2.1 or 3.0
592- * of the License.
593- *
594- * This program is distributed in the hope that it will be useful, but
595- * WITHOUT ANY WARRANTY; without even the implied warranties of
596- * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
597- * PURPOSE. See the applicable version of the GNU Lesser General Public
598- * License for more details.
599- *
600- * You should have received a copy of both the GNU Lesser General Public
601- * License along with this program. If not, see <http://www.gnu.org/licenses/>
602- *
603- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
604- */
605-
606-#include "TimeSource.h"
607-
608-#include <QElapsedTimer>
609-
610-namespace UbuntuGestures {
611-class RealTimeSourcePrivate {
612-public:
613- QElapsedTimer timer;
614-};
615-}
616-
617-using namespace UbuntuGestures;
618-
619-RealTimeSource::RealTimeSource()
620- : UbuntuGestures::TimeSource()
621- , d(new RealTimeSourcePrivate)
622-{
623- d->timer.start();
624-}
625-
626-RealTimeSource::~RealTimeSource()
627-{
628- delete d;
629-}
630-
631-qint64 RealTimeSource::msecsSinceReference()
632-{
633- return d->timer.elapsed();
634-}
635
636=== removed file 'libs/UbuntuGestures/TimeSource.h'
637--- libs/UbuntuGestures/TimeSource.h 2015-04-10 21:16:37 +0000
638+++ libs/UbuntuGestures/TimeSource.h 1970-01-01 00:00:00 +0000
639@@ -1,64 +0,0 @@
640-/*
641- * Copyright (C) 2013,2015 Canonical Ltd.
642- *
643- * This program is free software: you can redistribute it and/or modify it
644- * under the terms of the GNU Lesser General Public License, as
645- * published by the Free Software Foundation; either version 2.1 or 3.0
646- * of the License.
647- *
648- * This program is distributed in the hope that it will be useful, but
649- * WITHOUT ANY WARRANTY; without even the implied warranties of
650- * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
651- * PURPOSE. See the applicable version of the GNU Lesser General Public
652- * License for more details.
653- *
654- * You should have received a copy of both the GNU Lesser General Public
655- * License along with this program. If not, see <http://www.gnu.org/licenses/>
656- *
657- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
658- */
659-
660-#ifndef UBUNTUGESTURES_TIMESOURCE_H
661-#define UBUNTUGESTURES_TIMESOURCE_H
662-
663-#include "UbuntuGesturesGlobal.h"
664-#include <QSharedPointer>
665-
666-namespace UbuntuGestures {
667-/*
668- Interface for a time source.
669- */
670-class UBUNTUGESTURES_EXPORT TimeSource {
671-public:
672- virtual ~TimeSource() {}
673- /* Returns the current time in milliseconds since some reference time in the past. */
674- virtual qint64 msecsSinceReference() = 0;
675-};
676-typedef QSharedPointer<TimeSource> SharedTimeSource;
677-
678-/*
679- Implementation of a time source
680- */
681-class RealTimeSourcePrivate;
682-class UBUNTUGESTURES_EXPORT RealTimeSource : public TimeSource {
683-public:
684- RealTimeSource();
685- virtual ~RealTimeSource();
686- qint64 msecsSinceReference() override;
687-private:
688- RealTimeSourcePrivate *d;
689-};
690-
691-/*
692- A fake time source, useful for tests
693- */
694-class FakeTimeSource : public TimeSource {
695-public:
696- FakeTimeSource() { m_msecsSinceReference = 0; }
697- qint64 msecsSinceReference() override { return m_msecsSinceReference; }
698- qint64 m_msecsSinceReference;
699-};
700-
701-} // namespace UbuntuGestures
702-
703-#endif // UBUNTUGESTURES_TIMESOURCE_H
704
705=== removed file 'libs/UbuntuGestures/Timer.cpp'
706--- libs/UbuntuGestures/Timer.cpp 2015-04-24 13:19:24 +0000
707+++ libs/UbuntuGestures/Timer.cpp 1970-01-01 00:00:00 +0000
708@@ -1,152 +0,0 @@
709-/*
710- * Copyright (C) 2014-2015 Canonical, Ltd.
711- *
712- * This program is free software; you can redistribute it and/or modify
713- * it under the terms of the GNU General Public License as published by
714- * the Free Software Foundation; version 3.
715- *
716- * This program is distributed in the hope that it will be useful,
717- * but WITHOUT ANY WARRANTY; without even the implied warranty of
718- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
719- * GNU General Public License for more details.
720- *
721- * You should have received a copy of the GNU General Public License
722- * along with this program. If not, see <http://www.gnu.org/licenses/>.
723- */
724-
725-#include "Timer.h"
726-
727-namespace UbuntuGestures {
728-
729-Timer::Timer(QObject *parent) : AbstractTimer(parent)
730-{
731- m_timer.setSingleShot(false);
732- connect(&m_timer, &QTimer::timeout, this, &AbstractTimer::timeout);
733-}
734-
735-int Timer::interval() const
736-{
737- return m_timer.interval();
738-}
739-
740-void Timer::setInterval(int msecs)
741-{
742- m_timer.setInterval(msecs);
743-}
744-
745-void Timer::start()
746-{
747- m_timer.start();
748- AbstractTimer::start();
749-}
750-
751-void Timer::stop()
752-{
753- m_timer.stop();
754- AbstractTimer::stop();
755-}
756-
757-bool Timer::isSingleShot() const
758-{
759- return m_timer.isSingleShot();
760-}
761-
762-void Timer::setSingleShot(bool value)
763-{
764- m_timer.setSingleShot(value);
765-}
766-
767-/////////////////////////////////// FakeTimer //////////////////////////////////
768-
769-FakeTimer::FakeTimer(const SharedTimeSource &timeSource, QObject *parent)
770- : UbuntuGestures::AbstractTimer(parent)
771- , m_interval(0)
772- , m_singleShot(false)
773- , m_timeSource(timeSource)
774-{
775-}
776-
777-void FakeTimer::update()
778-{
779- if (!isRunning()) {
780- return;
781- }
782-
783- if (m_nextTimeoutTime <= m_timeSource->msecsSinceReference()) {
784- if (isSingleShot()) {
785- stop();
786- } else {
787- m_nextTimeoutTime += interval();
788- }
789- Q_EMIT timeout();
790- }
791-}
792-
793-void FakeTimer::start()
794-{
795- AbstractTimer::start();
796- m_nextTimeoutTime = m_timeSource->msecsSinceReference() + (qint64)interval();
797-}
798-
799-int FakeTimer::interval() const
800-{
801- return m_interval;
802-}
803-
804-void FakeTimer::setInterval(int msecs)
805-{
806- m_interval = msecs;
807-}
808-
809-bool FakeTimer::isSingleShot() const
810-{
811- return m_singleShot;
812-}
813-
814-void FakeTimer::setSingleShot(bool value)
815-{
816- m_singleShot = value;
817-}
818-
819-/////////////////////////////////// FakeTimerFactory //////////////////////////////////
820-
821-FakeTimerFactory::FakeTimerFactory()
822-{
823- m_timeSource.reset(new FakeTimeSource);
824-}
825-
826-void FakeTimerFactory::updateTime(qint64 targetTime)
827-{
828- qint64 minTimeoutTime = targetTime;
829-
830- for (int i = 0; i < timers.count(); ++i) {
831- FakeTimer *timer = timers[i].data();
832- if (timer && timer->isRunning() && timer->nextTimeoutTime() < minTimeoutTime) {
833- minTimeoutTime = timer->nextTimeoutTime();
834- }
835- }
836-
837- m_timeSource->m_msecsSinceReference = minTimeoutTime;
838-
839- for (int i = 0; i < timers.count(); ++i) {
840- FakeTimer *timer = timers[i].data();
841- if (timer) {
842- timer->update();
843- }
844- }
845-
846- if (m_timeSource->msecsSinceReference() < targetTime) {
847- updateTime(targetTime);
848- }
849-}
850-
851-AbstractTimer *FakeTimerFactory::createTimer(QObject *parent)
852-{
853- FakeTimer *fakeTimer = new FakeTimer(m_timeSource, parent);
854-
855- timers.append(fakeTimer);
856-
857- return fakeTimer;
858-}
859-
860-} // namespace UbuntuGestures
861
862=== removed file 'libs/UbuntuGestures/Timer.h'
863--- libs/UbuntuGestures/Timer.h 2016-03-29 03:47:39 +0000
864+++ libs/UbuntuGestures/Timer.h 1970-01-01 00:00:00 +0000
865@@ -1,122 +0,0 @@
866-/*
867- * Copyright (C) 2014 Canonical, Ltd.
868- *
869- * This program is free software; you can redistribute it and/or modify
870- * it under the terms of the GNU General Public License as published by
871- * the Free Software Foundation; version 3.
872- *
873- * This program is distributed in the hope that it will be useful,
874- * but WITHOUT ANY WARRANTY; without even the implied warranty of
875- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
876- * GNU General Public License for more details.
877- *
878- * You should have received a copy of the GNU General Public License
879- * along with this program. If not, see <http://www.gnu.org/licenses/>.
880- */
881-
882-#ifndef UBUNTUGESTURES_TIMER_H
883-#define UBUNTUGESTURES_TIMER_H
884-
885-#include "UbuntuGesturesGlobal.h"
886-#include "TimeSource.h"
887-
888-#include <QObject>
889-#include <QPointer>
890-#include <QTimer>
891-
892-namespace UbuntuGestures {
893-
894-/* Defines an interface for a Timer. Useful for tests. */
895-class UBUNTUGESTURES_EXPORT AbstractTimer : public QObject
896-{
897- Q_OBJECT
898-public:
899- AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
900- virtual int interval() const = 0;
901- virtual void setInterval(int msecs) = 0;
902- virtual void start() { m_isRunning = true; }
903- virtual void start(int msecs)
904- {
905- setInterval(msecs);
906- start();
907- }
908- virtual void stop() { m_isRunning = false; }
909- bool isRunning() const { return m_isRunning; }
910- virtual bool isSingleShot() const = 0;
911- virtual void setSingleShot(bool value) = 0;
912-Q_SIGNALS:
913- void timeout();
914-private:
915- bool m_isRunning;
916-};
917-
918-/* Essentially a QTimer wrapper */
919-class UBUNTUGESTURES_EXPORT Timer : public AbstractTimer
920-{
921- Q_OBJECT
922-public:
923- Timer(QObject *parent = nullptr);
924-
925- int interval() const override;
926- void setInterval(int msecs) override;
927- void start() override;
928- void stop() override;
929- bool isSingleShot() const override;
930- void setSingleShot(bool value) override;
931-private:
932- QTimer m_timer;
933-};
934-
935-/* For tests */
936-class UBUNTUGESTURES_EXPORT FakeTimer : public AbstractTimer
937-{
938- Q_OBJECT
939-public:
940- FakeTimer(const SharedTimeSource &timeSource, QObject *parent = nullptr);
941-
942- void update();
943- qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
944-
945- int interval() const override;
946- void setInterval(int msecs) override;
947- void start() override;
948- bool isSingleShot() const override;
949- void setSingleShot(bool value) override;
950-private:
951- int m_interval;
952- bool m_singleShot;
953- SharedTimeSource m_timeSource;
954- qint64 m_nextTimeoutTime;
955-};
956-
957-class UBUNTUGESTURES_EXPORT AbstractTimerFactory
958-{
959-public:
960- virtual ~AbstractTimerFactory() {}
961- virtual AbstractTimer *createTimer(QObject *parent = nullptr) = 0;
962-};
963-
964-class UBUNTUGESTURES_EXPORT TimerFactory : public AbstractTimerFactory
965-{
966-public:
967- AbstractTimer *createTimer(QObject *parent = nullptr) override { return new Timer(parent); }
968-};
969-
970-class UBUNTUGESTURES_EXPORT FakeTimerFactory : public AbstractTimerFactory
971-{
972-public:
973- FakeTimerFactory();
974- virtual ~FakeTimerFactory() {}
975-
976- void updateTime(qint64 msecsSinceReference);
977- QSharedPointer<TimeSource> timeSource() { return m_timeSource; }
978-
979- AbstractTimer *createTimer(QObject *parent = nullptr) override;
980- QList<QPointer<FakeTimer>> timers;
981-private:
982- QSharedPointer<FakeTimeSource> m_timeSource;
983-};
984-
985-} // namespace UbuntuGestures
986-
987-#endif // UBUNTUGESTURES_TIMER_H
988
989=== removed file 'libs/UbuntuGestures/TouchOwnershipEvent.cpp'
990--- libs/UbuntuGestures/TouchOwnershipEvent.cpp 2014-10-01 13:20:32 +0000
991+++ libs/UbuntuGestures/TouchOwnershipEvent.cpp 1970-01-01 00:00:00 +0000
992@@ -1,35 +0,0 @@
993-/*
994- * Copyright (C) 2014 Canonical, Ltd.
995- *
996- * This program is free software; you can redistribute it and/or modify
997- * it under the terms of the GNU General Public License as published by
998- * the Free Software Foundation; version 3.
999- *
1000- * This program is distributed in the hope that it will be useful,
1001- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1002- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1003- * GNU General Public License for more details.
1004- *
1005- * You should have received a copy of the GNU General Public License
1006- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1007- */
1008-
1009-#include "TouchOwnershipEvent.h"
1010-
1011-QEvent::Type TouchOwnershipEvent::m_touchOwnershipType = (QEvent::Type)-1;
1012-
1013-TouchOwnershipEvent::TouchOwnershipEvent(int touchId, bool gained)
1014- : QEvent(touchOwnershipEventType())
1015- , m_touchId(touchId)
1016- , m_gained(gained)
1017-{
1018-}
1019-
1020-QEvent::Type TouchOwnershipEvent::touchOwnershipEventType()
1021-{
1022- if (m_touchOwnershipType == (QEvent::Type)-1) {
1023- m_touchOwnershipType = (QEvent::Type)registerEventType();
1024- }
1025-
1026- return m_touchOwnershipType;
1027-}
1028
1029=== removed file 'libs/UbuntuGestures/TouchOwnershipEvent.h'
1030--- libs/UbuntuGestures/TouchOwnershipEvent.h 2014-10-01 13:20:32 +0000
1031+++ libs/UbuntuGestures/TouchOwnershipEvent.h 1970-01-01 00:00:00 +0000
1032@@ -1,50 +0,0 @@
1033-/*
1034- * Copyright (C) 2014 Canonical, Ltd.
1035- *
1036- * This program is free software; you can redistribute it and/or modify
1037- * it under the terms of the GNU General Public License as published by
1038- * the Free Software Foundation; version 3.
1039- *
1040- * This program is distributed in the hope that it will be useful,
1041- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1042- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1043- * GNU General Public License for more details.
1044- *
1045- * You should have received a copy of the GNU General Public License
1046- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1047- */
1048-
1049-#ifndef UBUNTU_TOUCHOWNERSHIPEVENT_H
1050-#define UBUNTU_TOUCHOWNERSHIPEVENT_H
1051-
1052-#include <QEvent>
1053-#include "UbuntuGesturesGlobal.h"
1054-
1055-/*
1056- When an item get an ownership event for a touch it can grab/steal that touch
1057- with a clean conscience.
1058- */
1059-class UBUNTUGESTURES_EXPORT TouchOwnershipEvent : public QEvent
1060-{
1061-public:
1062- TouchOwnershipEvent(int touchId, bool gained);
1063-
1064- static Type touchOwnershipEventType();
1065-
1066- /*
1067- Whether ownership was gained (true) or lost (false)
1068- */
1069- bool gained() const { return m_gained; }
1070-
1071- /*
1072- Id of the touch whose ownership was granted.
1073- */
1074- int touchId() const { return m_touchId; }
1075-
1076-private:
1077- static Type m_touchOwnershipType;
1078- int m_touchId;
1079- bool m_gained;
1080-};
1081-
1082-#endif // UBUNTU_TOUCHOWNERSHIPEVENT_H
1083
1084=== removed file 'libs/UbuntuGestures/TouchRegistry.cpp'
1085--- libs/UbuntuGestures/TouchRegistry.cpp 2016-03-29 03:47:39 +0000
1086+++ libs/UbuntuGestures/TouchRegistry.cpp 1970-01-01 00:00:00 +0000
1087@@ -1,553 +0,0 @@
1088-/*
1089- * Copyright (C) 2014-2015 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-#include "TouchRegistry.h"
1105-
1106-#include <QCoreApplication>
1107-#include <QDebug>
1108-
1109-#pragma GCC diagnostic push
1110-#pragma GCC diagnostic ignored "-pedantic"
1111-#include <private/qquickitem_p.h>
1112-#pragma GCC diagnostic pop
1113-
1114-#include "CandidateInactivityTimer.h"
1115-#include "Timer.h"
1116-#include "TouchOwnershipEvent.h"
1117-#include "UnownedTouchEvent.h"
1118-
1119-#define TOUCHREGISTRY_DEBUG 0
1120-
1121-#if TOUCHREGISTRY_DEBUG
1122- #include "DebugHelpers.h"
1123- #define UG_DEBUG qDebug() << "[TouchRegistry]"
1124-#endif // TOUCHREGISTRY_DEBUG
1125-
1126-using namespace UbuntuGestures;
1127-
1128-TouchRegistry *TouchRegistry::m_instance = nullptr;
1129-
1130-TouchRegistry::TouchRegistry(QObject *parent)
1131- : QObject(parent)
1132- , m_inDispatchLoop(false)
1133- , m_timerFactory(new TimerFactory)
1134-{
1135-}
1136-
1137-TouchRegistry::~TouchRegistry()
1138-{
1139- Q_ASSERT(m_instance != nullptr);
1140- m_instance = nullptr;
1141- delete m_timerFactory;
1142-}
1143-
1144-TouchRegistry *TouchRegistry::instance()
1145-{
1146- if (m_instance == nullptr) {
1147- m_instance = new TouchRegistry;
1148- }
1149- return m_instance;
1150-}
1151-
1152-void TouchRegistry::setTimerFactory(AbstractTimerFactory *timerFactory)
1153-{
1154- delete m_timerFactory;
1155- m_timerFactory = timerFactory;
1156-}
1157-
1158-void TouchRegistry::update(const QTouchEvent *event)
1159-{
1160- #if TOUCHREGISTRY_DEBUG
1161- UG_DEBUG << "got" << qPrintable(touchEventToString(event));
1162- #endif
1163-
1164- const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
1165- for (int i = 0; i < touchPoints.count(); ++i) {
1166- const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
1167- if (touchPoint.state() == Qt::TouchPointPressed) {
1168- TouchInfo &touchInfo = m_touchInfoPool.getEmptySlot();
1169- touchInfo.init(touchPoint.id());
1170- } else if (touchPoint.state() == Qt::TouchPointReleased) {
1171- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(touchPoint.id());
1172-
1173- touchInfo->physicallyEnded = true;
1174- }
1175- }
1176-
1177- deliverTouchUpdatesToUndecidedCandidatesAndWatchers(event);
1178-
1179- freeEndedTouchInfos();
1180-}
1181-
1182-void TouchRegistry::deliverTouchUpdatesToUndecidedCandidatesAndWatchers(const QTouchEvent *event)
1183-{
1184- // TODO: Look into how we could optimize this whole thing.
1185- // Although it's not really a problem as we should have at most two candidates
1186- // for each point and there should not be many active points at any given moment.
1187- // But having three nested for-loops does scare.
1188-
1189- const QList<QTouchEvent::TouchPoint> &updatedTouchPoints = event->touchPoints();
1190-
1191- // Maps an item to the touches in this event he should be informed about.
1192- // E.g.: a QTouchEvent might have three touches but a given item might be interested in only
1193- // one of them. So he will get a UnownedTouchEvent from this QTouchEvent containing only that
1194- // touch point.
1195- QHash<QQuickItem*, QList<int>> touchIdsForItems;
1196-
1197- // Build touchIdsForItems
1198- m_touchInfoPool.forEach([&](Pool<TouchInfo>::Iterator &touchInfo) {
1199- if (touchInfo->isOwned() && touchInfo->watchers.isEmpty())
1200- return true;
1201-
1202- for (int j = 0; j < updatedTouchPoints.count(); ++j) {
1203- if (updatedTouchPoints[j].id() == touchInfo->id) {
1204- if (!touchInfo->isOwned()) {
1205- for (int i = 0; i < touchInfo->candidates.count(); ++i) {
1206- CandidateInfo &candidate = touchInfo->candidates[i];
1207- Q_ASSERT(!candidate.item.isNull());
1208- if (candidate.state != CandidateInfo::InterimOwner) {
1209- touchIdsForItems[candidate.item.data()].append(touchInfo->id);
1210- }
1211- }
1212- }
1213-
1214- const QList<QPointer<QQuickItem>> &watchers = touchInfo->watchers;
1215- for (int i = 0; i < watchers.count(); ++i) {
1216- if (!watchers[i].isNull()) {
1217- touchIdsForItems[watchers[i].data()].append(touchInfo->id);
1218- }
1219- }
1220-
1221- return true;
1222- }
1223- }
1224-
1225- return true;
1226- });
1227-
1228- // TODO: Consider what happens if an item calls any of TouchRegistry's public methods
1229- // from the event handler callback.
1230- m_inDispatchLoop = true;
1231- auto it = touchIdsForItems.constBegin();
1232- while (it != touchIdsForItems.constEnd()) {
1233- QQuickItem *item = it.key();
1234- const QList<int> &touchIds = it.value();
1235- dispatchPointsToItem(event, touchIds, item);
1236- ++it;
1237- };
1238- m_inDispatchLoop = false;
1239-}
1240-
1241-void TouchRegistry::freeEndedTouchInfos()
1242-{
1243- m_touchInfoPool.forEach([&](Pool<TouchInfo>::Iterator &touchInfo) {
1244- if (touchInfo->ended()) {
1245- m_touchInfoPool.freeSlot(touchInfo);
1246- }
1247- return true;
1248- });
1249-}
1250-
1251-/*
1252- Extracts the touches with the given touchIds from event and send them in a
1253- UnownedTouchEvent to the given item
1254- */
1255-void TouchRegistry::dispatchPointsToItem(const QTouchEvent *event, const QList<int> &touchIds,
1256- QQuickItem *item)
1257-{
1258- Qt::TouchPointStates touchPointStates = 0;
1259- QList<QTouchEvent::TouchPoint> touchPoints;
1260-
1261- const QList<QTouchEvent::TouchPoint> &allTouchPoints = event->touchPoints();
1262-
1263- QTransform windowToCandidateTransform = QQuickItemPrivate::get(item)->windowToItemTransform();
1264- QMatrix4x4 windowToCandidateMatrix(windowToCandidateTransform);
1265-
1266- for (int i = 0; i < allTouchPoints.count(); ++i) {
1267- const QTouchEvent::TouchPoint &originalTouchPoint = allTouchPoints[i];
1268- if (touchIds.contains(originalTouchPoint.id())) {
1269- QTouchEvent::TouchPoint touchPoint = originalTouchPoint;
1270-
1271- translateTouchPointFromScreenToWindowCoords(touchPoint);
1272-
1273- // Set the point's local coordinates to that of the item
1274- touchPoint.setRect(windowToCandidateTransform.mapRect(touchPoint.sceneRect()));
1275- touchPoint.setStartPos(windowToCandidateTransform.map(touchPoint.startScenePos()));
1276- touchPoint.setLastPos(windowToCandidateTransform.map(touchPoint.lastScenePos()));
1277- touchPoint.setVelocity(windowToCandidateMatrix.mapVector(touchPoint.velocity()).toVector2D());
1278-
1279- touchPoints.append(touchPoint);
1280- touchPointStates |= touchPoint.state();
1281- }
1282- }
1283-
1284- QTouchEvent *eventForItem = new QTouchEvent(event->type(),
1285- event->device(),
1286- event->modifiers(),
1287- touchPointStates,
1288- touchPoints);
1289- eventForItem->setWindow(event->window());
1290- eventForItem->setTimestamp(event->timestamp());
1291- eventForItem->setTarget(event->target());
1292-
1293- UnownedTouchEvent unownedTouchEvent(eventForItem);
1294-
1295- #if TOUCHREGISTRY_DEBUG
1296- UG_DEBUG << "Sending unowned" << qPrintable(touchEventToString(eventForItem))
1297- << "to" << item;
1298- #endif
1299-
1300- QCoreApplication::sendEvent(item, &unownedTouchEvent);
1301-}
1302-
1303-void TouchRegistry::translateTouchPointFromScreenToWindowCoords(QTouchEvent::TouchPoint &touchPoint)
1304-{
1305- touchPoint.setScreenRect(touchPoint.sceneRect());
1306- touchPoint.setStartScreenPos(touchPoint.startScenePos());
1307- touchPoint.setLastScreenPos(touchPoint.lastScenePos());
1308-
1309- touchPoint.setSceneRect(touchPoint.rect());
1310- touchPoint.setStartScenePos(touchPoint.startPos());
1311- touchPoint.setLastScenePos(touchPoint.lastPos());
1312-}
1313-
1314-bool TouchRegistry::eventFilter(QObject *watched, QEvent *event)
1315-{
1316- Q_UNUSED(watched);
1317-
1318- switch (event->type()) {
1319- case QEvent::TouchBegin:
1320- case QEvent::TouchUpdate:
1321- case QEvent::TouchEnd:
1322- case QEvent::TouchCancel:
1323- update(static_cast<QTouchEvent*>(event));
1324- break;
1325- default:
1326- // do nothing
1327- break;
1328- }
1329-
1330- // Do not filter out the event. i.e., let it be handled further as
1331- // we're just monitoring events
1332- return false;
1333-}
1334-
1335-void TouchRegistry::addCandidateOwnerForTouch(int id, QQuickItem *candidate)
1336-{
1337- #if TOUCHREGISTRY_DEBUG
1338- UG_DEBUG << "addCandidateOwnerForTouch id" << id << "candidate" << candidate;
1339- #endif
1340-
1341- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id);
1342- if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); }
1343-
1344- if (touchInfo->isOwned()) {
1345- qWarning("TouchRegistry: trying to add candidate owner for a touch that's already owned");
1346- return;
1347- }
1348-
1349- // TODO: Check if candidate already exists
1350-
1351- CandidateInfo candidateInfo;
1352- candidateInfo.state = CandidateInfo::Undecided;
1353- candidateInfo.item = candidate;
1354- candidateInfo.inactivityTimer = new CandidateInactivityTimer(id, candidate,
1355- m_timerFactory->createTimer(),
1356- this);
1357- connect(candidateInfo.inactivityTimer, &CandidateInactivityTimer::candidateDefaulted,
1358- this, &TouchRegistry::rejectCandidateOwnerForTouch);
1359-
1360- touchInfo->candidates.append(candidateInfo);
1361-
1362- connect(candidate, &QObject::destroyed, this, [=](){ pruneNullCandidatesForTouch(id); });
1363-}
1364-
1365-void TouchRegistry::addTouchWatcher(int touchId, QQuickItem *watcher)
1366-{
1367- #if TOUCHREGISTRY_DEBUG
1368- UG_DEBUG << "addTouchWatcher id" << touchId << "watcher" << watcher;
1369- #endif
1370-
1371- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(touchId);
1372- if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); }
1373-
1374- // TODO: Check if watcher already exists
1375-
1376- touchInfo->watchers.append(watcher);
1377-}
1378-
1379-void TouchRegistry::removeCandidateOwnerForTouch(int id, QQuickItem *candidate)
1380-{
1381- #if TOUCHREGISTRY_DEBUG
1382- UG_DEBUG << "removeCandidateOwnerForTouch id" << id << "candidate" << candidate;
1383- #endif
1384-
1385- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id);
1386- if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); }
1387-
1388-
1389- // TODO: check if the candidate is in fact the owner of the touch
1390-
1391- bool removed = false;
1392- for (int i = 0; i < touchInfo->candidates.count() && !removed; ++i) {
1393- if (touchInfo->candidates[i].item == candidate) {
1394- removeCandidateOwnerForTouchByIndex(touchInfo, i);
1395- removed = true;
1396- }
1397- }
1398-}
1399-
1400-void TouchRegistry::pruneNullCandidatesForTouch(int touchId)
1401-{
1402- #if TOUCHREGISTRY_DEBUG
1403- UG_DEBUG << "pruneNullCandidatesForTouch touchId" << touchId;
1404- #endif
1405-
1406- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(touchId);
1407- if (!touchInfo) {
1408- // doesn't matter as touch is already gone.
1409- return;
1410- }
1411-
1412- int i = 0;
1413- while (i < touchInfo->candidates.count()) {
1414- if (touchInfo->candidates[i].item.isNull()) {
1415- removeCandidateOwnerForTouchByIndex(touchInfo, i);
1416- } else {
1417- ++i;
1418- }
1419- }
1420-}
1421-
1422-void TouchRegistry::removeCandidateOwnerForTouchByIndex(Pool<TouchRegistry::TouchInfo>::Iterator &touchInfo,
1423- int candidateIndex)
1424-{
1425- // TODO: check if the candidate is in fact the owner of the touch
1426-
1427- Q_ASSERT(candidateIndex < touchInfo->candidates.count());
1428-
1429- if (candidateIndex == 0 && touchInfo->candidates[candidateIndex].state != CandidateInfo::Undecided) {
1430- qCritical("TouchRegistry: touch owner is being removed.");
1431- }
1432- removeCandidateHelper(touchInfo, candidateIndex);
1433-
1434- if (candidateIndex == 0) {
1435- // the top candidate has been removed. if the new top candidate
1436- // wants the touch let him know he's now the owner.
1437- if (touchInfo->isOwned()) {
1438- touchInfo->notifyCandidatesOfOwnershipResolution();
1439- }
1440- }
1441-
1442- if (!m_inDispatchLoop && touchInfo->ended()) {
1443- m_touchInfoPool.freeSlot(touchInfo);
1444- }
1445-}
1446-
1447-void TouchRegistry::requestTouchOwnership(int id, QQuickItem *candidate)
1448-{
1449- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id);
1450- if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); }
1451-
1452- Q_ASSERT(!touchInfo->isOwned());
1453-
1454- int candidateIndex = -1;
1455- for (int i = 0; i < touchInfo->candidates.count(); ++i) {
1456- CandidateInfo &candidateInfo = touchInfo->candidates[i];
1457- if (candidateInfo.item == candidate) {
1458- candidateInfo.state = CandidateInfo::Requested;
1459- delete candidateInfo.inactivityTimer;
1460- candidateInfo.inactivityTimer = nullptr;
1461- candidateIndex = i;
1462- break;
1463- }
1464- }
1465- #if TOUCHREGISTRY_DEBUG
1466- UG_DEBUG << "requestTouchOwnership id " << id << "candidate" << candidate << "index: " << candidateIndex;
1467- #endif
1468-
1469- // add it as a candidate if not present yet
1470- if (candidateIndex < 0) {
1471- CandidateInfo candidateInfo;
1472- candidateInfo.state = CandidateInfo::InterimOwner;
1473- candidateInfo.item = candidate;
1474- candidateInfo.inactivityTimer = nullptr;
1475- touchInfo->candidates.append(candidateInfo);
1476- // it's the last one
1477- candidateIndex = touchInfo->candidates.count() - 1;
1478- connect(candidate, &QObject::destroyed, this, [=](){ pruneNullCandidatesForTouch(id); });
1479- }
1480-
1481- // If it's the top candidate it means it's now the owner. Let
1482- // it know about it.
1483- if (candidateIndex == 0) {
1484- touchInfo->notifyCandidatesOfOwnershipResolution();
1485- }
1486-}
1487-
1488-Pool<TouchRegistry::TouchInfo>::Iterator TouchRegistry::findTouchInfo(int id)
1489-{
1490- Pool<TouchInfo>::Iterator touchInfo;
1491-
1492- m_touchInfoPool.forEach([&](Pool<TouchInfo>::Iterator &someTouchInfo) -> bool {
1493- if (someTouchInfo->id == id) {
1494- touchInfo = someTouchInfo;
1495- return false;
1496- } else {
1497- return true;
1498- }
1499- });
1500-
1501- return touchInfo;
1502-}
1503-
1504-
1505-void TouchRegistry::rejectCandidateOwnerForTouch(int id, QQuickItem *candidate)
1506-{
1507- // NB: It's technically possible that candidate is a dangling pointer at this point.
1508- // Although that would most likely be due to a bug in our code.
1509- // In any case, only dereference it after it's confirmed that it indeed exists.
1510-
1511- #if TOUCHREGISTRY_DEBUG
1512- UG_DEBUG << "rejectCandidateOwnerForTouch id" << id << "candidate" << (void*)candidate;
1513- #endif
1514-
1515- Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id);
1516- if (!touchInfo) {
1517- #if TOUCHREGISTRY_DEBUG
1518- UG_DEBUG << "Failed to find TouchInfo for id" << id;
1519- #endif
1520- return;
1521- }
1522-
1523- int rejectedCandidateIndex = -1;
1524-
1525- // Check if the given candidate is valid and still undecided
1526- for (int i = 0; i < touchInfo->candidates.count() && rejectedCandidateIndex == -1; ++i) {
1527- CandidateInfo &candidateInfo = touchInfo->candidates[i];
1528- if (candidateInfo.item == candidate) {
1529- Q_ASSERT(i > 0 || candidateInfo.state == CandidateInfo::Undecided);
1530- if (i == 0 && candidateInfo.state != CandidateInfo::Undecided) {
1531- qCritical() << "TouchRegistry: Can't reject item (" << (void*)candidate
1532- << ") as it already owns touch" << id;
1533- return;
1534- } else {
1535- // we found the guy and it's all fine.
1536- rejectedCandidateIndex = i;
1537- }
1538- }
1539- }
1540-
1541- // If we reached this point it's because the given candidate exists and is indeed undecided.
1542-
1543- Q_ASSERT(rejectedCandidateIndex >= 0 && rejectedCandidateIndex < touchInfo->candidates.size());
1544-
1545- {
1546- TouchOwnershipEvent lostOwnershipEvent(id, false /*gained*/);
1547- QCoreApplication::sendEvent(candidate, &lostOwnershipEvent);
1548- }
1549-
1550- removeCandidateHelper(touchInfo, rejectedCandidateIndex);
1551-
1552- if (rejectedCandidateIndex == 0) {
1553- // the top candidate has been removed. if the new top candidate
1554- // wants the touch let him know he's now the owner.
1555- if (touchInfo->isOwned()) {
1556- touchInfo->notifyCandidatesOfOwnershipResolution();
1557- }
1558- }
1559-}
1560-
1561-void TouchRegistry::removeCandidateHelper(Pool<TouchInfo>::Iterator &touchInfo, int candidateIndex)
1562-{
1563- {
1564- CandidateInfo &candidateInfo = touchInfo->candidates[candidateIndex];
1565-
1566- delete candidateInfo.inactivityTimer;
1567- candidateInfo.inactivityTimer = nullptr;
1568-
1569- if (candidateInfo.item) {
1570- disconnect(candidateInfo.item.data(), nullptr, this, nullptr);
1571- }
1572- }
1573- touchInfo->candidates.removeAt(candidateIndex);
1574-}
1575-
1576-////////////////////////////////////// TouchRegistry::TouchInfo ////////////////////////////////////
1577-
1578-TouchRegistry::TouchInfo::TouchInfo(int id)
1579-{
1580- init(id);
1581-}
1582-
1583-void TouchRegistry::TouchInfo::reset()
1584-{
1585- id = -1;
1586-
1587- for (int i = 0; i < candidates.count(); ++i) {
1588- CandidateInfo &candidate = candidates[i];
1589- delete candidate.inactivityTimer;
1590- candidate.inactivityTimer.clear(); // shoundn't be needed but anyway...
1591- }
1592-}
1593-
1594-void TouchRegistry::TouchInfo::init(int id)
1595-{
1596- this->id = id;
1597- physicallyEnded = false;
1598- candidates.clear();
1599- watchers.clear();
1600-}
1601-
1602-bool TouchRegistry::TouchInfo::isOwned() const
1603-{
1604- return !candidates.isEmpty() && candidates.first().state != CandidateInfo::Undecided;
1605-}
1606-
1607-bool TouchRegistry::TouchInfo::ended() const
1608-{
1609- Q_ASSERT(isValid());
1610- return physicallyEnded && (isOwned() || candidates.isEmpty());
1611-}
1612-
1613-void TouchRegistry::TouchInfo::notifyCandidatesOfOwnershipResolution()
1614-{
1615- Q_ASSERT(isOwned());
1616-
1617- #if TOUCHREGISTRY_DEBUG
1618- UG_DEBUG << "sending TouchOwnershipEvent(id =" << id
1619- << " gained) to candidate" << candidates[0].item;
1620- #endif
1621-
1622- // need to take a copy of the item list in case
1623- // we call back in to remove candidate during the lost ownership event.
1624- QList<QPointer<QQuickItem>> items;
1625- Q_FOREACH(const CandidateInfo& info, candidates) {
1626- items << info.item;
1627- }
1628-
1629- TouchOwnershipEvent gainedOwnershipEvent(id, true /*gained*/);
1630- QCoreApplication::sendEvent(items[0], &gainedOwnershipEvent);
1631-
1632- TouchOwnershipEvent lostOwnershipEvent(id, false /*gained*/);
1633- for (int i = 1; i < items.count(); ++i) {
1634- #if TOUCHREGISTRY_DEBUG
1635- UG_DEBUG << "sending TouchOwnershipEvent(id =" << id << " lost) to candidate"
1636- << items[i];
1637- #endif
1638- QCoreApplication::sendEvent(items[i], &lostOwnershipEvent);
1639- }
1640-}
1641
1642=== removed file 'libs/UbuntuGestures/TouchRegistry.h'
1643--- libs/UbuntuGestures/TouchRegistry.h 2015-07-20 16:30:40 +0000
1644+++ libs/UbuntuGestures/TouchRegistry.h 1970-01-01 00:00:00 +0000
1645@@ -1,201 +0,0 @@
1646-/*
1647- * Copyright (C) 2014 Canonical, Ltd.
1648- *
1649- * This program is free software; you can redistribute it and/or modify
1650- * it under the terms of the GNU General Public License as published by
1651- * the Free Software Foundation; version 3.
1652- *
1653- * This program is distributed in the hope that it will be useful,
1654- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1655- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1656- * GNU General Public License for more details.
1657- *
1658- * You should have received a copy of the GNU General Public License
1659- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1660- */
1661-
1662-#ifndef UNITY_TOUCHREGISTRY_H
1663-#define UNITY_TOUCHREGISTRY_H
1664-
1665-#include <QQuickItem>
1666-#include <QObject>
1667-#include <QPointer>
1668-#include <QTouchEvent>
1669-#include <QVector>
1670-
1671-#include "UbuntuGesturesGlobal.h"
1672-#include "CandidateInactivityTimer.h"
1673-#include "Timer.h"
1674-#include "Pool.h"
1675-
1676-namespace UbuntuGestures {
1677- class AbstractTimerFactory;
1678-}
1679-
1680-/*
1681- Where the ownership of touches is registered.
1682-
1683- Singleton used for adding a touch point ownership model analogous to the one
1684- described in the XInput 2.2 protocol[1] on top of the existing input dispatch logic in QQuickWindow.
1685-
1686- It provides a much more flexible and powerful way of dealing with pointer ownership than the existing
1687- mechanisms in Qt. Namely QQuickItem::grabTouchPoints, QuickItem::keepTouchGrab,
1688- QQuickItem::setFiltersChildMouseEvents, QQuickItem::ungrabTouchPoints and QQuickItem::touchUngrabEvent.
1689-
1690- Usage:
1691-
1692- 1- An item receives a a new touch point. If he's not sure whether he wants it yet, he calls:
1693- TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, this);
1694- touchEvent->ignore();
1695- Ignoring the event is crucial so that it can be seen by other interested parties, which will
1696- behave similarly.
1697-
1698- 2- That item will then start receiving UnownedTouchEvents for that touch from step 1. Once he's
1699- made a decision he calls either:
1700- TouchRegistry::instance()->requestTouchOwnership(touchId, this);
1701- If he wants the touch point or:
1702- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, this);
1703-  if he does not want it.
1704-
1705- Candidates are put in a priority queue. The first one to call addCandidateOwnerForTouch() will
1706- take precedence over the others for receiving ownership over the touch point (from now on called
1707- simply top-candidate).
1708-
1709- If the top-candidate calls requestTouchOwnership() he will immediately receive a
1710- TouchOwnershipEvent(gained=true) for that touch point. He can then safely call
1711- QQuickItem::grabTouchPoints to actually get the owned touch points. The other candidates
1712- will receive TouchOwnershipEvent(gained=false) and will no longer receive UnownedTouchEvents
1713- for that touch point. They will have to undo whatever action they were performing with that
1714- touch point.
1715-
1716- But if the top-candidate calls removeCandidateOwnerForTouch() instead, he's popped from the
1717- candidacy queue and ownership is given to the new top-most candidate if he has already
1718- made his decision, that is.
1719-
1720- The TouchRegistry cannot enforce the results of this pointer ownership negotiation (i.e.,
1721- who gets to grab the touch points) as that would clash with QQuickWindow's input event
1722- dispatching logic. The candidates have to respect the decision and grab the touch points
1723- themselves.
1724-
1725- If an item wants ownership over touches as soon as he receives the TouchBegin for them, his step 1
1726- would be instead:
1727- TouchRegistry::instance()->requestTouchOwnership(touchId, this);
1728- touchEvent->accept();
1729- He won't get any UnownedTouchEvent for that touch as he is already the interim owner (ie, QQuickWindow
1730- will keep sending touch updates to him already). Eventually he will be notified once ownership has
1731- been granted to him (from TouchRegistry perspective), from which point onwards he could safely assume
1732- other TouchRegistry users wouldn't snatch this touch away from him.
1733-
1734- Items oblivious to TouchRegistry will lose their touch points without warning, just like in plain Qt.
1735-
1736- [1] - http://www.x.org/releases/X11R7.7/doc/inputproto/XI2proto.txt (see multitouch-ownership)
1737- */
1738-class UBUNTUGESTURES_EXPORT TouchRegistry : public QObject
1739-{
1740- Q_OBJECT
1741-public:
1742- virtual ~TouchRegistry();
1743-
1744- // Returns a pointer to the application's TouchRegistry instance.
1745- static TouchRegistry *instance();
1746-
1747- void update(const QTouchEvent *event);
1748-
1749- // Calls update() if the given event is a QTouchEvent
1750- bool eventFilter(QObject *watched, QEvent *event) override;
1751-
1752- // An item that might later request ownership over the given touch point.
1753- // He will be kept informed about that touch point through UnownedTouchEvents
1754- // All candidates must eventually decide whether they want to own the touch point
1755- // or not. That decision is informed through requestTouchOwnership() or
1756- // removeCandidateOwnerForTouch()
1757- void addCandidateOwnerForTouch(int id, QQuickItem *candidate);
1758-
1759- // The same as rejecting ownership of a touch
1760- void removeCandidateOwnerForTouch(int id, QQuickItem *candidate);
1761-
1762- // The candidate object wants to be the owner of the touch with the given id.
1763- // If he's currently the oldest/top-most candidate, he will get an ownership
1764- // event immediately. If not, he will get ownership if (or once) he becomes the
1765- // top-most candidate.
1766- void requestTouchOwnership(int id, QQuickItem *candidate);
1767-
1768- // An item that has no interest (effective or potential) in owning a touch point
1769- // but would nonetheless like to be kept up-to-date on its state.
1770- void addTouchWatcher(int touchId, QQuickItem *watcherItem);
1771-
1772- // Useful for tests, where you should use fake timers
1773- void setTimerFactory(UbuntuGestures::AbstractTimerFactory *timerFactory);
1774-
1775-private Q_SLOTS:
1776- void rejectCandidateOwnerForTouch(int id, QQuickItem *candidate);
1777-
1778-private:
1779- // Only instance() can cronstruct one
1780- TouchRegistry(QObject *parent = nullptr);
1781-
1782- class CandidateInfo {
1783- public:
1784- enum {
1785- // A candidate owner that doesn't yet know for sure whether he wants the touch point
1786- // (gesture recognition is stilll going on)
1787- Undecided = 0,
1788- // A candidate owner that wants the touch but hasn't been granted it yet,
1789- // most likely because there's an undecided candidate with higher priority
1790- Requested = 1,
1791- // An item that is the interim owner of the touch, receiving QTouchEvents of it
1792- // from QQuickWindow. Ie, it's the actual touch owner from Qt's point of view.
1793- // It wants to keep its touch ownership but hasn't been granted it by TouchRegistry
1794- // yet because of undecided candidates higher up.
1795- InterimOwner = 2
1796- } state;
1797- QPointer<QQuickItem> item;
1798- QPointer<UbuntuGestures::CandidateInactivityTimer> inactivityTimer;
1799- };
1800-
1801- class TouchInfo {
1802- public:
1803- TouchInfo() : id(-1) {}
1804- TouchInfo(int id);
1805- bool isValid() const { return id >= 0; }
1806- void reset();
1807- void init(int id);
1808- int id;
1809- bool physicallyEnded;
1810- bool isOwned() const;
1811- bool ended() const;
1812- void notifyCandidatesOfOwnershipResolution();
1813-
1814- // TODO optimize storage (s/QList/Pool)
1815- QList<CandidateInfo> candidates;
1816- QList<QPointer<QQuickItem>> watchers;
1817- };
1818-
1819- void pruneNullCandidatesForTouch(int touchId);
1820- void removeCandidateOwnerForTouchByIndex(Pool<TouchInfo>::Iterator &touchInfo, int candidateIndex);
1821- void removeCandidateHelper(Pool<TouchInfo>::Iterator &touchInfo, int candidateIndex);
1822-
1823- Pool<TouchInfo>::Iterator findTouchInfo(int id);
1824-
1825- void deliverTouchUpdatesToUndecidedCandidatesAndWatchers(const QTouchEvent *event);
1826-
1827- static void translateTouchPointFromScreenToWindowCoords(QTouchEvent::TouchPoint &touchPoint);
1828-
1829- static void dispatchPointsToItem(const QTouchEvent *event, const QList<int> &touchIds,
1830- QQuickItem *item);
1831- void freeEndedTouchInfos();
1832-
1833- Pool<TouchInfo> m_touchInfoPool;
1834-
1835- // the singleton instance
1836- static TouchRegistry *m_instance;
1837-
1838- bool m_inDispatchLoop;
1839-
1840- UbuntuGestures::AbstractTimerFactory *m_timerFactory;
1841-
1842- friend class tst_TouchRegistry;
1843- friend class tst_DirectionalDragArea;
1844-};
1845-
1846-#endif // UNITY_TOUCHREGISTRY_H
1847
1848=== removed file 'libs/UbuntuGestures/UbuntuGesturesGlobal.h'
1849--- libs/UbuntuGestures/UbuntuGesturesGlobal.h 2014-10-01 13:20:32 +0000
1850+++ libs/UbuntuGestures/UbuntuGesturesGlobal.h 1970-01-01 00:00:00 +0000
1851@@ -1,23 +0,0 @@
1852-/*
1853- * Copyright (C) 2014 Canonical, Ltd.
1854- *
1855- * This program is free software; you can redistribute it and/or modify
1856- * it under the terms of the GNU General Public License as published by
1857- * the Free Software Foundation; version 3.
1858- *
1859- * This program is distributed in the hope that it will be useful,
1860- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1861- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1862- * GNU General Public License for more details.
1863- *
1864- * You should have received a copy of the GNU General Public License
1865- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1866- */
1867-
1868-#include <QtCore/QtGlobal>
1869-
1870-#if defined(UBUNTUGESTURES_LIBRARY)
1871-# define UBUNTUGESTURES_EXPORT Q_DECL_EXPORT
1872-#else
1873-# define UBUNTUGESTURES_EXPORT Q_DECL_IMPORT
1874-#endif
1875
1876=== removed file 'libs/UbuntuGestures/UnownedTouchEvent.cpp'
1877--- libs/UbuntuGestures/UnownedTouchEvent.cpp 2014-10-01 13:20:32 +0000
1878+++ libs/UbuntuGestures/UnownedTouchEvent.cpp 1970-01-01 00:00:00 +0000
1879@@ -1,39 +0,0 @@
1880-/*
1881- * Copyright (C) 2014 Canonical, Ltd.
1882- *
1883- * This program is free software; you can redistribute it and/or modify
1884- * it under the terms of the GNU General Public License as published by
1885- * the Free Software Foundation; version 3.
1886- *
1887- * This program is distributed in the hope that it will be useful,
1888- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1889- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1890- * GNU General Public License for more details.
1891- *
1892- * You should have received a copy of the GNU General Public License
1893- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1894- */
1895-
1896-#include "UnownedTouchEvent.h"
1897-
1898-QEvent::Type UnownedTouchEvent::m_unownedTouchEventType = (QEvent::Type)-1;
1899-
1900-UnownedTouchEvent::UnownedTouchEvent(QTouchEvent *touchEvent)
1901- : QEvent(unownedTouchEventType())
1902- , m_touchEvent(touchEvent)
1903-{
1904-}
1905-
1906-QEvent::Type UnownedTouchEvent::unownedTouchEventType()
1907-{
1908- if (m_unownedTouchEventType == (QEvent::Type)-1) {
1909- m_unownedTouchEventType = (QEvent::Type)registerEventType();
1910- }
1911-
1912- return m_unownedTouchEventType;
1913-}
1914-
1915-QTouchEvent *UnownedTouchEvent::touchEvent()
1916-{
1917- return m_touchEvent.data();
1918-}
1919
1920=== removed file 'libs/UbuntuGestures/UnownedTouchEvent.h'
1921--- libs/UbuntuGestures/UnownedTouchEvent.h 2014-10-01 13:20:32 +0000
1922+++ libs/UbuntuGestures/UnownedTouchEvent.h 1970-01-01 00:00:00 +0000
1923@@ -1,45 +0,0 @@
1924-/*
1925- * Copyright (C) 2014 Canonical, Ltd.
1926- *
1927- * This program is free software; you can redistribute it and/or modify
1928- * it under the terms of the GNU General Public License as published by
1929- * the Free Software Foundation; version 3.
1930- *
1931- * This program is distributed in the hope that it will be useful,
1932- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1933- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1934- * GNU General Public License for more details.
1935- *
1936- * You should have received a copy of the GNU General Public License
1937- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1938- */
1939-
1940-#ifndef UBUNTU_UNOWNEDTOUCHEVENT_H
1941-#define UBUNTU_UNOWNEDTOUCHEVENT_H
1942-
1943-#include <QTouchEvent>
1944-#include <QScopedPointer>
1945-#include "UbuntuGesturesGlobal.h"
1946-
1947-/*
1948- A touch event with touch points that do not belong the item receiving it.
1949-
1950- See TouchRegistry::addCandidateOwnerForTouch and TouchRegistry::addTouchWatcher
1951- */
1952-class UBUNTUGESTURES_EXPORT UnownedTouchEvent : public QEvent
1953-{
1954-public:
1955- UnownedTouchEvent(QTouchEvent *touchEvent);
1956- static Type unownedTouchEventType();
1957-
1958- // TODO: It might be cleaner to store the information directly in UnownedTouchEvent
1959- // instead of carrying around a synthesized QTouchEvent. But the latter option
1960- // is very convenient.
1961- QTouchEvent *touchEvent();
1962-
1963-private:
1964- static Type m_unownedTouchEventType;
1965- QScopedPointer<QTouchEvent> m_touchEvent;
1966-};
1967-
1968-#endif // UBUNTU_UNOWNEDTOUCHEVENT_H
1969
1970=== modified file 'plugins/Cursor/CMakeLists.txt'
1971--- plugins/Cursor/CMakeLists.txt 2015-09-29 13:45:05 +0000
1972+++ plugins/Cursor/CMakeLists.txt 2016-06-01 16:58:47 +0000
1973@@ -8,8 +8,9 @@
1974
1975 set(QMLPLUGIN_SRC
1976 plugin.cpp
1977+ CursorImageInfo.cpp
1978+ CursorImageProvider.cpp
1979 MousePointer.cpp
1980- CursorImageProvider.cpp
1981 # We need to run moc on this header
1982 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h
1983 )
1984
1985=== modified file 'plugins/Cursor/Cursor.qml'
1986--- plugins/Cursor/Cursor.qml 2015-12-03 15:00:04 +0000
1987+++ plugins/Cursor/Cursor.qml 2016-06-01 16:58:47 +0000
1988@@ -1,5 +1,5 @@
1989 /*
1990- * Copyright (C) 2015 Canonical, Ltd.
1991+ * Copyright (C) 2015-2016 Canonical, Ltd.
1992 *
1993 * This program is free software; you can redistribute it and/or modify
1994 * it under the terms of the GNU General Public License as published by
1995@@ -15,14 +15,30 @@
1996 */
1997
1998 import QtQuick 2.4
1999-import Cursor 1.0 // For MousePointer
2000+import Cursor 1.1
2001
2002 MousePointer {
2003 id: mousePointer
2004
2005- Image {
2006- x: -mousePointer.hotspotX
2007- y: -mousePointer.hotspotY
2008+ CursorImageInfo {
2009+ id: imageInfo
2010+ themeName: mousePointer.themeName
2011+ cursorName: mousePointer.cursorName
2012+ }
2013+
2014+ AnimatedSprite {
2015+ x: -imageInfo.hotspot.x
2016+ y: -imageInfo.hotspot.y
2017 source: "image://cursor/" + mousePointer.themeName + "/" + mousePointer.cursorName
2018+
2019+ interpolate: false
2020+
2021+ width: imageInfo.frameWidth
2022+ height: imageInfo.frameHeight
2023+
2024+ frameCount: imageInfo.frameCount
2025+ frameDuration: imageInfo.frameDuration
2026+ frameWidth: imageInfo.frameWidth
2027+ frameHeight: imageInfo.frameHeight
2028 }
2029 }
2030
2031=== removed file 'plugins/Cursor/Cursor.qmltypes'
2032--- plugins/Cursor/Cursor.qmltypes 2016-03-11 20:18:12 +0000
2033+++ plugins/Cursor/Cursor.qmltypes 1970-01-01 00:00:00 +0000
2034@@ -1,78 +0,0 @@
2035-import QtQuick.tooling 1.1
2036-
2037-// This file describes the plugin-supplied types contained in the library.
2038-// It is used for QML tooling purposes only.
2039-//
2040-// This file was auto-generated by:
2041-// 'qmlplugindump -notrelocatable Cursor 1.0 plugins'
2042-
2043-Module {
2044- Component {
2045- name: "MirMousePointerInterface"
2046- defaultProperty: "data"
2047- prototype: "QQuickItem"
2048- Property { name: "cursorName"; type: "string"; isReadonly: true }
2049- Property { name: "themeName"; type: "string"; isReadonly: true }
2050- Property { name: "hotspotX"; type: "double"; isReadonly: true }
2051- Property { name: "hotspotY"; type: "double"; isReadonly: true }
2052- Signal {
2053- name: "cursorNameChanged"
2054- Parameter { name: "name"; type: "string" }
2055- }
2056- Signal {
2057- name: "themeNameChanged"
2058- Parameter { name: "name"; type: "string" }
2059- }
2060- Signal {
2061- name: "hotspotXChanged"
2062- Parameter { name: "value"; type: "double" }
2063- }
2064- Signal {
2065- name: "hotspotYChanged"
2066- Parameter { name: "value"; type: "double" }
2067- }
2068- Method {
2069- name: "handleMouseEvent"
2070- Parameter { name: "timestamp"; type: "ulong" }
2071- Parameter { name: "movement"; type: "QPointF" }
2072- Parameter { name: "buttons"; type: "Qt::MouseButtons" }
2073- Parameter { name: "modifiers"; type: "Qt::KeyboardModifiers" }
2074- }
2075- Method {
2076- name: "handleWheelEvent"
2077- Parameter { name: "timestamp"; type: "ulong" }
2078- Parameter { name: "angleDelta"; type: "QPoint" }
2079- Parameter { name: "modifiers"; type: "Qt::KeyboardModifiers" }
2080- }
2081- }
2082- Component {
2083- name: "MousePointer"
2084- defaultProperty: "data"
2085- prototype: "MirMousePointerInterface"
2086- exports: ["Cursor/MousePointer 1.0"]
2087- exportMetaObjectRevisions: [0]
2088- Signal {
2089- name: "pushedLeftBoundary"
2090- Parameter { name: "amount"; type: "double" }
2091- Parameter { name: "buttons"; type: "Qt::MouseButtons" }
2092- }
2093- Signal {
2094- name: "pushedRightBoundary"
2095- Parameter { name: "amount"; type: "double" }
2096- Parameter { name: "buttons"; type: "Qt::MouseButtons" }
2097- }
2098- Method {
2099- name: "handleMouseEvent"
2100- Parameter { name: "timestamp"; type: "ulong" }
2101- Parameter { name: "movement"; type: "QPointF" }
2102- Parameter { name: "buttons"; type: "Qt::MouseButtons" }
2103- Parameter { name: "modifiers"; type: "Qt::KeyboardModifiers" }
2104- }
2105- Method {
2106- name: "handleWheelEvent"
2107- Parameter { name: "timestamp"; type: "ulong" }
2108- Parameter { name: "angleDelta"; type: "QPoint" }
2109- Parameter { name: "modifiers"; type: "Qt::KeyboardModifiers" }
2110- }
2111- }
2112-}
2113
2114=== added file 'plugins/Cursor/CursorImageInfo.cpp'
2115--- plugins/Cursor/CursorImageInfo.cpp 1970-01-01 00:00:00 +0000
2116+++ plugins/Cursor/CursorImageInfo.cpp 2016-06-01 16:58:47 +0000
2117@@ -0,0 +1,106 @@
2118+/*
2119+ * Copyright (C) 2016 Canonical, Ltd.
2120+ *
2121+ * This program is free software; you can redistribute it and/or modify
2122+ * it under the terms of the GNU General Public License as published by
2123+ * the Free Software Foundation; version 3.
2124+ *
2125+ * This program is distributed in the hope that it will be useful,
2126+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2127+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2128+ * GNU General Public License for more details.
2129+ *
2130+ * You should have received a copy of the GNU General Public License
2131+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2132+ */
2133+
2134+#include "CursorImageInfo.h"
2135+
2136+CursorImageInfo::CursorImageInfo(QObject *parent)
2137+ : QObject(parent)
2138+{
2139+ m_updateTimer.setInterval(0);
2140+ m_updateTimer.setSingleShot(true);
2141+ connect(&m_updateTimer, &QTimer::timeout, this, &CursorImageInfo::update);
2142+}
2143+
2144+void CursorImageInfo::setCursorName(const QString &cursorName)
2145+{
2146+ if (cursorName != m_cursorName) {
2147+ m_cursorName = cursorName;
2148+ Q_EMIT cursorNameChanged();
2149+ scheduleUpdate();
2150+ }
2151+}
2152+
2153+void CursorImageInfo::setThemeName(const QString &themeName)
2154+{
2155+ if (m_themeName != themeName) {
2156+ m_themeName = themeName;
2157+ Q_EMIT themeNameChanged();
2158+ scheduleUpdate();
2159+ }
2160+}
2161+
2162+void CursorImageInfo::scheduleUpdate()
2163+{
2164+ if (!m_updateTimer.isActive()) {
2165+ m_updateTimer.start();
2166+ }
2167+}
2168+
2169+void CursorImageInfo::update()
2170+{
2171+ m_cursorImage = CursorImageProvider::instance()->fetchCursor(m_themeName, m_cursorName);
2172+
2173+ Q_EMIT hotspotChanged();
2174+ Q_EMIT frameWidthChanged();
2175+ Q_EMIT frameHeightChanged();
2176+ Q_EMIT frameCountChanged();
2177+ Q_EMIT frameDurationChanged();
2178+}
2179+
2180+QPoint CursorImageInfo::hotspot() const
2181+{
2182+ if (m_cursorImage) {
2183+ return m_cursorImage->hotspot;
2184+ } else {
2185+ return QPoint();
2186+ }
2187+}
2188+
2189+qreal CursorImageInfo::frameWidth() const
2190+{
2191+ if (m_cursorImage) {
2192+ return m_cursorImage->frameWidth;
2193+ } else {
2194+ return 0;
2195+ }
2196+}
2197+
2198+qreal CursorImageInfo::frameHeight() const
2199+{
2200+ if (m_cursorImage) {
2201+ return m_cursorImage->frameHeight;
2202+ } else {
2203+ return 0;
2204+ }
2205+}
2206+
2207+int CursorImageInfo::frameCount() const
2208+{
2209+ if (m_cursorImage) {
2210+ return m_cursorImage->frameCount;
2211+ } else {
2212+ return 0;
2213+ }
2214+}
2215+
2216+int CursorImageInfo::frameDuration() const
2217+{
2218+ if (m_cursorImage) {
2219+ return m_cursorImage->frameDuration;
2220+ } else {
2221+ return 0;
2222+ }
2223+}
2224
2225=== added file 'plugins/Cursor/CursorImageInfo.h'
2226--- plugins/Cursor/CursorImageInfo.h 1970-01-01 00:00:00 +0000
2227+++ plugins/Cursor/CursorImageInfo.h 2016-06-01 16:58:47 +0000
2228@@ -0,0 +1,76 @@
2229+/*
2230+ * Copyright (C) 2016 Canonical, Ltd.
2231+ *
2232+ * This program is free software; you can redistribute it and/or modify
2233+ * it under the terms of the GNU General Public License as published by
2234+ * the Free Software Foundation; version 3.
2235+ *
2236+ * This program is distributed in the hope that it will be useful,
2237+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2238+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2239+ * GNU General Public License for more details.
2240+ *
2241+ * You should have received a copy of the GNU General Public License
2242+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2243+ */
2244+
2245+#ifndef CURSOR_IMAGE_INFO_H
2246+#define CURSOR_IMAGE_INFO_H
2247+
2248+#include "CursorImageProvider.h"
2249+
2250+#include <QObject>
2251+#include <QString>
2252+#include <QTimer>
2253+
2254+class CursorImageInfo : public QObject
2255+{
2256+ Q_OBJECT
2257+
2258+ Q_PROPERTY(QString themeName READ themeName WRITE setThemeName NOTIFY themeNameChanged)
2259+ Q_PROPERTY(QString cursorName READ cursorName WRITE setCursorName NOTIFY cursorNameChanged)
2260+
2261+ Q_PROPERTY(QPoint hotspot READ hotspot NOTIFY hotspotChanged)
2262+ Q_PROPERTY(qreal frameWidth READ frameWidth NOTIFY frameWidthChanged)
2263+ Q_PROPERTY(qreal frameHeight READ frameHeight NOTIFY frameHeightChanged)
2264+ Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
2265+ Q_PROPERTY(int frameDuration READ frameDuration NOTIFY frameDurationChanged)
2266+
2267+public:
2268+ CursorImageInfo(QObject *parent = nullptr);
2269+
2270+ QString themeName() const { return m_themeName; }
2271+ void setThemeName(const QString &);
2272+
2273+ QString cursorName() const { return m_cursorName; }
2274+ void setCursorName(const QString &);
2275+
2276+ QPoint hotspot() const;
2277+ qreal frameWidth() const;
2278+ qreal frameHeight() const;
2279+ int frameCount() const;
2280+ int frameDuration() const;
2281+
2282+Q_SIGNALS:
2283+ void themeNameChanged();
2284+ void cursorNameChanged();
2285+ void hotspotChanged();
2286+ void frameWidthChanged();
2287+ void frameHeightChanged();
2288+ void frameCountChanged();
2289+ void frameDurationChanged();
2290+
2291+private Q_SLOTS:
2292+ void update();
2293+
2294+private:
2295+ void scheduleUpdate();
2296+ QTimer m_updateTimer;
2297+
2298+ QString m_themeName;
2299+ QString m_cursorName;
2300+
2301+ CursorImage *m_cursorImage{nullptr};
2302+};
2303+
2304+#endif // CURSOR_IMAGE_INFO_H
2305
2306=== modified file 'plugins/Cursor/CursorImageProvider.cpp'
2307--- plugins/Cursor/CursorImageProvider.cpp 2015-11-30 17:38:20 +0000
2308+++ plugins/Cursor/CursorImageProvider.cpp 2016-06-01 16:58:47 +0000
2309@@ -1,5 +1,5 @@
2310 /*
2311- * Copyright (C) 2015 Canonical, Ltd.
2312+ * Copyright (C) 2015-2016 Canonical, Ltd.
2313 *
2314 * This program is free software: you can redistribute it and/or modify it under
2315 * the terms of the GNU Lesser General Public License version 3, as published by
2316@@ -46,6 +46,9 @@
2317 qimage.fill(Qt::transparent);
2318 QPainter imagePainter(&qimage);
2319
2320+ frameWidth = qimage.width();
2321+ frameHeight = qimage.height();
2322+
2323 QSvgRenderer *svgRenderer = new QSvgRenderer(QByteArray(svgString));
2324 svgRenderer->render(&imagePainter);
2325 delete svgRenderer;
2326@@ -59,6 +62,8 @@
2327 {
2328 qimage = QImage(1, 1, QImage::Format_ARGB32);
2329 qimage.fill(Qt::transparent);
2330+ frameWidth = qimage.width();
2331+ frameHeight = qimage.height();
2332 }
2333
2334 /////
2335@@ -69,40 +74,74 @@
2336 {
2337 qimage = cursor.pixmap().toImage();
2338 hotspot = cursor.hotSpot();
2339+ frameWidth = qimage.width();
2340+ frameHeight = qimage.height();
2341 }
2342
2343 /////
2344 // XCursorImage
2345
2346 XCursorImage::XCursorImage(const QString &theme, const QString &file)
2347- : xcursorImages(nullptr)
2348 {
2349 // TODO: Consider grid unit value
2350 // Hardcoding to a medium size for now
2351 int preferredCursorHeightPx = 32;
2352
2353- xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme),
2354+ XcursorImages *xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme),
2355 preferredCursorHeightPx);
2356- if (!xcursorImages) {
2357+ if (!xcursorImages || xcursorImages->nimage == 0) {
2358 return;
2359 }
2360
2361- // Just take the first one. It will have multiple images in case of an animated cursor.
2362- // TODO: Support animated cursors
2363- if ( xcursorImages->nimage > 0) {
2364- XcursorImage *xcursorImage = xcursorImages->images[0];
2365-
2366- qimage = QImage((uchar*)xcursorImage->pixels,
2367- xcursorImage->width, xcursorImage->height, QImage::Format_ARGB32);
2368-
2369+ frameCount = xcursorImages->nimage;
2370+
2371+ for (int i = 0; i < xcursorImages->nimage; ++i) {
2372+ XcursorImage *xcursorImage = xcursorImages->images[0];
2373+ if (frameWidth < (int)xcursorImage->width) {
2374+ frameWidth = xcursorImage->width;
2375+ }
2376+ if (frameHeight < (int)xcursorImage->height) {
2377+ frameHeight = xcursorImage->height;
2378+ }
2379+ if (i == 0) {
2380+ frameDuration = (int)xcursorImage->delay;
2381+ } else {
2382+ if (frameDuration != (int)xcursorImage->delay) {
2383+ qWarning().nospace() << "CursorImageProvider: XCursorImage("<<theme<<","<<file<<") has"
2384+ " varying delays in its animation. Animation won't look right.";
2385+ }
2386+ }
2387+ }
2388+
2389+ {
2390+ // Assume that the hotspot position does not animate
2391+ XcursorImage *xcursorImage = xcursorImages->images[0];
2392 hotspot.setX(xcursorImage->xhot);
2393 hotspot.setY(xcursorImage->yhot);
2394 }
2395+
2396+ // Build the sprite as a single row of frames
2397+ qimage = QImage(frameWidth*frameCount, frameHeight, QImage::Format_ARGB32);
2398+ qimage.fill(Qt::transparent);
2399+
2400+ {
2401+ QPainter painter(&qimage);
2402+
2403+ for (int i = 0; i < xcursorImages->nimage; ++i) {
2404+ XcursorImage *xcursorImage = xcursorImages->images[i];
2405+
2406+ auto frameImage = QImage((uchar*)xcursorImage->pixels,
2407+ xcursorImage->width, xcursorImage->height, QImage::Format_ARGB32);
2408+
2409+ painter.drawImage(QPoint(i*frameWidth, 0), frameImage);
2410+ }
2411+ }
2412+
2413+ XcursorImagesDestroy(xcursorImages);
2414 }
2415
2416 XCursorImage::~XCursorImage()
2417 {
2418- XcursorImagesDestroy(xcursorImages);
2419 }
2420
2421 /////
2422@@ -205,16 +244,6 @@
2423 return cursorImage->qimage;
2424 }
2425
2426-QPoint CursorImageProvider::hotspot(const QString &themeName, const QString &cursorName)
2427-{
2428- CursorImage *cursorImage = fetchCursor(themeName, cursorName);
2429- if (cursorImage) {
2430- return cursorImage->hotspot;
2431- } else {
2432- return QPoint(0,0);
2433- }
2434-}
2435-
2436 CursorImage *CursorImageProvider::fetchCursor(const QString &cursorThemeAndName)
2437 {
2438 QString themeName;
2439
2440=== modified file 'plugins/Cursor/CursorImageProvider.h'
2441--- plugins/Cursor/CursorImageProvider.h 2015-11-16 14:27:31 +0000
2442+++ plugins/Cursor/CursorImageProvider.h 2016-06-01 16:58:47 +0000
2443@@ -31,15 +31,23 @@
2444 virtual ~CursorImage() {}
2445
2446 QImage qimage;
2447+
2448+ // TODO: consider if there's a need to animate the hotspot
2449+ // ie, if there's a need to make it an array of points, one for each frame.
2450+ // Maybe no single xcursor (or at least the ones we know of or use)
2451+ // vary its hotspot position through its animation.
2452 QPoint hotspot;
2453+
2454+ int frameWidth{0};
2455+ int frameHeight{0};
2456+ int frameCount{1};
2457+ int frameDuration{40};
2458 };
2459
2460 class XCursorImage : public CursorImage {
2461 public:
2462 XCursorImage(const QString &theme, const QString &file);
2463 virtual ~XCursorImage();
2464-
2465- XcursorImages *xcursorImages;
2466 };
2467
2468 class BuiltInCursorImage : public CursorImage {
2469@@ -68,16 +76,16 @@
2470
2471 QImage requestImage(const QString &cursorName, QSize *size, const QSize &requestedSize) override;
2472
2473- QPoint hotspot(const QString &themeName, const QString &cursorName);
2474+ CursorImage *fetchCursor(const QString &themeName, const QString &cursorName);
2475
2476 void setCustomCursor(const QCursor &customCursor);
2477
2478 private:
2479 CursorImage *fetchCursor(const QString &cursorThemeAndName);
2480- CursorImage *fetchCursor(const QString &themeName, const QString &cursorName);
2481 CursorImage *fetchCursorHelper(const QString &themeName, const QString &cursorName);
2482
2483 // themeName -> (cursorName -> cursorImage)
2484+ // TODO: discard old, unused, cursors
2485 QMap<QString, QMap<QString, CursorImage*> > m_cursors;
2486
2487 QScopedPointer<CursorImage> m_builtInCursorImage;
2488
2489=== modified file 'plugins/Cursor/MousePointer.cpp'
2490--- plugins/Cursor/MousePointer.cpp 2015-12-01 21:54:18 +0000
2491+++ plugins/Cursor/MousePointer.cpp 2016-06-01 16:58:47 +0000
2492@@ -29,10 +29,7 @@
2493 : MirMousePointerInterface(parent)
2494 , m_cursorName(QStringLiteral("left_ptr"))
2495 , m_themeName(QStringLiteral("default"))
2496- , m_hotspotX(0)
2497- , m_hotspotY(0)
2498 {
2499- updateHotspot();
2500 }
2501
2502 void MousePointer::handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
2503@@ -89,8 +86,32 @@
2504
2505 void MousePointer::registerWindow(QWindow *window)
2506 {
2507- if (m_registeredWindow && window != m_registeredWindow) {
2508- auto previousCursor = dynamic_cast<MirPlatformCursor*>(m_registeredWindow->screen()->handle()->cursor());
2509+ if (window == m_registeredWindow) {
2510+ return;
2511+ }
2512+
2513+ if (m_registeredWindow) {
2514+ m_registeredWindow->disconnect(this);
2515+ }
2516+
2517+ m_registeredWindow = window;
2518+
2519+ if (m_registeredWindow) {
2520+ connect(window, &QWindow::screenChanged, this, &MousePointer::registerScreen);
2521+ registerScreen(window->screen());
2522+ } else {
2523+ registerScreen(nullptr);
2524+ }
2525+}
2526+
2527+void MousePointer::registerScreen(QScreen *screen)
2528+{
2529+ if (m_registeredScreen == screen) {
2530+ return;
2531+ }
2532+
2533+ if (m_registeredScreen) {
2534+ auto previousCursor = dynamic_cast<MirPlatformCursor*>(m_registeredScreen->handle()->cursor());
2535 if (previousCursor) {
2536 previousCursor->setMousePointer(nullptr);
2537 } else {
2538@@ -98,10 +119,10 @@
2539 }
2540 }
2541
2542- m_registeredWindow = window;
2543+ m_registeredScreen = screen;
2544
2545- if (m_registeredWindow) {
2546- auto cursor = dynamic_cast<MirPlatformCursor*>(window->screen()->handle()->cursor());
2547+ if (m_registeredScreen) {
2548+ auto cursor = dynamic_cast<MirPlatformCursor*>(m_registeredScreen->handle()->cursor());
2549 if (cursor) {
2550 cursor->setMousePointer(this);
2551 } else {
2552@@ -115,22 +136,6 @@
2553 if (cursorName != m_cursorName) {
2554 m_cursorName = cursorName;
2555 Q_EMIT cursorNameChanged(m_cursorName);
2556- updateHotspot();
2557- }
2558-}
2559-
2560-void MousePointer::updateHotspot()
2561-{
2562- QPoint newHotspot = CursorImageProvider::instance()->hotspot(m_themeName, m_cursorName);
2563-
2564- if (m_hotspotX != newHotspot.x()) {
2565- m_hotspotX = newHotspot.x();
2566- Q_EMIT hotspotXChanged(m_hotspotX);
2567- }
2568-
2569- if (m_hotspotY != newHotspot.y()) {
2570- m_hotspotY = newHotspot.y();
2571- Q_EMIT hotspotYChanged(m_hotspotY);
2572 }
2573 }
2574
2575
2576=== modified file 'plugins/Cursor/MousePointer.h'
2577--- plugins/Cursor/MousePointer.h 2015-12-01 21:40:13 +0000
2578+++ plugins/Cursor/MousePointer.h 2016-06-01 16:58:47 +0000
2579@@ -20,6 +20,7 @@
2580 // Qt
2581 #include <QPointer>
2582 #include <QWindow>
2583+#include <QScreen>
2584
2585 // Unity API
2586 #include <unity/shell/application/MirMousePointerInterface.h>
2587@@ -35,9 +36,6 @@
2588 void setThemeName(const QString &themeName) override;
2589 QString themeName() const override { return m_themeName; }
2590
2591- qreal hotspotX() const override { return m_hotspotX; }
2592- qreal hotspotY() const override { return m_hotspotY; }
2593-
2594 void setCustomCursor(const QCursor &) override;
2595
2596 public Q_SLOTS:
2597@@ -53,15 +51,16 @@
2598 protected:
2599 void itemChange(ItemChange change, const ItemChangeData &value) override;
2600
2601+private Q_SLOTS:
2602+ void registerScreen(QScreen *screen);
2603+
2604 private:
2605 void registerWindow(QWindow *window);
2606- void updateHotspot();
2607
2608 QPointer<QWindow> m_registeredWindow;
2609+ QPointer<QScreen> m_registeredScreen;
2610 QString m_cursorName;
2611 QString m_themeName;
2612- int m_hotspotX;
2613- int m_hotspotY;
2614 };
2615
2616 #endif // MOUSEPOINTER_H
2617
2618=== modified file 'plugins/Cursor/plugin.cpp'
2619--- plugins/Cursor/plugin.cpp 2015-11-20 15:01:39 +0000
2620+++ plugins/Cursor/plugin.cpp 2016-06-01 16:58:47 +0000
2621@@ -1,5 +1,5 @@
2622 /*
2623- * Copyright (C) 2015 Canonical, Ltd.
2624+ * Copyright (C) 2015-2016 Canonical, Ltd.
2625 *
2626 * This program is free software; you can redistribute it and/or modify
2627 * it under the terms of the GNU General Public License as published by
2628@@ -22,13 +22,15 @@
2629 #include "plugin.h"
2630
2631 // local
2632+#include "CursorImageInfo.h"
2633 #include "CursorImageProvider.h"
2634 #include "MousePointer.h"
2635
2636 void CursorPlugin::registerTypes(const char *uri)
2637 {
2638 Q_ASSERT(uri == QLatin1String("Cursor"));
2639- qmlRegisterType<MousePointer>(uri, 1, 0, "MousePointer");
2640+ qmlRegisterType<CursorImageInfo>(uri, 1, 1, "CursorImageInfo");
2641+ qmlRegisterType<MousePointer>(uri, 1, 1, "MousePointer");
2642 }
2643
2644 void CursorPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
2645
2646=== modified file 'plugins/Cursor/qmldir'
2647--- plugins/Cursor/qmldir 2015-09-29 13:45:05 +0000
2648+++ plugins/Cursor/qmldir 2016-06-01 16:58:47 +0000
2649@@ -1,3 +1,3 @@
2650 module Cursor
2651 plugin Cursor-qml
2652-Cursor 1.0 Cursor.qml
2653+Cursor 1.1 Cursor.qml
2654
2655=== modified file 'plugins/Dash/AudioProgressBar.qml'
2656--- plugins/Dash/AudioProgressBar.qml 2016-01-18 22:56:16 +0000
2657+++ plugins/Dash/AudioProgressBar.qml 2016-06-01 16:58:47 +0000
2658@@ -49,6 +49,6 @@
2659 rightMargin: maxWidth - (maxWidth * root.progress)
2660 }
2661 height: units.dp(2)
2662- backgroundColor: UbuntuColors.orange
2663+ backgroundColor: theme.palette.normal.activity
2664 }
2665 }
2666
2667=== modified file 'plugins/Dash/CardCreator.js'
2668--- plugins/Dash/CardCreator.js 2016-05-04 14:09:00 +0000
2669+++ plugins/Dash/CardCreator.js 2016-06-01 16:58:47 +0000
2670@@ -59,14 +59,30 @@
2671 } \n\
2672 }\n';
2673
2674+// %1 is the aspect of the UbuntuShape
2675+var kArtUbuntuShapeCode = 'UbuntuShape { \n\
2676+ anchors.fill: parent; \n\
2677+ source: artImage; \n\
2678+ sourceFillMode: UbuntuShape.PreserveAspectCrop; \n\
2679+ radius: "medium"; \n\
2680+ aspect: %1; \n\
2681+ }';
2682+
2683+var kArtProportionalShapeCode = 'ProportionalShape { \n\
2684+ anchors.fill: parent; \n\
2685+ source: artImage; \n\
2686+ aspect: UbuntuShape.DropShadow; \n\
2687+ }';
2688+
2689 // %1 is used as anchors of artShapeHolder
2690 // %2 is used as image width
2691 // %3 is used as image height
2692-// %4 is whether the image or the Loader with the UbuntuShape/ProportionalShape should be visible
2693+// %4 is whether the image should be visible
2694 // %5 is used as aspect ratio fallback
2695 // %6 is whether the loader should be asynchronous or not
2696-// %7 is injected as code to artImage
2697-// %8 is used as image fallback
2698+// %7 is the shape code we want to use
2699+// %8 is injected as code to artImage
2700+// %9 is used as image fallback
2701 var kArtShapeHolderCode = 'Item { \n\
2702 id: artShapeHolder; \n\
2703 height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
2704@@ -75,7 +91,8 @@
2705 Loader { \n\
2706 id: artShapeLoader; \n\
2707 objectName: "artShapeLoader"; \n\
2708- readonly property string cardArt: cardData && cardData["art"] || %8; \n\
2709+ readonly property string cardArt: cardData && cardData["art"] || %9; \n\
2710+ onCardArtChanged: { if (item) { item.image.source = cardArt; } } \n\
2711 active: cardArt != ""; \n\
2712 asynchronous: %6; \n\
2713 visible: status == Loader.Ready; \n\
2714@@ -84,31 +101,7 @@
2715 objectName: "artShape"; \n\
2716 visible: image.status == Image.Ready; \n\
2717 readonly property alias image: artImage; \n\
2718- Loader { \n\
2719- anchors.fill: parent; \n\
2720- visible: %4; \n\
2721- sourceComponent: root.artShapeStyle === "icon" ? artShapeIconComponent : artShapeShapeComponent; \n\
2722- Component { \n\
2723- id: artShapeShapeComponent; \n\
2724- UbuntuShape { \n\
2725- source: artImage; \n\
2726- sourceFillMode: UbuntuShape.PreserveAspectCrop; \n\
2727- radius: "medium"; \n\
2728- aspect: { \n\
2729- switch (root.artShapeStyle) { \n\
2730- case "inset": return UbuntuShape.Inset; \n\
2731- case "shadow": return UbuntuShape.DropShadow; \n\
2732- default: \n\
2733- case "flat": return UbuntuShape.Flat; \n\
2734- } \n\
2735- } \n\
2736- } \n\
2737- } \n\
2738- Component { \n\
2739- id: artShapeIconComponent; \n\
2740- ProportionalShape { source: artImage; aspect: UbuntuShape.DropShadow; } \n\
2741- } \n\
2742- } \n\
2743+ %7 \n\
2744 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
2745 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : %5; \n\
2746 Component.onCompleted: { updateWidthHeightBindings(); } \n\
2747@@ -127,10 +120,10 @@
2748 objectName: "artImage"; \n\
2749 source: artShapeLoader.cardArt; \n\
2750 asynchronous: %6; \n\
2751- visible: !%4; \n\
2752+ visible: %4; \n\
2753 width: %2; \n\
2754 height: %3; \n\
2755- %7 \n\
2756+ %8 \n\
2757 } \n\
2758 } \n\
2759 } \n\
2760@@ -318,7 +311,7 @@
2761 id: touchdown; \n\
2762 objectName: "touchdown"; \n\
2763 anchors { %1 } \n\
2764- visible: root.artShapeStyle != "shadow" && root.artShapeStyle != "icon" && root.pressed; \n\
2765+ visible: root.pressed; \n\
2766 radius: "medium"; \n\
2767 borderSource: "radius_pressed.sci" \n\
2768 }\n';
2769@@ -412,7 +405,7 @@
2770 return colorString;
2771 }
2772
2773-function cardString(template, components, isCardTool) {
2774+function cardString(template, components, isCardTool, artShapeStyle) {
2775 var code;
2776
2777 var templateInteractive = (template == null ? true : (template["non-interactive"] !== undefined ? !template["non-interactive"] : true)) ? "true" : "false";
2778@@ -420,7 +413,6 @@
2779 code = 'AbstractButton { \n\
2780 id: root; \n\
2781 property var cardData; \n\
2782- property string artShapeStyle: "inset"; \n\
2783 property string backgroundShapeStyle: "inset"; \n\
2784 property real fontScale: 1.0; \n\
2785 property var scopeStyle: null; \n\
2786@@ -519,17 +511,35 @@
2787 var fallbackStatusCode = "";
2788 var fallbackURICode = '""';
2789 if (fallback !== "") {
2790- // fallbackStatusCode has %6 in it because we want to substitute it for fallbackURICode
2791- // which in kArtShapeHolderCode is %8
2792- fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %8;';
2793+ // fallbackStatusCode has %9 in it because we want to substitute it for fallbackURICode
2794+ // which in kArtShapeHolderCode is %9
2795+ fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %9;';
2796 fallbackURICode = 'decodeURI("%1")'.arg(fallback);
2797 }
2798+ var artShapeHolderShapeCode;
2799+ if (!isConciergeMode) {
2800+ if (artShapeStyle === "icon") {
2801+ artShapeHolderShapeCode = kArtProportionalShapeCode;
2802+ } else {
2803+ var artShapeHolderShapeAspect;
2804+ switch (artShapeStyle) {
2805+ case "inset": artShapeHolderShapeAspect = "UbuntuShape.Inset"; break;
2806+ case "shadow": artShapeHolderShapeAspect = "UbuntuShape.DropShadow"; break;
2807+ default:
2808+ case "flat": artShapeHolderShapeAspect = "UbuntuShape.Flat"; break;
2809+ }
2810+ artShapeHolderShapeCode = kArtUbuntuShapeCode.arg(artShapeHolderShapeAspect);
2811+ }
2812+ } else {
2813+ artShapeHolderShapeCode = "";
2814+ }
2815 code += kArtShapeHolderCode.arg(artAnchors)
2816 .arg(widthCode)
2817 .arg(heightCode)
2818- .arg(isConciergeMode ? "false" : "true")
2819+ .arg(isConciergeMode ? "true" : "false")
2820 .arg(aspectRatio)
2821 .arg(asynchronous)
2822+ .arg(artShapeHolderShapeCode)
2823 .arg(fallbackStatusCode)
2824 .arg(fallbackURICode);
2825 } else {
2826@@ -854,6 +864,10 @@
2827 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(summaryColor);
2828 }
2829
2830+// <<<<<<< TREE
2831+// if (artShapeStyle != "shadow" && artShapeStyle != "icon") {
2832+// var touchdownAnchors;
2833+// =======
2834 if (hasSocialActions) {
2835 var socialAnchors;
2836 var socialTopAnchor;
2837@@ -882,15 +896,17 @@
2838 code += kSocialActionsRowCode.arg(socialAnchors).arg(socialColor);
2839 }
2840
2841- var touchdownAnchors;
2842- if (hasBackground) {
2843- touchdownAnchors = 'fill: backgroundLoader';
2844- } else if (touchdownOnArtShape) {
2845- touchdownAnchors = 'fill: artShapeHolder';
2846- } else {
2847- touchdownAnchors = 'fill: root'
2848+ if (artShapeStyle != "shadow" && artShapeStyle != "icon") {
2849+ var touchdownAnchors;
2850+ if (hasBackground) {
2851+ touchdownAnchors = 'fill: backgroundLoader';
2852+ } else if (touchdownOnArtShape) {
2853+ touchdownAnchors = 'fill: artShapeHolder';
2854+ } else {
2855+ touchdownAnchors = 'fill: root'
2856+ }
2857+ code += kTouchdownCode.arg(touchdownAnchors);
2858 }
2859- code += kTouchdownCode.arg(touchdownAnchors);
2860
2861 var implicitHeight = 'implicitHeight: ';
2862 if (hasSocialActions) {
2863@@ -925,13 +941,13 @@
2864 return code;
2865 }
2866
2867-function createCardComponent(parent, template, components, isCardTool, identifier) {
2868+function createCardComponent(parent, template, components, isCardTool, artShapeStyle, identifier) {
2869 var imports = 'import QtQuick 2.4; \n\
2870 import Ubuntu.Components 1.3; \n\
2871 import Ubuntu.Settings.Components 0.1; \n\
2872 import Dash 0.1;\n\
2873 import Utils 0.1;\n';
2874- var card = cardString(template, components, isCardTool);
2875+ var card = cardString(template, components, isCardTool, artShapeStyle);
2876 var code = imports + 'Component {\n' + card + '}\n';
2877
2878 try {
2879
2880=== modified file 'plugins/Dash/CardCreatorCache.qml'
2881--- plugins/Dash/CardCreatorCache.qml 2016-02-16 14:26:58 +0000
2882+++ plugins/Dash/CardCreatorCache.qml 2016-06-01 16:58:47 +0000
2883@@ -23,7 +23,7 @@
2884
2885 property var cache: new Object();
2886
2887- function getCardComponent(template, components, isCardTool) {
2888+ function getCardComponent(template, components, isCardTool, artShapeStyle) {
2889 if (template === undefined || components === undefined)
2890 return undefined;
2891
2892@@ -32,7 +32,7 @@
2893 var allString = tString + cString + isCardTool;
2894 var component = cache[allString];
2895 if (component === undefined) {
2896- component = CardCreator.createCardComponent(root, template, components, isCardTool, allString);
2897+ component = CardCreator.createCardComponent(root, template, components, isCardTool, artShapeStyle, allString);
2898 cache[allString] = component;
2899 }
2900 return component;
2901
2902=== modified file 'plugins/Dash/ScopeStyle.qml'
2903--- plugins/Dash/ScopeStyle.qml 2016-03-29 03:47:39 +0000
2904+++ plugins/Dash/ScopeStyle.qml 2016-06-01 16:58:47 +0000
2905@@ -70,7 +70,7 @@
2906 readonly property url navigationBackground: "navigation-background" in d.headerStyle ? d.headerStyle["navigation-background"] : "color:///#f5f5f5"
2907
2908 /// Color of the primary preview button
2909- readonly property color previewButtonColor: "preview-button-color" in style ? style["preview-button-color"] : UbuntuColors.orange
2910+ readonly property color previewButtonColor: "preview-button-color" in style ? style["preview-button-color"] : theme.palette.normal.positive
2911
2912 //! @cond
2913 property var d: QtObject {
2914
2915=== modified file 'plugins/Dash/listviewwithpageheader.cpp'
2916--- plugins/Dash/listviewwithpageheader.cpp 2016-04-27 14:59:24 +0000
2917+++ plugins/Dash/listviewwithpageheader.cpp 2016-06-01 16:58:47 +0000
2918@@ -97,6 +97,7 @@
2919 #include <qqmlengine.h>
2920 #pragma GCC diagnostic push
2921 #pragma GCC diagnostic ignored "-pedantic"
2922+#include <private/qqmlcontext_p.h>
2923 #include <private/qqmldelegatemodel_p.h>
2924 #include <private/qqmlglobal_p.h>
2925 #include <private/qquickitem_p.h>
2926@@ -168,7 +169,7 @@
2927 m_contentYAnimation->setDuration(200);
2928 m_contentYAnimation->setTargetObject(this);
2929
2930- connect(this, &ListViewWithPageHeader::contentWidthChanged, this, &ListViewWithPageHeader::onContentWidthChanged);
2931+ connect(contentItem(), &QQuickItem::widthChanged, this, &ListViewWithPageHeader::onContentWidthChanged);
2932 connect(this, &ListViewWithPageHeader::contentHeightChanged, this, &ListViewWithPageHeader::onContentHeightChanged);
2933 connect(this, &ListViewWithPageHeader::heightChanged, this, &ListViewWithPageHeader::onHeightChanged);
2934 connect(m_contentYAnimation, &QQuickNumberAnimation::runningChanged, this, &ListViewWithPageHeader::contentYAnimationRunningChanged);
2935@@ -757,8 +758,6 @@
2936
2937 QQmlContext *creationContext = m_sectionDelegate->creationContext();
2938 QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
2939- context->setContextProperty(QStringLiteral("section"), sectionText);
2940- context->setContextProperty(QStringLiteral("delegateIndex"), -1);
2941 QObject *nobj = m_sectionDelegate->beginCreate(context);
2942 if (nobj) {
2943 QQml_setParent_noEvent(context, nobj);
2944@@ -766,6 +765,8 @@
2945 if (!sectionItem) {
2946 delete nobj;
2947 } else {
2948+ sectionItem->setProperty("text", sectionText);
2949+ sectionItem->setProperty("delegateIndex", -1);
2950 sectionItem->setZ(2);
2951 QQml_setParent_noEvent(sectionItem, m_clipItem);
2952 sectionItem->setParentItem(m_clipItem);
2953@@ -801,8 +802,7 @@
2954 if (!item->sectionItem()) {
2955 item->setSectionItem(getSectionItem(sectionText));
2956 } else {
2957- QQmlContext *context = QQmlEngine::contextForObject(item->sectionItem())->parentContext();
2958- context->setContextProperty(QStringLiteral("section"), sectionText);
2959+ item->sectionItem()->setProperty("text", sectionText);
2960 }
2961 } else {
2962 if (item->sectionItem()) {
2963@@ -923,8 +923,7 @@
2964 polish();
2965 }
2966 if (listItem->sectionItem()) {
2967- QQmlContext *context = QQmlEngine::contextForObject(listItem->sectionItem())->parentContext();
2968- context->setContextProperty(QStringLiteral("delegateIndex"), modelIndex);
2969+ listItem->sectionItem()->setProperty("delegateIndex", modelIndex);
2970 }
2971 adjustMinYExtent();
2972 m_contentHeightDirty = true;
2973@@ -948,9 +947,10 @@
2974 return;
2975
2976 item->setParentItem(m_clipItem);
2977+ // FIXME Why do we need the refreshExpressions call?
2978 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
2979- context->setContextProperty(QStringLiteral("ListViewWithPageHeader"), this);
2980- context->setContextProperty(QStringLiteral("heightToClip"), QVariant::fromValue<int>(0));
2981+ QQmlContextPrivate::get(context)->data->refreshExpressions();
2982+ item->setProperty("heightToClip", QVariant::fromValue<int>(0));
2983 if (modelIndex == m_asyncRequestedIndex) {
2984 createItem(modelIndex, false);
2985 refill();
2986@@ -1116,8 +1116,7 @@
2987 for (int i = 0; i < m_visibleItems.count(); ++i) {
2988 ListItem *item = m_visibleItems[i];
2989 if (item->sectionItem()) {
2990- QQmlContext *context = QQmlEngine::contextForObject(item->sectionItem())->parentContext();
2991- context->setContextProperty(QStringLiteral("delegateIndex"), m_firstVisibleIndex + i);
2992+ item->sectionItem()->setProperty("delegateIndex", m_firstVisibleIndex + i);
2993 }
2994 }
2995
2996@@ -1287,8 +1286,7 @@
2997 } else {
2998 // Update the top sticky section header
2999 const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
3000- QQmlContext *context = QQmlEngine::contextForObject(m_topSectionItem)->parentContext();
3001- context->setContextProperty(QStringLiteral("section"), section);
3002+ m_topSectionItem->setProperty("text", section);
3003
3004 QQuickItemPrivate::get(m_topSectionItem)->setCulled(false);
3005 m_topSectionItem->setY(topSectionStickPos);
3006@@ -1300,19 +1298,18 @@
3007 break;
3008 delegateIndex--;
3009 }
3010- context->setContextProperty(QStringLiteral("delegateIndex"), delegateIndex);
3011+ m_topSectionItem->setProperty("delegateIndex", delegateIndex);
3012 if (item->sectionItem()) {
3013 QQuickItemPrivate::get(item->sectionItem())->setCulled(true);
3014 }
3015 }
3016 }
3017 }
3018- QQmlContext *context = QQmlEngine::contextForObject(item->m_item)->parentContext();
3019 const qreal clipFrom = visibleFrom + (!item->sectionItem() && m_topSectionItem && !QQuickItemPrivate::get(m_topSectionItem)->culled ? m_topSectionItem->height() : 0);
3020 if (!cull && pos < clipFrom) {
3021- context->setContextProperty(QStringLiteral("heightToClip"), clipFrom - pos);
3022+ item->m_item->setProperty("heightToClip", clipFrom - pos);
3023 } else {
3024- context->setContextProperty(QStringLiteral("heightToClip"), QVariant::fromValue<int>(0));
3025+ item->m_item->setProperty("heightToClip", QVariant::fromValue<int>(0));
3026 }
3027 // qDebug() << "ListViewWithPageHeader::layout" << item->m_item;
3028 pos += item->height();
3029
3030=== modified file 'plugins/Ubuntu/Gestures/AxisVelocityCalculator.h'
3031--- plugins/Ubuntu/Gestures/AxisVelocityCalculator.h 2014-10-01 13:20:32 +0000
3032+++ plugins/Ubuntu/Gestures/AxisVelocityCalculator.h 2016-06-01 16:58:47 +0000
3033@@ -24,7 +24,7 @@
3034 #include "UbuntuGesturesQmlGlobal.h"
3035 #include <stdint.h>
3036 #include <QtCore/QObject>
3037-#include "TimeSource.h"
3038+#include <TimeSource>
3039
3040 /*
3041 Estimates the current velocity of a finger based on recent movement along an axis
3042
3043=== modified file 'plugins/Ubuntu/Gestures/CMakeLists.txt'
3044--- plugins/Ubuntu/Gestures/CMakeLists.txt 2016-03-29 03:47:39 +0000
3045+++ plugins/Ubuntu/Gestures/CMakeLists.txt 2016-06-01 16:58:47 +0000
3046@@ -4,27 +4,27 @@
3047 set(UbuntuGesturesQml_SOURCES
3048 plugin.cpp
3049 AxisVelocityCalculator.cpp
3050- Damper.cpp
3051 Direction.cpp
3052- DirectionalDragArea.cpp
3053- FloatingFlickable.cpp
3054+ MouseEventGenerator.cpp
3055 PressedOutsideNotifier.cpp
3056 TouchDispatcher.cpp
3057 TouchGate.cpp
3058 TouchGestureArea.cpp
3059 )
3060
3061+pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
3062+
3063 add_definitions(-DUBUNTUGESTURESQML_LIBRARY)
3064
3065 add_library(UbuntuGesturesQml MODULE ${UbuntuGesturesQml_SOURCES})
3066-target_link_libraries(UbuntuGesturesQml UbuntuGestures)
3067+target_link_libraries(UbuntuGesturesQml ${UBUNTUGESTURES_LIBRARIES})
3068
3069 qt5_use_modules(UbuntuGesturesQml Core Quick)
3070
3071 # So that Foo.cpp can #include "Foo.moc"
3072 include_directories(${CMAKE_CURRENT_BINARY_DIR})
3073
3074-include_directories(${CMAKE_SOURCE_DIR}/libs/UbuntuGestures)
3075+include_directories(${UBUNTUGESTURES_INCLUDE_DIRS})
3076
3077 # There's no cmake var for v8 include path :-/ so create one
3078 LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
3079
3080=== removed file 'plugins/Ubuntu/Gestures/Damper.cpp'
3081--- plugins/Ubuntu/Gestures/Damper.cpp 2015-04-10 21:16:37 +0000
3082+++ plugins/Ubuntu/Gestures/Damper.cpp 1970-01-01 00:00:00 +0000
3083@@ -1,24 +0,0 @@
3084-/*
3085- * Copyright (C) 2015 Canonical, Ltd.
3086- *
3087- * This program is free software; you can redistribute it and/or modify
3088- * it under the terms of the GNU General Public License as published by
3089- * the Free Software Foundation; version 3.
3090- *
3091- * This program is distributed in the hope that it will be useful,
3092- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3093- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3094- * GNU General Public License for more details.
3095- *
3096- * You should have received a copy of the GNU General Public License
3097- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3098- */
3099-
3100-#include "Damper.h"
3101-#include <QDebug>
3102-
3103-QDebug operator<<(QDebug dbg, const DampedPointF &p)
3104-{
3105- dbg.nospace() << "(" << p.x() << ", " << p.y() << ")";
3106- return dbg.space();
3107-}
3108
3109=== removed file 'plugins/Ubuntu/Gestures/Damper.h'
3110--- plugins/Ubuntu/Gestures/Damper.h 2015-11-20 15:01:39 +0000
3111+++ plugins/Ubuntu/Gestures/Damper.h 1970-01-01 00:00:00 +0000
3112@@ -1,89 +0,0 @@
3113-/*
3114- * Copyright (C) 2013 Canonical, Ltd.
3115- *
3116- * This program is free software; you can redistribute it and/or modify
3117- * it under the terms of the GNU General Public License as published by
3118- * the Free Software Foundation; version 3.
3119- *
3120- * This program is distributed in the hope that it will be useful,
3121- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3122- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3123- * GNU General Public License for more details.
3124- *
3125- * You should have received a copy of the GNU General Public License
3126- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3127- */
3128-
3129-#ifndef UBUNTU_GESTURES_DAMPER_H
3130-#define UBUNTU_GESTURES_DAMPER_H
3131-
3132-#include <QtCore/QPointF>
3133-
3134-/*
3135- Decreases the oscillations of a value along an axis.
3136- */
3137-template <class Type> class Damper {
3138-public:
3139- Damper() : m_value(0), m_maxDelta(0) { }
3140-
3141- // Maximum delta between the raw value and its dampened counterpart.
3142- void setMaxDelta(Type maxDelta) {
3143- if (maxDelta < 0) qFatal("Damper::maxDelta must be a positive number.");
3144- m_maxDelta = maxDelta;
3145- }
3146- Type maxDelta() const { return m_maxDelta; }
3147-
3148- void reset(Type value) {
3149- m_value = value;
3150- }
3151-
3152- Type update(Type value) {
3153- Type delta = value - m_value;
3154- if (delta > 0 && delta > m_maxDelta) {
3155- m_value += delta - m_maxDelta;
3156- } else if (delta < 0 && delta < -m_maxDelta) {
3157- m_value += delta + m_maxDelta;
3158- }
3159-
3160- return m_value;
3161- }
3162-
3163- Type value() const { return m_value; }
3164-
3165-private:
3166- Type m_value;
3167- Type m_maxDelta;
3168-};
3169-
3170-/*
3171- A point that has its movement dampened.
3172- */
3173-class DampedPointF {
3174-public:
3175- void setMaxDelta(qreal maxDelta) {
3176- m_x.setMaxDelta(maxDelta);
3177- m_y.setMaxDelta(maxDelta);
3178- }
3179-
3180- qreal maxDelta() const { return m_x.maxDelta(); }
3181-
3182- void reset(const QPointF point) {
3183- m_x.reset(point.x());
3184- m_y.reset(point.y());
3185- }
3186-
3187- void update(const QPointF point) {
3188- m_x.update(point.x());
3189- m_y.update(point.y());
3190- }
3191-
3192- qreal x() const { return m_x.value(); }
3193- qreal y() const { return m_y.value(); }
3194-private:
3195- Damper<qreal> m_x;
3196- Damper<qreal> m_y;
3197-};
3198-
3199-QDebug operator<<(QDebug dbg, const DampedPointF &p);
3200-
3201-#endif // UBUNTU_GESTURES_DAMPER_H
3202
3203=== modified file 'plugins/Ubuntu/Gestures/Direction.h'
3204--- plugins/Ubuntu/Gestures/Direction.h 2015-04-17 14:21:43 +0000
3205+++ plugins/Ubuntu/Gestures/Direction.h 2016-06-01 16:58:47 +0000
3206@@ -29,6 +29,7 @@
3207 Q_ENUMS(Type)
3208
3209 public:
3210+ // Make sure it is kept synchronized with SDK UCSwipeArea::Direction
3211 enum Type {
3212 Rightwards, // Along the positive direction of the X axis
3213 Leftwards, // Along the negative direction of the X axis
3214
3215=== removed file 'plugins/Ubuntu/Gestures/DirectionalDragArea.cpp'
3216--- plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 2016-03-29 03:47:39 +0000
3217+++ plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 1970-01-01 00:00:00 +0000
3218@@ -1,932 +0,0 @@
3219-/*
3220- * Copyright (C) 2013-2015 Canonical, Ltd.
3221- *
3222- * This program is free software; you can redistribute it and/or modify
3223- * it under the terms of the GNU General Public License as published by
3224- * the Free Software Foundation; version 3.
3225- *
3226- * This program is distributed in the hope that it will be useful,
3227- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3228- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3229- * GNU General Public License for more details.
3230- *
3231- * You should have received a copy of the GNU General Public License
3232- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3233- */
3234-
3235-#define ACTIVETOUCHESINFO_DEBUG 0
3236-#define DIRECTIONALDRAGAREA_DEBUG 0
3237-
3238-#include "DirectionalDragArea.h"
3239-
3240-#include <QQuickWindow>
3241-#include <QtCore/qmath.h>
3242-#include <QScreen>
3243-#include <QDebug>
3244-
3245-#pragma GCC diagnostic push
3246-#pragma GCC diagnostic ignored "-pedantic"
3247-#include <private/qquickwindow_p.h>
3248-#pragma GCC diagnostic pop
3249-
3250-// local
3251-#include "TouchOwnershipEvent.h"
3252-#include "TouchRegistry.h"
3253-#include "UnownedTouchEvent.h"
3254-
3255-#include "DirectionalDragArea_p.h"
3256-
3257-using namespace UbuntuGestures;
3258-
3259-#if DIRECTIONALDRAGAREA_DEBUG
3260-#define ddaDebug(params) qDebug().nospace() << "[DDA(" << qPrintable(objectName()) << ")] " << params
3261-#include "DebugHelpers.h"
3262-
3263-namespace {
3264-const char *statusToString(DirectionalDragAreaPrivate::Status status)
3265-{
3266- if (status == DirectionalDragAreaPrivate::WaitingForTouch) {
3267- return "WaitingForTouch";
3268- } else if (status == DirectionalDragAreaPrivate::Undecided) {
3269- return "Undecided";
3270- } else {
3271- return "Recognized";
3272- }
3273-}
3274-
3275-} // namespace {
3276-#else // DIRECTIONALDRAGAREA_DEBUG
3277-#define ddaDebug(params) ((void)0)
3278-#endif // DIRECTIONALDRAGAREA_DEBUG
3279-
3280-DirectionalDragArea::DirectionalDragArea(QQuickItem *parent)
3281- : QQuickItem(parent)
3282- , d(new DirectionalDragAreaPrivate(this))
3283-{
3284- d->setRecognitionTimer(new Timer(this));
3285- d->recognitionTimer->setInterval(d->maxTime);
3286- d->recognitionTimer->setSingleShot(true);
3287-
3288- connect(this, &QQuickItem::enabledChanged, d, &DirectionalDragAreaPrivate::giveUpIfDisabledOrInvisible);
3289- connect(this, &QQuickItem::visibleChanged, d, &DirectionalDragAreaPrivate::giveUpIfDisabledOrInvisible);
3290-}
3291-
3292-Direction::Type DirectionalDragArea::direction() const
3293-{
3294- return d->direction;
3295-}
3296-
3297-void DirectionalDragArea::setDirection(Direction::Type direction)
3298-{
3299- if (direction != d->direction) {
3300- d->direction = direction;
3301- Q_EMIT directionChanged(d->direction);
3302- }
3303-}
3304-
3305-void DirectionalDragAreaPrivate::setDistanceThreshold(qreal value)
3306-{
3307- if (distanceThreshold != value) {
3308- distanceThreshold = value;
3309- distanceThresholdSquared = distanceThreshold * distanceThreshold;
3310- }
3311-}
3312-
3313-void DirectionalDragAreaPrivate::setMaxTime(int value)
3314-{
3315- if (maxTime != value) {
3316- maxTime = value;
3317- recognitionTimer->setInterval(maxTime);
3318- }
3319-}
3320-
3321-void DirectionalDragAreaPrivate::setRecognitionTimer(UbuntuGestures::AbstractTimer *timer)
3322-{
3323- int interval = 0;
3324- bool timerWasRunning = false;
3325- bool wasSingleShot = false;
3326-
3327- // can be null when called from the constructor
3328- if (recognitionTimer) {
3329- interval = recognitionTimer->interval();
3330- timerWasRunning = recognitionTimer->isRunning();
3331- if (recognitionTimer->parent() == this) {
3332- delete recognitionTimer;
3333- }
3334- }
3335-
3336- recognitionTimer = timer;
3337- timer->setInterval(interval);
3338- timer->setSingleShot(wasSingleShot);
3339- connect(timer, &UbuntuGestures::AbstractTimer::timeout,
3340- this, &DirectionalDragAreaPrivate::rejectGesture);
3341- if (timerWasRunning) {
3342- recognitionTimer->start();
3343- }
3344-}
3345-
3346-void DirectionalDragAreaPrivate::setTimeSource(const SharedTimeSource &timeSource)
3347-{
3348- this->timeSource = timeSource;
3349- activeTouches.m_timeSource = timeSource;
3350-}
3351-
3352-qreal DirectionalDragArea::distance() const
3353-{
3354- if (Direction::isHorizontal(d->direction)) {
3355- return d->publicPos.x() - d->startPos.x();
3356- } else {
3357- return d->publicPos.y() - d->startPos.y();
3358- }
3359-}
3360-
3361-void DirectionalDragAreaPrivate::updateSceneDistance()
3362-{
3363- QPointF totalMovement = publicScenePos - startScenePos;
3364- sceneDistance = projectOntoDirectionVector(totalMovement);
3365-}
3366-
3367-qreal DirectionalDragArea::sceneDistance() const
3368-{
3369- return d->sceneDistance;
3370-}
3371-
3372-qreal DirectionalDragArea::touchX() const
3373-{
3374- return d->publicPos.x();
3375-}
3376-
3377-qreal DirectionalDragArea::touchY() const
3378-{
3379- return d->publicPos.y();
3380-}
3381-
3382-qreal DirectionalDragArea::touchSceneX() const
3383-{
3384- return d->publicScenePos.x();
3385-}
3386-
3387-qreal DirectionalDragArea::touchSceneY() const
3388-{
3389- return d->publicScenePos.y();
3390-}
3391-
3392-bool DirectionalDragArea::dragging() const
3393-{
3394- return d->status == DirectionalDragAreaPrivate::Recognized;
3395-}
3396-
3397-bool DirectionalDragArea::pressed() const
3398-{
3399- return d->status != DirectionalDragAreaPrivate::WaitingForTouch;
3400-}
3401-
3402-bool DirectionalDragArea::immediateRecognition() const
3403-{
3404- return d->immediateRecognition;
3405-}
3406-
3407-void DirectionalDragArea::setImmediateRecognition(bool enabled)
3408-{
3409- if (d->immediateRecognition != enabled) {
3410- d->immediateRecognition = enabled;
3411- Q_EMIT immediateRecognitionChanged(enabled);
3412- }
3413-}
3414-
3415-bool DirectionalDragArea::monitorOnly() const
3416-{
3417- return d->monitorOnly;
3418-}
3419-
3420-void DirectionalDragArea::setMonitorOnly(bool monitorOnly)
3421-{
3422- if (d->monitorOnly != monitorOnly) {
3423- d->monitorOnly = monitorOnly;
3424-
3425- if (monitorOnly && d->status == DirectionalDragAreaPrivate::Undecided) {
3426- TouchRegistry::instance()->removeCandidateOwnerForTouch(d->touchId, this);
3427- // We still wanna know when it ends for keeping the composition time window up-to-date
3428- TouchRegistry::instance()->addTouchWatcher(d->touchId, this);
3429- }
3430-
3431- Q_EMIT monitorOnlyChanged(monitorOnly);
3432- }
3433-}
3434-
3435-void DirectionalDragArea::removeTimeConstraints()
3436-{
3437- d->setMaxTime(60 * 60 * 1000);
3438- d->compositionTime = 0;
3439- ddaDebug("removed time constraints");
3440-}
3441-
3442-bool DirectionalDragArea::event(QEvent *event)
3443-{
3444- if (event->type() == TouchOwnershipEvent::touchOwnershipEventType()) {
3445- d->touchOwnershipEvent(static_cast<TouchOwnershipEvent *>(event));
3446- return true;
3447- } else if (event->type() == UnownedTouchEvent::unownedTouchEventType()) {
3448- d->unownedTouchEvent(static_cast<UnownedTouchEvent *>(event));
3449- return true;
3450- } else {
3451- return QQuickItem::event(event);
3452- }
3453-}
3454-
3455-void DirectionalDragAreaPrivate::touchOwnershipEvent(TouchOwnershipEvent *event)
3456-{
3457- if (event->gained()) {
3458- QVector<int> ids;
3459- ids.append(event->touchId());
3460- ddaDebug("grabbing touch");
3461- q->grabTouchPoints(ids);
3462-
3463- // Work around for Qt bug. If we grab a touch that is being used for mouse pointer
3464- // emulation it will cause the emulation logic to go nuts.
3465- // Thus we have to also grab the mouse in this case.
3466- //
3467- // The fix for this bug has landed in Qt 5.4 (https://codereview.qt-project.org/96887)
3468- // TODO: Remove this workaround once we start using Qt 5.4
3469- if (q->window()) {
3470- QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(q->window());
3471- if (windowPrivate->touchMouseId == event->touchId() && q->window()->mouseGrabberItem()) {
3472- ddaDebug("removing mouse grabber");
3473- q->window()->mouseGrabberItem()->ungrabMouse();
3474- }
3475- }
3476- } else {
3477- // We still wanna know when it ends for keeping the composition time window up-to-date
3478- TouchRegistry::instance()->addTouchWatcher(touchId, q);
3479-
3480- setStatus(WaitingForTouch);
3481- }
3482-}
3483-
3484-void DirectionalDragAreaPrivate::unownedTouchEvent(UnownedTouchEvent *unownedTouchEvent)
3485-{
3486- QTouchEvent *event = unownedTouchEvent->touchEvent();
3487-
3488- Q_ASSERT(!event->touchPointStates().testFlag(Qt::TouchPointPressed));
3489-
3490- ddaDebug("Unowned " << timeSource->msecsSinceReference() << " " << qPrintable(touchEventToString(event)));
3491-
3492- switch (status) {
3493- case WaitingForTouch:
3494- // do nothing
3495- break;
3496- case Undecided:
3497- Q_ASSERT(q->isEnabled() && q->isVisible());
3498- unownedTouchEvent_undecided(unownedTouchEvent);
3499- break;
3500- default: // Recognized:
3501- if (monitorOnly) {
3502- // Treat unowned event as if we owned it, but we are really just watching it
3503- touchEvent_recognized(event);
3504- }
3505- break;
3506- }
3507-
3508- activeTouches.update(event);
3509-}
3510-
3511-void DirectionalDragAreaPrivate::unownedTouchEvent_undecided(UnownedTouchEvent *unownedTouchEvent)
3512-{
3513- const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(unownedTouchEvent->touchEvent());
3514- if (!touchPoint) {
3515- qCritical() << "DirectionalDragArea[status=Undecided]: touch " << touchId
3516- << "missing from UnownedTouchEvent without first reaching state Qt::TouchPointReleased. "
3517- "Considering it as released.";
3518-
3519- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3520- setStatus(WaitingForTouch);
3521- return;
3522- }
3523-
3524- const QPointF &touchScenePos = touchPoint->scenePos();
3525-
3526- if (touchPoint->state() == Qt::TouchPointReleased) {
3527- // touch has ended before recognition concluded
3528- ddaDebug("Touch has ended before recognition concluded");
3529- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3530- setStatus(WaitingForTouch);
3531- return;
3532- }
3533-
3534- previousDampedScenePos.setX(dampedScenePos.x());
3535- previousDampedScenePos.setY(dampedScenePos.y());
3536- dampedScenePos.update(touchScenePos);
3537-
3538- if (!movingInRightDirection()) {
3539- ddaDebug("Rejecting gesture because touch point is moving in the wrong direction.");
3540- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3541- // We still wanna know when it ends for keeping the composition time window up-to-date
3542- TouchRegistry::instance()->addTouchWatcher(touchId, q);
3543- setStatus(WaitingForTouch);
3544- return;
3545- }
3546-
3547- if (isWithinTouchCompositionWindow()) {
3548- // There's still time for some new touch to appear and ruin our party as it would be combined
3549- // with our touchId one and therefore deny the possibility of a single-finger gesture.
3550- ddaDebug("Sill within composition window. Let's wait more.");
3551- return;
3552- }
3553-
3554- if (movedFarEnoughAlongGestureAxis()) {
3555- if (!monitorOnly) {
3556- TouchRegistry::instance()->requestTouchOwnership(touchId, q);
3557- }
3558- setStatus(Recognized);
3559- setPublicPos(touchPoint->pos());
3560- setPublicScenePos(touchScenePos);
3561- } else if (isPastMaxDistance()) {
3562- ddaDebug("Rejecting gesture because it went farther than maxDistance without getting recognized.");
3563- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3564- // We still wanna know when it ends for keeping the composition time window up-to-date
3565- TouchRegistry::instance()->addTouchWatcher(touchId, q);
3566- setStatus(WaitingForTouch);
3567- } else {
3568- ddaDebug("Didn't move far enough yet. Let's wait more.");
3569- }
3570-}
3571-
3572-void DirectionalDragArea::touchEvent(QTouchEvent *event)
3573-{
3574- // TODO: Consider when more than one touch starts in the same event (although it's not possible
3575- // with Mir's android-input). Have to track them all. Consider it a plus/bonus.
3576-
3577- ddaDebug(d->timeSource->msecsSinceReference() << " " << qPrintable(touchEventToString(event)));
3578-
3579- if (!isEnabled() || !isVisible()) {
3580- QQuickItem::touchEvent(event);
3581- return;
3582- }
3583-
3584- switch (d->status) {
3585- case DirectionalDragAreaPrivate::WaitingForTouch:
3586- d->touchEvent_absent(event);
3587- break;
3588- case DirectionalDragAreaPrivate::Undecided:
3589- d->touchEvent_undecided(event);
3590- break;
3591- default: // Recognized:
3592- d->touchEvent_recognized(event);
3593- break;
3594- }
3595-
3596- d->activeTouches.update(event);
3597-}
3598-
3599-void DirectionalDragAreaPrivate::touchEvent_absent(QTouchEvent *event)
3600-{
3601- // TODO: accept/reject is for the whole event, not per touch id. See how that affects us.
3602-
3603- if (!event->touchPointStates().testFlag(Qt::TouchPointPressed)) {
3604- // Nothing to see here. No touch starting in this event.
3605- return;
3606- }
3607-
3608- // to be proven wrong, if that's the case
3609- bool allGood = true;
3610-
3611- if (isWithinTouchCompositionWindow()) {
3612- // too close to the last touch start. So we consider them as starting roughly at the same time.
3613- // Can't be a single-touch gesture.
3614- ddaDebug("A new touch point came in but we're still within time composition window. Ignoring it.");
3615- allGood = false;
3616- }
3617-
3618- const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
3619-
3620- const QTouchEvent::TouchPoint *newTouchPoint = nullptr;
3621- for (int i = 0; i < touchPoints.count() && allGood; ++i) {
3622- const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
3623- if (touchPoint.state() == Qt::TouchPointPressed) {
3624- if (newTouchPoint) {
3625- // more than one touch starting in this QTouchEvent. Can't be a single-touch gesture
3626- allGood = false;
3627- } else {
3628- // that's our candidate
3629- newTouchPoint = &touchPoint;
3630- }
3631- }
3632- }
3633-
3634- if (allGood) {
3635- allGood = sanityCheckRecognitionProperties();
3636- if (!allGood) {
3637- qWarning("DirectionalDragArea: recognition properties are wrongly set. Gesture recognition"
3638- " is impossible");
3639- }
3640- }
3641-
3642- if (allGood) {
3643- Q_ASSERT(newTouchPoint);
3644-
3645- startPos = newTouchPoint->pos();
3646- startScenePos = newTouchPoint->scenePos();
3647- touchId = newTouchPoint->id();
3648- dampedScenePos.reset(startScenePos);
3649- setPublicPos(startPos);
3650-
3651- setPublicScenePos(startScenePos);
3652- updateSceneDirectionVector();
3653-
3654- if (recognitionIsDisabled()) {
3655- // Behave like a dumb TouchArea
3656- ddaDebug("Gesture recognition is disabled. Requesting touch ownership immediately.");
3657- setStatus(Recognized);
3658- if (monitorOnly) {
3659- watchPressedTouchPoints(touchPoints);
3660- event->ignore();
3661- } else {
3662- TouchRegistry::instance()->requestTouchOwnership(touchId, q);
3663- event->accept();
3664- }
3665- } else {
3666- // just monitor the touch points for now.
3667- if (monitorOnly) {
3668- watchPressedTouchPoints(touchPoints);
3669- } else {
3670- TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, q);
3671- }
3672-
3673- setStatus(Undecided);
3674- // Let the item below have it. We will monitor it and grab it later if a gesture
3675- // gets recognized.
3676- event->ignore();
3677- }
3678- } else {
3679- watchPressedTouchPoints(touchPoints);
3680- event->ignore();
3681- }
3682-}
3683-
3684-void DirectionalDragAreaPrivate::touchEvent_undecided(QTouchEvent *event)
3685-{
3686- Q_ASSERT(fetchTargetTouchPoint(event) == nullptr);
3687-
3688- // We're not interested in new touch points. We already have our candidate (touchId).
3689- // But we do want to know when those new touches end for keeping the composition time
3690- // window up-to-date
3691- event->ignore();
3692- watchPressedTouchPoints(event->touchPoints());
3693-
3694- if (event->touchPointStates().testFlag(Qt::TouchPointPressed) && isWithinTouchCompositionWindow()) {
3695- // multi-finger drags are not accepted
3696- ddaDebug("Multi-finger drags are not accepted");
3697-
3698- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3699- // We still wanna know when it ends for keeping the composition time window up-to-date
3700- TouchRegistry::instance()->addTouchWatcher(touchId, q);
3701-
3702- setStatus(WaitingForTouch);
3703- }
3704-}
3705-
3706-void DirectionalDragAreaPrivate::touchEvent_recognized(QTouchEvent *event)
3707-{
3708- const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
3709-
3710- if (!touchPoint) {
3711- qCritical() << "DirectionalDragArea[status=Recognized]: touch " << touchId
3712- << "missing from QTouchEvent without first reaching state Qt::TouchPointReleased. "
3713- "Considering it as released.";
3714- setStatus(WaitingForTouch);
3715- } else {
3716- setPublicPos(touchPoint->pos());
3717- setPublicScenePos(touchPoint->scenePos());
3718-
3719- if (touchPoint->state() == Qt::TouchPointReleased) {
3720- setStatus(WaitingForTouch);
3721- }
3722- }
3723-}
3724-
3725-void DirectionalDragAreaPrivate::watchPressedTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints)
3726-{
3727- for (int i = 0; i < touchPoints.count(); ++i) {
3728- const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
3729- if (touchPoint.state() == Qt::TouchPointPressed) {
3730- TouchRegistry::instance()->addTouchWatcher(touchPoint.id(), q);
3731- }
3732- }
3733-}
3734-
3735-bool DirectionalDragAreaPrivate::recognitionIsDisabled() const
3736-{
3737- return immediateRecognition || (distanceThreshold <= 0 && compositionTime <= 0);
3738-}
3739-
3740-bool DirectionalDragAreaPrivate::sanityCheckRecognitionProperties()
3741-{
3742- return recognitionIsDisabled()
3743- || (distanceThreshold < maxDistance && compositionTime < maxTime);
3744-}
3745-
3746-const QTouchEvent::TouchPoint *DirectionalDragAreaPrivate::fetchTargetTouchPoint(QTouchEvent *event)
3747-{
3748- const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
3749- const QTouchEvent::TouchPoint *touchPoint = 0;
3750- for (int i = 0; i < touchPoints.size(); ++i) {
3751- if (touchPoints.at(i).id() == touchId) {
3752- touchPoint = &touchPoints.at(i);
3753- break;
3754- }
3755- }
3756- return touchPoint;
3757-}
3758-
3759-bool DirectionalDragAreaPrivate::movingInRightDirection() const
3760-{
3761- if (direction == Direction::Horizontal || direction == Direction::Vertical) {
3762- return true;
3763- } else {
3764- QPointF movementVector(dampedScenePos.x() - previousDampedScenePos.x(),
3765- dampedScenePos.y() - previousDampedScenePos.y());
3766-
3767- qreal scalarProjection = projectOntoDirectionVector(movementVector);
3768-
3769- return scalarProjection >= 0.;
3770- }
3771-}
3772-
3773-bool DirectionalDragAreaPrivate::movedFarEnoughAlongGestureAxis() const
3774-{
3775- if (distanceThreshold <= 0.) {
3776- // distance threshold check is disabled
3777- return true;
3778- } else {
3779- QPointF totalMovement(dampedScenePos.x() - startScenePos.x(),
3780- dampedScenePos.y() - startScenePos.y());
3781-
3782- qreal scalarProjection = projectOntoDirectionVector(totalMovement);
3783-
3784- ddaDebug(" movedFarEnoughAlongGestureAxis: scalarProjection=" << scalarProjection
3785- << ", distanceThreshold=" << distanceThreshold);
3786-
3787- if (direction == Direction::Horizontal || direction == Direction::Vertical) {
3788- return qAbs(scalarProjection) > distanceThreshold;
3789- } else {
3790- return scalarProjection > distanceThreshold;
3791- }
3792- }
3793-}
3794-
3795-bool DirectionalDragAreaPrivate::isPastMaxDistance() const
3796-{
3797- QPointF totalMovement(dampedScenePos.x() - startScenePos.x(),
3798- dampedScenePos.y() - startScenePos.y());
3799-
3800- qreal squaredDistance = totalMovement.x()*totalMovement.x() + totalMovement.y()*totalMovement.y();
3801- return squaredDistance > maxDistance*maxDistance;
3802-}
3803-
3804-void DirectionalDragAreaPrivate::giveUpIfDisabledOrInvisible()
3805-{
3806- if (!q->isEnabled() || !q->isVisible()) {
3807- if (status == Undecided) {
3808- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3809- // We still wanna know when it ends for keeping the composition time window up-to-date
3810- TouchRegistry::instance()->addTouchWatcher(touchId, q);
3811- }
3812-
3813- if (status != WaitingForTouch) {
3814- ddaDebug("Resetting status because got disabled or made invisible");
3815- setStatus(WaitingForTouch);
3816- }
3817- }
3818-}
3819-
3820-void DirectionalDragAreaPrivate::rejectGesture()
3821-{
3822- if (status == Undecided) {
3823- ddaDebug("Rejecting gesture because it's taking too long to drag beyond the threshold.");
3824-
3825- TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, q);
3826- // We still wanna know when it ends for keeping the composition time window up-to-date
3827- TouchRegistry::instance()->addTouchWatcher(touchId, q);
3828-
3829- setStatus(WaitingForTouch);
3830- }
3831-}
3832-
3833-void DirectionalDragAreaPrivate::setStatus(Status newStatus)
3834-{
3835- if (newStatus == status)
3836- return;
3837-
3838- Status oldStatus = status;
3839-
3840- if (oldStatus == Undecided) {
3841- recognitionTimer->stop();
3842- }
3843-
3844- status = newStatus;
3845- Q_EMIT statusChanged(status);
3846-
3847- ddaDebug(statusToString(oldStatus) << " -> " << statusToString(newStatus));
3848-
3849- switch (newStatus) {
3850- case WaitingForTouch:
3851- if (oldStatus == Recognized) {
3852- Q_EMIT q->draggingChanged(false);
3853- }
3854- Q_EMIT q->pressedChanged(false);
3855- break;
3856- case Undecided:
3857- recognitionTimer->start();
3858- Q_EMIT q->pressedChanged(true);
3859- break;
3860- case Recognized:
3861- if (oldStatus == WaitingForTouch) { // for immediate recognition
3862- Q_EMIT q->pressedChanged(true);
3863- }
3864- Q_EMIT q->draggingChanged(true);
3865- break;
3866- default:
3867- // no-op
3868- break;
3869- }
3870-}
3871-
3872-void DirectionalDragAreaPrivate::setPublicPos(const QPointF point)
3873-{
3874- bool xChanged = publicPos.x() != point.x();
3875- bool yChanged = publicPos.y() != point.y();
3876-
3877- // Public position should not get updated while the gesture is still being recognized
3878- // (ie, Undecided status).
3879- Q_ASSERT(status == WaitingForTouch || status == Recognized);
3880-
3881- if (status == Recognized && !recognitionIsDisabled()) {
3882- // When the gesture finally gets recognized, the finger will likely be
3883- // reasonably far from the edge. If we made the contentX immediately
3884- // follow the finger position it would be visually unpleasant as it
3885- // would appear right next to the user's finger out of nowhere (ie,
3886- // it would jump). Instead, we make contentX go towards the user's
3887- // finger in several steps. ie., in an animated way.
3888- QPointF delta = point - publicPos;
3889- // the trick is not to go all the way (1.0) as it would cause a sudden jump
3890- publicPos.rx() += 0.4 * delta.x();
3891- publicPos.ry() += 0.4 * delta.y();
3892- } else {
3893- // no smoothing when initializing or if gesture recognition was immediate as there will
3894- // be no jump.
3895- publicPos = point;
3896- }
3897-
3898- if (xChanged) {
3899- Q_EMIT q->touchXChanged(publicPos.x());
3900- if (Direction::isHorizontal(direction))
3901- Q_EMIT q->distanceChanged(q->distance());
3902- }
3903-
3904- if (yChanged) {
3905- Q_EMIT q->touchYChanged(publicPos.y());
3906- if (Direction::isVertical(direction))
3907- Q_EMIT q->distanceChanged(q->distance());
3908- }
3909-}
3910-
3911-void DirectionalDragAreaPrivate::setPublicScenePos(const QPointF point)
3912-{
3913- bool xChanged = publicScenePos.x() != point.x();
3914- bool yChanged = publicScenePos.y() != point.y();
3915-
3916- if (!xChanged && !yChanged)
3917- return;
3918-
3919- // Public position should not get updated while the gesture is still being recognized
3920- // (ie, Undecided status).
3921- Q_ASSERT(status == WaitingForTouch || status == Recognized);
3922-
3923- qreal oldSceneDistance = sceneDistance;
3924-
3925- if (status == Recognized && !recognitionIsDisabled()) {
3926- // When the gesture finally gets recognized, the finger will likely be
3927- // reasonably far from the edge. If we made the contentX immediately
3928- // follow the finger position it would be visually unpleasant as it
3929- // would appear right next to the user's finger out of nowhere (ie,
3930- // it would jump). Instead, we make contentX go towards the user's
3931- // finger in several steps. ie., in an animated way.
3932- QPointF delta = point - publicScenePos;
3933- // the trick is not to go all the way (1.0) as it would cause a sudden jump
3934- publicScenePos.rx() += 0.4 * delta.x();
3935- publicScenePos.ry() += 0.4 * delta.y();
3936- } else {
3937- // no smoothing when initializing or if gesture recognition was immediate as there will
3938- // be no jump.
3939- publicScenePos = point;
3940- }
3941-
3942- updateSceneDistance();
3943-
3944- if (oldSceneDistance != sceneDistance) {
3945- Q_EMIT q->sceneDistanceChanged(sceneDistance);
3946- }
3947-
3948- if (xChanged) {
3949- Q_EMIT q->touchSceneXChanged(publicScenePos.x());
3950- }
3951-
3952- if (yChanged) {
3953- Q_EMIT q->touchSceneYChanged(publicScenePos.y());
3954- }
3955-}
3956-
3957-bool DirectionalDragAreaPrivate::isWithinTouchCompositionWindow()
3958-{
3959- return
3960- compositionTime > 0 &&
3961- !activeTouches.isEmpty() &&
3962- timeSource->msecsSinceReference() <=
3963- activeTouches.mostRecentStartTime() + (qint64)compositionTime;
3964-}
3965-
3966-void DirectionalDragArea::itemChange(ItemChange change, const ItemChangeData &value)
3967-{
3968- if (change == QQuickItem::ItemSceneChange) {
3969- if (value.window != nullptr) {
3970- value.window->installEventFilter(TouchRegistry::instance());
3971-
3972- // TODO: Handle window->screen() changes (ie window changing screens)
3973-
3974- qreal pixelsPerInch = value.window->screen()->physicalDotsPerInch();
3975- if (pixelsPerInch < 0) {
3976- // It can return garbage when run in a XVFB server (Virtual Framebuffer 'fake' X server)
3977- pixelsPerInch = 72;
3978- }
3979-
3980- d->setPixelsPerMm(pixelsPerInch / 25.4);
3981- }
3982- }
3983-}
3984-
3985-void DirectionalDragAreaPrivate::setPixelsPerMm(qreal pixelsPerMm)
3986-{
3987- dampedScenePos.setMaxDelta(1. * pixelsPerMm);
3988- setDistanceThreshold(4. * pixelsPerMm);
3989- maxDistance = 10. * pixelsPerMm;
3990-}
3991-
3992-//************************** ActiveTouchesInfo **************************
3993-
3994-ActiveTouchesInfo::ActiveTouchesInfo(const SharedTimeSource &timeSource)
3995- : m_timeSource(timeSource)
3996-{
3997-}
3998-
3999-void ActiveTouchesInfo::update(QTouchEvent *event)
4000-{
4001- if (!(event->touchPointStates() & (Qt::TouchPointPressed | Qt::TouchPointReleased))) {
4002- // nothing to update
4003- #if ACTIVETOUCHESINFO_DEBUG
4004- qDebug("[DDA::ActiveTouchesInfo] Nothing to Update");
4005- #endif
4006- return;
4007- }
4008-
4009- const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
4010- for (int i = 0; i < touchPoints.count(); ++i) {
4011- const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
4012- if (touchPoint.state() == Qt::TouchPointPressed) {
4013- addTouchPoint(touchPoint.id());
4014- } else if (touchPoint.state() == Qt::TouchPointReleased) {
4015- removeTouchPoint(touchPoint.id());
4016- }
4017- }
4018-}
4019-
4020-#if ACTIVETOUCHESINFO_DEBUG
4021-QString ActiveTouchesInfo::toString()
4022-{
4023- QString string = "(";
4024-
4025- {
4026- QTextStream stream(&string);
4027- m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &touchInfo) {
4028- stream << "(id=" << touchInfo->id << ",startTime=" << touchInfo->startTime << ")";
4029- return true;
4030- });
4031- }
4032-
4033- string.append(")");
4034-
4035- return string;
4036-}
4037-#endif // ACTIVETOUCHESINFO_DEBUG
4038-
4039-void ActiveTouchesInfo::addTouchPoint(int touchId)
4040-{
4041- ActiveTouchInfo &activeTouchInfo = m_touchInfoPool.getEmptySlot();
4042- activeTouchInfo.id = touchId;
4043- activeTouchInfo.startTime = m_timeSource->msecsSinceReference();
4044-
4045- #if ACTIVETOUCHESINFO_DEBUG
4046- qDebug() << "[DDA::ActiveTouchesInfo]" << qPrintable(toString());
4047- #endif
4048-}
4049-
4050-qint64 ActiveTouchesInfo::touchStartTime(int touchId)
4051-{
4052- qint64 result = -1;
4053-
4054- m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &touchInfo) {
4055- if (touchId == touchInfo->id) {
4056- result = touchInfo->startTime;
4057- return false;
4058- } else {
4059- return true;
4060- }
4061- });
4062-
4063- Q_ASSERT(result != -1);
4064- return result;
4065-}
4066-
4067-void ActiveTouchesInfo::removeTouchPoint(int touchId)
4068-{
4069- m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &touchInfo) {
4070- if (touchId == touchInfo->id) {
4071- m_touchInfoPool.freeSlot(touchInfo);
4072- return false;
4073- } else {
4074- return true;
4075- }
4076- });
4077-
4078- #if ACTIVETOUCHESINFO_DEBUG
4079- qDebug() << "[DDA::ActiveTouchesInfo]" << qPrintable(toString());
4080- #endif
4081-}
4082-
4083-qint64 ActiveTouchesInfo::mostRecentStartTime()
4084-{
4085- Q_ASSERT(!m_touchInfoPool.isEmpty());
4086-
4087- qint64 highestStartTime = -1;
4088-
4089- m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &activeTouchInfo) {
4090- if (activeTouchInfo->startTime > highestStartTime) {
4091- highestStartTime = activeTouchInfo->startTime;
4092- }
4093- return true;
4094- });
4095-
4096- return highestStartTime;
4097-}
4098-
4099-void DirectionalDragAreaPrivate::updateSceneDirectionVector()
4100-{
4101- QPointF localOrigin(0., 0.);
4102- QPointF localDirection;
4103- switch (direction) {
4104- case Direction::Upwards:
4105- localDirection.rx() = 0.;
4106- localDirection.ry() = -1.;
4107- break;
4108- case Direction::Downwards:
4109- case Direction::Vertical:
4110- localDirection.rx() = 0.;
4111- localDirection.ry() = 1;
4112- break;
4113- case Direction::Leftwards:
4114- localDirection.rx() = -1.;
4115- localDirection.ry() = 0.;
4116- break;
4117- default: // Direction::Rightwards || Direction.Horizontal
4118- localDirection.rx() = 1.;
4119- localDirection.ry() = 0.;
4120- break;
4121- }
4122- QPointF sceneOrigin = q->mapToScene(localOrigin);
4123- QPointF sceneDirection = q->mapToScene(localDirection);
4124- sceneDirectionVector = sceneDirection - sceneOrigin;
4125-}
4126-
4127-qreal DirectionalDragAreaPrivate::projectOntoDirectionVector(const QPointF sceneVector) const
4128-{
4129- // same as dot product as sceneDirectionVector is a unit vector
4130- return sceneVector.x() * sceneDirectionVector.x() +
4131- sceneVector.y() * sceneDirectionVector.y();
4132-}
4133-
4134-DirectionalDragAreaPrivate::DirectionalDragAreaPrivate(DirectionalDragArea *q)
4135- : q(q)
4136- , status(WaitingForTouch)
4137- , sceneDistance(0)
4138- , touchId(-1)
4139- , direction(Direction::Rightwards)
4140- , distanceThreshold(0)
4141- , distanceThresholdSquared(0.)
4142- , maxTime(400)
4143- , compositionTime(60)
4144- , immediateRecognition(false)
4145- , recognitionTimer(nullptr)
4146- , timeSource(new RealTimeSource)
4147- , activeTouches(timeSource)
4148- , monitorOnly(false)
4149-{
4150-}
4151
4152=== removed file 'plugins/Ubuntu/Gestures/DirectionalDragArea.h'
4153--- plugins/Ubuntu/Gestures/DirectionalDragArea.h 2016-03-29 03:47:39 +0000
4154+++ plugins/Ubuntu/Gestures/DirectionalDragArea.h 1970-01-01 00:00:00 +0000
4155@@ -1,143 +0,0 @@
4156-/*
4157- * Copyright (C) 2013,2014 Canonical, Ltd.
4158- *
4159- * This program is free software; you can redistribute it and/or modify
4160- * it under the terms of the GNU General Public License as published by
4161- * the Free Software Foundation; version 3.
4162- *
4163- * This program is distributed in the hope that it will be useful,
4164- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4165- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4166- * GNU General Public License for more details.
4167- *
4168- * You should have received a copy of the GNU General Public License
4169- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4170- */
4171-
4172-#ifndef DIRECTIONAL_DRAG_AREA_H
4173-#define DIRECTIONAL_DRAG_AREA_H
4174-
4175-#include <QtQuick/QQuickItem>
4176-#include "UbuntuGesturesQmlGlobal.h"
4177-#include "Damper.h"
4178-#include "Direction.h"
4179-
4180-// lib UbuntuGestures
4181-#include <Pool.h>
4182-#include <Timer.h>
4183-
4184-class TouchOwnershipEvent;
4185-class UnownedTouchEvent;
4186-class DirectionalDragAreaPrivate;
4187-
4188-/*
4189- An area that detects axis-aligned single-finger drag gestures
4190-
4191- If a drag deviates too much from the components' direction recognition will
4192- fail. It will also fail if the drag or flick is too short. E.g. a noisy or
4193- fidgety click
4194-
4195- See doc/DirectionalDragArea.svg
4196- */
4197-class UBUNTUGESTURESQML_EXPORT DirectionalDragArea : public QQuickItem {
4198- Q_OBJECT
4199-
4200- // The direction in which the gesture should move in order to be recognized.
4201- Q_PROPERTY(Direction::Type direction READ direction WRITE setDirection NOTIFY directionChanged)
4202-
4203- // The distance travelled by the finger along the axis specified by
4204- // DirectionalDragArea's direction.
4205- Q_PROPERTY(qreal distance READ distance NOTIFY distanceChanged)
4206-
4207- // The distance travelled by the finger along the axis specified by
4208- // DirectionalDragArea's direction in scene coordinates
4209- Q_PROPERTY(qreal sceneDistance READ sceneDistance NOTIFY sceneDistanceChanged)
4210-
4211- // Position of the touch point performing the drag relative to this item.
4212- Q_PROPERTY(qreal touchX READ touchX NOTIFY touchXChanged)
4213- Q_PROPERTY(qreal touchY READ touchY NOTIFY touchYChanged)
4214-
4215- // Position of the touch point performing the drag, in scene's coordinate system
4216- Q_PROPERTY(qreal touchSceneX READ touchSceneX NOTIFY touchSceneXChanged)
4217- Q_PROPERTY(qreal touchSceneY READ touchSceneY NOTIFY touchSceneYChanged)
4218-
4219- // Whether a drag gesture is taking place
4220- Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
4221-
4222- // Whether the drag area is pressed.
4223- Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
4224-
4225- // Whether a gesture should be Recognized as soon a touch lands on the area.
4226- // With this property enabled it will work pretty much like a MultiPointTouchArea,
4227- // just with a different API.
4228- //
4229- // It's false by default. In most cases you will not want that enabled.
4230- Q_PROPERTY(bool immediateRecognition
4231- READ immediateRecognition
4232- WRITE setImmediateRecognition
4233- NOTIFY immediateRecognitionChanged)
4234-
4235- // Whether we are merely monitoring touch events (in which case, we don't
4236- // claim ownership of the touch).
4237- Q_PROPERTY(bool monitorOnly READ monitorOnly WRITE setMonitorOnly NOTIFY monitorOnlyChanged)
4238-
4239- Q_ENUMS(Direction)
4240-public:
4241- DirectionalDragArea(QQuickItem *parent = 0);
4242-
4243- Direction::Type direction() const;
4244- void setDirection(Direction::Type);
4245-
4246- qreal distance() const;
4247- qreal sceneDistance() const;
4248-
4249- qreal touchX() const;
4250- qreal touchY() const;
4251-
4252- qreal touchSceneX() const;
4253- qreal touchSceneY() const;
4254-
4255- bool dragging() const;
4256-
4257- bool pressed() const;
4258-
4259- bool immediateRecognition() const;
4260- void setImmediateRecognition(bool enabled);
4261-
4262- bool monitorOnly() const;
4263- void setMonitorOnly(bool monitorOnly);
4264-
4265- bool event(QEvent *e) override;
4266-
4267- /*
4268- In qmltests, sequences of touch events are sent all at once, unlike in "real life".
4269- Also qmltests might run really slowly, e.g. when run from inside virtual machines.
4270- Thus to remove a variable that qmltests cannot really control, namely time, this
4271- function removes all constraints that are sensible to elapsed time.
4272-
4273- This effectively makes the DirectionalDragArea easier to fool.
4274- */
4275- Q_INVOKABLE void removeTimeConstraints();
4276-
4277-Q_SIGNALS:
4278- void directionChanged(Direction::Type direction);
4279- void draggingChanged(bool value);
4280- void pressedChanged(bool value);
4281- void distanceChanged(qreal value);
4282- void sceneDistanceChanged(qreal value);
4283- void touchXChanged(qreal value);
4284- void touchYChanged(qreal value);
4285- void touchSceneXChanged(qreal value);
4286- void touchSceneYChanged(qreal value);
4287- void immediateRecognitionChanged(bool value);
4288- void monitorOnlyChanged(bool value);
4289-
4290-protected:
4291- void touchEvent(QTouchEvent *event) override;
4292- void itemChange(ItemChange change, const ItemChangeData &value) override;
4293-
4294-public: // so tests can access it
4295- DirectionalDragAreaPrivate *d;
4296-};
4297-
4298-#endif // DIRECTIONAL_DRAG_AREA_H
4299
4300=== removed file 'plugins/Ubuntu/Gestures/DirectionalDragArea_p.h'
4301--- plugins/Ubuntu/Gestures/DirectionalDragArea_p.h 2016-03-29 03:47:39 +0000
4302+++ plugins/Ubuntu/Gestures/DirectionalDragArea_p.h 1970-01-01 00:00:00 +0000
4303@@ -1,169 +0,0 @@
4304-/*
4305- * Copyright (C) 2015 Canonical, Ltd.
4306- *
4307- * This program is free software; you can redistribute it and/or modify
4308- * it under the terms of the GNU General Public License as published by
4309- * the Free Software Foundation; version 3.
4310- *
4311- * This program is distributed in the hope that it will be useful,
4312- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4313- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4314- * GNU General Public License for more details.
4315- *
4316- * You should have received a copy of the GNU General Public License
4317- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4318- */
4319-
4320-#ifndef DIRECTIONAL_DRAG_AREA_PRIV_H
4321-#define DIRECTIONAL_DRAG_AREA_PRIV_H
4322-
4323-// Information about an active touch point
4324-struct UBUNTUGESTURESQML_EXPORT ActiveTouchInfo {
4325- ActiveTouchInfo() : id(-1), startTime(-1) {}
4326- bool isValid() const { return id != -1; }
4327- void reset() { id = -1; }
4328- int id;
4329- qint64 startTime;
4330-};
4331-class UBUNTUGESTURESQML_EXPORT ActiveTouchesInfo {
4332-public:
4333- ActiveTouchesInfo(const UbuntuGestures::SharedTimeSource &timeSource);
4334- void update(QTouchEvent *event);
4335- qint64 touchStartTime(int id);
4336- bool isEmpty() const { return m_touchInfoPool.isEmpty(); }
4337- qint64 mostRecentStartTime();
4338- UbuntuGestures::SharedTimeSource m_timeSource;
4339-private:
4340- void addTouchPoint(int touchId);
4341- void removeTouchPoint(int touchId);
4342- #if ACTIVETOUCHESINFO_DEBUG
4343- QString toString();
4344- #endif
4345-
4346- Pool<ActiveTouchInfo> m_touchInfoPool;
4347-};
4348-
4349-class UBUNTUGESTURESQML_EXPORT DirectionalDragAreaPrivate : public QObject {
4350- Q_OBJECT
4351-
4352- Q_ENUMS(Status)
4353-public:
4354- DirectionalDragAreaPrivate(DirectionalDragArea *q);
4355-
4356-public Q_SLOTS:
4357- void giveUpIfDisabledOrInvisible();
4358- void rejectGesture();
4359-
4360-public:
4361- // Describes the state of the directional drag gesture.
4362- enum Status {
4363- // Waiting for a new touch point to land on this area. No gesture is being processed
4364- // or tracked.
4365- WaitingForTouch,
4366-
4367- // A touch point has landed on this area but it's not know yet whether it is
4368- // performing a drag in the correct direction.
4369- // If it's decided that the touch point is not performing a directional drag gesture,
4370- // it will be rejected/ignored and status will return to WaitingForTouch.
4371- Undecided, //Recognizing,
4372-
4373- // There's a touch point in this area and it performed a drag in the correct
4374- // direction.
4375- //
4376- // Once recognized, the gesture state will move back to WaitingForTouch only once
4377- // that touch point ends. The gesture will remain in the Recognized state even if
4378- // the touch point starts moving in other directions or halts.
4379- Recognized,
4380- };
4381-
4382- void touchEvent_absent(QTouchEvent *event);
4383- void touchEvent_undecided(QTouchEvent *event);
4384- void touchEvent_recognized(QTouchEvent *event);
4385- bool movingInRightDirection() const;
4386- bool movedFarEnoughAlongGestureAxis() const;
4387- bool isPastMaxDistance() const;
4388- const QTouchEvent::TouchPoint *fetchTargetTouchPoint(QTouchEvent *event);
4389- void setStatus(Status newStatus);
4390- void setPublicPos(const QPointF point);
4391- void setPublicScenePos(const QPointF point);
4392- bool isWithinTouchCompositionWindow();
4393- void updateSceneDirectionVector();
4394- // returns the scalar projection between the given vector (in scene coordinates)
4395- // and m_sceneDirectionVector
4396- qreal projectOntoDirectionVector(const QPointF sceneVector) const;
4397- void touchOwnershipEvent(TouchOwnershipEvent *event);
4398- void unownedTouchEvent(UnownedTouchEvent *event);
4399- void unownedTouchEvent_undecided(UnownedTouchEvent *unownedTouchEvent);
4400- void watchPressedTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints);
4401- bool recognitionIsDisabled() const;
4402- bool sanityCheckRecognitionProperties();
4403- void updateSceneDistance();
4404- void setMaxTime(int value);
4405- void setDistanceThreshold(qreal value);
4406- void setPixelsPerMm(qreal pixelsPerMm);
4407- QString objectName() const { return q->objectName(); }
4408-
4409- // Replaces the existing Timer with the given one.
4410- //
4411- // Useful for providing a fake timer when testing.
4412- void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
4413-
4414- // Useful for testing, where a fake time source can be supplied
4415- void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
4416-
4417- DirectionalDragArea *q;
4418-
4419- // The current status of the directional drag gesture area.
4420- Status status;
4421-
4422- QPointF startPos;
4423- QPointF startScenePos;
4424- qreal sceneDistance;
4425- int touchId;
4426-
4427- // The touch position exposed in the public API.
4428- // It only starts to move once the gesture gets recognized.
4429- QPointF publicPos;
4430- QPointF publicScenePos;
4431-
4432- // A movement damper is used in some of the gesture recognition calculations
4433- // to get rid of noise or small oscillations in the touch position.
4434- DampedPointF dampedScenePos;
4435- QPointF previousDampedScenePos;
4436-
4437- // Unit vector in scene coordinates describing the direction of the gesture recognition
4438- QPointF sceneDirectionVector;
4439-
4440- Direction::Type direction;
4441-
4442- // How far a touch point has to move from its initial position along the gesture axis in order
4443- // for it to be recognized as a directional drag.
4444- qreal distanceThreshold;
4445- qreal distanceThresholdSquared; // it's pow(distanceThreshold, 2)
4446-
4447- // Maximum time (in milliseconds) the gesture can take to go beyond the distance threshold
4448- int maxTime;
4449-
4450- // Maximum distance the gesture can go without crossing the axis-aligned distance threshold
4451- qreal maxDistance;
4452-
4453- // Maximum time (in milliseconds) after the start of a given touch point where
4454- // subsequent touch starts are grouped with the first one into an N-touches gesture
4455- // (e.g. a two-fingers tap or drag).
4456- int compositionTime;
4457-
4458- bool immediateRecognition;
4459-
4460- UbuntuGestures::AbstractTimer *recognitionTimer;
4461-
4462- UbuntuGestures::SharedTimeSource timeSource;
4463-
4464- ActiveTouchesInfo activeTouches;
4465-
4466- bool monitorOnly;
4467-
4468-Q_SIGNALS:
4469- void statusChanged(Status value);
4470-};
4471-
4472-#endif // DIRECTIONAL_DRAG_AREA_PRIV_H
4473
4474=== modified file 'plugins/Ubuntu/Gestures/Gestures.qmltypes'
4475--- plugins/Ubuntu/Gestures/Gestures.qmltypes 2016-03-29 03:47:39 +0000
4476+++ plugins/Ubuntu/Gestures/Gestures.qmltypes 2016-06-01 16:58:47 +0000
4477@@ -55,88 +55,6 @@
4478 }
4479 }
4480 Component {
4481- name: "DirectionalDragArea"
4482- defaultProperty: "data"
4483- prototype: "QQuickItem"
4484- exports: ["Ubuntu.Gestures/DirectionalDragArea 0.1"]
4485- exportMetaObjectRevisions: [0]
4486- Property { name: "direction"; type: "Direction::Type" }
4487- Property { name: "distance"; type: "double"; isReadonly: true }
4488- Property { name: "sceneDistance"; type: "double"; isReadonly: true }
4489- Property { name: "touchX"; type: "double"; isReadonly: true }
4490- Property { name: "touchY"; type: "double"; isReadonly: true }
4491- Property { name: "touchSceneX"; type: "double"; isReadonly: true }
4492- Property { name: "touchSceneY"; type: "double"; isReadonly: true }
4493- Property { name: "dragging"; type: "bool"; isReadonly: true }
4494- Property { name: "pressed"; type: "bool"; isReadonly: true }
4495- Property { name: "immediateRecognition"; type: "bool" }
4496- Signal {
4497- name: "directionChanged"
4498- Parameter { name: "direction"; type: "Direction::Type" }
4499- }
4500- Signal {
4501- name: "draggingChanged"
4502- Parameter { name: "value"; type: "bool" }
4503- }
4504- Signal {
4505- name: "pressedChanged"
4506- Parameter { name: "value"; type: "bool" }
4507- }
4508- Signal {
4509- name: "distanceChanged"
4510- Parameter { name: "value"; type: "double" }
4511- }
4512- Signal {
4513- name: "sceneDistanceChanged"
4514- Parameter { name: "value"; type: "double" }
4515- }
4516- Signal {
4517- name: "touchXChanged"
4518- Parameter { name: "value"; type: "double" }
4519- }
4520- Signal {
4521- name: "touchYChanged"
4522- Parameter { name: "value"; type: "double" }
4523- }
4524- Signal {
4525- name: "touchSceneXChanged"
4526- Parameter { name: "value"; type: "double" }
4527- }
4528- Signal {
4529- name: "touchSceneYChanged"
4530- Parameter { name: "value"; type: "double" }
4531- }
4532- Signal {
4533- name: "immediateRecognitionChanged"
4534- Parameter { name: "value"; type: "bool" }
4535- }
4536- Method { name: "removeTimeConstraints" }
4537- }
4538- Component {
4539- name: "FloatingFlickable"
4540- defaultProperty: "data"
4541- prototype: "QQuickItem"
4542- exports: ["Ubuntu.Gestures/FloatingFlickable 0.1"]
4543- exportMetaObjectRevisions: [0]
4544- Property { name: "contentWidth"; type: "double" }
4545- Property { name: "contentHeight"; type: "double" }
4546- Property { name: "contentX"; type: "double" }
4547- Property { name: "contentY"; type: "double" }
4548- Property { name: "direction"; type: "Direction::Type" }
4549- }
4550- Component {
4551- name: "GestureTouchPoint"
4552- prototype: "QObject"
4553- exports: ["Ubuntu.Gestures/GestureTouchPoint 0.1"]
4554- isCreatable: false
4555- exportMetaObjectRevisions: [0]
4556- Property { name: "pointId"; type: "int"; isReadonly: true }
4557- Property { name: "pressed"; type: "bool"; isReadonly: true }
4558- Property { name: "x"; type: "double"; isReadonly: true }
4559- Property { name: "y"; type: "double"; isReadonly: true }
4560- Property { name: "dragging"; type: "bool"; isReadonly: true }
4561- }
4562- Component {
4563 name: "PressedOutsideNotifier"
4564 defaultProperty: "data"
4565 prototype: "QQuickItem"
4566@@ -156,54 +74,4 @@
4567 Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
4568 }
4569 }
4570- Component {
4571- name: "TouchGestureArea"
4572- defaultProperty: "data"
4573- prototype: "QQuickItem"
4574- exports: ["Ubuntu.Gestures/TouchGestureArea 0.1"]
4575- exportMetaObjectRevisions: [0]
4576- Enum {
4577- name: "Status"
4578- values: {
4579- "WaitingForTouch": 0,
4580- "Undecided": 1,
4581- "Recognized": 2,
4582- "Rejected": 3
4583- }
4584- }
4585- Property { name: "touchPoints"; type: "GestureTouchPoint"; isList: true; isReadonly: true }
4586- Property { name: "dragging"; type: "bool"; isReadonly: true }
4587- Property { name: "minimumTouchPoints"; type: "int" }
4588- Property { name: "maximumTouchPoints"; type: "int" }
4589- Signal {
4590- name: "statusChanged"
4591- Parameter { name: "status"; type: "Status" }
4592- }
4593- Signal { name: "touchPointsUpdated" }
4594- Signal {
4595- name: "draggingChanged"
4596- Parameter { name: "dragging"; type: "bool" }
4597- }
4598- Signal {
4599- name: "minimumTouchPointsChanged"
4600- Parameter { name: "value"; type: "bool" }
4601- }
4602- Signal {
4603- name: "maximumTouchPointsChanged"
4604- Parameter { name: "value"; type: "bool" }
4605- }
4606- Signal {
4607- name: "pressed"
4608- Parameter { name: "points"; type: "QList<QObject*>" }
4609- }
4610- Signal {
4611- name: "released"
4612- Parameter { name: "points"; type: "QList<QObject*>" }
4613- }
4614- Signal {
4615- name: "updated"
4616- Parameter { name: "points"; type: "QList<QObject*>" }
4617- }
4618- Signal { name: "clicked" }
4619- }
4620 }
4621
4622=== renamed file 'plugins/Ubuntu/Gestures/FloatingFlickable.cpp' => 'plugins/Ubuntu/Gestures/MouseEventGenerator.cpp'
4623--- plugins/Ubuntu/Gestures/FloatingFlickable.cpp 2015-05-27 09:37:34 +0000
4624+++ plugins/Ubuntu/Gestures/MouseEventGenerator.cpp 2016-06-01 16:58:47 +0000
4625@@ -1,5 +1,5 @@
4626 /*
4627- * Copyright (C) 2015 Canonical, Ltd.
4628+ * Copyright (C) 2015-2016 Canonical, Ltd.
4629 *
4630 * This program is free software; you can redistribute it and/or modify
4631 * it under the terms of the GNU General Public License as published by
4632@@ -14,137 +14,51 @@
4633 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4634 */
4635
4636-#include "FloatingFlickable.h"
4637-
4638-#include <private/qquickflickable_p.h>
4639-#include "DirectionalDragArea.h"
4640-
4641-#include <QDebug>
4642-
4643-FloatingFlickable::FloatingFlickable(QQuickItem *parent)
4644- : QQuickItem(parent)
4645- , m_mousePressed(false)
4646-{
4647- m_dragArea = new DirectionalDragArea(this);
4648- m_dragArea->setWidth(width());
4649- m_dragArea->setHeight(height());
4650- m_dragArea->setDirection(Direction::Horizontal);
4651- connect(m_dragArea, &DirectionalDragArea::touchXChanged,
4652- this, &FloatingFlickable::onDragAreaTouchPosChanged);
4653- connect(m_dragArea, &DirectionalDragArea::touchYChanged,
4654- this, &FloatingFlickable::onDragAreaTouchPosChanged);
4655- connect(m_dragArea, &DirectionalDragArea::draggingChanged,
4656- this, &FloatingFlickable::onDragAreaDraggingChanged);
4657- connect(m_dragArea, &DirectionalDragArea::directionChanged, this, &FloatingFlickable::directionChanged);
4658-
4659- m_flickable = new QQuickFlickable(this);
4660- m_flickable->setEnabled(false);
4661- m_flickable->setWidth(width());
4662- m_flickable->setHeight(height());
4663- connect(m_flickable, &QQuickFlickable::contentWidthChanged, this, &FloatingFlickable::contentWidthChanged);
4664- connect(m_flickable, &QQuickFlickable::contentHeightChanged, this, &FloatingFlickable::contentHeightChanged);
4665- connect(m_flickable, &QQuickFlickable::contentXChanged, this, &FloatingFlickable::contentXChanged);
4666- connect(m_flickable, &QQuickFlickable::contentYChanged, this, &FloatingFlickable::contentYChanged);
4667-
4668- connect(this, &QQuickItem::widthChanged, this, &FloatingFlickable::updateChildrenWidth);
4669- connect(this, &QQuickItem::heightChanged, this, &FloatingFlickable::updateChildrenHeight);
4670-}
4671-
4672-qreal FloatingFlickable::contentWidth() const
4673-{
4674- return m_flickable->contentWidth();
4675-}
4676-
4677-void FloatingFlickable::setContentWidth(qreal contentWidth)
4678-{
4679- m_flickable->setContentWidth(contentWidth);
4680-}
4681-
4682-qreal FloatingFlickable::contentHeight() const
4683-{
4684- return m_flickable->contentHeight();
4685-}
4686-
4687-void FloatingFlickable::setContentHeight(qreal contentHeight)
4688-{
4689- m_flickable->setContentHeight(contentHeight);
4690-}
4691-
4692-qreal FloatingFlickable::contentX() const
4693-{
4694- return m_flickable->contentX();
4695-}
4696-
4697-void FloatingFlickable::setContentX(qreal contentX)
4698-{
4699- m_flickable->setContentX(contentX);
4700-}
4701-
4702-qreal FloatingFlickable::contentY() const
4703-{
4704- return m_flickable->contentY();
4705-}
4706-
4707-void FloatingFlickable::setContentY(qreal contentY)
4708-{
4709- m_flickable->setContentY(contentY);
4710-}
4711-
4712-Direction::Type FloatingFlickable::direction() const
4713-{
4714- return m_dragArea->direction();
4715-}
4716-
4717-void FloatingFlickable::setDirection(Direction::Type direction)
4718-{
4719- m_dragArea->setDirection(direction);
4720- if (Direction::isHorizontal(direction)) {
4721- m_flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
4722- } else {
4723- m_flickable->setFlickableDirection(QQuickFlickable::VerticalFlick);
4724- }
4725-}
4726-
4727-void FloatingFlickable::updateChildrenWidth()
4728-{
4729- m_dragArea->setWidth(width());
4730- m_flickable->setWidth(width());
4731-}
4732-
4733-void FloatingFlickable::updateChildrenHeight()
4734-{
4735- m_dragArea->setHeight(height());
4736- m_flickable->setHeight(height());
4737-}
4738-
4739-void FloatingFlickable::onDragAreaTouchPosChanged(qreal)
4740-{
4741- if (m_mousePressed) {
4742- QMouseEvent mouseEvent(QEvent::MouseMove,
4743- QPointF(m_dragArea->touchX(),m_dragArea->touchY()),
4744- Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
4745-
4746- QCoreApplication::sendEvent(m_flickable, &mouseEvent);
4747-
4748- }
4749-}
4750-
4751-void FloatingFlickable::onDragAreaDraggingChanged(bool dragging)
4752-{
4753- if (dragging && !m_mousePressed) {
4754- QMouseEvent mouseEvent(QEvent::MouseButtonPress,
4755- QPointF(m_dragArea->touchX(),m_dragArea->touchY()),
4756- Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
4757-
4758- QCoreApplication::sendEvent(m_flickable, &mouseEvent);
4759- m_mousePressed = true;
4760-
4761- } else if (!dragging && m_mousePressed) {
4762- QMouseEvent mouseEvent(QEvent::MouseButtonRelease,
4763- QPointF(m_dragArea->touchX(),m_dragArea->touchY()),
4764- Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
4765-
4766- QCoreApplication::sendEvent(m_flickable, &mouseEvent);
4767- m_mousePressed = false;
4768- }
4769+#include "MouseEventGenerator.h"
4770+
4771+#include <QCoreApplication>
4772+#include <QMouseEvent>
4773+#include <QQuickItem>
4774+
4775+MouseEventGenerator::MouseEventGenerator(QObject *parent)
4776+ : QObject(parent)
4777+{
4778+}
4779+
4780+void MouseEventGenerator::move(const QPointF position)
4781+{
4782+ if (!m_mousePressed || !m_targetItem) {
4783+ return;
4784+ }
4785+
4786+ QMouseEvent mouseEvent(QEvent::MouseMove,
4787+ QPointF(position.x(), position.y()), Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
4788+
4789+ QCoreApplication::sendEvent(m_targetItem, &mouseEvent);
4790+}
4791+
4792+void MouseEventGenerator::press(const QPointF position)
4793+{
4794+ if (m_mousePressed || !m_targetItem) {
4795+ return;
4796+ }
4797+
4798+ QMouseEvent mouseEvent(QEvent::MouseButtonPress,
4799+ QPointF(position.x(), position.y()), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
4800+
4801+ QCoreApplication::sendEvent(m_targetItem, &mouseEvent);
4802+ m_mousePressed = true;
4803+}
4804+
4805+void MouseEventGenerator::release(const QPointF position)
4806+{
4807+ if (!m_mousePressed || !m_targetItem) {
4808+ return;
4809+ }
4810+
4811+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease,
4812+ QPointF(position.x(), position.y()), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
4813+
4814+ QCoreApplication::sendEvent(m_targetItem, &mouseEvent);
4815+ m_mousePressed = false;
4816 }
4817
4818=== renamed file 'plugins/Ubuntu/Gestures/FloatingFlickable.h' => 'plugins/Ubuntu/Gestures/MouseEventGenerator.h'
4819--- plugins/Ubuntu/Gestures/FloatingFlickable.h 2015-05-27 09:37:34 +0000
4820+++ plugins/Ubuntu/Gestures/MouseEventGenerator.h 2016-06-01 16:58:47 +0000
4821@@ -1,5 +1,5 @@
4822 /*
4823- * Copyright (C) 2015 Canonical, Ltd.
4824+ * Copyright (C) 2015-2016 Canonical, Ltd.
4825 *
4826 * This program is free software; you can redistribute it and/or modify
4827 * it under the terms of the GNU General Public License as published by
4828@@ -14,73 +14,35 @@
4829 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4830 */
4831
4832-#ifndef FLOATING_FLICKABLE_H
4833-#define FLOATING_FLICKABLE_H
4834-
4835-#include <QQuickItem>
4836+#ifndef MOUSEEVENTGENERATOR_H
4837+#define MOUSEEVENTGENERATOR_H
4838+
4839+#include <QObject>
4840+#include <QPointF>
4841+
4842 #include "UbuntuGesturesQmlGlobal.h"
4843-#include "Direction.h"
4844-
4845-class DirectionalDragArea;
4846-class QQuickFlickable;
4847-
4848-/*
4849- A Flickable that can be put in front of the item to be flicked and
4850- still have the item-to-be-flicked receive input events that are not flicks.
4851-
4852- Ie, it's a Flickable that, input-wise, is transparent to non-flick gestures.
4853-
4854- With a regular Flickable you would have to make the item-to-be-flicked a child
4855- of Flicakble to achieve the same result. FloatingFlickable has no such requirement
4856- or limitation.
4857- */
4858-class UBUNTUGESTURESQML_EXPORT FloatingFlickable : public QQuickItem {
4859+
4860+class QQuickItem;
4861+
4862+class UBUNTUGESTURESQML_EXPORT MouseEventGenerator : public QObject {
4863 Q_OBJECT
4864-
4865- Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged)
4866- Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged)
4867- Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged)
4868- Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged)
4869-
4870- Q_PROPERTY(Direction::Type direction READ direction WRITE setDirection NOTIFY directionChanged)
4871+ Q_PROPERTY(QQuickItem* targetItem MEMBER m_targetItem NOTIFY targetItemChanged)
4872+
4873+public:
4874+ MouseEventGenerator(QObject *parent = nullptr);
4875+
4876+ Q_INVOKABLE void move(const QPointF position);
4877+ Q_INVOKABLE void press(const QPointF position);
4878+ Q_INVOKABLE void release(const QPointF position);
4879
4880 Q_SIGNALS:
4881- void contentWidthChanged();
4882- void contentHeightChanged();
4883- void contentXChanged();
4884- void contentYChanged();
4885- void directionChanged();
4886-
4887-public:
4888- FloatingFlickable(QQuickItem *parent = nullptr);
4889-
4890- qreal contentWidth() const;
4891- void setContentWidth(qreal contentWidth);
4892-
4893- qreal contentHeight() const;
4894- void setContentHeight(qreal contentHeight);
4895-
4896- qreal contentX() const;
4897- void setContentX(qreal contentX);
4898-
4899- qreal contentY() const;
4900- void setContentY(qreal contentY);
4901-
4902- Direction::Type direction() const;
4903- void setDirection(Direction::Type);
4904-
4905-private Q_SLOTS:
4906- void updateChildrenWidth();
4907- void updateChildrenHeight();
4908- void onDragAreaTouchPosChanged(qreal);
4909- void onDragAreaDraggingChanged(bool value);
4910+ void targetItemChanged(QQuickItem *);
4911
4912 private:
4913- DirectionalDragArea *m_dragArea;
4914- QQuickFlickable *m_flickable;
4915- bool m_mousePressed;
4916+ bool m_mousePressed {false};
4917+ QQuickItem *m_targetItem {nullptr};
4918
4919 friend class tst_FloatingFlickable;
4920 };
4921
4922-#endif // FLOATING_FLICKABLE_H
4923+#endif // MOUSEEVENTGENERATOR_H
4924
4925=== modified file 'plugins/Ubuntu/Gestures/PressedOutsideNotifier.h'
4926--- plugins/Ubuntu/Gestures/PressedOutsideNotifier.h 2013-11-22 13:43:40 +0000
4927+++ plugins/Ubuntu/Gestures/PressedOutsideNotifier.h 2016-06-01 16:58:47 +0000
4928@@ -23,7 +23,7 @@
4929 #include <QPointer>
4930 #include <QTimer>
4931
4932-#include "UbuntuGesturesGlobal.h"
4933+#include <ubuntugesturesglobal.h>
4934
4935 /*
4936 Notifies when a point, mouse or touch, is pressed outside its area.
4937
4938=== modified file 'plugins/Ubuntu/Gestures/TouchGate.cpp'
4939--- plugins/Ubuntu/Gestures/TouchGate.cpp 2015-06-24 11:41:09 +0000
4940+++ plugins/Ubuntu/Gestures/TouchGate.cpp 2016-06-01 16:58:47 +0000
4941@@ -20,8 +20,8 @@
4942 #include <QDebug>
4943 #include <QQuickWindow>
4944
4945-#include <TouchOwnershipEvent.h>
4946-#include <TouchRegistry.h>
4947+#include <TouchOwnershipEvent>
4948+#include <TouchRegistry>
4949
4950 #if TOUCHGATE_DEBUG
4951 #define ugDebug(params) qDebug().nospace() << "[TouchGate(" << (void*)this << ")] " << params
4952
4953=== modified file 'plugins/Ubuntu/Gestures/TouchGestureArea.cpp'
4954--- plugins/Ubuntu/Gestures/TouchGestureArea.cpp 2016-03-11 20:18:12 +0000
4955+++ plugins/Ubuntu/Gestures/TouchGestureArea.cpp 2016-06-01 16:58:47 +0000
4956@@ -16,10 +16,11 @@
4957
4958 #include "TouchGestureArea.h"
4959
4960-// local
4961-#include "TouchOwnershipEvent.h"
4962-#include "TouchRegistry.h"
4963-#include "UnownedTouchEvent.h"
4964+#include <UbuntuGestures/TouchOwnershipEvent>
4965+#include <UbuntuGestures/TouchRegistry>
4966+#include <UbuntuGestures/UnownedTouchEvent>
4967+// #include "TouchRegistry.h"
4968+// #include "UnownedTouchEvent.h"
4969
4970 #include <QGuiApplication>
4971 #include <QStyleHints>
4972@@ -588,13 +589,15 @@
4973 resyncCachedTouchPoints();
4974 break;
4975 case InternalStatus::WaitingForMoreTouches:
4976- m_recognitionTimer->start(m_recognitionPeriod);
4977+ m_recognitionTimer->setInterval(m_recognitionPeriod);
4978+ m_recognitionTimer->start();
4979 break;
4980 case InternalStatus::Recognized:
4981 resyncCachedTouchPoints();
4982 break;
4983 case InternalStatus::WaitingForRejection:
4984- m_recognitionTimer->start(m_releaseRejectPeriod);
4985+ m_recognitionTimer->setInterval(m_releaseRejectPeriod);
4986+ m_recognitionTimer->start();
4987 break;
4988 case InternalStatus::Rejected:
4989 resyncCachedTouchPoints();
4990
4991=== modified file 'plugins/Ubuntu/Gestures/TouchGestureArea.h'
4992--- plugins/Ubuntu/Gestures/TouchGestureArea.h 2016-03-11 20:18:12 +0000
4993+++ plugins/Ubuntu/Gestures/TouchGestureArea.h 2016-06-01 16:58:47 +0000
4994@@ -21,8 +21,7 @@
4995
4996 #include <QQuickItem>
4997
4998-// lib UbuntuGestures
4999-#include <Timer.h>
5000+#include <UbuntuGestures/Timer>
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches