Merge lp:~aacid/ubuntu-ui-toolkit/nonsquareicons into lp:ubuntu-ui-toolkit/staging

Proposed by Albert Astals Cid
Status: Merged
Approved by: Zsombor Egri
Approved revision: 1418
Merged at revision: 1414
Proposed branch: lp:~aacid/ubuntu-ui-toolkit/nonsquareicons
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 271 lines (+142/-15)
7 files modified
modules/Ubuntu/Components/plugin/unitythemeiconprovider.cpp (+17/-14)
modules/Ubuntu/Components/plugin/unitythemeiconprovider.h (+1/-1)
tests/unit_x11/tst_iconprovider/icons/mockTheme/actions/scalable/battery-100-charging.svg (+25/-0)
tests/unit_x11/tst_iconprovider/icons/mockTheme/index.theme (+17/-0)
tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp (+76/-0)
tests/unit_x11/tst_iconprovider/tst_iconprovider.pro (+5/-0)
tests/unit_x11/unit_x11.pro (+1/-0)
To merge this branch: bzr merge lp:~aacid/ubuntu-ui-toolkit/nonsquareicons
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Lars Karlitski (community) Approve
Zsombor Egri Approve
Sebastien Bacher (community) runtime testing Approve
Review via email: mp+250110@code.launchpad.net

Commit message

Fix infinite icon size grow when asked for a non square icon

Without this patch we could end up in loops like
requested icon "battery-080-charging" QSize(24, 24)
returned QSize(37, 24)
requested icon "battery-080-charging" QSize(37, 24)
returned QSize(57, 37)
requested icon "battery-080-charging" QSize(57, 24)
returned QSize(88, 57)
requested icon "battery-080-charging" QSize(57, 37)
returned QSize(88, 57)

To post a comment you must log in.
Revision history for this message
Albert Astals Cid (aacid) wrote :

I'm also working on a unit test, since i couldn't find any

1411. By Albert Astals Cid

Add tests for the icon provider

They are bit dependent on the suru icon theme so may need a bit of adjusting as time goes by

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

The diff seems very big but that's just because i moved the declaration of the icon theme class to the header in r1411 :/

1412. By Albert Astals Cid

Update

1413. By Albert Astals Cid

Get my own mockTheme for more stable testin

1414. By Albert Astals Cid

Revert unneeded changes

1415. By Albert Astals Cid

We don't need this either

1416. By Albert Astals Cid

smaller diff against original code

1417. By Albert Astals Cid

my mock inherits noone

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

Without the changes in the cpp code these are the tests that fail

tst_iconprovider: FAIL! : tst_IconProvider::test_loadIcon(battery2) Compared values are not the same
   tst_iconprovider: Actual (p.size()) : QSize(24x16)
   tst_iconprovider: Expected (resultSize): QSize(16x10)
   tst_iconprovider: Loc: [tst_iconprovider.cpp(69)]
i.e. asking for a 16x-1 icon returns a 24x16 icon

tst_iconprovider: FAIL! : tst_IconProvider::test_loadIcon(battery4) Compared values are not the same
   tst_iconprovider: Actual (p.size()) : QSize(24x16)
   tst_iconprovider: Expected (resultSize): QSize(16x10)
   tst_iconprovider: Loc: [tst_iconprovider.cpp(69)]
i.e. asking for a 16x0 icon returns a 24x16 icon

tst_iconprovider: FAIL! : tst_IconProvider::test_loadIcon(battery5) Compared values are not the same
   tst_iconprovider: Actual (p.size()) : QSize(37x24)
   tst_iconprovider: Expected (resultSize): QSize(24x16)
   tst_iconprovider: Loc: [tst_iconprovider.cpp(69)]
i.e. asking for a 24x16 icon returns a 37x24 icon

tst_iconprovider: FAIL! : tst_IconProvider::test_loadIcon(battery7) Compared values are not the same
   tst_iconprovider: Actual (p.size()) : QSize(57x37)
   tst_iconprovider: Expected (resultSize): QSize(37x24)
   tst_iconprovider: Loc: [tst_iconprovider.cpp(69)]
