Merge lp:~aacid/unity8/nodda into lp:unity8

Proposed by Albert Astals Cid on 2015-12-17
Status: Merged
Approved by: Daniel d'Andrada on 2016-05-02
Approved revision: 2125
Merged at revision: 2410
Proposed branch: lp:~aacid/unity8/nodda
Merge into: lp:unity8
Prerequisite: lp:~aacid/unity8/fixQmlTestsNewSDK
Diff against target: 7650 lines (+314/-6218)
77 files modified
CMakeLists.txt (+12/-1)
debian/control (+2/-0)
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/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 (+1/-2)
plugins/Ubuntu/Gestures/plugin.cpp (+3/-5)
qml/Components/DragHandle.qml (+16/-18)
qml/Components/FloatingFlickable.qml (+59/-0)
qml/Dash/Dash.qml (+3/-3)
qml/Launcher/Launcher.qml (+4/-4)
qml/Panel/IndicatorsMenu.qml (+17/-13)
qml/Stages/DesktopStage.qml (+1/-1)
qml/Stages/PhoneStage.qml (+4/-4)
qml/Stages/TabletStage.qml (+4/-4)
qml/Tutorial/TutorialBottom.qml (+3/-3)
src/CMakeLists.txt (+0/-4)
tests/CMakeLists.txt (+0/-1)
tests/libs/CMakeLists.txt (+0/-1)
tests/libs/UbuntuGestures/CMakeLists.txt (+0/-16)
tests/libs/UbuntuGestures/tst_TouchRegistry.cpp (+0/-974)
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/qmltests/Components/CMakeLists.txt (+6/-3)
tests/qmltests/Components/tst_DragHandle.cpp (+25/-21)
tests/qmltests/Components/tst_EdgeDragEvaluator.cpp (+1/-1)
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 (+1/-1)
tests/qmltests/Tutorial/tst_Tutorial.qml (+2/-2)
tests/qmltests/tst_OrientedShell.qml (+1/-1)
tests/qmltests/tst_Shell.qml (+7/-5)
tests/qmltests/tst_ShellWithPin.qml (+1/-1)
tests/utils/modules/Unity/Test/CMakeLists.txt (+4/-2)
tests/utils/modules/Unity/Test/UnityTestCase.qml (+8/-8)
tests/utils/modules/Unity/Test/testutil.cpp (+2/-2)
To merge this branch: bzr merge lp:~aacid/unity8/nodda
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Needs Fixing on 2016-05-02
Daniel d'Andrada (community) 2015-12-17 Approve on 2016-05-02
PS Jenkins bot continuous-integration 2015-12-17 Needs Fixing on 2015-12-17
Review via email: mp+280814@code.launchpad.net

This proposal supersedes a proposal from 2015-12-07.

Commit Message

Remove DirectionalDragArea and libs/UbuntuGestures and port to SDK equivalents

Description of the Change

* Are there any related MPs required for this MP to build/function as expected?
None

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * Did you make sure that your branch does not contain spurious tags?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
N/A

To post a comment you must log in.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

Please document FloatingFlickableHelper. Explain what's its purpose.

review: Needs Fixing
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

> Please document FloatingFlickableHelper. Explain what's its purpose.

You could even give it a more informative/accurate name, such as MouseEventSynthesizer

Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

"""
 * Copyright (C) 2013 Canonical, Ltd.
"""

Please fix the copyright year in FloatingFlickable.qml

review: Needs Fixing
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

In tests/autopilot/unity8/dash.py:

"""
- current_header.select_single(objectName="search_action_button")
+ current_header.select_single(objectName="search_button")
"""

Seems unrelated.

Same in tests/qmltests/Dash/tst_GenericScopeView.qml and tests/qmltests/Dash/tst_Dash.qml

-------------------------

I don't get why you had to make those changes in tests/qmltests/Panel/tst_IndicatorsMenu.qml

----------------------

This "wait(1000);" in tests/qmltests/Stages/tst_PhoneStage.qml doesn't look right.

Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

> In tests/autopilot/unity8/dash.py:
>
> """
> - current_header.select_single(objectName="search_action_button")
> + current_header.select_single(objectName="search_button")
> """
>
> Seems unrelated.
>
> Same in tests/qmltests/Dash/tst_GenericScopeView.qml and
> tests/qmltests/Dash/tst_Dash.qml

