Merge lp:~nick-dedekind/unity8/menu.overflow into lp:unity8

Proposed by Nick Dedekind
Status: Merged
Approved by: Albert Astals Cid
Approved revision: 2790
Merged at revision: 2815
Proposed branch: lp:~nick-dedekind/unity8/menu.overflow
Merge into: lp:unity8
Prerequisite: lp:~aacid/unity8/eatHoverWhenMenuIsOpen
Diff against target: 978 lines (+503/-188)
12 files modified
plugins/Utils/CMakeLists.txt (+1/-0)
plugins/Utils/expressionfiltermodel.cpp (+49/-0)
plugins/Utils/expressionfiltermodel.h (+42/-0)
plugins/Utils/plugin.cpp (+2/-0)
qml/ApplicationMenus/MenuBar.qml (+317/-175)
qml/ApplicationMenus/MenuItem.qml (+3/-1)
qml/ApplicationMenus/MenuNavigator.qml (+23/-0)
qml/ApplicationMenus/MenuPopup.qml (+26/-3)
qml/Panel/Panel.qml (+3/-1)
tests/mocks/Utils/CMakeLists.txt (+1/-0)
tests/mocks/Utils/plugin.cpp (+2/-0)
tests/qmltests/ApplicationMenus/tst_MenuBar.qml (+34/-8)
To merge this branch: bzr merge lp:~nick-dedekind/unity8/menu.overflow
Reviewer Review Type Date Requested Status
Albert Astals Cid (community) Approve
Unity8 CI Bot continuous-integration Approve
Lukáš Tinkl Pending
Review via email: mp+315925@code.launchpad.net

This proposal supersedes a proposal from 2017-01-24.

Commit message

Added overflow support to application menus.
Hover timer for auto-scrolling menu popup overflow.

Description of the change

* Are there any related MPs required for this MP to build/function as expected? Please list.
N/A

 * Did you perform an exploratory manual test run of your code change and any related functionality?
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?
Yes

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

/<<BUILDDIR>>/unity8-8.15+17.04.20170110.4+fetch3941bzr2778/qml/ApplicationMenus/MenuNavigator.qml: bad whitespace in line 83

review: Needs Fixing
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

PASSED: Continuous integration, rev:2780
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3015/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3922
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2299
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2299
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3950
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3795
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3795/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3795
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3795/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3795
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3795/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3795
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3795/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3795
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3795/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3795
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3795/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2781
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3018/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3925
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2301
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2301
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3953
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3798
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3798/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3798
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3798/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3798
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3798/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3798
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3798/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3798
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3798/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3798
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3798/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

MenuNavigator.qml: bad whitespace in line 83

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

Text conflict in plugins/Utils/CMakeLists.txt
Text conflict in plugins/Utils/plugin.cpp
Text conflict in tests/mocks/Utils/CMakeLists.txt
Text conflict in tests/mocks/Utils/plugin.cpp
Text conflict in tests/qmltests/ApplicationMenus/tst_MenuBar.qml
5 conflicts encountered.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal

> Text conflict in plugins/Utils/CMakeLists.txt
> Text conflict in plugins/Utils/plugin.cpp
> Text conflict in tests/mocks/Utils/CMakeLists.txt
> Text conflict in tests/mocks/Utils/plugin.cpp
> Text conflict in tests/qmltests/ApplicationMenus/tst_MenuBar.qml
> 5 conflicts encountered.

merged

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2782
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3042/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3957
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2313
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2313
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3985
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3830
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3830/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3830
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3830/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3830
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3830/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3830
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3830/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3830
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3830/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3830
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3830/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

PASSED: Continuous integration, rev:2782
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3049/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3964
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2317
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2317
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3992
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3837
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3837/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3837
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3837/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3837
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3837/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3837
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3837/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3837
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3837/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3837
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3837/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2785
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3086/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4011
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2349
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2349
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4039
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3883/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2785
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3085/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4010
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2350
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2350
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4038
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3882
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3882/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3882
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3882/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3882
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3882/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3882
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3882/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3882
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3882/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3882
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3882/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Seems you have broken the menu positioning when it collides with the bottom border.

Run make tryDesktopStage, move the window down so that the menu would collide with the window bottom border and open it, previously it would show inside the window just fine, now it shows just the Up/down arrows and that's it.

review: Needs Fixing
2786. By Nick Dedekind

removed height change

Revision history for this message
Albert Astals Cid (aacid) wrote :

Seems you removed two tests from tst_MenuBar.qml by mistake?

review: Needs Fixing
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2786
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3089/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/4016/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4044
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3888
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3888/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3888
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3888/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3888
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3888/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3888/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3888
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3888/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3888
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3888/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
2787. By Nick Dedekind

moved shouldDisplay connection

Revision history for this message
Albert Astals Cid (aacid) wrote :

Looking good :)

Some minor things

Readd test_menuActivateClosesMenu() and test_subMenuActivateClosesMenu()