i.e. asking for a 37x24 icon returns a 57x27 icon

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Sebastien Bacher (seb128) wrote :

The changes work for me, my unity8 desktop session starts again with that update

review: Approve (runtime testing)
Revision history for this message
Zsombor Egri (zsombi) wrote :

Looks good, lets wait till we get the staging fixed with 5.4 (i.e. binding loops in Picker)

review: Approve
Revision history for this message
Lars Karlitski (larsu) wrote :

I can't reproduce the infinite loop. That isn't an issue in with the provider, though, as it sets its outgoing size correctly.

However, I agree that returning e.g. a pixmap sized (57, 37) when requesting (37, 24) is obviously bogus. Thanks for the patch!

Note that you still return values greater than requested in some cases. Not sure if that lead to the orginal problem.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Agreed, the Qt::KeepAspectRatioByExpanding makes it return an icon of QSize(37, 24) when asking one of QSize(24, 24) and i'm with you that's a questionable choice.

Zsombor, do you want me to explore fixing that too?

1418. By Albert Astals Cid

Merge staging

Revision history for this message
Zsombor Egri (zsombi) wrote :

> Agreed, the Qt::KeepAspectRatioByExpanding makes it return an icon of
> QSize(37, 24) when asking one of QSize(24, 24) and i'm with you that's a
> questionable choice.
>
> Zsombor, do you want me to explore fixing that too?