Yeah i merged https://code.launchpad.net/~aacid/unity8/fixQmlTestsNewSDK/+merge/280260 and forgot to set it as prerequisite, will do now.

Albert Astals Cid (aacid) wrote :

> I don't get why you had to make those changes in tests/qmltests/Panel/tst_IndicatorsMenu.qml

That's https://code.launchpad.net/~aacid/unity8/testIndicatorsMenuFix/+merge/280165 I merged it in because i wanted to have as few errors as possible in qmluitests run

Albert Astals Cid (aacid) wrote :

> This "wait(1000);" in tests/qmltests/Stages/tst_PhoneStage.qml doesn't look right.

Yeah, removed, now for some reason there's failing tests there i did not have when i presented the branch, i'll investigate.

Daniel d'Andrada (dandrader) wrote :

-- checking for module 'UbuntuGestures'
-- package 'UbuntuGestures' not found

Getting this error in my arm chroot. Might be related to the fact that uitk replaced the package libubuntugestures with libubuntugestures5

Daniel d'Andrada (dandrader) wrote :

In src/CMakeLists.txt

"""
# For it to find libUbuntuGestures.so
set_target_properties(${SHELL_APP} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}")
"""

You can remove this since we no longer build libUbuntuGestures ourselves.

Daniel d'Andrada (dandrader) wrote :

In src/CMakeLists.txt:

"""
include_directories(
    ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
    ${CMAKE_SOURCE_DIR}/libs/UbuntuGestures
    ${CONNECTIVITY_INCLUDE_DIRS}
)
"""

"${CMAKE_SOURCE_DIR}/libs/UbuntuGestures" should go away as well.

Albert Astals Cid (aacid) wrote :

Fixed the src/CMakeLists.txt issues

Daniel d'Andrada (dandrader) wrote :

"""
// don't go the whole distance in order to smooth out the movement
"""

Please remove that comment from qml/Components/DragHandle.qml as well

Daniel d'Andrada (dandrader) wrote :

Looks like FloatingFlickable is broken. I'm no longer able to move the list of windows in the desktop spread with my finger.

review: Needs Fixing
Michael Terry (mterry) wrote :

