- Update to 3.7.0:

* QSvgRenderer is used with a cache for SVG icons, so that LXQt's
    icon handling could not be broken by intruding icon engines
	that register themselves for "svg" (like kiconthemes 5.80).
  * Allow runtime overriding of detachment of processes by
    setting QTXDG_START_DETACH_TRULY.
  * XTerm is added as a runtime dependency.
  * Code cleanup.
- Remove libqt5xdg-svg-render.patch: upstreamed

OBS-URL: https://build.opensuse.org/package/show/X11:LXQt/libqt5xdg?expand=0&rev=20
This commit is contained in:
Michael Vetter 2021-04-16 06:35:42 +00:00 committed by Git OBS Bridge
parent cafe3cf97b
commit 23b023fff2
7 changed files with 36 additions and 274 deletions

View File

@ -1,249 +0,0 @@
From 07bb4531fe90afed28785ae2ce1a5b3f8de1c022 Mon Sep 17 00:00:00 2001
From: tsujan <tsujan2000@gmail.com>
Date: Wed, 24 Mar 2021 14:24:55 +0430
Subject: [PATCH] Use QSvgRenderer for SVG icons (#247)
* Use QSvgRenderer for SVG icons
`QSvgRenderer` is used with a cache for both ordinary and colorized SVG icons. In this way, LXQt's icon handling cannot be broken by intruding icon engines, which register themselves for "svg" (see https://github.com/lxqt/libqtxdg/issues/246). Moreover, it does not depend on a specific code structure of `qtsvg` or any other icon engine.
* Just removed a redundant computation
* Used the same key structure for SVG cache
---
src/xdgiconloader/xdgiconloader.cpp | 179 ++++++++++++++++------------
1 file changed, 100 insertions(+), 79 deletions(-)
diff --git a/src/xdgiconloader/xdgiconloader.cpp b/src/xdgiconloader/xdgiconloader.cpp
index aeabda8..66d3dd8 100644
--- a/src/xdgiconloader/xdgiconloader.cpp
+++ b/src/xdgiconloader/xdgiconloader.cpp
@@ -53,6 +53,7 @@
#include <QImageReader>
#include <QXmlStreamReader>
#include <QFileSystemWatcher>
+#include <QSvgRenderer>
#include <private/qhexstring_p.h>
@@ -787,121 +788,141 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st
return cachedPixmap;
}
-// XXX: duplicated from qiconloader.cpp, because this symbol isn't exported :(
+// NOTE: For SVG, QSvgRenderer is used to prevent our icon handling from
+// being broken by icon engines that register themselves for SVG.
QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
{
- if (svgIcon.isNull())
- svgIcon = QIcon(filename);
+ QPixmap pm;
+ if (size.isEmpty())
+ return pm;
- // Bypass QIcon API, as that will scale by device pixel ratio of the
- // highest DPR screen since we're not passing on any QWindow.
- if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr)
- return engine->pixmap(size, mode, state);
+ QString key = QLatin1String("lxqt_")
+ % filename
+ % HexString<int>(mode)
+ % HexString<int>(state)
+ % HexString<int>(size.width())
+ % HexString<int>(size.height());
+ if (!QPixmapCache::find(key, &pm))
+ {
+ int icnSize = qMin(size.width(), size.height());
+ pm = QPixmap(icnSize, icnSize);
+ pm.fill(Qt::transparent);
- return QPixmap();
+ QSvgRenderer renderer;
+ if (renderer.load(filename))
+ {
+ QPainter p;
+ p.begin(&pm);
+ renderer.render(&p, QRect(0, 0, icnSize, icnSize));
+ p.end();
+ }
+
+ svgIcon = QIcon(pm);
+ if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr)
+ pm = engine->pixmap(size, mode, state);
+ QPixmapCache::insert(key, pm);
+ }
+
+ return pm;
}
static const QString STYLE = QStringLiteral("\n.ColorScheme-Text, .ColorScheme-NeutralText {color:%1;}\
\n.ColorScheme-Background {color:%2;}\
\n.ColorScheme-Highlight {color:%3;}");
-// Note: Qt palette does not have any colors for positive/negative text
+// NOTE: Qt palette does not have any colors for positive/negative text
// .ColorScheme-PositiveText,ColorScheme-NegativeText {color:%4;}
QPixmap ScalableFollowsColorEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
{
QPixmap pm;
- // see ScalableEntry::pixmap() for the reason
- if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr)
- pm = engine->pixmap(size, mode, state);
+ if (size.isEmpty())
+ return pm;
- // Note: not checking the QIcon::isNull(), because in Qt5.10 the isNull() is not reliable
- // for svg icons desierialized from stream (see https://codereview.qt-project.org/#/c/216086/)
- if (pm.isNull())
+ const QPalette pal = qApp->palette();
+ QString txtCol, bgCol, hCol;
+ if (mode == QIcon::Disabled)
+ {
+ txtCol = pal.color(QPalette::Disabled, QPalette::WindowText).name();
+ bgCol = pal.color(QPalette::Disabled, QPalette::Window).name();
+ hCol = pal.color(QPalette::Disabled, QPalette::Highlight).name();
+ }
+ else
+ {
+ if (mode == QIcon::Selected)
+ {
+ txtCol = pal.highlightedText().color().name();
+ bgCol = pal.highlight().color().name();
+ }
+ else // normal or active
+ {
+ txtCol = pal.windowText().color().name();
+ bgCol = pal.window().color().name();
+ }
+ hCol = pal.highlight().color().name();
+ }
+ QString key = QLatin1String("lxqt_")
+ % filename
+ % HexString<int>(mode)
+ % HexString<int>(state)
+ % HexString<int>(size.width())
+ % HexString<int>(size.height())
+ % txtCol % bgCol % hCol;
+ if (!QPixmapCache::find(key, &pm))
{
- // The following lines are adapted and updated from KDE's "kiconloader.cpp" ->
- // KIconLoaderPrivate::processSvg() and KIconLoaderPrivate::createIconImage().
- // They read the SVG color scheme of SVG icons and give images based on the icon mode.
- QHash<int, QByteArray> svg_buffers;
+ int icnSize = qMin(size.width(), size.height());
+ pm = QPixmap(icnSize, icnSize);
+ pm.fill(Qt::transparent);
+
QFile device{filename};
if (device.open(QIODevice::ReadOnly))
{
- const QPalette pal = qApp->palette();
- // Note: indexes are assembled as in qtsvg (QSvgIconEnginePrivate::hashKey())
- QMap<int, QString> style_sheets;
- style_sheets[(QIcon::Normal<<4)|QIcon::Off] = STYLE.arg(pal.windowText().color().name(), pal.window().color().name(), pal.highlight().color().name());
- style_sheets[(QIcon::Selected<<4)|QIcon::Off] = STYLE.arg(pal.highlightedText().color().name(), pal.highlight().color().name(), pal.highlightedText().color().name());
- QMap<int, QSharedPointer<QXmlStreamWriter> > writers;
- for (auto i = style_sheets.cbegin(); i != style_sheets.cend(); ++i)
- {
- writers[i.key()].reset(new QXmlStreamWriter{&svg_buffers[i.key()]});
- }
-
+ QString styleSheet = STYLE.arg(txtCol, bgCol, hCol);
+ QByteArray svgBuffer;
+ QXmlStreamWriter writer(&svgBuffer);
QXmlStreamReader xmlReader(&device);
while (!xmlReader.atEnd())
{
if (xmlReader.readNext() == QXmlStreamReader::StartElement
- && xmlReader.qualifiedName() == QLatin1String("style")
- && xmlReader.attributes().value(QLatin1String("id")) == QLatin1String("current-color-scheme"))
+ && xmlReader.qualifiedName() == QLatin1String("style")
+ && xmlReader.attributes().value(QLatin1String("id")) == QLatin1String("current-color-scheme"))
{
const auto attribs = xmlReader.attributes();
// store original data/text of the <style> element
- QString original_data;
+ QString origData;
while (xmlReader.tokenType() != QXmlStreamReader::EndElement)
{
if (xmlReader.tokenType() == QXmlStreamReader::Characters)
- original_data += xmlReader.text();
+ origData += xmlReader.text();
xmlReader.readNext();
}
- for (auto i = style_sheets.cbegin(); i != style_sheets.cend(); ++i)
- {
- QXmlStreamWriter & writer = *writers[i.key()];
- writer.writeStartElement(QLatin1String("style"));
- writer.writeAttributes(attribs);
- // Note: We're writting the original style text to leave
- // there "defaults" for unknown/unsupported classes.
- // Then appending our "overrides"
- writer.writeCharacters(original_data);
- writer.writeCharacters(*i);
- writer.writeEndElement();
- }
- } else if (xmlReader.tokenType() != QXmlStreamReader::Invalid)
- {
- for (auto i = style_sheets.cbegin(); i != style_sheets.cend(); ++i)
- {
- writers[i.key()]->writeCurrentToken(xmlReader);
- }
+ writer.writeStartElement(QLatin1String("style"));
+ writer.writeAttributes(attribs);
+ writer.writeCharacters(origData);
+ writer.writeCharacters(styleSheet);
+ writer.writeEndElement();
}
+ else if (xmlReader.tokenType() != QXmlStreamReader::Invalid)
+ writer.writeCurrentToken(xmlReader);
+ }
+
+ if (!svgBuffer.isEmpty())
+ {
+ QSvgRenderer renderer;
+ renderer.load(svgBuffer);
+ QPainter p;
+ p.begin(&pm);
+ renderer.render(&p, QRect(0, 0, icnSize, icnSize));
+ p.end();
}
- // duplicate the contets also for opposite state
- svg_buffers[(QIcon::Normal<<4)|QIcon::On] = svg_buffers[(QIcon::Normal<<4)|QIcon::Off];
- svg_buffers[(QIcon::Selected<<4)|QIcon::On] = svg_buffers[(QIcon::Selected<<4)|QIcon::Off];
}
- // use the QSvgIconEngine
- // - assemble the content as it is done by the operator <<(QDataStream &s, const QIcon &icon)
- // (the QSvgIconEngine::key() + QSvgIconEngine::write())
- // - create the QIcon from the content by usage of the QIcon::operator >>(QDataStream &s, const QIcon &icon)
- // (icon with the (QSvgIconEngine) will be used)
- QByteArray icon_arr;
- QDataStream str{&icon_arr, QIODevice::WriteOnly};
- str.setVersion(QDataStream::Qt_4_4);
- QHash<int, QString> filenames;
- filenames[0] = filename; // Note: filenames are ignored in the QSvgIconEngine::read()
- str << QStringLiteral("svg") << filenames << static_cast<int>(0)/*isCompressed*/ << svg_buffers << static_cast<int>(0)/*hasAddedPimaps*/;
-
- QDataStream str_read{&icon_arr, QIODevice::ReadOnly};
- str_read.setVersion(QDataStream::Qt_4_4);
-
- str_read >> svgIcon;
+
+ // Do not use this pixmap directly but first get the icon
+ // for QIcon::pixmap() to handle states and modes,
+ // especially the disabled mode.
+ svgIcon = QIcon(pm);
if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr)
pm = engine->pixmap(size, mode, state);
-
- // load the icon directly from file, if still null
- if (pm.isNull())
- {
- svgIcon = QIcon(filename);
- if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr)
- pm = engine->pixmap(size, mode, state);
- }
+ QPixmapCache::insert(key, pm);
}
return pm;