If you have time to check it, I wouldn't mind, more, I would be very thankful!

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'modules/Ubuntu/Components/plugin/unitythemeiconprovider.cpp'
--- modules/Ubuntu/Components/plugin/unitythemeiconprovider.cpp 2014-09-02 09:39:09 +0000
+++ modules/Ubuntu/Components/plugin/unitythemeiconprovider.cpp 2015-02-19 08:47:10 +0000
@@ -48,7 +48,7 @@
48 // Does a breadth-first search for an icon with any name in @names. Parent48 // Does a breadth-first search for an icon with any name in @names. Parent
49 // themes are only looked at if the current theme doesn't contain any icon49 // themes are only looked at if the current theme doesn't contain any icon
50 // in @names.50 // in @names.
51 QPixmap findBestIcon(const QStringList &names, int size)51 QPixmap findBestIcon(const QStringList &names, const QSize &size)
52 {52 {
53 Q_FOREACH(const QString &name, names) {53 Q_FOREACH(const QString &name, names) {
54 QPixmap pixmap = lookupIcon(name, size);54 QPixmap pixmap = lookupIcon(name, size);
@@ -121,18 +121,20 @@
121 return Fixed;121 return Fixed;
122 }122 }
123123
124 static QPixmap loadIcon(const QString &filename, int size)124 static QPixmap loadIcon(const QString &filename, const QSize &size)
125 {125 {
126 QPixmap pixmap;126 QPixmap pixmap;
127127
128 if (filename.endsWith(".png")) {128 if (filename.endsWith(".png")) {
129 pixmap = QPixmap(filename);129 pixmap = QPixmap(filename);
130 if (!pixmap.isNull() && size > 0 && (pixmap.width() != size || pixmap.height() != size))130 if (!pixmap.isNull() && !size.isNull() && (pixmap.width() != size.width() || pixmap.height() != size.height())) {
131 pixmap = pixmap.scaled(size, size, Qt::KeepAspectRatioByExpanding);131 const QSize newSize = pixmap.size().scaled(size.width(), size.height(), Qt::KeepAspectRatioByExpanding);
132 pixmap = pixmap.scaled(newSize);
133 }
132 }134 }
133 else if (filename.endsWith(".svg")) {135 else if (filename.endsWith(".svg")) {
134 QSvgRenderer renderer(filename);136 QSvgRenderer renderer(filename);
135 pixmap = QPixmap(renderer.defaultSize().scaled(size, size, Qt::KeepAspectRatioByExpanding));137 pixmap = QPixmap(renderer.defaultSize().scaled(size.width(), size.height(), Qt::KeepAspectRatioByExpanding));
136 pixmap.fill(Qt::transparent);138 pixmap.fill(Qt::transparent);
137 QPainter painter(&pixmap);139 QPainter painter(&pixmap);
138 renderer.render(&painter);140 renderer.render(&painter);
@@ -160,15 +162,16 @@
160 return QString();162 return QString();
161 }163 }
162164
163 QPixmap lookupIcon(const QString &iconName, int size)165 QPixmap lookupIcon(const QString &iconName, const QSize &size)
164 {166 {
165 if (size > 0)167 const int iconSize = qMax(size.width(), size.height());
168 if (iconSize > 0)
166 return lookupBestMatchingIcon(iconName, size);169 return lookupBestMatchingIcon(iconName, size);
167 else170 else
168 return lookupLargestIcon(iconName);171 return lookupLargestIcon(iconName);
169 }172 }
170173
171 QPixmap lookupBestMatchingIcon(const QString &iconName, int size)174 QPixmap lookupBestMatchingIcon(const QString &iconName, const QSize &size)
172 {175 {
173 int minDistance = 10000;176 int minDistance = 10000;
174 QString bestFilename;177 QString bestFilename;
@@ -213,13 +216,14 @@
213 }216 }
214217
215 if (!bestFilename.isNull())218 if (!bestFilename.isNull())
216 return loadIcon(bestFilename, maxSize);219 return loadIcon(bestFilename, QSize(maxSize, maxSize));
217220
218 return QPixmap();221 return QPixmap();
219 }222 }
220223
221 int directorySizeDistance(const Directory &dir, int size)224 int directorySizeDistance(const Directory &dir, const QSize &iconSize)
222 {225 {
226 const int size = qMax(iconSize.width(), iconSize.height());
223 switch (dir.sizeType) {227 switch (dir.sizeType) {
224 case Fixed:228 case Fixed:
225 return qAbs(size - dir.size);229 return qAbs(size - dir.size);
@@ -241,16 +245,15 @@
241 QList<IconThemePointer> parents;245 QList<IconThemePointer> parents;
242};246};
243247
244UnityThemeIconProvider::UnityThemeIconProvider():248UnityThemeIconProvider::UnityThemeIconProvider(const QString &themeName):
245 QQuickImageProvider(QQuickImageProvider::Pixmap)249 QQuickImageProvider(QQuickImageProvider::Pixmap)
246{250{
247 theme = IconTheme::get("suru");251 theme = IconTheme::get(themeName);
248}252}
249253
250QPixmap UnityThemeIconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)254QPixmap UnityThemeIconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
251{255{
252 int iconSize = qMax(requestedSize.width(), requestedSize.height());256 QPixmap pixmap = theme->findBestIcon(id.split(",", QString::SkipEmptyParts), requestedSize);
253 QPixmap pixmap = theme->findBestIcon(id.split(",", QString::SkipEmptyParts), iconSize);
254 *size = pixmap.size();257 *size = pixmap.size();
255 return pixmap;258 return pixmap;
256}259}
257260
=== modified file 'modules/Ubuntu/Components/plugin/unitythemeiconprovider.h'
--- modules/Ubuntu/Components/plugin/unitythemeiconprovider.h 2014-09-02 09:39:09 +0000
+++ modules/Ubuntu/Components/plugin/unitythemeiconprovider.h 2015-02-19 08:47:10 +0000
@@ -24,7 +24,7 @@
24class UnityThemeIconProvider: public QQuickImageProvider24class UnityThemeIconProvider: public QQuickImageProvider
25{25{
26public:26public:
27 UnityThemeIconProvider();27 UnityThemeIconProvider(const QString &themeName = "suru");
28 QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);28 QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);
2929
30private:30private:
3131
=== added directory 'tests/unit_x11/tst_iconprovider'
=== added directory 'tests/unit_x11/tst_iconprovider/icons'
=== added directory 'tests/unit_x11/tst_iconprovider/icons/mockTheme'
=== added directory 'tests/unit_x11/tst_iconprovider/icons/mockTheme/actions'
=== added directory 'tests/unit_x11/tst_iconprovider/icons/mockTheme/actions/scalable'
=== added file 'tests/unit_x11/tst_iconprovider/icons/mockTheme/actions/scalable/battery-100-charging.svg'
--- tests/unit_x11/tst_iconprovider/icons/mockTheme/actions/scalable/battery-100-charging.svg 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_iconprovider/icons/mockTheme/actions/scalable/battery-100-charging.svg 2015-02-19 08:47:10 +0000
@@ -0,0 +1,25 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg id="svg4966" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="90" viewBox="0 0 139.00489 90.000001" width="139" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
4 <metadata id="metadata4971">
5 <rdf:RDF>
6 <cc:Work rdf:about="">
7 <dc:format>image/svg+xml</dc:format>
8 <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
9 <dc:title/>
10 </cc:Work>
11 </rdf:RDF>
12 </metadata>
13 <g id="layer1" transform="translate(-149.78 -484.51)">
14 <g id="g5120" transform="translate(-433.79 125.71)">
15 <g id="g5124" transform="translate(409.57 223.43)">
16 <g id="g5126" style="fill:none" transform="matrix(2.1875 0 0 1.875 -456 -1657.8)">
17 <rect id="rect5128" style="opacity:.21171;fill:none" transform="translate(0 804.36)" height="48" width="48" y="152" x="288"/>
18 </g>
19 <path id="path5130" style="fill:#808080" transform="translate(174 135.36)" d="m86 15-75.156 0.012c-7.844-0.012-10.844 1.988-10.844 11.988v18 18c0 10 3 12 10.844 11.988l75.156 0.012c7.8438 0.01172 11-2.3633 11-12v-4.0117h8v-13.988-13.988h-8v-4.012c0-9.637-3.156-12.012-11-12zm-75 6c21.619 0.0096 48.956 0.0081 75 0 4 0 5 1 5 6v18 18c0 5-1 6-5 6-26.044-0.008-53.381-0.01-75 0-4 0-5-1-5-6v-18-18c0-5 1-6 5-6z"/>
20 <path id="path5132" style="fill:#38b44a" d="m1051 697c-3 0-4 0-4 5v26c0 5 1 5 4 5h65c3 0 4 0 4-5v-26c0-5-1-5-4-5z" transform="translate(-861 -534.64)"/>
21 <path id="path3847-0" style="fill:#808080" d="m299 150.36-13.996 35h14v25l14.005-35h-14z"/>
22 </g>
23 </g>
24 </g>
25</svg>
026
=== added directory 'tests/unit_x11/tst_iconprovider/icons/mockTheme/apps'
=== added directory 'tests/unit_x11/tst_iconprovider/icons/mockTheme/apps/512'
=== added file 'tests/unit_x11/tst_iconprovider/icons/mockTheme/apps/512/gallery-app.png'
1Binary files tests/unit_x11/tst_iconprovider/icons/mockTheme/apps/512/gallery-app.png 1970-01-01 00:00:00 +0000 and tests/unit_x11/tst_iconprovider/icons/mockTheme/apps/512/gallery-app.png 2015-02-19 08:47:10 +0000 differ27Binary files tests/unit_x11/tst_iconprovider/icons/mockTheme/apps/512/gallery-app.png 1970-01-01 00:00:00 +0000 and tests/unit_x11/tst_iconprovider/icons/mockTheme/apps/512/gallery-app.png 2015-02-19 08:47:10 +0000 differ
=== added file 'tests/unit_x11/tst_iconprovider/icons/mockTheme/index.theme'
--- tests/unit_x11/tst_iconprovider/icons/mockTheme/index.theme 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_iconprovider/icons/mockTheme/index.theme 2015-02-19 08:47:10 +0000
@@ -0,0 +1,17 @@
1[Icon Theme]
2Name=MockTheme
3
4Directories=actions/scalable,apps/512
5
6[actions/scalable]
7MinSize=9
8Size=90
9MaxSize=256
10Context=Actions
11Type=Scalable
12
13[apps/512]
14Size=512
15Context=Applications
16Type=Fixed
17
018
=== added file 'tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp'
--- tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_iconprovider/tst_iconprovider.cpp 2015-02-19 08:47:10 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <QtTest/QtTest>
18
19#define private public
20#include "unitythemeiconprovider.h"
21#undef private
22
23class tst_IconProvider : public QObject
24{
25 Q_OBJECT
26public:
27 tst_IconProvider() {}
28
29private Q_SLOTS:
30
31 void initTestCase()
32 {
33 qputenv("XDG_DATA_DIRS", SRCDIR);
34 }
35
36 void test_loadIcon_data()
37 {
38 QTest::addColumn<QString>("icon");
39 QTest::addColumn<QSize>("requestSize");
40 QTest::addColumn<QSize>("resultSize");
41
42 QTest::newRow("battery0") << "battery-100-charging" << QSize(-1, -1) << QSize(395, 256);
43 QTest::newRow("battery1") << "battery-100-charging" << QSize(-1, 16) << QSize(24, 16);
44 QTest::newRow("battery2") << "battery-100-charging" << QSize(16, -1) << QSize(16, 10);
45 QTest::newRow("battery3") << "battery-100-charging" << QSize(0, 16) << QSize(24, 16);
46 QTest::newRow("battery4") << "battery-100-charging" << QSize(16, 0) << QSize(16, 10);
47 QTest::newRow("battery5") << "battery-100-charging" << QSize(24, 16) << QSize(24, 16);
48 QTest::newRow("battery6") << "battery-100-charging" << QSize(24, 24) << QSize(37, 24);
49 QTest::newRow("battery7") << "battery-100-charging" << QSize(37, 24) << QSize(37, 24);
50
51 QTest::newRow("gallery0") << "gallery-app" << QSize(-1, -1) << QSize(512, 512);
52 QTest::newRow("gallery1") << "gallery-app" << QSize(-1, 16) << QSize(16, 16);
53 QTest::newRow("gallery2") << "gallery-app" << QSize(16, -1) << QSize(16, 16);
54 QTest::newRow("gallery3") << "gallery-app" << QSize(0, 16) << QSize(16, 16);
55 QTest::newRow("gallery4") << "gallery-app" << QSize(16, 0) << QSize(16, 16);
56 QTest::newRow("gallery5") << "gallery-app" << QSize(24, 16) << QSize(24, 24);
57 QTest::newRow("gallery6") << "gallery-app" << QSize(24, 24) << QSize(24, 24);
58 }
59
60 void test_loadIcon()
61 {
62 QFETCH(QString, icon);
63 QFETCH(QSize, requestSize);
64 QFETCH(QSize, resultSize);
65
66 UnityThemeIconProvider provider("mockTheme");
67 QSize returnedSize;
68 const QPixmap p = provider.requestPixmap(icon, &returnedSize, requestSize);
69 QCOMPARE(p.size(), resultSize);
70 QCOMPARE(returnedSize, resultSize);
71 }
72};
73
74QTEST_MAIN(tst_IconProvider)
75
76#include "tst_iconprovider.moc"
077
=== added file 'tests/unit_x11/tst_iconprovider/tst_iconprovider.pro'
--- tests/unit_x11/tst_iconprovider/tst_iconprovider.pro 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_iconprovider/tst_iconprovider.pro 2015-02-19 08:47:10 +0000
@@ -0,0 +1,5 @@
1include(../test-include.pri)
2DEFINES += SRCDIR=\\\"$$PWD/\\\"
3
4SOURCES += \
5 tst_iconprovider.cpp
06
=== modified file 'tests/unit_x11/unit_x11.pro'
--- tests/unit_x11/unit_x11.pro 2015-02-10 16:47:59 +0000
+++ tests/unit_x11/unit_x11.pro 2015-02-19 08:47:10 +0000
@@ -4,6 +4,7 @@
4 tst_ubuntu_shape \4 tst_ubuntu_shape \
5 tst_page \5 tst_page \
6 tst_test \6 tst_test \
7 tst_iconprovider \
7 tst_inversemousearea \8 tst_inversemousearea \
8 tst_recreateview \9 tst_recreateview \
9 tst_statesaver \10 tst_statesaver \

Subscribers

People subscribed via source and target branches