Ugh, if this lands it blocks my tutorial-redesign branch on landing the monitorOnly mode in the SDK. Which I'll get started on trying to land anyway. But still. I'm sad to lose the race. :(

PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2108
http://jenkins.qa.ubuntu.com/job/unity8-ci/6975/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5852
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/390/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1685
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/388
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1580
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1580
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/387
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/386
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4511
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5863
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5863/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26170
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/151/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/388
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/388/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26173

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6975/rebuild

review: Needs Fixing (continuous-integration)
Daniel d'Andrada (dandrader) wrote :

Code looks good. Didn't spot any regressions on my Nexus 7 in tablet nor desktop modes

review: Approve
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2114
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/245/
Executed test runs:

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/245/rebuild

review: Needs Fixing (continuous-integration)
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2116
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/645/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/366
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/366
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/366
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/850
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/866
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/866
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/864
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/864/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/864
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/864/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/864
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/864/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/864
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/864/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/864
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/864/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/864
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/864/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/645/rebuild

review: Needs Fixing (continuous-integration)
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2117
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/700/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/400/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/400/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/400/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/924
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/940
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/940
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/938
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/938/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/938
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/938/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/938
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/938/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/938
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/938/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/938
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/938/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/938
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/938/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/700/rebuild

review: Needs Fixing (continuous-integration)
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Albert Astals Cid (aacid) wrote :

Lots of stuff changed behind my feet so need to update this :'(

Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2120
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/865/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1153
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1133
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1133
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1131
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1131/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1131/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1131
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1131/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1131/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1131
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1131/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1131/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/865/rebuild

review: Needs Fixing (continuous-integration)
Michael Terry (mterry) wrote :

The new SwipeArea property "grabGesture" (which is an inverse of the property the new tutorial uses -- "monitorOnly"), landed in the released toolkit now.

So that's not a blocker anymore.

Albert Astals Cid (aacid) wrote :

> The new SwipeArea property "grabGesture" (which is an inverse of the property
> the new tutorial uses -- "monitorOnly"), landed in the released toolkit now.
>
> So that's not a blocker anymore.

I'd say we should still wait for https://code.launchpad.net/~aacid/unity8/nodda/+merge/280814 to get released too since it's a bugfix that we have on our side that the SDK doesn't.

lp:~aacid/unity8/nodda updated on 2016-04-13
2121. By Albert Astals Cid on 2016-04-13

Merge

lp:~aacid/unity8/nodda updated on 2016-04-13
2122. By Albert Astals Cid on 2016-04-13

Fix borken merge

Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2122
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/987/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/559
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/559
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/559/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1329
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1300
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1300
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1298
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1298/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1298
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1298/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1298
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1298/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1298
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1298/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1298
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1298/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1298
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1298/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/987/rebuild

review: Needs Fixing (continuous-integration)
Daniel d'Andrada (dandrader) wrote :

On 13/04/2016 05:28, Albert Astals Cid wrote:
>> The new SwipeArea property "grabGesture" (which is an inverse of the property
>> the new tutorial uses -- "monitorOnly"), landed in the released toolkit now.
>>
>> So that's not a blocker anymore.
> I'd say we should still wait for https://code.launchpad.net/~aacid/unity8/nodda/+merge/280814 to get released too since it's a bugfix that we have on our side that the SDK doesn't.

I think you pasted the wrong URL...

Albert Astals Cid (aacid) wrote :

> On 13/04/2016 05:28, Albert Astals Cid wrote:
> >> The new SwipeArea property "grabGesture" (which is an inverse of the
> property
> >> the new tutorial uses -- "monitorOnly"), landed in the released toolkit
> now.
> >>
> >> So that's not a blocker anymore.
> > I'd say we should still wait for
> https://code.launchpad.net/~aacid/unity8/nodda/+merge/280814 to get released
> too since it's a bugfix that we have on our side that the SDK doesn't.
>
> I think you pasted the wrong URL...

Right, i meant https://code.launchpad.net/~aacid/ubuntu-ui-toolkit/touchRegistryUnity8Fixes/+merge/290024

lp:~aacid/unity8/nodda updated on 2016-04-26
2123. By Albert Astals Cid on 2016-04-26

Merge

Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2123
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1052/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1418
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1385
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1385
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1385
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1385
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1385/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1385/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1385
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1385/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1385
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1385/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1385/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1385
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1385/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1385
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1385/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1385/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1385
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1385/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1052/rebuild

review: Needs Fixing (continuous-integration)
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2123
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1066/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/615
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/615/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/615/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1435
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1401
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1401
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1401
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1401/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1401
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1401/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1401
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1401/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1401
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1401/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1401
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1401/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1401
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1401/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1066/rebuild

review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/nodda updated on 2016-05-02
2124. By Albert Astals Cid on 2016-05-02

Merge

Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2124
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1098/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/651
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/651
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/651/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1475
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1440
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1440
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1440
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1440/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1440
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1440/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1440
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1440/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1440
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1440/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1440
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1440/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1440
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1440/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1098/rebuild

review: Needs Fixing (continuous-integration)
Daniel d'Andrada (dandrader) wrote :

Addded cmake checks for libubuntugestures5-dev and libubuntugestures5-private-dev in lp:~dandrader/unity8/nodda (rev 2377)

lp:~aacid/unity8/nodda updated on 2016-05-02
2125. By Daniel d'Andrada on 2016-05-02

Add cmake check for libubuntugestures5-dev and libubuntugestures5-private-dev

Daniel d'Andrada (dandrader) wrote :

* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes.

* Did CI run pass? If not, please explain why.
Only one failure which seems unrelated (https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/651/console). Link doesn't even exist...

review: Approve
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2125
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1105/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/658
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/658
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/658
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1483
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1448
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1448
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1448
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1448/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1448
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1448/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1448
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1448/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1448
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1448/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1448
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1448/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1448
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1448/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/1105/rebuild

review: Needs Fixing (continuous-integration)

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

Subscribers

People subscribed via source and target branches