View File

@ -1,3 +1,16 @@
-------------------------------------------------------------------
Fri Apr 16 06:31:20 UTC 2021 - Michael Vetter <mvetter@suse.com>
- Update to 3.7.0:
* QSvgRenderer is used with a cache for SVG icons, so that LXQt's
icon handling could not be broken by intruding icon engines
that register themselves for "svg" (like kiconthemes 5.80).
* Allow runtime overriding of detachment of processes by
setting QTXDG_START_DETACH_TRULY.
* XTerm is added as a runtime dependency.
* Code cleanup.
- Remove libqt5xdg-svg-render.patch: upstreamed
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Mar 31 10:02:43 UTC 2021 - Michael Vetter <mvetter@suse.com> Wed Mar 31 10:02:43 UTC 2021 - Michael Vetter <mvetter@suse.com>

View File

@ -18,7 +18,7 @@
%define _name libqtxdg %define _name libqtxdg
Name: libqt5xdg Name: libqt5xdg
Version: 3.6.0 Version: 3.7.0
Release: 0 Release: 0
Summary: Qt implementation of xdg specs for lxqt Summary: Qt implementation of xdg specs for lxqt
License: GPL-3.0-only License: GPL-3.0-only
@ -27,14 +27,13 @@ URL: https://lxqt.org
Source: https://github.com/lxqt/libqtxdg/releases/download/%{version}/%{_name}-%{version}.tar.xz Source: https://github.com/lxqt/libqtxdg/releases/download/%{version}/%{_name}-%{version}.tar.xz
Source1: https://github.com/lxqt/libqtxdg/releases/download/%{version}/%{_name}-%{version}.tar.xz.asc Source1: https://github.com/lxqt/libqtxdg/releases/download/%{version}/%{_name}-%{version}.tar.xz.asc
Source2: %{name}.keyring Source2: %{name}.keyring
Patch0: libqt5xdg-svg-render.patch
BuildRequires: cmake >= 3.1.0 BuildRequires: cmake >= 3.1.0
BuildRequires: fdupes BuildRequires: fdupes
BuildRequires: gcc-c++ BuildRequires: gcc-c++
BuildRequires: libQt5Gui-private-headers-devel BuildRequires: libQt5Gui-private-headers-devel
BuildRequires: lxqt-build-tools-devel >= 0.8.0 BuildRequires: lxqt-build-tools-devel >= 0.9.0
BuildRequires: pkgconfig BuildRequires: pkgconfig
BuildRequires: pkgconfig(Qt5Core) >= 5.10 BuildRequires: pkgconfig(Qt5Core) >= 5.12
BuildRequires: pkgconfig(Qt5DBus) BuildRequires: pkgconfig(Qt5DBus)
BuildRequires: pkgconfig(Qt5Svg) BuildRequires: pkgconfig(Qt5Svg)
BuildRequires: pkgconfig(Qt5Test) BuildRequires: pkgconfig(Qt5Test)
@ -89,7 +88,6 @@ Tools for QtXdg.
%prep %prep
%setup -q -n %{_name}-%{version} %setup -q -n %{_name}-%{version}
%patch0 -p1
%build %build
%cmake %cmake

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0fefb362eac9120fccd401202f15d092a59fd1aaacfc4b885a33578cdd41cf42
size 76028

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQJJBAABCAAzFiEEGd/fOleb1QnbtXLYvnkwB60i334FAl+inicVHHRzdWphbjIw
MDBAZ21haWwuY29tAAoJEL55MAetIt9+0MUQANxt9szJ9nLEII02s3Wg0LXnkvIF
VP3teGldyr197cKjXDucg4lM9aCNJ9kUC5CoLLZmKueSzml3iS1FMvb5XAsIAyqd
BMWkmNC4dFvQtfEBwXNgPhBlnRSNy0JbHa+YZPpPuGFXcYBVN6/u3oVlW2T0ePFw
F7CkluC2AayCbcrMaKSIHV0og9/XoXF1osA3jE4PhfwUQPA2bx8WbUXCyjCwB4wc
WujkPYUxq7Ue+mRsTBbxrOshMDpw7dmnA/rx+itfh2AXil/oEVhQf2pnJ6DqZxPV
y8vON7qiYKtTO8jKvCgAEUwga/n2kW9JOWmXPRGbgouyFZRh5jSBVclQgIjj6X7h
F4XfqqBC0+52CuTrZYXpwb5V7hHDLsanQAlME814o7f+JioPWeEt96Ium38gD5dJ
UTcEpr3FCsxsN5q8L8q4iZrcmy4jqp8TPpluVXEzdQieOiaDOADedoJ6i5LZ8AbB
CFDsfI6+jkMQyxl/z4UsB85RakYabYD383wNm/6b/VFas58A0EgawUM5AhVYq9+D
KhPWV5/Zbxqv8qZ5SrhEyKu9D7bYBeUWTC87ewuaykEqfrR6QWrsAQFOhIoRqMtR
XzBY0w5SAVNdkyG/Yzli9sBVdUmpAq0kBWkmNnyCTVWnPZ2XoUvCKpiuJmkOOSW/
ujOaVyiHCFrh/PWy
=/ogB
-----END PGP SIGNATURE-----

