1 /*
2 SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "themetest.h"
8 #include "../src/plasma/private/svg_p.h"
9 #include <QApplication>
10 #include <QSignalSpy>
11 #include <QStandardPaths>
12
13 #include <KIconLoader>
14 #include <KIconTheme>
15 #include <KWindowSystem>
16
17 #include <config-plasma.h>
18 #if HAVE_X11
19 #include <KSelectionOwner>
20 #endif
21 #include <array>
22
cacheIdHash(const Plasma::SvgPrivate::CacheId & id)23 QString cacheIdHash(const Plasma::SvgPrivate::CacheId &id)
24 {
25 static const uint seed = 0x9e3779b9;
26 std::array<uint, 10> parts = {::qHash(id.width),
27 ::qHash(id.height),
28 ::qHash(id.elementName),
29 ::qHash(id.filePath),
30 ::qHash(id.status),
31 ::qHash(id.devicePixelRatio),
32 ::qHash(id.scaleFactor),
33 ::qHash(id.colorGroup),
34 ::qHash(id.extraFlags),
35 ::qHash(id.lastModified)};
36 return QString::number(qHashRange(parts.begin(), parts.end(), seed));
37 }
38
initTestCase()39 void ThemeTest::initTestCase()
40 {
41 // make our theme in search path
42 qputenv("XDG_DATA_DIRS", qgetenv("XDG_DATA_DIRS") + ":" + QFINDTESTDATA("data").toLocal8Bit());
43
44 // set default icon theme to test-theme
45 QStandardPaths::setTestModeEnabled(true);
46
47 m_theme = new Plasma::Theme("testtheme", this);
48 QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
49
50 if (!QDir(configPath).mkpath(QStringLiteral("."))) {
51 qFatal("Failed to create test configuration directory.");
52 }
53
54 QFile::remove(configPath);
55
56 QIcon::setThemeSearchPaths(QStringList() << QFINDTESTDATA("data/icons"));
57
58 KConfigGroup plasmaConfig(KSharedConfig::openConfig("plasmarc"), "Theme");
59 plasmaConfig.writeEntry("name", "default");
60 m_svg = new Plasma::Svg();
61
62 KIconTheme::forceThemeForTests("test-theme");
63 KSharedConfig::openConfig()->reparseConfiguration();
64 KIconTheme::reconfigure();
65 KIconLoader::global()->reconfigure(QString());
66 }
67
cleanupTestCase()68 void ThemeTest::cleanupTestCase()
69 {
70 // m_testIconsDir.removeRecursively();
71 delete m_svg;
72 }
73
loadSvgIcon()74 void ThemeTest::loadSvgIcon()
75 {
76 const auto *iconTheme = KIconLoader::global()->theme();
77 QString iconPath;
78 if (iconTheme) {
79 iconPath = iconTheme->iconPath(QLatin1String("konversation.svg"), 48, KIconLoader::MatchBest);
80 }
81
82 QVERIFY(iconTheme);
83 QVERIFY(iconTheme->isValid());
84 QVERIFY2(QFile::exists(iconPath), qPrintable(iconPath));
85 m_svg->setImagePath(iconPath);
86 QVERIFY(m_svg->isValid());
87
88 m_svg->pixmap(); // trigger the SVG being loaded
89
90 QFileInfo info(iconPath);
91
92 QString cacheId = cacheIdHash(Plasma::SvgPrivate::CacheId{48,
93 48,
94 iconPath,
95 QString(),
96 m_svg->status(),
97 m_svg->devicePixelRatio(),
98 m_svg->scaleFactor(),
99 m_svg->colorGroup(),
100 0,
101 static_cast<uint>(info.lastModified().toSecsSinceEpoch())});
102
103 QPixmap result;
104 QVERIFY(m_svg->theme()->findInCache(cacheId, result, info.lastModified().toSecsSinceEpoch()));
105
106 QSignalSpy spy(m_svg, SIGNAL(repaintNeeded()));
107 QVERIFY(spy.isValid());
108
109 KIconTheme::forceThemeForTests("test-theme-two");
110 // KIconloader needs changesto be emitted manually, ouch.
111 for (int i = 0; i < KIconLoader::LastGroup; i++) {
112 KIconLoader::emitChange(KIconLoader::Group(i));
113 }
114
115 spy.wait();
116 // Svg emitting repaintNeeded when something changes in KIconLoader means the svg loaded an icon
117 QVERIFY(spy.count() == 1);
118
119 QVERIFY(!m_svg->theme()->findInCache(cacheId, result));
120 }
121
testColors()122 void ThemeTest::testColors()
123 {
124 QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::NormalColorGroup), QColor(49, 54, 59));
125 QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::NormalColorGroup), QColor(239, 240, 241));
126 QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
127 QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
128 QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::NormalColorGroup), QColor(30, 146, 255));
129 QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
130 QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
131 QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::NormalColorGroup), QColor(252, 252, 252));
132 QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::NormalColorGroup), QColor(17, 209, 22));
133 QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::NormalColorGroup), QColor(201, 206, 59));
134 QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::NormalColorGroup), QColor(237, 21, 21));
135
136 QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup), QColor(49, 54, 59));
137 QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ButtonColorGroup), QColor(239, 240, 241));
138 QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
139 QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
140 QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ButtonColorGroup), QColor(30, 146, 255));
141 QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
142 QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
143 QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ButtonColorGroup), QColor(252, 252, 252));
144 QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ButtonColorGroup), QColor(17, 209, 23));
145 QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ButtonColorGroup), QColor(201, 206, 60));
146 QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ButtonColorGroup), QColor(237, 21, 22));
147
148 QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup), QColor(49, 54, 59));
149 QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ViewColorGroup), QColor(252, 252, 252));
150 QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
151 QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
152 QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ViewColorGroup), QColor(30, 146, 255));
153 QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
154 QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
155 QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ViewColorGroup), QColor(252, 252, 252));
156 QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ViewColorGroup), QColor(17, 209, 24));
157 QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ViewColorGroup), QColor(201, 206, 61));
158 QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ViewColorGroup), QColor(237, 21, 23));
159
160 QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup), QColor(239, 240, 241));
161 QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ComplementaryColorGroup), QColor(49, 54, 59));
162 QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ComplementaryColorGroup), QColor(61, 174, 230));
163 QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230));
164 QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ComplementaryColorGroup), QColor(40, 146, 255));
165 QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230));
166 QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230));
167 QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(252, 252, 252));
168 QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(17, 209, 25));
169 QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(201, 206, 62));
170 QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(237, 21, 24));
171 }
172
testCompositingChange()173 void ThemeTest::testCompositingChange()
174 {
175 // this test simulates the compositing change on X11
176 #if HAVE_X11
177 if (!KWindowSystem::isPlatformX11()) {
178 QSKIP("Test is only for X11");
179 }
180 QVERIFY(!KWindowSystem::compositingActive());
181
182 // image path should give us an opaque variant
183 QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/opaque/element.svg")));
184
185 QSignalSpy themeChangedSpy(m_theme, &Plasma::Theme::themeChanged);
186 QVERIFY(themeChangedSpy.isValid());
187
188 // fake the compositor
189 QSignalSpy compositingChangedSpy(KWindowSystem::self(), &KWindowSystem::compositingChanged);
190 QVERIFY(compositingChangedSpy.isValid());
191 QScopedPointer<KSelectionOwner> compositorSelection(new KSelectionOwner("_NET_WM_CM_S0"));
192 QSignalSpy claimedSpy(compositorSelection.data(), &KSelectionOwner::claimedOwnership);
193 QVERIFY(claimedSpy.isValid());
194 compositorSelection->claim(true);
195 QVERIFY(claimedSpy.wait());
196
197 QCOMPARE(compositingChangedSpy.count(), 1);
198 QVERIFY(KWindowSystem::compositingActive());
199 QVERIFY(themeChangedSpy.wait());
200 QCOMPARE(themeChangedSpy.count(), 1);
201 QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/element.svg")));
202
203 // remove compositor again
204 compositorSelection.reset();
205 QVERIFY(compositingChangedSpy.wait());
206 QCOMPARE(compositingChangedSpy.count(), 2);
207 QVERIFY(!KWindowSystem::compositingActive());
208 QVERIFY(themeChangedSpy.wait());
209 QCOMPARE(themeChangedSpy.count(), 2);
210 QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/opaque/element.svg")));
211 #endif
212 }
213
214 QTEST_MAIN(ThemeTest)
215