Merge lp:~dandrader/unity8/childWindows into lp:unity8

Proposed by Daniel d'Andrada
Status: Merged
Approved by: Gerry Boland
Approved revision: 2799
Merged at revision: 2804
Proposed branch: lp:~dandrader/unity8/childWindows
Merge into: lp:unity8
Prerequisite: lp:~dandrader/unity8/simplifyWindowDecoration
Diff against target: 1464 lines (+726/-108)
31 files modified
CMakeLists.txt (+1/-1)
debian/control (+3/-3)
plugins/WindowManager/TopLevelWindowModel.cpp (+36/-28)
plugins/WindowManager/TopLevelWindowModel.h (+2/-0)
plugins/WindowManager/Window.h (+0/-1)
qml/Components/WindowControlButtons.qml (+2/-0)
qml/Stage/ChildWindow.qml (+159/-0)
qml/Stage/ChildWindowRepeater.qml (+28/-0)
qml/Stage/ChildWindowTree.qml (+127/-0)
qml/Stage/DecoratedWindow.qml (+1/-2)
qml/Stage/MoveHandler.qml (+23/-18)
qml/Stage/Stage.qml (+50/-9)
qml/Stage/WindowControlsOverlay.qml (+21/-24)
qml/Stage/WindowDecoration.qml (+1/-0)
qml/Stage/WindowResizeArea.qml (+3/-2)
tests/mocks/Unity/Application/ApplicationInfo.cpp (+9/-1)
tests/mocks/Unity/Application/ApplicationInfo.h (+3/-0)
tests/mocks/Unity/Application/ApplicationManager.cpp (+9/-0)
tests/mocks/Unity/Application/MirSurface.cpp (+43/-0)
tests/mocks/Unity/Application/MirSurface.h (+11/-0)
tests/mocks/Unity/Application/MirSurfaceItem.cpp (+19/-4)
tests/mocks/Unity/Application/MirSurfaceListModel.h (+0/-1)
tests/mocks/Unity/Application/SurfaceManager.cpp (+15/-8)
tests/mocks/Unity/Application/SurfaceManager.h (+3/-1)
tests/mocks/Unity/Application/VirtualKeyboard.cpp (+5/-4)
tests/mocks/Unity/Application/resources/Kate.qml (+49/-0)
tests/mocks/Unity/Application/resources/KateDialog.qml (+48/-0)
tests/mocks/Unity/Application/resources/KateMenu.qml (+41/-0)
tests/mocks/Unity/Application/resources/surfaces.qrc (+3/-0)
tests/qmltests/Stage/ApplicationCheckBox.qml (+1/-1)
tests/qmltests/Stage/tst_WindowResizeArea.qml (+10/-0)
To merge this branch: bzr merge lp:~dandrader/unity8/childWindows
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
Unity8 CI Bot continuous-integration Needs Fixing
Michael Zanetti Pending
Lukáš Tinkl Pending
Nick Dedekind Pending
Review via email: mp+315145@code.launchpad.net

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

Commit message

Initial support for child windows (menus, dialogs, tooltips)

Description of the change

Prereq-archive: ppa:ci-train-ppa-service/2313

Good Qt apps to test with: kate, qtcreator

And keep in mind this is just the first iteration.

You can also play with it in "make tryDesktopStage" or "make tryShell" by launching the mock kate application and interacting with its UI to launch menus and dialogs.

* Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~dandrader/unity-api/parentSurface/+merge/313056
https://code.launchpad.net/~dandrader/qtmir/miral-surfaceLocalPos/+merge/313438

Make sure you have miral 1.0.2, which has been released on 20/Jan/2017.

Tooltips work better with this:
https://code.launchpad.net/~dandrader/qtubuntu/resizeToolTip

* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes, although it's basically new functionality

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

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

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in debian/control
Text conflict in qml/Shell.qml
Text conflict in qml/Stage/Stage.qml
Text conflict in tests/mocks/Unity/Application/plugin.cpp
Text conflict in tests/qmltests/Stage/tst_DesktopStage.qml
Text conflict in tests/qmltests/tst_Shell.qml
6 conflicts encountered.

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

tested with tiled and kate (qt5 apps), brief test with tiled and kate, the child windows positioning works, if i move the parrent window, the child windows moves according to parrent's x/y. in the app switcher (alt tab) i see both the parrent and the child window. the menus open in a separate window with a wrong size and position and it usually ends up freezing unity8 when i try to close the menu or or parent. tooltips same as with menus. short video here https://vid.me/aCWQ

ubuntu 17.04 / nouveau

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

On 01/12/2016 13:47, dinamic wrote:
> tested with tiled and kate (qt5 apps), brief test with tiled and kate, the child windows positioning works, if i move the parrent window, the child windows moves according to parrent's x/y. in the app switcher (alt tab) i see both the parrent and the child window. the menus open in a separate window with a wrong size and position and it usually ends up freezing unity8 when i try to close the menu or or parent. tooltips same as with menus. short video here https://vid.me/aCWQ
>
> ubuntu 17.04 / nouveau

Looks like you have an outdated qtubuntu. Menus should work fine and
child windows should not show in the app switcher.

Revision history for this message
dinamic (dinamic6661) wrote : Posted in a previous version of this proposal

i have qtubuntu-desktop/zesty,now 0.63+17.04.20161123-0ubuntu1 amd64 [installed]

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

Getting a conflict merging in latest unity8/miral branch.

Text conflict in plugins/WindowManager/TopLevelWindowModel.h
Text conflict in qml/Stage/WindowResizeArea.qml

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

> Getting a conflict merging in latest unity8/miral branch.
>
> Text conflict in plugins/WindowManager/TopLevelWindowModel.h
> Text conflict in qml/Stage/WindowResizeArea.qml

Fixed. Rebased on top of latest unity8/miral.

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