3
libqtxdg-3.7.0.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5bb8f67432726429966c5ceaf6b7ce4608adfe8e6f3a1c4a9e2c65d7dcf2eae0
size 74756

17
libqtxdg-3.7.0.tar.xz.asc Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
iQJJBAABCAAzFiEEGd/fOleb1QnbtXLYvnkwB60i334FAmB4CwoVHHRzdWphbjIw
MDBAZ21haWwuY29tAAoJEL55MAetIt9+CQQP/Ak82Cyedhqqco041joqIl7eO9tg
IQPYF/PR0g7PvHGurJGsLXrwkJ4NofRGZzaPa8oWx7jw9KNRYGob93WmfLohFC5C
8Vo2TlHivX16XaFFqnoYiC6Vx9+qALIqYa9yj9KDnJBTH4uIxwI6o+YtkXqw4Gzg
V9/wNcDehJG8ZyurdgkihKUbeze7rfRV9x9HOG6Dku5n5v6zcXYhvjCHOlPKezf0
GMKvNaGlJsbv3hOfd2n5LuwPs0uigMymuqwxtyOscZoaMrHobB2A7x/n1pBenJA9
mBnDe3ZdJIGG0kkR6Vr86RWzoYduI8957FKrywfBFAPFKi9kQSAjKi+tInQe2Hak
ZBAEduQUhVa80MVaPOBZ4hc7kgQv2Mrv4K4tey8Us+LI1tmRnWe5vsKvg7qfqDPi
41fiDWAI1gj0xaZokbnOURiiFKI0DIgso1ez5Iu2MlGOz49oxMm2Wxeaxhz5SESy
/up3eeeiAXN9XvZAlX9CickmUpmTZFEnCtSXIXpZdVyMUO/4P/zgp7gfJ2oc6miJ
zhNpDRvk0wKCfFVnvHGUA8yQLBP+RoY4Z/TSOoWAzifA28hPD3Vj1HRuV2EgQnGC
DLZPUqswcAstUCXcGgMtNZ+nEtuPVtlm9udEk0xiidWY37ht6m3RMihLDeIQNbPM
/cRhq0B1Lr7J4kjE
=vHzj
-----END PGP SIGNATURE-----