Remove console.log("progress!")

Make readonly (if possible)
   visualItem: property bool popupVisible
   visualItem: property bool shouldDisplay
   overflowButton: property bool popupVisible
   overflowButton: property Item firstInvisibleItem

review: Needs Fixing
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2787
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3090/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4017
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2353
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2353
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4045
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3889
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3889/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3889
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3889/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3889
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3889/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3889
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3889/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3889
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3889/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3889
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3889/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
2788. By Nick Dedekind

include panel height in max height calc

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2788
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3091/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4019
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2354
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2354
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4047
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3891
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3891/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3891
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3891/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3891
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3891/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3891
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3891/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3891
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3891/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3891
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3891/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
2789. By Nick Dedekind

readd tests

2790. By Nick Dedekind

review comments

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2789
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3097/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4025
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2358
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2358
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4053
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3897
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3897/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3897
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3897/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3897
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3897/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3897
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3897/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3897
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3897/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3897
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3897/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2790
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3102/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4031
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2362
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2362
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4059
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3903
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3903/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3903
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3903/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3903
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3903/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3903
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3903/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3903
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3903/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3903
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3903/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) 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.
Yes

review: Approve
2791. By Nick Dedekind

merged with parent

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/Utils/CMakeLists.txt'
--- plugins/Utils/CMakeLists.txt 2016-12-21 10:20:36 +0000
+++ plugins/Utils/CMakeLists.txt 2017-02-07 16:54:54 +0000
@@ -35,6 +35,7 @@
35 globalfunctions.cpp35 globalfunctions.cpp
36 URLDispatcher.cpp36 URLDispatcher.cpp
37 tabfocusfence.cpp37 tabfocusfence.cpp
38 expressionfiltermodel.cpp
38 plugin.cpp39 plugin.cpp
39 )40 )
4041
4142
=== added file 'plugins/Utils/expressionfiltermodel.cpp'
--- plugins/Utils/expressionfiltermodel.cpp 1970-01-01 00:00:00 +0000
+++ plugins/Utils/expressionfiltermodel.cpp 2017-02-07 16:54:54 +0000
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "expressionfiltermodel.h"
18
19ExpressionFilterModel::ExpressionFilterModel(QObject *parent)
20 : UnitySortFilterProxyModelQML(parent)
21{
22}
23
24QJSValue ExpressionFilterModel::matchExpression() const
25{
26 return m_matchExpression;
27}
28
29void ExpressionFilterModel::setMatchExpression(const QJSValue &value)
30{
31 m_matchExpression = value;
32 invalidateFilter();
33}
34
35bool
36ExpressionFilterModel::filterAcceptsRow(int sourceRow,
37 const QModelIndex &sourceParent) const
38{
39 if (m_matchExpression.isCallable()) {
40 QJSValueList args;
41 args << sourceRow;
42 QJSValue ret = m_matchExpression.call(args);
43 if (ret.isBool()) {
44 return ret.toBool();
45 }
46 }
47
48 return UnitySortFilterProxyModelQML::filterAcceptsRow(sourceRow, sourceParent);
49}
050
=== added file 'plugins/Utils/expressionfiltermodel.h'
--- plugins/Utils/expressionfiltermodel.h 1970-01-01 00:00:00 +0000
+++ plugins/Utils/expressionfiltermodel.h 2017-02-07 16:54:54 +0000
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef EXPRESSIONFILTERMODEL_H
18#define EXPRESSIONFILTERMODEL_H
19
20#include "unitysortfilterproxymodelqml.h"
21#include <QJSValue>
22
23class ExpressionFilterModel : public UnitySortFilterProxyModelQML
24{
25 Q_OBJECT
26 Q_PROPERTY(QJSValue matchExpression READ matchExpression WRITE setMatchExpression NOTIFY matchExpressionChanged)
27public:
28 explicit ExpressionFilterModel(QObject *parent = 0);
29
30 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
31
32 QJSValue matchExpression() const;
33 void setMatchExpression(const QJSValue& value);
34
35Q_SIGNALS:
36 void matchExpressionChanged();
37
38private:
39 mutable QJSValue m_matchExpression;
40};
41
42#endif // EXPRESSIONFILTERMODEL_H
043
=== modified file 'plugins/Utils/plugin.cpp'
--- plugins/Utils/plugin.cpp 2017-01-03 12:16:00 +0000
+++ plugins/Utils/plugin.cpp 2017-02-07 16:54:54 +0000
@@ -41,6 +41,7 @@
41#include "URLDispatcher.h"41#include "URLDispatcher.h"
42#include "appdrawerproxymodel.h"42#include "appdrawerproxymodel.h"
43#include "tabfocusfence.h"43#include "tabfocusfence.h"
44#include "expressionfiltermodel.h"
4445
45static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)46static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
46{47{
@@ -86,4 +87,5 @@
86 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");87 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
87 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");88 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
88 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");89 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
90 qmlRegisterType<ExpressionFilterModel>(uri, 0, 1, "ExpressionFilterModel");
89}91}
9092
=== modified file 'qml/ApplicationMenus/MenuBar.qml'
--- qml/ApplicationMenus/MenuBar.qml 2017-02-07 16:54:54 +0000
+++ qml/ApplicationMenus/MenuBar.qml 2017-02-07 16:54:54 +0000
@@ -24,12 +24,13 @@
24 id: root24 id: root
25 objectName: "menuBar"25 objectName: "menuBar"
2626
27 // set from outside
27 property alias unityMenuModel: rowRepeater.model28 property alias unityMenuModel: rowRepeater.model
29 property bool enableKeyFilter: false
30 property real overflowWidth: width
2831
32 // read from outside
29 readonly property bool valid: rowRepeater.count > 033 readonly property bool valid: rowRepeater.count > 0
30
31 property bool enableKeyFilter: false
32
33 readonly property bool showRequested: d.longAltPressed || d.currentItem != null34 readonly property bool showRequested: d.longAltPressed || d.currentItem != null
3435
35 implicitWidth: row.width36 implicitWidth: row.width
@@ -75,197 +76,334 @@
75 acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton76 acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
76 anchors.fill: parent77 anchors.fill: parent
77 enabled: d.currentItem != null78 enabled: d.currentItem != null
78 hoverEnabled: enabled && d.currentItem.__popup != null79 hoverEnabled: enabled && d.currentItem && d.currentItem.__popup != null
79 onPressed: d.dismissAll()80 onPressed: d.dismissAll()
80 }81 }
8182
82 Item {83 Row {
83 id: clippingItem84 id: row
8485 spacing: units.gu(2)
85 height: root.height86 height: parent.height
86 width: root.width87
87 clip: true88 ActionContext {
8889 id: menuBarContext
89 Row {90 objectName: "barContext"
90 id: row91 active: !d.currentItem && enableKeyFilter
91 spacing: units.gu(2)92 }
92 height: parent.height93
9394 Connections {
94 ActionContext {95 target: root.unityMenuModel
95 id: menuBarContext96 onModelReset: d.firstInvisibleIndex = undefined
96 objectName: "barContext"97 }
97 active: !d.currentItem && enableKeyFilter98
98 }99 Repeater {
99100 id: rowRepeater
100 Repeater {101
101 id: rowRepeater102 onItemAdded: d.recalcFirstInvisibleIndexAdded(index, item)
102103 onCountChanged: d.recalcFirstInvisibleIndex()
103 Item {104
104 id: visualItem105 Item {
105 objectName: root.objectName + "-item" + __ownIndex106 id: visualItem
106107 objectName: root.objectName + "-item" + __ownIndex
107 readonly property int __ownIndex: index108
108 property Item __popup: null;109 readonly property int __ownIndex: index
109 property bool popupVisible: __popup && __popup.visible110 property Item __popup: null;
110111 readonly property bool popupVisible: __popup && __popup.visible
111 implicitWidth: column.implicitWidth112 readonly property bool shouldDisplay: x + width + ((__ownIndex < rowRepeater.count-1) ? units.gu(2) : 0) <
112 implicitHeight: row.height113 root.overflowWidth - ((__ownIndex < rowRepeater.count-1) ? overflowButton.width : 0)
113 enabled: model.sensitive114
114115 implicitWidth: column.implicitWidth
115 function show() {116 implicitHeight: row.height
116 if (!__popup) {117 enabled: model.sensitive && shouldDisplay
117 __popup = menuComponent.createObject(root, { objectName: visualItem.objectName + "-menu" });118 opacity: shouldDisplay ? 1 : 0
118 __popup.childActivated.connect(dismiss);119
119 // force the current item to be the newly popped up menu120 function show() {
120 } else {121 if (!__popup) {
121 __popup.show();122 __popup = menuComponent.createObject(root, { objectName: visualItem.objectName + "-menu" });
122 }123 __popup.childActivated.connect(dismiss);
123 d.currentItem = visualItem;124 // force the current item to be the newly popped up menu
124 }125 } else {
125 function hide() {126 __popup.show();
126 if (__popup) {127 }
127 __popup.hide();128 d.currentItem = visualItem;
128129 }
129 if (d.currentItem === visualItem) {130 function hide() {
130 d.currentItem = null;131 if (__popup) {
131 }132 __popup.hide();
132 }133
133 }134 if (d.currentItem === visualItem) {
134 function dismiss() {135 d.currentItem = null;
135 if (__popup) {136 }
136 __popup.destroy();137 }
137 __popup = null;138 }
138139 function dismiss() {
139 if (d.currentItem === visualItem) {140 if (__popup) {
140 d.currentItem = null;141 __popup.destroy();
141 }142 __popup = null;
142 }143
143 }144 if (d.currentItem === visualItem) {
144145 d.currentItem = null;
145 Connections {146 }
146 target: d147 }
147 onDismissAll: visualItem.dismiss()148 }
148 }149
149150 onVisibleChanged: {
150 Component {151 if (!visible && __popup) dismiss();
151 id: menuComponent152 }
152 MenuPopup {153
153 desiredX: visualItem.x - units.gu(1)154 onShouldDisplayChanged: {
154 desiredY: parent.height155 if ((!shouldDisplay && d.firstInvisibleIndex == undefined) || __ownIndex <= d.firstInvisibleIndex) {
155 unityMenuModel: root.unityMenuModel.submenu(visualItem.__ownIndex)156 d.recalcFirstInvisibleIndex();
156157 }
157 Component.onCompleted: reset();158 }
158 }159
159 }160 Connections {
160161 target: d
161 RowLayout {162 onDismissAll: visualItem.dismiss()
162 id: column163 }
163 spacing: units.gu(1)164
164 anchors {165 Component {
165 centerIn: parent166 id: menuComponent
166 }167 MenuPopup {
167168 desiredX: visualItem.x - units.gu(1)
168 Icon {169 desiredY: parent.height
169 Layout.preferredWidth: units.gu(2)170 unityMenuModel: root.unityMenuModel.submenu(visualItem.__ownIndex)
170 Layout.preferredHeight: units.gu(2)171
171 Layout.alignment: Qt.AlignVCenter172 Component.onCompleted: reset();
172173 }
173 visible: model.icon || false174 }
174 source: model.icon || ""175
175 }176 RowLayout {
176177 id: column
177 ActionItem {178 spacing: units.gu(1)
178 id: actionItem179 anchors {
179 width: _title.width180 centerIn: parent
180 height: _title.height181 }
181182
182 action: Action {183 Icon {
183 // FIXME - SDK Action:text modifies menu text with html underline for mnemonic184 Layout.preferredWidth: units.gu(2)
184 text: model.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")185 Layout.preferredHeight: units.gu(2)
185186 Layout.alignment: Qt.AlignVCenter
186 onTriggered: {187
187 visualItem.show();188 visible: model.icon || false
188 }189 source: model.icon || ""
189 }190 }
190191
191 Label {192 ActionItem {
192 id: _title193 id: actionItem
193 text: actionItem.text194 width: _title.width
194 horizontalAlignment: Text.AlignLeft195 height: _title.height
195 color: enabled ? "white" : "#5d5d5d"196
196 }197 action: Action {
197 }198 enabled: visualItem.enabled
198 }199 // FIXME - SDK Action:text modifies menu text with html underline for mnemonic
199 } // Item ( delegate )200 text: model.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")
200 } // Repeater201
201 } // Row202 onTriggered: {
202203 visualItem.show();
203 MouseArea {204 }
204 anchors.fill: parent205 }
205 hoverEnabled: d.currentItem206
206207 Label {
207 onEntered: {208 id: _title
208 if (d.currentItem) {209 text: actionItem.text
209 updateCurrentItemFromPosition(Qt.point(mouseX, mouseY))210 horizontalAlignment: Text.AlignLeft
210 }211 color: enabled ? "white" : "#5d5d5d"
211 }212 }
212 onPositionChanged: {213 }
213 if (d.currentItem) {214 }
214 updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))215 } // Item ( delegate )
215 }216 } // Repeater
216 }217 } // Row
217 onClicked: {218
218 var prevItem = d.currentItem;219 MouseArea {
220 anchors.fill: parent
221 hoverEnabled: d.currentItem
222
223 onEntered: {
224 if (d.currentItem) {
225 updateCurrentItemFromPosition(Qt.point(mouseX, mouseY))
226 }
227 }
228 onPositionChanged: {
229 if (d.currentItem) {
219 updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))230 updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))
220 if (prevItem && d.currentItem == prevItem) {231 }
221 prevItem.hide();232 }
222 }233 onClicked: {
223 }234 var prevItem = d.currentItem;
224235 updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))
225 function updateCurrentItemFromPosition(point) {236 if (prevItem && d.currentItem == prevItem) {
226 var pos = mapToItem(row, point.x, point.y);237 prevItem.hide();
227238 }
228 if (!d.hoveredItem || !d.currentItem || !d.hoveredItem.contains(Qt.point(pos.x - d.currentItem.x, pos.y - d.currentItem.y))) {239 }
229 d.hoveredItem = row.childAt(pos.x, pos.y);240
230 if (!d.hoveredItem || !d.hoveredItem.enabled)241 function updateCurrentItemFromPosition(point) {
231 return false;242 var pos = mapToItem(row, point.x, point.y);
232 if (d.currentItem != d.hoveredItem) {243
233 d.currentItem = d.hoveredItem;244 if (!d.hoveredItem || !d.currentItem || !d.hoveredItem.contains(Qt.point(pos.x - d.currentItem.x, pos.y - d.currentItem.y))) {
234 }245 d.hoveredItem = row.childAt(pos.x, pos.y);
235 }246 if (!d.hoveredItem || !d.hoveredItem.enabled)
236 return true;247 return;
237 }248 if (d.currentItem != d.hoveredItem) {
238 }249 d.currentItem = d.hoveredItem;
239250 }
240 Rectangle {251 }
241 id: underline252 }
242 anchors {253 }
243 bottom: row.bottom254
244 }255 MouseArea {
245 x: d.currentItem ? row.x + d.currentItem.x - units.gu(1) : 0256 id: overflowButton
246 width: d.currentItem ? d.currentItem.width + units.gu(2) : 0257 objectName: "overflow"
247 height: units.dp(4)258
248 color: UbuntuColors.orange259 hoverEnabled: d.currentItem
249 visible: d.currentItem260 onEntered: d.currentItem = this
250 }261 onPositionChanged: d.currentItem = this
262 onClicked: d.currentItem = this
263
264 property Item __popup: null;
265 readonly property bool popupVisible: __popup && __popup.visible
266 readonly property Item firstInvisibleItem: d.firstInvisibleIndex !== undefined ? rowRepeater.itemAt(d.firstInvisibleIndex) : null
267
268 visible: d.firstInvisibleIndex != undefined
269 x: firstInvisibleItem ? firstInvisibleItem.x : 0
270
271 height: parent.height
272 width: units.gu(4)
273
274 onVisibleChanged: {
275 if (!visible && __popup) dismiss();
276 }
277
278 Icon {
279 id: icon
280 width: units.gu(2)
281 height: units.gu(2)
282 anchors.centerIn: parent
283 color: theme.palette.normal.overlayText
284 name: "toolkit_chevron-down_2gu"
285 }
286
287 function show() {
288 if (!__popup) {
289 __popup = overflowComponent.createObject(root, { objectName: overflowButton.objectName + "-menu" });
290 __popup.childActivated.connect(dismiss);
291 // force the current item to be the newly popped up menu
292 } else {
293 __popup.show();
294 }
295 d.currentItem = overflowButton;
296 }
297 function hide() {
298 if (__popup) {
299 __popup.hide();
300
301 if (d.currentItem === overflowButton) {
302 d.currentItem = null;
303 }
304 }
305 }
306 function dismiss() {
307 if (__popup) {
308 __popup.destroy();
309 __popup = null;
310
311 if (d.currentItem === overflowButton) {
312 d.currentItem = null;
313 }
314 }
315 }
316
317 Connections {
318 target: d
319 onDismissAll: overflowButton.dismiss()
320 }
321
322 Component {
323 id: overflowComponent
324 MenuPopup {
325 id: overflowPopup
326 desiredX: overflowButton.x - units.gu(1)
327 desiredY: parent.height
328 unityMenuModel: overflowModel
329
330 ExpressionFilterModel {
331 id: overflowModel
332 sourceModel: root.unityMenuModel
333 matchExpression: function(index) {
334 if (d.firstInvisibleIndex === undefined) return false;
335 return index >= d.firstInvisibleIndex;
336 }
337
338 function submenu(index) {
339 return sourceModel.submenu(mapRowToSource(index));
340 }
341 function activate(index) {
342 return sourceModel.activate(mapRowToSource(index));
343 }
344 }
345
346 Connections {
347 target: d
348 onFirstInvisibleIndexChanged: overflowModel.invalidate()
349 }
350 }
351 }
352 }
353
354 Rectangle {
355 id: underline
356 anchors {
357 bottom: row.bottom
358 }
359 x: d.currentItem ? row.x + d.currentItem.x - units.gu(1) : 0
360 width: d.currentItem ? d.currentItem.width + units.gu(2) : 0
361 height: units.dp(4)
362 color: UbuntuColors.orange
363 visible: d.currentItem
251 }364 }
252365
253 MenuNavigator {366 MenuNavigator {
254 id: d367 id: d
255 objectName: "d"368 objectName: "d"
256 itemView: rowRepeater369 itemView: rowRepeater
370 hasOverflow: overflowButton.visible
257371
258 property Item currentItem: null372 property Item currentItem: null
259 property Item hoveredItem: null373 property Item hoveredItem: null
260 property Item prevCurrentItem: null374 property Item prevCurrentItem: null
261
262 readonly property int currentIndex: currentItem ? currentItem.__ownIndex : -1
263
264 property bool altPressed: false375 property bool altPressed: false
265 property bool longAltPressed: false376 property bool longAltPressed: false
377 property var firstInvisibleIndex: undefined
378
379 readonly property int currentIndex: currentItem && currentItem.hasOwnProperty("__ownIndex") ? currentItem.__ownIndex : -1
266380
267 signal dismissAll()381 signal dismissAll()
268382
383 function recalcFirstInvisibleIndexAdded(index, item) {
384 if (firstInvisibleIndex === undefined) {
385 if (!item.shouldDisplay) {
386 firstInvisibleIndex = index;
387 }
388 } else if (index <= firstInvisibleIndex) {
389 if (!item.shouldDisplay) {
390 firstInvisibleIndex = index;
391 } else {
392 firstInvisibleIndex++;
393 }
394 }
395 }
396
397 function recalcFirstInvisibleIndex() {
398 for (var i = 0; i < rowRepeater.count; i++) {
399 if (!rowRepeater.itemAt(i).shouldDisplay) {
400 firstInvisibleIndex = i;
401 return;
402 }
403 }
404 firstInvisibleIndex = undefined;
405 }
406
269 onSelect: {407 onSelect: {
270 var delegate = rowRepeater.itemAt(index);408 var delegate = rowRepeater.itemAt(index);
271 if (delegate) {409 if (delegate) {
@@ -273,6 +411,10 @@
273 }411 }
274 }412 }
275413
414 onOverflow: {
415 d.currentItem = overflowButton;
416 }
417
276 onCurrentItemChanged: {418 onCurrentItemChanged: {
277 if (prevCurrentItem && prevCurrentItem != currentItem) {419 if (prevCurrentItem && prevCurrentItem != currentItem) {
278 if (currentItem) {420 if (currentItem) {
279421
=== modified file 'qml/ApplicationMenus/MenuItem.qml'
--- qml/ApplicationMenus/MenuItem.qml 2017-02-07 16:54:54 +0000
+++ qml/ApplicationMenus/MenuItem.qml 2017-02-07 16:54:54 +0000
@@ -46,6 +46,8 @@
46 enabled: menuData ? menuData.sensitive : false46 enabled: menuData ? menuData.sensitive : false
4747
48 action: Action {48 action: Action {
49 enabled: root.enabled
50
49 // FIXME - SDK Action:text modifies menu text with html underline for mnemonic51 // FIXME - SDK Action:text modifies menu text with html underline for mnemonic
50 text: menuData.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")52 text: menuData.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")
51 checkable: menuData.isCheck || menuData.isRadio53 checkable: menuData.isCheck || menuData.isRadio
@@ -137,7 +139,7 @@
137 theme.palette.disabled.backgroundSecondaryText139 theme.palette.disabled.backgroundSecondaryText
138140
139 visible: root.hasSubmenu141 visible: root.hasSubmenu
140 name: "chevron"142 name: "toolkit_chevron-ltr_2gu"
141 }143 }
142 }144 }
143}145}
144146
=== modified file 'qml/ApplicationMenus/MenuNavigator.qml'
--- qml/ApplicationMenus/MenuNavigator.qml 2016-11-28 13:44:30 +0000
+++ qml/ApplicationMenus/MenuNavigator.qml 2017-02-07 16:54:54 +0000
@@ -18,8 +18,10 @@
1818
19QtObject {19QtObject {
20 property Item itemView: null20 property Item itemView: null
21 property bool hasOverflow: false
2122
22 signal select(int index)23 signal select(int index)
24 signal overflow()
2325
24 function selectNext(currentIndex) {26 function selectNext(currentIndex) {
25 var menu;27 var menu;
@@ -32,6 +34,11 @@
32 break;34 break;
33 }35 }
34 newIndex++;36 newIndex++;
37
38 if (hasOverflow && newIndex === itemView.count) {
39 overflow()
40 break;
41 }
35 }42 }
36 } else if (currentIndex !== -1 && itemView.count > 1) {43 } else if (currentIndex !== -1 && itemView.count > 1) {
37 var startIndex = (currentIndex + 1) % itemView.count;44 var startIndex = (currentIndex + 1) % itemView.count;
@@ -42,6 +49,12 @@
42 select(newIndex);49 select(newIndex);
43 break;50 break;
44 }51 }
52
53 if (hasOverflow && newIndex + 1 === itemView.count) {
54 overflow()
55 break;
56 }
57
45 newIndex = (newIndex + 1) % itemView.count;58 newIndex = (newIndex + 1) % itemView.count;
46 } while (newIndex !== startIndex)59 } while (newIndex !== startIndex)
47 }60 }
@@ -58,12 +71,21 @@
58 break;71 break;
59 }72 }
60 newIndex--;73 newIndex--;
74
75 if (hasOverflow && newIndex < 0 ) {
76 overflow();
77 break;
78 }
61 }79 }
62 } else if (currentIndex !== -1 && itemView.count > 1) {80 } else if (currentIndex !== -1 && itemView.count > 1) {
63 var startIndex = currentIndex - 1;81 var startIndex = currentIndex - 1;
64 newIndex = startIndex;82 newIndex = startIndex;
65 do {83 do {
66 if (newIndex < 0) {84 if (newIndex < 0) {
85 if (hasOverflow) {
86 overflow();
87 break;
88 }
67 newIndex = itemView.count - 1;89 newIndex = itemView.count - 1;
68 }90 }
69 menu = itemView.itemAt(newIndex);91 menu = itemView.itemAt(newIndex);
@@ -72,6 +94,7 @@
72 break;94 break;
73 }95 }
74 newIndex--;96 newIndex--;
97
75 } while (newIndex !== startIndex)98 } while (newIndex !== startIndex)
76 }99 }
77 }100 }
78101
=== modified file 'qml/ApplicationMenus/MenuPopup.qml'
--- qml/ApplicationMenus/MenuPopup.qml 2017-02-07 16:54:54 +0000
+++ qml/ApplicationMenus/MenuPopup.qml 2017-02-07 16:54:54 +0000
@@ -19,6 +19,7 @@
19import Ubuntu.Components 1.319import Ubuntu.Components 1.3
20import Ubuntu.Components.ListItems 1.3 as ListItems20import Ubuntu.Components.ListItems 1.3 as ListItems
21import "../Components"21import "../Components"
22import "../Components/PanelState"
22import "."23import "."
2324
24UbuntuShape {25UbuntuShape {
@@ -100,7 +101,7 @@
100 property real __minimumWidth: units.gu(20)101 property real __minimumWidth: units.gu(20)
101 property real __maximumWidth: ApplicationMenusLimits.screenWidth * 0.7102 property real __maximumWidth: ApplicationMenusLimits.screenWidth * 0.7
102 property real __minimumHeight: units.gu(2)103 property real __minimumHeight: units.gu(2)
103 property real __maximumHeight: ApplicationMenusLimits.screenHeight * 0.7104 property real __maximumHeight: ApplicationMenusLimits.screenHeight - PanelState.panelHeight
104105
105 signal dismissAll()106 signal dismissAll()
106107
@@ -183,8 +184,19 @@
183 }184 }
184185
185 MouseArea {186 MouseArea {
187 id: previousMA
186 anchors.fill: parent188 anchors.fill: parent
187 onPressed: {189 hoverEnabled: enabled
190 onPressed: progress()
191
192 Timer {
193 running: previousMA.containsMouse && !listView.atYBeginning
194 interval: 1000
195 repeat: true
196 onTriggered: previousMA.progress()
197 }
198
199 function progress() {
188 var item = menuColumn.childAt(0, listView.contentY);200 var item = menuColumn.childAt(0, listView.contentY);
189 if (item) {201 if (item) {
190 var previousItem = item;202 var previousItem = item;
@@ -412,8 +424,19 @@
412 }424 }
413425
414 MouseArea {426 MouseArea {
427 id: nextMA
415 anchors.fill: parent428 anchors.fill: parent
416 onPressed: {429 hoverEnabled: enabled
430 onPressed: progress()
431
432 Timer {
433 running: nextMA.containsMouse && !listView.atYEnd
434 interval: 1000
435 repeat: true
436 onTriggered: nextMA.progress()
437 }
438
439 function progress() {
417 var item = menuColumn.childAt(0, listView.contentY + listView.height);440 var item = menuColumn.childAt(0, listView.contentY + listView.height);
418 if (item) {441 if (item) {
419 var nextItem = item;442 var nextItem = item;
420443
=== modified file 'qml/Panel/Panel.qml'
--- qml/Panel/Panel.qml 2017-01-09 14:10:17 +0000
+++ qml/Panel/Panel.qml 2017-02-07 16:54:54 +0000
@@ -209,6 +209,8 @@
209 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }209 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
210 active: __applicationMenus.model210 active: __applicationMenus.model
211211
212 width: parent.width - windowControlButtons.width - units.gu(2) - __indicators.barWidth
213
212 property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false214 property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false
213215
214 sourceComponent: MenuBar {216 sourceComponent: MenuBar {
@@ -385,7 +387,7 @@
385 }387 }
386388
387 enabled: !applicationMenus.expanded389 enabled: !applicationMenus.expanded
388 opacity: !applicationMenus.expanded ? 1 : 0390 opacity: !callHint.visible && !applicationMenus.expanded ? 1 : 0
389 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }391 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
390392
391 onEnabledChanged: {393 onEnabledChanged: {
392394
=== modified file 'tests/mocks/Utils/CMakeLists.txt'
--- tests/mocks/Utils/CMakeLists.txt 2016-12-21 10:20:36 +0000
+++ tests/mocks/Utils/CMakeLists.txt 2017-02-07 16:54:54 +0000
@@ -26,6 +26,7 @@
26 ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp26 ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp
27 ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp27 ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp
28 ${CMAKE_SOURCE_DIR}/plugins/Utils/tabfocusfence.cpp28 ${CMAKE_SOURCE_DIR}/plugins/Utils/tabfocusfence.cpp
29 ${CMAKE_SOURCE_DIR}/plugins/Utils/expressionfiltermodel.cpp
29 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h30 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
30 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h31 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
31 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h32 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
3233
=== modified file 'tests/mocks/Utils/plugin.cpp'
--- tests/mocks/Utils/plugin.cpp 2017-01-03 12:16:00 +0000
+++ tests/mocks/Utils/plugin.cpp 2017-02-07 16:54:54 +0000
@@ -42,6 +42,7 @@
42#include <globalfunctions.h>42#include <globalfunctions.h>
43#include <appdrawerproxymodel.h>43#include <appdrawerproxymodel.h>
44#include <tabfocusfence.h>44#include <tabfocusfence.h>
45#include <expressionfiltermodel.h>
4546
46static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)47static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
47{48{
@@ -86,4 +87,5 @@
86 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");87 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
87 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");88 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
88 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");89 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
90 qmlRegisterType<ExpressionFilterModel>(uri, 0, 1, "ExpressionFilterModel");
89}91}
9092
=== modified file 'tests/qmltests/ApplicationMenus/tst_MenuBar.qml'
--- tests/qmltests/ApplicationMenus/tst_MenuBar.qml 2017-02-07 16:54:54 +0000
+++ tests/qmltests/ApplicationMenus/tst_MenuBar.qml 2017-02-07 16:54:54 +0000
@@ -28,8 +28,8 @@
2828
29Item {29Item {
30 id: root30 id: root
31 width: units.gu(100)31 width: units.gu(120)
32 height: units.gu(50)32 height: units.gu(70)
3333
34 Component.onCompleted: {34 Component.onCompleted: {
35 QuickUtils.keyboardAttached = true;35 QuickUtils.keyboardAttached = true;
@@ -51,11 +51,11 @@
51 Rectangle {51 Rectangle {
52 anchors {52 anchors {
53 left: parent.left53 left: parent.left
54 right: parent.right
55 top: parent.top54 top: parent.top
56 margins: units.gu(1)55 margins: units.gu(1)
57 }56 }
58 height: units.gu(3)57 height: units.gu(3)
58 width: parent.width * 2/3
59 color: "grey"59 color: "grey"
6060
61 MenuBar {61 MenuBar {
@@ -65,7 +65,7 @@
6565
66 unityMenuModel: UnityMenuModel {66 unityMenuModel: UnityMenuModel {
67 id: menuBackend67 id: menuBackend
68 modelData: appMenuData.generateTestData(17,5,2,3)68 modelData: appMenuData.generateTestData(10,5,2,3)
69 }69 }
70 }70 }
71 }71 }
@@ -83,12 +83,12 @@
8383
84 function init() {84 function init() {
85 menuBar.dismiss();85 menuBar.dismiss();
86 menuBackend.modelData = appMenuData.generateTestData(5,5,2,3)86 menuBackend.modelData = appMenuData.generateTestData(5,5,2,3, "menu")
87 activatedSpy.clear();87 activatedSpy.clear();
88 }88 }
8989
90 function test_mouseNavigation() {90 function test_mouseNavigation() {
91 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0);91 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
92 wait(50) // wait for row to build92 wait(50) // wait for row to build
93 var priv = findInvisibleChild(menuBar, "d");93 var priv = findInvisibleChild(menuBar, "d");
9494
@@ -114,7 +114,7 @@
114 }114 }
115115
116 function test_keyboardNavigation_RightKeySelectsNextMenuItem(data) {116 function test_keyboardNavigation_RightKeySelectsNextMenuItem(data) {
117 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0);117 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
118 var priv = findInvisibleChild(menuBar, "d");118 var priv = findInvisibleChild(menuBar, "d");
119119
120 var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);120 var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);
@@ -139,7 +139,7 @@
139 }139 }
140140
141 function test_keyboardNavigation_LeftKeySelectsPreviousMenuItem(data) {141 function test_keyboardNavigation_LeftKeySelectsPreviousMenuItem(data) {
142 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0);142 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
143 var priv = findInvisibleChild(menuBar, "d");143 var priv = findInvisibleChild(menuBar, "d");
144144
145 var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);145 var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);
@@ -242,5 +242,31 @@
242 mouseClick(menuItem);242 mouseClick(menuItem);
243 compare(priv.currentItem, null, "CurrentItem should be null");243 compare(priv.currentItem, null, "CurrentItem should be null");
244 }244 }
245
246 function test_overfow() {
247 menuBackend.modelData = appMenuData.generateTestData(5,2,0,0,"menu");
248
249 var overflow = findChild(menuBar, "overflow");
250 compare(overflow.visible, false, "Overflow should not be visible");
251
252 var menu = { "rowData": { "label": "Short" } };
253 tryCompareFunction(function() {
254 menuBackend.insertRow(0, menu);
255 wait(1);
256 if (overflow.visible) {
257 return true;
258 }
259 return false;
260 }, true);
261
262 tryCompareFunction(function() {
263 menuBackend.removeRow(0);
264 wait(1);
265 if (!overflow.visible) {
266 return true;
267 }
268 return false;
269 }, true);
270 }
245 }271 }
246}272}

Subscribers

People subscribed via source and target branches