Merge lp:~dandrader/unity8/mouseEdgePush into lp:unity8
- mouseEdgePush
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~dandrader/unity8/mouseEdgePush |
Merge into: | lp:unity8 |
Prerequisite: | lp:~dandrader/unity8/cursorStartup |
Diff against target: |
2832 lines (+1243/-372) 40 files modified
data/com.canonical.Unity8.gschema.xml (+16/-0) plugins/Cursor/MousePointer.cpp (+2/-0) plugins/Cursor/MousePointer.h (+4/-0) plugins/Utils/EdgeBarrierSettings.qml (+66/-0) plugins/Utils/qmldir (+1/-0) qml/Components/EdgeBarrier.qml (+111/-0) qml/Components/EdgeBarrierController.qml (+71/-0) 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/Launcher/Launcher.qml (+30/-32) qml/Launcher/LauncherPanel.qml (+7/-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/Shell.qml (+13/-0) qml/Stages/ApplicationWindow.qml (+29/-3) qml/Stages/DecoratedWindow.qml (+24/-16) qml/Stages/DesktopSpread.qml (+5/-19) qml/Stages/DesktopStage.qml (+107/-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/Cursor/Cursor.qml (+2/-0) tests/mocks/Unity/Application/MirSurface.cpp (+52/-0) tests/mocks/Unity/Application/MirSurface.h (+16/-0) tests/mocks/Utils/EdgeBarrierSettings.qml (+22/-0) tests/mocks/Utils/qmldir (+1/-0) tests/qmltests/EdgeBarrierControls.qml (+97/-0) tests/qmltests/Launcher/tst_Launcher.qml (+15/-5) tests/qmltests/Panel/tst_Panel.qml (+45/-11) tests/qmltests/Stages/tst_DesktopStage.qml (+96/-31) tests/qmltests/Stages/tst_WindowResizeArea.qml (+31/-12) tests/qmltests/tst_Shell.qml (+17/-12) |
To merge this branch: | bzr merge lp:~dandrader/unity8/mouseEdgePush |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Zanetti (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Albert Astals Cid (community) | merges fine | Abstain | |
Review via email: mp+276306@code.launchpad.net |
This proposal has been superseded by a proposal from 2015-11-24.
Commit message
Mouse has to push against edges to show launcher or apps spread
edge-barrier-
edge-barrier-
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* 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?
Not applicable
* If you changed the UI, has there been a design review?
John Lea tried it out. Values for the edge barrier parameters are still preliminary. Proper values will come once we have configurable mouse pointer speed and, most importantly, mouse pointer acceleration.
The graphical effect is following the design specification.
PS Jenkins bot (ps-jenkins) wrote : | # |
Albert Astals Cid (aacid) wrote : | # |
There's a few qmluitests that fail to compile
Daniel d'Andrada (dandrader) wrote : | # |
> There's a few qmluitests that fail to compile
Fixed.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2022
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://
- 2022. By Daniel d'Andrada
-
Use SDK 1.3 across all files Fixes: #1449628, #1503498, #1508363
Approved by: PS Jenkins bot - 2023. By Andrea Cimitan
-
Updated all 1.3 UbuntuShape to use new APIs where possible
Approved by: Albert Astals Cid - 2024. By Andrea Cimitan
-
Make zoomable and video playback widgets edge to edge
Approved by: Albert Astals Cid - 2025. By Andrea Cimitan
-
Add sharing widget to zoomable image and video playback
Approved by: Albert Astals Cid, Pawel Stolowski - 2026. By Albert Astals Cid
-
Make the scope settings list scroll to text visible area
Fixes: #1499084
Approved by: Michael Terry - 2027. By Albert Astals Cid
-
Move to importing QtQuick 2.4 & friends
This means we obviously require Qt 5.4 or greater, we had for a while
but make it official now
Approved by: Michael Terry - 2028. By Albert Astals Cid
-
Add an Item that proxies for old and new audio roles Fixes: #1493851
- 2029. By Michael Zanetti
-
Fixes for the panel buttons
* Hide panel buttons when switching to staged mode
* properly save/restore window states, not just geometry Fixes: #1431566, #1443319, #1504269, #1510360
Approved by: Lukáš Tinkl - 2030. By Michał Sawicz
-
Enable support for overriding application orientations based on device type Fixes: #1478637
- 2031. By Michael Terry
-
Handle lifecycle policy exceptions ourselves, instead of letting qtmir do it for us and allow non-Touch apps to opt-out of the Touch lifecycle.
This requires using the new isTouchApp unity-api property to ApplicationInfo
Interface. Now that qtmir won't decide policy for suspending exemptions anymore, we take over the interpretation of the lifecycleException GSettings key. Since the GSettings key for that was registered under the qtmir namespace (and there's no technical reason to migrate settings), I left the schema in qtmir itself. We merely consume it.
- 2032. By Michał Sawicz
-
Support server->client visibility change to stop rendering (lp:#1475678) Fixes: #1475678
Approved by: Daniel d'Andrada - 2033. By Christopher Lee
-
Quick spelling fix in process control output.
Approved by: Albert Astals Cid - 2034. By Albert Astals Cid
-
CroppedImageMin
imumSourceSize: Fix 'Binding loop detected for property "imageAspectRatio"' Approved by: Gerry Boland, Michał Sawicz
- 2035. By Michael Terry
-
Avoid showing the shutdown dialog when turning on the screen if your device is under heavy load.
Specifically, we actually watch the timestamp of input events as they come in to determine how long it's been. This means that if for whatever reason, processing of events get delayed, we don't misinterpret user input.
To test this, try running the following command and then turning the screen on and off again:
sudo cpulimit -l 1 -c 1 -p `ps ax | grep dbus-daemon | head -n 1 | awk '{print $1;}'`Without this branch, you'll notice that at some point, you see the shutdown dialog in error. Because unity8 couldn't keep up with events and thought 2s passed between power-pressed and power-released events.
But if we watch the timestamps, we can avoid that particular fate. Fixes: #1508563
Approved by: Albert Astals Cid, Michael Zanetti - 2036. By CI Train Bot Account
-
Releasing 8.11+16.
04.20151104- 0ubuntu1
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2023
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:2026
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://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Text conflict in tests/qmltests/
1 conflicts encountered.
Michael Zanetti (mzanetti) wrote : | # |
Hmm... curious why we need 3 settings for this. Wouldn't one be enough? For instance, sensitivity, going from 0 to 100, which defines the grid units to be pushed... You probably do have a reason for this, what is it?
========
The shadow on the right edge looks very wrong. And I have a feeling it's too strong on the left edge too. You sure someone from design saw this? I know John didn't so far.
====
+ anchors.top: {
+ if (edge == Qt.LeftEdge || edge == Qt.RightEdge) {
+ return target.top;
+ } else {
+ return undefined;
+ }
+ }
writing this like this:
anchors.top: edge == Qt.LeftEdge || edge == Qt.RightEdge ? target.top : undefined
is quite a bit faster in evaluating. You should avoid adding JS blocks for bindings unless the other approach really ends up being unreadable.
======
+ // to be overwritten by tests
+ property bool _containsMouse: root.containsMouse
I'm starting to think you are mocking too much. Instead of all that logic with _containsMouse, wouldn't it be nicer to just use the standard containsMouse and in the test just do a mouseMove to fulfill that?
====
+ property real _defaultMinPush
+ property real _minPushThreshold:
+ property real _maxPushThreshold:
+ property real _accumulatedPush:
instead of all those _properties everywhere, didn't we agree to put them into private objects instead?
====
I feel like EdgeBarrierSettings isn't needed at all. The tiny bit of logic could happen in EdgeBarrier.qml too, and for mocking the settings, we already have a fully mocked GSettings backend in tests/mocks/
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 09:48, Michael Zanetti wrote:
> Review: Needs Fixing
>
> Hmm... curious why we need 3 settings for this. Wouldn't one be enough? For instance, sensitivity, going from 0 to 100, which defines the grid units to be pushed... You probably do have a reason for this, what is it?
>
It's explained in the commit message
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 09:48, Michael Zanetti wrote:
> + // to be overwritten by tests
> + property bool _containsMouse: root.containsMouse
>
> I'm starting to think you are mocking too much. Instead of all that logic with _containsMouse, wouldn't it be nicer to just use the standard containsMouse and in the test just do a mouseMove to fulfill that?
I've to mock this in order to *manually* test edge barriers. Can't do
otherwise. See EdgeBarrierCont
The automated tests do not overwrite this property and do the
mouseMove() just like you mentioned.
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 09:48, Michael Zanetti wrote:
> I feel like EdgeBarrierSettings isn't needed at all. The tiny bit of logic could happen in EdgeBarrier.qml too, and for mocking the settings, we already have a fully mocked GSettings backend in tests/mocks/
This is to avoid doing the same work several times. This settings stuff
is a singleton and thus is calculated/
can save several EdgeBarrier instances. So yes, we don't *need* to have
it separate, but it is more efficient that way.
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 09:48, Michael Zanetti wrote:
> The shadow on the right edge looks very wrong. And I have a feeling it's too strong on the left edge too. You sure someone from design saw this? I know John didn't so far.
The right edge and left edge shadows are the very same, just mirrored.
John Lea saw that (as I commented on the merge description). It puzzles
me to heard you say he did not...
By "wrong" you mean they're too opaque? Let's talk over IRC
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 08:09, Albert Astals Cid wrote:
> Text conflict in tests/qmltests/
> 1 conflicts encountered.
Fixed, thanks.
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 09:48, Michael Zanetti wrote:
> + property real _defaultMinPush
> + property real _minPushThreshold:
> + property real _maxPushThreshold:
> + property real _accumulatedPush:
>
> instead of all those _properties everywhere, didn't we agree to put them into private objects instead?
Done.
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 09:48, Michael Zanetti wrote:
> writing this like this:
>
> anchors.top: edge == Qt.LeftEdge || edge == Qt.RightEdge ? target.top : undefined
>
> is quite a bit faster in evaluating. You should avoid adding JS blocks for bindings unless the other approach really ends up being unreadable.
Isn't that Javascript all the same, but just in a more concise notation?
Michael Zanetti (mzanetti) wrote : | # |
On 06.11.2015 14:12, Daniel d'Andrada wrote:
> On 06/11/2015 09:48, Michael Zanetti wrote:
>> writing this like this:
>>
>> anchors.top: edge == Qt.LeftEdge || edge == Qt.RightEdge ? target.top : undefined
>>
>> is quite a bit faster in evaluating. You should avoid adding JS blocks for bindings unless the other approach really ends up being unreadable.
>
> Isn't that Javascript all the same, but just in a more concise notation?
>
From http://
"There are two types of bindings in QML: optimized and non-optimized
bindings.
...
Things to avoid in binding expressions to maximize optimizability:
...
* constructing closures or defining functions within the binding expression"
If I understand that correctly, adding {} already breaks some optimizations.
Daniel d'Andrada (dandrader) wrote : | # |
On 06/11/2015 11:30, Michael Zanetti wrote:
>
> On 06.11.2015 14:12, Daniel d'Andrada wrote:
>> On 06/11/2015 09:48, Michael Zanetti wrote:
>>> writing this like this:
>>>
>>> anchors.top: edge == Qt.LeftEdge || edge == Qt.RightEdge ? target.top : undefined
>>>
>>> is quite a bit faster in evaluating. You should avoid adding JS blocks for bindings unless the other approach really ends up being unreadable.
>> Isn't that Javascript all the same, but just in a more concise notation?
>>
> >From http://
>
> "There are two types of bindings in QML: optimized and non-optimized
> bindings.
> ...
> Things to avoid in binding expressions to maximize optimizability:
> ...
> * constructing closures or defining functions within the binding expression"
>
> If I understand that correctly, adding {} already breaks some optimizations.
>
>
I think "{}" is a way of making scope explicit, not defining a closure
nor an internal function.
But thanks for the link. Bookmarked it. And as I said in a previous
comment, I made the change anyway as it does make the code cleaner
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2027
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: 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://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2029
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: 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://
- 2039. By Launchpad Translations on behalf of unity-team
-
Launchpad automatic translations update.
- 2040. By Michael Terry
-
Make a few DBus calls asynchronous, for a smoother UX.
The calls I've changed here are neither hugely important nor frequent calls. But every little bit helps.
- Made a few sync calls async.
- Made a few sync calls more obviously sync. We had several instances of asyncCall()'s return value -- a QDBusPendingReply -- being assigned to a QDBusReply variable, which makes it wait for the call to finish. In cases where it didn't make sense to rewrite logic to be async, I've merely changed the method to be call() instead of asyncCall() for clarity.
- I removed the API in our AccountsService plugin for even making sync calls. This won't stop future developers from from writing sync code, but might give them pause.
- I removed some test mocks for our AccountsService plugin interface and changed those tests to use our actual AS plugin against a mock AS server. In truth, this change was because I had a devil of a time crafting a fake reply that included a custom complex type. But it's a good change anyway. Exercises more of our code in tests and reduces duplicated interfaces.
Approved by: Albert Astals Cid - 2041. By Daniel d'Andrada
-
Cursor: properly initialize hotspot position Fixes: #1510407
Approved by: Gerry Boland - 2042. By Albert Astals Cid
-
Warn we're using only the cache when not connected to the interwebs
Approved by: Michael Terry
- 2043. By Michael Zanetti
-
added icon for the dash Fixes: #1488146
Approved by: Albert Astals Cid, Lukáš Tinkl - 2044. By Daniel d'Andrada
-
Update GSettings mock in tst_OrientedShell
Gets rid of the following warning:
OrientedShell.qml:76: Error: Cannot assign to non-existent property "disableHeight"
Approved by: Albert Astals Cid - 2045. By Andrea Cimitan
-
Add sharing widget to zoomable image and video playback
Approved by: Albert Astals Cid, Pawel Stolowski - 2046. By Lukáš Tinkl
-
Restore windows when activating from the spread, maintain a focus stack
Stop displaying the "grabbing" icon when we merely click to focus the app's decoration.
Provide keyboard shortcuts for common window operations
Approved by: Michael Zanetti - 2047. By Michael Zanetti
-
prevent windows to be moved under the panel
If they happen to have a saved state which is under the panel
(might happen on alt+drag later), they will be moved below the panel
on close and reopen. This is how unity7 behaves in this regard. Fixes: #1438465
Approved by: Lukáš Tinkl - 2048. By Michael Zanetti
-
use UbuntuNumberAni
mations instead of linear ones for window state transitions Fixes: #1497097
Approved by: Lukáš Tinkl - 2049. By Albert Astals Cid
-
Make cardWidth and cardHeight real
If they are var the properties depending on them get reevaluated even if they don't change
Approved by: Michael Zanetti - 2050. By Michael Zanetti
-
update inputinfo api to the latest upstream snapshot
* Import latest update of api from gerrit.
* drop all the old mock code
* instead of mocking the whole api, add mocks for the backend only. This should simplify future updates and moving to upstream implementation a lot.
* update tests to use new mocking system
Approved by: Lukáš Tinkl - 2051. By Michael Zanetti
-
Add a warning dialog when disconnecting the external monitor.
In case there are still legacy apps running, the dialog forces the user to reconnect the external monitor, or close all the legacy apps.
Approved by: Daniel d'Andrada - 2052. By Albert Astals Cid
-
Reset instead of qFatal when removing things from the middle
This can be optimized but let's see how this behaves, at least we won't qFatal anymore :D Fixes: #1238979
Approved by: Andrea Cimitan - 2053. By CI Train Bot Account
-
Releasing 8.11+16.
04.20151112. 1-0ubuntu1
Daniel d'Andrada (dandrader) wrote : | # |
Updated according to design spec.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2031
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: 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://
- 2054. By CI Train Bot Account
-
Resync trunk.
Albert Astals Cid (aacid) wrote : | # |
Text conflict in qml/Stages/
Text conflict in tests/qmltests/
Text conflict in tests/qmltests/
3 conflicts encountered.
Daniel d'Andrada (dandrader) wrote : | # |
> Text conflict in qml/Stages/
> Text conflict in tests/qmltests/
> Text conflict in tests/qmltests/
> 3 conflicts encountered.
Fixed.
Albert Astals Cid (aacid) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2055
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: 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://
Michael Zanetti (mzanetti) wrote : | # |
The jenkins test failure seems a real one. also, trying to run this on my laptop I get:
file://
Shell {
^
file://
^
file://
^
file://
^
file://
file://
property QtObject private: QtObject {
Daniel d'Andrada (dandrader) wrote : | # |
> The jenkins test failure seems a real one. also, trying to run this on my
> laptop I get:
> [...]
Fixed.
Also fixed the problem in tst_Shell.qml
Michael Zanetti (mzanetti) wrote : | # |
I'm still not 100% satisfied with the visuals. But I understand it's a lot of fiddling to tweak that further. I'm okay with doing that in a future branch. Let's land it.
All my other review comments have been addressed, so
* Did you perform an exploratory manual test run of the code change and any related functionality?
yes
* Did CI run pass? If not, please explain why.
not yet, but issue has been fixed, let's see if next run passes.
* Did you make sure that the branch does not contain spurious tags?
yes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2056
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://
Michael Zanetti (mzanetti) wrote : | # |
I'm afraid at least some of the autopilot failures are related to the changes here. At least they passed today already on another branch (e.g. https:/
Can you please check them
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2057
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://
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://
Michael Zanetti (mzanetti) wrote : | # |
ok... seems that was a stale run above. jenkins looks ok now.
* Did you perform an exploratory manual test run of the code change and any related functionality?
yes
* Did CI run pass? If not, please explain why.
on v+o it did, yes. x AP tests still busted.
* Did you make sure that the branch does not contain spurious tags?
yes
- 2057. By Daniel d'Andrada
- 2058. By Daniel d'Andrada
- 2059. By Daniel d'Andrada
-
Mouse has to push against edges to show launcher or apps spread
edge-barrier-
sensitivity is the property that should show up in the System Settings GUI. edge-barrier-
min-push and edge-barrier- max-push are exposed in GSettings merely as a
convenience so you can tweak those values without having to restart unity8. But they
should NOT show up in system settings. - 2060. By Daniel d'Andrada
-
Merge lp:~lukas-kde/unity8/newWindowDecosAndPanel again
Unmerged revisions
Preview Diff
1 | === modified file 'data/com.canonical.Unity8.gschema.xml' |
2 | --- data/com.canonical.Unity8.gschema.xml 2015-08-19 21:45:40 +0000 |
3 | +++ data/com.canonical.Unity8.gschema.xml 2015-11-24 17:51:40 +0000 |
4 | @@ -11,6 +11,22 @@ |
5 | <summary>The usage mode.</summary> |
6 | <description>The usage mode chosen will affect the Window Management behaviour.</description> |
7 | </key> |
8 | + <key type="y" name="edge-barrier-sensitivity"> |
9 | + <default>35</default> |
10 | + <range min="1" max="100"/> |
11 | + <summary>Sensitivity of screen edge barriers for the mouse pointer.</summary> |
12 | + <description>Some UI actions like revealing the launcher or the applications spread are triggered by pushing the mouse pointer against a screen edge. This key defines how much you have to push in order to trigger the associated action.</description> |
13 | + </key> |
14 | + <key type="u" name="edge-barrier-min-push"> |
15 | + <default>2</default> |
16 | + <summary>Minimum push needed to overcome edge barrier</summary> |
17 | + <description>How much you have to push (in grid units)the mouse against an edge barrier when sensibility is 100.</description> |
18 | + </key> |
19 | + <key type="u" name="edge-barrier-max-push"> |
20 | + <default>60</default> |
21 | + <summary>Maximum push needed to overcome edge barrier</summary> |
22 | + <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description> |
23 | + </key> |
24 | </schema> |
25 | |
26 | <schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8"> |
27 | |
28 | === modified file 'plugins/Cursor/MousePointer.cpp' |
29 | --- plugins/Cursor/MousePointer.cpp 2015-11-12 20:39:12 +0000 |
30 | +++ plugins/Cursor/MousePointer.cpp 2015-11-24 17:51:40 +0000 |
31 | @@ -44,8 +44,10 @@ |
32 | |
33 | qreal newX = x() + movement.x(); |
34 | if (newX < 0) { |
35 | + Q_EMIT pushedLeftBoundary(qAbs(newX), buttons); |
36 | newX = 0; |
37 | } else if (newX > parentItem()->width()) { |
38 | + Q_EMIT pushedRightBoundary(newX - parentItem()->width(), buttons); |
39 | newX = parentItem()->width(); |
40 | } |
41 | setX(newX); |
42 | |
43 | === modified file 'plugins/Cursor/MousePointer.h' |
44 | --- plugins/Cursor/MousePointer.h 2015-10-21 16:16:37 +0000 |
45 | +++ plugins/Cursor/MousePointer.h 2015-11-24 17:51:40 +0000 |
46 | @@ -42,6 +42,10 @@ |
47 | void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons, |
48 | Qt::KeyboardModifiers modifiers) override; |
49 | |
50 | +Q_SIGNALS: |
51 | + void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons); |
52 | + void pushedRightBoundary(qreal amount, Qt::MouseButtons buttons); |
53 | + |
54 | protected: |
55 | void itemChange(ItemChange change, const ItemChangeData &value) override; |
56 | |
57 | |
58 | === added file 'plugins/Utils/EdgeBarrierSettings.qml' |
59 | --- plugins/Utils/EdgeBarrierSettings.qml 1970-01-01 00:00:00 +0000 |
60 | +++ plugins/Utils/EdgeBarrierSettings.qml 2015-11-24 17:51:40 +0000 |
61 | @@ -0,0 +1,66 @@ |
62 | +/* |
63 | + * Copyright (C) 2015 Canonical, Ltd. |
64 | + * |
65 | + * This program is free software; you can redistribute it and/or modify |
66 | + * it under the terms of the GNU General Public License as published by |
67 | + * the Free Software Foundation; version 3. |
68 | + * |
69 | + * This program is distributed in the hope that it will be useful, |
70 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
71 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72 | + * GNU General Public License for more details. |
73 | + * |
74 | + * You should have received a copy of the GNU General Public License |
75 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
76 | + */ |
77 | + |
78 | +pragma Singleton |
79 | +import QtQuick 2.4 |
80 | +import GSettings 1.0 |
81 | + |
82 | +QtObject { |
83 | + id: root |
84 | + |
85 | + // The only public property |
86 | + readonly property real pushThreshold: |
87 | + d.minPushThreshold + ((d.maxPushThreshold - d.minPushThreshold) * (1.0 - d.sensitivity)) |
88 | + |
89 | + onPushThresholdChanged: { |
90 | + // Avoid calling d.printSettings() directly as it would spam the console during initialization |
91 | + d.printSettingsTimer.start(); |
92 | + } |
93 | + |
94 | + property QtObject priv: QtObject { |
95 | + id: d |
96 | + |
97 | + property Timer printSettingsTimer: Timer { |
98 | + interval: 1 |
99 | + onTriggered: printSettings(); |
100 | + } |
101 | + function printSettings() { |
102 | + console.log("EdgeBarrierSettings: min="+(minPushThreshold/units.gu(1))+"gu("+minPushThreshold+"px)" |
103 | + +", max="+(maxPushThreshold/units.gu(1))+"gu("+maxPushThreshold+"px)" |
104 | + +", sensitivity="+sensitivity |
105 | + +", threshold="+(pushThreshold/units.gu(1))+"gu("+pushThreshold+"px)" |
106 | + ); |
107 | + } |
108 | + |
109 | + property real defaultMinPushThreshold: units.gu(2) |
110 | + property real minPushThreshold: gsettings.edgeBarrierMinPush ? units.gu(gsettings.edgeBarrierMinPush) : defaultMinPushThreshold |
111 | + property real maxPushThreshold: { |
112 | + if (gsettings.edgeBarrierMaxPush && units.gu(gsettings.edgeBarrierMaxPush) > minPushThreshold) { |
113 | + return units.gu(gsettings.edgeBarrierMaxPush); |
114 | + } else if (minPushThreshold == defaultMinPushThreshold) { |
115 | + return units.gu(60); |
116 | + } else { |
117 | + return minPushThreshold * 10.0; |
118 | + } |
119 | + } |
120 | + // Value range is [0.0, 1.0] |
121 | + readonly property real sensitivity: gsettings.edgeBarrierSensitivity |
122 | + ? Math.min(Math.max(0, gsettings.edgeBarrierSensitivity), 100) / 100 |
123 | + : 0.35 |
124 | + |
125 | + property var gsettings: GSettings { schema.id: "com.canonical.Unity8" } |
126 | + } |
127 | +} |
128 | |
129 | === modified file 'plugins/Utils/qmldir' |
130 | --- plugins/Utils/qmldir 2014-08-14 11:43:32 +0000 |
131 | +++ plugins/Utils/qmldir 2015-11-24 17:51:40 +0000 |
132 | @@ -2,3 +2,4 @@ |
133 | plugin Utils-qml |
134 | typeinfo Utils.qmltypes |
135 | Style 0.1 Style.js |
136 | +singleton EdgeBarrierSettings 0.1 EdgeBarrierSettings.qml |
137 | |
138 | === added file 'qml/Components/EdgeBarrier.qml' |
139 | --- qml/Components/EdgeBarrier.qml 1970-01-01 00:00:00 +0000 |
140 | +++ qml/Components/EdgeBarrier.qml 2015-11-24 17:51:40 +0000 |
141 | @@ -0,0 +1,111 @@ |
142 | +/* |
143 | + * Copyright (C) 2015 Canonical, Ltd. |
144 | + * |
145 | + * This program is free software; you can redistribute it and/or modify |
146 | + * it under the terms of the GNU General Public License as published by |
147 | + * the Free Software Foundation; version 3. |
148 | + * |
149 | + * This program is distributed in the hope that it will be useful, |
150 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
151 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
152 | + * GNU General Public License for more details. |
153 | + * |
154 | + * You should have received a copy of the GNU General Public License |
155 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
156 | + */ |
157 | + |
158 | +import QtQuick 2.4 |
159 | +import Ubuntu.Components 1.3 |
160 | + |
161 | +/* |
162 | + An edge barrier for the mouse pointer |
163 | + |
164 | + The further you push against it, the stronger the visual hint. Until it's |
165 | + overcome, when passed() is emitted. |
166 | + */ |
167 | +Item { |
168 | + id: root |
169 | + |
170 | + // Supported values are: Qt.LeftEdge, Qt.RightEdge |
171 | + property int edge: Qt.LeftEdge |
172 | + |
173 | + property Item target: parent |
174 | + function push(amount) { controller.push(amount); } |
175 | + signal passed() |
176 | + |
177 | + anchors.top: (edge == Qt.LeftEdge || edge == Qt.RightEdge) ? target.top : undefined |
178 | + anchors.bottom: (edge == Qt.LeftEdge || edge == Qt.RightEdge) ? target.bottom : undefined |
179 | + anchors.left: edge == Qt.LeftEdge ? target.left : undefined |
180 | + anchors.right: edge == Qt.RightEdge ? target.right : undefined |
181 | + |
182 | + width: units.gu(0.5) |
183 | + |
184 | + property Component material |
185 | + |
186 | + Loader { |
187 | + id: materialContainer |
188 | + |
189 | + sourceComponent: root.material |
190 | + |
191 | + anchors.top: parent.top |
192 | + anchors.bottom: parent.bottom |
193 | + anchors.left: root.edge == Qt.LeftEdge ? root.left : undefined |
194 | + anchors.right: root.edge == Qt.RightEdge ? root.right : undefined |
195 | + |
196 | + anchors.leftMargin: root.edge == Qt.LeftEdge ? -width * (1 - positionProgress) : 0 |
197 | + anchors.rightMargin: root.edge == Qt.RightEdge ? -width * (1 - positionProgress) : 0 |
198 | + |
199 | + property real positionProgress |
200 | + |
201 | + visible: positionProgress > 0 |
202 | + |
203 | + width: units.gu(2) |
204 | + } |
205 | + |
206 | + EdgeBarrierController { |
207 | + id: controller |
208 | + objectName: "edgeBarrierController" |
209 | + anchors.fill: parent |
210 | + onPassed: root.passed(); |
211 | + } |
212 | + |
213 | + state: { |
214 | + if (controller.progress === 0.0) { |
215 | + return ""; |
216 | + } else if (controller.progress < 1.0) { |
217 | + return "resisting"; |
218 | + } else { // controller.progress == 1.0 |
219 | + return "passed"; |
220 | + } |
221 | + } |
222 | + states: [ |
223 | + State { |
224 | + name: "" |
225 | + PropertyChanges { target: materialContainer; opacity: 0.0 } |
226 | + PropertyChanges { target: materialContainer; positionProgress: 0.0 } |
227 | + }, |
228 | + State { |
229 | + name: "resisting" |
230 | + PropertyChanges { target: materialContainer; opacity: controller.progress } |
231 | + PropertyChanges { target: materialContainer; positionProgress: controller.progress } |
232 | + }, |
233 | + State { |
234 | + name: "passed" |
235 | + PropertyChanges { target: materialContainer; opacity: 0.0 } |
236 | + PropertyChanges { target: materialContainer; positionProgress: 1.0 } |
237 | + } |
238 | + ] |
239 | + transitions: [ |
240 | + Transition { |
241 | + from: "passed"; to: "" |
242 | + }, |
243 | + Transition { |
244 | + from: "resisting"; to: "" |
245 | + UbuntuNumberAnimation { target: materialContainer; properties: "opacity,positionProgress" } |
246 | + }, |
247 | + Transition { |
248 | + from: "resisting"; to: "passed" |
249 | + UbuntuNumberAnimation { target: materialContainer; property: "opacity" } |
250 | + } |
251 | + ] |
252 | +} |
253 | |
254 | === added file 'qml/Components/EdgeBarrierController.qml' |
255 | --- qml/Components/EdgeBarrierController.qml 1970-01-01 00:00:00 +0000 |
256 | +++ qml/Components/EdgeBarrierController.qml 2015-11-24 17:51:40 +0000 |
257 | @@ -0,0 +1,71 @@ |
258 | +/* |
259 | + * Copyright (C) 2015 Canonical, Ltd. |
260 | + * |
261 | + * This program is free software; you can redistribute it and/or modify |
262 | + * it under the terms of the GNU General Public License as published by |
263 | + * the Free Software Foundation; version 3. |
264 | + * |
265 | + * This program is distributed in the hope that it will be useful, |
266 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
267 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
268 | + * GNU General Public License for more details. |
269 | + * |
270 | + * You should have received a copy of the GNU General Public License |
271 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
272 | + */ |
273 | + |
274 | +import QtQuick 2.4 |
275 | +import Utils 0.1 // For EdgeBarrierSettings |
276 | + |
277 | +MouseArea { |
278 | + id: root |
279 | + |
280 | + hoverEnabled: true |
281 | + |
282 | + // Edge push progress |
283 | + // Value range is [0.0, 1.0] |
284 | + readonly property real progress: Math.min(Math.max(0.0, _accumulatedPush / EdgeBarrierSettings.pushThreshold), 1.0) |
285 | + |
286 | + // Emitted when progress reaches 1.0 |
287 | + // Should trigger the action associated with this edge |
288 | + signal passed() |
289 | + |
290 | + function push(amount) { |
291 | + if (!root._containsMouse) { |
292 | + return; |
293 | + } |
294 | + |
295 | + if (_accumulatedPush === EdgeBarrierSettings.pushThreshold) { |
296 | + // NO-OP |
297 | + return; |
298 | + } |
299 | + |
300 | + if (_accumulatedPush + amount > EdgeBarrierSettings.pushThreshold) { |
301 | + _accumulatedPush = EdgeBarrierSettings.pushThreshold; |
302 | + } else { |
303 | + _accumulatedPush += amount; |
304 | + } |
305 | + |
306 | + if (_accumulatedPush === EdgeBarrierSettings.pushThreshold) { |
307 | + passed(); |
308 | + } |
309 | + } |
310 | + |
311 | + onEnabledChanged: { |
312 | + if (!enabled) { |
313 | + // reset |
314 | + _accumulatedPush = 0; |
315 | + } |
316 | + } |
317 | + |
318 | + // to be overwritten by tests |
319 | + property bool _containsMouse: root.containsMouse |
320 | + on_ContainsMouseChanged: { |
321 | + if (!_containsMouse) { |
322 | + // reset |
323 | + _accumulatedPush = 0; |
324 | + } |
325 | + } |
326 | + |
327 | + property real _accumulatedPush: 0 |
328 | +} |
329 | |
330 | === modified file 'qml/Components/PanelState/PanelState.qml' |
331 | --- qml/Components/PanelState/PanelState.qml 2015-11-09 10:16:18 +0000 |
332 | +++ qml/Components/PanelState/PanelState.qml 2015-11-24 17:51:40 +0000 |
333 | @@ -22,10 +22,11 @@ |
334 | |
335 | property string title: "" |
336 | property bool buttonsVisible: false |
337 | - |
338 | - property int panelHeight: 0 |
339 | + property bool dropShadow: false |
340 | + property int panelHeight: units.gu(3) |
341 | |
342 | signal close() |
343 | signal minimize() |
344 | signal maximize() |
345 | + signal focusMaximizedApp() |
346 | } |
347 | |
348 | === modified file 'qml/Components/WindowControlButtons.qml' |
349 | --- qml/Components/WindowControlButtons.qml 2015-11-04 14:57:33 +0000 |
350 | +++ qml/Components/WindowControlButtons.qml 2015-11-24 17:51:40 +0000 |
351 | @@ -1,5 +1,5 @@ |
352 | /* |
353 | - * Copyright (C) 2014 Canonical, Ltd. |
354 | + * Copyright (C) 2014-2015 Canonical, Ltd. |
355 | * |
356 | * This program is free software; you can redistribute it and/or modify |
357 | * it under the terms of the GNU General Public License as published by |
358 | @@ -12,8 +12,6 @@ |
359 | * |
360 | * You should have received a copy of the GNU General Public License |
361 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
362 | - * |
363 | - * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
364 | */ |
365 | |
366 | import QtQuick 2.4 |
367 | @@ -21,43 +19,90 @@ |
368 | |
369 | Row { |
370 | id: root |
371 | - spacing: units.gu(0.5) |
372 | + spacing: units.gu(1) |
373 | + |
374 | + // to be set from outside |
375 | + property bool active: false |
376 | |
377 | signal close() |
378 | signal minimize() |
379 | signal maximize() |
380 | |
381 | - Rectangle { |
382 | + MouseArea { |
383 | + id: closeWindowButton |
384 | objectName: "closeWindowButton" |
385 | - height: parent.height; width: height; radius: height / 2 |
386 | - gradient: Gradient { |
387 | - GradientStop { color: "#F49073"; position: 0 } |
388 | - GradientStop { color: "#DF4F1C"; position: 1 } |
389 | - } |
390 | - border.width: units.dp(.5) |
391 | - border.color: "black" |
392 | - MouseArea { anchors.fill: parent; onClicked: root.close() } |
393 | + hoverEnabled: true |
394 | + height: parent.height |
395 | + width: height |
396 | + onClicked: root.close() |
397 | + |
398 | + Rectangle { |
399 | + anchors.centerIn: parent |
400 | + width: units.gu(2) |
401 | + height: units.gu(2) |
402 | + radius: height / 2 |
403 | + color: "#ed3146" |
404 | + visible: parent.containsMouse |
405 | + } |
406 | + Icon { |
407 | + width: height |
408 | + height: parent.height *.5 |
409 | + anchors.centerIn: parent |
410 | + source: "graphics/window-close.svg" |
411 | + color: root.active ? "white" : "#5d5d5d" |
412 | + keyColor: "black" |
413 | + } |
414 | } |
415 | - Rectangle { |
416 | + |
417 | + MouseArea { |
418 | + id: minimizeWindowButton |
419 | objectName: "minimizeWindowButton" |
420 | - height: parent.height; width: height; radius: height / 2 |
421 | - gradient: Gradient { |
422 | - GradientStop { color: "#92918C"; position: 0 } |
423 | - GradientStop { color: "#5E5D58"; position: 1 } |
424 | - } |
425 | - border.width: units.dp(.5) |
426 | - border.color: "black" |
427 | - MouseArea { anchors.fill: parent; onClicked: root.minimize() } |
428 | + hoverEnabled: true |
429 | + height: parent.height |
430 | + width: height |
431 | + onClicked: root.minimize() |
432 | + |
433 | + Rectangle { |
434 | + anchors.centerIn: parent |
435 | + width: units.gu(2) |
436 | + height: units.gu(2) |
437 | + radius: height / 2 |
438 | + color: "#888888" |
439 | + visible: parent.containsMouse |
440 | + } |
441 | + Icon { |
442 | + width: height |
443 | + height: parent.height *.5 |
444 | + anchors.centerIn: parent |
445 | + source: "graphics/window-minimize.svg" |
446 | + color: root.active ? "white" : "#5d5d5d" |
447 | + keyColor: "black" |
448 | + } |
449 | } |
450 | - Rectangle { |
451 | + |
452 | + MouseArea { |
453 | + id: maximizeWindowButton |
454 | objectName: "maximizeWindowButton" |
455 | - height: parent.height; width: height; radius: height / 2 |
456 | - gradient: Gradient { |
457 | - GradientStop { color: "#92918C"; position: 0 } |
458 | - GradientStop { color: "#5E5D58"; position: 1 } |
459 | - } |
460 | - border.width: units.dp(.5) |
461 | - border.color: "black" |
462 | - MouseArea { anchors.fill: parent; onClicked: root.maximize() } |
463 | + hoverEnabled: true |
464 | + height: parent.height |
465 | + width: height |
466 | + onClicked: root.maximize() |
467 | + |
468 | + Rectangle { |
469 | + anchors.centerIn: parent |
470 | + width: units.gu(2) |
471 | + height: units.gu(2) |
472 | + radius: height / 2 |
473 | + color: "#888888" |
474 | + visible: parent.containsMouse |
475 | + } |
476 | + Icon { |
477 | + width: height |
478 | + height: parent.height *.5 |
479 | + anchors.centerIn: parent |
480 | + source: "graphics/window-maximize.svg" |
481 | + color: root.active ? "white" : "#5d5d5d" |
482 | + keyColor: "black" |
483 | + } |
484 | } |
485 | } |
486 | |
487 | === added file 'qml/Components/graphics/window-close.svg' |
488 | --- qml/Components/graphics/window-close.svg 1970-01-01 00:00:00 +0000 |
489 | +++ qml/Components/graphics/window-close.svg 2015-11-24 17:51:40 +0000 |
490 | @@ -0,0 +1,14 @@ |
491 | +<?xml version="1.0" encoding="iso-8859-1"?> |
492 | +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> |
493 | +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
494 | +<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" |
495 | + width="94.926px" height="94.926px" viewBox="0 0 94.926 94.926" style="enable-background:new 0 0 94.926 94.926;" |
496 | + xml:space="preserve"> |
497 | +<g> |
498 | + <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 |
499 | + 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 |
500 | + 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 |
501 | + 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 |
502 | + s1.101-0.224,1.498-0.62l5.473-5.476c0.826-0.827,0.826-2.167,0-2.994L55.931,47.463z"/> |
503 | +</g> |
504 | +</svg> |
505 | |
506 | === added file 'qml/Components/graphics/window-maximize.svg' |
507 | --- qml/Components/graphics/window-maximize.svg 1970-01-01 00:00:00 +0000 |
508 | +++ qml/Components/graphics/window-maximize.svg 2015-11-24 17:51:40 +0000 |
509 | @@ -0,0 +1,12 @@ |
510 | +<?xml version="1.0" encoding="iso-8859-1"?> |
511 | +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> |
512 | +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
513 | +<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" |
514 | + width="459px" height="459px" viewBox="0 0 459 459" style="enable-background:new 0 0 459 459;" xml:space="preserve"> |
515 | +<g> |
516 | + <g id="check-box-outline-blank"> |
517 | + <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 |
518 | + C459,22.95,436.05,0,408,0L408,0z"/> |
519 | + </g> |
520 | +</g> |
521 | +</svg> |
522 | |
523 | === added file 'qml/Components/graphics/window-minimize.svg' |
524 | --- qml/Components/graphics/window-minimize.svg 1970-01-01 00:00:00 +0000 |
525 | +++ qml/Components/graphics/window-minimize.svg 2015-11-24 17:51:40 +0000 |
526 | @@ -0,0 +1,13 @@ |
527 | +<?xml version="1.0" encoding="iso-8859-1"?> |
528 | +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> |
529 | +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
530 | +<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" |
531 | + width="121.805px" height="121.804px" viewBox="0 0 121.805 121.804" style="enable-background:new 0 0 121.805 121.804;" |
532 | + xml:space="preserve"> |
533 | +<g> |
534 | + <g> |
535 | + <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 |
536 | + C3.272,53.593,0,56.865,0,60.902C0,64.939,3.272,68.211,7.308,68.211z"/> |
537 | + </g> |
538 | +</g> |
539 | +</svg> |
540 | |
541 | === modified file 'qml/Launcher/Launcher.qml' |
542 | --- qml/Launcher/Launcher.qml 2015-11-04 14:57:33 +0000 |
543 | +++ qml/Launcher/Launcher.qml 2015-11-24 17:51:40 +0000 |
544 | @@ -1,5 +1,5 @@ |
545 | /* |
546 | - * Copyright (C) 2013-2014 Canonical, Ltd. |
547 | + * Copyright (C) 2013-2015 Canonical, Ltd. |
548 | * |
549 | * This program is free software; you can redistribute it and/or modify |
550 | * it under the terms of the GNU General Public License as published by |
551 | @@ -84,6 +84,12 @@ |
552 | } |
553 | } |
554 | |
555 | + function pushEdge(amount) { |
556 | + if (root.state === "") { |
557 | + edgeBarrier.push(amount); |
558 | + } |
559 | + } |
560 | + |
561 | Timer { |
562 | id: teaseTimer |
563 | interval: mode == "teasing" ? 200 : 300 |
564 | @@ -96,7 +102,7 @@ |
565 | interval: 500 |
566 | onTriggered: { |
567 | if (root.autohideEnabled) { |
568 | - if (!panel.preventHiding && !hoverArea.containsMouse) { |
569 | + if (!panel.preventHiding) { |
570 | root.state = "" |
571 | } else { |
572 | dismissTimer.restart() |
573 | @@ -176,7 +182,6 @@ |
574 | root.switchToNextState("visible") |
575 | } |
576 | } |
577 | - |
578 | } |
579 | |
580 | MultiPointTouchArea { |
581 | @@ -203,6 +208,28 @@ |
582 | Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.BriskDuration } } |
583 | } |
584 | |
585 | + EdgeBarrier { |
586 | + id: edgeBarrier |
587 | + edge: Qt.LeftEdge |
588 | + target: parent |
589 | + enabled: root.available |
590 | + onPassed: { root.switchToNextState("visibleTemporary"); } |
591 | + material: Component { |
592 | + Item { |
593 | + Rectangle { |
594 | + width: parent.height |
595 | + height: parent.width |
596 | + rotation: -90 |
597 | + anchors.centerIn: parent |
598 | + gradient: Gradient { |
599 | + GradientStop { position: 0.0; color: panel.color} |
600 | + GradientStop { position: 1.0; color: Qt.rgba(panel.r,panel.g,panel.b,0)} |
601 | + } |
602 | + } |
603 | + } |
604 | + } |
605 | + } |
606 | + |
607 | LauncherPanel { |
608 | id: panel |
609 | objectName: "launcherPanel" |
610 | @@ -248,33 +275,6 @@ |
611 | } |
612 | } |
613 | |
614 | - // TODO: This should be replaced by some mechanism that reveals the launcher |
615 | - // after a certain resistance has been overcome, like unity7 does. However, |
616 | - // as we don't get relative mouse coordinates yet, this will do for now. |
617 | - MouseArea { |
618 | - id: hoverArea |
619 | - anchors { fill: panel; rightMargin: -1 } |
620 | - hoverEnabled: true |
621 | - propagateComposedEvents: true |
622 | - onContainsMouseChanged: { |
623 | - if (containsMouse) { |
624 | - root.switchToNextState("visibleTemporary"); |
625 | - } else { |
626 | - dismissTimer.restart(); |
627 | - } |
628 | - } |
629 | - onPressed: mouse.accepted = false; |
630 | - |
631 | - // We need to eat touch events here in order to make sure that |
632 | - // we don't trigger both, the dragArea and the hoverArea |
633 | - MultiPointTouchArea { |
634 | - anchors { top: parent.top; right: parent.right; bottom: parent.bottom } |
635 | - width: units.dp(1) |
636 | - mouseEnabled: false |
637 | - enabled: parent.enabled |
638 | - } |
639 | - } |
640 | - |
641 | DirectionalDragArea { |
642 | id: dragArea |
643 | objectName: "launcherDragArea" |
644 | @@ -322,7 +322,6 @@ |
645 | target: panel |
646 | x: -root.x // so we never go past panelWidth, even when teased by tutorial |
647 | } |
648 | - PropertyChanges { target: hoverArea; enabled: false } |
649 | }, |
650 | State { |
651 | name: "visibleTemporary" |
652 | @@ -331,7 +330,6 @@ |
653 | target: root |
654 | autohideEnabled: true |
655 | } |
656 | - PropertyChanges { target: hoverArea; enabled: true } |
657 | }, |
658 | State { |
659 | name: "teasing" |
660 | |
661 | === modified file 'qml/Launcher/LauncherPanel.qml' |
662 | --- qml/Launcher/LauncherPanel.qml 2015-11-04 14:57:13 +0000 |
663 | +++ qml/Launcher/LauncherPanel.qml 2015-11-24 17:51:40 +0000 |
664 | @@ -33,6 +33,7 @@ |
665 | property bool dragging: false |
666 | property bool moving: launcherListView.moving || launcherListView.flicking |
667 | property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed |
668 | + || mouseEventEater.containsMouse || dashItem.hovered |
669 | property int highlightIndex: -1 |
670 | |
671 | signal applicationSelected(string appId) |
672 | @@ -44,6 +45,12 @@ |
673 | } |
674 | } |
675 | |
676 | + MouseArea { |
677 | + id: mouseEventEater |
678 | + anchors.fill: parent |
679 | + hoverEnabled: true |
680 | + } |
681 | + |
682 | Column { |
683 | id: mainColumn |
684 | anchors { |
685 | |
686 | === modified file 'qml/Panel/Handle.qml' |
687 | --- qml/Panel/Handle.qml 2015-07-15 15:07:19 +0000 |
688 | +++ qml/Panel/Handle.qml 2015-11-24 17:51:40 +0000 |
689 | @@ -19,7 +19,7 @@ |
690 | |
691 | Rectangle { |
692 | id: handle |
693 | - color: "#333333" |
694 | + color: "#5d5d5d" |
695 | height: units.gu(2) |
696 | property bool active: false |
697 | |
698 | @@ -35,7 +35,7 @@ |
699 | id: dot |
700 | width: units.dp(3) |
701 | height: width |
702 | - color: handle.active ? "#de4814" : "#717171" |
703 | + color: handle.active ? UbuntuColors.orange : "#717171" |
704 | radius: units.dp(1) |
705 | } |
706 | } |
707 | |
708 | === modified file 'qml/Panel/Indicators/client/IndicatorsClient.qml' |
709 | --- qml/Panel/Indicators/client/IndicatorsClient.qml 2015-07-15 15:07:19 +0000 |
710 | +++ qml/Panel/Indicators/client/IndicatorsClient.qml 2015-11-24 17:51:40 +0000 |
711 | @@ -22,7 +22,7 @@ |
712 | import Ubuntu.Components.ListItems 1.3 as ListItem |
713 | |
714 | Rectangle { |
715 | - color: "black" |
716 | + color: "#333333" |
717 | id: root |
718 | |
719 | Component.onCompleted: { |
720 | |
721 | === modified file 'qml/Panel/IndicatorsMenu.qml' |
722 | --- qml/Panel/IndicatorsMenu.qml 2015-09-02 07:42:27 +0000 |
723 | +++ qml/Panel/IndicatorsMenu.qml 2015-11-24 17:51:40 +0000 |
724 | @@ -38,7 +38,7 @@ |
725 | property bool enableHint: true |
726 | property bool contentEnabled: true |
727 | property bool showOnClick: true |
728 | - property color panelColor: "black" |
729 | + property color panelColor: "#333333" |
730 | |
731 | signal showTapped(point position) |
732 | |
733 | @@ -110,12 +110,21 @@ |
734 | height: units.gu(0.5) |
735 | gradient: Gradient { |
736 | GradientStop { position: 0.0; color: "transparent" } |
737 | - GradientStop { position: 1.0; color: "black" } |
738 | + GradientStop { position: 1.0; color: "#333333" } |
739 | } |
740 | opacity: 0.3 |
741 | } |
742 | } |
743 | |
744 | + PanelSeparatorLine { |
745 | + id: indicatorOrangeLine |
746 | + anchors { |
747 | + bottom: handle.top |
748 | + left: handle.left |
749 | + right: handle.right |
750 | + } |
751 | + } |
752 | + |
753 | Rectangle { |
754 | anchors.fill: bar |
755 | color: panelColor |
756 | |
757 | === modified file 'qml/Panel/MenuContent.qml' |
758 | --- qml/Panel/MenuContent.qml 2015-07-15 15:13:18 +0000 |
759 | +++ qml/Panel/MenuContent.qml 2015-11-24 17:51:40 +0000 |
760 | @@ -27,7 +27,7 @@ |
761 | |
762 | property QtObject indicatorsModel: null |
763 | property int currentMenuIndex: -1 |
764 | - color: "#221e1c" // FIXME not in palette yet |
765 | + color: "#333333" // FIXME not in palette yet |
766 | |
767 | width: units.gu(40) |
768 | height: units.gu(42) |
769 | |
770 | === modified file 'qml/Panel/Panel.qml' |
771 | --- qml/Panel/Panel.qml 2015-11-09 10:16:18 +0000 |
772 | +++ qml/Panel/Panel.qml 2015-11-24 17:51:40 +0000 |
773 | @@ -30,23 +30,12 @@ |
774 | property real indicatorAreaShowProgress: 1.0 |
775 | property bool locked: false |
776 | |
777 | - opacity: fullscreenMode && indicators.fullyClosed ? 0.0 : 1.0 |
778 | - |
779 | - Binding { |
780 | - target: PanelState |
781 | - property: "panelHeight" |
782 | - value: root.panelHeight |
783 | - } |
784 | - |
785 | Rectangle { |
786 | id: darkenedArea |
787 | property real darkenedOpacity: 0.6 |
788 | anchors { |
789 | - top: parent.top |
790 | + fill: parent |
791 | topMargin: panelHeight |
792 | - left: parent.left |
793 | - right: parent.right |
794 | - bottom: parent.bottom |
795 | } |
796 | color: "black" |
797 | opacity: indicators.unitProgress * darkenedOpacity |
798 | @@ -59,16 +48,18 @@ |
799 | } |
800 | } |
801 | |
802 | + Binding { |
803 | + target: PanelState |
804 | + property: "panelHeight" |
805 | + value: indicators.minimizedPanelHeight |
806 | + } |
807 | + |
808 | Item { |
809 | id: indicatorArea |
810 | objectName: "indicatorArea" |
811 | |
812 | anchors.fill: parent |
813 | |
814 | - Behavior on anchors.topMargin { |
815 | - NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
816 | - } |
817 | - |
818 | transform: Translate { |
819 | y: indicators.state === "initial" |
820 | ? (1.0 - indicatorAreaShowProgress) * -d.indicatorHeight |
821 | @@ -76,7 +67,7 @@ |
822 | } |
823 | |
824 | BorderImage { |
825 | - id: dropShadow |
826 | + id: indicatorsDropShadow |
827 | anchors { |
828 | fill: indicators |
829 | leftMargin: -units.gu(1) |
830 | @@ -86,9 +77,19 @@ |
831 | source: "graphics/rectangular_dropshadow.sci" |
832 | } |
833 | |
834 | + BorderImage { |
835 | + id: panelDropShadow |
836 | + anchors { |
837 | + fill: indicatorAreaBackground |
838 | + bottomMargin: -units.gu(1) |
839 | + } |
840 | + visible: PanelState.dropShadow && !callHint.visible |
841 | + source: "graphics/rectangular_dropshadow.sci" |
842 | + } |
843 | + |
844 | Rectangle { |
845 | id: indicatorAreaBackground |
846 | - color: callHint.visible ? "green" : "black" |
847 | + color: callHint.visible ? "green" : "#333333" |
848 | anchors { |
849 | top: parent.top |
850 | left: parent.left |
851 | @@ -99,30 +100,6 @@ |
852 | Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } } |
853 | } |
854 | |
855 | - PanelSeparatorLine { |
856 | - id: orangeLine |
857 | - anchors { |
858 | - top: indicatorAreaBackground.bottom |
859 | - left: parent.left |
860 | - right: indicators.left |
861 | - } |
862 | - saturation: 1 - indicators.unitProgress |
863 | - |
864 | - // Don't let input event pass trough |
865 | - MouseArea { anchors.fill: parent } |
866 | - } |
867 | - |
868 | - Image { |
869 | - anchors { |
870 | - top: indicators.top |
871 | - bottom: indicators.bottom |
872 | - right: indicators.left |
873 | - topMargin: indicatorArea.anchors.topMargin + indicators.minimizedPanelHeight |
874 | - } |
875 | - width: units.dp(2) |
876 | - source: "graphics/VerticalDivider.png" |
877 | - } |
878 | - |
879 | MouseArea { |
880 | anchors { |
881 | top: parent.top |
882 | @@ -130,7 +107,29 @@ |
883 | right: indicators.left |
884 | } |
885 | height: indicators.minimizedPanelHeight |
886 | - onClicked: { if (callHint.visible) { callHint.showLiveCall(); } } |
887 | + hoverEnabled: true |
888 | + onClicked: callHint.visible ? callHint.showLiveCall() : PanelState.focusMaximizedApp() |
889 | + onDoubleClicked: PanelState.maximize() |
890 | + |
891 | + // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/ |
892 | + // cf. https://bugreports.qt.io/browse/QTBUG-32909 |
893 | + WindowControlButtons { |
894 | + id: windowControlButtons |
895 | + objectName: "panelWindowControlButtons" |
896 | + anchors { |
897 | + left: parent.left |
898 | + top: parent.top |
899 | + leftMargin: units.gu(1) |
900 | + topMargin: units.gu(0.5) |
901 | + bottomMargin: units.gu(0.5) |
902 | + } |
903 | + height: indicators.minimizedPanelHeight - anchors.topMargin - anchors.bottomMargin |
904 | + visible: PanelState.buttonsVisible && parent.containsMouse && !root.locked && !callHint.visible |
905 | + active: PanelState.buttonsVisible |
906 | + onClose: PanelState.close() |
907 | + onMinimize: PanelState.minimize() |
908 | + onMaximize: PanelState.maximize() |
909 | + } |
910 | } |
911 | |
912 | IndicatorsMenu { |
913 | @@ -146,7 +145,7 @@ |
914 | width: root.width - (windowControlButtons.visible ? windowControlButtons.width + titleLabel.width : 0) |
915 | minimizedPanelHeight: units.gu(3) |
916 | expandedPanelHeight: units.gu(7) |
917 | - openedHeight: root.height - indicatorOrangeLine.height |
918 | + openedHeight: root.height |
919 | |
920 | overFlowWidth: { |
921 | if (callHint.visible) { |
922 | @@ -163,58 +162,34 @@ |
923 | callHint.showLiveCall(); |
924 | } |
925 | } |
926 | - |
927 | - hideDragHandle { |
928 | - anchors.bottomMargin: -indicatorOrangeLine.height |
929 | - } |
930 | - } |
931 | - |
932 | - WindowControlButtons { |
933 | - id: windowControlButtons |
934 | - objectName: "panelWindowControlButtons" |
935 | - anchors { |
936 | - left: parent.left |
937 | - top: parent.top |
938 | - margins: units.gu(0.7) |
939 | - } |
940 | - height: indicators.minimizedPanelHeight - anchors.margins * 2 |
941 | - visible: PanelState.buttonsVisible && !root.locked |
942 | - onClose: PanelState.close() |
943 | - onMinimize: PanelState.minimize() |
944 | - onMaximize: PanelState.maximize() |
945 | } |
946 | |
947 | Label { |
948 | id: titleLabel |
949 | objectName: "windowDecorationTitle" |
950 | anchors { |
951 | - left: windowControlButtons.right |
952 | + left: parent.left |
953 | top: parent.top |
954 | - margins: units.gu(0.7) |
955 | + leftMargin: units.gu(1) |
956 | + topMargin: units.gu(0.5) |
957 | + bottomMargin: units.gu(0.5) |
958 | } |
959 | - color: "#DFDBD2" |
960 | - height: windowControlButtons.height |
961 | - visible: windowControlButtons.visible |
962 | + color: PanelState.buttonsVisible ? "#ffffff" : "#5d5d5d" |
963 | + height: indicators.minimizedPanelHeight - anchors.topMargin - anchors.bottomMargin |
964 | + visible: !windowControlButtons.visible && !root.locked && !callHint.visible |
965 | verticalAlignment: Text.AlignVCenter |
966 | - fontSize: "small" |
967 | - font.bold: true |
968 | + fontSize: "medium" |
969 | + font.weight: Font.Normal |
970 | text: PanelState.title |
971 | } |
972 | |
973 | - PanelSeparatorLine { |
974 | - id: indicatorOrangeLine |
975 | - anchors { |
976 | - top: indicators.bottom |
977 | - left: indicators.left |
978 | - right: indicators.right |
979 | - } |
980 | - } |
981 | + // TODO here would the Locally integrated menus come |
982 | |
983 | ActiveCallHint { |
984 | id: __callHint |
985 | anchors { |
986 | top: parent.top |
987 | - left: windowControlButtons.visible ? windowControlButtons.right : parent.left |
988 | + left: parent.left |
989 | } |
990 | height: indicators.minimizedPanelHeight |
991 | visible: active && indicators.state == "initial" |
992 | @@ -224,7 +199,7 @@ |
993 | QtObject { |
994 | id: d |
995 | objectName: "panelPriv" |
996 | - readonly property real indicatorHeight: indicators.minimizedPanelHeight + indicatorOrangeLine.height |
997 | + readonly property real indicatorHeight: indicators.minimizedPanelHeight |
998 | } |
999 | |
1000 | states: [ |
1001 | @@ -234,6 +209,7 @@ |
1002 | PropertyChanges { |
1003 | target: indicatorArea; |
1004 | anchors.topMargin: 0 |
1005 | + opacity: 1; |
1006 | } |
1007 | }, |
1008 | State { |
1009 | @@ -242,6 +218,7 @@ |
1010 | PropertyChanges { |
1011 | target: indicatorArea; |
1012 | anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 |
1013 | + opacity: indicators.fullyClosed ? 0.0 : 1.0 |
1014 | } |
1015 | PropertyChanges { |
1016 | target: indicators.showDragHandle; |
1017 | @@ -249,4 +226,15 @@ |
1018 | } |
1019 | } |
1020 | ] |
1021 | + |
1022 | + transitions: [ |
1023 | + Transition { |
1024 | + to: "onscreen" |
1025 | + UbuntuNumberAnimation { target: indicatorArea; properties: "anchors.topMargin,opacity" } |
1026 | + }, |
1027 | + Transition { |
1028 | + to: "offscreen" |
1029 | + UbuntuNumberAnimation { target: indicatorArea; properties: "anchors.topMargin,opacity" } |
1030 | + } |
1031 | + ] |
1032 | } |
1033 | |
1034 | === removed file 'qml/Panel/PanelBackground.qml' |
1035 | --- qml/Panel/PanelBackground.qml 2015-07-15 15:07:19 +0000 |
1036 | +++ qml/Panel/PanelBackground.qml 1970-01-01 00:00:00 +0000 |
1037 | @@ -1,21 +0,0 @@ |
1038 | -/* |
1039 | - * Copyright (C) 2013 Canonical, Ltd. |
1040 | - * |
1041 | - * This program is free software; you can redistribute it and/or modify |
1042 | - * it under the terms of the GNU General Public License as published by |
1043 | - * the Free Software Foundation; version 3. |
1044 | - * |
1045 | - * This program is distributed in the hope that it will be useful, |
1046 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1047 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1048 | - * GNU General Public License for more details. |
1049 | - * |
1050 | - * You should have received a copy of the GNU General Public License |
1051 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1052 | - */ |
1053 | - |
1054 | -import QtQuick 2.4 |
1055 | - |
1056 | -Rectangle { |
1057 | - color: "black" |
1058 | -} |
1059 | |
1060 | === modified file 'qml/Shell.qml' |
1061 | --- qml/Shell.qml 2015-11-06 10:06:58 +0000 |
1062 | +++ qml/Shell.qml 2015-11-24 17:51:40 +0000 |
1063 | @@ -663,6 +663,19 @@ |
1064 | id: cursor |
1065 | visible: shell.hasMouse |
1066 | z: screenGrabber.z + 1 |
1067 | + |
1068 | + onPushedLeftBoundary: { |
1069 | + if (buttons === Qt.NoButton) { |
1070 | + launcher.pushEdge(amount); |
1071 | + } |
1072 | + } |
1073 | + |
1074 | + onPushedRightBoundary: { |
1075 | + if (buttons === Qt.NoButton && applicationsDisplayLoader.item |
1076 | + && applicationsDisplayLoader.item.pushRightEdge) { |
1077 | + applicationsDisplayLoader.item.pushRightEdge(amount); |
1078 | + } |
1079 | + } |
1080 | } |
1081 | |
1082 | Rectangle { |
1083 | |
1084 | === modified file 'qml/Stages/ApplicationWindow.qml' |
1085 | --- qml/Stages/ApplicationWindow.qml 2015-10-26 09:59:50 +0000 |
1086 | +++ qml/Stages/ApplicationWindow.qml 2015-11-24 17:51:40 +0000 |
1087 | @@ -34,6 +34,8 @@ |
1088 | property QtObject application |
1089 | property int surfaceOrientationAngle |
1090 | property alias resizeSurface: sessionContainer.resizeSurface |
1091 | + property int requestedWidth: -1 |
1092 | + property int requestedHeight: -1 |
1093 | |
1094 | QtObject { |
1095 | id: d |
1096 | @@ -54,7 +56,7 @@ |
1097 | // Whether the Application had a surface before but lost it. |
1098 | property bool hadSurface: sessionContainer.surfaceContainer.hadSurface |
1099 | |
1100 | - property bool needToTakeScreenshot: |
1101 | + readonly property bool needToTakeScreenshot: |
1102 | ((sessionContainer.surface && d.surfaceInitialized) || d.hadSurface) |
1103 | && screenshotImage.status === Image.Null |
1104 | && d.applicationState === ApplicationInfoInterface.Stopped |
1105 | @@ -69,7 +71,7 @@ |
1106 | // Remove this when possible |
1107 | property bool surfaceInitialized: false |
1108 | |
1109 | - property bool supportsSurfaceResize: |
1110 | + readonly property bool supportsSurfaceResize: |
1111 | application && |
1112 | ((application.supportedOrientations & Qt.PortraitOrientation) |
1113 | || (application.supportedOrientations & Qt.InvertedPortraitOrientation)) |
1114 | @@ -135,7 +137,9 @@ |
1115 | id: sessionContainer |
1116 | // A fake application might not even have a session property. |
1117 | session: application && application.session ? application.session : null |
1118 | - anchors.fill: parent |
1119 | + |
1120 | + requestedWidth: root.requestedWidth |
1121 | + requestedHeight: root.requestedHeight |
1122 | |
1123 | surfaceOrientationAngle: application && application.rotatesWindowContents ? root.surfaceOrientationAngle : 0 |
1124 | |
1125 | @@ -150,6 +154,28 @@ |
1126 | focus: true |
1127 | } |
1128 | |
1129 | + // SessionContainer size drives ApplicationWindow size |
1130 | + Binding { |
1131 | + target: root; property: "width" |
1132 | + value: stateGroup.state === "surface" ? sessionContainer.width : root.requestedWidth |
1133 | + when: root.requestedWidth >= 0 |
1134 | + } |
1135 | + Binding { |
1136 | + target: root; property: "height" |
1137 | + value: stateGroup.state === "surface" ? sessionContainer.height : root.requestedHeight |
1138 | + when: root.requestedHeight >= 0 |
1139 | + } |
1140 | + |
1141 | + // ApplicationWindow size drives SessionContainer size |
1142 | + Binding { |
1143 | + target: sessionContainer; property: "width"; value: root.width |
1144 | + when: root.requestedWidth < 0 |
1145 | + } |
1146 | + Binding { |
1147 | + target: sessionContainer; property: "height"; value: root.height |
1148 | + when: root.requestedHeight < 0 |
1149 | + } |
1150 | + |
1151 | StateGroup { |
1152 | id: stateGroup |
1153 | objectName: "applicationWindowStateGroup" |
1154 | |
1155 | === modified file 'qml/Stages/DecoratedWindow.qml' |
1156 | --- qml/Stages/DecoratedWindow.qml 2015-11-06 13:48:29 +0000 |
1157 | +++ qml/Stages/DecoratedWindow.qml 2015-11-24 17:51:40 +0000 |
1158 | @@ -23,29 +23,27 @@ |
1159 | FocusScope { |
1160 | id: root |
1161 | |
1162 | + width: applicationWindow.width |
1163 | + height: (decorationShown ? decoration.height : 0) + applicationWindow.height |
1164 | + |
1165 | property alias window: applicationWindow |
1166 | property alias application: applicationWindow.application |
1167 | property alias active: decoration.active |
1168 | property alias title: decoration.title |
1169 | + property alias fullscreen: applicationWindow.fullscreen |
1170 | |
1171 | - property bool decorationShown: true |
1172 | + readonly property bool decorationShown: !fullscreen |
1173 | property bool highlightShown: false |
1174 | property real shadowOpacity: 1 |
1175 | |
1176 | + property alias requestedWidth: applicationWindow.requestedWidth |
1177 | + property real requestedHeight |
1178 | + |
1179 | signal close() |
1180 | signal maximize() |
1181 | signal minimize() |
1182 | signal decorationPressed() |
1183 | |
1184 | - BorderImage { |
1185 | - anchors { |
1186 | - fill: root |
1187 | - margins: -units.gu(2) |
1188 | - } |
1189 | - source: "graphics/dropshadow2gu.sci" |
1190 | - opacity: root.shadowOpacity * .3 |
1191 | - } |
1192 | - |
1193 | Rectangle { |
1194 | id: selectionHighlight |
1195 | anchors.fill: parent |
1196 | @@ -58,7 +56,17 @@ |
1197 | anchors { left: selectionHighlight.left; right: selectionHighlight.right; bottom: selectionHighlight.bottom; } |
1198 | height: units.dp(2) |
1199 | color: UbuntuColors.orange |
1200 | - visible: root.highlightShown |
1201 | + visible: highlightShown |
1202 | + } |
1203 | + |
1204 | + BorderImage { |
1205 | + anchors { |
1206 | + fill: root |
1207 | + margins: active ? -units.gu(2) : -units.gu(1.5) |
1208 | + } |
1209 | + source: "graphics/dropshadow2gu.sci" |
1210 | + opacity: root.shadowOpacity * .3 |
1211 | + enabled: !fullscreen |
1212 | } |
1213 | |
1214 | WindowDecoration { |
1215 | @@ -68,12 +76,13 @@ |
1216 | anchors { left: parent.left; top: parent.top; right: parent.right } |
1217 | height: units.gu(3) |
1218 | width: root.width |
1219 | - title: window.title !== "" ? window.title : "" |
1220 | + title: window.title |
1221 | + visible: root.decorationShown |
1222 | + |
1223 | onClose: root.close(); |
1224 | - onMaximize: root.maximize(); |
1225 | + onMaximize: { root.decorationPressed(); root.maximize(); } |
1226 | onMinimize: root.minimize(); |
1227 | onPressed: root.decorationPressed(); |
1228 | - visible: decorationShown |
1229 | } |
1230 | |
1231 | ApplicationWindow { |
1232 | @@ -82,8 +91,7 @@ |
1233 | anchors.top: parent.top |
1234 | anchors.topMargin: decoration.height |
1235 | anchors.left: parent.left |
1236 | - width: root.width |
1237 | - height: root.height - decoration.height |
1238 | + requestedHeight: root.requestedHeight - (root.decorationShown ? decoration.height : 0) |
1239 | interactive: true |
1240 | focus: true |
1241 | } |
1242 | |
1243 | === modified file 'qml/Stages/DesktopSpread.qml' |
1244 | --- qml/Stages/DesktopSpread.qml 2015-11-06 13:48:29 +0000 |
1245 | +++ qml/Stages/DesktopSpread.qml 2015-11-24 17:51:40 +0000 |
1246 | @@ -28,6 +28,11 @@ |
1247 | |
1248 | readonly property alias highlightedIndex: spreadRepeater.highlightedIndex |
1249 | |
1250 | + function show() { |
1251 | + spreadContainer.animateIn = true; |
1252 | + root.state = "altTab"; |
1253 | + } |
1254 | + |
1255 | onFocusChanged: { |
1256 | // When the spread comes active, we want to keep focus to the input handler below |
1257 | // Make sure nothing inside the ApplicationWindow grabs our focus! |
1258 | @@ -515,23 +520,4 @@ |
1259 | } |
1260 | |
1261 | ] |
1262 | - |
1263 | - MouseArea { |
1264 | - id: rightEdgePushArea |
1265 | - anchors { |
1266 | - top: parent.top |
1267 | - right: parent.right |
1268 | - bottom: parent.bottom |
1269 | - } |
1270 | - // TODO: Make this a push to edge thing like the launcher when we can, |
1271 | - // for now, yes, we want 1 pixel, regardless of the scaling |
1272 | - width: 1 |
1273 | - hoverEnabled: true |
1274 | - onContainsMouseChanged: { |
1275 | - if (containsMouse) { |
1276 | - spreadContainer.animateIn = true; |
1277 | - root.state = "altTab"; |
1278 | - } |
1279 | - } |
1280 | - } |
1281 | } |
1282 | |
1283 | === modified file 'qml/Stages/DesktopStage.qml' |
1284 | --- qml/Stages/DesktopStage.qml 2015-11-12 20:40:49 +0000 |
1285 | +++ qml/Stages/DesktopStage.qml 2015-11-24 17:51:40 +0000 |
1286 | @@ -12,12 +12,9 @@ |
1287 | * |
1288 | * You should have received a copy of the GNU General Public License |
1289 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1290 | - * |
1291 | - * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
1292 | */ |
1293 | |
1294 | import QtQuick 2.4 |
1295 | -import QtQuick.Layouts 1.1 |
1296 | import Ubuntu.Components 1.3 |
1297 | import Unity.Application 0.1 |
1298 | import "../Components/PanelState" |
1299 | @@ -33,6 +30,11 @@ |
1300 | // functions to be called from outside |
1301 | function updateFocusedAppOrientation() { /* TODO */ } |
1302 | function updateFocusedAppOrientationAnimated() { /* TODO */} |
1303 | + function pushRightEdge(amount) { |
1304 | + if (spread.state === "") { |
1305 | + edgeBarrier.push(amount); |
1306 | + } |
1307 | + } |
1308 | |
1309 | mainApp: ApplicationManager.focusedApplicationId |
1310 | ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId) |
1311 | @@ -55,7 +57,7 @@ |
1312 | onFocusRequested: { |
1313 | var appIndex = priv.indexOf(appId); |
1314 | var appDelegate = appRepeater.itemAt(appIndex); |
1315 | - appDelegate.restoreFromMinimized(); |
1316 | + appDelegate.restore(); |
1317 | |
1318 | if (spread.state == "altTab") { |
1319 | spread.cancel(); |
1320 | @@ -107,7 +109,7 @@ |
1321 | id: minimizeRestoreShortcut |
1322 | shortcut: Qt.MetaModifier|Qt.ControlModifier|Qt.Key_Down |
1323 | onTriggered: priv.focusedAppDelegate.maximized || priv.focusedAppDelegate.maximizedLeft || priv.focusedAppDelegate.maximizedRight |
1324 | - ? priv.focusedAppDelegate.restore() : priv.focusedAppDelegate.minimize(true) |
1325 | + ? priv.focusedAppDelegate.restoreFromMaximized() : priv.focusedAppDelegate.minimize() |
1326 | active: priv.focusedAppDelegate !== null |
1327 | } |
1328 | |
1329 | @@ -119,18 +121,16 @@ |
1330 | var index = indexOf(focusedAppId); |
1331 | return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null |
1332 | } |
1333 | + onFocusedAppDelegateChanged: updateForegroundMaximizedApp(); |
1334 | + |
1335 | property int foregroundMaximizedAppIdIndex: -1 |
1336 | |
1337 | function updateForegroundMaximizedApp() { |
1338 | for (var i = 0; i < appRepeater.count; i++) { |
1339 | var item = appRepeater.itemAt(i); |
1340 | - |
1341 | if (item && item.visuallyMaximized) { |
1342 | - var app = ApplicationManager.get(i); |
1343 | - if (app) { |
1344 | - foregroundMaximizedAppIdIndex = i; |
1345 | - return; |
1346 | - } |
1347 | + foregroundMaximizedAppIdIndex = i; |
1348 | + return; |
1349 | } |
1350 | } |
1351 | foregroundMaximizedAppIdIndex = -1; |
1352 | @@ -149,7 +149,7 @@ |
1353 | for (var i = 0; i < appRepeater.count; i++) { |
1354 | var appDelegate = appRepeater.itemAt(i); |
1355 | if (appDelegate && !appDelegate.minimized) { |
1356 | - appDelegate.minimize(false); // minimize but don't switch focus |
1357 | + appDelegate.minimize(); |
1358 | } |
1359 | } |
1360 | |
1361 | @@ -173,24 +173,47 @@ |
1362 | onClose: { |
1363 | ApplicationManager.stopApplication(ApplicationManager.focusedApplicationId) |
1364 | } |
1365 | - onMinimize: appRepeater.itemAt(0).minimize(true); |
1366 | - onMaximize: appRepeater.itemAt(0).restore(); |
1367 | + onMinimize: priv.focusedAppDelegate && priv.focusedAppDelegate.minimize(); |
1368 | + onMaximize: priv.focusedAppDelegate // don't restore minimized apps when double clicking the panel |
1369 | + && priv.focusedAppDelegate.restoreFromMaximized(); |
1370 | + onFocusMaximizedApp: if (priv.foregroundMaximizedAppIdIndex != -1) { |
1371 | + ApplicationManager.focusApplication(appRepeater.itemAt(priv.foregroundMaximizedAppIdIndex).appId); |
1372 | + } |
1373 | } |
1374 | |
1375 | Binding { |
1376 | target: PanelState |
1377 | property: "buttonsVisible" |
1378 | - value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized |
1379 | + value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.maximized // FIXME for Locally integrated menus |
1380 | + && spread.state == "" |
1381 | } |
1382 | |
1383 | Binding { |
1384 | target: PanelState |
1385 | property: "title" |
1386 | - value: priv.focusedAppDelegate !== null && priv.focusedAppDelegate.title |
1387 | - when: priv.focusedAppDelegate && priv.focusedAppDelegate.maximized |
1388 | - } |
1389 | - |
1390 | - Component.onDestruction: PanelState.buttonsVisible = false; |
1391 | + value: { |
1392 | + if (priv.focusedAppDelegate !== null && spread.state == "") { |
1393 | + if (priv.focusedAppDelegate.maximized) |
1394 | + return priv.focusedAppDelegate.title |
1395 | + else |
1396 | + return priv.focusedAppDelegate.appName |
1397 | + } |
1398 | + return "" |
1399 | + } |
1400 | + when: priv.focusedAppDelegate |
1401 | + } |
1402 | + |
1403 | + Binding { |
1404 | + target: PanelState |
1405 | + property: "dropShadow" |
1406 | + value: priv.focusedAppDelegate && !priv.focusedAppDelegate.maximized && priv.foregroundMaximizedAppIdIndex !== -1 |
1407 | + } |
1408 | + |
1409 | + Component.onDestruction: { |
1410 | + PanelState.title = ""; |
1411 | + PanelState.buttonsVisible = false; |
1412 | + PanelState.dropShadow = false; |
1413 | + } |
1414 | |
1415 | FocusScope { |
1416 | id: appContainer |
1417 | @@ -211,17 +234,16 @@ |
1418 | model: ApplicationManager |
1419 | objectName: "appRepeater" |
1420 | |
1421 | - onItemAdded: priv.updateForegroundMaximizedApp() |
1422 | - onItemRemoved: priv.updateForegroundMaximizedApp() |
1423 | - |
1424 | delegate: FocusScope { |
1425 | id: appDelegate |
1426 | objectName: "appDelegate_" + appId |
1427 | z: ApplicationManager.count - index |
1428 | - y: units.gu(3) |
1429 | - width: units.gu(60) |
1430 | - height: units.gu(50) |
1431 | + y: PanelState.panelHeight |
1432 | focus: appId === priv.focusedAppId |
1433 | + width: decoratedWindow.width |
1434 | + height: decoratedWindow.height |
1435 | + property alias requestedWidth: decoratedWindow.requestedWidth |
1436 | + property alias requestedHeight: decoratedWindow.requestedHeight |
1437 | |
1438 | QtObject { |
1439 | id: appDelegatePrivate |
1440 | @@ -238,6 +260,7 @@ |
1441 | readonly property string appId: model.appId |
1442 | property bool animationsEnabled: true |
1443 | property alias title: decoratedWindow.title |
1444 | + readonly property string appName: model.name |
1445 | property bool visuallyMaximized: false |
1446 | property bool visuallyMinimized: false |
1447 | |
1448 | @@ -247,7 +270,6 @@ |
1449 | } |
1450 | } |
1451 | |
1452 | - onZChanged: priv.updateForegroundMaximizedApp() |
1453 | onVisuallyMaximizedChanged: priv.updateForegroundMaximizedApp() |
1454 | |
1455 | visible: !visuallyMinimized && |
1456 | @@ -287,19 +309,18 @@ |
1457 | } |
1458 | function minimize(animated) { |
1459 | animationsEnabled = (animated === undefined) || animated; |
1460 | - appDelegatePrivate.maximized = false; |
1461 | appDelegatePrivate.minimized = true; |
1462 | } |
1463 | + function restoreFromMaximized(animated) { |
1464 | + animationsEnabled = (animated === undefined) || animated; |
1465 | + appDelegatePrivate.minimized = false; |
1466 | + appDelegatePrivate.maximized = false; |
1467 | + appDelegatePrivate.maximizedLeft = false; |
1468 | + appDelegatePrivate.maximizedRight = false; |
1469 | + } |
1470 | function restore(animated) { |
1471 | animationsEnabled = (animated === undefined) || animated; |
1472 | appDelegatePrivate.minimized = false; |
1473 | - appDelegatePrivate.maximized = false; |
1474 | - appDelegatePrivate.maximizedLeft = false; |
1475 | - appDelegatePrivate.maximizedRight = false; |
1476 | - } |
1477 | - function restoreFromMinimized(animated) { |
1478 | - animationsEnabled = (animated === undefined) || animated; |
1479 | - appDelegatePrivate.minimized = false; |
1480 | if (maximized) |
1481 | maximize(); |
1482 | else if (maximizedLeft) |
1483 | @@ -311,6 +332,14 @@ |
1484 | |
1485 | states: [ |
1486 | State { |
1487 | + name: "fullscreen"; when: decoratedWindow.fullscreen |
1488 | + extend: "maximized" |
1489 | + PropertyChanges { |
1490 | + target: appDelegate; |
1491 | + y: -PanelState.panelHeight |
1492 | + } |
1493 | + }, |
1494 | + State { |
1495 | name: "normal"; |
1496 | when: !appDelegate.maximized && !appDelegate.minimized |
1497 | && !appDelegate.maximizedLeft && !appDelegate.maximizedRight |
1498 | @@ -321,22 +350,24 @@ |
1499 | } |
1500 | }, |
1501 | State { |
1502 | - name: "maximized"; when: appDelegate.maximized |
1503 | + name: "maximized"; when: appDelegate.maximized && !appDelegate.minimized |
1504 | PropertyChanges { |
1505 | target: appDelegate; |
1506 | x: 0; y: 0; |
1507 | - width: root.width; height: root.height; |
1508 | + requestedWidth: root.width; requestedHeight: root.height; |
1509 | visuallyMinimized: false; |
1510 | visuallyMaximized: true |
1511 | } |
1512 | }, |
1513 | State { |
1514 | name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized |
1515 | - PropertyChanges { target: appDelegate; x: 0; y: units.gu(3); width: root.width/2; height: root.height - units.gu(3) } |
1516 | + PropertyChanges { target: appDelegate; x: 0; y: PanelState.panelHeight; |
1517 | + requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight } |
1518 | }, |
1519 | State { |
1520 | name: "maximizedRight"; when: appDelegate.maximizedRight && !appDelegate.minimized |
1521 | - PropertyChanges { target: appDelegate; x: root.width/2; y: units.gu(3); width: root.width/2; height: root.height - units.gu(3) } |
1522 | + PropertyChanges { target: appDelegate; x: root.width/2; y: PanelState.panelHeight; |
1523 | + requestedWidth: root.width/2; requestedHeight: root.height - PanelState.panelHeight } |
1524 | }, |
1525 | State { |
1526 | name: "minimized"; when: appDelegate.minimized |
1527 | @@ -355,32 +386,32 @@ |
1528 | to: "normal" |
1529 | enabled: appDelegate.animationsEnabled |
1530 | PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" } |
1531 | - UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale"; duration: UbuntuAnimation.FastDuration } |
1532 | - }, |
1533 | - Transition { |
1534 | - to: "maximized" |
1535 | - enabled: appDelegate.animationsEnabled |
1536 | - PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
1537 | - SequentialAnimation { |
1538 | - UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale"; duration: UbuntuAnimation.FastDuration } |
1539 | - PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
1540 | - } |
1541 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration } |
1542 | }, |
1543 | Transition { |
1544 | to: "minimized" |
1545 | enabled: appDelegate.animationsEnabled |
1546 | PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
1547 | SequentialAnimation { |
1548 | - UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,width,height,scale"; duration: UbuntuAnimation.FastDuration } |
1549 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration } |
1550 | PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
1551 | ScriptAction { |
1552 | script: { |
1553 | - if (appDelegate.animationsEnabled && state === "minimized" ) { |
1554 | + if (appDelegate.minimized) { |
1555 | priv.focusNext(); |
1556 | } |
1557 | } |
1558 | } |
1559 | } |
1560 | + }, |
1561 | + Transition { |
1562 | + to: "*" //maximized and fullscreen |
1563 | + enabled: appDelegate.animationsEnabled |
1564 | + PropertyAction { target: appDelegate; property: "visuallyMinimized" } |
1565 | + SequentialAnimation { |
1566 | + UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration } |
1567 | + PropertyAction { target: appDelegate; property: "visuallyMaximized" } |
1568 | + } |
1569 | } |
1570 | ] |
1571 | |
1572 | @@ -410,16 +441,14 @@ |
1573 | objectName: "decoratedWindow" |
1574 | anchors.left: appDelegate.left |
1575 | anchors.top: appDelegate.top |
1576 | - width: appDelegate.width |
1577 | - height: appDelegate.height |
1578 | application: ApplicationManager.get(index) |
1579 | active: ApplicationManager.focusedApplicationId === model.appId |
1580 | focus: true |
1581 | |
1582 | onClose: ApplicationManager.stopApplication(model.appId) |
1583 | onMaximize: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight |
1584 | - ? appDelegate.restore() : appDelegate.maximize() |
1585 | - onMinimize: appDelegate.minimize(true) |
1586 | + ? appDelegate.restoreFromMaximized() : appDelegate.maximize() |
1587 | + onMinimize: appDelegate.minimize() |
1588 | onDecorationPressed: { ApplicationManager.focusApplication(model.appId) } |
1589 | } |
1590 | } |
1591 | @@ -447,6 +476,29 @@ |
1592 | enabled: visible |
1593 | } |
1594 | |
1595 | + EdgeBarrier { |
1596 | + id: edgeBarrier |
1597 | + |
1598 | + // NB: it does its own positioning according to the specified edge |
1599 | + edge: Qt.RightEdge |
1600 | + |
1601 | + onPassed: { spread.show(); } |
1602 | + material: Component { |
1603 | + Item { |
1604 | + Rectangle { |
1605 | + width: parent.height |
1606 | + height: parent.width |
1607 | + rotation: 90 |
1608 | + anchors.centerIn: parent |
1609 | + gradient: Gradient { |
1610 | + GradientStop { position: 0.0; color: Qt.rgba(0.16,0.16,0.16,0.7)} |
1611 | + GradientStop { position: 1.0; color: Qt.rgba(0.16,0.16,0.16,0)} |
1612 | + } |
1613 | + } |
1614 | + } |
1615 | + } |
1616 | + } |
1617 | + |
1618 | DesktopSpread { |
1619 | id: spread |
1620 | objectName: "spread" |
1621 | |
1622 | === modified file 'qml/Stages/SessionContainer.qml' |
1623 | --- qml/Stages/SessionContainer.qml 2015-09-29 12:28:10 +0000 |
1624 | +++ qml/Stages/SessionContainer.qml 2015-11-24 17:51:40 +0000 |
1625 | @@ -29,13 +29,37 @@ |
1626 | property alias surfaceOrientationAngle: _surfaceContainer.surfaceOrientationAngle |
1627 | property alias resizeSurface: _surfaceContainer.resizeSurface |
1628 | |
1629 | + property int requestedWidth: -1 |
1630 | + property int requestedHeight: -1 |
1631 | + |
1632 | readonly property alias surfaceContainer: _surfaceContainer |
1633 | SurfaceContainer { |
1634 | id: _surfaceContainer |
1635 | - anchors.fill: parent |
1636 | + requestedWidth: root.requestedWidth |
1637 | + requestedHeight: root.requestedHeight |
1638 | surface: session ? session.surface : null |
1639 | } |
1640 | |
1641 | + // SurfaceContainer size drives SessionContainer size |
1642 | + Binding { |
1643 | + target: root; property: "width"; value: _surfaceContainer.width |
1644 | + when: root.requestedWidth >= 0 |
1645 | + } |
1646 | + Binding { |
1647 | + target: root; property: "height"; value: _surfaceContainer.height |
1648 | + when: root.requestedHeight >= 0 |
1649 | + } |
1650 | + |
1651 | + // SessionContainer size drives SurfaceContainer size |
1652 | + Binding { |
1653 | + target: _surfaceContainer; property: "width"; value: root.width |
1654 | + when: root.requestedWidth < 0 |
1655 | + } |
1656 | + Binding { |
1657 | + target: _surfaceContainer; property: "height"; value: root.height |
1658 | + when: root.requestedHeight < 0 |
1659 | + } |
1660 | + |
1661 | Repeater { |
1662 | id: childSessionsRepeater |
1663 | model: root.childSessions |
1664 | |
1665 | === modified file 'qml/Stages/SurfaceContainer.qml' |
1666 | --- qml/Stages/SurfaceContainer.qml 2015-10-26 09:59:50 +0000 |
1667 | +++ qml/Stages/SurfaceContainer.qml 2015-11-24 17:51:40 +0000 |
1668 | @@ -31,6 +31,9 @@ |
1669 | property string name: surface ? surface.name : "" |
1670 | property bool resizeSurface: true |
1671 | |
1672 | + property int requestedWidth: -1 |
1673 | + property int requestedHeight: -1 |
1674 | + |
1675 | onSurfaceChanged: { |
1676 | if (surface) { |
1677 | surfaceItem.surface = surface; |
1678 | @@ -54,16 +57,65 @@ |
1679 | |
1680 | consumesInput: true |
1681 | |
1682 | - surfaceWidth: root.resizeSurface ? width : -1 |
1683 | - surfaceHeight: root.resizeSurface ? height : -1 |
1684 | - |
1685 | - anchors.fill: root |
1686 | + surfaceWidth: { |
1687 | + if (root.resizeSurface) { |
1688 | + if (root.requestedWidth >= 0) { |
1689 | + return root.requestedWidth; |
1690 | + } else { |
1691 | + return width; |
1692 | + } |
1693 | + } else { |
1694 | + return -1; |
1695 | + } |
1696 | + } |
1697 | + |
1698 | + surfaceHeight: { |
1699 | + if (root.resizeSurface) { |
1700 | + if (root.requestedHeight >= 0) { |
1701 | + return root.requestedHeight; |
1702 | + } else { |
1703 | + return height; |
1704 | + } |
1705 | + } else { |
1706 | + return -1; |
1707 | + } |
1708 | + } |
1709 | + |
1710 | enabled: root.interactive |
1711 | focus: true |
1712 | antialiasing: !root.interactive |
1713 | orientationAngle: root.surfaceOrientationAngle |
1714 | } |
1715 | |
1716 | + // MirSurface size drives SurfaceContainer size |
1717 | + Binding { |
1718 | + target: surfaceItem; property: "width"; value: root.surface ? root.surface.size.width : 0 |
1719 | + when: root.requestedWidth >= 0 && root.surface |
1720 | + } |
1721 | + Binding { |
1722 | + target: surfaceItem; property: "height"; value: root.surface ? root.surface.size.height : 0 |
1723 | + when: root.requestedHeight >= 0 && root.surface |
1724 | + } |
1725 | + Binding { |
1726 | + target: root; property: "width"; value: surfaceItem.width |
1727 | + when: root.requestedWidth >= 0 |
1728 | + } |
1729 | + Binding { |
1730 | + target: root; property: "height"; value: surfaceItem.height |
1731 | + when: root.requestedHeight >= 0 |
1732 | + } |
1733 | + |
1734 | + // SurfaceContainer size drives MirSurface size |
1735 | + Binding { |
1736 | + target: surfaceItem; property: "width"; value: root.width |
1737 | + when: root.requestedWidth < 0 |
1738 | + } |
1739 | + Binding { |
1740 | + target: surfaceItem; property: "height"; value: root.height |
1741 | + when: root.requestedHeight < 0 |
1742 | + } |
1743 | + |
1744 | + |
1745 | TouchGate { |
1746 | targetItem: surfaceItem |
1747 | anchors.fill: root |
1748 | |
1749 | === modified file 'qml/Stages/WindowDecoration.qml' |
1750 | --- qml/Stages/WindowDecoration.qml 2015-11-09 10:16:18 +0000 |
1751 | +++ qml/Stages/WindowDecoration.qml 2015-11-24 17:51:40 +0000 |
1752 | @@ -33,6 +33,8 @@ |
1753 | signal minimize() |
1754 | signal maximize() |
1755 | |
1756 | + onDoubleClicked: root.maximize() |
1757 | + |
1758 | QtObject { |
1759 | id: priv |
1760 | property real distanceX |
1761 | @@ -65,20 +67,23 @@ |
1762 | anchors.fill: parent |
1763 | anchors.bottomMargin: -radius |
1764 | radius: units.gu(.5) |
1765 | - gradient: Gradient { |
1766 | - GradientStop { color: "#626055"; position: 0 } |
1767 | - GradientStop { color: "#3C3B37"; position: 1 } |
1768 | - } |
1769 | + color: "#333333" |
1770 | } |
1771 | |
1772 | Row { |
1773 | - anchors { fill: parent; margins: units.gu(0.7) } |
1774 | - spacing: units.gu(1) |
1775 | - opacity: root.active ? 1 : 0.5 |
1776 | + anchors { |
1777 | + fill: parent |
1778 | + leftMargin: units.gu(1) |
1779 | + rightMargin: units.gu(1) |
1780 | + topMargin: units.gu(0.5) |
1781 | + bottomMargin: units.gu(0.5) |
1782 | + } |
1783 | + spacing: units.gu(3) |
1784 | |
1785 | WindowControlButtons { |
1786 | id: buttons |
1787 | height: parent.height |
1788 | + active: root.active |
1789 | onClose: root.close(); |
1790 | onMinimize: root.minimize(); |
1791 | onMaximize: root.maximize(); |
1792 | @@ -87,12 +92,12 @@ |
1793 | Label { |
1794 | id: titleLabel |
1795 | objectName: "windowDecorationTitle" |
1796 | - color: "#DFDBD2" |
1797 | + color: root.active ? "white" : "#5d5d5d" |
1798 | height: parent.height |
1799 | width: parent.width - buttons.width - parent.anchors.rightMargin - parent.anchors.leftMargin |
1800 | verticalAlignment: Text.AlignVCenter |
1801 | - fontSize: "small" |
1802 | - font.bold: true |
1803 | + fontSize: "medium" |
1804 | + font.weight: root.active ? Font.Light : Font.Normal |
1805 | elide: Text.ElideRight |
1806 | } |
1807 | } |
1808 | |
1809 | === modified file 'qml/Stages/WindowResizeArea.qml' |
1810 | --- qml/Stages/WindowResizeArea.qml 2015-11-09 10:52:53 +0000 |
1811 | +++ qml/Stages/WindowResizeArea.qml 2015-11-24 17:51:40 +0000 |
1812 | @@ -25,7 +25,7 @@ |
1813 | anchors.fill: target |
1814 | anchors.margins: -borderThickness |
1815 | |
1816 | - hoverEnabled: true |
1817 | + hoverEnabled: target && !target.maximized // don't grab the resize under the panel |
1818 | |
1819 | property var windowStateStorage: WindowStateStorage |
1820 | |
1821 | @@ -36,6 +36,8 @@ |
1822 | property int borderThickness: 0 |
1823 | property int minWidth: 0 |
1824 | property int minHeight: 0 |
1825 | + property int defaultWidth: units.gu(60) |
1826 | + property int defaultHeight: units.gu(50) |
1827 | property int screenWidth: 0 |
1828 | property int screenHeight: 0 |
1829 | |
1830 | @@ -67,13 +69,14 @@ |
1831 | } |
1832 | |
1833 | Component.onCompleted: { |
1834 | - var windowGeometry = windowStateStorage.getGeometry(root.windowId, Qt.rect(target.x, target.y, target.width, target.height)) |
1835 | - if (windowGeometry !== undefined) { |
1836 | - target.width = Math.min(windowGeometry.width, root.screenWidth) |
1837 | - target.height = Math.min(windowGeometry.height, root.screenHeight - PanelState.panelHeight) |
1838 | - target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.width), 0) |
1839 | - target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.height), PanelState.panelHeight) |
1840 | - } |
1841 | + var windowGeometry = windowStateStorage.getGeometry(root.windowId, |
1842 | + Qt.rect(target.x, target.y, defaultWidth, defaultHeight)); |
1843 | + |
1844 | + target.requestedWidth = Math.min(Math.max(windowGeometry.width, minWidth), screenWidth); |
1845 | + target.requestedHeight = Math.min(Math.max(windowGeometry.height, minHeight), root.screenHeight - PanelState.panelHeight); |
1846 | + target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0) |
1847 | + target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight) |
1848 | + |
1849 | var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal) |
1850 | if (windowState === WindowStateStorage.WindowStateMaximized) { |
1851 | target.maximize(false) |
1852 | @@ -93,6 +96,18 @@ |
1853 | property bool topBorder: false |
1854 | property bool bottomBorder: false |
1855 | |
1856 | + // true - A change in surface size will cause the left border of the window to move accordingly. |
1857 | + // The window's right border will stay in the same position. |
1858 | + // false - a change in surface size will cause the right border of the window to move accordingly. |
1859 | + // The window's left border will stay in the same position. |
1860 | + property bool moveLeftBorder: false |
1861 | + |
1862 | + // true - A change in surface size will cause the top border of the window to move accordingly. |
1863 | + // The window's bottom border will stay in the same position. |
1864 | + // false - a change in surface size will cause the bottom border of the window to move accordingly. |
1865 | + // The window's top border will stay in the same position. |
1866 | + property bool moveTopBorder: false |
1867 | + |
1868 | property bool dragging: false |
1869 | property real startMousePosX |
1870 | property real startMousePosY |
1871 | @@ -100,6 +115,8 @@ |
1872 | property real startY |
1873 | property real startWidth |
1874 | property real startHeight |
1875 | + property real currentWidth |
1876 | + property real currentHeight |
1877 | |
1878 | property string cursorName: { |
1879 | if (root.containsMouse || root.pressed) { |
1880 | @@ -138,11 +155,24 @@ |
1881 | } |
1882 | } |
1883 | |
1884 | + Timer { |
1885 | + id: resetBordersToMoveTimer |
1886 | + interval: 2000 |
1887 | + onTriggered: { |
1888 | + d.moveLeftBorder = false; |
1889 | + d.moveTopBorder = false; |
1890 | + } |
1891 | + } |
1892 | + |
1893 | onPressedChanged: { |
1894 | var pos = mapToItem(target.parent, mouseX, mouseY); |
1895 | |
1896 | if (pressed) { |
1897 | d.updateBorders(); |
1898 | + resetBordersToMoveTimer.stop(); |
1899 | + d.moveLeftBorder = d.leftBorder; |
1900 | + d.moveTopBorder = d.topBorder; |
1901 | + |
1902 | var pos = mapToItem(root.target.parent, mouseX, mouseY); |
1903 | d.startMousePosX = pos.x; |
1904 | d.startMousePosY = pos.y; |
1905 | @@ -150,8 +180,11 @@ |
1906 | d.startY = target.y; |
1907 | d.startWidth = target.width; |
1908 | d.startHeight = target.height; |
1909 | + d.currentWidth = target.width; |
1910 | + d.currentHeight = target.height; |
1911 | d.dragging = true; |
1912 | } else { |
1913 | + resetBordersToMoveTimer.start(); |
1914 | d.dragging = false; |
1915 | if (containsMouse) { |
1916 | d.updateBorders(); |
1917 | @@ -182,37 +215,49 @@ |
1918 | if (d.leftBorder) { |
1919 | var newTargetX = d.startX + deltaX; |
1920 | if (target.x + target.width > newTargetX + minWidth) { |
1921 | - target.width = target.x + target.width - newTargetX; |
1922 | - target.x = newTargetX; |
1923 | + target.requestedWidth = target.x + target.width - newTargetX; |
1924 | } else { |
1925 | - target.x = target.x + target.width - minWidth; |
1926 | - target.width = minWidth; |
1927 | + target.requestedWidth = minWidth; |
1928 | } |
1929 | |
1930 | } else if (d.rightBorder) { |
1931 | if (d.startWidth + deltaX >= minWidth) { |
1932 | - target.width = d.startWidth + deltaX; |
1933 | + target.requestedWidth = d.startWidth + deltaX; |
1934 | } else { |
1935 | - target.width = minWidth; |
1936 | + target.requestedWidth = minWidth; |
1937 | } |
1938 | } |
1939 | |
1940 | if (d.topBorder) { |
1941 | var newTargetY = d.startY + deltaY; |
1942 | if (target.y + target.height > newTargetY + minHeight) { |
1943 | - target.height = target.y + target.height - newTargetY; |
1944 | - target.y = newTargetY; |
1945 | + target.requestedHeight = target.y + target.height - newTargetY; |
1946 | } else { |
1947 | - target.y = target.y + target.height - minHeight; |
1948 | - target.height = minHeight; |
1949 | + target.requestedHeight = minHeight; |
1950 | } |
1951 | |
1952 | } else if (d.bottomBorder) { |
1953 | if (d.startHeight + deltaY >= minHeight) { |
1954 | - target.height = d.startHeight + deltaY; |
1955 | + target.requestedHeight = d.startHeight + deltaY; |
1956 | } else { |
1957 | - target.height = minHeight; |
1958 | - } |
1959 | + target.requestedHeight = minHeight; |
1960 | + } |
1961 | + } |
1962 | + } |
1963 | + |
1964 | + Connections { |
1965 | + target: root.target |
1966 | + onWidthChanged: { |
1967 | + if (d.moveLeftBorder) { |
1968 | + target.x += d.currentWidth - target.width; |
1969 | + } |
1970 | + d.currentWidth = target.width; |
1971 | + } |
1972 | + onHeightChanged: { |
1973 | + if (d.moveTopBorder) { |
1974 | + target.y += d.currentHeight - target.height; |
1975 | + } |
1976 | + d.currentHeight = target.height; |
1977 | } |
1978 | } |
1979 | } |
1980 | |
1981 | === modified file 'tests/mocks/Cursor/Cursor.qml' |
1982 | --- tests/mocks/Cursor/Cursor.qml 2015-09-29 13:45:05 +0000 |
1983 | +++ tests/mocks/Cursor/Cursor.qml 2015-11-24 17:51:40 +0000 |
1984 | @@ -17,4 +17,6 @@ |
1985 | import QtQuick 2.4 |
1986 | |
1987 | Item { |
1988 | + signal pushedLeftBoundary(real amount, int buttons) |
1989 | + signal pushedRightBoundary(real amount, int buttons) |
1990 | } |
1991 | |
1992 | === modified file 'tests/mocks/Unity/Application/MirSurface.cpp' |
1993 | --- tests/mocks/Unity/Application/MirSurface.cpp 2015-10-27 21:55:10 +0000 |
1994 | +++ tests/mocks/Unity/Application/MirSurface.cpp 2015-11-24 17:51:40 +0000 |
1995 | @@ -35,8 +35,12 @@ |
1996 | , m_activeFocus(false) |
1997 | , m_width(-1) |
1998 | , m_height(-1) |
1999 | + , m_slowToResize(false) |
2000 | { |
2001 | // qDebug() << "MirSurface::MirSurface() " << name; |
2002 | + m_delayedResizeTimer.setInterval(600); |
2003 | + m_delayedResizeTimer.setSingleShot(true); |
2004 | + connect(&m_delayedResizeTimer, &QTimer::timeout, this, &MirSurface::applyDelayedResize); |
2005 | } |
2006 | |
2007 | MirSurface::~MirSurface() |
2008 | @@ -197,7 +201,38 @@ |
2009 | |
2010 | void MirSurface::resize(int width, int height) |
2011 | { |
2012 | + if (m_slowToResize) { |
2013 | + if (!m_delayedResizeTimer.isActive()) { |
2014 | + m_delayedResize.setWidth(width); |
2015 | + m_delayedResize.setHeight(height); |
2016 | + m_delayedResizeTimer.start(); |
2017 | + } else { |
2018 | + m_pendingResize.setWidth(width); |
2019 | + m_pendingResize.setHeight(height); |
2020 | + } |
2021 | + } else { |
2022 | + doResize(width, height); |
2023 | + } |
2024 | +} |
2025 | + |
2026 | +void MirSurface::applyDelayedResize() |
2027 | +{ |
2028 | + doResize(m_delayedResize.width(), m_delayedResize.height()); |
2029 | + m_delayedResize.setWidth(-1); |
2030 | + m_delayedResize.setHeight(-1); |
2031 | + |
2032 | + if (m_pendingResize.isValid()) { |
2033 | + QSize size = m_pendingResize; |
2034 | + m_pendingResize.setWidth(-1); |
2035 | + m_pendingResize.setHeight(-1); |
2036 | + resize(size.width(), size.height()); |
2037 | + } |
2038 | +} |
2039 | + |
2040 | +void MirSurface::doResize(int width, int height) |
2041 | +{ |
2042 | bool changed = false; |
2043 | + |
2044 | if (width != m_width) { |
2045 | m_width = width; |
2046 | Q_EMIT widthChanged(); |
2047 | @@ -214,3 +249,20 @@ |
2048 | Q_EMIT sizeChanged(QSize(width, height)); |
2049 | } |
2050 | } |
2051 | + |
2052 | +bool MirSurface::isSlowToResize() const |
2053 | +{ |
2054 | + return m_slowToResize; |
2055 | +} |
2056 | + |
2057 | +void MirSurface::setSlowToResize(bool value) |
2058 | +{ |
2059 | + if (m_slowToResize != value) { |
2060 | + m_slowToResize = value; |
2061 | + Q_EMIT slowToResizeChanged(); |
2062 | + if (!m_slowToResize && m_delayedResizeTimer.isActive()) { |
2063 | + m_delayedResizeTimer.stop(); |
2064 | + applyDelayedResize(); |
2065 | + } |
2066 | + } |
2067 | +} |
2068 | |
2069 | === modified file 'tests/mocks/Unity/Application/MirSurface.h' |
2070 | --- tests/mocks/Unity/Application/MirSurface.h 2015-10-20 16:48:06 +0000 |
2071 | +++ tests/mocks/Unity/Application/MirSurface.h 2015-11-24 17:51:40 +0000 |
2072 | @@ -18,6 +18,7 @@ |
2073 | #define MOCK_MIR_SURFACE_H |
2074 | |
2075 | #include <QObject> |
2076 | +#include <QTimer> |
2077 | #include <QUrl> |
2078 | #include <QHash> |
2079 | |
2080 | @@ -33,6 +34,7 @@ |
2081 | Q_PROPERTY(int width READ width NOTIFY widthChanged) |
2082 | Q_PROPERTY(int height READ height NOTIFY heightChanged) |
2083 | Q_PROPERTY(bool activeFocus READ activeFocus NOTIFY activeFocusChanged) |
2084 | + Q_PROPERTY(bool slowToResize READ isSlowToResize WRITE setSlowToResize NOTIFY slowToResizeChanged) |
2085 | |
2086 | public: |
2087 | MirSurface(const QString& name, |
2088 | @@ -77,6 +79,9 @@ |
2089 | int width() const; |
2090 | int height() const; |
2091 | |
2092 | + bool isSlowToResize() const; |
2093 | + void setSlowToResize(bool value); |
2094 | + |
2095 | ///// |
2096 | // internal mock stuff |
2097 | |
2098 | @@ -94,13 +99,18 @@ |
2099 | void orientationAngleChanged(Mir::OrientationAngle angle); |
2100 | void widthChanged(); |
2101 | void heightChanged(); |
2102 | + void slowToResizeChanged(); |
2103 | |
2104 | //// |
2105 | // internal mock stuff |
2106 | void screenshotUrlChanged(QUrl); |
2107 | void activeFocusChanged(bool); |
2108 | |
2109 | +private Q_SLOTS: |
2110 | + void applyDelayedResize(); |
2111 | + |
2112 | private: |
2113 | + void doResize(int width, int height); |
2114 | void updateVisibility(); |
2115 | |
2116 | const QString m_name; |
2117 | @@ -114,6 +124,12 @@ |
2118 | bool m_activeFocus; |
2119 | int m_width; |
2120 | int m_height; |
2121 | + |
2122 | + bool m_slowToResize; |
2123 | + QTimer m_delayedResizeTimer; |
2124 | + QSize m_delayedResize; |
2125 | + QSize m_pendingResize; |
2126 | + |
2127 | struct View { |
2128 | bool visible; |
2129 | }; |
2130 | |
2131 | === added file 'tests/mocks/Utils/EdgeBarrierSettings.qml' |
2132 | --- tests/mocks/Utils/EdgeBarrierSettings.qml 1970-01-01 00:00:00 +0000 |
2133 | +++ tests/mocks/Utils/EdgeBarrierSettings.qml 2015-11-24 17:51:40 +0000 |
2134 | @@ -0,0 +1,22 @@ |
2135 | +/* |
2136 | + * Copyright (C) 2015 Canonical, Ltd. |
2137 | + * |
2138 | + * This program is free software; you can redistribute it and/or modify |
2139 | + * it under the terms of the GNU General Public License as published by |
2140 | + * the Free Software Foundation; version 3. |
2141 | + * |
2142 | + * This program is distributed in the hope that it will be useful, |
2143 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2144 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2145 | + * GNU General Public License for more details. |
2146 | + * |
2147 | + * You should have received a copy of the GNU General Public License |
2148 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2149 | + */ |
2150 | + |
2151 | +pragma Singleton |
2152 | +import QtQuick 2.4 |
2153 | + |
2154 | +QtObject { |
2155 | + readonly property real pushThreshold: units.gu(8) |
2156 | +} |
2157 | |
2158 | === modified file 'tests/mocks/Utils/qmldir' |
2159 | --- tests/mocks/Utils/qmldir 2015-05-06 11:22:18 +0000 |
2160 | +++ tests/mocks/Utils/qmldir 2015-11-24 17:51:40 +0000 |
2161 | @@ -3,3 +3,4 @@ |
2162 | typeinfo Utils.qmltypes |
2163 | Style 0.1 Style.js |
2164 | HomeKeyWatcher 0.1 HomeKeyWatcher.qml |
2165 | +singleton EdgeBarrierSettings 0.1 EdgeBarrierSettings.qml |
2166 | |
2167 | === added file 'tests/qmltests/EdgeBarrierControls.qml' |
2168 | --- tests/qmltests/EdgeBarrierControls.qml 1970-01-01 00:00:00 +0000 |
2169 | +++ tests/qmltests/EdgeBarrierControls.qml 2015-11-24 17:51:40 +0000 |
2170 | @@ -0,0 +1,97 @@ |
2171 | +/* |
2172 | + * Copyright 2015 Canonical Ltd. |
2173 | + * |
2174 | + * This program is free software; you can redistribute it and/or modify |
2175 | + * it under the terms of the GNU General Public License as published by |
2176 | + * the Free Software Foundation; version 3. |
2177 | + * |
2178 | + * This program is distributed in the hope that it will be useful, |
2179 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2180 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2181 | + * GNU General Public License for more details. |
2182 | + * |
2183 | + * You should have received a copy of the GNU General Public License |
2184 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2185 | + */ |
2186 | + |
2187 | +import QtQuick 2.4 |
2188 | +import QtQuick.Layouts 1.1 |
2189 | +import Ubuntu.Components 1.3 |
2190 | +import Unity.Test 0.1 |
2191 | + |
2192 | +RowLayout { |
2193 | + id: root |
2194 | + Layout.fillWidth: true |
2195 | + |
2196 | + property var target: null |
2197 | + property string backgroundColor: "darkGrey" |
2198 | + property alias text: label.text |
2199 | + signal dragged(real amount); |
2200 | + |
2201 | + Binding { |
2202 | + id: containsMouseBinding |
2203 | + |
2204 | + // only activate the binding once the controls start to get used in order to not |
2205 | + // interfere with automated tests |
2206 | + property bool activated: false |
2207 | + |
2208 | + when: root.target !== undefined && root.target !== null && activated |
2209 | + target: root.target |
2210 | + property: "_containsMouse" |
2211 | + value: checkbox.checked |
2212 | + } |
2213 | + |
2214 | + |
2215 | + Rectangle { |
2216 | + width: label.width + units.gu(1) |
2217 | + height: units.gu(4) |
2218 | + color: root.backgroundColor |
2219 | + |
2220 | + Rectangle { |
2221 | + anchors.fill: parent |
2222 | + color: "darkGreen" |
2223 | + opacity: target ? target.progress : 0 |
2224 | + } |
2225 | + |
2226 | + Label { |
2227 | + id: label |
2228 | + color: "white" |
2229 | + anchors.centerIn: parent |
2230 | + } |
2231 | + MouseArea { |
2232 | + id: mouseArea |
2233 | + anchors.fill: parent |
2234 | + property real lastX |
2235 | + property bool dragging: false |
2236 | + onPressedChanged: { |
2237 | + if (pressed) { |
2238 | + containsMouseBinding.activated = true; |
2239 | + checkbox.checked = true; |
2240 | + } else { |
2241 | + dragging = false; |
2242 | + } |
2243 | + } |
2244 | + onMouseXChanged: { |
2245 | + if (dragging) { |
2246 | + var amount = Math.abs(mouseX - lastX); |
2247 | + lastX = mouseX; |
2248 | + root.dragged(amount); |
2249 | + } else { |
2250 | + lastX = mouseX; |
2251 | + dragging = true; |
2252 | + } |
2253 | + } |
2254 | + } |
2255 | + } |
2256 | + |
2257 | + CheckBox { |
2258 | + id: checkbox |
2259 | + checked: false |
2260 | + activeFocusOnPress: false |
2261 | + onCheckedChanged: { |
2262 | + if (checked) { |
2263 | + containsMouseBinding.activated = true; |
2264 | + } |
2265 | + } |
2266 | + } |
2267 | +} |
2268 | |
2269 | === modified file 'tests/qmltests/Launcher/tst_Launcher.qml' |
2270 | --- tests/qmltests/Launcher/tst_Launcher.qml 2015-10-26 09:59:50 +0000 |
2271 | +++ tests/qmltests/Launcher/tst_Launcher.qml 2015-11-24 17:51:40 +0000 |
2272 | @@ -22,6 +22,7 @@ |
2273 | import ".." |
2274 | import "../../../qml/Launcher" |
2275 | import Unity.Launcher 0.1 |
2276 | +import Utils 0.1 // For EdgeBarrierSettings |
2277 | |
2278 | /* Nothing is shown at first. If you drag from left edge you will bring up the |
2279 | launcher. */ |
2280 | @@ -67,6 +68,7 @@ |
2281 | |
2282 | Component.onCompleted: { |
2283 | launcherLoader.itemDestroyed = false; |
2284 | + edgeBarrierControls.target = testCase.findChild(this, "edgeBarrierController"); |
2285 | } |
2286 | Component.onDestruction: { |
2287 | launcherLoader.itemDestroyed = true; |
2288 | @@ -82,6 +84,12 @@ |
2289 | |
2290 | MouseTouchEmulationCheckbox {} |
2291 | |
2292 | + EdgeBarrierControls { |
2293 | + id: edgeBarrierControls |
2294 | + text: "Drag here to pull out launcher" |
2295 | + onDragged: { launcherLoader.item.pushEdge(amount); } |
2296 | + } |
2297 | + |
2298 | Button { |
2299 | text: "emit hinting signal" |
2300 | onClicked: LauncherModel.emitHint() |
2301 | @@ -207,8 +215,10 @@ |
2302 | tryCompare(launcher, "state", "visible"); |
2303 | } |
2304 | |
2305 | - function revealByHover() { |
2306 | + function revealByEdgePush() { |
2307 | + // Place the mouse against the window/screen edge and push beyond the barrier threshold |
2308 | mouseMove(root, 1, root.height / 2); |
2309 | + launcher.pushEdge(EdgeBarrierSettings.pushThreshold * 1.1); |
2310 | |
2311 | var panel = findChild(launcher, "launcherPanel"); |
2312 | verify(!!panel); |
2313 | @@ -278,7 +288,7 @@ |
2314 | |
2315 | function test_clickingOnAppIconCausesSignalEmission(data) { |
2316 | if (data.mouse) { |
2317 | - revealByHover(); |
2318 | + revealByEdgePush(); |
2319 | } else { |
2320 | dragLauncherIntoView(); |
2321 | } |
2322 | @@ -748,12 +758,12 @@ |
2323 | verify(quickList, "state", "") |
2324 | } |
2325 | |
2326 | - function test_revealByHover() { |
2327 | + function test_revealByEdgePush() { |
2328 | var panel = findChild(launcher, "launcherPanel"); |
2329 | verify(!!panel); |
2330 | |
2331 | - revealByHover(); |
2332 | - tryCompare(launcher, "state", "visibleTemporary"); |
2333 | + revealByEdgePush(); |
2334 | + compare(launcher.state, "visibleTemporary"); |
2335 | |
2336 | // Now move the mouse away and make sure it hides in less than a second |
2337 | mouseMove(root, root.width, root.height / 2) |
2338 | |
2339 | === modified file 'tests/qmltests/Panel/tst_Panel.qml' |
2340 | --- tests/qmltests/Panel/tst_Panel.qml 2015-08-03 13:48:14 +0000 |
2341 | +++ tests/qmltests/Panel/tst_Panel.qml 2015-11-24 17:51:40 +0000 |
2342 | @@ -23,6 +23,7 @@ |
2343 | import Unity.Indicators 0.1 as Indicators |
2344 | import Ubuntu.Telephony 0.1 as Telephony |
2345 | import "../../../qml/Panel" |
2346 | +import "../../../qml/Components/PanelState" |
2347 | |
2348 | IndicatorTest { |
2349 | id: root |
2350 | @@ -30,6 +31,12 @@ |
2351 | height: units.gu(71) |
2352 | color: "white" |
2353 | |
2354 | + Binding { |
2355 | + target: mouseEmulation |
2356 | + property: "checked" |
2357 | + value: !windowControlsCB.checked |
2358 | + } |
2359 | + |
2360 | RowLayout { |
2361 | anchors.fill: parent |
2362 | anchors.margins: units.gu(1) |
2363 | @@ -45,17 +52,18 @@ |
2364 | MouseArea { |
2365 | id: backgroundMouseArea |
2366 | anchors.fill: parent |
2367 | - } |
2368 | - |
2369 | - Panel { |
2370 | - id: panel |
2371 | - anchors.fill: parent |
2372 | - indicators { |
2373 | - width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
2374 | - indicatorsModel: root.indicatorsModel |
2375 | + hoverEnabled: true |
2376 | + |
2377 | + Panel { |
2378 | + id: panel |
2379 | + anchors.fill: parent |
2380 | + indicators { |
2381 | + width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
2382 | + indicatorsModel: root.indicatorsModel |
2383 | + } |
2384 | + |
2385 | + property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight |
2386 | } |
2387 | - |
2388 | - property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight + units.dp(2) |
2389 | } |
2390 | } |
2391 | |
2392 | @@ -93,6 +101,32 @@ |
2393 | } |
2394 | } |
2395 | |
2396 | + RowLayout { |
2397 | + Layout.fillWidth: true |
2398 | + CheckBox { |
2399 | + id: windowControlsCB |
2400 | + onClicked: PanelState.buttonsVisible = checked |
2401 | + } |
2402 | + Label { |
2403 | + text: "Show window controls" |
2404 | + } |
2405 | + } |
2406 | + |
2407 | + RowLayout { |
2408 | + Layout.fillWidth: true |
2409 | + CheckBox { |
2410 | + onClicked: { |
2411 | + if (checked) |
2412 | + PanelState.title = "Fake window title" |
2413 | + else |
2414 | + PanelState.title = "" |
2415 | + } |
2416 | + } |
2417 | + Label { |
2418 | + text: "Show fake window title" |
2419 | + } |
2420 | + } |
2421 | + |
2422 | Rectangle { |
2423 | Layout.preferredHeight: units.dp(1); |
2424 | Layout.fillWidth: true; |
2425 | @@ -127,7 +161,7 @@ |
2426 | color: "black" |
2427 | } |
2428 | |
2429 | - MouseTouchEmulationCheckbox {} |
2430 | + MouseTouchEmulationCheckbox { id: mouseEmulation } |
2431 | } |
2432 | } |
2433 | |
2434 | |
2435 | === modified file 'tests/qmltests/Stages/tst_DesktopStage.qml' |
2436 | --- tests/qmltests/Stages/tst_DesktopStage.qml 2015-11-06 13:48:29 +0000 |
2437 | +++ tests/qmltests/Stages/tst_DesktopStage.qml 2015-11-24 17:51:40 +0000 |
2438 | @@ -17,11 +17,12 @@ |
2439 | import QtQuick 2.4 |
2440 | import QtTest 1.0 |
2441 | import Ubuntu.Components 1.3 |
2442 | -import Ubuntu.Components.ListItems 1.3 as ListItem |
2443 | +import Ubuntu.Components.ListItems 1.3 |
2444 | import Unity.Application 0.1 |
2445 | import Unity.Test 0.1 |
2446 | import Utils 0.1 |
2447 | |
2448 | +import ".." // For EdgeBarrierControls |
2449 | import "../../../qml/Stages" |
2450 | import "../../../qml/Components" |
2451 | |
2452 | @@ -46,8 +47,8 @@ |
2453 | WindowStateStorage.geometry = { |
2454 | 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)), |
2455 | 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)), |
2456 | - 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)), |
2457 | - 'gallery-app': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40)) |
2458 | + 'gmail-webapp': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)), |
2459 | + 'twitter-webapp': Qt.rect(units.gu(51), units.gu(44), units.gu(50), units.gu(40)) |
2460 | } |
2461 | } |
2462 | |
2463 | @@ -60,10 +61,18 @@ |
2464 | |
2465 | focus: true |
2466 | |
2467 | + property bool itemDestroyed: false |
2468 | sourceComponent: Component { |
2469 | DesktopStage { |
2470 | color: "darkblue" |
2471 | anchors.fill: parent |
2472 | + |
2473 | + Component.onCompleted: { |
2474 | + edgeBarrierControls.target = testCase.findChild(this, "edgeBarrierController"); |
2475 | + } |
2476 | + Component.onDestruction: { |
2477 | + desktopStageLoader.itemDestroyed = true; |
2478 | + } |
2479 | orientations: Orientations {} |
2480 | } |
2481 | } |
2482 | @@ -82,6 +91,28 @@ |
2483 | Column { |
2484 | anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) } |
2485 | spacing: units.gu(1) |
2486 | + |
2487 | + Button { |
2488 | + color: "white" |
2489 | + text: "Make surface slow to resize" |
2490 | + activeFocusOnPress: false |
2491 | + onClicked: { |
2492 | + if (ApplicationManager.focusedApplicationId) { |
2493 | + var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.surface; |
2494 | + surface.slowToResize = true; |
2495 | + } |
2496 | + } |
2497 | + } |
2498 | + |
2499 | + EdgeBarrierControls { |
2500 | + id: edgeBarrierControls |
2501 | + text: "Drag here to pull out spread" |
2502 | + backgroundColor: "blue" |
2503 | + onDragged: { desktopStageLoader.item.pushRightEdge(amount); } |
2504 | + } |
2505 | + |
2506 | + Divider {} |
2507 | + |
2508 | Repeater { |
2509 | model: ApplicationManager.availableApplications |
2510 | ApplicationCheckBox { |
2511 | @@ -99,10 +130,16 @@ |
2512 | property Item desktopStage: desktopStageLoader.status === Loader.Ready ? desktopStageLoader.item : null |
2513 | |
2514 | function cleanup() { |
2515 | + desktopStageLoader.itemDestroyed = false; |
2516 | desktopStageLoader.active = false; |
2517 | |
2518 | tryCompare(desktopStageLoader, "status", Loader.Null); |
2519 | tryCompare(desktopStageLoader, "item", null); |
2520 | + // Loader.status might be Loader.Null and Loader.item might be null but the Loader |
2521 | + // actually took place. Likely because Loader waits until the next event loop |
2522 | + // iteration to do its work. So to ensure the reload, we will wait until the |
2523 | + // Shell instance gets destroyed. |
2524 | + tryCompare(desktopStageLoader, "itemDestroyed", true); |
2525 | |
2526 | killAllRunningApps(); |
2527 | |
2528 | @@ -156,8 +193,8 @@ |
2529 | |
2530 | function test_tappingOnWindowChangesFocusedApp_data() { |
2531 | return [ |
2532 | - {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 0, focusTo: 1 }, |
2533 | - {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 1, focusTo: 0 }, |
2534 | + {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 0, focusTo: 1 }, |
2535 | + {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 1, focusTo: 0 } |
2536 | ] |
2537 | } |
2538 | |
2539 | @@ -203,8 +240,8 @@ |
2540 | |
2541 | function test_tappingOnDecorationFocusesApplication_data() { |
2542 | return [ |
2543 | - {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 0, focusTo: 1 }, |
2544 | - {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 1, focusTo: 0 }, |
2545 | + {tag: "dash to dialer", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 0, focusTo: 1 }, |
2546 | + {tag: "dialer to dash", apps: [ "unity8-dash", "dialer-app", "gmail-webapp"], focusfrom: 1, focusTo: 0 } |
2547 | ] |
2548 | } |
2549 | |
2550 | @@ -214,12 +251,16 @@ |
2551 | var fromAppDecoration = findChild(desktopStage, "appWindowDecoration_" + data.apps[data.focusfrom]); |
2552 | verify(fromAppDecoration); |
2553 | tap(fromAppDecoration); |
2554 | - tryCompare(ApplicationManager.findApplication(data.apps[data.focusfrom]).session.surface, "activeFocus", true); |
2555 | + var fromApp = ApplicationManager.findApplication(data.apps[data.focusfrom]); |
2556 | + verify(fromApp); |
2557 | + tryCompare(fromApp.session.surface, "activeFocus", true); |
2558 | |
2559 | var toAppDecoration = findChild(desktopStage, "appWindowDecoration_" + data.apps[data.focusTo]); |
2560 | verify(toAppDecoration); |
2561 | tap(toAppDecoration); |
2562 | - tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true); |
2563 | + var toApp = ApplicationManager.findApplication(data.apps[data.focusTo]); |
2564 | + verify(toApp); |
2565 | + tryCompare(toApp.session.surface, "activeFocus", true); |
2566 | } |
2567 | |
2568 | function test_clickingOnDecorationFocusesApplication_data() { |
2569 | @@ -339,26 +380,26 @@ |
2570 | function test_maximizeApplicationHidesSurfacesBehindIt() { |
2571 | var dashApp = startApplication("unity8-dash"); |
2572 | var dialerApp = startApplication("dialer-app"); |
2573 | - var cameraApp = startApplication("camera-app"); |
2574 | + var gmailApp = startApplication("gmail-webapp"); |
2575 | |
2576 | var dashDelegate = findChild(desktopStage, "appDelegate_unity8-dash"); |
2577 | verify(dashDelegate); |
2578 | var dialerDelegate = findChild(desktopStage, "appDelegate_dialer-app"); |
2579 | verify(dialerDelegate); |
2580 | - var cameraDelegate = findChild(desktopStage, "appDelegate_camera-app"); |
2581 | - verify(cameraDelegate); |
2582 | + var gmailDelegate = findChild(desktopStage, "appDelegate_gmail-webapp"); |
2583 | + verify(gmailDelegate); |
2584 | |
2585 | // maximize |
2586 | - findChild(dialerDelegate, "decoratedWindow").maximize(); |
2587 | + dialerDelegate.maximize(); |
2588 | tryCompare(dialerDelegate, "visuallyMaximized", true); |
2589 | |
2590 | tryCompare(dashApp.session.surface, "visible", false); |
2591 | - compare(cameraApp.session.surface.visible, true); |
2592 | + compare(gmailApp.session.surface.visible, true); |
2593 | |
2594 | // restore |
2595 | - findChild(dialerDelegate, "decoratedWindow").maximize(); |
2596 | + dialerDelegate.restoreFromMaximized(); |
2597 | compare(dashApp.session.surface.visible, true); |
2598 | - compare(cameraApp.session.surface.visible, true); |
2599 | + compare(gmailApp.session.surface.visible, true); |
2600 | } |
2601 | |
2602 | function test_applicationsBecomeVisibleWhenOccludingAppRemoved() { |
2603 | @@ -370,28 +411,52 @@ |
2604 | var dialerDelegate = findChild(desktopStage, "appDelegate_dialer-app"); |
2605 | verify(dialerDelegate); |
2606 | |
2607 | - var cameraApp = startApplication("camera-app"); |
2608 | - var cameraDelegate = findChild(desktopStage, "appDelegate_camera-app"); |
2609 | - verify(cameraDelegate); |
2610 | - findChild(dialerDelegate, "decoratedWindow").maximize(); |
2611 | - |
2612 | - var galleryApp = startApplication("gallery-app"); |
2613 | - var galleryDelegate = findChild(desktopStage, "appDelegate_gallery-app"); |
2614 | - verify(galleryDelegate); |
2615 | - findChild(galleryDelegate, "decoratedWindow").maximize(); |
2616 | + var dialerMaximizeButton = findChild(dialerDelegate, "maximizeWindowButton"); |
2617 | + verify(dialerMaximizeButton); |
2618 | + mouseClick(dialerMaximizeButton); |
2619 | + |
2620 | + var mapApp = startApplication("map"); |
2621 | + var mapDelegate = findChild(desktopStage, "appDelegate_map"); |
2622 | + verify(mapDelegate); |
2623 | + |
2624 | + var gmailApp = startApplication("gmail-webapp"); |
2625 | + var gmailDelegate = findChild(desktopStage, "appDelegate_gmail-webapp"); |
2626 | + verify(gmailDelegate); |
2627 | + |
2628 | + var gmailMaximizeButton = findChild(gmailDelegate, "maximizeWindowButton"); |
2629 | + verify(gmailMaximizeButton); |
2630 | + mouseClick(gmailMaximizeButton); |
2631 | |
2632 | tryCompare(dialerDelegate, "visuallyMaximized", true); |
2633 | - tryCompare(galleryDelegate, "visuallyMaximized", true); |
2634 | + tryCompare(gmailDelegate, "visuallyMaximized", true); |
2635 | |
2636 | tryCompare(dashApp.session.surface, "visible", false); |
2637 | tryCompare(dialerApp.session.surface, "visible", false); |
2638 | - tryCompare(cameraApp.session.surface, "visible", false); |
2639 | - |
2640 | - ApplicationManager.stopApplication("gallery-app"); |
2641 | - |
2642 | - compare(cameraApp.session.surface.visible, true); |
2643 | + tryCompare(mapApp.session.surface, "visible", false); |
2644 | + |
2645 | + ApplicationManager.stopApplication("gmail-webapp"); |
2646 | + |
2647 | + compare(mapApp.session.surface.visible, true); |
2648 | tryCompare(dialerApp.session.surface, "visible", true); |
2649 | tryCompare(dashApp.session.surface, "visible", false); // still occluded by maximised dialer |
2650 | } |
2651 | + |
2652 | + function test_maximisedAppStaysVisibleWhenAppStarts() { |
2653 | + var dashApp = startApplication("unity8-dash"); |
2654 | + var dashDelegate = findChild(desktopStage, "appDelegate_unity8-dash"); |
2655 | + verify(dashDelegate); |
2656 | + // maximize |
2657 | + var dashMaximizeButton = findChild(dashDelegate, "maximizeWindowButton"); |
2658 | + verify(dashMaximizeButton); |
2659 | + mouseClick(dashMaximizeButton); |
2660 | + tryCompare(dashDelegate, "visuallyMaximized", true); |
2661 | + |
2662 | + var dialerApp = startApplication("dialer-app"); |
2663 | + var dialerDelegate = findChild(desktopStage, "appDelegate_dialer-app"); |
2664 | + verify(dialerDelegate); |
2665 | + |
2666 | + compare(dialerDelegate.visible, true, "Dialer should be visible"); |
2667 | + compare(dashDelegate.visible, true, "Dash should still be visible"); |
2668 | + } |
2669 | } |
2670 | } |
2671 | |
2672 | === modified file 'tests/qmltests/Stages/tst_WindowResizeArea.qml' |
2673 | --- tests/qmltests/Stages/tst_WindowResizeArea.qml 2015-11-09 10:16:18 +0000 |
2674 | +++ tests/qmltests/Stages/tst_WindowResizeArea.qml 2015-11-24 17:51:40 +0000 |
2675 | @@ -30,8 +30,6 @@ |
2676 | height: units.gu(60) |
2677 | width: units.gu(60) |
2678 | |
2679 | - property var fakeWindow: windowLoader.item |
2680 | - |
2681 | Binding { |
2682 | target: PanelState |
2683 | property: "panelHeight" |
2684 | @@ -47,10 +45,10 @@ |
2685 | property alias minHeight: windowResizeArea.minHeight |
2686 | x: units.gu(20) |
2687 | y: units.gu(20) |
2688 | - height: units.gu(20) |
2689 | - width: units.gu(20) |
2690 | - property int windowHeight: height |
2691 | - property int windowWidth: width |
2692 | + width: requestedWidth |
2693 | + height: requestedHeight |
2694 | + property real requestedWidth |
2695 | + property real requestedHeight |
2696 | state: "normal" |
2697 | |
2698 | function maximize() { |
2699 | @@ -63,6 +61,8 @@ |
2700 | borderThickness: units.gu(2) |
2701 | minWidth: units.gu(15) |
2702 | minHeight: units.gu(10) |
2703 | + defaultWidth: units.gu(20) |
2704 | + defaultHeight: units.gu(20) |
2705 | windowId: "test-window-id" |
2706 | screenWidth: root.width |
2707 | screenHeight: root.height |
2708 | @@ -87,22 +87,41 @@ |
2709 | Loader { |
2710 | id: windowLoader |
2711 | sourceComponent: fakeWindowComponent |
2712 | + active: windowLoaderCheckbox.checked |
2713 | } |
2714 | |
2715 | - MouseTouchEmulationCheckbox { |
2716 | - checked: false |
2717 | - color: "black" |
2718 | + Column { |
2719 | + MouseTouchEmulationCheckbox { |
2720 | + checked: false |
2721 | + color: "black" |
2722 | + } |
2723 | + RowLayout { |
2724 | + Layout.fillWidth: true |
2725 | + CheckBox { |
2726 | + id: windowLoaderCheckbox |
2727 | + checked: true |
2728 | + activeFocusOnPress: false |
2729 | + } |
2730 | + Label { |
2731 | + id: label |
2732 | + color: "black" |
2733 | + text: "Window loader active" |
2734 | + anchors.verticalCenter: parent.verticalCenter |
2735 | + } |
2736 | + } |
2737 | } |
2738 | |
2739 | UnityTestCase { |
2740 | name: "WindowResizeArea" |
2741 | when: windowShown |
2742 | |
2743 | + property var fakeWindow: windowLoader.item |
2744 | + |
2745 | function init() { |
2746 | fakeWindow.x = units.gu(20) |
2747 | fakeWindow.y = units.gu(20) |
2748 | - fakeWindow.width = units.gu(20) |
2749 | - fakeWindow.height = units.gu(20) |
2750 | + fakeWindow.requestedWidth = units.gu(20) |
2751 | + fakeWindow.requestedHeight = units.gu(20) |
2752 | } |
2753 | |
2754 | function test_resizeWindowRightBottom_data() { |
2755 | @@ -188,7 +207,7 @@ |
2756 | function test_resizeSmallerAndLarger_data() { |
2757 | return [ |
2758 | { tag: "topLeft", startX: -1, startY: -1, dx: units.gu(15), dy: units.gu(15) }, |
2759 | - { tag: "bottomRight", startX: fakeWindow.width + 1, startY: fakeWindow.height + 1, dx: -units.gu(15), dy: -units.gu(15) } |
2760 | + { tag: "bottomRight", startX: units.gu(20) + 1, startY: units.gu(20) + 1, dx: -units.gu(15), dy: -units.gu(15) } |
2761 | ] |
2762 | } |
2763 | |
2764 | |
2765 | === modified file 'tests/qmltests/tst_Shell.qml' |
2766 | --- tests/qmltests/tst_Shell.qml 2015-11-12 20:40:49 +0000 |
2767 | +++ tests/qmltests/tst_Shell.qml 2015-11-24 17:51:40 +0000 |
2768 | @@ -954,6 +954,22 @@ |
2769 | removeTimeConstraintsFromDirectionalDragAreas(greeter); |
2770 | } |
2771 | |
2772 | + function revealLauncherByEdgePushWithMouse() { |
2773 | + var launcher = findChild(shell, "launcher"); |
2774 | + verify(launcher); |
2775 | + |
2776 | + // Place the mouse against the window/screen edge and push beyond the barrier threshold |
2777 | + mouseMove(shell, 0, shell.height / 2); |
2778 | + launcher.pushEdge(EdgeBarrierSettings.pushThreshold * 1.1); |
2779 | + |
2780 | + var panel = findChild(launcher, "launcherPanel"); |
2781 | + verify(panel); |
2782 | + |
2783 | + // wait until it gets fully extended |
2784 | + tryCompare(panel, "x", 0); |
2785 | + tryCompare(launcher, "state", "visibleTemporary"); |
2786 | + } |
2787 | + |
2788 | function test_focusRequestedHidesGreeter() { |
2789 | loadShell("phone"); |
2790 | swipeAwayGreeter(); |
2791 | @@ -1713,8 +1729,7 @@ |
2792 | |
2793 | tryCompare(desktopSpread, "state", "altTab") |
2794 | |
2795 | - mouseMove(shell, 0, shell.height / 2); |
2796 | - tryCompare(launcher, "state", "visibleTemporary") |
2797 | + revealLauncherByEdgePushWithMouse(); |
2798 | waitForRendering(shell) |
2799 | |
2800 | mouseClick(bfb, bfb.width / 2, bfb.height / 2) |
2801 | @@ -1777,15 +1792,10 @@ |
2802 | tryCompare(panelButtons, "visible", false); |
2803 | |
2804 | appDelegate.maximize(false); |
2805 | - tryCompare(panelButtons, "visible", true); |
2806 | |
2807 | shell.usageScenario = "phone"; |
2808 | waitForRendering(shell); |
2809 | tryCompare(panelButtons, "visible", false); |
2810 | - |
2811 | - shell.usageScenario = "desktop"; |
2812 | - waitForRendering(shell); |
2813 | - tryCompare(panelButtons, "visible", true); |
2814 | } |
2815 | |
2816 | function test_lockingGreeterHidesPanelButtons() { |
2817 | @@ -1799,15 +1809,10 @@ |
2818 | tryCompare(panelButtons, "visible", false); |
2819 | |
2820 | appDelegate.maximize(false); |
2821 | - tryCompare(panelButtons, "visible", true); |
2822 | |
2823 | LightDM.Greeter.showGreeter(); |
2824 | waitForRendering(shell); |
2825 | tryCompare(panelButtons, "visible", false); |
2826 | - |
2827 | - LightDM.Greeter.hideGreeter(); |
2828 | - waitForRendering(shell); |
2829 | - tryCompare(panelButtons, "visible", true); |
2830 | } |
2831 | |
2832 | function test_cantMoveWindowUnderPanel() { |
FAILED: Continuous integration, rev:2021 jenkins. qa.ubuntu. com/job/ unity8- ci/6613/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 4954 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- xenial- touch/28/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- vivid/1325 jenkins. qa.ubuntu. com/job/ unity8- qmluitest- xenial- amd64/28 jenkins. qa.ubuntu. com/job/ unity8- vivid-amd64- ci/1220 jenkins. qa.ubuntu. com/job/ unity8- vivid-i386- ci/1221 jenkins. qa.ubuntu. com/job/ unity8- xenial- amd64-ci/ 27 jenkins. qa.ubuntu. com/job/ unity8- xenial- i386-ci/ 27 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 3977 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 4951 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 4951/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 24761 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- xenial- mako/16/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- xenial- armhf/28 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- xenial- armhf/28/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 24763
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
UNSTABLE: 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: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/6613/ rebuild
http://