Merge lp:~ahayzen/webbrowser-app/dnd-tabs-001 into lp:webbrowser-app

Proposed by Andrew Hayzen
Status: Superseded
Proposed branch: lp:~ahayzen/webbrowser-app/dnd-tabs-001
Merge into: lp:webbrowser-app
Prerequisite: lp:webbrowser-app/staging
Diff against target: 1612 lines (+1080/-47)
22 files modified
po/webbrowser-app.pot (+24/-20)
src/app/webbrowser/Browser.qml (+129/-4)
src/app/webbrowser/BrowserTab.qml (+20/-3)
src/app/webbrowser/CMakeLists.txt (+2/-0)
src/app/webbrowser/Chrome.qml (+6/-0)
src/app/webbrowser/TabComponent.qml (+22/-10)
src/app/webbrowser/TabsBar.qml (+84/-4)
src/app/webbrowser/TabsList.qml (+2/-2)
src/app/webbrowser/drag-helper.cpp (+100/-0)
src/app/webbrowser/drag-helper.h (+61/-0)
src/app/webbrowser/reparenter.cpp (+94/-0)
src/app/webbrowser/reparenter.h (+45/-0)
src/app/webbrowser/webbrowser-app.cpp (+4/-0)
src/app/webbrowser/webbrowser-app.qml (+48/-2)
tests/autopilot/webbrowser_app/tests/__init__.py (+28/-0)
tests/autopilot/webbrowser_app/tests/test_multiple_windows.py (+203/-0)
tests/unittests/qml/CMakeLists.txt (+2/-0)
tests/unittests/qml/ReparenterFakeContainer.qml (+40/-0)
tests/unittests/qml/ReparenterFakeTab.qml (+37/-0)
tests/unittests/qml/tst_BrowserTab.qml (+5/-2)
tests/unittests/qml/tst_QmlTests.cpp (+4/-0)
tests/unittests/qml/tst_Reparenter.qml (+120/-0)
To merge this branch: bzr merge lp:~ahayzen/webbrowser-app/dnd-tabs-001
Reviewer Review Type Date Requested Status
system-apps-ci-bot continuous-integration Needs Fixing
Ubuntu Phablet Team Pending
Review via email: mp+308505@code.launchpad.net

This proposal supersedes a proposal from 2016-09-28.

This proposal has been superseded by a proposal from 2016-10-14.

Commit message

WIP Drag and drop support

Description of the change

WIP Drag and drop support, proposing so that we can get debs easily.

To post a comment you must log in.
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1518
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/661/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1655/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1655
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1501/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1501/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/661/rebuild

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

FAILED: Continuous integration, rev:1518
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/662/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1657/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1657
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1503/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1503/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/662/rebuild

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

FAILED: Continuous integration, rev:1519
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/665/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1683/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1683
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1529/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1529/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1529/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1529/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1529/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1529/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1529/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1529/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1529
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1529/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/665/rebuild

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

FAILED: Continuous integration, rev:1520
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/666/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1691
    UNSTABLE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/403
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1691
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1537/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1537
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1537/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/666/rebuild

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

FAILED: Continuous integration, rev:1521
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/667/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1696
    UNSTABLE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/405
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1696
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1541/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1541
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1541/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/667/rebuild

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

FAILED: Continuous integration, rev:1522
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/668/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1700
    UNSTABLE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/408
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1700
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1545/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1545
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1545/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/668/rebuild

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

FAILED: Continuous integration, rev:1523
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/669/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1701
    UNSTABLE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/409
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1701
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1546/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1546
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1546/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/669/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote : Posted in a previous version of this proposal

tested, works great!
One comment: if you create a private window and then some tabs, not sure if you should be able to drag that tab into a non-private window. Seems to be allowed in this implementation but not sure we want that behavior. Seems in Chromium you can only move private tabs between private windows and public tabs between public windows. Guessing we should follow same thing.

Revision history for this message
Bill Filler (bfiller) wrote : Posted in a previous version of this proposal

previously was testing with unity7, and could drag a tab into it's own new window or drag into another existing browser window. this all functioned well.

On unity8, I encountered the following problems, guessing they are limitations with unity/mir
1) when trying to drag a tab into a new window it actually works but leaves an additional shadow window with pixelated display. so if you start with one window and drag out you are left with 3 windows.
2) cannot seem to drag out of one window and drop in another. I see an icon with circle with line through it on the drop target.
You should probably file qtmir bugs on these

Revision history for this message
Andrew Hayzen (ahayzen) wrote : Posted in a previous version of this proposal

For unity7:
Agreed tabs should not be able to move between windows of different incognito modes, I'll get onto that.

For the issues under unity8:
1) I suspected this is due to handle on the mouse, which didn't work on unity8 when I tried and appeared as a separate window. This seems like the same issue that Gtk/Qt right click menus have where they are in another window. I mentioned this in the bug I reported below as well.
2) I reported a bug in mir while developing https://bugs.launchpad.net/ubuntu/+source/mir/+bug/1627013

Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1524
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/672/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1730
    UNSTABLE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/416
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1730
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1575/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1575
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1575/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/672/rebuild

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

FAILED: Continuous integration, rev:1525
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/674/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1734
    UNSTABLE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/418
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1734
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1579/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1579
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1579/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/674/rebuild

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

FAILED: Continuous integration, rev:1527
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/700/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1817/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1817
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1661/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1661/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1661/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1661/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1661/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1661/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1661/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1661/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1661
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1661/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/700/rebuild

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

FAILED: Continuous integration, rev:1528
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/702/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1826/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1826
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1670/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1670/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1670
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1670/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/702/rebuild

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

FAILED: Continuous integration, rev:1529
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/703/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1835/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1836
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1676/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1676/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1676/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1676
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1676/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/703/rebuild

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

FAILED: Continuous integration, rev:1529
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/704/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/1836/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1837
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1677/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1677
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1677/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1677/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1677
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1677
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1677
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1677
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1677/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1677
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1677/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1677/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/704/rebuild

review: Needs Fixing (continuous-integration)
1531. By Andrew Hayzen

* Fix for progress bar appearing after tab is dragged out

Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :

FAILED: Continuous integration, rev:1530
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/712/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/1844
    FAILURE: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/443/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/1845
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/1685/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1685
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/1685/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-webbrowser-app-ci/712/rebuild

review: Needs Fixing (continuous-integration)
1532. By Andrew Hayzen

* Be more declarative in DropArea
* Change use of DropActions to make more sense
* Change unit test to use default timeout
* Allow setting of expectedAction in DragHelper
* Update uses of null to Q_NULLPTR
* Disable dragging on mir clients

1533. By Andrew Hayzen

* Limit y diff of visual tabitem when dragging

1534. By Andrew Hayzen

* Fix regression where new tabs have massive favicons

1535. By Andrew Hayzen

* Remove white shade on bottom part of browser to match design

1536. By Andrew Hayzen

* Revert change in use of DropAction as dropping outside of a DropArea is always IgnoreAction
* Change test_drag_tab_outside_new_window to move the tab below the window
* Change property tabsBarHeight to be real rather than int

1537. By Andrew Hayzen

* Revert .pot changes

1538. By Andrew Hayzen

* Revert changes to test as it was fine before :-)

1539. By Andrew Hayzen

* Remove referenes to browser, tabModel and windo in TabsBar.qml
* Remove reference to builder in Browser.qml
* Allowed passing of properties to Reparenter::createObject()
* Made Reparenter a singleton
* Moved buildContextProperties() and createTabHelper() into internal to make them private
* Change dropArea.heightThreshold to be real not int
* Removed many console.debug() calls
* Changes includes to be fully-qualified in drag-helper and reparenter
* Renamed closeMethod to callback for newWindowFromTab()

1540. By Andrew Hayzen

* Ensure that switchToTab is called after binding a new tab, otherwise the chrome's position can be broken

1541. By Andrew Hayzen

* Merge of lp:webbrowser-app/staging

1542. By Andrew Hayzen

* Update dropArea shade to match new design
* Fix for bad conflict resolution

1543. By Andrew Hayzen

* Fix for typo

1544. By Andrew Hayzen

* Add .dragging property to DragHelper so that drop area shade knows when a drag event is occuring
* Change DragHelper to a singleton

1545. By Andrew Hayzen

* Changed DragHelper to be a QObject and use member initialisation
* Changed Reparenter::createObject to use beginCreate and completeCreate
* Various fixes to reduce warnings under QML tests

1546. By Andrew Hayzen

* Use forward declaration of QQuickItem

1547. By Andrew Hayzen

* Fix for missed case of createTabHelper -> createTab

1548. By Andrew Hayzen

* Ensure webviews are not shown when newTabView is active

1549. By Andrew Hayzen

* Change keyboard shortcuts to use contentsContainer visibility instead of tabsContainer

