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
1=== modified file 'plugins/Utils/CMakeLists.txt'
2--- plugins/Utils/CMakeLists.txt 2016-12-21 10:20:36 +0000
3+++ plugins/Utils/CMakeLists.txt 2017-02-07 16:54:54 +0000
4@@ -35,6 +35,7 @@
5 globalfunctions.cpp
6 URLDispatcher.cpp
7 tabfocusfence.cpp
8+ expressionfiltermodel.cpp
9 plugin.cpp
10 )
11
12
13=== added file 'plugins/Utils/expressionfiltermodel.cpp'
14--- plugins/Utils/expressionfiltermodel.cpp 1970-01-01 00:00:00 +0000
15+++ plugins/Utils/expressionfiltermodel.cpp 2017-02-07 16:54:54 +0000
16@@ -0,0 +1,49 @@
17+/*
18+ * Copyright (C) 2017 Canonical, Ltd.
19+ *
20+ * This program is free software; you can redistribute it and/or modify
21+ * it under the terms of the GNU General Public License as published by
22+ * the Free Software Foundation; version 3.
23+ *
24+ * This program is distributed in the hope that it will be useful,
25+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27+ * GNU General Public License for more details.
28+ *
29+ * You should have received a copy of the GNU General Public License
30+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31+ */
32+
33+#include "expressionfiltermodel.h"
34+
35+ExpressionFilterModel::ExpressionFilterModel(QObject *parent)
36+ : UnitySortFilterProxyModelQML(parent)
37+{
38+}
39+
40+QJSValue ExpressionFilterModel::matchExpression() const
41+{
42+ return m_matchExpression;
43+}
44+
45+void ExpressionFilterModel::setMatchExpression(const QJSValue &value)
46+{
47+ m_matchExpression = value;
48+ invalidateFilter();
49+}
50+
51+bool
52+ExpressionFilterModel::filterAcceptsRow(int sourceRow,
53+ const QModelIndex &sourceParent) const
54+{
55+ if (m_matchExpression.isCallable()) {
56+ QJSValueList args;
57+ args << sourceRow;
58+ QJSValue ret = m_matchExpression.call(args);
59+ if (ret.isBool()) {
60+ return ret.toBool();
61+ }
62+ }
63+
64+ return UnitySortFilterProxyModelQML::filterAcceptsRow(sourceRow, sourceParent);
65+}
66
67=== added file 'plugins/Utils/expressionfiltermodel.h'
68--- plugins/Utils/expressionfiltermodel.h 1970-01-01 00:00:00 +0000
69+++ plugins/Utils/expressionfiltermodel.h 2017-02-07 16:54:54 +0000
70@@ -0,0 +1,42 @@
71+/*
72+ * Copyright (C) 2017 Canonical, Ltd.
73+ *
74+ * This program is free software; you can redistribute it and/or modify
75+ * it under the terms of the GNU General Public License as published by
76+ * the Free Software Foundation; version 3.
77+ *
78+ * This program is distributed in the hope that it will be useful,
79+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
80+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81+ * GNU General Public License for more details.
82+ *
83+ * You should have received a copy of the GNU General Public License
84+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
85+ */
86+
87+#ifndef EXPRESSIONFILTERMODEL_H
88+#define EXPRESSIONFILTERMODEL_H
89+
90+#include "unitysortfilterproxymodelqml.h"
91+#include <QJSValue>
92+
93+class ExpressionFilterModel : public UnitySortFilterProxyModelQML
94+{
95+ Q_OBJECT
96+ Q_PROPERTY(QJSValue matchExpression READ matchExpression WRITE setMatchExpression NOTIFY matchExpressionChanged)
97+public:
98+ explicit ExpressionFilterModel(QObject *parent = 0);
99+
100+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
101+
102+ QJSValue matchExpression() const;
103+ void setMatchExpression(const QJSValue& value);
104+
105+Q_SIGNALS:
106+ void matchExpressionChanged();
107+
108+private:
109+ mutable QJSValue m_matchExpression;
110+};
111+
112+#endif // EXPRESSIONFILTERMODEL_H
113
114=== modified file 'plugins/Utils/plugin.cpp'
115--- plugins/Utils/plugin.cpp 2017-01-03 12:16:00 +0000
116+++ plugins/Utils/plugin.cpp 2017-02-07 16:54:54 +0000
117@@ -41,6 +41,7 @@
118 #include "URLDispatcher.h"
119 #include "appdrawerproxymodel.h"
120 #include "tabfocusfence.h"
121+#include "expressionfiltermodel.h"
122
123 static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
124 {
125@@ -86,4 +87,5 @@
126 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
127 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
128 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
129+ qmlRegisterType<ExpressionFilterModel>(uri, 0, 1, "ExpressionFilterModel");
130 }
131
132=== modified file 'qml/ApplicationMenus/MenuBar.qml'
133--- qml/ApplicationMenus/MenuBar.qml 2017-02-07 16:54:54 +0000
134+++ qml/ApplicationMenus/MenuBar.qml 2017-02-07 16:54:54 +0000
135@@ -24,12 +24,13 @@
136 id: root
137 objectName: "menuBar"
138
139+ // set from outside
140 property alias unityMenuModel: rowRepeater.model
141+ property bool enableKeyFilter: false
142+ property real overflowWidth: width
143
144+ // read from outside
145 readonly property bool valid: rowRepeater.count > 0
146-
147- property bool enableKeyFilter: false
148-
149 readonly property bool showRequested: d.longAltPressed || d.currentItem != null
150
151 implicitWidth: row.width
152@@ -75,197 +76,334 @@
153 acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
154 anchors.fill: parent
155 enabled: d.currentItem != null
156- hoverEnabled: enabled && d.currentItem.__popup != null
157+ hoverEnabled: enabled && d.currentItem && d.currentItem.__popup != null
158 onPressed: d.dismissAll()
159 }
160
161- Item {
162- id: clippingItem
163-
164- height: root.height
165- width: root.width
166- clip: true
167-
168- Row {
169- id: row
170- spacing: units.gu(2)
171- height: parent.height
172-
173- ActionContext {
174- id: menuBarContext
175- objectName: "barContext"
176- active: !d.currentItem && enableKeyFilter
177- }
178-
179- Repeater {
180- id: rowRepeater
181-
182- Item {
183- id: visualItem
184- objectName: root.objectName + "-item" + __ownIndex
185-
186- readonly property int __ownIndex: index
187- property Item __popup: null;
188- property bool popupVisible: __popup && __popup.visible
189-
190- implicitWidth: column.implicitWidth
191- implicitHeight: row.height
192- enabled: model.sensitive
193-
194- function show() {
195- if (!__popup) {
196- __popup = menuComponent.createObject(root, { objectName: visualItem.objectName + "-menu" });
197- __popup.childActivated.connect(dismiss);
198- // force the current item to be the newly popped up menu
199- } else {
200- __popup.show();
201- }
202- d.currentItem = visualItem;
203- }
204- function hide() {
205- if (__popup) {
206- __popup.hide();
207-
208- if (d.currentItem === visualItem) {
209- d.currentItem = null;
210- }
211- }
212- }
213- function dismiss() {
214- if (__popup) {
215- __popup.destroy();
216- __popup = null;
217-
218- if (d.currentItem === visualItem) {
219- d.currentItem = null;
220- }
221- }
222- }
223-
224- Connections {
225- target: d
226- onDismissAll: visualItem.dismiss()
227- }
228-
229- Component {
230- id: menuComponent
231- MenuPopup {
232- desiredX: visualItem.x - units.gu(1)
233- desiredY: parent.height
234- unityMenuModel: root.unityMenuModel.submenu(visualItem.__ownIndex)
235-
236- Component.onCompleted: reset();
237- }
238- }
239-
240- RowLayout {
241- id: column
242- spacing: units.gu(1)
243- anchors {
244- centerIn: parent
245- }
246-
247- Icon {
248- Layout.preferredWidth: units.gu(2)
249- Layout.preferredHeight: units.gu(2)
250- Layout.alignment: Qt.AlignVCenter
251-
252- visible: model.icon || false
253- source: model.icon || ""
254- }
255-
256- ActionItem {
257- id: actionItem
258- width: _title.width
259- height: _title.height
260-
261- action: Action {
262- // FIXME - SDK Action:text modifies menu text with html underline for mnemonic
263- text: model.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")
264-
265- onTriggered: {
266- visualItem.show();
267- }
268- }
269-
270- Label {
271- id: _title
272- text: actionItem.text
273- horizontalAlignment: Text.AlignLeft
274- color: enabled ? "white" : "#5d5d5d"
275- }
276- }
277- }
278- } // Item ( delegate )
279- } // Repeater
280- } // Row
281-
282- MouseArea {
283- anchors.fill: parent
284- hoverEnabled: d.currentItem
285-
286- onEntered: {
287- if (d.currentItem) {
288- updateCurrentItemFromPosition(Qt.point(mouseX, mouseY))
289- }
290- }
291- onPositionChanged: {
292- if (d.currentItem) {
293- updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))
294- }
295- }
296- onClicked: {
297- var prevItem = d.currentItem;
298+ Row {
299+ id: row
300+ spacing: units.gu(2)
301+ height: parent.height
302+
303+ ActionContext {
304+ id: menuBarContext
305+ objectName: "barContext"
306+ active: !d.currentItem && enableKeyFilter
307+ }
308+
309+ Connections {
310+ target: root.unityMenuModel
311+ onModelReset: d.firstInvisibleIndex = undefined
312+ }
313+
314+ Repeater {
315+ id: rowRepeater
316+
317+ onItemAdded: d.recalcFirstInvisibleIndexAdded(index, item)
318+ onCountChanged: d.recalcFirstInvisibleIndex()
319+
320+ Item {
321+ id: visualItem
322+ objectName: root.objectName + "-item" + __ownIndex
323+
324+ readonly property int __ownIndex: index
325+ property Item __popup: null;
326+ readonly property bool popupVisible: __popup && __popup.visible
327+ readonly property bool shouldDisplay: x + width + ((__ownIndex < rowRepeater.count-1) ? units.gu(2) : 0) <
328+ root.overflowWidth - ((__ownIndex < rowRepeater.count-1) ? overflowButton.width : 0)
329+
330+ implicitWidth: column.implicitWidth
331+ implicitHeight: row.height
332+ enabled: model.sensitive && shouldDisplay
333+ opacity: shouldDisplay ? 1 : 0
334+
335+ function show() {
336+ if (!__popup) {
337+ __popup = menuComponent.createObject(root, { objectName: visualItem.objectName + "-menu" });
338+ __popup.childActivated.connect(dismiss);
339+ // force the current item to be the newly popped up menu
340+ } else {
341+ __popup.show();
342+ }
343+ d.currentItem = visualItem;
344+ }
345+ function hide() {
346+ if (__popup) {
347+ __popup.hide();
348+
349+ if (d.currentItem === visualItem) {
350+ d.currentItem = null;
351+ }
352+ }
353+ }
354+ function dismiss() {
355+ if (__popup) {
356+ __popup.destroy();
357+ __popup = null;
358+
359+ if (d.currentItem === visualItem) {
360+ d.currentItem = null;
361+ }
362+ }
363+ }
364+
365+ onVisibleChanged: {
366+ if (!visible && __popup) dismiss();
367+ }
368+
369+ onShouldDisplayChanged: {
370+ if ((!shouldDisplay && d.firstInvisibleIndex == undefined) || __ownIndex <= d.firstInvisibleIndex) {
371+ d.recalcFirstInvisibleIndex();
372+ }
373+ }
374+
375+ Connections {
376+ target: d
377+ onDismissAll: visualItem.dismiss()
378+ }
379+
380+ Component {
381+ id: menuComponent
382+ MenuPopup {
383+ desiredX: visualItem.x - units.gu(1)
384+ desiredY: parent.height
385+ unityMenuModel: root.unityMenuModel.submenu(visualItem.__ownIndex)
386+
387+ Component.onCompleted: reset();
388+ }
389+ }
390+
391+ RowLayout {
392+ id: column
393+ spacing: units.gu(1)
394+ anchors {
395+ centerIn: parent
396+ }
397+
398+ Icon {
399+ Layout.preferredWidth: units.gu(2)
400+ Layout.preferredHeight: units.gu(2)
401+ Layout.alignment: Qt.AlignVCenter
402+
403+ visible: model.icon || false
404+ source: model.icon || ""
405+ }
406+
407+ ActionItem {
408+ id: actionItem
409+ width: _title.width
410+ height: _title.height
411+
412+ action: Action {
413+ enabled: visualItem.enabled
414+ // FIXME - SDK Action:text modifies menu text with html underline for mnemonic
415+ text: model.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")
416+
417+ onTriggered: {
418+ visualItem.show();
419+ }
420+ }
421+
422+ Label {
423+ id: _title
424+ text: actionItem.text
425+ horizontalAlignment: Text.AlignLeft
426+ color: enabled ? "white" : "#5d5d5d"
427+ }
428+ }
429+ }
430+ } // Item ( delegate )
431+ } // Repeater
432+ } // Row
433+
434+ MouseArea {
435+ anchors.fill: parent
436+ hoverEnabled: d.currentItem
437+
438+ onEntered: {
439+ if (d.currentItem) {
440+ updateCurrentItemFromPosition(Qt.point(mouseX, mouseY))
441+ }
442+ }
443+ onPositionChanged: {
444+ if (d.currentItem) {
445 updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))
446- if (prevItem && d.currentItem == prevItem) {
447- prevItem.hide();
448- }
449- }
450-
451- function updateCurrentItemFromPosition(point) {
452- var pos = mapToItem(row, point.x, point.y);
453-
454- if (!d.hoveredItem || !d.currentItem || !d.hoveredItem.contains(Qt.point(pos.x - d.currentItem.x, pos.y - d.currentItem.y))) {
455- d.hoveredItem = row.childAt(pos.x, pos.y);
456- if (!d.hoveredItem || !d.hoveredItem.enabled)
457- return false;
458- if (d.currentItem != d.hoveredItem) {
459- d.currentItem = d.hoveredItem;
460- }
461- }
462- return true;
463- }
464- }
465-
466- Rectangle {
467- id: underline
468- anchors {
469- bottom: row.bottom
470- }
471- x: d.currentItem ? row.x + d.currentItem.x - units.gu(1) : 0
472- width: d.currentItem ? d.currentItem.width + units.gu(2) : 0
473- height: units.dp(4)
474- color: UbuntuColors.orange
475- visible: d.currentItem
476- }
477+ }
478+ }
479+ onClicked: {
480+ var prevItem = d.currentItem;
481+ updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))
482+ if (prevItem && d.currentItem == prevItem) {
483+ prevItem.hide();
484+ }
485+ }
486+
487+ function updateCurrentItemFromPosition(point) {
488+ var pos = mapToItem(row, point.x, point.y);
489+
490+ if (!d.hoveredItem || !d.currentItem || !d.hoveredItem.contains(Qt.point(pos.x - d.currentItem.x, pos.y - d.currentItem.y))) {
491+ d.hoveredItem = row.childAt(pos.x, pos.y);
492+ if (!d.hoveredItem || !d.hoveredItem.enabled)
493+ return;
494+ if (d.currentItem != d.hoveredItem) {
495+ d.currentItem = d.hoveredItem;
496+ }
497+ }
498+ }
499+ }
500+
501+ MouseArea {
502+ id: overflowButton
503+ objectName: "overflow"
504+
505+ hoverEnabled: d.currentItem
506+ onEntered: d.currentItem = this
507+ onPositionChanged: d.currentItem = this
508+ onClicked: d.currentItem = this
509+
510+ property Item __popup: null;
511+ readonly property bool popupVisible: __popup && __popup.visible
512+ readonly property Item firstInvisibleItem: d.firstInvisibleIndex !== undefined ? rowRepeater.itemAt(d.firstInvisibleIndex) : null
513+
514+ visible: d.firstInvisibleIndex != undefined
515+ x: firstInvisibleItem ? firstInvisibleItem.x : 0
516+
517+ height: parent.height
518+ width: units.gu(4)
519+
520+ onVisibleChanged: {
521+ if (!visible && __popup) dismiss();
522+ }
523+
524+ Icon {
525+ id: icon
526+ width: units.gu(2)
527+ height: units.gu(2)
528+ anchors.centerIn: parent
529+ color: theme.palette.normal.overlayText
530+ name: "toolkit_chevron-down_2gu"
531+ }
532+
533+ function show() {
534+ if (!__popup) {
535+ __popup = overflowComponent.createObject(root, { objectName: overflowButton.objectName + "-menu" });
536+ __popup.childActivated.connect(dismiss);
537+ // force the current item to be the newly popped up menu
538+ } else {
539+ __popup.show();
540+ }
541+ d.currentItem = overflowButton;
542+ }
543+ function hide() {
544+ if (__popup) {
545+ __popup.hide();
546+
547+ if (d.currentItem === overflowButton) {
548+ d.currentItem = null;
549+ }
550+ }
551+ }
552+ function dismiss() {
553+ if (__popup) {
554+ __popup.destroy();
555+ __popup = null;
556+
557+ if (d.currentItem === overflowButton) {
558+ d.currentItem = null;
559+ }
560+ }
561+ }
562+
563+ Connections {
564+ target: d
565+ onDismissAll: overflowButton.dismiss()
566+ }
567+
568+ Component {
569+ id: overflowComponent
570+ MenuPopup {
571+ id: overflowPopup
572+ desiredX: overflowButton.x - units.gu(1)
573+ desiredY: parent.height
574+ unityMenuModel: overflowModel
575+
576+ ExpressionFilterModel {
577+ id: overflowModel
578+ sourceModel: root.unityMenuModel
579+ matchExpression: function(index) {
580+ if (d.firstInvisibleIndex === undefined) return false;
581+ return index >= d.firstInvisibleIndex;
582+ }
583+
584+ function submenu(index) {
585+ return sourceModel.submenu(mapRowToSource(index));
586+ }
587+ function activate(index) {
588+ return sourceModel.activate(mapRowToSource(index));
589+ }
590+ }
591+
592+ Connections {
593+ target: d
594+ onFirstInvisibleIndexChanged: overflowModel.invalidate()
595+ }
596+ }
597+ }
598+ }
599+
600+ Rectangle {
601+ id: underline
602+ anchors {
603+ bottom: row.bottom
604+ }
605+ x: d.currentItem ? row.x + d.currentItem.x - units.gu(1) : 0
606+ width: d.currentItem ? d.currentItem.width + units.gu(2) : 0
607+ height: units.dp(4)
608+ color: UbuntuColors.orange
609+ visible: d.currentItem
610 }
611
612 MenuNavigator {
613 id: d
614 objectName: "d"
615 itemView: rowRepeater
616+ hasOverflow: overflowButton.visible
617
618 property Item currentItem: null
619 property Item hoveredItem: null
620 property Item prevCurrentItem: null
621-
622- readonly property int currentIndex: currentItem ? currentItem.__ownIndex : -1
623-
624 property bool altPressed: false
625 property bool longAltPressed: false
626+ property var firstInvisibleIndex: undefined
627+
628+ readonly property int currentIndex: currentItem && currentItem.hasOwnProperty("__ownIndex") ? currentItem.__ownIndex : -1
629
630 signal dismissAll()
631
632+ function recalcFirstInvisibleIndexAdded(index, item) {
633+ if (firstInvisibleIndex === undefined) {
634+ if (!item.shouldDisplay) {
635+ firstInvisibleIndex = index;
636+ }
637+ } else if (index <= firstInvisibleIndex) {
638+ if (!item.shouldDisplay) {
639+ firstInvisibleIndex = index;
640+ } else {
641+ firstInvisibleIndex++;
642+ }
643+ }
644+ }
645+
646+ function recalcFirstInvisibleIndex() {
647+ for (var i = 0; i < rowRepeater.count; i++) {
648+ if (!rowRepeater.itemAt(i).shouldDisplay) {
649+ firstInvisibleIndex = i;
650+ return;
651+ }
652+ }
653+ firstInvisibleIndex = undefined;
654+ }
655+
656 onSelect: {
657 var delegate = rowRepeater.itemAt(index);
658 if (delegate) {
659@@ -273,6 +411,10 @@
660 }
661 }
662
663+ onOverflow: {
664+ d.currentItem = overflowButton;
665+ }
666+
667 onCurrentItemChanged: {
668 if (prevCurrentItem && prevCurrentItem != currentItem) {
669 if (currentItem) {
670
671=== modified file 'qml/ApplicationMenus/MenuItem.qml'
672--- qml/ApplicationMenus/MenuItem.qml 2017-02-07 16:54:54 +0000
673+++ qml/ApplicationMenus/MenuItem.qml 2017-02-07 16:54:54 +0000
674@@ -46,6 +46,8 @@
675 enabled: menuData ? menuData.sensitive : false
676
677 action: Action {
678+ enabled: root.enabled
679+
680 // FIXME - SDK Action:text modifies menu text with html underline for mnemonic
681 text: menuData.label.replace("_", "&").replace("<u>", "&").replace("</u>", "")
682 checkable: menuData.isCheck || menuData.isRadio
683@@ -137,7 +139,7 @@
684 theme.palette.disabled.backgroundSecondaryText
685
686 visible: root.hasSubmenu
687- name: "chevron"
688+ name: "toolkit_chevron-ltr_2gu"
689 }
690 }
691 }
692
693=== modified file 'qml/ApplicationMenus/MenuNavigator.qml'
694--- qml/ApplicationMenus/MenuNavigator.qml 2016-11-28 13:44:30 +0000
695+++ qml/ApplicationMenus/MenuNavigator.qml 2017-02-07 16:54:54 +0000
696@@ -18,8 +18,10 @@
697
698 QtObject {
699 property Item itemView: null
700+ property bool hasOverflow: false
701
702 signal select(int index)
703+ signal overflow()
704
705 function selectNext(currentIndex) {
706 var menu;
707@@ -32,6 +34,11 @@
708 break;
709 }
710 newIndex++;
711+
712+ if (hasOverflow && newIndex === itemView.count) {
713+ overflow()
714+ break;
715+ }
716 }
717 } else if (currentIndex !== -1 && itemView.count > 1) {
718 var startIndex = (currentIndex + 1) % itemView.count;
719@@ -42,6 +49,12 @@
720 select(newIndex);
721 break;
722 }
723+
724+ if (hasOverflow && newIndex + 1 === itemView.count) {
725+ overflow()
726+ break;
727+ }
728+
729 newIndex = (newIndex + 1) % itemView.count;
730 } while (newIndex !== startIndex)
731 }
732@@ -58,12 +71,21 @@
733 break;
734 }
735 newIndex--;
736+
737+ if (hasOverflow && newIndex < 0 ) {
738+ overflow();
739+ break;
740+ }
741 }
742 } else if (currentIndex !== -1 && itemView.count > 1) {
743 var startIndex = currentIndex - 1;
744 newIndex = startIndex;
745 do {
746 if (newIndex < 0) {
747+ if (hasOverflow) {
748+ overflow();
749+ break;
750+ }
751 newIndex = itemView.count - 1;
752 }
753 menu = itemView.itemAt(newIndex);
754@@ -72,6 +94,7 @@
755 break;
756 }
757 newIndex--;
758+
759 } while (newIndex !== startIndex)
760 }
761 }
762
763=== modified file 'qml/ApplicationMenus/MenuPopup.qml'
764--- qml/ApplicationMenus/MenuPopup.qml 2017-02-07 16:54:54 +0000
765+++ qml/ApplicationMenus/MenuPopup.qml 2017-02-07 16:54:54 +0000
766@@ -19,6 +19,7 @@
767 import Ubuntu.Components 1.3
768 import Ubuntu.Components.ListItems 1.3 as ListItems
769 import "../Components"
770+import "../Components/PanelState"
771 import "."
772
773 UbuntuShape {
774@@ -100,7 +101,7 @@
775 property real __minimumWidth: units.gu(20)
776 property real __maximumWidth: ApplicationMenusLimits.screenWidth * 0.7
777 property real __minimumHeight: units.gu(2)
778- property real __maximumHeight: ApplicationMenusLimits.screenHeight * 0.7
779+ property real __maximumHeight: ApplicationMenusLimits.screenHeight - PanelState.panelHeight
780
781 signal dismissAll()
782
783@@ -183,8 +184,19 @@
784 }
785
786 MouseArea {
787+ id: previousMA
788 anchors.fill: parent
789- onPressed: {
790+ hoverEnabled: enabled
791+ onPressed: progress()
792+
793+ Timer {
794+ running: previousMA.containsMouse && !listView.atYBeginning
795+ interval: 1000
796+ repeat: true
797+ onTriggered: previousMA.progress()
798+ }
799+
800+ function progress() {
801 var item = menuColumn.childAt(0, listView.contentY);
802 if (item) {
803 var previousItem = item;
804@@ -412,8 +424,19 @@
805 }
806
807 MouseArea {
808+ id: nextMA
809 anchors.fill: parent
810- onPressed: {
811+ hoverEnabled: enabled
812+ onPressed: progress()
813+
814+ Timer {
815+ running: nextMA.containsMouse && !listView.atYEnd
816+ interval: 1000
817+ repeat: true
818+ onTriggered: nextMA.progress()
819+ }
820+
821+ function progress() {
822 var item = menuColumn.childAt(0, listView.contentY + listView.height);
823 if (item) {
824 var nextItem = item;
825
826=== modified file 'qml/Panel/Panel.qml'
827--- qml/Panel/Panel.qml 2017-01-09 14:10:17 +0000
828+++ qml/Panel/Panel.qml 2017-02-07 16:54:54 +0000
829@@ -209,6 +209,8 @@
830 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
831 active: __applicationMenus.model
832
833+ width: parent.width - windowControlButtons.width - units.gu(2) - __indicators.barWidth
834+
835 property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false
836
837 sourceComponent: MenuBar {
838@@ -385,7 +387,7 @@
839 }
840
841 enabled: !applicationMenus.expanded
842- opacity: !applicationMenus.expanded ? 1 : 0
843+ opacity: !callHint.visible && !applicationMenus.expanded ? 1 : 0
844 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
845
846 onEnabledChanged: {
847
848=== modified file 'tests/mocks/Utils/CMakeLists.txt'
849--- tests/mocks/Utils/CMakeLists.txt 2016-12-21 10:20:36 +0000
850+++ tests/mocks/Utils/CMakeLists.txt 2017-02-07 16:54:54 +0000
851@@ -26,6 +26,7 @@
852 ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp
853 ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp
854 ${CMAKE_SOURCE_DIR}/plugins/Utils/tabfocusfence.cpp
855+ ${CMAKE_SOURCE_DIR}/plugins/Utils/expressionfiltermodel.cpp
856 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
857 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
858 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
859
860=== modified file 'tests/mocks/Utils/plugin.cpp'
861--- tests/mocks/Utils/plugin.cpp 2017-01-03 12:16:00 +0000
862+++ tests/mocks/Utils/plugin.cpp 2017-02-07 16:54:54 +0000
863@@ -42,6 +42,7 @@
864 #include <globalfunctions.h>
865 #include <appdrawerproxymodel.h>
866 #include <tabfocusfence.h>
867+#include <expressionfiltermodel.h>
868
869 static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
870 {
871@@ -86,4 +87,5 @@
872 qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
873 qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
874 qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
875+ qmlRegisterType<ExpressionFilterModel>(uri, 0, 1, "ExpressionFilterModel");
876 }
877
878=== modified file 'tests/qmltests/ApplicationMenus/tst_MenuBar.qml'
879--- tests/qmltests/ApplicationMenus/tst_MenuBar.qml 2017-02-07 16:54:54 +0000
880+++ tests/qmltests/ApplicationMenus/tst_MenuBar.qml 2017-02-07 16:54:54 +0000
881@@ -28,8 +28,8 @@
882
883 Item {
884 id: root
885- width: units.gu(100)
886- height: units.gu(50)
887+ width: units.gu(120)
888+ height: units.gu(70)
889
890 Component.onCompleted: {
891 QuickUtils.keyboardAttached = true;
892@@ -51,11 +51,11 @@
893 Rectangle {
894 anchors {
895 left: parent.left
896- right: parent.right
897 top: parent.top
898 margins: units.gu(1)
899 }
900 height: units.gu(3)
901+ width: parent.width * 2/3
902 color: "grey"
903
904 MenuBar {
905@@ -65,7 +65,7 @@
906
907 unityMenuModel: UnityMenuModel {
908 id: menuBackend
909- modelData: appMenuData.generateTestData(17,5,2,3)
910+ modelData: appMenuData.generateTestData(10,5,2,3)
911 }
912 }
913 }
914@@ -83,12 +83,12 @@
915
916 function init() {
917 menuBar.dismiss();
918- menuBackend.modelData = appMenuData.generateTestData(5,5,2,3)
919+ menuBackend.modelData = appMenuData.generateTestData(5,5,2,3, "menu")
920 activatedSpy.clear();
921 }
922
923 function test_mouseNavigation() {
924- menuBackend.modelData = appMenuData.generateTestData(3,3,0,0);
925+ menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
926 wait(50) // wait for row to build
927 var priv = findInvisibleChild(menuBar, "d");
928
929@@ -114,7 +114,7 @@
930 }
931
932 function test_keyboardNavigation_RightKeySelectsNextMenuItem(data) {
933- menuBackend.modelData = appMenuData.generateTestData(3,3,0,0);
934+ menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
935 var priv = findInvisibleChild(menuBar, "d");
936
937 var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);
938@@ -139,7 +139,7 @@
939 }
940
941 function test_keyboardNavigation_LeftKeySelectsPreviousMenuItem(data) {
942- menuBackend.modelData = appMenuData.generateTestData(3,3,0,0);
943+ menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
944 var priv = findInvisibleChild(menuBar, "d");
945
946 var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);
947@@ -242,5 +242,31 @@
948 mouseClick(menuItem);
949 compare(priv.currentItem, null, "CurrentItem should be null");
950 }
951+
952+ function test_overfow() {
953+ menuBackend.modelData = appMenuData.generateTestData(5,2,0,0,"menu");
954+
955+ var overflow = findChild(menuBar, "overflow");
956+ compare(overflow.visible, false, "Overflow should not be visible");
957+
958+ var menu = { "rowData": { "label": "Short" } };
959+ tryCompareFunction(function() {
960+ menuBackend.insertRow(0, menu);
961+ wait(1);
962+ if (overflow.visible) {
963+ return true;
964+ }
965+ return false;
966+ }, true);
967+
968+ tryCompareFunction(function() {
969+ menuBackend.removeRow(0);
970+ wait(1);
971+ if (!overflow.visible) {
972+ return true;
973+ }
974+ return false;
975+ }, true);
976+ }
977 }
978 }

Subscribers

People subscribed via source and target branches