Merge lp:~lukas-kde/unity8/newWindowDecosAndPanel into lp:unity8
- newWindowDecosAndPanel
- Merge into trunk
Status: | Superseded | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~lukas-kde/unity8/newWindowDecosAndPanel | ||||||||||||
Merge into: | lp:unity8 | ||||||||||||
Prerequisite: | lp:~lukas-kde/unity8/activateWindows | ||||||||||||
Diff against target: |
1983 lines (+723/-313) 24 files modified
qml/Components/PanelState/PanelState.qml (+3/-2) qml/Components/WindowControlButtons.qml (+76/-31) qml/Components/graphics/window-close.svg (+14/-0) qml/Components/graphics/window-maximize.svg (+12/-0) qml/Components/graphics/window-minimize.svg (+13/-0) qml/Panel/Handle.qml (+2/-2) qml/Panel/Indicators/client/IndicatorsClient.qml (+1/-1) qml/Panel/IndicatorsMenu.qml (+11/-2) qml/Panel/MenuContent.qml (+1/-1) qml/Panel/Panel.qml (+68/-80) qml/Panel/PanelBackground.qml (+0/-21) qml/Stages/ApplicationWindow.qml (+29/-3) qml/Stages/DecoratedWindow.qml (+24/-15) qml/Stages/DesktopStage.qml (+79/-55) qml/Stages/SessionContainer.qml (+25/-1) qml/Stages/SurfaceContainer.qml (+56/-4) qml/Stages/WindowDecoration.qml (+15/-10) qml/Stages/WindowResizeArea.qml (+66/-21) tests/mocks/Unity/Application/MirSurface.cpp (+52/-0) tests/mocks/Unity/Application/MirSurface.h (+16/-0) tests/qmltests/Panel/tst_Panel.qml (+45/-11) tests/qmltests/Stages/tst_DesktopStage.qml (+84/-31) tests/qmltests/Stages/tst_WindowResizeArea.qml (+31/-12) tests/qmltests/tst_Shell.qml (+0/-10) |
||||||||||||
To merge this branch: | bzr merge lp:~lukas-kde/unity8/newWindowDecosAndPanel | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Daniel d'Andrada (community) | Approve | ||
Review via email: mp+276810@code.launchpad.net |
This proposal has been superseded by a proposal from 2015-11-23.
Commit message
Implement new visuals for panel and window decorations
Description of the change
Implement new visuals for panel and window decorations
* Are there any related MPs required for this MP to build/function as expected? Please list.
lp:~lukas-kde/unity8/activateWindows
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Yes
* If you changed the UI, has there been a design review?
Yes
Albert Astals Cid (aacid) wrote : | # |
Lukáš Tinkl (lukas-kde) wrote : | # |
Conflicts resolved
Daniel d'Andrada (dandrader) wrote : | # |
I think it's worth considering using pre-rendered images (PNGs) instead of rendering them at runtime from SVGs for performance reasons.
We keep the SVG, but also ship a couple or prerendered versions at common grid unit resolutions (like for 1080p monitors, etc). So if we don't have a PNG for the grid unit at hand, we fallback to rendering one at runtime from the original SVG.
And maybe that scheme could be turned into a component of its own.
Daniel d'Andrada (dandrader) wrote : | # |
> I think it's worth considering using pre-rendered images (PNGs) instead of
> rendering them at runtime from SVGs for performance reasons.
>
> We keep the SVG, but also ship a couple or prerendered versions at common grid
> unit resolutions (like for 1080p monitors, etc). So if we don't have a PNG for
> the grid unit at hand, we fallback to rendering one at runtime from the
> original SVG.
>
> And maybe that scheme could be turned into a component of its own.
I recall this had a significant impact on start up time back in 2010/2011. Not sure how relevant it still is with todays hardware.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2034
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2047. By Lukáš Tinkl
-
restoreFromMini
mized() -> restore()
restore() -> restoreFromMaximized()
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2046
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2048. By Lukáš Tinkl
-
bring back the panel hiding/showing animations
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2047
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Lukáš Tinkl (lukas-kde) wrote : | # |
> > I think it's worth considering using pre-rendered images (PNGs) instead of
> > rendering them at runtime from SVGs for performance reasons.
> >
> > We keep the SVG, but also ship a couple or prerendered versions at common
> grid
> > unit resolutions (like for 1080p monitors, etc). So if we don't have a PNG
> for
> > the grid unit at hand, we fallback to rendering one at runtime from the
> > original SVG.
> >
> > And maybe that scheme could be turned into a component of its own.
>
> I recall this had a significant impact on start up time back in 2010/2011. Not
> sure how relevant it still is with todays hardware.
This doesn't seem to have any impact on performance, design would be fine with giving me whatever format assets we want I guess.
I feel like going with SVGs has the advantage of being able to freely resize the decoration once we allow clients to provide their own in the longterm.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2048
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
Could you please remove all those empty <g></g> from the SVGs?
Daniel d'Andrada (dandrader) wrote : | # |
> This doesn't seem to have any impact on performance
Sure, as it's used only for a couple of small images. But it might if adoption becomes widespread throughout unity8, specially on phones. We can worry about it once we get there.
Daniel d'Andrada (dandrader) wrote : | # |
Don't know how to reset it. "Abstain" will do it for now...
Daniel d'Andrada (dandrader) wrote : | # |
- run "make tryDesktopStage"
- Launch camera-app, gallery-app and webbrowser-app
Why are those apps being launched fullscreen now?
Daniel d'Andrada (dandrader) wrote : | # |
By the way, what about those rounded corner I saw in the design mock up. Should we have a trello card for it or was it dropped?
Daniel d'Andrada (dandrader) wrote : | # |
Is qml/Stages/
Daniel d'Andrada (dandrader) wrote : | # |
There's not a shadow around the indicators panel (that thing that you drag down from the top) anymore. Instead, there's just a black line on its left side. Is it how design intended?
Daniel d'Andrada (dandrader) wrote : | # |
- run "make tryShell
- select desktop size
- select desktop usage scenario
- unlock the shell (dismiss lockscreen)
- Click on the indicators bar grey area between the focused app name and the indicators icons
This is what you get:
qml/Stages/
Daniel d'Andrada (dandrader) wrote : | # |
I don't get why you set "hoverEnabled: true" on that MouseArea where you put WindowControlBu
Daniel d'Andrada (dandrader) wrote : | # |
Still in Panel.qml:
"// TODO here would the LIM come"
What's "LIM"? Also the sentence doesn't look grammatically correct.
Daniel d'Andrada (dandrader) wrote : | # |
Would it be too much to ask for adding a way to show/hide window controls and name in "make tryPanel" so we can see how it interacts with other panel components and states without having to run a fullblown Shell.qml test?
Daniel d'Andrada (dandrader) wrote : | # |
qml/Panel/
If so, could you please nuke it? It's a pretty ridiculous component anyway... (a Rectangle with a pre-defined color)
- 2049. By Lukáš Tinkl
-
sanitize SVGs
Lukáš Tinkl (lukas-kde) wrote : | # |
> Could you please remove all those empty <g></g> from the SVGs?
Done
Lukáš Tinkl (lukas-kde) wrote : | # |
> - run "make tryDesktopStage"
> - Launch camera-app, gallery-app and webbrowser-app
>
> Why are those apps being launched fullscreen now?
Because of the bugfix for https:/
Lukáš Tinkl (lukas-kde) wrote : | # |
> By the way, what about those rounded corner I saw in the design mock up.
> Should we have a trello card for it or was it dropped?
Right, we will need another task in trello for this (qtmir I suppose)
Lukáš Tinkl (lukas-kde) wrote : | # |
> Is qml/Stages/
Yup, for the desktop spread imo
Daniel d'Andrada (dandrader) wrote : | # |
In DesktopStage.qml:
Your updateForegroun
Daniel d'Andrada (dandrader) wrote : | # |
> > - run "make tryDesktopStage"
> > - Launch camera-app, gallery-app and webbrowser-app
> >
> > Why are those apps being launched fullscreen now?
>
> Because of the bugfix for https:/
> /webbrowser-
Can you please stick to the purpose of this branch and just update the visuals?
Please put this bug fix in a separate merge proposal.
Lukáš Tinkl (lukas-kde) wrote : | # |
> Still in Panel.qml:
>
> "// TODO here would the LIM come"
>
> What's "LIM"? Also the sentence doesn't look grammatically correct.
Locally integrated menus
Lukáš Tinkl (lukas-kde) wrote : | # |
> I don't get why you set "hoverEnabled: true" on that MouseArea where you put
> WindowControlBu
Because the whole group is visible only on mouse over _and_ I need the individual mouse over visual effect when hovering over a single button. Any idea how to do that better?
Daniel d'Andrada (dandrader) wrote : | # |
On 12/11/2015 11:04, Lukáš Tinkl wrote:
>> Still in Panel.qml:
>>
>> "// TODO here would the LIM come"
>>
>> What's "LIM"? Also the sentence doesn't look grammatically correct.
> Locally integrated menus
Please write it down in full. Acronyms just hamper communication.
- 2050. By Lukáš Tinkl
-
nuke unused component
Lukáš Tinkl (lukas-kde) wrote : | # |
> qml/Panel/
> and didn't notice any difference. Also grepping for it didn't show anything.
>
> If so, could you please nuke it? It's a pretty ridiculous component anyway...
> (a Rectangle with a pre-defined color)
Yup, it's gone
Lukáš Tinkl (lukas-kde) wrote : | # |
> In DesktopStage.qml:
>
> Your updateForegroun
> model once again unnecessarily. The delegates are already ordered according to
> ApplicationManager model, so their indexes match. No need to look up for it.
Not quite the same, the window might be maximized (its state) but not visually. In other words, the window might be maximized and minimized at the same time.
- 2051. By Lukáš Tinkl
-
remove acronyms
Lukáš Tinkl (lukas-kde) wrote : | # |
> On 12/11/2015 11:04, Lukáš Tinkl wrote:
> >> Still in Panel.qml:
> >>
> >> "// TODO here would the LIM come"
> >>
> >> What's "LIM"? Also the sentence doesn't look grammatically correct.
> > Locally integrated menus
>
> Please write it down in full. Acronyms just hamper communication.
That's what the design docs use but yea, you're right
Daniel d'Andrada (dandrader) wrote : | # |
On 12/11/2015 11:10, Lukáš Tinkl wrote:
>> In DesktopStage.qml:
>>
>> Your updateForegroun
>> model once again unnecessarily. The delegates are already ordered according to
>> ApplicationManager model, so their indexes match. No need to look up for it.
> Not quite the same, the window might be maximized (its state) but not visually. In other words, the window might be maximized and minimized at the same time.
Their state doesn't change their index.
appRepeater already iterates on ApplicationManager. I don't get how is
it possible to have a delegate in that repeater whose index differs from
the model it was created from.
- 2052. By Lukáš Tinkl
-
fix warning when clicking the panel with no maximized window at all
Lukáš Tinkl (lukas-kde) wrote : | # |
> - run "make tryShell
> - select desktop size
> - select desktop usage scenario
> - unlock the shell (dismiss lockscreen)
> - Click on the indicators bar grey area between the focused app name and the
> indicators icons
>
> This is what you get:
> qml/Stages/
> null
Fixed
Lukáš Tinkl (lukas-kde) wrote : | # |
> On 12/11/2015 11:10, Lukáš Tinkl wrote:
> >> In DesktopStage.qml:
> >>
> >> Your updateForegroun
> ApplicationManager
> >> model once again unnecessarily. The delegates are already ordered according
> to
> >> ApplicationManager model, so their indexes match. No need to look up for
> it.
> > Not quite the same, the window might be maximized (its state) but not
> visually. In other words, the window might be maximized and minimized at the
> same time.
>
> Their state doesn't change their index.
And that's problem, I need to know what index is the (visually) maximized window at. To be able to cast the panel drop shadow and focus the correct window when clicking on the panel.
> appRepeater already iterates on ApplicationManager. I don't get how is
> it possible to have a delegate in that repeater whose index differs from
> the model it was created from.
- 2053. By Lukáš Tinkl
-
readd the accidentally dropped indicators shadow
Lukáš Tinkl (lukas-kde) wrote : | # |
> There's not a shadow around the indicators panel (that thing that you drag
> down from the top) anymore. Instead, there's just a black line on its left
> side. Is it how design intended?
Yup, I re-added it now but there's still the thin black line... dunno where it comes from :) Will investigate
- 2054. By Lukáš Tinkl
-
optimize the for loop
- 2055. By Lukáš Tinkl
-
remove the left black divider for now
Lukáš Tinkl (lukas-kde) wrote : | # |
> > There's not a shadow around the indicators panel (that thing that you drag
> > down from the top) anymore. Instead, there's just a black line on its left
> > side. Is it how design intended?
>
> Yup, I re-added it now but there's still the thin black line... dunno where it
> comes from :) Will investigate
Should be fixed now
Lukáš Tinkl (lukas-kde) wrote : | # |
> > On 12/11/2015 11:10, Lukáš Tinkl wrote:
> > >> In DesktopStage.qml:
> > >>
> > >> Your updateForegroun
> > ApplicationManager
> > >> model once again unnecessarily. The delegates are already ordered
> according
> > to
> > >> ApplicationManager model, so their indexes match. No need to look up for
> > it.
> > > Not quite the same, the window might be maximized (its state) but not
> > visually. In other words, the window might be maximized and minimized at the
> > same time.
> >
> > Their state doesn't change their index.
>
> And that's problem, I need to know what index is the (visually) maximized
> window at. To be able to cast the panel drop shadow and focus the correct
> window when clicking on the panel.
>
> > appRepeater already iterates on ApplicationManager. I don't get how is
> > it possible to have a delegate in that repeater whose index differs from
> > the model it was created from.
Optimized the for loop by returning the already available index from appManager
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2049
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2056. By Lukáš Tinkl
-
add a checkbox to see window control buttons
Lukáš Tinkl (lukas-kde) wrote : | # |
> Would it be too much to ask for adding a way to show/hide window controls and
> name in "make tryPanel" so we can see how it interacts with other panel
> components and states without having to run a fullblown Shell.qml test?
Done
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2055
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2056
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2057. By Lukáš Tinkl
-
fix some failing tests
- 2058. By Lukáš Tinkl
-
more shell tests fixing
- 2059. By Lukáš Tinkl
-
wait for the shell rendering
- 2060. By Lukáš Tinkl
-
clear the window controls and title when showing the desktop spread
Daniel d'Andrada (dandrader) wrote : | # |
> > Would it be too much to ask for adding a way to show/hide window controls
> and
> > name in "make tryPanel" so we can see how it interacts with other panel
> > components and states without having to run a fullblown Shell.qml test?
>
> Done
But I don't see the name of the application there when the mouse is not hovering over it.
Daniel d'Andrada (dandrader) wrote : | # |
- make tryShell
- Select desktop size and desktop usage scenario
- Unlock screen
- Select phone size & usage scenario
- Unlock screen again
Expected outcome:
Indicators bar does not display the focused application name
Actual outcome:
Indicators bar displays the focused application name, like in a desktop usage scenario.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2057
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2060
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2057
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2057
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Lukáš Tinkl (lukas-kde) wrote : | # |
> > > Would it be too much to ask for adding a way to show/hide window controls
> > and
> > > name in "make tryPanel" so we can see how it interacts with other panel
> > > components and states without having to run a fullblown Shell.qml test?
> >
> > Done
>
> But I don't see the name of the application there when the mouse is not
> hovering over it.
I don't see any applications in "make tryPanel", what should it show then?
- 2061. By Lukáš Tinkl
-
properly destroy PanelState
in order not to leave artifacts behind (window title, controls, etc)
Lukáš Tinkl (lukas-kde) wrote : | # |
> - make tryShell
> - Select desktop size and desktop usage scenario
> - Unlock screen
> - Select phone size & usage scenario
> - Unlock screen again
>
> Expected outcome:
> Indicators bar does not display the focused application name
>
> Actual outcome:
> Indicators bar displays the focused application name, like in a desktop usage
> scenario.
Thanks for spotting, fixed
- 2062. By Lukáš Tinkl
-
add an option to show a fake window title in panel
Lukáš Tinkl (lukas-kde) wrote : | # |
> > > Would it be too much to ask for adding a way to show/hide window controls
> > and
> > > name in "make tryPanel" so we can see how it interacts with other panel
> > > components and states without having to run a fullblown Shell.qml test?
> >
> > Done
>
> But I don't see the name of the application there when the mouse is not
> hovering over it.
Ok, added an option to show a fake window title
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2061
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2062
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
- Run "make tryShell"
- Select desktop size and usage scenario
- Unlock the screen
- Launch a fullscreen app, like gallery
Expected outcome:
The applications takes the entire area of Shell.qml
Actual outcome:
It doesn't take the space on top that was previously occupied by the indicators bar.
Comments:
I know you said it works when run for real on a laptop/device. But those manual tests should reproduce exactly what happens "for real". Otherwise it undermines the value of qml tests. There's no reason why they should behave differently. This is just high-level QML code afterall.
- 2063. By Lukáš Tinkl
-
merge trunk
- 2064. By Lukáš Tinkl
-
fix for fullscreen apps not taking the panel height into account
Lukáš Tinkl (lukas-kde) wrote : | # |
> - Run "make tryShell"
> - Select desktop size and usage scenario
> - Unlock the screen
> - Launch a fullscreen app, like gallery
>
> Expected outcome:
> The applications takes the entire area of Shell.qml
>
> Actual outcome:
> It doesn't take the space on top that was previously occupied by the
> indicators bar.
>
> Comments:
> I know you said it works when run for real on a laptop/device. But those
> manual tests should reproduce exactly what happens "for real". Otherwise it
> undermines the value of qml tests. There's no reason why they should behave
> differently. This is just high-level QML code afterall.
Fixed
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2063
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2064
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel d'Andrada (dandrader) wrote : | # |
In test_tappingOnD
Please keep launching 3 applications. It's important that neither the "from" nor the "to" applications are focused before the test. That's why a 3rd one is being launched.
I guess the problem is that camera-app is now fullscreen in DesktopStage. So just replace it with another an application that is not fullscreen, like gmail-webapp.
You will have to change its saved mock geometry so that it doesn't overlap unity8-dash or dialer-app.
So just replace camera-app and gallery-app below with other two non-fullscreen apps:
"""
}
"""
I suggest gmail-webapp and twitter-webapp
Daniel d'Andrada (dandrader) wrote : | # |
Likewise in test_tappingOnW
Daniel d'Andrada (dandrader) wrote : | # |
In test_maximisedA
"""
findChild(
"""
You should click on the maximize button instead of directly calling an internal function. We should strive to keep code paths as close to real usage as possible.
"""
var dialerApp = startApplicatio
"""
I guess you're using dialer-app here because it starts in normal state (ie non-maximed and non-fullscreen). If so, please explicitly check for this condition in the test to have it clear.
- 2065. By Lukáš Tinkl
-
merge trunk
- 2066. By Lukáš Tinkl
-
fix bad merge
- 2067. By Lukáš Tinkl
-
amend the test to launch 3 apps and maximize the windows by clicking the button
Lukáš Tinkl (lukas-kde) wrote : | # |
Tests now launch 3 apps and use the maximize button manually
Daniel d'Andrada (dandrader) wrote : | # |
In test_maximizeAp
I think you should s/camera-
Daniel d'Andrada (dandrader) wrote : | # |
Likewise in test_applicatio
s/camera-
s/gallery-
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2065
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2068. By Lukáš Tinkl
-
don't change expectations for maximized apps (that are also fullscreen)
Lukáš Tinkl (lukas-kde) wrote : | # |
> In test_maximizeAp
>
> I think you should s/camera-
> code expectations
Fixed
Lukáš Tinkl (lukas-kde) wrote : | # |
> Likewise in test_applicatio
>
> s/camera-
> s/gallery-
I don't see a problem with this testcase
Daniel d'Andrada (dandrader) wrote : | # |
test_applicatio
In this test you launch gallery-app and click on its maximize button.
But I cannot do it manually because gallery-app starts in fullscreen. No maximize button in sight. That's why I told you to change it into an app that doesn't start in fullscreen.
- 2069. By Lukáš Tinkl
-
s/gallery/gmail
Daniel d'Andrada (dandrader) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2067
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2070. By Lukáš Tinkl
-
merge trunk
- 2071. By Lukáš Tinkl
-
merge prereq and fix conflicts
- 2072. By Lukáš Tinkl
-
don't set width/height directly
- 2073. By Lukáš Tinkl
-
don't hide the decoration when the window is not visible
- 2074. By Lukáš Tinkl
-
get rid of the dp(2) gap for the orange line
- 2075. By Lukáš Tinkl
-
#333333 -> #292929
- 2076. By Lukáš Tinkl
-
get rid of the orange line in the handle
- 2077. By Lukáš Tinkl
-
Light font weight for the root indicator labels
Unmerged revisions
Preview Diff
1 | === modified file 'qml/Components/PanelState/PanelState.qml' |
2 | --- qml/Components/PanelState/PanelState.qml 2015-11-09 10:16:18 +0000 |
3 | +++ qml/Components/PanelState/PanelState.qml 2015-11-23 13:54:01 +0000 |
4 | @@ -22,10 +22,11 @@ |
5 | |
6 | property string title: "" |
7 | property bool buttonsVisible: false |
8 | - |
9 | - property int panelHeight: 0 |
10 | + property bool dropShadow: false |
11 | + property int panelHeight: units.gu(3) |
12 | |
13 | signal close() |
14 | signal minimize() |
15 | signal maximize() |
16 | + signal focusMaximizedApp() |
17 | } |
18 | |
19 | === modified file 'qml/Components/WindowControlButtons.qml' |
20 | --- qml/Components/WindowControlButtons.qml 2015-11-04 14:57:33 +0000 |
21 | +++ qml/Components/WindowControlButtons.qml 2015-11-23 13:54:01 +0000 |
22 | @@ -1,5 +1,5 @@ |
23 | /* |
24 | - * Copyright (C) 2014 Canonical, Ltd. |
25 | + * Copyright (C) 2014-2015 Canonical, Ltd. |
26 | * |
27 | * This program is free software; you can redistribute it and/or modify |
28 | * it under the terms of the GNU General Public License as published by |
29 | @@ -12,8 +12,6 @@ |
30 | * |
31 | * You should have received a copy of the GNU General Public License |
32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
33 | - * |
34 | - * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
35 | */ |
36 | |
37 | import QtQuick 2.4 |
38 | @@ -21,43 +19,90 @@ |
39 | |
40 | Row { |
41 | id: root |
42 | - spacing: units.gu(0.5) |
43 | + spacing: units.gu(1) |
44 | + |
45 | + // to be set from outside |
46 | + property bool active: false |
47 | |
48 | signal close() |
49 | signal minimize() |
50 | signal maximize() |
51 | |
52 | - Rectangle { |
53 | + MouseArea { |
54 | + id: closeWindowButton |
55 | objectName: "closeWindowButton" |
56 | - height: parent.height; width: height; radius: height / 2 |
57 | - gradient: Gradient { |
58 | - GradientStop { color: "#F49073"; position: 0 } |
59 | - GradientStop { color: "#DF4F1C"; position: 1 } |
60 | - } |
61 | - border.width: units.dp(.5) |
62 | - border.color: "black" |
63 | - MouseArea { anchors.fill: parent; onClicked: root.close() } |
64 | + hoverEnabled: true |
65 | + height: parent.height |
66 | + width: height |
67 | + onClicked: root.close() |
68 | + |
69 | + Rectangle { |
70 | + anchors.centerIn: parent |
71 | + width: units.gu(2) |
72 | + height: units.gu(2) |
73 | + radius: height / 2 |
74 | + color: "#ed3146" |
75 | + visible: parent.containsMouse |
76 | + } |
77 | + Icon { |
78 | + width: height |
79 | + height: parent.height *.5 |
80 | + anchors.centerIn: parent |
81 | + source: "graphics/window-close.svg" |
82 | + color: root.active ? "white" : "#5d5d5d" |
83 | + keyColor: "black" |
84 | + } |
85 | } |
86 | - Rectangle { |
87 | + |
88 | + MouseArea { |
89 | + id: minimizeWindowButton |
90 | objectName: "minimizeWindowButton" |
91 | - height: parent.height; width: height; radius: height / 2 |
92 | - gradient: Gradient { |
93 | - GradientStop { color: "#92918C"; position: 0 } |
94 | - GradientStop { color: "#5E5D58"; position: 1 } |
95 | - } |
96 | - border.width: units.dp(.5) |
97 | - border.color: "black" |
98 | - MouseArea { anchors.fill: parent; onClicked: root.minimize() } |
99 | + hoverEnabled: true |
100 | + height: parent.height |
101 | + width: height |
102 | + onClicked: root.minimize() |
103 | + |
104 | + Rectangle { |
105 | + anchors.centerIn: parent |
106 | + width: units.gu(2) |
107 | + height: units.gu(2) |
108 | + radius: height / 2 |
109 | + color: "#888888" |
110 | + visible: parent.containsMouse |
111 | + } |
112 | + Icon { |
113 | + width: height |
114 | + height: parent.height *.5 |
115 | + anchors.centerIn: parent |
116 | + source: "graphics/window-minimize.svg" |
117 | + color: root.active ? "white" : "#5d5d5d" |
118 | + keyColor: "black" |
119 | + } |
120 | } |
121 | - Rectangle { |
122 | + |
123 | + MouseArea { |
124 | + id: maximizeWindowButton |
125 | objectName: "maximizeWindowButton" |
126 | - height: parent.height; width: height; radius: height / 2 |
127 | - gradient: Gradient { |
128 | - GradientStop { color: "#92918C"; position: 0 } |
129 | - GradientStop { color: "#5E5D58"; position: 1 } |
130 | - } |
131 | - border.width: units.dp(.5) |
132 | - border.color: "black" |
133 | - MouseArea { anchors.fill: parent; onClicked: root.maximize() } |
134 | + hoverEnabled: true |
135 | + height: parent.height |
136 | + width: height |
137 | + onClicked: root.maximize() |
138 | + |
139 | + Rectangle { |
140 | + anchors.centerIn: parent |
141 | + width: units.gu(2) |
142 | + height: units.gu(2) |
143 | + radius: height / 2 |
144 | + color: "#888888" |
145 | + visible: parent.containsMouse |
146 | + } |
147 | + Icon { |
148 | + width: height |
149 | + height: parent.height *.5 |
150 | + anchors.centerIn: parent |
151 | + source: "graphics/window-maximize.svg" |
152 | + color: root.active ? "white" : "#5d5d5d" |
153 | + keyColor: "black" |
154 | + } |
155 | } |
156 | } |
157 | |
158 | === added file 'qml/Components/graphics/window-close.svg' |
159 | --- qml/Components/graphics/window-close.svg 1970-01-01 00:00:00 +0000 |
160 | +++ qml/Components/graphics/window-close.svg 2015-11-23 13:54:01 +0000 |
161 | @@ -0,0 +1,14 @@ |
162 | +<?xml version="1.0" encoding="iso-8859-1"?> |
163 | +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> |
164 | +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
165 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" |
166 | + width="94.926px" height="94.926px" viewBox="0 0 94.926 94.926" style="enable-background:new 0 0 94.926 94.926;" |
167 | + xml:space="preserve"> |
168 | +<g> |
169 | + <path d="M55.931,47.463L94.306,9.09c0.826-0.827,0.826-2.167,0-2.994L88.833,0.62C88.436,0.224,87.896,0,87.335,0 |
170 | + c-0.562,0-1.101,0.224-1.498,0.62L47.463,38.994L9.089,0.62c-0.795-0.795-2.202-0.794-2.995,0L0.622,6.096 |
171 | + c-0.827,0.827-0.827,2.167,0,2.994l38.374,38.373L0.622,85.836c-0.827,0.827-0.827,2.167,0,2.994l5.473,5.476 |
172 | + c0.397,0.396,0.936,0.62,1.498,0.62s1.1-0.224,1.497-0.62l38.374-38.374l38.374,38.374c0.397,0.396,0.937,0.62,1.498,0.62 |
173 | + s1.101-0.224,1.498-0.62l5.473-5.476c0.826-0.827,0.826-2.167,0-2.994L55.931,47.463z"/> |
174 | +</g> |
175 | +</svg> |
176 | |
177 | === added file 'qml/Components/graphics/window-maximize.svg' |
178 | --- qml/Components/graphics/window-maximize.svg 1970-01-01 00:00:00 +0000 |
179 | +++ qml/Components/graphics/window-maximize.svg 2015-11-23 13:54:01 +0000 |
180 | @@ -0,0 +1,12 @@ |
181 | +<?xml version="1.0" encoding="iso-8859-1"?> |
182 | +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> |
183 | +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
184 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" |
185 | + width="459px" height="459px" viewBox="0 0 459 459" style="enable-background:new 0 0 459 459;" xml:space="preserve"> |
186 | +<g> |
187 | + <g id="check-box-outline-blank"> |
188 | + <path d="M408,51v357H51V51H408 M408,0H51C22.95,0,0,22.95,0,51v357c0,28.05,22.95,51,51,51h357c28.05,0,51-22.95,51-51V51 |
189 | + C459,22.95,436.05,0,408,0L408,0z"/> |
190 | + </g> |
191 | +</g> |
192 | +</svg> |
193 | |
194 | === added file 'qml/Components/graphics/window-minimize.svg' |
195 | --- qml/Components/graphics/window-minimize.svg 1970-01-01 00:00:00 +0000 |
196 | +++ qml/Components/graphics/window-minimize.svg 2015-11-23 13:54:01 +0000 |
197 | @@ -0,0 +1,13 @@ |
198 | +<?xml version="1.0" encoding="iso-8859-1"?> |
199 | +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> |
200 | +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
201 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" |
202 | + width="121.805px" height="121.804px" viewBox="0 0 121.805 121.804" style="enable-background:new 0 0 121.805 121.804;" |
203 | + xml:space="preserve"> |
204 | +<g> |
205 | + <g> |
206 | + <path d="M7.308,68.211h107.188c4.037,0,7.309-3.272,7.309-7.31c0-4.037-3.271-7.309-7.309-7.309H7.308 |
207 | + C3.272,53.593,0,56.865,0,60.902C0,64.939,3.272,68.211,7.308,68.211z"/> |
208 | + </g> |
209 | +</g> |
210 | +</svg> |
211 | |
212 | === modified file 'qml/Panel/Handle.qml' |
213 | --- qml/Panel/Handle.qml 2015-07-15 15:07:19 +0000 |
214 | +++ qml/Panel/Handle.qml 2015-11-23 13:54:01 +0000 |
215 | @@ -19,7 +19,7 @@ |
216 | |
217 | Rectangle { |
218 | id: handle |
219 | - color: "#333333" |
220 | + color: "#5d5d5d" |
221 | height: units.gu(2) |
222 | property bool active: false |
223 | |
224 | @@ -35,7 +35,7 @@ |
225 | id: dot |
226 | width: units.dp(3) |
227 | height: width |
228 | - color: handle.active ? "#de4814" : "#717171" |
229 | + color: handle.active ? UbuntuColors.orange : "#717171" |
230 | radius: units.dp(1) |
231 | } |
232 | } |
233 | |
234 | === modified file 'qml/Panel/Indicators/client/IndicatorsClient.qml' |
235 | --- qml/Panel/Indicators/client/IndicatorsClient.qml 2015-07-15 15:07:19 +0000 |
236 | +++ qml/Panel/Indicators/client/IndicatorsClient.qml 2015-11-23 13:54:01 +0000 |
237 | @@ -22,7 +22,7 @@ |
238 | import Ubuntu.Components.ListItems 1.3 as ListItem |
239 | |
240 | Rectangle { |
241 | - color: "black" |
242 | + color: "#333333" |
243 | id: root |
244 | |
245 | Component.onCompleted: { |
246 | |
247 | === modified file 'qml/Panel/IndicatorsMenu.qml' |
248 | --- qml/Panel/IndicatorsMenu.qml 2015-09-02 07:42:27 +0000 |
249 | +++ qml/Panel/IndicatorsMenu.qml 2015-11-23 13:54:01 +0000 |
250 | @@ -38,7 +38,7 @@ |
251 | property bool enableHint: true |
252 | property bool contentEnabled: true |
253 | property bool showOnClick: true |
254 | - property color panelColor: "black" |
255 | + property color panelColor: "#333333" |
256 | |
257 | signal showTapped(point position) |
258 | |
259 | @@ -110,12 +110,21 @@ |
260 | height: units.gu(0.5) |
261 | gradient: Gradient { |
262 | GradientStop { position: 0.0; color: "transparent" } |
263 | - GradientStop { position: 1.0; color: "black" } |
264 | + GradientStop { position: 1.0; color: "#333333" } |
265 | } |
266 | opacity: 0.3 |
267 | } |
268 | } |
269 | |
270 | + PanelSeparatorLine { |
271 | + id: indicatorOrangeLine |
272 | + anchors { |
273 | + bottom: handle.top |
274 | + left: handle.left |
275 | + right: handle.right |
276 | + } |
277 | + } |
278 | + |
279 | Rectangle { |
280 | anchors.fill: bar |
281 | color: panelColor |
282 | |
283 | === modified file 'qml/Panel/MenuContent.qml' |
284 | --- qml/Panel/MenuContent.qml 2015-07-15 15:13:18 +0000 |
285 | +++ qml/Panel/MenuContent.qml 2015-11-23 13:54:01 +0000 |
286 | @@ -27,7 +27,7 @@ |
287 | |
288 | property QtObject indicatorsModel: null |
289 | property int currentMenuIndex: -1 |
290 | - color: "#221e1c" // FIXME not in palette yet |
291 | + color: "#333333" // FIXME not in palette yet |
292 | |
293 | width: units.gu(40) |
294 | height: units.gu(42) |
295 | |
296 | === modified file 'qml/Panel/Panel.qml' |
297 | --- qml/Panel/Panel.qml 2015-11-09 10:16:18 +0000 |
298 | +++ qml/Panel/Panel.qml 2015-11-23 13:54:01 +0000 |
299 | @@ -30,23 +30,12 @@ |
300 | property real indicatorAreaShowProgress: 1.0 |
301 | property bool locked: false |
302 | |
303 | - opacity: fullscreenMode && indicators.fullyClosed ? 0.0 : 1.0 |
304 | - |
305 | - Binding { |
306 | - target: PanelState |
307 | - property: "panelHeight" |
308 | - value: root.panelHeight |
309 | - } |
310 | - |
311 | Rectangle { |
312 | id: darkenedArea |
313 | property real darkenedOpacity: 0.6 |
314 | anchors { |
315 | - top: parent.top |
316 | + fill: parent |
317 | topMargin: panelHeight |
318 | - left: parent.left |
319 | - right: parent.right |
320 | - bottom: parent.bottom |
321 | } |
322 | color: "black" |
323 | opacity: indicators.unitProgress * darkenedOpacity |
324 | @@ -59,16 +48,18 @@ |
325 | } |
326 | } |
327 | |
328 | + Binding { |
329 | + target: PanelState |
330 | + property: "panelHeight" |
331 | + value: indicators.minimizedPanelHeight |
332 | + } |
333 | + |
334 | Item { |
335 | id: indicatorArea |
336 | objectName: "indicatorArea" |
337 | |
338 | anchors.fill: parent |
339 | |
340 | - Behavior on anchors.topMargin { |
341 | - NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
342 | - } |
343 | - |
344 | transform: Translate { |
345 | y: indicators.state === "initial" |
346 | ? (1.0 - indicatorAreaShowProgress) * -d.indicatorHeight |
347 | @@ -76,7 +67,7 @@ |
348 | } |
349 | |
350 | BorderImage { |
351 | - id: dropShadow |
352 | + id: indicatorsDropShadow |
353 | anchors { |
354 | fill: indicators |
355 | leftMargin: -units.gu(1) |
356 | @@ -86,9 +77,19 @@ |
357 | source: "graphics/rectangular_dropshadow.sci" |
358 | } |
359 | |
360 | + BorderImage { |
361 | + id: panelDropShadow |
362 | + anchors { |
363 | + fill: indicatorAreaBackground |
364 | + bottomMargin: -units.gu(1) |
365 | + } |
366 | + visible: PanelState.dropShadow && !callHint.visible |
367 | + source: "graphics/rectangular_dropshadow.sci" |
368 | + } |
369 | + |
370 | Rectangle { |
371 | id: indicatorAreaBackground |
372 | - color: callHint.visible ? "green" : "black" |
373 | + color: callHint.visible ? "green" : "#333333" |
374 | anchors { |
375 | top: parent.top |
376 | left: parent.left |
377 | @@ -99,30 +100,6 @@ |
378 | Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } } |
379 | } |
380 | |
381 | - PanelSeparatorLine { |
382 | - id: orangeLine |
383 | - anchors { |
384 | - top: indicatorAreaBackground.bottom |
385 | - left: parent.left |
386 | - right: indicators.left |
387 | - } |
388 | - saturation: 1 - indicators.unitProgress |
389 | - |
390 | - // Don't let input event pass trough |
391 | - MouseArea { anchors.fill: parent } |
392 | - } |
393 | - |
394 | - Image { |
395 | - anchors { |
396 | - top: indicators.top |
397 | - bottom: indicators.bottom |
398 | - right: indicators.left |
399 | - topMargin: indicatorArea.anchors.topMargin + indicators.minimizedPanelHeight |
400 | - } |
401 | - width: units.dp(2) |
402 | - source: "graphics/VerticalDivider.png" |
403 | - } |
404 | - |
405 | MouseArea { |
406 | anchors { |
407 | top: parent.top |
408 | @@ -130,7 +107,29 @@ |
409 | right: indicators.left |
410 | } |
411 | height: indicators.minimizedPanelHeight |
412 | - onClicked: { if (callHint.visible) { callHint.showLiveCall(); } } |
413 | + hoverEnabled: true |
414 | + onClicked: callHint.visible ? callHint.showLiveCall() : PanelState.focusMaximizedApp() |
415 | + onDoubleClicked: PanelState.maximize() |
416 | + |
417 | + // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/ |
418 | + // cf. https://bugreports.qt.io/browse/QTBUG-32909 |
419 | + WindowControlButtons { |
420 | + id: windowControlButtons |
421 | + objectName: "panelWindowControlButtons" |
422 | + anchors { |
423 | + left: parent.left |
424 | + top: parent.top |
425 | + leftMargin: units.gu(1) |
426 | + topMargin: units.gu(0.5) |
427 | + bottomMargin: units.gu(0.5) |
428 | + } |
429 | + height: indicators.minimizedPanelHeight - anchors.topMargin - anchors.bottomMargin |
430 | + visible: PanelState.buttonsVisible && parent.containsMouse && !root.locked && !callHint.visible |
431 | + active: PanelState.buttonsVisible |
432 | + onClose: PanelState.close() |
433 | + onMinimize: PanelState.minimize() |
434 | + onMaximize: PanelState.maximize() |
435 | + } |
436 | } |
437 | |
438 | IndicatorsMenu { |
439 | @@ -146,7 +145,7 @@ |
440 | width: root.width - (windowControlButtons.visible ? windowControlButtons.width + titleLabel.width : 0) |
441 | minimizedPanelHeight: units.gu(3) |
442 | expandedPanelHeight: units.gu(7) |
443 | - openedHeight: root.height - indicatorOrangeLine.height |
444 | + openedHeight: root.height |
445 | |
446 | overFlowWidth: { |
447 | if (callHint.visible) { |
448 | @@ -163,58 +162,34 @@ |
449 | callHint.showLiveCall(); |
450 | } |
451 | } |
452 | - |
453 | - hideDragHandle { |
454 | - anchors.bottomMargin: -indicatorOrangeLine.height |
455 | - } |
456 | - } |
457 | - |
458 | - WindowControlButtons { |
459 | - id: windowControlButtons |
460 | - objectName: "panelWindowControlButtons" |
461 | - anchors { |
462 | - left: parent.left |
463 | - top: parent.top |
464 | - margins: units.gu(0.7) |
465 | - } |
466 | - height: indicators.minimizedPanelHeight - anchors.margins * 2 |
467 | - visible: PanelState.buttonsVisible && !root.locked |
468 | - onClose: PanelState.close() |
469 | - onMinimize: PanelState.minimize() |
470 | - onMaximize: PanelState.maximize() |
471 | } |
472 | |
473 | Label { |
474 | id: titleLabel |
475 | objectName: "windowDecorationTitle" |
476 | anchors { |
477 | - left: windowControlButtons.right |
478 | + left: parent.left |
479 | top: parent.top |
480 | - margins: units.gu(0.7) |
481 | + leftMargin: units.gu(1) |
482 | + topMargin: units.gu(0.5) |
483 | + bottomMargin: units.gu(0.5) |
484 | } |
485 | - color: "#DFDBD2" |
486 | - height: windowControlButtons.height |
487 | - visible: windowControlButtons.visible |
488 | + color: PanelState.buttonsVisible ? "#ffffff" : "#5d5d5d" |
489 | + height: indicators.minimizedPanelHeight - anchors.topMargin - anchors.bottomMargin |
490 | + visible: !windowControlButtons.visible && !root.locked && !callHint.visible |
491 | verticalAlignment: Text.AlignVCenter |
492 | - fontSize: "small" |
493 | - font.bold: true |
494 | + fontSize: "medium" |
495 | + font.weight: Font.Normal |
496 | text: PanelState.title |
497 | } |
498 | |
499 | - PanelSeparatorLine { |
500 | - id: indicatorOrangeLine |
501 | - anchors { |
502 | - top: indicators.bottom |
503 | - left: indicators.left |
504 | - right: indicators.right |
505 | - } |
506 | - } |
507 | + // TODO here would the Locally integrated menus come |
508 | |
509 | ActiveCallHint { |
510 | id: __callHint |
511 | anchors { |
512 | top: parent.top |
513 | - left: windowControlButtons.visible ? windowControlButtons.right : parent.left |
514 | + left: parent.left |
515 | } |
516 | height: indicators.minimizedPanelHeight |
517 | visible: active && indicators.state == "initial" |
518 | @@ -224,7 +199,7 @@ |
519 | QtObject { |
520 | id: d |
521 | objectName: "panelPriv" |
522 | - readonly property real indicatorHeight: indicators.minimizedPanelHeight + indicatorOrangeLine.height |
523 | + readonly property real indicatorHeight: indicators.minimizedPanelHeight |
524 | } |
525 | |
526 | states: [ |
527 | @@ -234,6 +209,7 @@ |
528 | PropertyChanges { |
529 | target: indicatorArea; |
530 | anchors.topMargin: 0 |
531 | + opacity: 1; |
532 | } |
533 | }, |
534 | State { |
535 | @@ -242,6 +218,7 @@ |
536 | PropertyChanges { |
537 | target: indicatorArea; |
538 | anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 |
539 | + opacity: indicators.fullyClosed ? 0.0 : 1.0 |
540 | } |
541 | PropertyChanges { |
542 | target: indicators.showDragHandle; |
543 | @@ -249,4 +226,15 @@ |
544 | } |
545 | } |
546 | ] |
547 | + |
548 | + transitions: [ |
549 | + Transition { |
550 | + to: "onscreen" |
551 | + UbuntuNumberAnimation { target: indicatorArea; properties: "anchors.topMargin,opacity" } |
552 | + }, |
553 | + Transition { |
554 | + to: "offscreen" |
555 | + UbuntuNumberAnimation { target: indicatorArea; properties: "anchors.topMargin,opacity" } |
556 | + } |
557 | + ] |
558 | } |
559 | |
560 | === removed file 'qml/Panel/PanelBackground.qml' |
561 | --- qml/Panel/PanelBackground.qml 2015-07-15 15:07:19 +0000 |
562 | +++ qml/Panel/PanelBackground.qml 1970-01-01 00:00:00 +0000 |
563 | @@ -1,21 +0,0 @@ |
564 | -/* |
565 | - * Copyright (C) 2013 Canonical, Ltd. |
566 | - * |
567 | - * This program is free software; you can redistribute it and/or modify |
568 | - * it under the terms of the GNU General Public License as published by |
569 | - * the Free Software Foundation; version 3. |
570 | - * |
571 | - * This program is distributed in the hope that it will be useful, |
572 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
573 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
574 | - * GNU General Public License for more details. |
575 | - * |
576 | - * You should have received a copy of the GNU General Public License |
577 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
578 | - */ |
579 | - |
580 | -import QtQuick 2.4 |
581 | - |
582 | -Rectangle { |
583 | - color: "black" |
584 | -} |
585 | |
586 | === modified file 'qml/Stages/ApplicationWindow.qml' |
587 | --- qml/Stages/ApplicationWindow.qml 2015-10-26 09:59:50 +0000 |
588 | +++ qml/Stages/ApplicationWindow.qml 2015-11-23 13:54:01 +0000 |
589 | @@ -34,6 +34,8 @@ |
590 | property QtObject application |
591 | property int surfaceOrientationAngle |
592 | property alias resizeSurface: sessionContainer.resizeSurface |
593 | + property int requestedWidth: -1 |
594 | + property int requestedHeight: -1 |
595 | |
596 | QtObject { |
597 | id: d |
598 | @@ -54,7 +56,7 @@ |
599 | // Whether the Application had a surface before but lost it. |
600 | property bool hadSurface: sessionContainer.surfaceContainer.hadSurface |
601 | |
602 | - property bool needToTakeScreenshot: |
603 | + readonly property bool needToTakeScreenshot: |
604 | ((sessionContainer.surface && d.surfaceInitialized) || d.hadSurface) |
605 | && screenshotImage.status === Image.Null |
606 | && d.applicationState === ApplicationInfoInterface.Stopped |
607 | @@ -69,7 +71,7 @@ |
608 | // Remove this when possible |
609 | property bool surfaceInitialized: false |
610 | |
611 | - property bool supportsSurfaceResize: |
612 | + readonly property bool supportsSurfaceResize: |
613 | application && |
614 | ((application.supportedOrientations & Qt.PortraitOrientation) |
615 | || (application.supportedOrientations & Qt.InvertedPortraitOrientation)) |
616 | @@ -135,7 +137,9 @@ |
617 | id: sessionContainer |
618 | // A fake application might not even have a session property. |
619 | session: application && application.session ? application.session : null |
620 | - anchors.fill: parent |
621 | + |
622 | + requestedWidth: root.requestedWidth |
623 | + requestedHeight: root.requestedHeight |
624 | |
625 | surfaceOrientationAngle: application && application.rotatesWindowContents ? root.surfaceOrientationAngle : 0 |
626 | |
627 | @@ -150,6 +154,28 @@ |
628 | focus: true |
629 | } |
630 | |
631 | + // SessionContainer size drives ApplicationWindow size |
632 | + Binding { |
633 | + target: root; property: "width" |
634 | + value: stateGroup.state === "surface" ? sessionContainer.width : root.requestedWidth |
635 | + when: root.requestedWidth >= 0 |
636 | + } |
637 | + Binding { |
638 | + target: root; property: "height" |
639 | + value: stateGroup.state === "surface" ? sessionContainer.height : root.requestedHeight |
640 | + when: root.requestedHeight >= 0 |
641 | + } |
642 | + |
643 | + // ApplicationWindow size drives SessionContainer size |
644 | + Binding { |
645 | + target: sessionContainer; property: "width"; value: root.width |
646 | + when: root.requestedWidth < 0 |
647 | + } |
648 | + Binding { |
649 | + target: sessionContainer; property: "height"; value: root.height |
650 | + when: root.requestedHeight < 0 |
651 | + } |
652 | + |
653 | StateGroup { |
654 | id: stateGroup |
655 | objectName: "applicationWindowStateGroup" |
656 | |
657 | === modified file 'qml/Stages/DecoratedWindow.qml' |
658 | --- qml/Stages/DecoratedWindow.qml 2015-11-06 13:48:29 +0000 |
659 | +++ qml/Stages/DecoratedWindow.qml 2015-11-23 13:54:01 +0000 |
660 | @@ -23,29 +23,26 @@ |
661 | FocusScope { |
662 | id: root |
663 | |
664 | + width: applicationWindow.width |
665 | + height: (decoration.visible ? decoration.height : 0) + applicationWindow.height |
666 | + |
667 | property alias window: applicationWindow |
668 | property alias application: applicationWindow.application |
669 | property alias active: decoration.active |
670 | property alias title: decoration.title |
671 | + property alias fullscreen: applicationWindow.fullscreen |
672 | |
673 | - property bool decorationShown: true |
674 | property bool highlightShown: false |
675 | property real shadowOpacity: 1 |
676 | |
677 | + property alias requestedWidth: applicationWindow.requestedWidth |
678 | + property real requestedHeight |
679 | + |
680 | signal close() |
681 | signal maximize() |
682 | signal minimize() |
683 | signal decorationPressed() |
684 | |
685 | - BorderImage { |
686 | - anchors { |
687 | - fill: root |
688 | - margins: -units.gu(2) |
689 | - } |
690 | - source: "graphics/dropshadow2gu.sci" |
691 | - opacity: root.shadowOpacity * .3 |
692 | - } |
693 | - |
694 | Rectangle { |
695 | id: selectionHighlight |
696 | anchors.fill: parent |
697 | @@ -58,7 +55,17 @@ |
698 | anchors { left: selectionHighlight.left; right: selectionHighlight.right; bottom: selectionHighlight.bottom; } |
699 | height: units.dp(2) |
700 | color: UbuntuColors.orange |
701 | - visible: root.highlightShown |
702 | + visible: highlightShown |
703 | + } |
704 | + |
705 | + BorderImage { |
706 | + anchors { |
707 | + fill: root |
708 | + margins: active ? -units.gu(2) : -units.gu(1.5) |
709 | + } |
710 | + source: "graphics/dropshadow2gu.sci" |
711 | + opacity: root.shadowOpacity * .3 |
712 | + enabled: !fullscreen |
713 | } |
714 | |
715 | WindowDecoration { |
716 | @@ -68,12 +75,13 @@ |
717 | anchors { left: parent.left; top: parent.top; right: parent.right } |
718 | height: units.gu(3) |
719 | width: root.width |
720 | - title: window.title !== "" ? window.title : "" |
721 | + title: window.title |
722 | + visible: !root.fullscreen |
723 | + |
724 | onClose: root.close(); |
725 | - onMaximize: root.maximize(); |
726 | + onMaximize: { root.decorationPressed(); root.maximize(); } |
727 | onMinimize: root.minimize(); |
728 | onPressed: root.decorationPressed(); |
729 | - visible: decorationShown |
730 | } |
731 | |
732 | ApplicationWindow { |
733 | @@ -83,7 +91,8 @@ |
734 | anchors.topMargin: decoration.height |
735 | anchors.left: parent.left |
736 | width: root.width |
737 | - height: root.height - decoration.height |
738 | + height: fullscreen ? root.height : root.height - decoration.height |
739 | + requestedHeight: root.requestedHeight - (decoration.visible ? decoration.height : 0) |
740 | interactive: true |
741 | focus: true |
742 | } |
743 | |
744 | === modified file 'qml/Stages/DesktopStage.qml' |
745 | --- qml/Stages/DesktopStage.qml 2015-11-12 20:40:49 +0000 |
746 | +++ qml/Stages/DesktopStage.qml 2015-11-23 13:54:01 +0000 |
747 | @@ -12,12 +12,9 @@ |
748 | * |
749 | * You should have received a copy of the GNU General Public License |
750 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
751 | - * |
752 | - * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
753 | */ |
754 | |
755 | import QtQuick 2.4 |
756 | -import QtQuick.Layouts 1.1 |
757 | import Ubuntu.Components 1.3 |
758 | import Unity.Application 0.1 |
759 | import "../Components/PanelState" |
760 | @@ -55,7 +52,7 @@ |
761 | onFocusRequested: { |
762 | var appIndex = priv.indexOf(appId); |
763 | var appDelegate = appRepeater.itemAt(appIndex); |
764 | - appDelegate.restoreFromMinimized(); |
765 | + appDelegate.restore(); |
766 | |
767 | if (spread.state == "altTab") { |
768 | spread.cancel(); |
769 | @@ -107,7 +104,7 @@ |
770 | id: minimizeRestoreShortcut |
771 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Down |
772 | onTriggered: priv.focusedAppDelegate.maximized || priv.focusedAppDelegate.maximizedLeft || priv.focusedAppDelegate.maximizedRight |
773 | - ? priv.focusedAppDelegate.restore() : priv.focusedAppDelegate.minimize(true) |
774 | + ? priv.focusedAppDelegate.restoreFromMaximized() : priv.focusedAppDelegate.minimize() |
775 | active: priv.focusedAppDelegate !== null |
776 | } |
777 | |
778 | @@ -119,18 +116,16 @@ |
779 | var index = indexOf(focusedAppId); |
780 | return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null |
781 | } |
782 | + onFocusedAppDelegateChanged: updateForegroundMaximizedApp(); |
783 | + |
784 | property int foregroundMaximizedAppIdIndex: -1 |
785 | |
786 | function updateForegroundMaximizedApp() { |
787 | for (var i = 0; i < appRepeater.count; i++) { |
788 | var item = appRepeater.itemAt(i); |
789 | - |
790 | if (item && item.visuallyMaximized) { |
791 | - var app = ApplicationManager.get(i); |
792 | - if (app) { |
793 | - foregroundMaximizedAppIdIndex = i; |
794 | - return; |
795 | - } |
796 | + foregroundMaximizedAppIdIndex = i; |
797 | + return; |
798 | } |
799 | } |
800 | foregroundMaximizedAppIdIndex = -1; |
801 | @@ -149,7 +144,7 @@ |
802 | for (var i = 0; i < appRepeater.count; i++) { |
803 | var appDelegate = appRepeater.itemAt(i); |
804 | if (appDelegate && !appDelegate.minimized) { |
805 | - appDelegate.minimize(false); // minimize but don't switch focus |
806 | + appDelegate.minimize(); |
807 | } |
808 | } |
809 | |
810 | @@ -173,24 +168,47 @@ |
811 | onClose: { |
812 | ApplicationManager.stopApplication(ApplicationManager.focusedApplicationId) |
813 | } |
814 | - onMinimize: appRepeater.itemAt(0).minimize(true); |
815 | - onMaximize: appRepeater.itemAt(0).restore(); |
816 | + onMinimize: priv.focusedAppDelegate && priv.focusedAppDelegate.minimize(); |
817 | + onMaximize: priv.focusedAppDelegate // don't restore minimized apps when double clicking the panel |
818 | + && priv.focusedAppDelegate.restoreFromMaximized(); |
819 | + onFocusMaximizedApp: if (priv.foregroundMaximizedAppIdIndex != -1) { |
820 | + ApplicationManager.focusApplication(appRepeater.itemAt(priv.foregroundMaximizedAppIdIndex).appId); |
821 | + } |
822 | } |
823 | |
824 | Binding { |
825 | target: PanelState |
826 | property: "buttonsVisible" |
827 | - value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized |
828 | + value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus |
829 | + && spread.state == "" |
830 | } |
831 | |
832 | Binding { |
833 | target: PanelState |
834 | property: "title" |
835 | - value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.title |
836 | - when: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized |
837 | - } |
838 | - |
839 | - Component.onDestruction: PanelState.buttonsVisible = false; |
840 | + value: { |
841 | + if (priv.focusedAppDelegate !== null && spread.state == "") { |
842 | + if (priv.focusedAppDelegate.maximized) |
843 | + return priv.focusedAppDelegate.title |
844 | + else |
845 | + return priv.focusedAppDelegate.appName |
846 | + } |
847 | + return "" |
848 | + } |
849 | + when: priv.focusedAppDelegate |
850 | + } |
851 | + |
852 | + Binding { |
853 | + target: PanelState |
854 | + property: "dropShadow" |
855 | + value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppIdIndex !== -1 |
856 | + } |
857 | + |
858 | + Component.onDestruction: { |
859 | + PanelState.title = ""; |
860 | + PanelState.buttonsVisible = false; |
861 | + PanelState.dropShadow = false; |
862 | + } |
863 | |
864 | FocusScope { |
865 | id: appContainer |
866 | @@ -211,17 +229,16 @@ |
867 | model: ApplicationManager |
868 | objectName: "appRepeater" |
869 | |
870 | - onItemAdded: priv.updateForegroundMaximizedApp() |
871 | - onItemRemoved: priv.updateForegroundMaximizedApp() |
872 | - |
873 | delegate: FocusScope { |
874 | id: appDelegate |
875 | objectName: "appDelegate_" + appId |
876 | z: ApplicationManager.count - index |
877 | - y: units.gu(3) |
878 | - width: units.gu(60) |
879 | - height: units.gu(50) |
880 | + y: PanelState.panelHeight |
881 | focus: appId === priv.focusedAppId |
882 | + width: decoratedWindow.width |
883 | + height: decoratedWindow.height |
884 | + property alias requestedWidth: decoratedWindow.requestedWidth |
885 | + property alias requestedHeight: decoratedWindow.requestedHeight |
886 | |
887 | QtObject { |
888 | id: appDelegatePrivate |
889 | @@ -238,6 +255,7 @@ |
890 | readonly property string appId: model.appId |
891 | property bool animationsEnabled: true |
892 | property alias title: decoratedWindow.title |
893 | + readonly property string appName: model.name |
894 | property bool visuallyMaximized: false |
895 | property bool visuallyMinimized: false |
896 | |
897 | @@ -247,7 +265,6 @@ |
898 | } |
899 | } |
900 | |
901 | - onZChanged: priv.updateForegroundMaximizedApp() |
902 | onVisuallyMaximizedChanged: priv.updateForegroundMaximizedApp() |
903 | |
904 | visible: !visuallyMinimized && |
905 | @@ -287,19 +304,18 @@ |
906 | } |
907 | function minimize(animated) { |
908 | animationsEnabled = (animated === undefined) || animated; |
909 | - appDelegatePrivate.maximized = false; |
910 | appDelegatePrivate.minimized = true; |
911 | } |
912 | + function restoreFromMaximized(animated) { |
913 | + animationsEnabled = (animated === undefined) || animated; |
914 | + appDelegatePrivate.minimized = false; |
915 | + appDelegatePrivate.maximized = false; |
916 | + appDelegatePrivate.maximizedLeft = false; |
917 | + appDelegatePrivate.maximizedRight = false; |
918 | + } |
919 | function restore(animated) { |
920 | animationsEnabled = (animated === undefined) || animated; |
921 | appDelegatePrivate.minimized = false; |
922 | - appDelegatePrivate.maximized = false; |
923 | - appDelegatePrivate.maximizedLeft = false; |
924 | - appDelegatePrivate.maximizedRight = false; |
925 | - } |
926 | - function restoreFromMinimized(animated) { |
927 | - animationsEnabled = (animated === undefined) || animated; |
928 | - appDelegatePrivate.minimized = false; |
929 | if (maximized) |
930 | maximize(); |
931 | else if (maximizedLeft) |
932 | @@ -311,6 +327,14 @@ |
933 | |
934 | states: [ |
935 | State { |
936 | + name: "fullscreen"; when: decoratedWindow.fullscreen |
937 | + extend: "maximized" |
938 | + PropertyChanges { |
939 | + target: appDelegate; |
940 | + y: -PanelState.panelHeight |
941 | + } |
942 | + }, |
943 | + State { |
944 | name: "normal"; |
945 | when: !appDelegate.maximized && !appDelegate.minimized |
946 | && !appDelegate.maximizedLeft && !appDelegate.maximizedRight |
947 | @@ -321,22 +345,24 @@ |
948 | } |
949 | }, |
950 | State { |
951 | - name: "maximized"; when: appDelegate.maximized |
952 | + name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized |
953 | PropertyChanges { |
954 | target: appDelegate; |
955 | x: 0; y: 0; |
956 | - width: root.width; height: root.height; |
957 | + requestedWidth: root.width; requestedHeight: root.height; |
958 | visuallyMinimized: false; |
959 | visuallyMaximized: true |
960 | } |
961 | }, |
962 | State { |
963 | name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized |
964 | - PropertyChanges { target: appDelegate; x: 0; y: units.gu(3); width: root.width/2; height: root.height - units.gu(3) } |
965 | + PropertyChanges { target: appDelegate; x: 0; y: PanelState.panelHeight; |
966 | + requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight } |
967 | }, |
968 | State { |
969 | name: "maximizedRight"; when: appDelegate.maximizedRight && !appDelegate.minimized |
970 | - PropertyChanges { target: appDelegate; x: root.width/2; y: units.gu(3); width: root.width/2; height: root.height - units.gu(3) } |
971 | + PropertyChanges { target: appDelegate; x: root.width/2; y: PanelState.panelHeight; |
972 | + requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight } |
973 | }, |
974 | State { |
975 | name: "minimized"; when: appDelegate.minimized |
976 | @@ -355,32 +381,32 @@ |
977 | to: "normal" |
978 | enabled: appDelegate.animationsEnabled |
979 | PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" } |
980 | - UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale"; duration: UbuntuAnimation.FastDuration } |
981 | - }, |
982 | - Transition { |
983 | - to: "maximized" |
984 | - enabled: appDelegate.animationsEnabled |
985 | - PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
986 | - SequentialAnimation { |
987 | - UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale"; duration: UbuntuAnimation.FastDuration } |
988 | - PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
989 | - } |
990 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration } |
991 | }, |
992 | Transition { |
993 | to: "minimized" |
994 | enabled: appDelegate.animationsEnabled |
995 | PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
996 | SequentialAnimation { |
997 | - UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale"; duration: UbuntuAnimation.FastDuration } |
998 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration } |
999 | PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
1000 | ScriptAction { |
1001 | script: { |
1002 | - if (appDelegate.animationsEnabled && state === "minimized" ) { |
1003 | + if (appDelegate.minimized) { |
1004 | priv.focusNext(); |
1005 | } |
1006 | } |
1007 | } |
1008 | } |
1009 | + }, |
1010 | + Transition { |
1011 | + to: "*" //maximized and fullscreen |
1012 | + enabled: appDelegate.animationsEnabled |
1013 | + PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
1014 | + SequentialAnimation { |
1015 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration } |
1016 | + PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
1017 | + } |
1018 | } |
1019 | ] |
1020 | |
1021 | @@ -410,16 +436,14 @@ |
1022 | objectName: "decoratedWindow" |
1023 | anchors.left: appDelegate.left |
1024 | anchors.top: appDelegate.top |
1025 | - width: appDelegate.width |
1026 | - height: appDelegate.height |
1027 | application: ApplicationManager.get(index) |
1028 | active: ApplicationManager.focusedApplicationId === model.appId |
1029 | focus: true |
1030 | |
1031 | onClose: ApplicationManager.stopApplication(model.appId) |
1032 | onMaximize: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight |
1033 | - ? appDelegate.restore() : appDelegate.maximize() |
1034 | - onMinimize: appDelegate.minimize(true) |
1035 | + ? appDelegate.restoreFromMaximized() : appDelegate.maximize() |
1036 | + onMinimize: appDelegate.minimize() |
1037 | onDecorationPressed: { ApplicationManager.focusApplication(model.appId) } |
1038 | } |
1039 | } |
1040 | |
1041 | === modified file 'qml/Stages/SessionContainer.qml' |
1042 | --- qml/Stages/SessionContainer.qml 2015-09-29 12:28:10 +0000 |
1043 | +++ qml/Stages/SessionContainer.qml 2015-11-23 13:54:01 +0000 |
1044 | @@ -29,13 +29,37 @@ |
1045 | property alias surfaceOrientationAngle: _surfaceContainer.surfaceOrientationAngle |
1046 | property alias resizeSurface: _surfaceContainer.resizeSurface |
1047 | |
1048 | + property int requestedWidth: -1 |
1049 | + property int requestedHeight: -1 |
1050 | + |
1051 | readonly property alias surfaceContainer: _surfaceContainer |
1052 | SurfaceContainer { |
1053 | id: _surfaceContainer |
1054 | - anchors.fill: parent |
1055 | + requestedWidth: root.requestedWidth |
1056 | + requestedHeight: root.requestedHeight |
1057 | surface: session ? session.surface : null |
1058 | } |
1059 | |
1060 | + // SurfaceContainer size drives SessionContainer size |
1061 | + Binding { |
1062 | + target: root; property: "width"; value: _surfaceContainer.width |
1063 | + when: root.requestedWidth >= 0 |
1064 | + } |
1065 | + Binding { |
1066 | + target: root; property: "height"; value: _surfaceContainer.height |
1067 | + when: root.requestedHeight >= 0 |
1068 | + } |
1069 | + |
1070 | + // SessionContainer size drives SurfaceContainer size |
1071 | + Binding { |
1072 | + target: _surfaceContainer; property: "width"; value: root.width |
1073 | + when: root.requestedWidth < 0 |
1074 | + } |
1075 | + Binding { |
1076 | + target: _surfaceContainer; property: "height"; value: root.height |
1077 | + when: root.requestedHeight < 0 |
1078 | + } |
1079 | + |
1080 | Repeater { |
1081 | id: childSessionsRepeater |
1082 | model: root.childSessions |
1083 | |
1084 | === modified file 'qml/Stages/SurfaceContainer.qml' |
1085 | --- qml/Stages/SurfaceContainer.qml 2015-10-26 09:59:50 +0000 |
1086 | +++ qml/Stages/SurfaceContainer.qml 2015-11-23 13:54:01 +0000 |
1087 | @@ -31,6 +31,9 @@ |
1088 | property string name: surface ? surface.name : "" |
1089 | property bool resizeSurface: true |
1090 | |
1091 | + property int requestedWidth: -1 |
1092 | + property int requestedHeight: -1 |
1093 | + |
1094 | onSurfaceChanged: { |
1095 | if (surface) { |
1096 | surfaceItem.surface = surface; |
1097 | @@ -54,16 +57,65 @@ |
1098 | |
1099 | consumesInput: true |
1100 | |
1101 | - surfaceWidth: root.resizeSurface ? width : -1 |
1102 | - surfaceHeight: root.resizeSurface ? height : -1 |
1103 | - |
1104 | - anchors.fill: root |
1105 | + surfaceWidth: { |
1106 | + if (root.resizeSurface) { |
1107 | + if (root.requestedWidth >= 0) { |
1108 | + return root.requestedWidth; |
1109 | + } else { |
1110 | + return width; |
1111 | + } |
1112 | + } else { |
1113 | + return -1; |
1114 | + } |
1115 | + } |
1116 | + |
1117 | + surfaceHeight: { |
1118 | + if (root.resizeSurface) { |
1119 | + if (root.requestedHeight >= 0) { |
1120 | + return root.requestedHeight; |
1121 | + } else { |
1122 | + return height; |
1123 | + } |
1124 | + } else { |
1125 | + return -1; |
1126 | + } |
1127 | + } |
1128 | + |
1129 | enabled: root.interactive |
1130 | focus: true |
1131 | antialiasing: !root.interactive |
1132 | orientationAngle: root.surfaceOrientationAngle |
1133 | } |
1134 | |
1135 | + // MirSurface size drives SurfaceContainer size |
1136 | + Binding { |
1137 | + target: surfaceItem; property: "width"; value: root.surface ? root.surface.size.width : 0 |
1138 | + when: root.requestedWidth >= 0 && root.surface |
1139 | + } |
1140 | + Binding { |
1141 | + target: surfaceItem; property: "height"; value: root.surface ? root.surface.size.height : 0 |
1142 | + when: root.requestedHeight >= 0 && root.surface |
1143 | + } |
1144 | + Binding { |
1145 | + target: root; property: "width"; value: surfaceItem.width |
1146 | + when: root.requestedWidth >= 0 |
1147 | + } |
1148 | + Binding { |
1149 | + target: root; property: "height"; value: surfaceItem.height |
1150 | + when: root.requestedHeight >= 0 |
1151 | + } |
1152 | + |
1153 | + // SurfaceContainer size drives MirSurface size |
1154 | + Binding { |
1155 | + target: surfaceItem; property: "width"; value: root.width |
1156 | + when: root.requestedWidth < 0 |
1157 | + } |
1158 | + Binding { |
1159 | + target: surfaceItem; property: "height"; value: root.height |
1160 | + when: root.requestedHeight < 0 |
1161 | + } |
1162 | + |
1163 | + |
1164 | TouchGate { |
1165 | targetItem: surfaceItem |
1166 | anchors.fill: root |
1167 | |
1168 | === modified file 'qml/Stages/WindowDecoration.qml' |
1169 | --- qml/Stages/WindowDecoration.qml 2015-11-09 10:16:18 +0000 |
1170 | +++ qml/Stages/WindowDecoration.qml 2015-11-23 13:54:01 +0000 |
1171 | @@ -33,6 +33,8 @@ |
1172 | signal minimize() |
1173 | signal maximize() |
1174 | |
1175 | + onDoubleClicked: root.maximize() |
1176 | + |
1177 | QtObject { |
1178 | id: priv |
1179 | property real distanceX |
1180 | @@ -65,20 +67,23 @@ |
1181 | anchors.fill: parent |
1182 | anchors.bottomMargin: -radius |
1183 | radius: units.gu(.5) |
1184 | - gradient: Gradient { |
1185 | - GradientStop { color: "#626055"; position: 0 } |
1186 | - GradientStop { color: "#3C3B37"; position: 1 } |
1187 | - } |
1188 | + color: "#333333" |
1189 | } |
1190 | |
1191 | Row { |
1192 | - anchors { fill: parent; margins: units.gu(0.7) } |
1193 | - spacing: units.gu(1) |
1194 | - opacity: root.active ? 1 : 0.5 |
1195 | + anchors { |
1196 | + fill: parent |
1197 | + leftMargin: units.gu(1) |
1198 | + rightMargin: units.gu(1) |
1199 | + topMargin: units.gu(0.5) |
1200 | + bottomMargin: units.gu(0.5) |
1201 | + } |
1202 | + spacing: units.gu(3) |
1203 | |
1204 | WindowControlButtons { |
1205 | id: buttons |
1206 | height: parent.height |
1207 | + active: root.active |
1208 | onClose: root.close(); |
1209 | onMinimize: root.minimize(); |
1210 | onMaximize: root.maximize(); |
1211 | @@ -87,12 +92,12 @@ |
1212 | Label { |
1213 | id: titleLabel |
1214 | objectName: "windowDecorationTitle" |
1215 | - color: "#DFDBD2" |
1216 | + color: root.active ? "white" : "#5d5d5d" |
1217 | height: parent.height |
1218 | width: parent.width - buttons.width - parent.anchors.rightMargin - parent.anchors.leftMargin |
1219 | verticalAlignment: Text.AlignVCenter |
1220 | - fontSize: "small" |
1221 | - font.bold: true |
1222 | + fontSize: "medium" |
1223 | + font.weight: root.active ? Font.Light : Font.Normal |
1224 | elide: Text.ElideRight |
1225 | } |
1226 | } |
1227 | |
1228 | === modified file 'qml/Stages/WindowResizeArea.qml' |
1229 | --- qml/Stages/WindowResizeArea.qml 2015-11-09 10:52:53 +0000 |
1230 | +++ qml/Stages/WindowResizeArea.qml 2015-11-23 13:54:01 +0000 |
1231 | @@ -25,7 +25,7 @@ |
1232 | anchors.fill: target |
1233 | anchors.margins: -borderThickness |
1234 | |
1235 | - hoverEnabled: true |
1236 | + hoverEnabled: target && !target.maximized // don't grab the resize under the panel |
1237 | |
1238 | property var windowStateStorage: WindowStateStorage |
1239 | |
1240 | @@ -36,6 +36,8 @@ |
1241 | property int borderThickness: 0 |
1242 | property int minWidth: 0 |
1243 | property int minHeight: 0 |
1244 | + property int defaultWidth: units.gu(60) |
1245 | + property int defaultHeight: units.gu(50) |
1246 | property int screenWidth: 0 |
1247 | property int screenHeight: 0 |
1248 | |
1249 | @@ -67,13 +69,14 @@ |
1250 | } |
1251 | |
1252 | Component.onCompleted: { |
1253 | - var windowGeometry = windowStateStorage.getGeometry(root.windowId, Qt.rect(target.x, target.y, target.width, target.height)) |
1254 | - if (windowGeometry !== undefined) { |
1255 | - target.width = Math.min(windowGeometry.width, root.screenWidth) |
1256 | - target.height = Math.min(windowGeometry.height, root.screenHeight - PanelState.panelHeight) |
1257 | - target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.width), 0) |
1258 | - target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.height), PanelState.panelHeight) |
1259 | - } |
1260 | + var windowGeometry = windowStateStorage.getGeometry(root.windowId, |
1261 | + Qt.rect(target.x, target.y, defaultWidth, defaultHeight)); |
1262 | + |
1263 | + target.requestedWidth = Math.min(Math.max(windowGeometry.width, minWidth), screenWidth); |
1264 | + target.requestedHeight = Math.min(Math.max(windowGeometry.height, minHeight), root.screenHeight - PanelState.panelHeight); |
1265 | + target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0) |
1266 | + target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight) |
1267 | + |
1268 | var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal) |
1269 | if (windowState === WindowStateStorage.WindowStateMaximized) { |
1270 | target.maximize(false) |
1271 | @@ -93,6 +96,18 @@ |
1272 | property bool topBorder: false |
1273 | property bool bottomBorder: false |
1274 | |
1275 | + // true - A change in surface size will cause the left border of the window to move accordingly. |
1276 | + // The window's right border will stay in the same position. |
1277 | + // false - a change in surface size will cause the right border of the window to move accordingly. |
1278 | + // The window's left border will stay in the same position. |
1279 | + property bool moveLeftBorder: false |
1280 | + |
1281 | + // true - A change in surface size will cause the top border of the window to move accordingly. |
1282 | + // The window's bottom border will stay in the same position. |
1283 | + // false - a change in surface size will cause the bottom border of the window to move accordingly. |
1284 | + // The window's top border will stay in the same position. |
1285 | + property bool moveTopBorder: false |
1286 | + |
1287 | property bool dragging: false |
1288 | property real startMousePosX |
1289 | property real startMousePosY |
1290 | @@ -100,6 +115,8 @@ |
1291 | property real startY |
1292 | property real startWidth |
1293 | property real startHeight |
1294 | + property real currentWidth |
1295 | + property real currentHeight |
1296 | |
1297 | property string cursorName: { |
1298 | if (root.containsMouse || root.pressed) { |
1299 | @@ -138,11 +155,24 @@ |
1300 | } |
1301 | } |
1302 | |
1303 | + Timer { |
1304 | + id: resetBordersToMoveTimer |
1305 | + interval: 2000 |
1306 | + onTriggered: { |
1307 | + d.moveLeftBorder = false; |
1308 | + d.moveTopBorder = false; |
1309 | + } |
1310 | + } |
1311 | + |
1312 | onPressedChanged: { |
1313 | var pos = mapToItem(target.parent, mouseX, mouseY); |
1314 | |
1315 | if (pressed) { |
1316 | d.updateBorders(); |
1317 | + resetBordersToMoveTimer.stop(); |
1318 | + d.moveLeftBorder = d.leftBorder; |
1319 | + d.moveTopBorder = d.topBorder; |
1320 | + |
1321 | var pos = mapToItem(root.target.parent, mouseX, mouseY); |
1322 | d.startMousePosX = pos.x; |
1323 | d.startMousePosY = pos.y; |
1324 | @@ -150,8 +180,11 @@ |
1325 | d.startY = target.y; |
1326 | d.startWidth = target.width; |
1327 | d.startHeight = target.height; |
1328 | + d.currentWidth = target.width; |
1329 | + d.currentHeight = target.height; |
1330 | d.dragging = true; |
1331 | } else { |
1332 | + resetBordersToMoveTimer.start(); |
1333 | d.dragging = false; |
1334 | if (containsMouse) { |
1335 | d.updateBorders(); |
1336 | @@ -182,37 +215,49 @@ |
1337 | if (d.leftBorder) { |
1338 | var newTargetX = d.startX + deltaX; |
1339 | if (target.x + target.width > newTargetX + minWidth) { |
1340 | - target.width = target.x + target.width - newTargetX; |
1341 | - target.x = newTargetX; |
1342 | + target.requestedWidth = target.x + target.width - newTargetX; |
1343 | } else { |
1344 | - target.x = target.x + target.width - minWidth; |
1345 | - target.width = minWidth; |
1346 | + target.requestedWidth = minWidth; |
1347 | } |
1348 | |
1349 | } else if (d.rightBorder) { |
1350 | if (d.startWidth + deltaX >= minWidth) { |
1351 | - target.width = d.startWidth + deltaX; |
1352 | + target.requestedWidth = d.startWidth + deltaX; |
1353 | } else { |
1354 | - target.width = minWidth; |
1355 | + target.requestedWidth = minWidth; |
1356 | } |
1357 | } |
1358 | |
1359 | if (d.topBorder) { |
1360 | var newTargetY = d.startY + deltaY; |
1361 | if (target.y + target.height > newTargetY + minHeight) { |
1362 | - target.height = target.y + target.height - newTargetY; |
1363 | - target.y = newTargetY; |
1364 | + target.requestedHeight = target.y + target.height - newTargetY; |
1365 | } else { |
1366 | - target.y = target.y + target.height - minHeight; |
1367 | - target.height = minHeight; |
1368 | + target.requestedHeight = minHeight; |
1369 | } |
1370 | |
1371 | } else if (d.bottomBorder) { |
1372 | if (d.startHeight + deltaY >= minHeight) { |
1373 | - target.height = d.startHeight + deltaY; |
1374 | + target.requestedHeight = d.startHeight + deltaY; |
1375 | } else { |
1376 | - target.height = minHeight; |
1377 | - } |
1378 | + target.requestedHeight = minHeight; |
1379 | + } |
1380 | + } |
1381 | + } |
1382 | + |
1383 | + Connections { |
1384 | + target: root.target |
1385 | + onWidthChanged: { |
1386 | + if (d.moveLeftBorder) { |
1387 | + target.x += d.currentWidth - target.width; |
1388 | + } |
1389 | + d.currentWidth = target.width; |
1390 | + } |
1391 | + onHeightChanged: { |
1392 | + if (d.moveTopBorder) { |
1393 | + target.y += d.currentHeight - target.height; |
1394 | + } |
1395 | + d.currentHeight = target.height; |
1396 | } |
1397 | } |
1398 | } |
1399 | |
1400 | === modified file 'tests/mocks/Unity/Application/MirSurface.cpp' |
1401 | --- tests/mocks/Unity/Application/MirSurface.cpp 2015-10-27 21:55:10 +0000 |
1402 | +++ tests/mocks/Unity/Application/MirSurface.cpp 2015-11-23 13:54:01 +0000 |
1403 | @@ -35,8 +35,12 @@ |
1404 | , m_activeFocus(false) |
1405 | , m_width(-1) |
1406 | , m_height(-1) |
1407 | + , m_slowToResize(false) |
1408 | { |
1409 | // qDebug() << "MirSurface::MirSurface() " << name; |
1410 | + m_delayedResizeTimer.setInterval(600); |
1411 | + m_delayedResizeTimer.setSingleShot(true); |
1412 | + connect(&m_delayedResizeTimer, &QTimer::timeout, this, &MirSurface::applyDelayedResize); |
1413 | } |
1414 | |
1415 | MirSurface::~MirSurface() |
1416 | @@ -197,7 +201,38 @@ |
1417 | |
1418 | void MirSurface::resize(int width, int height) |
1419 | { |
1420 | + if (m_slowToResize) { |
1421 | + if (!m_delayedResizeTimer.isActive()) { |
1422 | + m_delayedResize.setWidth(width); |
1423 | + m_delayedResize.setHeight(height); |
1424 | + m_delayedResizeTimer.start(); |
1425 | + } else { |
1426 | + m_pendingResize.setWidth(width); |
1427 | + m_pendingResize.setHeight(height); |
1428 | + } |
1429 | + } else { |
1430 | + doResize(width, height); |
1431 | + } |
1432 | +} |
1433 | + |
1434 | +void MirSurface::applyDelayedResize() |
1435 | +{ |
1436 | + doResize(m_delayedResize.width(), m_delayedResize.height()); |
1437 | + m_delayedResize.setWidth(-1); |
1438 | + m_delayedResize.setHeight(-1); |
1439 | + |
1440 | + if (m_pendingResize.isValid()) { |
1441 | + QSize size = m_pendingResize; |
1442 | + m_pendingResize.setWidth(-1); |
1443 | + m_pendingResize.setHeight(-1); |
1444 | + resize(size.width(), size.height()); |
1445 | + } |
1446 | +} |
1447 | + |
1448 | +void MirSurface::doResize(int width, int height) |
1449 | +{ |
1450 | bool changed = false; |
1451 | + |
1452 | if (width != m_width) { |
1453 | m_width = width; |
1454 | Q_EMIT widthChanged(); |
1455 | @@ -214,3 +249,20 @@ |
1456 | Q_EMIT sizeChanged(QSize(width, height)); |
1457 | } |
1458 | } |
1459 | + |
1460 | +bool MirSurface::isSlowToResize() const |
1461 | +{ |
1462 | + return m_slowToResize; |
1463 | +} |
1464 | + |
1465 | +void MirSurface::setSlowToResize(bool value) |
1466 | +{ |
1467 | + if (m_slowToResize != value) { |
1468 | + m_slowToResize = value; |
1469 | + Q_EMIT slowToResizeChanged(); |
1470 | + if (!m_slowToResize && m_delayedResizeTimer.isActive()) { |
1471 | + m_delayedResizeTimer.stop(); |
1472 | + applyDelayedResize(); |
1473 | + } |
1474 | + } |
1475 | +} |
1476 | |
1477 | === modified file 'tests/mocks/Unity/Application/MirSurface.h' |
1478 | --- tests/mocks/Unity/Application/MirSurface.h 2015-10-20 16:48:06 +0000 |
1479 | +++ tests/mocks/Unity/Application/MirSurface.h 2015-11-23 13:54:01 +0000 |
1480 | @@ -18,6 +18,7 @@ |
1481 | #define MOCK_MIR_SURFACE_H |
1482 | |
1483 | #include <QObject> |
1484 | +#include <QTimer> |
1485 | #include <QUrl> |
1486 | #include <QHash> |
1487 | |
1488 | @@ -33,6 +34,7 @@ |
1489 | Q_PROPERTY(int width READ width NOTIFY widthChanged) |
1490 | Q_PROPERTY(int height READ height NOTIFY heightChanged) |
1491 | Q_PROPERTY(bool activeFocus READ activeFocus NOTIFY activeFocusChanged) |
1492 | + Q_PROPERTY(bool slowToResize READ isSlowToResize WRITE setSlowToResize NOTIFY slowToResizeChanged) |
1493 | |
1494 | public: |
1495 | MirSurface(const QString& name, |
1496 | @@ -77,6 +79,9 @@ |
1497 | int width() const; |
1498 | int height() const; |
1499 | |
1500 | + bool isSlowToResize() const; |
1501 | + void setSlowToResize(bool value); |
1502 | + |
1503 | ///// |
1504 | // internal mock stuff |
1505 | |
1506 | @@ -94,13 +99,18 @@ |
1507 | void orientationAngleChanged(Mir::OrientationAngle angle); |
1508 | void widthChanged(); |
1509 | void heightChanged(); |
1510 | + void slowToResizeChanged(); |
1511 | |
1512 | //// |
1513 | // internal mock stuff |
1514 | void screenshotUrlChanged(QUrl); |
1515 | void activeFocusChanged(bool); |
1516 | |
1517 | +private Q_SLOTS: |
1518 | + void applyDelayedResize(); |
1519 | + |
1520 | private: |
1521 | + void doResize(int width, int height); |
1522 | void updateVisibility(); |
1523 | |
1524 | const QString m_name; |
1525 | @@ -114,6 +124,12 @@ |
1526 | bool m_activeFocus; |
1527 | int m_width; |
1528 | int m_height; |
1529 | + |
1530 | + bool m_slowToResize; |
1531 | + QTimer m_delayedResizeTimer; |
1532 | + QSize m_delayedResize; |
1533 | + QSize m_pendingResize; |
1534 | + |
1535 | struct View { |
1536 | bool visible; |
1537 | }; |
1538 | |
1539 | === modified file 'tests/qmltests/Panel/tst_Panel.qml' |
1540 | --- tests/qmltests/Panel/tst_Panel.qml 2015-08-03 13:48:14 +0000 |
1541 | +++ tests/qmltests/Panel/tst_Panel.qml 2015-11-23 13:54:01 +0000 |
1542 | @@ -23,6 +23,7 @@ |
1543 | import Unity.Indicators 0.1 as Indicators |
1544 | import Ubuntu.Telephony 0.1 as Telephony |
1545 | import "../../../qml/Panel" |
1546 | +import "../../../qml/Components/PanelState" |
1547 | |
1548 | IndicatorTest { |
1549 | id: root |
1550 | @@ -30,6 +31,12 @@ |
1551 | height: units.gu(71) |
1552 | color: "white" |
1553 | |
1554 | + Binding { |
1555 | + target: mouseEmulation |
1556 | + property: "checked" |
1557 | + value: !windowControlsCB.checked |
1558 | + } |
1559 | + |
1560 | RowLayout { |
1561 | anchors.fill: parent |
1562 | anchors.margins: units.gu(1) |
1563 | @@ -45,17 +52,18 @@ |
1564 | MouseArea { |
1565 | id: backgroundMouseArea |
1566 | anchors.fill: parent |
1567 | - } |
1568 | - |
1569 | - Panel { |
1570 | - id: panel |
1571 | - anchors.fill: parent |
1572 | - indicators { |
1573 | - width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
1574 | - indicatorsModel: root.indicatorsModel |
1575 | + hoverEnabled: true |
1576 | + |
1577 | + Panel { |
1578 | + id: panel |
1579 | + anchors.fill: parent |
1580 | + indicators { |
1581 | + width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
1582 | + indicatorsModel: root.indicatorsModel |
1583 | + } |
1584 | + |
1585 | + property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight |
1586 | } |
1587 | - |
1588 | - property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight + units.dp(2) |
1589 | } |
1590 | } |
1591 | |
1592 | @@ -93,6 +101,32 @@ |
1593 | } |
1594 | } |
1595 | |
1596 | + RowLayout { |
1597 | + Layout.fillWidth: true |
1598 | + CheckBox { |
1599 | + id: windowControlsCB |
1600 | + onClicked: PanelState.buttonsVisible = checked |
1601 | + } |
1602 | + Label { |
1603 | + text: "Show window controls" |
1604 | + } |
1605 | + } |
1606 | + |
1607 | + RowLayout { |
1608 | + Layout.fillWidth: true |
1609 | + CheckBox { |
1610 | + onClicked: { |
1611 | + if (checked) |
1612 | + PanelState.title = "Fake window title" |
1613 | + else |
1614 | + PanelState.title = "" |
1615 | + } |
1616 | + } |
1617 | + Label { |
1618 | + text: "Show fake window title" |
1619 | + } |
1620 | + } |
1621 | + |
1622 | Rectangle { |
1623 | Layout.preferredHeight: units.dp(1); |
1624 | Layout.fillWidth: true; |
1625 | @@ -127,7 +161,7 @@ |
1626 | color: "black" |
1627 | } |
1628 | |
1629 | - MouseTouchEmulationCheckbox {} |
1630 | + MouseTouchEmulationCheckbox { id: mouseEmulation } |
1631 | } |
1632 | } |
1633 | |
1634 | |
1635 | === modified file 'tests/qmltests/Stages/tst_DesktopStage.qml' |
1636 | --- tests/qmltests/Stages/tst_DesktopStage.qml 2015-11-06 13:48:29 +0000 |
1637 | +++ tests/qmltests/Stages/tst_DesktopStage.qml 2015-11-23 13:54:01 +0000 |
1638 | @@ -17,7 +17,7 @@ |
1639 | import QtQuick 2.4 |
1640 | import QtTest 1.0 |
1641 | import Ubuntu.Components 1.3 |
1642 | -import Ubuntu.Components.ListItems 1.3 as ListItem |
1643 | +import Ubuntu.Components.ListItems 1.3 |
1644 | import Unity.Application 0.1 |
1645 | import Unity.Test 0.1 |
1646 | import Utils 0.1 |
1647 | @@ -46,8 +46,8 @@ |
1648 | WindowStateStorage.geometry = { |
1649 | 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)), |
1650 | 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)), |
1651 | - 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)), |
1652 | - 'gallery-app': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40)) |
1653 | + 'gmail-webapp': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)), |
1654 | + 'twitter-webapp': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40)) |
1655 | } |
1656 | } |
1657 | |
1658 | @@ -60,10 +60,14 @@ |
1659 | |
1660 | focus: true |
1661 | |
1662 | + property bool itemDestroyed: false |
1663 | sourceComponent: Component { |
1664 | DesktopStage { |
1665 | color: "darkblue" |
1666 | anchors.fill: parent |
1667 | + Component.onDestruction: { |
1668 | + desktopStageLoader.itemDestroyed = true; |
1669 | + } |
1670 | orientations: Orientations {} |
1671 | } |
1672 | } |
1673 | @@ -82,6 +86,21 @@ |
1674 | Column { |
1675 | anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) } |
1676 | spacing: units.gu(1) |
1677 | + |
1678 | + Button { |
1679 | + color: "white" |
1680 | + text: "Make surface slow to resize" |
1681 | + activeFocusOnPress: false |
1682 | + onClicked: { |
1683 | + if (ApplicationManager.focusedApplicationId) { |
1684 | + var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.surface; |
1685 | + surface.slowToResize = true; |
1686 | + } |
1687 | + } |
1688 | + } |
1689 | + |
1690 | + Divider {} |
1691 | + |
1692 | Repeater { |
1693 | model: ApplicationManager.availableApplications |
1694 | ApplicationCheckBox { |
1695 | @@ -99,10 +118,16 @@ |
1696 | property Item desktopStage: desktopStageLoader.status === Loader.Ready ? desktopStageLoader.item : null |
1697 | |
1698 | function cleanup() { |
1699 | + desktopStageLoader.itemDestroyed = false; |
1700 | desktopStageLoader.active = false; |
1701 | |
1702 | tryCompare(desktopStageLoader, "status", Loader.Null); |
1703 | tryCompare(desktopStageLoader, "item", null); |
1704 | + // Loader.status might be Loader.Null and Loader.item might be null but the Loader |
1705 | + // actually took place. Likely because Loader waits until the next event loop |
1706 | + // iteration to do its work. So to ensure the reload, we will wait until the |
1707 | + // Shell instance gets destroyed. |
1708 | + tryCompare(desktopStageLoader, "itemDestroyed", true); |
1709 | |
1710 | killAllRunningApps(); |
1711 | |
1712 | @@ -156,8 +181,8 @@ |
1713 | |
1714 | function test_tappingOnWindowChangesFocusedApp_data() { |
1715 | return [ |
1716 | - {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 0, focusTo: 1 }, |
1717 | - {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 1, focusTo: 0 }, |
1718 | + {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 0, focusTo: 1 }, |
1719 | + {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 1, focusTo: 0 } |
1720 | ] |
1721 | } |
1722 | |
1723 | @@ -203,8 +228,8 @@ |
1724 | |
1725 | function test_tappingOnDecorationFocusesApplication_data() { |
1726 | return [ |
1727 | - {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 0, focusTo: 1 }, |
1728 | - {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 1, focusTo: 0 }, |
1729 | + {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 0, focusTo: 1 }, |
1730 | + {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 1, focusTo: 0 } |
1731 | ] |
1732 | } |
1733 | |
1734 | @@ -214,12 +239,16 @@ |
1735 | var fromAppDecoration = findChild(desktopStage, "appWindowDecoration_" + data.apps[data.focusfrom]); |
1736 | verify(fromAppDecoration); |
1737 | tap(fromAppDecoration); |
1738 | - tryCompare(ApplicationManager.findApplication(data.apps[data.focusfrom]).session.surface, "activeFocus", true); |
1739 | + var fromApp = ApplicationManager.findApplication(data.apps[data.focusfrom]); |
1740 | + verify(fromApp); |
1741 | + tryCompare(fromApp.session.surface, "activeFocus", true); |
1742 | |
1743 | var toAppDecoration = findChild(desktopStage, "appWindowDecoration_" + data.apps[data.focusTo]); |
1744 | verify(toAppDecoration); |
1745 | tap(toAppDecoration); |
1746 | - tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true); |
1747 | + var toApp = ApplicationManager.findApplication(data.apps[data.focusTo]); |
1748 | + verify(toApp); |
1749 | + tryCompare(toApp.session.surface, "activeFocus", true); |
1750 | } |
1751 | |
1752 | function test_clickingOnDecorationFocusesApplication_data() { |
1753 | @@ -339,26 +368,26 @@ |
1754 | function test_maximizeApplicationHidesSurfacesBehindIt() { |
1755 | var dashApp = startApplication("unity8-dash"); |
1756 | var dialerApp = startApplication("dialer-app"); |
1757 | - var cameraApp = startApplication("camera-app"); |
1758 | + var gmailApp = startApplication("gmail-webapp"); |
1759 | |
1760 | var dashDelegate = findChild(desktopStage, "appDelegate_unity8-dash"); |
1761 | verify(dashDelegate); |
1762 | var dialerDelegate = findChild(desktopStage, "appDelegate_dialer-app"); |
1763 | verify(dialerDelegate); |
1764 | - var cameraDelegate = findChild(desktopStage, "appDelegate_camera-app"); |
1765 | - verify(cameraDelegate); |
1766 | + var gmailDelegate = findChild(desktopStage, "appDelegate_gmail-webapp"); |
1767 | + verify(gmailDelegate); |
1768 | |
1769 | // maximize |
1770 | - findChild(dialerDelegate, "decoratedWindow").maximize(); |
1771 | + dialerDelegate.maximize(); |
1772 | tryCompare(dialerDelegate, "visuallyMaximized", true); |
1773 | |
1774 | tryCompare(dashApp.session.surface, "visible", false); |
1775 | - compare(cameraApp.session.surface.visible, true); |
1776 | + compare(gmailApp.session.surface.visible, true); |
1777 | |
1778 | // restore |
1779 | - findChild(dialerDelegate, "decoratedWindow").maximize(); |
1780 | + dialerDelegate.restoreFromMaximized(); |
1781 | compare(dashApp.session.surface.visible, true); |
1782 | - compare(cameraApp.session.surface.visible, true); |
1783 | + compare(gmailApp.session.surface.visible, true); |
1784 | } |
1785 | |
1786 | function test_applicationsBecomeVisibleWhenOccludingAppRemoved() { |
1787 | @@ -370,28 +399,52 @@ |
1788 | var dialerDelegate = findChild(desktopStage, "appDelegate_dialer-app"); |
1789 | verify(dialerDelegate); |
1790 | |
1791 | - var cameraApp = startApplication("camera-app"); |
1792 | - var cameraDelegate = findChild(desktopStage, "appDelegate_camera-app"); |
1793 | - verify(cameraDelegate); |
1794 | - findChild(dialerDelegate, "decoratedWindow").maximize(); |
1795 | - |
1796 | - var galleryApp = startApplication("gallery-app"); |
1797 | - var galleryDelegate = findChild(desktopStage, "appDelegate_gallery-app"); |
1798 | - verify(galleryDelegate); |
1799 | - findChild(galleryDelegate, "decoratedWindow").maximize(); |
1800 | + var dialerMaximizeButton = findChild(dialerDelegate, "maximizeWindowButton"); |
1801 | + verify(dialerMaximizeButton); |
1802 | + mouseClick(dialerMaximizeButton); |
1803 | + |
1804 | + var mapApp = startApplication("map"); |
1805 | + var mapDelegate = findChild(desktopStage, "appDelegate_map"); |
1806 | + verify(mapDelegate); |
1807 | + |
1808 | + var gmailApp = startApplication("gmail-webapp"); |
1809 | + var gmailDelegate = findChild(desktopStage, "appDelegate_gmail-webapp"); |
1810 | + verify(gmailDelegate); |
1811 | + |
1812 | + var gmailMaximizeButton = findChild(gmailDelegate, "maximizeWindowButton"); |
1813 | + verify(gmailMaximizeButton); |
1814 | + mouseClick(gmailMaximizeButton); |
1815 | |
1816 | tryCompare(dialerDelegate, "visuallyMaximized", true); |
1817 | - tryCompare(galleryDelegate, "visuallyMaximized", true); |
1818 | + tryCompare(gmailDelegate, "visuallyMaximized", true); |
1819 | |
1820 | tryCompare(dashApp.session.surface, "visible", false); |
1821 | tryCompare(dialerApp.session.surface, "visible", false); |
1822 | - tryCompare(cameraApp.session.surface, "visible", false); |
1823 | - |
1824 | - ApplicationManager.stopApplication("gallery-app"); |
1825 | - |
1826 | - compare(cameraApp.session.surface.visible, true); |
1827 | + tryCompare(mapApp.session.surface, "visible", false); |
1828 | + |
1829 | + ApplicationManager.stopApplication("gmail-webapp"); |
1830 | + |
1831 | + compare(mapApp.session.surface.visible, true); |
1832 | tryCompare(dialerApp.session.surface, "visible", true); |
1833 | tryCompare(dashApp.session.surface, "visible", false); // still occluded by maximised dialer |
1834 | } |
1835 | + |
1836 | + function test_maximisedAppStaysVisibleWhenAppStarts() { |
1837 | + var dashApp = startApplication("unity8-dash"); |
1838 | + var dashDelegate = findChild(desktopStage, "appDelegate_unity8-dash"); |
1839 | + verify(dashDelegate); |
1840 | + // maximize |
1841 | + var dashMaximizeButton = findChild(dashDelegate, "maximizeWindowButton"); |
1842 | + verify(dashMaximizeButton); |
1843 | + mouseClick(dashMaximizeButton); |
1844 | + tryCompare(dashDelegate, "visuallyMaximized", true); |
1845 | + |
1846 | + var dialerApp = startApplication("dialer-app"); |
1847 | + var dialerDelegate = findChild(desktopStage, "appDelegate_dialer-app"); |
1848 | + verify(dialerDelegate); |
1849 | + |
1850 | + compare(dialerDelegate.visible, true, "Dialer should be visible"); |
1851 | + compare(dashDelegate.visible, true, "Dash should still be visible"); |
1852 | + } |
1853 | } |
1854 | } |
1855 | |
1856 | === modified file 'tests/qmltests/Stages/tst_WindowResizeArea.qml' |
1857 | --- tests/qmltests/Stages/tst_WindowResizeArea.qml 2015-11-09 10:16:18 +0000 |
1858 | +++ tests/qmltests/Stages/tst_WindowResizeArea.qml 2015-11-23 13:54:01 +0000 |
1859 | @@ -30,8 +30,6 @@ |
1860 | height: units.gu(60) |
1861 | width: units.gu(60) |
1862 | |
1863 | - property var fakeWindow: windowLoader.item |
1864 | - |
1865 | Binding { |
1866 | target: PanelState |
1867 | property: "panelHeight" |
1868 | @@ -47,10 +45,10 @@ |
1869 | property alias minHeight: windowResizeArea.minHeight |
1870 | x: units.gu(20) |
1871 | y: units.gu(20) |
1872 | - height: units.gu(20) |
1873 | - width: units.gu(20) |
1874 | - property int windowHeight: height |
1875 | - property int windowWidth: width |
1876 | + width: requestedWidth |
1877 | + height: requestedHeight |
1878 | + property real requestedWidth |
1879 | + property real requestedHeight |
1880 | state: "normal" |
1881 | |
1882 | function maximize() { |
1883 | @@ -63,6 +61,8 @@ |
1884 | borderThickness: units.gu(2) |
1885 | minWidth: units.gu(15) |
1886 | minHeight: units.gu(10) |
1887 | + defaultWidth: units.gu(20) |
1888 | + defaultHeight: units.gu(20) |
1889 | windowId: "test-window-id" |
1890 | screenWidth: root.width |
1891 | screenHeight: root.height |
1892 | @@ -87,22 +87,41 @@ |
1893 | Loader { |
1894 | id: windowLoader |
1895 | sourceComponent: fakeWindowComponent |
1896 | + active: windowLoaderCheckbox.checked |
1897 | } |
1898 | |
1899 | - MouseTouchEmulationCheckbox { |
1900 | - checked: false |
1901 | - color: "black" |
1902 | + Column { |
1903 | + MouseTouchEmulationCheckbox { |
1904 | + checked: false |
1905 | + color: "black" |
1906 | + } |
1907 | + RowLayout { |
1908 | + Layout.fillWidth: true |
1909 | + CheckBox { |
1910 | + id: windowLoaderCheckbox |
1911 | + checked: true |
1912 | + activeFocusOnPress: false |
1913 | + } |
1914 | + Label { |
1915 | + id: label |
1916 | + color: "black" |
1917 | + text: "Window loader active" |
1918 | + anchors.verticalCenter: parent.verticalCenter |
1919 | + } |
1920 | + } |
1921 | } |
1922 | |
1923 | UnityTestCase { |
1924 | name: "WindowResizeArea" |
1925 | when: windowShown |
1926 | |
1927 | + property var fakeWindow: windowLoader.item |
1928 | + |
1929 | function init() { |
1930 | fakeWindow.x = units.gu(20) |
1931 | fakeWindow.y = units.gu(20) |
1932 | - fakeWindow.width = units.gu(20) |
1933 | - fakeWindow.height = units.gu(20) |
1934 | + fakeWindow.requestedWidth = units.gu(20) |
1935 | + fakeWindow.requestedHeight = units.gu(20) |
1936 | } |
1937 | |
1938 | function test_resizeWindowRightBottom_data() { |
1939 | @@ -188,7 +207,7 @@ |
1940 | function test_resizeSmallerAndLarger_data() { |
1941 | return [ |
1942 | { tag: "topLeft", startX: -1, startY: -1, dx: units.gu(15), dy: units.gu(15) }, |
1943 | - { tag: "bottomRight", startX: fakeWindow.width + 1, startY: fakeWindow.height + 1, dx: -units.gu(15), dy: -units.gu(15) } |
1944 | + { tag: "bottomRight", startX: units.gu(20) + 1, startY: units.gu(20) + 1, dx: -units.gu(15), dy: -units.gu(15) } |
1945 | ] |
1946 | } |
1947 | |
1948 | |
1949 | === modified file 'tests/qmltests/tst_Shell.qml' |
1950 | --- tests/qmltests/tst_Shell.qml 2015-11-12 20:40:49 +0000 |
1951 | +++ tests/qmltests/tst_Shell.qml 2015-11-23 13:54:01 +0000 |
1952 | @@ -1777,15 +1777,10 @@ |
1953 | tryCompare(panelButtons, "visible", false); |
1954 | |
1955 | appDelegate.maximize(false); |
1956 | - tryCompare(panelButtons, "visible", true); |
1957 | |
1958 | shell.usageScenario = "phone"; |
1959 | waitForRendering(shell); |
1960 | tryCompare(panelButtons, "visible", false); |
1961 | - |
1962 | - shell.usageScenario = "desktop"; |
1963 | - waitForRendering(shell); |
1964 | - tryCompare(panelButtons, "visible", true); |
1965 | } |
1966 | |
1967 | function test_lockingGreeterHidesPanelButtons() { |
1968 | @@ -1799,15 +1794,10 @@ |
1969 | tryCompare(panelButtons, "visible", false); |
1970 | |
1971 | appDelegate.maximize(false); |
1972 | - tryCompare(panelButtons, "visible", true); |
1973 | |
1974 | LightDM.Greeter.showGreeter(); |
1975 | waitForRendering(shell); |
1976 | tryCompare(panelButtons, "visible", false); |
1977 | - |
1978 | - LightDM.Greeter.hideGreeter(); |
1979 | - waitForRendering(shell); |
1980 | - tryCompare(panelButtons, "visible", true); |
1981 | } |
1982 | |
1983 | function test_cantMoveWindowUnderPanel() { |
Text conflict in qml/Components/ WindowControlBu ttons.qml DecoratedWindow .qml DesktopStage. qml Stages/ tst_DesktopStag e.qml
Text conflict in qml/Panel/Panel.qml
Text conflict in qml/Stages/
Text conflict in qml/Stages/
Text conflict in tests/qmltests/
5 conflicts encountered.