1550. By Andrew Hayzen

* Use enabled rather than visible on the tabContainer to prevent events being stolen, otherwise chrome disappears when opening new tabs as the locationBarController.offset doesn't get set

1551. By Andrew Hayzen

* Before tab is closed, check if a new tab needs to be generated as the context will disappear

1552. By Andrew Hayzen

* Use deleteLater rather than delete item; otherwise on slower devices such as phones it crashes
* Don't delete the context if it was not removed from the reparenter context store
* Change qml test for reparenter to respect that the delete may take time to happen

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'po/webbrowser-app.pot'
2--- po/webbrowser-app.pot 2016-10-04 14:07:17 +0000
3+++ po/webbrowser-app.pot 2016-10-14 13:08:37 +0000
4@@ -8,7 +8,7 @@
5 msgstr ""
6 "Project-Id-Version: webbrowser-app\n"
7 "Report-Msgid-Bugs-To: \n"
8-"POT-Creation-Date: 2016-10-04 16:02+0200\n"
9+"POT-Creation-Date: 2016-10-10 17:45+0100\n"
10 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12 "Language-Team: LANGUAGE <LL@li.org>\n"
13@@ -378,7 +378,7 @@
14 msgid "Erase"
15 msgstr ""
16
17-#: src/app/actions/FindInPage.qml:23 src/app/webbrowser/Browser.qml:569
18+#: src/app/actions/FindInPage.qml:23 src/app/webbrowser/Browser.qml:604
19 msgid "Find in page"
20 msgstr ""
21
22@@ -408,8 +408,8 @@
23 msgid "Address;URL;www"
24 msgstr ""
25
26-#: src/app/actions/NewTab.qml:23 src/app/webbrowser/Browser.qml:440
27-#: src/app/webbrowser/TabsBar.qml:91
28+#: src/app/actions/NewTab.qml:23 src/app/webbrowser/Browser.qml:475
29+#: src/app/webbrowser/TabsBar.qml:95
30 msgid "New Tab"
31 msgstr ""
32
33@@ -456,7 +456,7 @@
34 msgstr ""
35
36 #: src/app/actions/Reload.qml:23 src/app/webbrowser/SadTab.qml:86
37-#: src/app/webbrowser/TabsBar.qml:96 src/app/webcontainer/SadPage.qml:51
38+#: src/app/webbrowser/TabsBar.qml:100 src/app/webcontainer/SadPage.qml:51
39 msgid "Reload"
40 msgstr ""
41
42@@ -482,7 +482,7 @@
43 msgid "Select all"
44 msgstr ""
45
46-#: src/app/actions/Share.qml:22 src/app/webbrowser/Browser.qml:549
47+#: src/app/actions/Share.qml:22 src/app/webbrowser/Browser.qml:584
48 msgid "Share"
49 msgstr ""
50
51@@ -547,14 +547,14 @@
52
53 #: src/app/webbrowser/BookmarksView.qml:32
54 #: src/app/webbrowser/BookmarksViewWide.qml:32
55-#: src/app/webbrowser/Browser.qml:557 src/app/webbrowser/NewTabView.qml:130
56+#: src/app/webbrowser/Browser.qml:592 src/app/webbrowser/NewTabView.qml:130
57 #: src/app/webbrowser/NewTabViewWide.qml:139
58 msgid "Bookmarks"
59 msgstr ""
60
61 #: src/app/webbrowser/BookmarksView.qml:76
62 #: src/app/webbrowser/BookmarksViewWide.qml:75
63-#: src/app/webbrowser/Browser.qml:426 src/app/webbrowser/HistoryView.qml:126
64+#: src/app/webbrowser/Browser.qml:461 src/app/webbrowser/HistoryView.qml:126
65 #: src/app/webbrowser/HistoryViewWide.qml:407
66 msgid "Done"
67 msgstr ""
68@@ -563,42 +563,42 @@
69 #: src/app/webbrowser/BookmarksViewWide.qml:89
70 #: src/app/webbrowser/HistoryView.qml:140
71 #: src/app/webbrowser/HistoryViewWide.qml:421
72-#: src/app/webbrowser/TabsBar.qml:153 src/app/webbrowser/TabsList.qml:99
73+#: src/app/webbrowser/TabsBar.qml:174 src/app/webbrowser/TabsList.qml:99
74 msgid "New tab"
75 msgstr ""
76
77-#: src/app/webbrowser/Browser.qml:537
78+#: src/app/webbrowser/Browser.qml:572
79 msgid "New window"
80 msgstr ""
81
82-#: src/app/webbrowser/Browser.qml:543
83+#: src/app/webbrowser/Browser.qml:578
84 msgid "New private window"
85 msgstr ""
86
87-#: src/app/webbrowser/Browser.qml:563 src/app/webbrowser/HistoryView.qml:30
88+#: src/app/webbrowser/Browser.qml:598 src/app/webbrowser/HistoryView.qml:30
89 #: src/app/webbrowser/HistoryViewWide.qml:35
90 msgid "History"
91 msgstr ""
92
93-#: src/app/webbrowser/Browser.qml:576 src/app/webbrowser/DownloadsPage.qml:45
94+#: src/app/webbrowser/Browser.qml:611 src/app/webbrowser/DownloadsPage.qml:45
95 msgid "Downloads"
96 msgstr ""
97
98-#: src/app/webbrowser/Browser.qml:583 src/app/webbrowser/SettingsPage.qml:41
99+#: src/app/webbrowser/Browser.qml:618 src/app/webbrowser/SettingsPage.qml:41
100 msgid "Settings"
101 msgstr ""
102
103 #. TRANSLATORS: %1 refers to the current number of tabs opened
104-#: src/app/webbrowser/Browser.qml:756 src/app/webbrowser/Browser.qml:794
105+#: src/app/webbrowser/Browser.qml:791 src/app/webbrowser/Browser.qml:829
106 #, qt-format
107 msgid "(%1)"
108 msgstr ""
109
110-#: src/app/webbrowser/Browser.qml:1337
111+#: src/app/webbrowser/Browser.qml:1386
112 msgid "Swipe Up To Exit Full Screen"
113 msgstr ""
114
115-#: src/app/webbrowser/Browser.qml:1338
116+#: src/app/webbrowser/Browser.qml:1387
117 msgid "Press ESC To Exit Full Screen"
118 msgstr ""
119
120@@ -823,7 +823,11 @@
121 msgid "Tap to view"
122 msgstr ""
123
124-#: src/app/webbrowser/TabsBar.qml:102
125+#: src/app/webbrowser/TabsBar.qml:106
126+msgid "Move to New Window"
127+msgstr ""
128+
129+#: src/app/webbrowser/TabsBar.qml:115
130 msgid "Close Tab"
131 msgstr ""
132
133@@ -832,13 +836,13 @@
134 msgstr ""
135
136 #. TRANSLATORS: %1 refers to the current page’s title
137-#: src/app/webbrowser/webbrowser-app.qml:108
138+#: src/app/webbrowser/webbrowser-app.qml:112
139 #: src/app/webcontainer/webapp-container.qml:72
140 #, qt-format
141 msgid "%1 - Ubuntu Web Browser"
142 msgstr ""
143
144-#: src/app/webbrowser/webbrowser-app.qml:110
145+#: src/app/webbrowser/webbrowser-app.qml:114
146 #: src/app/webcontainer/webapp-container.qml:74
147 msgid "Ubuntu Web Browser"
148 msgstr ""
149
150=== modified file 'src/app/webbrowser/Browser.qml'
151--- src/app/webbrowser/Browser.qml 2016-10-14 13:08:37 +0000
152+++ src/app/webbrowser/Browser.qml 2016-10-14 13:08:37 +0000
153@@ -64,12 +64,47 @@
154 'restoreType': Oxide.WebView.RestoreLastSessionExitedCleanly}
155 return createTab(properties)
156 }
157-
158+
159+ function buildContextProperties(properties) {
160+ if (properties === undefined) {
161+ properties = {};
162+ }
163+
164+ properties["bottomEdgeHandle"] = bottomEdgeHandle;
165+ properties["browser"] = browser;
166+ properties["chrome"] = chrome;
167+ properties["chromeController"] = chromeController;
168+ properties["contentHandlerLoader"] = contentHandlerLoader;
169+ properties["downloadDialogLoader"] = downloadDialogLoader;
170+ properties["downloadsViewLoader"] = downloadsViewLoader;
171+ properties["filePickerLoader"] = filePickerLoader;
172+ properties["internal"] = internal;
173+ properties["recentView"] = recentView;
174+ properties["tabsModel"] = tabsModel;
175+
176+ return properties;
177+ }
178+
179+ function createTabHelper(properties) {
180+ return builder(tabComponent, tabContainer, buildContextProperties(properties));
181+ }
182+
183 function createTab(properties) {
184- return tabComponent.createObject(tabContainer, properties)
185+ return createTabHelper(properties)
186+ }
187+
188+ function bindExistingTab(tab) {
189+ reparenter.reparent(tab, tabContainer);
190+
191+ var properties = buildContextProperties();
192+
193+ for (var prop in properties) {
194+ tab[prop] = properties[prop];
195+ }
196 }
197
198 signal newWindowRequested(bool incognito)
199+ signal newWindowFromTab(var tab, var closeMethod)
200 signal openLinkInWindowRequested(url url, bool incognito)
201
202 Connections {
203@@ -977,7 +1012,7 @@
204
205 function openUrlInNewTab(url, setCurrent, load, index) {
206 load = typeof load !== 'undefined' ? load : true
207- var tab = tabComponent.createObject(tabContainer, {"initialUrl": url})
208+ var tab = createTabHelper({"initialUrl": url})
209 addTab(tab, setCurrent, index)
210 if (load) {
211 tab.load()
212@@ -998,6 +1033,7 @@
213
214 function closeTab(index) {
215 var tab = tabsModel.get(index)
216+ tabsModel.remove(index)
217 if (tab) {
218 if (!incognito && tab.url.toString().length > 0) {
219 closedTabHistory.push({
220@@ -1007,7 +1043,6 @@
221 }
222 tab.close()
223 }
224- tabsModel.remove(index)
225 if (tabsModel.currentTab) {
226 tabsModel.currentTab.load()
227 }
228@@ -1400,4 +1435,94 @@
229 source: "ContentPickerDialog.qml"
230 asynchronous: true
231 }
232+
233+ DropArea {
234+ anchors {
235+ fill: parent
236+ }
237+ keys: ["webbrowser/tab-" + (incognito ? "incognito" : "public")]
238+
239+ onPositionChanged: {
240+ if (drag.source.tabWindow === window && drag.y < chrome.height) {
241+ // tab drag is within same window and in chrome
242+ // so reorder tabs by setting tabDelegate x position
243+ drag.source.x = drag.x - (drag.source.width / 2);
244+ }
245+
246+ dropChromeShade.opacity = drag.y <= chrome.height ? 0.7 : 0.4
247+ }
248+ onEntered: {
249+ window.raise()
250+ dropShade.opacity = 1
251+ }
252+ onExited: dropShade.opacity = 0
253+ onDropped: {
254+ if (drag.y > chrome.height) {
255+ console.debug("Dropped in bottom area, creating new window");
256+ drop.accept(Qt.IgnoreAction);
257+ } else if (drag.source.tabWindow === window) {
258+ console.debug("Dropped in same window");
259+ drop.accept(Qt.CopyAction);
260+ } else {
261+ console.debug("Dropped in new window, moving tab");
262+
263+ window.addExistingTab(drag.source.tab);
264+ window.tabsModel.currentIndex = window.tabsModel.count - 1;
265+ window.show();
266+ window.requestActivate();
267+
268+ window.tabsModel.currentTab.load();
269+
270+ drop.accept(Qt.MoveAction);
271+ }
272+
273+ dropShade.opacity = 0
274+ }
275+
276+ Item {
277+ id: dropShade
278+ anchors {
279+ fill: parent
280+ }
281+ opacity: 0
282+
283+ Rectangle {
284+ id: dropChromeShade
285+ anchors {
286+ left: parent.left
287+ right: parent.right
288+ top: parent.top
289+ }
290+ border {
291+ color: UbuntuColors.orange
292+ width: units.gu(1)
293+ }
294+ color: "transparent"
295+ height: chrome.height
296+ opacity: 0.4
297+
298+ Behavior on opacity {
299+ NumberAnimation {
300+
301+ }
302+ }
303+ }
304+
305+ Rectangle {
306+ id: dropTabShade
307+ anchors {
308+ fill: parent
309+ topMargin: chrome.height
310+ }
311+ color: "#FFF"
312+ opacity: 0.7
313+ }
314+
315+ Behavior on opacity {
316+ NumberAnimation {
317+
318+ }
319+ }
320+ }
321+ }
322 }
323
324=== modified file 'src/app/webbrowser/BrowserTab.qml'
325--- src/app/webbrowser/BrowserTab.qml 2016-10-14 13:08:37 +0000
326+++ src/app/webbrowser/BrowserTab.qml 2016-10-14 13:08:37 +0000
327@@ -97,7 +97,18 @@
328 }
329 }
330 }
331-
332+
333+ function loadExisting(existingTab) {
334+ if (!webview && !internal.incubator) {
335+ // Reparent the webview and any other vars
336+ existingTab.webview.parent = webviewContainer;
337+ existingTab.webview.tab = tab;
338+
339+ // Set the webview into this window
340+ webviewContainer.webview = existingTab.webview;
341+ }
342+ }
343+
344 function unload() {
345 if (webview) {
346 initialUrl = webview.url
347@@ -118,11 +129,17 @@
348 }
349 }
350
351- function close() {
352+ function close(reparentDestroy) {
353 var _url = url
354 unload()
355 if (_url.toString()) PreviewManager.checkDelete(_url)
356- destroy()
357+
358+ if (reparentDestroy || reparentDestroy === undefined) {
359+ // Destroys context and object
360+ reparenter.destroyContextAndObject(tab);
361+ } else {
362+ destroy();
363+ }
364 }
365
366 QtObject {
367
368=== modified file 'src/app/webbrowser/CMakeLists.txt'
369--- src/app/webbrowser/CMakeLists.txt 2015-12-10 09:06:06 +0000
370+++ src/app/webbrowser/CMakeLists.txt 2016-10-14 13:08:37 +0000
371@@ -33,7 +33,9 @@
372
373 set(WEBBROWSER_APP_SRC
374 cache-deleter.cpp
375+ drag-helper.cpp
376 file-operations.cpp
377+ reparenter.cpp
378 searchengine.cpp
379 webbrowser-app.cpp
380 )
381
382=== modified file 'src/app/webbrowser/Chrome.qml'
383--- src/app/webbrowser/Chrome.qml 2016-10-14 13:08:37 +0000
384+++ src/app/webbrowser/Chrome.qml 2016-10-14 13:08:37 +0000
385@@ -51,6 +51,12 @@
386
387 implicitHeight: tabsBar.height + navigationBar.height + content.anchors.topMargin
388
389+ onWebviewChanged: {
390+ if (webview) {
391+ loading = webview.loading
392+ }
393+ }
394+
395 function selectAll() {
396 navigationBar.selectAll()
397 }
398
399=== modified file 'src/app/webbrowser/TabComponent.qml'
400--- src/app/webbrowser/TabComponent.qml 2016-10-14 13:08:37 +0000
401+++ src/app/webbrowser/TabComponent.qml 2016-10-14 13:08:37 +0000
402@@ -34,10 +34,22 @@
403
404 BrowserTab {
405 anchors.fill: parent
406- incognito: browser.incognito
407- current: tabsModel && tabsModel.currentTab === this
408+ incognito: browser ? browser.incognito : false
409+ current: browser ? browser.tabsModel && browser.tabsModel.currentTab === this : false
410 focus: current
411
412+ property var bottomEdgeHandle
413+ property var browser
414+ property var chrome
415+ property var chromeController
416+ property var contentHandlerLoader
417+ property var downloadDialogLoader
418+ property var downloadsViewLoader
419+ property var filePickerLoader
420+ property var internal
421+ property var recentView
422+ property var tabsModel
423+
424 Item {
425 id: contextualMenuTarget
426 visible: false
427@@ -49,18 +61,18 @@
428 property BrowserTab tab
429 readonly property bool current: tab.current
430
431- currentWebview: browser.currentWebview
432- filePicker: filePickerLoader.item
433+ currentWebview: browser ? browser.currentWebview : null
434+ filePicker: filePickerLoader ? filePickerLoader.item : null
435
436 anchors.fill: parent
437
438 focus: true
439
440- enabled: current && !bottomEdgeHandle.dragging && !recentView.visible && tabContainer.focus
441+ enabled: current && !bottomEdgeHandle.dragging && !recentView.visible && parent.focus
442
443 locationBarController {
444- height: chrome.height
445- mode: chromeController.defaultMode
446+ height: chrome ? chrome.height : 0
447+ mode: chromeController ? chromeController.defaultMode : null
448 }
449
450 //experimental.preferences.developerExtrasEnabled: developerExtrasEnabled
451@@ -115,7 +127,7 @@
452 }
453 Actions.Share {
454 objectName: "ShareContextualAction"
455- enabled: (contentHandlerLoader.status == Loader.Ready) && contextModel &&
456+ enabled: (contentHandlerLoader && contentHandlerLoader.status == Loader.Ready) && contextModel &&
457 (contextModel.linkUrl.toString() || contextModel.selectionText)
458 onTriggered: {
459 if (contextModel.linkUrl.toString()) {
460@@ -237,10 +249,10 @@
461 Component.onCompleted: webviewimpl.contextMenuOnCompleted(this)
462 }
463 }
464- contextMenu: browser.wide ? contextMenuWideComponent : contextMenuNarrowComponent
465+ contextMenu: browser && browser.wide ? contextMenuWideComponent : contextMenuNarrowComponent
466
467 onNewViewRequested: {
468- var tab = tabComponent.createObject(tabContainer, {"request": request})
469+ var tab = browser.createTabHelper({"request": request})
470 var setCurrent = (request.disposition == Oxide.NewViewRequest.DispositionNewForegroundTab)
471 internal.addTab(tab, setCurrent)
472 if (setCurrent) tabContainer.forceActiveFocus()
473
474=== modified file 'src/app/webbrowser/TabsBar.qml'
475--- src/app/webbrowser/TabsBar.qml 2016-10-14 13:08:37 +0000
476+++ src/app/webbrowser/TabsBar.qml 2016-10-14 13:08:37 +0000
477@@ -19,6 +19,10 @@
478 import QtQuick 2.4
479 import Ubuntu.Components 1.3
480 import Ubuntu.Components.Popups 1.3
481+
482+import webbrowserapp.private 0.1
483+
484+import "."
485 import ".."
486
487 Item {
488@@ -110,6 +114,15 @@
489 onTriggered: menu.tab.reload()
490 }
491 Action {
492+ objectName: "tab_action_move_to_new_window"
493+ text: i18n.tr("Move to New Window")
494+ onTriggered: {
495+ // callback function only removes from model
496+ // and not destroy as webview is in new window
497+ browser.newWindowFromTab(menu.tab, function() { tabsModel.remove(menu.targetIndex); })
498+ }
499+ }
500+ Action {
501 objectName: "tab_action_close_tab"
502 text: i18n.tr("Close Tab")
503 onTriggered: root.tabClosed(menu.targetIndex)
504@@ -140,21 +153,29 @@
505 objectName: "tabDelegate"
506
507 readonly property int tabIndex: index
508+ readonly property BrowserTab tab: tabsModel.get(index)
509+ readonly property BrowserWindow tabWindow: window
510
511- anchors.top: tabsContainer.top
512-
513+ property real rightMargin: units.dp(1)
514 width: getSize(index)
515 height: tabsContainer.height
516+ y: tabsContainer.y // don't use anchor otherwise drag doesn't work
517
518 acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
519 readonly property bool dragging: drag.active
520 drag {
521 target: (pressedButtons === Qt.LeftButton) ? tabDelegate : null
522- axis: Drag.XAxis
523+ axis: Drag.XAndYAxis
524 minimumX: 0
525 maximumX: root.width - tabDelegate.width
526 filterChildren: true
527 }
528+
529+ DragHelper {
530+ id: dragHelper
531+ mimeType: "webbrowser/tab-" + (window.incognito ? "incognito" : "public")
532+ source: tabDelegate
533+ }
534
535 TabItem {
536 anchors.fill: parent
537@@ -188,7 +209,66 @@
538 value: getLeftX(index)
539 }
540
541- Behavior on x { NumberAnimation { duration: 250 } }
542+ Behavior on x {
543+ NumberAnimation {
544+ duration: 250
545+ }
546+ }
547+
548+ NumberAnimation {
549+ id: resetVerticalAnimation
550+ target: tabDelegate
551+ duration: 250
552+ property: "y"
553+ to: 0
554+ }
555+
556+ onPositionChanged: {
557+ if (Math.abs(y) > height) {
558+ // Reset visual position of tab delegate
559+ resetVerticalAnimation.start();
560+
561+ if (mouse.buttons === Qt.LeftButton) {
562+ // Generate tab preview for drag handle
563+ dragHelper.previewUrl = PreviewManager.previewPathFromUrl(tab.url);
564+
565+ var dropAction = dragHelper.execDrag(tab.url);
566+
567+ if (dropAction === Qt.MoveAction) {
568+ // Moved into another window
569+ console.debug("Moved to another window, closing tab");
570+
571+ // drag.active does not become false when
572+ // closing the tab so set reordering back
573+ repeater.reordering = false;
574+
575+ // Just remove from model and do not destory
576+ // as webview is used in other window
577+ tabsModel.remove(index);
578+ } else if (dropAction === Qt.CopyAction) {
579+ // Moved into the same window
580+
581+ // So no action
582+ console.debug("No action, dropped in same window");
583+ } else if (dropAction === Qt.IgnoreAction) {
584+ // Moved outside of any window
585+ console.debug("Moved outside, generating new window");
586+
587+ // drag.active does not become false when
588+ // closing the tab so set reordering back
589+ repeater.reordering = false;
590+
591+ // callback function only removes from model
592+ // and not destroy as webview is in new window
593+ browser.newWindowFromTab(tab, function() { tabsModel.remove(index); })
594+ } else {
595+ // Unknown state
596+ console.debug("Unknown drop action:", dropAction);
597+ }
598+ }
599+ }
600+ }
601+ onReleased: resetVerticalAnimation.start();
602
603 function getLeftX(index) {
604 if (unevenTabWidth) {
605
606=== modified file 'src/app/webbrowser/TabsList.qml'
607--- src/app/webbrowser/TabsList.qml 2016-02-25 14:54:54 +0000
608+++ src/app/webbrowser/TabsList.qml 2016-10-14 13:08:37 +0000
609@@ -109,14 +109,14 @@
610 incognito: tabslist.incognito
611 tab: model.tab
612 showContent: ((index > 0) && (delegate.y > flickable.contentY)) ||
613- !(tab.webview && tab.webview.visible)
614+ !(tab && tab.webview && tab.webview.visible)
615
616 Binding {
617 // Change the height of the location bar controller
618 // for the first webview only, and only while the tabs
619 // list view is visible.
620 when: tabslist.visible && (index == 0)
621- target: tab.webview ? tab.webview.locationBarController : null
622+ target: tab && tab.webview ? tab.webview.locationBarController : null
623 property: "height"
624 value: invisibleTabChrome.height
625 }
626
627=== added file 'src/app/webbrowser/drag-helper.cpp'
628--- src/app/webbrowser/drag-helper.cpp 1970-01-01 00:00:00 +0000
629+++ src/app/webbrowser/drag-helper.cpp 2016-10-14 13:08:37 +0000
630@@ -0,0 +1,100 @@
631+/*
632+ * Copyright 2016 Canonical Ltd.
633+ *
634+ * This file is part of webbrowser-app.
635+ *
636+ * webbrowser-app is free software; you can redistribute it and/or modify
637+ * it under the terms of the GNU General Public License as published by
638+ * the Free Software Foundation; version 3.
639+ *
640+ * webbrowser-app is distributed in the hope that it will be useful,
641+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
642+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643+ * GNU General Public License for more details.
644+ *
645+ * You should have received a copy of the GNU General Public License
646+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
647+ */
648+
649+#include "drag-helper.h"
650+
651+#include <QDrag>
652+#include <QDropEvent>
653+#include <QMimeData>
654+#include <QPainter>
655+#include <QPixmap>
656+#include <QSize>
657+
658+DragHelper::DragHelper()
659+{
660+ m_active = false;
661+ m_mime_type = QStringLiteral("webbrowser/tab");
662+ m_preview_url = "";
663+ m_source = NULL;
664+}
665+
666+Qt::DropAction DragHelper::execDrag(QString tabId)
667+{
668+ QDrag *drag = new QDrag(m_source);
669+
670+ QMimeData *mimeData = new QMimeData;
671+ mimeData->setData(mimeType(), tabId.toLatin1());
672+
673+ QSize pixmapSize(200, 150);
674+
675+ QPixmap pixmap(previewUrl());
676+
677+ if (pixmap.isNull()) {
678+ // If loading pixmap failed, draw a white rectangle
679+ pixmap = QPixmap(pixmapSize);
680+ QPainter painter(&pixmap);
681+ painter.eraseRect(0, 0, pixmapSize.width(), pixmapSize.height());
682+ painter.fillRect(0, 0, pixmapSize.width(), pixmapSize.height(), QColor(255, 255, 255, 255));
683+ } else {
684+ // Scale image to fit the expected size
685+ pixmap = pixmap.scaled(pixmapSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
686+ }
687+
688+ drag->setHotSpot(QPoint(0, 0));
689+ drag->setMimeData(mimeData);
690+ drag->setPixmap(pixmap);
691+
692+ return drag->exec(Qt::CopyAction | Qt::MoveAction | Qt::IgnoreAction);
693+}
694+
695+void DragHelper::setActive(bool active)
696+{
697+ if (m_active != active) {
698+ m_active = active;
699+
700+ Q_EMIT activeChanged(m_active);
701+ }
702+}
703+
704+void DragHelper::setMimeType(QString mimeType)
705+{
706+ if (m_mime_type != mimeType) {
707+ m_mime_type = mimeType;
708+
709+ Q_EMIT mimeTypeChanged(m_mime_type);
710+ }
711+}
712+
713+void DragHelper::setPreviewUrl(QString previewUrl)
714+{
715+ if (m_preview_url != previewUrl) {
716+ m_preview_url = previewUrl;
717+
718+ Q_EMIT previewUrlChanged(m_preview_url);
719+ }
720+}
721+
722+void DragHelper::setSource(QQuickItem *source)
723+{
724+ if (m_source != source) {
725+ m_source = source;
726+
727+ Q_EMIT sourceChanged(m_source);
728+ }
729+}
730+
731
732=== added file 'src/app/webbrowser/drag-helper.h'
733--- src/app/webbrowser/drag-helper.h 1970-01-01 00:00:00 +0000
734+++ src/app/webbrowser/drag-helper.h 2016-10-14 13:08:37 +0000
735@@ -0,0 +1,61 @@
736+/*
737+ * Copyright 2016 Canonical Ltd.
738+ *
739+ * This file is part of webbrowser-app.
740+ *
741+ * webbrowser-app is free software; you can redistribute it and/or modify
742+ * it under the terms of the GNU General Public License as published by
743+ * the Free Software Foundation; version 3.
744+ *
745+ * webbrowser-app is distributed in the hope that it will be useful,
746+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
747+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
748+ * GNU General Public License for more details.
749+ *
750+ * You should have received a copy of the GNU General Public License
751+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
752+ */
753+
754+#ifndef __DRAGHELPER_H__
755+#define __DRAGHELPER_H__
756+
757+#include <QQuickItem>
758+#include <QMouseEvent>
759+#include <QRect>
760+
761+class DragHelper : public QQuickItem
762+{
763+ Q_OBJECT
764+
765+ // TODO: add expectedAction
766+
767+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
768+ Q_PROPERTY(QString mimeType READ mimeType WRITE setMimeType NOTIFY mimeTypeChanged)
769+ Q_PROPERTY(QString previewUrl READ previewUrl WRITE setPreviewUrl NOTIFY previewUrlChanged)
770+ Q_PROPERTY(QQuickItem* source READ source WRITE setSource NOTIFY sourceChanged)
771+public:
772+ DragHelper();
773+ bool active() { return m_active; }
774+ QString mimeType() { return m_mime_type; }
775+ QString previewUrl() { return m_preview_url; }
776+ QQuickItem *source() { return m_source; }
777+signals:
778+ void activeChanged(bool active);
779+ void mimeTypeChanged(QString mimeType);
780+ void previewUrlChanged(QString previewUrl);
781+ void sourceChanged(QQuickItem *source);
782+public slots:
783+ Q_INVOKABLE Qt::DropAction execDrag(QString tabId);
784+ void setActive(bool active);
785+ void setMimeType(QString mimeType);
786+ void setPreviewUrl(QString previewUrl);
787+ void setSource(QQuickItem *source);
788+private:
789+ bool m_active;
790+ QString m_mime_type;
791+ QString m_preview_url;
792+ QQuickItem *m_source;
793+};
794+
795+#endif // __DRAGHELPER_H__
796+
797
798=== added file 'src/app/webbrowser/reparenter.cpp'
799--- src/app/webbrowser/reparenter.cpp 1970-01-01 00:00:00 +0000
800+++ src/app/webbrowser/reparenter.cpp 2016-10-14 13:08:37 +0000
801@@ -0,0 +1,94 @@
802+/*
803+ * Copyright 2016 Canonical Ltd.
804+ *
805+ * This file is part of webbrowser-app.
806+ *
807+ * webbrowser-app is free software; you can redistribute it and/or modify
808+ * it under the terms of the GNU General Public License as published by
809+ * the Free Software Foundation; version 3.
810+ *
811+ * webbrowser-app is distributed in the hope that it will be useful,
812+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
813+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
814+ * GNU General Public License for more details.
815+ *
816+ * You should have received a copy of the GNU General Public License
817+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
818+ */
819+
820+#include "reparenter.h"
821+
822+#include <QPointer>
823+#include <QQuickItem>
824+#include <QQmlComponent>
825+#include <QQmlContext>
826+#include <QQmlEngine>
827+
828+Reparenter::Reparenter()
829+{
830+}
831+
832+Reparenter::~Reparenter()
833+{
834+ QMap<QPointer<QQmlContext>, QPointer<QObject>>::iterator i;
835+
836+ for (i = m_contexts.begin(); i != m_contexts.end(); ++i) {
837+ QPointer<QQmlContext> context = i.key();
838+ QPointer<QObject> obj = i.value();
839+
840+ // If there is valid object then delete
841+ if (obj) {
842+ delete obj;
843+ }
844+
845+ // If there is a valid contex then delete
846+ if (context) {
847+ delete context;
848+ }
849+ }
850+
851+ m_contexts.clear(); // ensure contexts are removed
852+}
853+
854+QObject *Reparenter::createObject(QQmlComponent *comp, QQuickItem *contextItem)
855+{
856+ if (contextItem == NULL) {
857+ contextItem = this;
858+ }
859+
860+ // Make context
861+ QPointer<QQmlContext> context = new QQmlContext(QQmlEngine::contextForObject(contextItem));
862+ context->setContextObject(contextItem);
863+
864+ // Make component
865+ QPointer<QObject> obj = comp->create(context);
866+
867+ // Add to store
868+ m_contexts.insert(context, obj);
869+
870+ return obj;
871+}
872+
873+void Reparenter::destroyContextAndObject(QQuickItem *item)
874+{
875+ // Get context for object
876+ QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
877+
878+ // Remove from store
879+ m_contexts.remove(context);
880+
881+ // Disconnect everything
882+ item->disconnect();
883+
884+ // Delete context and object
885+ delete context;
886+ delete item;
887+}
888+
889+void Reparenter::reparent(QQuickItem *obj, QQuickItem *newParent)
890+{
891+ // Set object and visual parent
892+ obj->setParent(newParent);
893+ obj->setParentItem(newParent);
894+}
895+
896
897=== added file 'src/app/webbrowser/reparenter.h'
898--- src/app/webbrowser/reparenter.h 1970-01-01 00:00:00 +0000
899+++ src/app/webbrowser/reparenter.h 2016-10-14 13:08:37 +0000
900@@ -0,0 +1,45 @@
901+/*
902+ * Copyright 2016 Canonical Ltd.
903+ *
904+ * This file is part of webbrowser-app.
905+ *
906+ * webbrowser-app is free software; you can redistribute it and/or modify
907+ * it under the terms of the GNU General Public License as published by
908+ * the Free Software Foundation; version 3.
909+ *
910+ * webbrowser-app is distributed in the hope that it will be useful,
911+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
912+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
913+ * GNU General Public License for more details.
914+ *
915+ * You should have received a copy of the GNU General Public License
916+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
917+ */
918+
919+#ifndef __REPARENTER_H__
920+#define __REPARENTER_H__
921+
922+#include <QMap>
923+#include <QObject>
924+#include <QPointer>
925+#include <QQmlComponent>
926+#include <QQmlContext>
927+#include <QQuickItem>
928+
929+class Reparenter : public QQuickItem
930+{
931+ Q_OBJECT
932+
933+public:
934+ Reparenter();
935+ ~Reparenter();
936+
937+ Q_INVOKABLE QObject *createObject(QQmlComponent *comp, QQuickItem *contextItem=NULL);
938+ Q_INVOKABLE void destroyContextAndObject(QQuickItem *item);
939+ Q_INVOKABLE void reparent(QQuickItem *obj, QQuickItem *newParent);
940+private:
941+ QMap<QPointer<QQmlContext>, QPointer<QObject>> m_contexts;
942+};
943+
944+#endif // __REPARENTER_H__
945+
946
947=== modified file 'src/app/webbrowser/webbrowser-app.cpp'
948--- src/app/webbrowser/webbrowser-app.cpp 2016-08-18 16:29:35 +0000
949+++ src/app/webbrowser/webbrowser-app.cpp 2016-10-14 13:08:37 +0000
950@@ -21,11 +21,13 @@
951 #include "cache-deleter.h"
952 #include "config.h"
953 #include "downloads-model.h"
954+#include "drag-helper.h"
955 #include "file-operations.h"
956 #include "history-domainlist-model.h"
957 #include "history-lastvisitdatelist-model.h"
958 #include "history-model.h"
959 #include "limit-proxy-model.h"
960+#include "reparenter.h"
961 #include "searchengine.h"
962 #include "text-search-filter-model.h"
963 #include "tabs-model.h"
964@@ -76,6 +78,8 @@
965 qmlRegisterSingletonType<CacheDeleter>(uri, 0, 1, "CacheDeleter", CacheDeleter_singleton_factory);
966 qmlRegisterSingletonType<DownloadsModel>(uri, 0, 1, "DownloadsModel", DownloadsModel_singleton_factory);
967 qmlRegisterType<TextSearchFilterModel>(uri, 0, 1, "TextSearchFilterModel");
968+ qmlRegisterType<DragHelper>(uri, 0, 1, "DragHelper");
969+ qmlRegisterType<Reparenter>(uri, 0, 1, "Reparenter");
970
971 if (BrowserApplication::initialize("webbrowser/webbrowser-app.qml", QStringLiteral("webbrowser-app"))) {
972 QStringList searchEnginesSearchPaths;
973
974=== modified file 'src/app/webbrowser/webbrowser-app.qml'
975--- src/app/webbrowser/webbrowser-app.qml 2016-10-14 13:08:37 +0000
976+++ src/app/webbrowser/webbrowser-app.qml 2016-10-14 13:08:37 +0000
977@@ -83,7 +83,11 @@
978 window.show()
979 window.requestActivate()
980 }
981-
982+
983+ property Reparenter reparenter: Reparenter {
984+
985+ }
986+
987 property var windowFactory: Component {
988 BrowserWindow {
989 id: window
990@@ -119,6 +123,7 @@
991 session.clear()
992 }
993 }
994+
995 if (incognito && (allWindows.length > 1)) {
996 // If the last incognito window is being closed,
997 // prune incognito entries from the downloads model
998@@ -133,6 +138,7 @@
999 DownloadsModel.pruneIncognitoDownloads()
1000 }
1001 }
1002+
1003 destroy()
1004 }
1005
1006@@ -182,6 +188,25 @@
1007 id: browser
1008 anchors.fill: parent
1009 settings: webbrowserapp.settings
1010+ onNewWindowFromTab: {
1011+ var window = windowFactory.createObject(
1012+ null,
1013+ {
1014+ "incognito": tab.incognito,
1015+ "height": parent.height,
1016+ "width": parent.width,
1017+ }
1018+ );
1019+
1020+ window.addExistingTab(tab);
1021+ window.tabsModel.currentIndex = window.tabsModel.count - 1;
1022+ window.show();
1023+ window.requestActivate();
1024+
1025+ window.tabsModel.currentTab.load();
1026+
1027+ closeMethod();
1028+ }
1029 onNewWindowRequested: {
1030 var window = windowFactory.createObject(
1031 null,
1032@@ -261,10 +286,18 @@
1033 }
1034
1035 function addTab(url) {
1036- var tab = browser.createTab({"initialUrl": url})
1037+ var tab = browser.createTab({"initialUrl": url || ""})
1038 tabsModel.add(tab)
1039 return tab
1040 }
1041+
1042+ function addExistingTab(tab) {
1043+ tabsModel.add(tab);
1044+
1045+ browser.bindExistingTab(tab);
1046+
1047+ return tab;
1048+ }
1049 }
1050 }
1051
1052@@ -465,4 +498,17 @@
1053 PreviewManager.cleanUnusedPreviews(doNotCleanUrls)
1054 }
1055 }
1056+
1057+ // Builder for components which have a context set to reparenter
1058+ // so that when a window closes the context is still valid
1059+ function builder(comp, parent, properties) {
1060+ var obj = reparenter.createObject(comp);
1061+ obj.parent = parent;
1062+
1063+ for (var prop in properties) {
1064+ obj[prop] = properties[prop];
1065+ }
1066+
1067+ return obj;
1068+ }
1069 }
1070
1071=== modified file 'tests/autopilot/webbrowser_app/tests/__init__.py'
1072--- tests/autopilot/webbrowser_app/tests/__init__.py 2016-09-20 21:56:25 +0000
1073+++ tests/autopilot/webbrowser_app/tests/__init__.py 2016-10-14 13:08:37 +0000
1074@@ -256,6 +256,34 @@
1075 os.kill(child.pid, signal)
1076 break
1077
1078+ def switch_to_unfocused_window(self, target_window,
1079+ expected_number_unfocused_windows=1):
1080+ try:
1081+ windows = [
1082+ window for window in self.process_manager.get_open_windows()
1083+ if window.application.desktop_file ==
1084+ "webbrowser-app.desktop" and
1085+ not window.is_focused
1086+ ]
1087+
1088+ # There should be 1 unfocused window
1089+ self.assertThat(len(windows),
1090+ Equals(expected_number_unfocused_windows))
1091+
1092+ # Cycle through possible windows until target gets focus
1093+ for window in windows:
1094+ window.set_focus()
1095+ self.assertThat(lambda: window.is_focused,
1096+ Eventually(Equals(True)))
1097+
1098+ if target_window.activeFocus:
1099+ break
1100+ except (RuntimeError, ImportError):
1101+ # Fallback to clicking on the window
1102+ self.pointing_device.click_object(target_window)
1103+
1104+ self.assertThat(target_window.activeFocus, Eventually(Equals(True)))
1105+
1106
1107 class StartOpenRemotePageTestCaseBase(BrowserTestCaseBase):
1108
1109
1110=== modified file 'tests/autopilot/webbrowser_app/tests/test_multiple_windows.py'
1111--- tests/autopilot/webbrowser_app/tests/test_multiple_windows.py 2016-09-20 21:56:25 +0000
1112+++ tests/autopilot/webbrowser_app/tests/test_multiple_windows.py 2016-10-14 13:08:37 +0000
1113@@ -15,6 +15,8 @@
1114 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1115
1116 from testtools.matchers import Equals
1117+from autopilot.matchers import Eventually
1118+from time import sleep
1119
1120 from webbrowser_app.tests import StartOpenRemotePageTestCaseBase
1121
1122@@ -38,3 +40,204 @@
1123 self.assertThat(len(windows), Equals(2))
1124 self.assertThat(len(self.app.get_windows(incognito=False)), Equals(1))
1125 self.assertThat(len(self.app.get_windows(incognito=True)), Equals(1))
1126+
1127+
1128+class TestMultipleWindowsDrag(StartOpenRemotePageTestCaseBase):
1129+ def setUp(self):
1130+ super(TestMultipleWindowsDrag, self).setUp()
1131+
1132+ if not self.main_window.wide:
1133+ self.skipTest("Only on wide form factors")
1134+
1135+ def drag_tab(self, tab, x2, y2):
1136+ x1, y1 = self.get_object_center(tab)
1137+
1138+ self.pointing_device.move(x1, y1)
1139+ self.pointing_device.press()
1140+
1141+ # Drag tab downwards first to ensure we activate tab dragging
1142+ for i in range(100):
1143+ self.pointing_device.move(x1, y1 + i)
1144+
1145+ # Move to destination and release
1146+ # pause at each point so we can what is happening
1147+ sleep(0.25)
1148+ self.pointing_device.move(x2, y2)
1149+ sleep(0.25)
1150+ self.pointing_device.release()
1151+ sleep(0.25)
1152+
1153+ def get_object_center(self, obj):
1154+ x1, y1, width, height = obj.globalRect
1155+ x1 += width // 2
1156+ y1 += height // 2
1157+
1158+ return x1, y1
1159+
1160+ def get_tab_delegate(self, window, tabIndex):
1161+ return window.chrome.get_tabs_bar().get_tab(tabIndex)
1162+
1163+ def test_drag_tab_tabbar_nothing(self):
1164+ '''test that dragging a tab out and in of tabbar is same'''
1165+ window = self.app.get_windows()[0]
1166+
1167+ # Drag tab down and then back into tab bar
1168+ tab = self.get_tab_delegate(window, 0)
1169+ x2, y2 = self.get_object_center(tab)
1170+
1171+ self.drag_tab(tab, x2, y2)
1172+
1173+ # Check we still have 1 window and 1 tab
1174+ windows = self.app.get_windows()
1175+ self.assertThat(len(windows), Equals(1))
1176+ self.assertThat(lambda: len(windows[0].get_webviews()),
1177+ Eventually(Equals(1)))
1178+
1179+ def test_drag_tab_bottom_new_window(self):
1180+ '''test with two tabs dragging one to the bottom opens a new window'''
1181+ window = self.app.get_windows()[0]
1182+
1183+ # Open a new tab and check we have two
1184+ self.open_new_tab()
1185+ self.assertThat(lambda: len(window.get_webviews()),
1186+ Eventually(Equals(2)))
1187+
1188+ # Drag new tab to bottom part of window
1189+ tab = self.get_tab_delegate(window, 1)
1190+ x2, y2 = self.get_object_center(window)
1191+
1192+ self.drag_tab(tab, x2, y2)
1193+
1194+ # Check that a new window has been opened
1195+ windows = self.app.get_windows()
1196+ self.assertThat(len(windows), Equals(2))
1197+ self.assertThat(lambda: len(windows[0].get_webviews()),
1198+ Eventually(Equals(1)))
1199+ self.assertThat(lambda: len(windows[1].get_webviews()),
1200+ Eventually(Equals(1)))
1201+
1202+ def test_drag_tab_outside_new_window(self):
1203+ '''test with two tabs dragging one to the bottom opens a new window'''
1204+ window = self.app.get_windows()[0]
1205+
1206+ # Open a new tab and check we have two
1207+ self.open_new_tab()
1208+ self.assertThat(lambda: len(window.get_webviews()),
1209+ Eventually(Equals(2)))
1210+
1211+ # Drag new tab outside of window
1212+ tab = self.get_tab_delegate(window, 1)
1213+ x2, y2, width, height = window.globalRect
1214+
1215+ if x2 > 20:
1216+ x2 -= 20
1217+ else:
1218+ x2 += width + 20
1219+
1220+ self.drag_tab(tab, x2, y2)
1221+
1222+ # Check that a new window has been opened
1223+ windows = self.app.get_windows()
1224+ self.assertThat(len(windows), Equals(2))
1225+ self.assertThat(lambda: len(windows[0].get_webviews()),
1226+ Eventually(Equals(1)))
1227+ self.assertThat(lambda: len(windows[1].get_webviews()),
1228+ Eventually(Equals(1)))
1229+
1230+ def test_drag_tab_between_windows_move(self):
1231+ '''test that dragging a tab from one window to another'''
1232+ # Open a new tab and window
1233+ self.open_new_tab()
1234+ self.open_new_window()
1235+
1236+ windows = self.app.get_windows()
1237+ self.assertThat(len(windows), Equals(2))
1238+ self.assertThat(lambda: len(windows[0].get_webviews()),
1239+ Eventually(Equals(2)))
1240+ self.assertThat(lambda: len(windows[1].get_webviews()),
1241+ Eventually(Equals(1)))
1242+
1243+ # Focus window 0
1244+ self.switch_to_unfocused_window(windows[0])
1245+
1246+ # Move tab into window 1
1247+ tab = self.get_tab_delegate(windows[0], 1)
1248+ x2, y2 = self.get_object_center(windows[1].chrome.get_tabs_bar())
1249+
1250+ self.drag_tab(tab, x2, y2)
1251+
1252+ # Check there are two windows and two tabs open in the second window
1253+ windows = self.app.get_windows()
1254+ self.assertThat(len(windows), Equals(2))
1255+ self.assertThat(lambda: len(windows[0].get_webviews()),
1256+ Eventually(Equals(1)))
1257+ self.assertThat(lambda: len(windows[1].get_webviews()),
1258+ Eventually(Equals(2)))
1259+
1260+ def test_drag_tab_between_windows_move_and_close_window(self):
1261+ '''test that dragging tab from one window to another closes original'''
1262+ self.open_new_window()
1263+ windows = self.app.get_windows()
1264+ self.assertThat(len(windows), Equals(2))
1265+
1266+ # Focus window 0
1267+ self.switch_to_unfocused_window(windows[0])
1268+
1269+ # Move tab into window 1
1270+ tab = self.get_tab_delegate(windows[0], 0)
1271+ x2, y2 = self.get_object_center(windows[1].chrome.get_tabs_bar())
1272+
1273+ self.drag_tab(tab, x2, y2)
1274+
1275+ # Check there are two tabs open in the single remaining window
1276+ windows = self.app.get_windows()
1277+ self.assertThat(len(windows), Equals(1))
1278+ self.assertThat(lambda: len(windows[0].get_webviews()),
1279+ Eventually(Equals(2)))
1280+
1281+ def test_drag_public_tab_into_private_window(self):
1282+ '''test that you cannot drag a public tab into private window'''
1283+ # Open private window, check there are two windows
1284+ self.open_new_private_window()
1285+ windows = self.app.get_windows()
1286+ self.assertThat(len(windows), Equals(2))
1287+
1288+ public_window = self.app.get_windows(incognito=False)[0]
1289+ private_window = self.app.get_windows(incognito=True)[0]
1290+
1291+ # Focus public window
1292+ self.switch_to_unfocused_window(public_window)
1293+
1294+ # Move tab into private window
1295+ tab = self.get_tab_delegate(public_window, 0)
1296+ x2, y2 = self.get_object_center(private_window)
1297+
1298+ self.drag_tab(tab, x2, y2)
1299+
1300+ # Check there are two windows, one of public and one private
1301+ windows = self.app.get_windows()
1302+ self.assertThat(len(windows), Equals(2))
1303+ self.assertThat(len(self.app.get_windows(incognito=False)), Equals(1))
1304+ self.assertThat(len(self.app.get_windows(incognito=True)), Equals(1))
1305+
1306+ def test_drag_private_tab_into_public_window(self):
1307+ '''test that you cannot drag a private tab into public window'''
1308+ # Open private window, check there are two windows
1309+ self.open_new_private_window()
1310+ windows = self.app.get_windows()
1311+ self.assertThat(len(windows), Equals(2))
1312+
1313+ public_window = self.app.get_windows(incognito=False)[0]
1314+ private_window = self.app.get_windows(incognito=True)[0]
1315+
1316+ # Move tab into public window
1317+ tab = self.get_tab_delegate(private_window, 0)
1318+ x2, y2 = self.get_object_center(public_window)
1319+
1320+ self.drag_tab(tab, x2, y2)
1321+
1322+ # Check there are two windows, one of public and one private
1323+ windows = self.app.get_windows()
1324+ self.assertThat(len(windows), Equals(2))
1325+ self.assertThat(len(self.app.get_windows(incognito=False)), Equals(1))
1326+ self.assertThat(len(self.app.get_windows(incognito=True)), Equals(1))
1327
1328=== modified file 'tests/unittests/qml/CMakeLists.txt'
1329--- tests/unittests/qml/CMakeLists.txt 2016-10-14 13:08:37 +0000
1330+++ tests/unittests/qml/CMakeLists.txt 2016-10-14 13:08:37 +0000
1331@@ -18,12 +18,14 @@
1332 ${webbrowser-app_SOURCE_DIR}/bookmarks-model.cpp
1333 ${webbrowser-app_SOURCE_DIR}/bookmarks-folder-model.cpp
1334 ${webbrowser-app_SOURCE_DIR}/bookmarks-folderlist-model.cpp
1335+ ${webbrowser-app_SOURCE_DIR}/drag-helper.cpp
1336 ${webbrowser-app_SOURCE_DIR}/file-operations.cpp
1337 ${webbrowser-app_SOURCE_DIR}/history-domain-model.cpp
1338 ${webbrowser-app_SOURCE_DIR}/history-domainlist-model.cpp
1339 ${webbrowser-app_SOURCE_DIR}/history-model.cpp
1340 ${webbrowser-app_SOURCE_DIR}/history-lastvisitdatelist-model.cpp
1341 ${webbrowser-app_SOURCE_DIR}/limit-proxy-model.cpp
1342+ ${webbrowser-app_SOURCE_DIR}/reparenter.cpp
1343 ${webbrowser-app_SOURCE_DIR}/searchengine.cpp
1344 ${webbrowser-app_SOURCE_DIR}/tabs-model.cpp
1345 ${webbrowser-app_SOURCE_DIR}/text-search-filter-model.cpp
1346
1347=== added file 'tests/unittests/qml/ReparenterFakeContainer.qml'
1348--- tests/unittests/qml/ReparenterFakeContainer.qml 1970-01-01 00:00:00 +0000
1349+++ tests/unittests/qml/ReparenterFakeContainer.qml 2016-10-14 13:08:37 +0000
1350@@ -0,0 +1,40 @@
1351+/*
1352+ * Copyright 2016 Canonical Ltd.
1353+ *
1354+ * This file is part of webbrowser-app.
1355+ *
1356+ * webbrowser-app is free software; you can redistribute it and/or modify
1357+ * it under the terms of the GNU General Public License as published by
1358+ * the Free Software Foundation; version 3.
1359+ *
1360+ * webbrowser-app is distributed in the hope that it will be useful,
1361+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1362+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1363+ * GNU General Public License for more details.
1364+ *
1365+ * You should have received a copy of the GNU General Public License
1366+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1367+ */
1368+import QtQuick 2.4
1369+
1370+Item {
1371+ id: containerLeft
1372+ anchors {
1373+ bottom: parent.bottom
1374+ left: parent.left
1375+ right: parent.horizontalCenter
1376+ top: parent.top
1377+ }
1378+
1379+ property var root
1380+
1381+ function makeTab() {
1382+ var component = Qt.createComponent(Qt.resolvedUrl("ReparenterFakeTab.qml"))
1383+ return component.createObject(containerLeft, {})
1384+ }
1385+
1386+ function makeTabHelper() {
1387+ var component = Qt.createComponent(Qt.resolvedUrl("ReparenterFakeTab.qml"))
1388+ return root.builder(component, containerLeft)
1389+ }
1390+}
1391
1392=== added file 'tests/unittests/qml/ReparenterFakeTab.qml'
1393--- tests/unittests/qml/ReparenterFakeTab.qml 1970-01-01 00:00:00 +0000
1394+++ tests/unittests/qml/ReparenterFakeTab.qml 2016-10-14 13:08:37 +0000
1395@@ -0,0 +1,37 @@
1396+/*
1397+ * Copyright 2016 Canonical Ltd.
1398+ *
1399+ * This file is part of webbrowser-app.
1400+ *
1401+ * webbrowser-app is free software; you can redistribute it and/or modify
1402+ * it under the terms of the GNU General Public License as published by
1403+ * the Free Software Foundation; version 3.
1404+ *
1405+ * webbrowser-app is distributed in the hope that it will be useful,
1406+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1407+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1408+ * GNU General Public License for more details.
1409+ *
1410+ * You should have received a copy of the GNU General Public License
1411+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1412+ */
1413+import QtQuick 2.4
1414+
1415+Item {
1416+ anchors {
1417+ fill: parent
1418+ }
1419+
1420+ readonly property MouseArea mouseArea: mouseAreaObj
1421+
1422+ MouseArea {
1423+ id: mouseAreaObj
1424+ anchors {
1425+ fill: parent
1426+ }
1427+
1428+ property int clickCount: 0
1429+
1430+ onClicked: clickCount++
1431+ }
1432+}
1433
1434=== modified file 'tests/unittests/qml/tst_BrowserTab.qml'
1435--- tests/unittests/qml/tst_BrowserTab.qml 2016-08-18 17:10:32 +0000
1436+++ tests/unittests/qml/tst_BrowserTab.qml 2016-10-14 13:08:37 +0000
1437@@ -26,6 +26,10 @@
1438
1439 width: 200
1440 height: 200
1441+
1442+ property Reparenter reparenter: Reparenter {
1443+
1444+ }
1445
1446 Component {
1447 id: tabComponent
1448@@ -163,9 +167,8 @@
1449 tab.current = false
1450 tryCompare(previewSavedSpy, "count", 1)
1451 verify(FileOperations.exists(path))
1452- tab.close()
1453+ tab.close(false)
1454 verify(!FileOperations.exists(path))
1455-
1456 tab.destroy()
1457 }
1458 }
1459
1460=== modified file 'tests/unittests/qml/tst_QmlTests.cpp'
1461--- tests/unittests/qml/tst_QmlTests.cpp 2016-02-11 08:26:47 +0000
1462+++ tests/unittests/qml/tst_QmlTests.cpp 2016-10-14 13:08:37 +0000
1463@@ -27,6 +27,7 @@
1464 // local
1465 #include "bookmarks-model.h"
1466 #include "bookmarks-folderlist-model.h"
1467+#include "drag-helper.h"
1468 #include "favicon-fetcher.h"
1469 #include "file-operations.h"
1470 #include "history-domain-model.h"
1471@@ -34,6 +35,7 @@
1472 #include "history-model.h"
1473 #include "history-lastvisitdatelist-model.h"
1474 #include "limit-proxy-model.h"
1475+#include "reparenter.h"
1476 #include "searchengine.h"
1477 #include "tabs-model.h"
1478 #include "text-search-filter-model.h"
1479@@ -183,6 +185,8 @@
1480 qmlRegisterType<LimitProxyModel>(browserUri, 0, 1, "LimitProxyModel");
1481 qmlRegisterType<TextSearchFilterModel>(browserUri, 0, 1, "TextSearchFilterModel");
1482 qmlRegisterSingletonType<FileOperations>(browserUri, 0, 1, "FileOperations", FileOperations_singleton_factory);
1483+ qmlRegisterType<DragHelper>(browserUri, 0, 1, "DragHelper");
1484+ qmlRegisterType<Reparenter>(browserUri, 0, 1, "Reparenter");
1485
1486 const char* testUri = "webbrowsertest.private";
1487 qmlRegisterSingletonType<TestContext>(testUri, 0, 1, "TestContext", TestContext_singleton_factory);
1488
1489=== added file 'tests/unittests/qml/tst_Reparenter.qml'
1490--- tests/unittests/qml/tst_Reparenter.qml 1970-01-01 00:00:00 +0000
1491+++ tests/unittests/qml/tst_Reparenter.qml 2016-10-14 13:08:37 +0000
1492@@ -0,0 +1,120 @@
1493+/*
1494+ * Copyright 2016 Canonical Ltd.
1495+ *
1496+ * This file is part of webbrowser-app.
1497+ *
1498+ * webbrowser-app is free software; you can redistribute it and/or modify
1499+ * it under the terms of the GNU General Public License as published by
1500+ * the Free Software Foundation; version 3.
1501+ *
1502+ * webbrowser-app is distributed in the hope that it will be useful,
1503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1505+ * GNU General Public License for more details.
1506+ *
1507+ * You should have received a copy of the GNU General Public License
1508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1509+ */
1510+import QtQuick 2.4
1511+import QtTest 1.0
1512+import webbrowserapp.private 0.1
1513+
1514+Item {
1515+ id: root
1516+ height: 100
1517+ width: 100
1518+
1519+ property Item containerLeft
1520+
1521+ property Reparenter reparenter: Reparenter {
1522+
1523+ }
1524+
1525+ Item {
1526+ id: containerRight
1527+ anchors {
1528+ bottom: parent.bottom
1529+ left: parent.horizontalCenter
1530+ right: parent.right
1531+ top: parent.top
1532+ }
1533+ }
1534+
1535+ function addExisting(container, tab) {
1536+ tab.parent = container
1537+ }
1538+
1539+ function addExistingHelper(container, tab) {
1540+ reparenter.reparent(tab, container, {});
1541+ }
1542+
1543+ function builder(component, container) {
1544+ var tab = reparenter.createObject(component)
1545+ tab.parent = container
1546+ return tab
1547+ }
1548+
1549+ TestCase {
1550+ name: "Reparenter"
1551+ when: windowShown
1552+
1553+ function init() {
1554+ var component = Qt.createComponent(Qt.resolvedUrl("ReparenterFakeContainer.qml"))
1555+ containerLeft = component.createObject(root, {})
1556+ containerLeft.root = root
1557+ }
1558+
1559+ function cleanup() {
1560+ containerRight.children = null
1561+ }
1562+
1563+ function test_reparenter_cpp() {
1564+ var tab = containerLeft.makeTabHelper()
1565+
1566+ // Click on tab ensure it has been clicked
1567+ mouseClick(root, 25, 50, Qt.LeftButton)
1568+ compare(tab.mouseArea.clickCount, 1)
1569+
1570+ // Move tab
1571+ addExistingHelper(containerRight, tab)
1572+
1573+ // Click on tab ensure it has been clicked
1574+ mouseClick(root, 75, 50, Qt.LeftButton)
1575+ compare(tab.mouseArea.clickCount, 2)
1576+
1577+ // Destroy context
1578+ containerLeft.destroy()
1579+
1580+ // Click on tab ensure it has been clicked
1581+ mouseClick(root, 75, 50, Qt.LeftButton)
1582+ compare(tab.mouseArea.clickCount, 3)
1583+
1584+ // Destroy object and check children have gone
1585+ reparenter.destroyContextAndObject(tab)
1586+ compare(tab.mouseArea, undefined)
1587+ }
1588+
1589+ function test_reparenter_qml_expect_fail() {
1590+ var tab = containerLeft.makeTab()
1591+
1592+ // Click on tab ensure it has been clicked
1593+ mouseClick(root, 25, 50, Qt.LeftButton)
1594+ compare(tab.mouseArea.clickCount, 1)
1595+
1596+ // Move tab
1597+ addExisting(containerRight, tab)
1598+
1599+ // Click on tab ensure it has been clicked
1600+ mouseClick(root, 75, 50, Qt.LeftButton)
1601+ compare(tab.mouseArea.clickCount, 2)
1602+
1603+ // Destroy context
1604+ containerLeft.destroy()
1605+
1606+ // Attempt to click on tab find that children of tab have been
1607+ // destroyed as the context has gone
1608+ mouseClick(root, 75, 50, Qt.LeftButton)
1609+ tryCompare(tab, "mouseArea", undefined, 1000)
1610+ }
1611+ }
1612+}

Subscribers

People subscribed via source and target branches

to status/vote changes: