Merge lp:~dandrader/unity8/childWindows into lp:unity8
- childWindows
- Merge into trunk
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 |
Related bugs: |
|
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:
|
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-
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:/
https:/
Make sure you have miral 1.0.2, which has been released on 20/Jan/2017.
Tooltips work better with this:
https:/
* 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

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2709
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

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/
Text conflict in tests/qmltests/
Text conflict in tests/qmltests/
6 conflicts encountered.

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2729
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

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:/
ubuntu 17.04 / nouveau

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:/
>
> 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.

dinamic (dinamic6661) wrote : Posted in a previous version of this proposal | # |
i have qtubuntu-

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2729
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2729
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

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/
Text conflict in qml/Stage/

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/
> Text conflict in qml/Stage/
Fixed. Rebased on top of latest unity8/miral.

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2744
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

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 *TopLevelWindow
-> const qualifier, it's a getter
+ readonly property bool decorated
-> this could be rewritten to be a direct binding, instead of a function

Lukáš Tinkl (lukas-kde) wrote : Posted in a previous version of this proposal | # |
Console is spammed with this warning:
TypeError: Property 'updateSurfaceR

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 *TopLevelWindow
>
> -> 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.

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 'updateSurfaceR
Fixed.

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2745
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2746
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

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.

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.

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

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.

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

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.

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2748
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2749
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2750
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2751
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2752
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2753
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2754
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2755
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:2756
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

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::

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::
> 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?

Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
laptop touchpad

Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
The problem of tooltips not redrawing is bug 1652109

Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
Another issue fixed elsewhere: https:/

Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal | # |
Text conflict in tests/qmltests/
1 conflicts encountered.

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/
> 1 conflicts encountered.
Fixed

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2769
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2769
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

Nick Dedekind (nick-dedekind) : Posted in a previous version of this proposal | # |

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2770
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2770
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

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)

Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal | # |
+++ qml/Stage/
Just a thought:
+ readonly property bool maximized: false
+ readonly property bool maximizedLeft: false
+ readonly property bool maximizedRight: false
+ readonly property bool maximizedHorizo
+ readonly property bool maximizedVertic
+ readonly property bool maximizedTopLeft: false
+ readonly property bool maximizedTopRight: false
+ readonly property bool maximizedBottom
+ readonly property bool maximizedBottom
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.

Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
On 19/01/2017 11:44, Gerry Boland wrote:
> +++ qml/Stage/
>
> Just a thought:
>
> + readonly property bool maximized: false
> + readonly property bool maximizedLeft: false
> + readonly property bool maximizedRight: false
> + readonly property bool maximizedHorizo
> + readonly property bool maximizedVertic
> + readonly property bool maximizedTopLeft: false
> + readonly property bool maximizedTopRight: false
> + readonly property bool maximizedBottom
> + readonly property bool maximizedBottom
>
> 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.

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/
Wanted to double-check this with you:
+ WindowDecoration {
+ onPressed: root.surface.
+ onPressedChanged: if (d.moveHandler) { d.moveHandler.
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..

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.

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/
> Wanted to double-check this with you:
>
> + WindowDecoration {
> + onPressed: root.surface.
> + onPressedChanged: if (d.moveHandler) { d.moveHandler.
>
> 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 (DecoratedWindo
case). I think those two are rather independent (order not particularly
important).

Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal | # |
+++ qml/Stage/
+ function restore(someBool, someEnum) {}
cruft?
+ var pos = mapToItem(
very good question. It is working yeah?

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.

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/
========
some inline comments

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2770
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

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

Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
On 19/01/2017 12:08, Gerry Boland wrote:
> +++ qml/Stage/
> + function restore(someBool, someEnum) {}
> cruft?
Removed
>
> + var pos = mapToItem(
> 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.

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.

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:/
https:/
updated it, btw)

Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2773
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2773
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

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/
Yes. Done.
> Diff comments:
>
>> === added file 'qml/Stage/
>> --- qml/Stage/
>> +++ qml/Stage/
>> @@ -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 { UbuntuNumberAni
> 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/
>> --- qml/Stage/
>> +++ qml/Stage/
>> @@ -0,0 +1,129 @@
>> +/*
>> [...]
>> + }
>> +
>> + readonly property bool windowedTransit
> 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/
>> --- qml/Stage/
>> +++ qml/Stage/
>> @@ -117,35 +119,38 @@
>> target.
>> }
>>
>> - var pos = mapToItem(
>> + var pos = mapToItem(
> 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/
>> --- tests/mocks/
>> +++ tests/mocks/
>> @@ -122,7 +123,9 @@
>> auto surface = surfaceManager-
>> Mir::NormalType,
>> fullscreen() ? Mir::Fullscreen
>> - m_screenshotFil
>> + nullptr, /* parentSurface */
> is there a space too much?
Yes. Fixed.

Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2774
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/

Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2775
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 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 nextApproved 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 indicatorApproved 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.

Albert Astals Cid (aacid) wrote : | # |
Text conflict in CMakeLists.txt
1 conflicts encountered.

Daniel d'Andrada (dandrader) wrote : | # |
On 26/01/2017 06:29, Albert Astals Cid wrote:
> Text conflict in CMakeLists.txt
> 1 conflicts encountered.
Fixed.
- 2799. By Daniel d'Andrada
-
Initial support for child windows (menus, dialogs, tooltips)

Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2799
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/

dinamic (dinamic6661) wrote : | # |
the shadows are a bit big http://

Gerry Boland (gerboland) wrote : | # |
Did another pass through the code, looks ok
Preview Diff
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 |
FAILED: Continuous integration, rev:2707 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2587/ /unity8- jenkins. ubuntu. com/job/ build/3402/ console /unity8- jenkins. ubuntu. com/job/ build-0- fetch/3430 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 3281/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 3281/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= zesty/3281/ console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 3281/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 3281/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= zesty/3281/ console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 3281/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 3281/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= zesty/3281/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2587/ rebuild
https:/