Merge lp:~uriboni/unity-2d/launcher-shelf into lp:unity-2d/3.0

Proposed by Ugo Riboni
Status: Merged
Approved by: Ugo Riboni
Approved revision: 393
Merged at revision: 393
Proposed branch: lp:~uriboni/unity-2d/launcher-shelf
Merge into: lp:unity-2d/3.0
Diff against target: 338 lines (+142/-121)
4 files modified
launcher/AutoScrollingListView.qml (+2/-0)
launcher/Launcher.qml (+21/-120)
launcher/LauncherItem.qml (+2/-1)
launcher/LauncherList.qml (+117/-0)
To merge this branch: bzr merge lp:~uriboni/unity-2d/launcher-shelf
Reviewer Review Type Date Requested Status
Ugo Riboni (community) Approve
Florian Boucault (community) Approve
Review via email: mp+49863@code.launchpad.net

Description of the change

[launcher] New "shelf" area at the bottom of the launcher, which is essentially a second list of items which stays fixed in place and is always as tall as all the items it contains. For now it only contain the trash.

To post a comment you must log in.
Revision history for this message
Ugo Riboni (uriboni) wrote :

Please note that is one issue that I have not been able to solve.

In some cases (which i can't repro consistently) the menu for some items stop to appear on mouse over.
The items are always those close to the bottom of the normal list or the item in the shelf (i.e. trash).

The way I seem to get this issue the most often is when i very quickly move the mouse up and down over the seam between the launcher and shelf, making sure to go in and out of the bottom autoscroll area of the main list in both directions.
Then going over these items will consistently stop showing a menu.

The menu doesn't show because of the check for isVisible() in LauncherContextualMenu::show() finds that the menu isVisible() is true even though there's no menu actually visible on screen.

Revision history for this message
Olivier Tilloy (osomon) wrote :

This may also be of interest to the reviewer(s): I haven’t looked at the code, but from the description of the changes, this branch very likely breaks and/or conflicts with the changes this other merge request: https://code.launchpad.net/~osomon/unity-2d/dnd2/+merge/49782.

Revision history for this message
Florian Boucault (fboucault) wrote :

> This may also be of interest to the reviewer(s): I haven’t looked at the code,
> but from the description of the changes, this branch very likely breaks and/or
> conflicts with the changes this other merge request:
> https://code.launchpad.net/~osomon/unity-2d/dnd2/+merge/49782.

Indeed though the conflicts will be easy to solve I believe. Now the question is, who will be first in? :)

Revision history for this message
Florian Boucault (fboucault) wrote :

There is a conflict in Launcher.qml introduced by revision 391. I believe it's resolved by:
- keeping the code from the launcher-shelf branch
- adding the 3 lines of code introduced by revision 391:

            /* Drag’n’drop handling */
            function dragEnterEvent(event) { item.onDragEnter(event) }
            function dropEvent(event) { item.onDrop(event) }

review: Needs Fixing
Revision history for this message
Florian Boucault (fboucault) wrote :

Very clean job. Good to go.

Please approve the MR once the conflict is resolved.

review: Approve
lp:~uriboni/unity-2d/launcher-shelf updated
393. By Ugo Riboni

Merge changes from trunk

Revision history for this message
Ugo Riboni (uriboni) wrote :