Just 2 minor nitpicks, otherwise the code looks good (haven't tested yet):

+ Window *TopLevelWindowModel::createWindow(unityapi::MirSurfaceInterface *surface)

-> const qualifier, it's a getter

+ readonly property bool decorated

-> this could be rewritten to be a direct binding, instead of a function

review: Needs Fixing
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

Console is spammed with this warning:

TypeError: Property 'updateSurfaceRequestedPosition' of object QObject_QML_309(0x7024140) is not a function

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

On 13/12/2016 09:46, Lukáš Tinkl wrote:
> Review: Needs Fixing
>
> Just 2 minor nitpicks, otherwise the code looks good (haven't tested yet):
>
> + Window *TopLevelWindowModel::createWindow(unityapi::MirSurfaceInterface *surface)
>
> -> const qualifier, it's a getter

It's not a getter and it can't be const since the generateId() method it
uses cannot be const.

> + readonly property bool decorated
>
> -> this could be rewritten to be a direct binding, instead of a function

AFAIK both notations work exactly the same. It's syntactic sugar. Made
the change anyway as it's less code.

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

On 13/12/2016 11:59, Lukáš Tinkl wrote:
> Review: Needs Fixing
>
> Console is spammed with this warning:
>
> TypeError: Property 'updateSurfaceRequestedPosition' of object QObject_QML_309(0x7024140) is not a function

Fixed.

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

I have a question regarding the (Kate) dialog's placement, caption and focus:

Shouldn't the dialog's titlebar be actually placed under its parent's titlebar, and focused? The font used for the dialog's caption should probably be the same as any other "focused" window; the current way it is suggests the main window in the background is still focused.

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 16/12/2016 12:36, Lukáš Tinkl wrote:
> Review: Needs Information
>
> I have a question regarding the (Kate) dialog's placement, caption and focus:
>
> Shouldn't the dialog's titlebar be actually placed under its parent's titlebar, and focused? The font used for the dialog's caption should probably be the same as any other "focused" window; the current way it is suggests the main window in the background is still focused.

Please don't get lost in the details. This is just the first iteration.
There are loads of things to improve.

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

> On 16/12/2016 12:36, Lukáš Tinkl wrote:
> > Review: Needs Information
> >
> > I have a question regarding the (Kate) dialog's placement, caption and
> focus:
> >
> > Shouldn't the dialog's titlebar be actually placed under its parent's
> titlebar, and focused? The font used for the dialog's caption should probably
> be the same as any other "focused" window; the current way it is suggests the
> main window in the background is still focused.
>
> Please don't get lost in the details. This is just the first iteration.
> There are loads of things to improve.

"The devil is in the detail"

I'm aware of the fact this is a first iteration but I'm sure we don't want to land stuff in a (semi) broken state

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

On 16/12/2016 13:00, Lukáš Tinkl wrote:
>> On 16/12/2016 12:36, Lukáš Tinkl wrote:
>>> Review: Needs Information
>>>
>>> I have a question regarding the (Kate) dialog's placement, caption and
>> focus:
>>> Shouldn't the dialog's titlebar be actually placed under its parent's
>> titlebar, and focused? The font used for the dialog's caption should probably
>> be the same as any other "focused" window; the current way it is suggests the
>> main window in the background is still focused.
>>
>> Please don't get lost in the details. This is just the first iteration.
>> There are loads of things to improve.
> "The devil is in the detail"
>
> I'm aware of the fact this is a first iteration but I'm sure we don't want to land stuff in a (semi) broken state
>
>
As long as it's not causing regressions on existing features, it
shouldn't be a problem.

Proper positioning of child dialogs hasn't been implemented yet. Will
likely involve work on miral.

Eg: Open a child dialog. Move it to the side of its top-level parent.
Now move that top-level parent right to the edge of the display. The
child dialog will be completely offscreen.

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal

And, is this supposed to work in anything else than the desktop mode? Because in phone/tablet modes, it doesn't do anything

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 16/12/2016 13:32, Lukáš Tinkl wrote:
> Review: Needs Information
>
> And, is this supposed to work in anything else than the desktop mode? Because in phone/tablet modes, it doesn't do anything

phone/tablet is uncharted territory with regards to child windows. Need
input from design etc.

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

FAILED: Continuous integration, rev:2755
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2756/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3614
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2067
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2067
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3642
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3488
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3488/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3488
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3488/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3488
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3488/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3488
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3488/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3488
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3488/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3488
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3488/artifact/output/*zip*/output.zip

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

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

PASSED: Continuous integration, rev:2756
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2758/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3616
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2069
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2069
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3644
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3490
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3490/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3490
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3490/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3490
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3490/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3490
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3490/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3490
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3490/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3490
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3490/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

some notes from testing it:

* Menus are opening, but they close themselves again immediately again.

* Dragging around child surfaces (in my case a Toolbar in a QWidget application) will get unity8 to spin on 100% cpu in miral::Window::move_to() and not recover from that.

review: Needs Fixing
Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

> some notes from testing it:
>
> * Menus are opening, but they close themselves again immediately again.
>
> * Dragging around child surfaces (in my case a Toolbar in a QWidget
> application) will get unity8 to spin on 100% cpu in miral::Window::move_to()
> and not recover from that.

I'm testing QtCreator and Kate, and not hitting either of these so far. The menu thing especially. But it does sound familiar, I think I had it at one stage, it was down to a focus issue.

Just for our info, are you using a USB mouse, or laptop trackpad, or touch?

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

laptop touchpad

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

The problem of tooltips not redrawing is bug 1652109

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

Text conflict in tests/qmltests/Stage/tst_WindowResizeArea.qml
1 conflicts encountered.

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

On 16/01/2017 06:46, Albert Astals Cid wrote:
> Text conflict in tests/qmltests/Stage/tst_WindowResizeArea.qml
> 1 conflicts encountered.

Fixed

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

FAILED: Continuous integration, rev:2769
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2925/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3817
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2213
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2213
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3845
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3688
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3688/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3688
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3688/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3688
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3688/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3688
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3688/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3688
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3688/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3688
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3688/artifact/output/*zip*/output.zip

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

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

FAILED: Continuous integration, rev:2769
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2939/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3835
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2228
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2228
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3863
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3706
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3706/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3706
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3706/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3706
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3706/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3706
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3706/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3706
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3706/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3706
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3706/artifact/output/*zip*/output.zip

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

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

FAILED: Continuous integration, rev:2770
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2947/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3844
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2237
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2237
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3872
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3715
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3715/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3715
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3715/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3715
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3715/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3715
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3715/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3715
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3715/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3715
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3715/artifact/output/*zip*/output.zip

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

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

FAILED: Continuous integration, rev:2770
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2950/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3848
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2241
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2241
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3876
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3719
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3719/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3719
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3719/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3719
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3719/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3719
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3719/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3719
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3719/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3719
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3719/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

I still see some issues:

* the right click context menu shows up but closes immediately again

* the code completion popup in kate seems to not be updated properly.
  this you said would be a known bug. also, normal tooltips seem to work fine, this just happens with the code completion windows (which probably aren't tooltip windows)

Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

+++ qml/Stage/ChildWindowTree.qml

Just a thought:

+ readonly property bool maximized: false
+ readonly property bool maximizedLeft: false
+ readonly property bool maximizedRight: false
+ readonly property bool maximizedHorizontally: false
+ readonly property bool maximizedVertically: false
+ readonly property bool maximizedTopLeft: false
+ readonly property bool maximizedTopRight: false
+ readonly property bool maximizedBottomLeft: false
+ readonly property bool maximizedBottomRight: false

Only one of these can be set true at any time, am I right? In that case, perhaps an enum would be less wordy, and reduce chances of logic error (multiple trues)

MaximizedState.qml:

pragma Singleton
import QtQuick 2.5
QtObject {
    id: singleton

    property bool maximized: 0
    property bool maximizedLeft: 1
    property bool maximizedRight: 2
...
}

and then use readonly property MaximizedState instead.

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

On 19/01/2017 11:44, Gerry Boland wrote:
> +++ qml/Stage/ChildWindowTree.qml
>
> Just a thought:
>
> + readonly property bool maximized: false
> + readonly property bool maximizedLeft: false
> + readonly property bool maximizedRight: false
> + readonly property bool maximizedHorizontally: false
> + readonly property bool maximizedVertically: false
> + readonly property bool maximizedTopLeft: false
> + readonly property bool maximizedTopRight: false
> + readonly property bool maximizedBottomLeft: false
> + readonly property bool maximizedBottomRight: false
>
> Only one of these can be set true at any time, am I right? In that case, perhaps an enum would be less wordy, and reduce chances of logic error (multiple trues)
>
> MaximizedState.qml:
>
> pragma Singleton
> import QtQuick 2.5
> QtObject {
> id: singleton
>
> property bool maximized: 0
> property bool maximizedLeft: 1
> property bool maximizedRight: 2
> ...
> }
>
> and then use readonly property MaximizedState instead.

I'm just mimicking the existing API in Stage.qml, where those are used
in several places. Having all those booleans separate seem to be
convenient for use in states and expressions over there.

Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

+// Meant to be created with a Loader to circunvent
typo, "circumvent"

+++ qml/Stage/ChildWindow.qml
Wanted to double-check this with you:

+ WindowDecoration {
+ onPressed: root.surface.activate();
+ onPressedChanged: if (d.moveHandler) { d.moveHandler.handlePressedChanged(pressed, pressedButtons, mouseX, mouseY); }

You're listening to both of MouseArea's pressed signals. Since the order is emission isn't guaranteed, you're sure both slots are roughly independent (one doesn't impact the other)? Just in case future Qt's reversed the order..

review: Needs Information
Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

+ // Do not hold on to a dead surface so that it can be destroyed.
+ surface: root.surface && root.surface.live ? root.surface : null

Could you add a FIXME here, as I think it should not be QML's job to release the MirSurface if its backing surface goes away. Instead backing MirSurface should go away but the MirSurfaceItem can live on with the last drawn frame and properties.

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

On 19/01/2017 11:58, Gerry Boland wrote:
> Review: Needs Information
>
> +// Meant to be created with a Loader to circunvent
> typo, "circumvent"

Fixed, thanks.

> +++ qml/Stage/ChildWindow.qml
> Wanted to double-check this with you:
>
> + WindowDecoration {
> + onPressed: root.surface.activate();
> + onPressedChanged: if (d.moveHandler) { d.moveHandler.handlePressedChanged(pressed, pressedButtons, mouseX, mouseY); }
>
> You're listening to both of MouseArea's pressed signals. Since the order is emission isn't guaranteed, you're sure both slots are roughly independent (one doesn't impact the other)? Just in case future Qt's reversed the order..

Again, am copy-pasting from elsewhere (DecoratedWindow.qml in this
case). I think those two are rather independent (order not particularly
important).

Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

+++ qml/Stage/ChildWindowTree.qml
+ function restore(someBool, someEnum) {}
cruft?

+ var pos = mapToItem(target.parent, mouse.x, mouse.y); // How can that work if we're just a QtObject (not an Item)?
very good question. It is working yeah?

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

On 19/01/2017 12:01, Gerry Boland wrote:
> + // Do not hold on to a dead surface so that it can be destroyed.
> + surface: root.surface && root.surface.live ? root.surface : null
>
> Could you add a FIXME here, as I think it should not be QML's job to release the MirSurface if its backing surface goes away. Instead backing MirSurface should go away but the MirSurfaceItem can live on with the last drawn frame and properties.

Done.

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

There's an issue with alt+tab:

* open an application that has only a toplevel window (e.g. terminal app)
* open an application (e.g. kate) and open a child window (e.g. the file open dialog).
* press alt+tab quickly, it will focus the terminal app
* press alt+tab again, it will focus kate's file open dialog, but not bring it to front.

=========

shouldn't this have ~dandrader/unity8/simplifyWindowDecoration as a prerequisite?

========

some inline comments

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

FAILED: Continuous integration, rev:2770
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2957/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3856
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2248
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2248
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3884
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3727
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3727/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3727
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3727/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3727
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3727/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3727
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3727/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3727
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3727/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3727
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3727/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

playing with tryShell, opening kate and then opening the menu dialogs, it would seem to me that they should close again when clicking outside of them? Currently allows going into situation where you e.g. open a couple of those menus and then when you click the menu in the title bar, the menu will appear below those in-app menus

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 19/01/2017 12:08, Gerry Boland wrote:
> +++ qml/Stage/ChildWindowTree.qml
> + function restore(someBool, someEnum) {}
> cruft?

Removed

>
> + var pos = mapToItem(target.parent, mouse.x, mouse.y); // How can that work if we're just a QtObject (not an Item)?
> very good question. It is working yeah?

It must, otherwise resize wouldn't be working. :D
According to lukaz it gets from the context, to from the closest Item
parent...
/me shrugs
But it does deserve a refactoring at some point. This is quite messy.

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

On 19/01/2017 13:31, Michael Zanetti wrote:
> Review: Needs Information
>
> playing with tryShell, opening kate and then opening the menu dialogs, it would seem to me that they should close again when clicking outside of them? Currently allows going into situation where you e.g. open a couple of those menus and then when you click the menu in the title bar, the menu will appear below those in-app menus

That fake kate has a very crude menu implementation. They are there just
so that you can check positioning and, most-importantly, its decorations
(or lack thereof).

A ChildWindow that has a dialog surface will get shadows, title bar and
be movable with touch (ie, get touch controls when appropriate). But a
ChildWindow that has a menu surface will only get shadows and nothing else.

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

On 19/01/2017 11:23, Michael Zanetti wrote:
> I still see some issues:
>
> * the right click context menu shows up but closes immediately again

Still can't reproduce it. :/

> * the code completion popup in kate seems to not be updated properly.
> this you said would be a known bug. also, normal tooltips seem to work fine, this just happens with the code completion windows (which probably aren't tooltip windows)

Works fine if you install those:

https://bileto.ubuntu.com/#/ticket/2382 (miral 1.0.2)
https://code.launchpad.net/~dandrader/qtubuntu/resizeToolTip (just
updated it, btw)

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

FAILED: Continuous integration, rev:2773
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2961/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3860
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2252
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2252
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3888
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3733
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3733/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3733
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3733/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3733
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3733/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3733
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3733/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3733
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3733/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3733
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3733/artifact/output/*zip*/output.zip

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

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

FAILED: Continuous integration, rev:2773
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2964/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3863
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2254
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2254
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3891
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3736
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3736/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3736
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3736/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3736
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3736/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3736
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3736/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3736
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3736/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3736
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3736/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 19/01/2017 12:33, Michael Zanetti wrote:
> Review: Needs Fixing
>
> There's an issue with alt+tab:
>
> * open an application that has only a toplevel window (e.g. terminal app)
> * open an application (e.g. kate) and open a child window (e.g. the file open dialog).
> * press alt+tab quickly, it will focus the terminal app
> * press alt+tab again, it will focus kate's file open dialog, but not bring it to front.

That's miral bug 1658085

> shouldn't this have ~dandrader/unity8/simplifyWindowDecoration as a prerequisite?

Yes. Done.

> Diff comments:
>
>> === added file 'qml/Stage/ChildWindow.qml'
>> --- qml/Stage/ChildWindow.qml 1970-01-01 00:00:00 +0000
>> +++ qml/Stage/ChildWindow.qml 2017-01-18 19:24:19 +0000
>> @@ -0,0 +1,156 @@
>> [...]
>> +
>> + width: surface ? surface.size.width : 0
>> + height: surface ? surface.size.height : 0
>> +
>> + // Make it get shown and hidden with a fade in/out effect
>> + opacity: surface && surface.state !== Mir.MinimizedState && surface.state !== Mir.HiddenState ? 1.0 : 0.0
>> + Behavior on opacity { UbuntuNumberAnimation {} }
> I wonder if this might be better set to SnapDuration instead of the default of FastDuration.

I don't really have a preference. Want me to change to that?

>
>> === added file 'qml/Stage/ChildWindowTree.qml'
>> --- qml/Stage/ChildWindowTree.qml 1970-01-01 00:00:00 +0000
>> +++ qml/Stage/ChildWindowTree.qml 2017-01-18 19:24:19 +0000
>> @@ -0,0 +1,129 @@
>> +/*
>> [...]
>> + }
>> +
>> + readonly property bool windowedTransitionRunning: false
> hmm... is this used somewhere? if it's readonly and set to false, what is it good for?

As the comment above says, that's API that MoveHandler expects its
target to have.

>
>> === modified file 'qml/Stage/MoveHandler.qml'
>> --- qml/Stage/MoveHandler.qml 2016-12-12 16:45:09 +0000
>> +++ qml/Stage/MoveHandler.qml 2017-01-18 19:24:19 +0000
>> @@ -117,35 +119,38 @@
>> target.requestRestore();
>> }
>>
>> - var pos = mapToItem(target.parent, mouse.x, mouse.y);
>> + var pos = mapToItem(target.parent, mouse.x, mouse.y); // How can that work if we're just a QtObject (not an Item)?
> good question, does it?

It must, otherwise resize wouldn't be working. :D

According to lukaz it gets from the context, to from the closest Item
parent...
/me shrugs
But it does deserve a refactoring at some point. This is quite messy.

>
>> === modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp'
>> --- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-12-20 15:50:41 +0000
>> +++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2017-01-18 19:24:19 +0000
>> @@ -122,7 +123,9 @@
>> auto surface = surfaceManager->createSurface(surfaceName,
>> Mir::NormalType,
>> fullscreen() ? Mir::FullscreenState : Mir::RestoredState,
>> - m_screenshotFileName);
>> + nullptr, /* parentSurface */
> is there a space too much?

Yes. Fixed.

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

FAILED: Continuous integration, rev:2774
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/2982/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/3884
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2273
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2273
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/3912
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3757
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/3757/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3757
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/3757/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3757
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/3757/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3757
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/3757/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3757
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/3757/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3757
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/3757/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
lp:~dandrader/unity8/childWindows updated
2771. By Lukáš Tinkl

Fix keymap not being applied on the shell itself (LP: #1626435)

Approved by: Gerry Boland, Unity8 CI Bot

2772. By Albert Astals Cid

Limit tab-focus travelling on dialogs with a fence

Approved by: Lukáš Tinkl, Unity8 CI Bot

2773. By Lukáš Tinkl

Shell dialog improvements (kbd focus, mouse eater)

Approved by: Michael Zanetti, Unity8 CI Bot

2774. By Albert Astals Cid

Restore focus to where it was when our ShellDialogs get unloaded

UITK Dialogs want to have this feature but it seems to be broken, so i'm fixing it here first (since we use dialogs in a kind of special way)
I'll try to fix UITK next

Approved by: Andrea Cimitan, Unity8 CI Bot

2775. By Michael Terry

Simplify the lightdm mock to make future greeter improvements easier to test.

I simplified the mock liblightdm to avoid separate files for the Private classes. That can all go into the main files. The separation isn't worth wading through the files to find what you want.

And I dropped the mock LightDM plugin entirely. (opting instead for a tiny "mock()" API call on the real plugin that returns an object that can be used to manipulate our mock liblightdm, if we're in testing mode)

Approved by: Albert Astals Cid, Unity8 CI Bot

2776. By Josh Arenson

Add a test for the session chooser icon in the greeter's sessions list

Approved by: Albert Astals Cid, Unity8 CI Bot

2777. By Michael Terry

Add support for guest sessions in unity8-greeter.

Adds support for the "hasGuestAccount" and "selectGuest" LightDM hints and does so largely by having the users model report a "*guest" user, rather than adding special support in qml.

Approved by: Albert Astals Cid, Unity8 CI Bot

2778. By Michael Terry

Add support for LightDM hints for manual logins and hiding normal users.

Approved by: Albert Astals Cid, Unity8 CI Bot

2779. By Michael Terry

Use a model for PAM prompts, supporting more possible interactions.

- This lets us show more than one message and more than one prompt from PAM.

- We now also show error text when a user enters a wrong password. This matches unity7-greeter behavior.

- Similarly, when a fingerprint login is attempted, but we are demanding a real login (e.g. the user hasn't logged in before), we now show a message to explain that a bit.

- Simplify the Greeter/View interactions a bit. We no longer need to signal quite as much events, since the view reflects the prompts model directly.

- Fix keyboard focus highlight handling among prompts.

- Update and expand the tests.

Approved by: Albert Astals Cid

2780. By Albert Astals Cid

Update current session after changing the user

This matches unity7 greeter behaviour, i.e. if you change the session and then change the user, the session that shows up is the last session that new user logged in and not the new session you selected in the previous user

Approved by: Josh Arenson, Unity8 CI Bot

2781. By Albert Astals Cid

Add keyboard navigation for Indicators

Esc closes
Left/Right selects prev/next indicator

Approved by: Michael Zanetti, Unity8 CI Bot

2782. By Nick Dedekind

Added Alt+F10 shortcut to open app menus. (LP: #1656896)

Approved by: Albert Astals Cid, Unity8 CI Bot

2783. By Daniel d'Andrada

Simplify DecoratedWindow

Reduce the number of nested MouseAreas

Approved by: Nick Dedekind, Unity8 CI Bot

2784. By Nick Dedekind

Fixed menu layout width calculations. (LP: #1657050)

Approved by: Albert Astals Cid, Unity8 CI Bot

2785. By Michael Zanetti

hint the launcher to indicate a successful size change to the user (LP: #1646457)

Approved by: Lukáš Tinkl, Unity8 CI Bot

2786. By Lukáš Tinkl

Start searching directly as you type, w/o having to first focus/click the search field.

Approved by: Michael Zanetti, Unity8 CI Bot

2787. By Michael Zanetti

Improvements for the appdrawer

Allow cancelling of the reveal gesture
move the app store uri to a gsetting (LP: #1648173)

Approved by: Lukáš Tinkl, Unity8 CI Bot

2788. By Michael Zanetti

Adjust home key to still focus the dash instead of messing with the drawer

Approved by: Lukáš Tinkl

2789. By Albert Astals Cid

a window -> the current window

Approved by: Lukáš Tinkl

2790. By Lukáš Tinkl

Add a test for the real implementation of WindowStateStorage

Approved by: Albert Astals Cid, Unity8 CI Bot

2791. By Albert Astals Cid

There's no spreadDelegate_ anymore

Goes from ~9 to ~3 minutes

Approved by: Michael Zanetti, Unity8 CI Bot

2792. By Michael Terry

Fix grouping of autopkg output and allow optionally passing arguments to installed test scripts.

Approved by: Albert Astals Cid, Unity8 CI Bot

2793. By Lukáš Tinkl

Use a four finger gesture to open the drawer, much like in u7

Approved by: Michael Zanetti, Unity8 CI Bot

2794. By Michael Zanetti

allow 4 finger simulation with mousetouchadaptor

Approved by: Lukáš Tinkl, Unity8 CI Bot

2795. By Nick Dedekind

Skip Panel::test_drag_indicator_item_down_shows_menu

Approved by: Lukáš Tinkl, Michał Sawicz, Unity8 CI Bot

2796. By Daniel d'Andrada

Remove unnecessary warning message

It's being printed on every initialization for quite a while now and it's not prompting us
to perform any action. Thus this can't be really a warning if it's always there.

Approved by: Michael Zanetti, Unity8 CI Bot

2797. By CI Train Bot Account

Releasing 8.15+17.04.20170124-0ubuntu1

2798. By Launchpad Translations on behalf of unity-team

Launchpad automatic translations update.

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

Text conflict in CMakeLists.txt
1 conflicts encountered.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 26/01/2017 06:29, Albert Astals Cid wrote:
> Text conflict in CMakeLists.txt
> 1 conflicts encountered.

Fixed.

lp:~dandrader/unity8/childWindows updated
2799. By Daniel d'Andrada

Initial support for child windows (menus, dialogs, tooltips)

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

the shadows are a bit big http://i.imgur.com/Pv779co.jpg

Revision history for this message
Gerry Boland (gerboland) wrote :

Did another pass through the code, looks ok

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2017-01-24 07:39:33 +0000
3+++ CMakeLists.txt 2017-01-26 11:10:45 +0000
4@@ -70,7 +70,7 @@
5 find_package(Qt5Concurrent 5.6 REQUIRED)
6 find_package(Qt5Sql 5.6 REQUIRED)
7
8-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=25)
9+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=26)
10 pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
11 pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
12 pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
13
14=== modified file 'debian/control'
15--- debian/control 2017-01-24 07:38:04 +0000
16+++ debian/control 2017-01-26 11:10:45 +0000
17@@ -38,7 +38,7 @@
18 libubuntugestures5-private-dev (>= 1.3.2030),
19 libudev-dev,
20 libudm-common-dev,
21- libunity-api-dev (>= 8.1),
22+ libunity-api-dev (>= 8.2),
23 libusermetricsoutput1-dev,
24 # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
25 libx11-dev[!arm64 !armhf],
26@@ -163,7 +163,7 @@
27 qttranslations5-l10n,
28 ubuntu-thumbnailer-impl-0,
29 ubuntu-wallpapers,
30- unity-application-impl-23,
31+ unity-application-impl-26,
32 unity-notifications-impl-3,
33 unity-plugin-scopes | unity-scopes-impl,
34 unity-scopes-impl-12,
35@@ -214,7 +214,7 @@
36 ${misc:Depends},
37 ${shlibs:Depends},
38 Provides: unity-application-impl,
39- unity-application-impl-23,
40+ unity-application-impl-26,
41 unity8-fake-env,
42 Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1),
43 unity8-fake-env,
44
45=== modified file 'plugins/WindowManager/TopLevelWindowModel.cpp'
46--- plugins/WindowManager/TopLevelWindowModel.cpp 2016-12-06 14:42:26 +0000
47+++ plugins/WindowManager/TopLevelWindowModel.cpp 2017-01-26 11:10:45 +0000
48@@ -176,18 +176,13 @@
49 // No point in signaling anything if we're resetting the whole model
50 }
51
52- int id = generateId();
53- Window *window = new Window(id, this);
54- if (surface) {
55- window->setSurface(surface);
56- }
57+ Window *window = createWindow(surface);
58+
59 m_windowModel.prepend(ModelEntry(window, application));
60 if (surface) {
61 connectSurface(surface);
62 }
63
64- connectWindow(window);
65-
66 if (m_modelState == InsertingState) {
67 endInsertRows();
68 Q_EMIT countChanged();
69@@ -322,34 +317,47 @@
70 }
71 }
72
73+Window *TopLevelWindowModel::createWindow(unityapi::MirSurfaceInterface *surface)
74+{
75+ int id = generateId();
76+ Window *qmlWindow = new Window(id, this);
77+ connectWindow(qmlWindow);
78+ if (surface) {
79+ qmlWindow->setSurface(surface);
80+ }
81+ return qmlWindow;
82+}
83+
84 void TopLevelWindowModel::onSurfaceCreated(unityapi::MirSurfaceInterface *surface)
85 {
86 DEBUG_MSG << "(" << surface << ")";
87- if (surface->type() == Mir::InputMethodType) {
88- int id = generateId();
89- Window *qmlWindow = new Window(id, this);
90- connectWindow(qmlWindow);
91- qmlWindow->setSurface(surface);
92- setInputMethodWindow(qmlWindow);
93+
94+ if (surface->parentSurface()) {
95+ // Wrap it in a Window so that we keep focusedWindow() up to date.
96+ Window *window = createWindow(surface);
97+ connect(surface, &QObject::destroyed, window, [=](){
98+ window->setSurface(nullptr);
99+ window->deleteLater();
100+ });
101 } else {
102- auto application = m_applicationManager->findApplicationWithSurface(surface);
103- if (application) {
104- prependSurface(surface, application);
105+ if (surface->type() == Mir::InputMethodType) {
106+ setInputMethodWindow(createWindow(surface));
107 } else {
108- // Must be a prompt session. No need to do add it as a prompt surface is not top-level.
109- // It will show up in the ApplicationInfoInterface::promptSurfaceList of some application.
110- // Still wrap it in a Window though, so that we keep focusedWindow() up to date.
111- int id = generateId();
112- Window *promptWindow = new Window(id, this);
113- connectWindow(promptWindow);
114- promptWindow->setSurface(surface);
115- connect(surface, &QObject::destroyed, promptWindow, [=](){
116- promptWindow->setSurface(nullptr);
117- promptWindow->deleteLater();
118- });
119+ auto *application = m_applicationManager->findApplicationWithSurface(surface);
120+ if (application) {
121+ prependSurface(surface, application);
122+ } else {
123+ // Must be a prompt session. No need to do add it as a prompt surface is not top-level.
124+ // It will show up in the ApplicationInfoInterface::promptSurfaceList of some application.
125+ // Still wrap it in a Window though, so that we keep focusedWindow() up to date.
126+ Window *promptWindow = createWindow(surface);
127+ connect(surface, &QObject::destroyed, promptWindow, [=](){
128+ promptWindow->setSurface(nullptr);
129+ promptWindow->deleteLater();
130+ });
131+ }
132 }
133 }
134- // TODO: handle surfaces that are neither top-level windows nor input method. eg: child dialogs, popups, menus
135 }
136
137 void TopLevelWindowModel::removeAt(int index)
138
139=== modified file 'plugins/WindowManager/TopLevelWindowModel.h'
140--- plugins/WindowManager/TopLevelWindowModel.h 2016-12-06 14:42:26 +0000
141+++ plugins/WindowManager/TopLevelWindowModel.h 2017-01-26 11:10:45 +0000
142@@ -220,6 +220,8 @@
143
144 void activateTopMostWindowWithoutId(int forbiddenId);
145
146+ Window *createWindow(unity::shell::application::MirSurfaceInterface *surface);
147+
148 struct ModelEntry {
149 ModelEntry() {}
150 ModelEntry(Window *window,
151
152=== modified file 'plugins/WindowManager/Window.h'
153--- plugins/WindowManager/Window.h 2016-11-30 19:24:02 +0000
154+++ plugins/WindowManager/Window.h 2017-01-26 11:10:45 +0000
155@@ -32,7 +32,6 @@
156 }
157 }
158
159-
160 Q_DECLARE_LOGGING_CATEGORY(UNITY_WINDOW)
161
162 /**
163
164=== modified file 'qml/Components/WindowControlButtons.qml'
165--- qml/Components/WindowControlButtons.qml 2016-10-27 14:54:48 +0000
166+++ qml/Components/WindowControlButtons.qml 2017-01-26 11:10:45 +0000
167@@ -29,6 +29,7 @@
168 property bool windowIsMaximized: false
169 property bool closeButtonShown: true
170 property bool maximizeButtonShown: true
171+ property bool minimizeButtonVisible: true
172 property bool overlayShown
173
174 signal closeClicked()
175@@ -75,6 +76,7 @@
176 height: parent.height
177 width: height
178 onClicked: root.minimizeClicked()
179+ visible: root.minimizeButtonVisible
180
181 // We dont want touch events to fall through to parent,
182 // otherwise the containsMouse will not work.
183
184=== added file 'qml/Stage/ChildWindow.qml'
185--- qml/Stage/ChildWindow.qml 1970-01-01 00:00:00 +0000
186+++ qml/Stage/ChildWindow.qml 2017-01-26 11:10:45 +0000
187@@ -0,0 +1,159 @@
188+/*
189+ * Copyright (C) 2016 Canonical, Ltd.
190+ *
191+ * This program is free software; you can redistribute it and/or modify
192+ * it under the terms of the GNU General Public License as published by
193+ * the Free Software Foundation; version 3.
194+ *
195+ * This program is distributed in the hope that it will be useful,
196+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
197+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
198+ * GNU General Public License for more details.
199+ *
200+ * You should have received a copy of the GNU General Public License
201+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
202+ */
203+
204+import QtQuick 2.4
205+import Ubuntu.Components 1.3
206+import Unity.Application 0.1
207+
208+Item {
209+ id: root
210+
211+ // Set from outside.
212+ property var surface
213+ property Item boundsItem
214+ property Item target
215+ property alias requestedWidth: surfaceContainer.requestedWidth
216+ property alias requestedHeight: surfaceContainer.requestedHeight
217+
218+ width: surface ? surface.size.width : 0
219+ height: surface ? surface.size.height : 0
220+
221+ // Make it get shown and hidden with a fade in/out effect
222+ opacity: surface && surface.state !== Mir.MinimizedState && surface.state !== Mir.HiddenState ? 1.0 : 0.0
223+ Behavior on opacity { UbuntuNumberAnimation {} }
224+ visible: opacity !== 0.0 // make it transparent to input as well
225+
226+ readonly property bool dragging: windowResizeArea.dragging || d.touchOverlayDragging || d.moveHandlerDragging
227+
228+ QtObject {
229+ id: d
230+ readonly property bool decorated: surface ? surface.type === Mir.UtilityType
231+ || surface.type === Mir.DialogType
232+ || surface.type === Mir.NormalType
233+ : false
234+
235+ readonly property bool moveable: decorated
236+ readonly property bool resizeable: decorated
237+
238+ property alias decoration: decorationLoader.item
239+ property alias moveHandler: moveHandlerLoader.item
240+
241+ readonly property bool touchOverlayDragging: touchOverlayLoader.item ? touchOverlayLoader.item.dragging : false
242+ readonly property bool moveHandlerDragging: moveHandlerLoader.item ? moveHandlerLoader.item.dragging : false
243+ }
244+
245+ WindowResizeArea {
246+ id: windowResizeArea
247+ anchors {
248+ top: decorationLoader.top
249+ bottom: parent.bottom
250+ left: parent.left; right: parent.right
251+ }
252+ target: root.target
253+ boundsItem: root.boundsItem
254+ minWidth: units.gu(10)
255+ minHeight: units.gu(10)
256+ borderThickness: units.gu(2)
257+ enabled: d.resizeable
258+ visible: enabled
259+ onPressed: root.surface.activate();
260+ }
261+
262+ BorderImage {
263+ property real shadowThickness: root.surface && root.surface.focused ? units.gu(2) : units.gu(1.5)
264+ anchors {
265+ top: decorationLoader.top
266+ bottom: parent.bottom
267+ left: parent.left; right: parent.right
268+ margins: -shadowThickness
269+ }
270+ source: "../graphics/dropshadow2gu.sci"
271+ opacity: .3
272+ }
273+
274+ Loader {
275+ id: decorationLoader
276+ anchors.bottom: root.top
277+ anchors.left: root.left
278+ anchors.right: root.right
279+
280+ visible: active
281+ active: d.decorated
282+
283+ height: item ? item.height : 0
284+
285+ sourceComponent: Component {
286+ WindowDecoration {
287+ height: units.gu(3)
288+ title: root.surface ? root.surface.name : ""
289+ active: root.surface ? root.surface.focused : false
290+ closeButtonVisible: false
291+ minimizeButtonVisible: false
292+ maximizeButtonShown: false
293+ onPressed: root.surface.activate();
294+ onPressedChanged: if (d.moveHandler) { d.moveHandler.handlePressedChanged(pressed, pressedButtons, mouseX, mouseY); }
295+ onPositionChanged: if (d.moveHandler) {
296+ d.moveHandler.handlePositionChanged(mouse);
297+ }
298+ onReleased: if (d.moveHandler) { d.moveHandler.handleReleased(); }
299+ }
300+ }
301+ }
302+
303+ Loader {
304+ id: moveHandlerLoader
305+ active: d.moveable
306+ sourceComponent: Component {
307+ MoveHandler {
308+ target: root.target
309+ buttonsWidth: d.decoration ? d.decoration.buttonsWidth : 0
310+ boundsItem: root.boundsItem
311+ boundsTopMargin: decorationLoader.height
312+ }
313+ }
314+ }
315+
316+ SurfaceContainer {
317+ id: surfaceContainer
318+
319+ // Do not hold on to a dead surface so that it can be destroyed.
320+ // FIXME It should not be QML's job to release the MirSurface if its backing surface goes away. Instead backing
321+ // MirSurface should go away but the MirSurfaceItem should be able to live on with the last drawn frame
322+ // and properties.
323+ surface: root.surface && root.surface.live ? root.surface : null
324+
325+ requestedWidth: surface ? surface.size.width : 0
326+ requestedHeight: surface ? surface.size.height : 0
327+
328+ // TODO ChildWindow parent will probably want to control those
329+ interactive: true
330+ consumesInput: true
331+ }
332+
333+ Loader {
334+ id: touchOverlayLoader
335+ active: d.resizeable || d.moveable
336+ anchors.top: decorationLoader.top
337+ anchors.bottom: parent.bottom
338+ anchors.left: parent.left
339+ anchors.right: parent.right
340+ sourceComponent: Component { WindowControlsOverlay {
341+ target: root.target
342+ resizeArea: windowResizeArea
343+ boundsItem: root.boundsItem
344+ } }
345+ }
346+}
347
348=== added file 'qml/Stage/ChildWindowRepeater.qml'
349--- qml/Stage/ChildWindowRepeater.qml 1970-01-01 00:00:00 +0000
350+++ qml/Stage/ChildWindowRepeater.qml 2017-01-26 11:10:45 +0000
351@@ -0,0 +1,28 @@
352+/*
353+ * Copyright (C) 2016 Canonical, Ltd.
354+ *
355+ * This program is free software; you can redistribute it and/or modify
356+ * it under the terms of the GNU General Public License as published by
357+ * the Free Software Foundation; version 3.
358+ *
359+ * This program is distributed in the hope that it will be useful,
360+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
361+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
362+ * GNU General Public License for more details.
363+ *
364+ * You should have received a copy of the GNU General Public License
365+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
366+ */
367+
368+import QtQuick 2.4
369+
370+// Meant to be created with a Loader to circumvent the "ChildWindowTree is instantiated recursively" error from the QML engine
371+Repeater {
372+ id: root
373+ property Item boundsItem
374+ delegate: ChildWindowTree {
375+ surface: model.surface
376+ z: root.count - model.index
377+ boundsItem: root.boundsItem
378+ }
379+}
380
381=== added file 'qml/Stage/ChildWindowTree.qml'
382--- qml/Stage/ChildWindowTree.qml 1970-01-01 00:00:00 +0000
383+++ qml/Stage/ChildWindowTree.qml 2017-01-26 11:10:45 +0000
384@@ -0,0 +1,127 @@
385+/*
386+ * Copyright (C) 2016 Canonical, Ltd.
387+ *
388+ * This program is free software; you can redistribute it and/or modify
389+ * it under the terms of the GNU General Public License as published by
390+ * the Free Software Foundation; version 3.
391+ *
392+ * This program is distributed in the hope that it will be useful,
393+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
394+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
395+ * GNU General Public License for more details.
396+ *
397+ * You should have received a copy of the GNU General Public License
398+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
399+ */
400+
401+import QtQuick 2.4
402+import Ubuntu.Components 1.3
403+import Unity.Application 0.1
404+
405+Item {
406+ id: root
407+
408+ property alias surface: childWindow.surface
409+ property real displacementX: 0
410+ property real displacementY: 0
411+ property alias boundsItem: childWindow.boundsItem
412+
413+ x: surface ? surface.position.x + displacementX : 0
414+ y: surface ? surface.position.y + displacementY : 0
415+ width: childWindow.width
416+ height: childWindow.height
417+
418+ ////
419+ // API expected by MoveHandler (and some by WindowResizeArea as well)
420+ readonly property bool maximized: false
421+ readonly property bool maximizedLeft: false
422+ readonly property bool maximizedRight: false
423+ readonly property bool maximizedHorizontally: false
424+ readonly property bool maximizedVertically: false
425+ readonly property bool maximizedTopLeft: false
426+ readonly property bool maximizedTopRight: false
427+ readonly property bool maximizedBottomLeft: false
428+ readonly property bool maximizedBottomRight: false
429+ readonly property bool anyMaximized: maximized || maximizedLeft || maximizedRight || maximizedHorizontally || maximizedVertically ||
430+ maximizedTopLeft || maximizedTopRight || maximizedBottomLeft || maximizedBottomRight
431+
432+ readonly property bool canBeCornerMaximized: false
433+ readonly property bool canBeMaximizedLeftRight: false
434+ readonly property bool canBeMaximized: false
435+
436+ readonly property var resizeArea: QtObject {
437+ property real normalWidth: units.gu(1)
438+ property real normalHeight: units.gu(1)
439+ }
440+
441+ readonly property bool windowedTransitionRunning: false
442+
443+ // NB: those bindings will be overwritten by MoveHandler when you first move the window
444+ property real windowedX: x
445+ property real windowedY: y
446+
447+
448+ property real restoredX
449+ property real restoredY
450+
451+ state: "restored"
452+ // end of API expected by MoveHandler
453+ ////
454+
455+ ////
456+ // API expected by WindowResizeArea
457+ property real windowedWidth: childWindow.width
458+ property real windowedHeight: childWindow.height
459+ // end of API expected by WindowResizeArea
460+ ////
461+
462+ ////
463+ // API expected by WindowControlsOverlay
464+ function activate() {
465+ surface.activate();
466+ }
467+ // end of API expected by WindowControlsOverlay
468+ ////
469+
470+ Binding {
471+ target: root.surface
472+ when: childWindow.dragging
473+ property: "requestedPosition"
474+ value: Qt.point(root.windowedX - root.displacementX,
475+ root.windowedY - root.displacementY);
476+ }
477+
478+ // It's a separate Item so that a window can be hid independently of its children
479+ ChildWindow {
480+ id: childWindow
481+ target: root
482+ requestedWidth: root.windowedWidth
483+ requestedHeight: root.windowedHeight
484+ }
485+
486+ Connections {
487+ target: root.surface
488+ onFocusRequested: {
489+ root.surface.activate();
490+ }
491+ }
492+
493+ // Using a loader here mainly to circunvent the "ChildWindowTree is instantiated recursively" error from the QML engine
494+ Loader {
495+ id: childRepeaterLoader
496+ source: "ChildWindowRepeater.qml"
497+ active: root.surface && root.surface.childSurfaceList.count > 0
498+ Binding {
499+ target: childRepeaterLoader.item
500+ when: childRepeaterLoader.item
501+ property: "model"
502+ value: root.surface ? root.surface.childSurfaceList : null
503+ }
504+ Binding {
505+ target: childRepeaterLoader.item
506+ when: childRepeaterLoader.item
507+ property: "boundsItem"
508+ value: root.boundsItem
509+ }
510+ }
511+}
512
513=== modified file 'qml/Stage/DecoratedWindow.qml'
514--- qml/Stage/DecoratedWindow.qml 2017-01-18 17:34:57 +0000
515+++ qml/Stage/DecoratedWindow.qml 2017-01-26 11:10:45 +0000
516@@ -67,8 +67,7 @@
517 readonly property int heightIncrement: !counterRotate ? applicationWindow.heightIncrement : applicationWindow.widthIncrement
518
519 property alias overlayShown: decoration.overlayShown
520- property alias stageWidth: moveHandler.stageWidth
521- property alias stageHeight: moveHandler.stageHeight
522+ property alias boundsItem: moveHandler.boundsItem
523 readonly property alias dragging: moveHandler.dragging
524
525 readonly property Item clientAreaItem: applicationWindow
526
527=== modified file 'qml/Stage/MoveHandler.qml'
528--- qml/Stage/MoveHandler.qml 2016-12-12 16:45:09 +0000
529+++ qml/Stage/MoveHandler.qml 2017-01-26 11:10:45 +0000
530@@ -19,15 +19,14 @@
531 import Ubuntu.Components 1.3
532 import Utils 0.1
533 import "../Components"
534-import "../Components/PanelState"
535
536 QtObject {
537 id: root
538
539 property Item target // appDelegate
540- property int stageWidth
541- property int stageHeight
542 property real buttonsWidth: 0
543+ property Item boundsItem
544+ property real boundsTopMargin: 0
545
546 readonly property bool dragging: priv.dragging
547
548@@ -79,7 +78,10 @@
549 // length of the triggerArea square diagonal
550 var diagLength = Math.sqrt(2 * priv.triggerArea * priv.triggerArea);
551 var ratio = 1 - (distance / diagLength);
552- return bx > 0 && bx <= stageWidth && by > 0 && by <= stageHeight ? ratio : 1; // everything "outside" of our square from the center is 1
553+
554+ // everything "outside" of our square from the center is 1
555+ var mousePosBoundsCoords = target.mapToItem(root.boundsItem, bx, by);
556+ return root.boundsItem.contains(mousePosBoundsCoords) ? ratio : 1;
557 }
558 property real progress: 0
559 }
560@@ -117,35 +119,38 @@
561 target.requestRestore();
562 }
563
564- var pos = mapToItem(target.parent, mouse.x, mouse.y);
565+ var pos = mapToItem(target.parent, mouse.x, mouse.y); // How can that work if we're just a QtObject (not an Item)?
566+ var bounds = boundsItem.mapToItem(target.parent, 0, 0, boundsItem.width, boundsItem.height);
567+ bounds.y += boundsTopMargin;
568+ bounds.height -= boundsTopMargin;
569 // Use integer coordinate values to ensure that target is left in a pixel-aligned
570 // position. Mouse movement could have subpixel precision, yielding a fractional
571 // mouse position.
572 target.windowedX = Math.round(pos.x - priv.distanceX);
573- target.windowedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
574+ target.windowedY = Math.round(Math.max(pos.y - priv.distanceY, bounds.top));
575
576 if (sensingPoints) { // edge/corner detection when dragging via the touch overlay
577- if (sensingPoints.topLeft.x < priv.triggerArea && sensingPoints.topLeft.y < PanelState.panelHeight + priv.triggerArea
578+ if (sensingPoints.topLeft.x < priv.triggerArea && sensingPoints.topLeft.y < bounds.top + priv.triggerArea
579 && target.canBeCornerMaximized) { // top left
580- priv.progress = priv.progressInCorner(0, PanelState.panelHeight, sensingPoints.topLeft.x, sensingPoints.topLeft.y);
581+ priv.progress = priv.progressInCorner(bounds.left, bounds.top, sensingPoints.topLeft.x, sensingPoints.topLeft.y);
582 priv.resetEdges();
583 priv.nearTopLeftCorner = true;
584 root.fakeMaximizeTopLeftAnimationRequested(priv.progress);
585- } else if (sensingPoints.topRight.x > stageWidth - priv.triggerArea && sensingPoints.topRight.y < PanelState.panelHeight + priv.triggerArea
586+ } else if (sensingPoints.topRight.x > bounds.right - priv.triggerArea && sensingPoints.topRight.y < bounds.top + priv.triggerArea
587 && target.canBeCornerMaximized) { // top right
588- priv.progress = priv.progressInCorner(stageWidth, PanelState.panelHeight, sensingPoints.topRight.x, sensingPoints.topRight.y);
589+ priv.progress = priv.progressInCorner(bounds.right, bounds.top, sensingPoints.topRight.x, sensingPoints.topRight.y);
590 priv.resetEdges();
591 priv.nearTopRightCorner = true;
592 root.fakeMaximizeTopRightAnimationRequested(priv.progress);
593- } else if (sensingPoints.bottomLeft.x < priv.triggerArea && sensingPoints.bottomLeft.y > stageHeight - priv.triggerArea
594+ } else if (sensingPoints.bottomLeft.x < priv.triggerArea && sensingPoints.bottomLeft.y > bounds.bottom - priv.triggerArea
595 && target.canBeCornerMaximized) { // bottom left
596- priv.progress = priv.progressInCorner(0, stageHeight, sensingPoints.bottomLeft.x, sensingPoints.bottomLeft.y);
597+ priv.progress = priv.progressInCorner(bounds.left, bounds.bottom, sensingPoints.bottomLeft.x, sensingPoints.bottomLeft.y);
598 priv.resetEdges();
599 priv.nearBottomLeftCorner = true;
600 root.fakeMaximizeBottomLeftAnimationRequested(priv.progress);
601- } else if (sensingPoints.bottomRight.x > stageWidth - priv.triggerArea && sensingPoints.bottomRight.y > stageHeight - priv.triggerArea
602+ } else if (sensingPoints.bottomRight.x > bounds.right - priv.triggerArea && sensingPoints.bottomRight.y > bounds.bottom - priv.triggerArea
603 && target.canBeCornerMaximized) { // bottom right
604- priv.progress = priv.progressInCorner(stageWidth, stageHeight, sensingPoints.bottomRight.x, sensingPoints.bottomRight.y);
605+ priv.progress = priv.progressInCorner(bounds.right, bounds.bottom, sensingPoints.bottomRight.x, sensingPoints.bottomRight.y);
606 priv.resetEdges();
607 priv.nearBottomRightCorner = true;
608 root.fakeMaximizeBottomRightAnimationRequested(priv.progress);
609@@ -154,13 +159,13 @@
610 priv.resetEdges();
611 priv.nearLeftEdge = true;
612 root.fakeMaximizeLeftAnimationRequested(priv.progress);
613- } else if (sensingPoints.right.x > stageWidth - priv.triggerArea && target.canBeMaximizedLeftRight) { // right
614- priv.progress = MathUtils.clampAndProject(sensingPoints.right.x, stageWidth - priv.triggerArea, stageWidth, 0, 1);
615+ } else if (sensingPoints.right.x > bounds.right - priv.triggerArea && target.canBeMaximizedLeftRight) { // right
616+ priv.progress = MathUtils.clampAndProject(sensingPoints.right.x, bounds.right - priv.triggerArea, bounds.right, 0, 1);
617 priv.resetEdges();
618 priv.nearRightEdge = true;
619 root.fakeMaximizeRightAnimationRequested(priv.progress);
620- } else if (sensingPoints.top.y < PanelState.panelHeight + priv.triggerArea && target.canBeMaximized) { // top
621- priv.progress = MathUtils.clampAndProject(sensingPoints.top.y, PanelState.panelHeight + priv.triggerArea, 0, 0, 1);
622+ } else if (sensingPoints.top.y < bounds.top + priv.triggerArea && target.canBeMaximized) { // top
623+ priv.progress = MathUtils.clampAndProject(sensingPoints.top.y, bounds.top + priv.triggerArea, 0, 0, 1);
624 priv.resetEdges();
625 priv.nearTopEdge = true;
626 root.fakeMaximizeAnimationRequested(priv.progress);
627
628=== modified file 'qml/Stage/Stage.qml'
629--- qml/Stage/Stage.qml 2017-01-03 12:04:08 +0000
630+++ qml/Stage/Stage.qml 2017-01-26 11:10:45 +0000
631@@ -100,7 +100,7 @@
632 } else {
633 // No we didn't, do a quick alt-tab
634 if (appRepeater.count > 1) {
635- appRepeater.itemAt(1).claimFocus();
636+ appRepeater.itemAt(1).activate();
637 }
638 }
639 }
640@@ -665,6 +665,13 @@
641 }
642 }
643
644+ Item {
645+ id: boundariesForWindowPlacement
646+ anchors.fill: parent
647+ anchors.topMargin: PanelState.panelHeight
648+ visible: false
649+ }
650+
651 Repeater {
652 id: appRepeater
653 model: topLevelSurfaceList
654@@ -833,7 +840,6 @@
655 readonly property var surface: model.window.surface
656 readonly property var window: model.window
657
658- readonly property alias resizeArea: resizeArea
659 readonly property alias focusedSurface: decoratedWindow.focusedSurface
660 readonly property bool dragging: touchControls.overlayShown ? touchControls.dragging : decoratedWindow.dragging
661
662@@ -890,7 +896,7 @@
663 screenWidth: appContainer.width
664 screenHeight: appContainer.height
665 leftMargin: root.leftMargin
666- minimumY: PanelState.panelHeight
667+ minimumY: boundariesForWindowPlacement.y
668 }
669
670 Connections {
671@@ -1520,7 +1526,7 @@
672 anchors.margins: touchControls.overlayShown ? borderThickness/2 : -borderThickness
673
674 target: appDelegate
675- minimumY: PanelState.panelHeight // disallow resizing up past Panel
676+ boundsItem: boundariesForWindowPlacement
677 minWidth: units.gu(10)
678 minHeight: units.gu(10)
679 borderThickness: units.gu(2)
680@@ -1539,7 +1545,7 @@
681 anchors.top: appDelegate.top
682 application: model.application
683 surface: model.window.surface
684- active: appDelegate.focus
685+ active: model.window.focused
686 focus: true
687 interactive: root.interactive
688 showDecoration: 1
689@@ -1548,8 +1554,7 @@
690 width: implicitWidth
691 height: implicitHeight
692 highlightSize: windowInfoItem.iconMargin / 2
693- stageWidth: appContainer.width
694- stageHeight: appContainer.height
695+ boundsItem: boundariesForWindowPlacement
696
697 requestedWidth: appDelegate.requestedWidth
698 requestedHeight: appDelegate.requestedHeight
699@@ -1604,11 +1609,12 @@
700
701 WindowControlsOverlay {
702 id: touchControls
703+ anchors.fill: appDelegate
704 target: appDelegate
705+ resizeArea: resizeArea
706 enabled: false
707 visible: enabled
708- stageWidth: appContainer.width
709- stageHeight: appContainer.height
710+ boundsItem: boundariesForWindowPlacement
711
712 onFakeMaximizeAnimationRequested: if (!appDelegate.maximized) fakeRectangle.maximize(amount, true)
713 onFakeMaximizeLeftAnimationRequested: if (!appDelegate.maximizedLeft) fakeRectangle.maximizeLeft(amount, true)
714@@ -1703,6 +1709,41 @@
715 sourceSize.height: height
716 }
717 }
718+
719+ Item {
720+ // Group all child windows in this item so that we can fade them out together when going to the spread
721+ // (and fade them in back again when returning from it)
722+ readonly property bool stageOnProperState: root.state === "windowed"
723+ || root.state === "staged"
724+ || root.state === "stagedWithSideStage"
725+
726+ // TODO: Is it worth the extra cost of layering to avoid the opacity artifacts of intersecting children?
727+ // Btw, will involve more than uncommenting the line below as children won't necessarily fit this item's
728+ // geometry. This is just a reference.
729+ //layer.enabled: opacity !== 0.0 && opacity !== 1.0
730+
731+ opacity: stageOnProperState ? 1.0 : 0.0
732+ visible: opacity !== 0.0 // make it transparent to input as well
733+ Behavior on opacity { UbuntuNumberAnimation {} }
734+
735+ Repeater {
736+ id: childWindowRepeater
737+ model: appDelegate.surface ? appDelegate.surface.childSurfaceList : null
738+
739+ delegate: ChildWindowTree {
740+ surface: model.surface
741+
742+ // Account for the displacement caused by window decoration in the top-level surface
743+ // Ie, the top-level surface is not positioned at (0,0) of this ChildWindow's parent (appDelegate)
744+ displacementX: appDelegate.clientAreaItem.x
745+ displacementY: appDelegate.clientAreaItem.y
746+
747+ boundsItem: boundariesForWindowPlacement
748+
749+ z: childWindowRepeater.count - model.index
750+ }
751+ }
752+ }
753 }
754 }
755 }
756
757=== modified file 'qml/Stage/WindowControlsOverlay.qml'
758--- qml/Stage/WindowControlsOverlay.qml 2016-12-27 22:09:12 +0000
759+++ qml/Stage/WindowControlsOverlay.qml 2017-01-26 11:10:45 +0000
760@@ -18,17 +18,14 @@
761 import Ubuntu.Components 1.3
762 import Ubuntu.Gestures 0.1
763 import Unity.Application 0.1
764-import "../Components/PanelState"
765
766 Item {
767 id: root
768- enabled: target && !target.fullscreen
769- anchors.fill: target
770
771 // to be set from outside
772 property Item target // appDelegate
773- property alias stageWidth: moveHandler.stageWidth
774- property alias stageHeight: moveHandler.stageHeight
775+ property WindowResizeArea resizeArea
776+ property Item boundsItem
777
778 // to be read from outside
779 readonly property alias overlayShown: overlay.visible
780@@ -90,9 +87,7 @@
781
782 QtObject {
783 id: priv
784- readonly property var resizeArea: root.target && root.target.resizeArea ? root.target.resizeArea : null
785- readonly property bool ensureWindow: root.target.state == "normal" || root.target.state == "restored"
786- readonly property bool dragging: moveHandler.dragging || (resizeArea && resizeArea.dragging)
787+ readonly property bool dragging: moveHandler.dragging || (root.resizeArea && root.resizeArea.dragging)
788
789 function getSensingPoints() {
790 var xPoints = [];
791@@ -162,6 +157,8 @@
792 objectName: "moveHandler"
793 target: root.target
794
795+ boundsItem: root.boundsItem
796+
797 onFakeMaximizeAnimationRequested: root.fakeMaximizeAnimationRequested(amount)
798 onFakeMaximizeLeftAnimationRequested: root.fakeMaximizeLeftAnimationRequested(amount)
799 onFakeMaximizeRightAnimationRequested: root.fakeMaximizeRightAnimationRequested(amount)
800@@ -193,65 +190,65 @@
801 ResizeGrip { // top left
802 anchors.horizontalCenter: parent.left
803 anchors.verticalCenter: parent.top
804- visible: priv.ensureWindow || target.maximizedBottomRight
805- resizeTarget: priv.resizeArea
806+ visible: root.enabled || target.maximizedBottomRight
807+ resizeTarget: root.resizeArea
808 }
809
810 ResizeGrip { // top center
811 anchors.horizontalCenter: parent.horizontalCenter
812 anchors.verticalCenter: parent.top
813 rotation: 45
814- visible: priv.ensureWindow || target.maximizedHorizontally || target.maximizedBottomLeft || target.maximizedBottomRight
815- resizeTarget: priv.resizeArea
816+ visible: root.enabled || target.maximizedHorizontally || target.maximizedBottomLeft || target.maximizedBottomRight
817+ resizeTarget: root.resizeArea
818 }
819
820 ResizeGrip { // top right
821 anchors.horizontalCenter: parent.right
822 anchors.verticalCenter: parent.top
823 rotation: 90
824- visible: priv.ensureWindow || target.maximizedBottomLeft
825- resizeTarget: priv.resizeArea
826+ visible: root.enabled || target.maximizedBottomLeft
827+ resizeTarget: root.resizeArea
828 }
829
830 ResizeGrip { // right
831 anchors.horizontalCenter: parent.right
832 anchors.verticalCenter: parent.verticalCenter
833 rotation: 135
834- visible: priv.ensureWindow || target.maximizedVertically || target.maximizedLeft ||
835+ visible: root.enabled || target.maximizedVertically || target.maximizedLeft ||
836 target.maximizedTopLeft || target.maximizedBottomLeft
837- resizeTarget: priv.resizeArea
838+ resizeTarget: root.resizeArea
839 }
840
841 ResizeGrip { // bottom right
842 anchors.horizontalCenter: parent.right
843 anchors.verticalCenter: parent.bottom
844- visible: priv.ensureWindow || target.maximizedTopLeft
845- resizeTarget: priv.resizeArea
846+ visible: root.enabled || target.maximizedTopLeft
847+ resizeTarget: root.resizeArea
848 }
849
850 ResizeGrip { // bottom center
851 anchors.horizontalCenter: parent.horizontalCenter
852 anchors.verticalCenter: parent.bottom
853 rotation: 45
854- visible: priv.ensureWindow || target.maximizedHorizontally || target.maximizedTopLeft || target.maximizedTopRight
855- resizeTarget: priv.resizeArea
856+ visible: root.enabled || target.maximizedHorizontally || target.maximizedTopLeft || target.maximizedTopRight
857+ resizeTarget: root.resizeArea
858 }
859
860 ResizeGrip { // bottom left
861 anchors.horizontalCenter: parent.left
862 anchors.verticalCenter: parent.bottom
863 rotation: 90
864- visible: priv.ensureWindow || target.maximizedTopRight
865- resizeTarget: priv.resizeArea
866+ visible: root.enabled || target.maximizedTopRight
867+ resizeTarget: root.resizeArea
868 }
869
870 ResizeGrip { // left
871 anchors.horizontalCenter: parent.left
872 anchors.verticalCenter: parent.verticalCenter
873 rotation: 135
874- visible: priv.ensureWindow || target.maximizedVertically || target.maximizedRight ||
875+ visible: root.enabled || target.maximizedVertically || target.maximizedRight ||
876 target.maximizedTopRight || target.maximizedBottomRight
877- resizeTarget: priv.resizeArea
878+ resizeTarget: root.resizeArea
879 }
880 }
881 }
882
883=== modified file 'qml/Stage/WindowDecoration.qml'
884--- qml/Stage/WindowDecoration.qml 2017-01-18 17:34:57 +0000
885+++ qml/Stage/WindowDecoration.qml 2017-01-26 11:10:45 +0000
886@@ -28,6 +28,7 @@
887 property alias closeButtonVisible: buttons.closeButtonShown
888 property alias title: titleLabel.text
889 property alias maximizeButtonShown: buttons.maximizeButtonShown
890+ property alias minimizeButtonVisible: buttons.minimizeButtonVisible
891 property bool active: false
892 property alias overlayShown: buttons.overlayShown
893 property var menu: undefined
894
895=== modified file 'qml/Stage/WindowResizeArea.qml'
896--- qml/Stage/WindowResizeArea.qml 2016-12-12 16:45:09 +0000
897+++ qml/Stage/WindowResizeArea.qml 2017-01-26 11:10:45 +0000
898@@ -32,7 +32,7 @@
899 // The area will anchor to it and manage resize events
900 property Item target: null
901 property int borderThickness: 0
902- property real minimumY: -100000000 // By default, impose no limit
903+ property Item boundsItem
904 property int minWidth: 0
905 property int minHeight: 0
906
907@@ -243,7 +243,8 @@
908 }
909
910 if (d.topBorder) {
911- var newTargetY = Math.max(d.startY + deltaY, root.minimumY);
912+ var bounds = boundsItem.mapToItem(target.parent, 0, 0, boundsItem.width, boundsItem.height);
913+ var newTargetY = Math.max(d.startY + deltaY, bounds.y);
914 var bottomBorderY = target.windowedY + target.height;
915 if (bottomBorderY > newTargetY + d.minimumHeight) {
916 if (bottomBorderY < newTargetY + d.maximumHeight) {
917
918=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp'
919--- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-12-20 15:50:41 +0000
920+++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2017-01-26 11:10:45 +0000
921@@ -94,6 +94,7 @@
922 auto surface = surfaceManager->createSurface(QString("prompt foo"),
923 Mir::NormalType,
924 Mir::RestoredState,
925+ nullptr, /* parentSurface */
926 screenshotUrl);
927 surfaceManager->notifySurfaceCreated(surface);
928
929@@ -122,7 +123,9 @@
930 auto surface = surfaceManager->createSurface(surfaceName,
931 Mir::NormalType,
932 fullscreen() ? Mir::FullscreenState : Mir::RestoredState,
933- m_screenshotFileName);
934+ nullptr, /* parentSurface */
935+ m_screenshotFileName,
936+ m_qmlFilePath);
937
938 surface->setShellChrome(m_shellChrome);
939
940@@ -201,6 +204,11 @@
941 }
942 }
943
944+void ApplicationInfo::setQmlFilename(const QString &qmlFilename)
945+{
946+ m_qmlFilePath = QString("qrc:///Unity/Application/%1").arg(qmlFilename);
947+}
948+
949 void ApplicationInfo::setName(const QString &value)
950 {
951 if (value != m_name) {
952
953=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.h'
954--- tests/mocks/Unity/Application/ApplicationInfo.h 2016-12-23 11:05:09 +0000
955+++ tests/mocks/Unity/Application/ApplicationInfo.h 2017-01-26 11:10:45 +0000
956@@ -29,6 +29,7 @@
957
958 #include <QList>
959 #include <QTimer>
960+#include <QUrl>
961
962 using namespace unity::shell::application;
963
964@@ -58,6 +59,7 @@
965
966 void setIconId(const QString &iconId);
967 void setScreenshotId(const QString &screenshotId);
968+ void setQmlFilename(const QString &);
969
970 void setAppId(const QString &value) { m_appId = value; }
971 QString appId() const override { return m_appId; }
972@@ -152,6 +154,7 @@
973 QList<MirSurface*> m_closingSurfaces;
974 bool m_manualSurfaceCreation{false};
975 Mir::ShellChrome m_shellChrome{Mir::NormalChrome};
976+ QUrl m_qmlFilePath;
977 };
978
979 Q_DECLARE_METATYPE(ApplicationInfo*)
980
981=== modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp'
982--- tests/mocks/Unity/Application/ApplicationManager.cpp 2016-12-07 11:19:17 +0000
983+++ tests/mocks/Unity/Application/ApplicationManager.cpp 2017-01-26 11:10:45 +0000
984@@ -480,6 +480,15 @@
985 application->setName("Primary Oriented");
986 application->setSupportedOrientations(Qt::PrimaryOrientation);
987 m_availableApplications.append(application);
988+
989+ application = new ApplicationInfo(this);
990+ application->setAppId("kate");
991+ application->setName("Kate");
992+ application->setIconId("libreoffice");
993+ application->setScreenshotId("libreoffice");
994+ application->setQmlFilename("Kate.qml");
995+ application->setIsTouchApp(false);
996+ m_availableApplications.append(application);
997 }
998
999
1000
1001=== modified file 'tests/mocks/Unity/Application/MirSurface.cpp'
1002--- tests/mocks/Unity/Application/MirSurface.cpp 2016-12-02 18:15:36 +0000
1003+++ tests/mocks/Unity/Application/MirSurface.cpp 2017-01-26 11:10:45 +0000
1004@@ -74,6 +74,7 @@
1005 MirSurface::MirSurface(const QString& name,
1006 Mir::Type type,
1007 Mir::State state,
1008+ MirSurface *parentSurface,
1009 const QUrl& screenshot,
1010 const QUrl &qmlFilePath)
1011 : unity::shell::application::MirSurfaceInterface(nullptr)
1012@@ -90,6 +91,8 @@
1013 , m_height(-1)
1014 , m_slowToResize(false)
1015 , m_shellChrome(Mir::NormalChrome)
1016+ , m_parentSurface(parentSurface)
1017+ , m_childSurfaceList(new MirSurfaceListModel(this))
1018 {
1019 DEBUG_MSG("state=" << stateToStr(state));
1020
1021@@ -493,6 +496,36 @@
1022 }
1023 }
1024
1025+void MirSurface::openMenu(qreal x, qreal y, qreal width, qreal height)
1026+{
1027+ auto *menu = SurfaceManager::instance()->createSurface("menu", Mir::MenuType, Mir::HiddenState,
1028+ this /* parentSurface */,
1029+ QUrl() /* screenshot */,
1030+ QUrl("qrc:///Unity/Application/KateMenu.qml"));
1031+
1032+ menu->setRequestedPosition(QPoint(x,y));
1033+ menu->resize(width, height);
1034+ menu->requestState(Mir::RestoredState);
1035+
1036+ SurfaceManager::instance()->notifySurfaceCreated(menu);
1037+}
1038+
1039+void MirSurface::openDialog(qreal x, qreal y, qreal width, qreal height)
1040+{
1041+ auto *dialog = SurfaceManager::instance()->createSurface("dialog", Mir::DialogType, Mir::HiddenState,
1042+ this /* parentSurface */,
1043+ QUrl() /* screenshot */,
1044+ QUrl("qrc:///Unity/Application/KateDialog.qml"));
1045+
1046+ dialog->setRequestedPosition(QPoint(x,y));
1047+ dialog->resize(width, height);
1048+ dialog->requestState(Mir::RestoredState);
1049+
1050+ SurfaceManager::instance()->notifySurfaceCreated(dialog);
1051+
1052+ dialog->requestFocus();
1053+}
1054+
1055 void MirSurface::setRequestedPosition(const QPoint &value)
1056 {
1057 if (value != m_requestedPosition) {
1058@@ -505,3 +538,13 @@
1059 Q_EMIT positionChanged(m_position);
1060 }
1061 }
1062+
1063+MirSurfaceInterface* MirSurface::parentSurface() const
1064+{
1065+ return m_parentSurface;
1066+}
1067+
1068+MirSurfaceListInterface* MirSurface::childSurfaceList() const
1069+{
1070+ return m_childSurfaceList;
1071+}
1072
1073=== modified file 'tests/mocks/Unity/Application/MirSurface.h'
1074--- tests/mocks/Unity/Application/MirSurface.h 2016-12-03 18:41:45 +0000
1075+++ tests/mocks/Unity/Application/MirSurface.h 2017-01-26 11:10:45 +0000
1076@@ -45,6 +45,7 @@
1077 MirSurface(const QString& name,
1078 Mir::Type type,
1079 Mir::State state,
1080+ MirSurface *parentSurface,
1081 const QUrl& screenshot,
1082 const QUrl &qmlFilePath = QUrl());
1083 virtual ~MirSurface();
1084@@ -94,6 +95,9 @@
1085 QPoint requestedPosition() const override { return m_requestedPosition; }
1086 void setRequestedPosition(const QPoint &) override;
1087
1088+ unity::shell::application::MirSurfaceInterface* parentSurface() const override;
1089+ unity::shell::application::MirSurfaceListInterface* childSurfaceList() const override;
1090+
1091 Q_INVOKABLE void close() override;
1092 Q_INVOKABLE void activate() override;
1093
1094@@ -121,6 +125,9 @@
1095
1096 Q_INVOKABLE virtual void setInputBounds(const QRect &boundsRect);
1097
1098+ Q_INVOKABLE void openMenu(qreal x, qreal y, qreal width, qreal height);
1099+ Q_INVOKABLE void openDialog(qreal x, qreal y, qreal width, qreal height);
1100+
1101 /////
1102 // internal mock stuff
1103
1104@@ -216,6 +223,10 @@
1105
1106 QPoint m_position;
1107 QPoint m_requestedPosition;
1108+
1109+ unity::shell::application::MirSurfaceInterface* m_parentSurface;
1110+
1111+ MirSurfaceListModel *m_childSurfaceList;
1112 };
1113
1114 #endif // MOCK_MIR_SURFACE_H
1115
1116=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.cpp'
1117--- tests/mocks/Unity/Application/MirSurfaceItem.cpp 2016-12-23 11:05:09 +0000
1118+++ tests/mocks/Unity/Application/MirSurfaceItem.cpp 2017-01-26 11:10:45 +0000
1119@@ -159,7 +159,9 @@
1120
1121 if (m_qmlItem) {
1122 QQmlProperty orientationProp(m_qmlItem, "orientationAngle");
1123- orientationProp.write(QVariant::fromValue(orientationAngle()));
1124+ if (orientationProp.isValid()) {
1125+ orientationProp.write(QVariant::fromValue(orientationAngle()));
1126+ }
1127 }
1128 }
1129
1130@@ -167,7 +169,9 @@
1131 {
1132 if (m_qmlItem) {
1133 QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
1134- screenshotSource.write(QVariant::fromValue(screenshotUrl));
1135+ if (screenshotSource.isValid()) {
1136+ screenshotSource.write(QVariant::fromValue(screenshotUrl));
1137+ }
1138 }
1139 }
1140
1141@@ -193,12 +197,23 @@
1142
1143 {
1144 QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
1145- screenshotSource.write(QVariant::fromValue(m_qmlSurface->screenshotUrl()));
1146+ if (screenshotSource.isValid()) {
1147+ screenshotSource.write(QVariant::fromValue(m_qmlSurface->screenshotUrl()));
1148+ }
1149 }
1150
1151 {
1152 QQmlProperty orientationProp(m_qmlItem, "orientationAngle");
1153- orientationProp.write(QVariant::fromValue(orientationAngle()));
1154+ if (orientationProp.isValid()) {
1155+ orientationProp.write(QVariant::fromValue(orientationAngle()));
1156+ }
1157+ }
1158+
1159+ {
1160+ QQmlProperty surfaceProperty(m_qmlItem, "surface");
1161+ if (surfaceProperty.isValid()) {
1162+ surfaceProperty.write(QVariant::fromValue(m_qmlSurface));
1163+ }
1164 }
1165 }
1166
1167
1168=== modified file 'tests/mocks/Unity/Application/MirSurfaceListModel.h'
1169--- tests/mocks/Unity/Application/MirSurfaceListModel.h 2016-11-30 19:24:02 +0000
1170+++ tests/mocks/Unity/Application/MirSurfaceListModel.h 2017-01-26 11:10:45 +0000
1171@@ -44,7 +44,6 @@
1172 bool contains(MirSurface *surface) const { return m_surfaceList.contains(surface); }
1173
1174 private:
1175- void appendSurface(MirSurface *surface);
1176 void raise(MirSurface *surface);
1177 void moveSurface(int from, int to);
1178 void connectSurface(MirSurface *surface);
1179
1180=== modified file 'tests/mocks/Unity/Application/SurfaceManager.cpp'
1181--- tests/mocks/Unity/Application/SurfaceManager.cpp 2017-01-03 12:45:42 +0000
1182+++ tests/mocks/Unity/Application/SurfaceManager.cpp 2017-01-26 11:10:45 +0000
1183@@ -61,10 +61,15 @@
1184 MirSurface *SurfaceManager::createSurface(const QString& name,
1185 Mir::Type type,
1186 Mir::State state,
1187- const QUrl& screenshot)
1188+ MirSurface *parentSurface,
1189+ const QUrl &screenshot,
1190+ const QUrl &qmlFilePath)
1191 {
1192- MirSurface* surface = new MirSurface(name, type, state, screenshot);
1193+ MirSurface* surface = new MirSurface(name, type, state, parentSurface, screenshot, qmlFilePath);
1194 registerSurface(surface);
1195+ if (parentSurface) {
1196+ static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->addSurface(surface);
1197+ }
1198 return surface;
1199 }
1200
1201@@ -72,12 +77,14 @@
1202 {
1203 m_surfaces.prepend(surface);
1204
1205- surface->setMinimumWidth(m_newSurfaceMinimumWidth);
1206- surface->setMaximumWidth(m_newSurfaceMaximumWidth);
1207- surface->setMinimumHeight(m_newSurfaceMinimumHeight);
1208- surface->setMaximumHeight(m_newSurfaceMaximumHeight);
1209- surface->setWidthIncrement(m_newSurfaceWidthIncrement);
1210- surface->setHeightIncrement(m_newSurfaceHeightIncrement);
1211+ if (!surface->parentSurface()) {
1212+ surface->setMinimumWidth(m_newSurfaceMinimumWidth);
1213+ surface->setMaximumWidth(m_newSurfaceMaximumWidth);
1214+ surface->setMinimumHeight(m_newSurfaceMinimumHeight);
1215+ surface->setMaximumHeight(m_newSurfaceMaximumHeight);
1216+ surface->setWidthIncrement(m_newSurfaceWidthIncrement);
1217+ surface->setHeightIncrement(m_newSurfaceHeightIncrement);
1218+ }
1219
1220 connect(surface, &MirSurface::stateRequested, this, [=](Mir::State state) {
1221 this->onStateRequested(surface, state);
1222
1223=== modified file 'tests/mocks/Unity/Application/SurfaceManager.h'
1224--- tests/mocks/Unity/Application/SurfaceManager.h 2017-01-03 12:45:42 +0000
1225+++ tests/mocks/Unity/Application/SurfaceManager.h 2017-01-26 11:10:45 +0000
1226@@ -49,7 +49,9 @@
1227 Q_INVOKABLE MirSurface* createSurface(const QString& name,
1228 Mir::Type type,
1229 Mir::State state,
1230- const QUrl& screenshot);
1231+ MirSurface *parentSurface,
1232+ const QUrl &screenshot,
1233+ const QUrl &qmlFilePath = QUrl());
1234
1235
1236 void notifySurfaceCreated(unity::shell::application::MirSurfaceInterface *);
1237
1238=== modified file 'tests/mocks/Unity/Application/VirtualKeyboard.cpp'
1239--- tests/mocks/Unity/Application/VirtualKeyboard.cpp 2016-09-26 12:25:19 +0000
1240+++ tests/mocks/Unity/Application/VirtualKeyboard.cpp 2017-01-26 11:10:45 +0000
1241@@ -24,10 +24,11 @@
1242
1243 VirtualKeyboard::VirtualKeyboard()
1244 : MirSurface("input-method",
1245- Mir::InputMethodType,
1246- Mir::MinimizedState,
1247- QUrl("qrc:///Unity/Application/vkb_portrait.png"),
1248- QUrl("qrc:///Unity/Application/VirtualKeyboard.qml"))
1249+ Mir::InputMethodType,
1250+ Mir::MinimizedState,
1251+ nullptr, /* parentSurface */
1252+ QUrl("qrc:///Unity/Application/vkb_portrait.png"),
1253+ QUrl("qrc:///Unity/Application/VirtualKeyboard.qml"))
1254 {
1255 }
1256
1257
1258=== added file 'tests/mocks/Unity/Application/resources/Kate.qml'
1259--- tests/mocks/Unity/Application/resources/Kate.qml 1970-01-01 00:00:00 +0000
1260+++ tests/mocks/Unity/Application/resources/Kate.qml 2017-01-26 11:10:45 +0000
1261@@ -0,0 +1,49 @@
1262+/*
1263+ * Copyright (C) 2016 Canonical, Ltd.
1264+ *
1265+ * This program is free software; you can redistribute it and/or modify
1266+ * it under the terms of the GNU General Public License as published by
1267+ * the Free Software Foundation; version 3.
1268+ *
1269+ * This program is distributed in the hope that it will be useful,
1270+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1271+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1272+ * GNU General Public License for more details.
1273+ *
1274+ * You should have received a copy of the GNU General Public License
1275+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1276+ */
1277+
1278+import QtQuick 2.4
1279+import Ubuntu.Components 1.3
1280+
1281+Rectangle {
1282+ id: root
1283+ color: "white"
1284+ implicitWidth: width
1285+ implicitHeight: height
1286+
1287+ property var surface
1288+
1289+ Column {
1290+ Button {
1291+ text: "Open Menu"
1292+ property real nextY: y
1293+ property real menuHeight: units.gu(5)
1294+ onClicked: {
1295+ surface.openMenu(x+width, nextY, units.gu(10), menuHeight);
1296+ nextY += menuHeight + units.gu(.5)
1297+ }
1298+ }
1299+
1300+ Button {
1301+ text: "Open Dialog"
1302+ property real dialogWidth: units.gu(30)
1303+ property real dialogHeight: units.gu(20)
1304+ onClicked: {
1305+ surface.openDialog(root.x+(root.width/2)-(dialogWidth/2), root.y+(root.height/2)-(dialogHeight/2),
1306+ dialogWidth, dialogHeight);
1307+ }
1308+ }
1309+ }
1310+}
1311
1312=== added file 'tests/mocks/Unity/Application/resources/KateDialog.qml'
1313--- tests/mocks/Unity/Application/resources/KateDialog.qml 1970-01-01 00:00:00 +0000
1314+++ tests/mocks/Unity/Application/resources/KateDialog.qml 2017-01-26 11:10:45 +0000
1315@@ -0,0 +1,48 @@
1316+/*
1317+ * Copyright (C) 2016 Canonical, Ltd.
1318+ *
1319+ * This program is free software; you can redistribute it and/or modify
1320+ * it under the terms of the GNU General Public License as published by
1321+ * the Free Software Foundation; version 3.
1322+ *
1323+ * This program is distributed in the hope that it will be useful,
1324+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1325+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1326+ * GNU General Public License for more details.
1327+ *
1328+ * You should have received a copy of the GNU General Public License
1329+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1330+ */
1331+
1332+import QtQuick 2.4
1333+import Ubuntu.Components 1.3
1334+
1335+Rectangle {
1336+ id: root
1337+ color: "grey"
1338+ implicitWidth: width
1339+ implicitHeight: height
1340+
1341+ property var surface
1342+
1343+ Text {
1344+ anchors.left: parent.left
1345+ anchors.right: parent.right
1346+ horizontalAlignment: Text.AlignHCenter
1347+ verticalAlignment: Text.AlignVCenter
1348+ text: "This is a child dialog."
1349+ }
1350+
1351+ Row {
1352+ anchors.bottom: parent.bottom
1353+ anchors.right: parent.right
1354+ Button {
1355+ text: "OK"
1356+ onClicked: root.surface.close()
1357+ }
1358+ Button {
1359+ text: "Cancel"
1360+ onClicked: root.surface.close()
1361+ }
1362+ }
1363+}
1364
1365=== added file 'tests/mocks/Unity/Application/resources/KateMenu.qml'
1366--- tests/mocks/Unity/Application/resources/KateMenu.qml 1970-01-01 00:00:00 +0000
1367+++ tests/mocks/Unity/Application/resources/KateMenu.qml 2017-01-26 11:10:45 +0000
1368@@ -0,0 +1,41 @@
1369+/*
1370+ * Copyright (C) 2016 Canonical, Ltd.
1371+ *
1372+ * This program is free software; you can redistribute it and/or modify
1373+ * it under the terms of the GNU General Public License as published by
1374+ * the Free Software Foundation; version 3.
1375+ *
1376+ * This program is distributed in the hope that it will be useful,
1377+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1378+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1379+ * GNU General Public License for more details.
1380+ *
1381+ * You should have received a copy of the GNU General Public License
1382+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1383+ */
1384+
1385+import QtQuick 2.4
1386+import Ubuntu.Components 1.3
1387+
1388+Rectangle {
1389+ id: root
1390+ color: "grey"
1391+ implicitWidth: width
1392+ implicitHeight: height
1393+
1394+ property var surface
1395+
1396+ Text {
1397+ anchors.centerIn: parent
1398+ text: "menu"
1399+ }
1400+ MouseArea {
1401+ anchors.fill: parent
1402+ property real nextY: 0
1403+ onClicked: {
1404+ // ensure some overlap with is parent in order to visually check for nested opacity artifacts
1405+ root.surface.openMenu(x+(width*0.6), nextY, units.gu(10), root.height);
1406+ nextY += root.height
1407+ }
1408+ }
1409+}
1410
1411=== modified file 'tests/mocks/Unity/Application/resources/surfaces.qrc'
1412--- tests/mocks/Unity/Application/resources/surfaces.qrc 2015-11-05 17:59:16 +0000
1413+++ tests/mocks/Unity/Application/resources/surfaces.qrc 2017-01-26 11:10:45 +0000
1414@@ -1,5 +1,8 @@
1415 <RCC>
1416 <qresource prefix="/Unity/Application">
1417+ <file>Kate.qml</file>
1418+ <file>KateDialog.qml</file>
1419+ <file>KateMenu.qml</file>
1420 <file>VirtualKeyboard.qml</file>
1421 <file>MirSurfaceItem.qml</file>
1422 <file>vkb_portrait.png</file>
1423
1424=== modified file 'tests/qmltests/Stage/ApplicationCheckBox.qml'
1425--- tests/qmltests/Stage/ApplicationCheckBox.qml 2016-11-30 19:24:02 +0000
1426+++ tests/qmltests/Stage/ApplicationCheckBox.qml 2017-01-26 11:10:45 +0000
1427@@ -162,7 +162,7 @@
1428 }
1429 }
1430
1431- // Rows of application surfaces
1432+ // Rows of top-level application surfaces
1433 Repeater {
1434 model: d.application ? d.application.surfaceList : null
1435 RowLayout {
1436
1437=== modified file 'tests/qmltests/Stage/tst_WindowResizeArea.qml'
1438--- tests/qmltests/Stage/tst_WindowResizeArea.qml 2016-12-21 16:20:58 +0000
1439+++ tests/qmltests/Stage/tst_WindowResizeArea.qml 2017-01-26 11:10:45 +0000
1440@@ -90,6 +90,7 @@
1441 id: windowResizeArea
1442 anchors.fill: parent
1443 target: fakeWindow
1444+ boundsItem: bounds
1445 borderThickness: units.gu(2)
1446 minWidth: units.gu(15)
1447 minHeight: units.gu(10)
1448@@ -121,7 +122,16 @@
1449 active: windowLoaderCheckbox.checked
1450 }
1451
1452+ Item {
1453+ id: bounds
1454+ anchors.left: parent.left
1455+ anchors.top: parent.top
1456+ anchors.right: controls.left
1457+ anchors.bottom: parent.bottom
1458+ }
1459+
1460 Rectangle {
1461+ id: controls
1462 anchors.right: parent.right
1463 anchors.top: parent.top
1464 anchors.bottom: parent.bottom

Subscribers

People subscribed via source and target branches