Fixed conflicts. Self-approving as requested.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/AutoScrollingListView.qml'
2--- launcher/AutoScrollingListView.qml 2011-02-15 18:33:55 +0000
3+++ launcher/AutoScrollingListView.qml 2011-02-18 13:38:21 +0000
4@@ -84,6 +84,7 @@
5 Connections {
6 target: scrollZoneTop
7 onEntered: updateItemBelow(scrollZoneTop)
8+ onExited: { if (itemBelow) itemBelow.exited(); itemBelow = null }
9 onPositionChanged: updateItemBelow(scrollZoneTop)
10 onClicked: forwardClick(scrollZoneTop, mouse)
11 }
12@@ -91,6 +92,7 @@
13 Connections {
14 target: scrollZoneBottom
15 onEntered: updateItemBelow(scrollZoneBottom)
16+ onExited: { if (itemBelow) itemBelow.exited(); itemBelow = null }
17 onPositionChanged: updateItemBelow(scrollZoneBottom)
18 onClicked: forwardClick(scrollZoneBottom, mouse)
19 }
20
21=== modified file 'launcher/Launcher.qml'
22--- launcher/Launcher.qml 2011-02-16 16:12:23 +0000
23+++ launcher/Launcher.qml 2011-02-18 13:38:21 +0000
24@@ -13,129 +13,30 @@
25 source: "artwork/background.png"
26 }
27
28- AutoScrollingListView {
29- id: list
30+ LauncherList {
31+ id: main
32+ anchors.top: parent.top
33+ anchors.bottom: shelf.top
34+ width: parent.width
35
36- spacing: 5
37 paddingTop: 5
38 paddingBottom: 5
39-
40- anchors.fill: parent
41- focus: true
42- property int itemHeight: 54
43- autoScrollSize: itemHeight / 2
44+ autoScrollSize: tileSize / 2
45 autoScrollVelocity: 200
46
47- /* Keep a reference to the currently visible contextual menu */
48- property variant visibleMenu
49-
50 model: ListAggregatorModel {
51 id: items
52 }
53-
54- delegate: LauncherItem {
55- id: launcherItem
56-
57- width: launcher.width
58- height: tileSize
59-
60- icon: "image://icons/" + item.icon
61- running: item.running
62- active: item.active
63- urgent: item.urgent
64- launching: item.launching
65- pips: Math.min(item.windowCount, 3)
66- tileSize: list.itemHeight
67-
68- /* Best way I could find to check if the item is an application or the
69- workspaces switcher. There may be something cleaner and better. */
70- backgroundFromIcon: item.toString().indexOf("LauncherApplication") == 0 ||
71- item.toString().indexOf("Workspaces") == 0
72-
73- Binding { target: item.menu; property: "title"; value: item.name }
74-
75- /* Drag’n’drop handling */
76- function dragEnterEvent(event) { item.onDragEnter(event) }
77- function dropEvent(event) { item.onDrop(event) }
78-
79- function showMenu() {
80- /* Prevent the simultaneous display of multiple menus */
81- if (list.visibleMenu != item.menu && list.visibleMenu != undefined) {
82- list.visibleMenu.hide()
83- }
84- list.visibleMenu = item.menu
85- // The extra 4 pixels are needed to center exactly with the arrow
86- // that indicated the active tile.
87- item.menu.show(width,
88- y + height / 2 - list.contentY +
89- panel.y - list.paddingTop + 4)
90- }
91-
92- onClicked: {
93- if (mouse.button == Qt.LeftButton) {
94- item.menu.hide()
95- item.activate()
96- }
97- else if (mouse.button == Qt.RightButton) {
98- item.menu.folded = false
99- showMenu()
100- }
101- }
102-
103- /* Display the tooltip when hovering the item only when the list
104- is not moving */
105- onEntered: if (!list.moving && !list.autoScrolling) showMenu()
106- onExited: {
107- /* When unfolded, leave enough time for the user to reach the
108- menu. Necessary because there is some void between the item
109- and the menu. Also it fixes the case when the user
110- overshoots. */
111- if (!item.menu.folded)
112- item.menu.hideWithDelay(400)
113- else
114- item.menu.hide()
115- }
116-
117- Connections {
118- target: list
119- onMovementStarted: item.menu.hide()
120- onAutoScrollingChanged: if (list.autoScrolling) item.menu.hide()
121- }
122-
123- function setIconGeometry() {
124- if (running) {
125- item.setIconGeometry(x + panel.x, y + panel.y, width, height)
126- }
127- }
128-
129- ListView.onAdd: SequentialAnimation {
130- PropertyAction { target: launcherItem; property: "scale"; value: 0 }
131- NumberAnimation { target: launcherItem; property: "height";
132- from: 0; to: launcherItem.tileSize; duration: 250; easing.type: Easing.InOutQuad }
133- NumberAnimation { target: launcherItem; property: "scale"; to: 1; duration: 250; easing.type: Easing.InOutQuad }
134- }
135-
136- ListView.onRemove: SequentialAnimation {
137- PropertyAction { target: launcherItem; property: "ListView.delayRemove"; value: true }
138- NumberAnimation { target: launcherItem; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
139- NumberAnimation { target: launcherItem; property: "height"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
140- PropertyAction { target: launcherItem; property: "ListView.delayRemove"; value: false }
141- }
142-
143- onRunningChanged: setIconGeometry()
144- /* Note: this doesn’t work as expected for the first favorite
145- application in the list if it is already running when the
146- launcher is started, because its y property doesn’t change.
147- This isn’t too bad though, as the launcher is supposed to be
148- started before any other regular application. */
149- onYChanged: setIconGeometry()
150-
151- Connections {
152- target: item
153- onWindowAdded: item.setIconGeometry(x + panel.x, y + panel.y, width, height, xid)
154- /* Not all items are applications. */
155- ignoreUnknownSignals: true
156- }
157+ }
158+
159+ LauncherList {
160+ id: shelf
161+ anchors.bottom: parent.bottom;
162+ height: tileSize * count + spacing * Math.max(0, count - 1)
163+ width: parent.width
164+
165+ model: ListAggregatorModel {
166+ id: shelfItems
167 }
168 }
169
170@@ -151,20 +52,20 @@
171 id: devices
172 }
173
174+ WorkspacesList {
175+ id: workspaces
176+ }
177+
178 Trashes {
179 id: trashes
180 }
181
182- WorkspacesList {
183- id: workspaces
184- }
185-
186 Component.onCompleted: {
187 items.appendModel(applications);
188 items.appendModel(workspaces);
189 items.appendModel(places);
190 items.appendModel(devices);
191- items.appendModel(trashes);
192+ shelfItems.appendModel(trashes);
193 }
194
195 Connections {
196
197=== modified file 'launcher/LauncherItem.qml'
198--- launcher/LauncherItem.qml 2011-02-16 11:11:46 +0000
199+++ launcher/LauncherItem.qml 2011-02-18 13:38:21 +0000
200@@ -34,6 +34,7 @@
201 objectName: "launcherItem"
202
203 anchors.horizontalCenter: parent.horizontalCenter
204+ height: tileSize
205
206 property int tileSize
207 property alias icon: icon.source
208@@ -108,7 +109,7 @@
209 id: tile
210 anchors.centerIn: parent
211 width: item.tileSize
212- height: parent.height
213+ height: item.height
214
215 /* This is the image providing the background image. The
216 color blended with this image is obtained from the color of the icon when it's
217
218=== added file 'launcher/LauncherList.qml'
219--- launcher/LauncherList.qml 1970-01-01 00:00:00 +0000
220+++ launcher/LauncherList.qml 2011-02-18 13:38:21 +0000
221@@ -0,0 +1,117 @@
222+import Qt 4.7
223+import UnityApplications 1.0
224+import Unity2d 1.0 /* required for drag’n’drop handling */
225+
226+AutoScrollingListView {
227+ id: list
228+ spacing: 5
229+ property int tileSize: 54
230+
231+ /* Keep a reference to the currently visible contextual menu */
232+ property variant visibleMenu
233+
234+ delegate: LauncherItem {
235+ id: launcherItem
236+
237+ width: list.width
238+ tileSize: list.tileSize
239+
240+ icon: "image://icons/" + item.icon
241+ running: item.running
242+ active: item.active
243+ urgent: item.urgent
244+ launching: item.launching
245+ pips: Math.min(item.windowCount, 3)
246+
247+ /* Best way I could find to check if the item is an application or the
248+ workspaces switcher. There may be something cleaner and better. */
249+ backgroundFromIcon: item.toString().indexOf("LauncherApplication") == 0 ||
250+ item.toString().indexOf("Workspaces") == 0
251+
252+ Binding { target: item.menu; property: "title"; value: item.name }
253+
254+ /* Drag’n’drop handling */
255+ function dragEnterEvent(event) { item.onDragEnter(event) }
256+ function dropEvent(event) { item.onDrop(event) }
257+
258+ function showMenu() {
259+ /* Prevent the simultaneous display of multiple menus */
260+ if (list.visibleMenu != item.menu && list.visibleMenu != undefined) {
261+ list.visibleMenu.hide()
262+ }
263+ list.visibleMenu = item.menu
264+ // The extra 4 pixels are needed to center exactly with the arrow
265+ // indicating the active tile.
266+ item.menu.show(width, panel.y + list.y +
267+ y + height / 2 - list.contentY
268+ - list.paddingTop + 4)
269+
270+ }
271+
272+ onClicked: {
273+ if (mouse.button == Qt.LeftButton) {
274+ item.menu.hide()
275+ item.activate()
276+ }
277+ else if (mouse.button == Qt.RightButton) {
278+ item.menu.folded = false
279+ showMenu()
280+ }
281+ }
282+
283+ /* Display the tooltip when hovering the item only when the list
284+ is not moving */
285+ onEntered: if (!list.moving && !list.autoScrolling) showMenu()
286+ onExited: {
287+ /* When unfolded, leave enough time for the user to reach the
288+ menu. Necessary because there is some void between the item
289+ and the menu. Also it fixes the case when the user
290+ overshoots. */
291+ if (!item.menu.folded)
292+ item.menu.hideWithDelay(400)
293+ else
294+ item.menu.hide()
295+ }
296+
297+ Connections {
298+ target: list
299+ onMovementStarted: item.menu.hide()
300+ onAutoScrollingChanged: if (list.autoScrolling) item.menu.hide()
301+ }
302+
303+ function setIconGeometry() {
304+ if (running) {
305+ item.setIconGeometry(x + panel.x, y + panel.y, width, height)
306+ }
307+ }
308+
309+ ListView.onAdd: SequentialAnimation {
310+ PropertyAction { target: launcherItem; property: "scale"; value: 0 }
311+ NumberAnimation { target: launcherItem; property: "height";
312+ from: 0; to: launcherItem.tileSize; duration: 250; easing.type: Easing.InOutQuad }
313+ NumberAnimation { target: launcherItem; property: "scale"; to: 1; duration: 250; easing.type: Easing.InOutQuad }
314+ }
315+
316+ ListView.onRemove: SequentialAnimation {
317+ PropertyAction { target: launcherItem; property: "ListView.delayRemove"; value: true }
318+ NumberAnimation { target: launcherItem; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
319+ NumberAnimation { target: launcherItem; property: "height"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
320+ PropertyAction { target: launcherItem; property: "ListView.delayRemove"; value: false }
321+ }
322+
323+ onRunningChanged: setIconGeometry()
324+ /* Note: this doesn’t work as expected for the first favorite
325+ application in the list if it is already running when the
326+ launcher is started, because its y property doesn’t change.
327+ This isn’t too bad though, as the launcher is supposed to be
328+ started before any other regular application. */
329+ onYChanged: setIconGeometry()
330+
331+ Connections {
332+ target: item
333+ onWindowAdded: item.setIconGeometry(x + panel.x, y + panel.y, width, height, xid)
334+ /* Not all items are applications. */
335+ ignoreUnknownSignals: true
336+ }
337+ }
338+}

Subscribers

People subscribed via source and target branches

to all changes: