Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libqt5xdg for openSUSE:Factory checked in at 2021-11-09 23:54:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqt5xdg (Old) and /work/SRC/openSUSE:Factory/.libqt5xdg.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqt5xdg" Tue Nov 9 23:54:15 2021 rev:15 rq:929698 version:3.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libqt5xdg/libqt5xdg.changes 2021-04-17 00:01:57.569612457 +0200 +++ /work/SRC/openSUSE:Factory/.libqt5xdg.new.1890/libqt5xdg.changes 2021-11-09 23:54:29.095948787 +0100 @@ -1,0 +2,10 @@ +Fri Nov 5 15:48:22 UTC 2021 - Michael Vetter <mvet...@suse.com> + +- Update to 3.8.0: + * Added support for default terminal. + * Considered XDG_DATA_HOME when computing desktop entry id. + * Made sure that hicolor is searched before dash fallbacks. + * Considered Qt's fallback search paths when finding icons. + * Handle relative paths in qtxdg-desktop-file-start. + +------------------------------------------------------------------- Old: ---- libqtxdg-3.7.1.tar.xz libqtxdg-3.7.1.tar.xz.asc New: ---- libqtxdg-3.8.0.tar.xz libqtxdg-3.8.0.tar.xz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqt5xdg.spec ++++++ --- /var/tmp/diff_new_pack.T0IN4i/_old 2021-11-09 23:54:29.831949162 +0100 +++ /var/tmp/diff_new_pack.T0IN4i/_new 2021-11-09 23:54:29.831949162 +0100 @@ -18,7 +18,7 @@ %define _name libqtxdg Name: libqt5xdg -Version: 3.7.1 +Version: 3.8.0 Release: 0 Summary: Qt implementation of xdg specs for lxqt License: GPL-3.0-only @@ -31,9 +31,9 @@ BuildRequires: fdupes BuildRequires: gcc-c++ BuildRequires: libQt5Gui-private-headers-devel -BuildRequires: lxqt-build-tools-devel >= 0.9.0 +BuildRequires: lxqt-build-tools-devel >= 0.10.0 BuildRequires: pkgconfig -BuildRequires: pkgconfig(Qt5Core) >= 5.12 +BuildRequires: pkgconfig(Qt5Core) >= 5.15 BuildRequires: pkgconfig(Qt5DBus) BuildRequires: pkgconfig(Qt5Svg) BuildRequires: pkgconfig(Qt5Test) @@ -91,7 +91,7 @@ %build %cmake -make %{?_smp_mflags} +%make_build %install %cmake_install @@ -106,6 +106,9 @@ %license COPYING %doc AUTHORS %{_libdir}/libQt5Xdg.so.* +%dir %{_datadir}/lxqt +%{_datadir}/lxqt/lxqt-qtxdg.conf +%{_datadir}/lxqt/qtxdg.conf %files devel %{_datadir}/cmake/qt5xdg ++++++ libqtxdg-3.7.1.tar.xz -> libqtxdg-3.8.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/AUTHORS new/libqtxdg-3.8.0/AUTHORS --- old/libqtxdg-3.7.1/AUTHORS 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/AUTHORS 2021-11-05 10:57:03.000000000 +0100 @@ -1,5 +1,5 @@ Upstream Authors: - LXQt team: https://lxqt.org + LXQt team: https://lxqt-project.org/ Razor team: http://razor-qt.org Copyright: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/CHANGELOG new/libqtxdg-3.8.0/CHANGELOG --- old/libqtxdg-3.7.1/CHANGELOG 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/CHANGELOG 2021-11-05 10:57:03.000000000 +0100 @@ -1,3 +1,13 @@ +libqtxdg-3.8.0 / 2021-11-04 +=========================== + * Handle relative paths in qtxdg-desktop-file-start. + * Improved error message. + * Make sure hicolor is searched before dash fallbacks. + * Improved file manager command line handling in qtxdg-mat. + * Added default terminal. + * Consider XDG_DATA_HOME when computing desktop entry id. + * Consider Qt's fallback search paths when finding icons. + libqtxdg-3.7.1 / 2021-04-16 =========================== * Fixed compilation against Qt < 5.14. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/CMakeLists.txt new/libqtxdg-3.8.0/CMakeLists.txt --- old/libqtxdg-3.7.1/CMakeLists.txt 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/CMakeLists.txt 2021-11-05 10:57:03.000000000 +0100 @@ -13,12 +13,12 @@ set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(QTXDG_MAJOR_VERSION 3) -set(QTXDG_MINOR_VERSION 7) -set(QTXDG_PATCH_VERSION 1) +set(QTXDG_MINOR_VERSION 8) +set(QTXDG_PATCH_VERSION 0) set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION}) -set(LXQTBT_MINIMUM_VERSION "0.9.0") -set(QT_MINIMUM_VERSION "5.12.0") +set(LXQTBT_MINIMUM_VERSION "0.10.0") +set(QT_MINIMUM_VERSION "5.15.0") set(GLIB_MINIMUM_VERSION "2.41.0") # Mime Apps new implementation find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED) @@ -63,6 +63,8 @@ message(STATUS "Building ${PROJECT_NAME} with Qt ${Qt5Core_VERSION}") +file(GLOB QTXDG_CONFIG_FILES config/*.conf) + add_subdirectory(src) if(BUILD_TESTS) @@ -156,6 +158,11 @@ COMPONENT Devel ) +install(FILES ${QTXDG_CONFIG_FILES} + DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/lxqt" + COMPONENT Runtime +) + # uninstall target configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/config/lxqt-qtxdg.conf new/libqtxdg-3.8.0/config/lxqt-qtxdg.conf --- old/libqtxdg-3.7.1/config/lxqt-qtxdg.conf 1970-01-01 01:00:00.000000000 +0100 +++ new/libqtxdg-3.8.0/config/lxqt-qtxdg.conf 2021-11-05 10:57:03.000000000 +0100 @@ -0,0 +1 @@ +TerminalEmulator=qterminal.desktop diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/config/qtxdg.conf new/libqtxdg-3.8.0/config/qtxdg.conf --- old/libqtxdg-3.7.1/config/qtxdg.conf 1970-01-01 01:00:00.000000000 +0100 +++ new/libqtxdg-3.8.0/config/qtxdg.conf 2021-11-05 10:57:03.000000000 +0100 @@ -0,0 +1 @@ +TerminalEmulator=xterm.desktop diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgdefaultapps.cpp new/libqtxdg-3.8.0/src/qtxdg/xdgdefaultapps.cpp --- old/libqtxdg-3.7.1/src/qtxdg/xdgdefaultapps.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgdefaultapps.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -21,15 +21,38 @@ #include "xdgdefaultapps.h" #include "xdgdesktopfile.h" +#include "xdgdirs.h" #include "xdgmimeapps.h" #include <QSet> +#include <QSettings> #include <QString> #include <QStringList> #include <memory> #include <vector> + +static XdgDesktopFile *getTerminal(const QString &terminalName) +{ + XdgDesktopFile *t = new XdgDesktopFile{}; + if (t->load(terminalName) && t->isValid()) { + const QStringList cats = t->value(QL1S("Categories"), QString()).toString().split(QL1C(';'), Qt::SkipEmptyParts); + if (cats.contains(QL1S("TerminalEmulator"))) { + if (t->contains(QL1S("TryExec"))) { + if (t->tryExec()) { + return t; + } + } else { + return t; + } + } + } + + delete t; + return nullptr; +} + static QStringList getWebBrowserProtocolsGet() { // Protocols needed to quailify a application as the default browser @@ -52,24 +75,28 @@ return webBrowserProtocolsSet; } +static QString qtxdgConfigFilename() +{ + // first find the DE's qtxdg.conf file + QByteArray qtxdgConfig("qtxdg"); + QList<QByteArray> desktopsList = qgetenv("XDG_CURRENT_DESKTOP").toLower().split(':'); + if (!desktopsList.isEmpty()) { + qtxdgConfig = desktopsList.at(0) + '-' + qtxdgConfig; + } + + return QString::fromLocal8Bit(qtxdgConfig); +} + // returns the list of apps that are from category and support protocols static QList<XdgDesktopFile *> categoryAndMimeTypeApps(const QString &category, const QStringList &protocols) { XdgMimeApps db; QList<XdgDesktopFile *> apps = db.categoryApps(category); -#if (QT_VERSION < QT_VERSION_CHECK(5,14,0)) - const QSet<QString> protocolsSet = QSet<QString>::fromList(protocols); -#else const QSet<QString> protocolsSet = QSet<QString>(protocols.begin(), protocols.end()); -#endif QList<XdgDesktopFile*>::iterator it = apps.begin(); while (it != apps.end()) { const auto list = (*it)->mimeTypes(); -#if (QT_VERSION < QT_VERSION_CHECK(5,14,0)) - const QSet<QString> appSupportsSet = QSet<QString>::fromList(list); -#else const QSet<QString> appSupportsSet = QSet<QString>(list.begin(), list.end()); -#endif if (appSupportsSet.contains(protocolsSet) && (*it)->isShown()) { ++it; } else { @@ -128,6 +155,17 @@ return setDefaultApp(QL1S("inode/directory"), app); } +bool XdgDefaultApps::setTerminal(const XdgDesktopFile &app) +{ + if (!app.isValid()) + return false; + + const QString configFile = qtxdgConfigFilename(); + QSettings settings(QSettings::UserScope, configFile); + settings.setValue(QL1S("TerminalEmulator"), XdgDesktopFile::id(app.fileName())); + return true; +} + bool XdgDefaultApps::setWebBrowser(const XdgDesktopFile &app) { const QStringList protocols = @@ -140,6 +178,30 @@ return true; } +XdgDesktopFile *XdgDefaultApps::terminal() +{ + const QString configFile = qtxdgConfigFilename(); + QSettings settings(QSettings::UserScope, configFile); + const QString terminalName = settings.value(QL1S("TerminalEmulator"), QString()).toString(); + return getTerminal(terminalName); +} + +QList<XdgDesktopFile *> XdgDefaultApps::terminals() +{ + XdgMimeApps db; + QList<XdgDesktopFile *> terminalList = db.categoryApps(QL1S("TerminalEmulator")); + QList<XdgDesktopFile *>::iterator it = terminalList.begin(); + while (it != terminalList.end()) { + if ((*it)->isShown()) { + ++it; + } else { + delete *it; + it = terminalList.erase(it); + } + } + return terminalList; +} + // To be qualified as the default browser all protocols must be set to the same // valid application XdgDesktopFile *XdgDefaultApps::webBrowser() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgdefaultapps.h new/libqtxdg-3.8.0/src/qtxdg/xdgdefaultapps.h --- old/libqtxdg-3.7.1/src/qtxdg/xdgdefaultapps.h 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgdefaultapps.h 2021-11-05 10:57:03.000000000 +0100 @@ -70,6 +70,13 @@ static bool setFileManager(const XdgDesktopFile &app); /*! + * \brief Sets the default terminal emulator + * \param The app to be set as the default terminal emulator + * \return True if successful, false otherwise + */ + static bool setTerminal(const XdgDesktopFile &app); + + /*! * \brief Sets the default web browser * \param The app to be set as the default web browser * \return True if successful, false otherwise @@ -77,6 +84,18 @@ static bool setWebBrowser(const XdgDesktopFile &app); /*! + * \brief Gets the default terminal emulator + * \return The default terminal emulator. nullptr if it's not set or an error ocurred. + */ + static XdgDesktopFile *terminal(); + + /*! + * \brief Gets the installed terminal emulators + * \return A list of installed terminal emulators + */ + static QList<XdgDesktopFile *> terminals(); + + /*! * \brief Gets the default web browser * \return The default web browser. nullptr if it's not set or a error ocurred. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.cpp new/libqtxdg-3.8.0/src/qtxdg/xdgdesktopfile.cpp --- old/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgdesktopfile.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -34,6 +34,7 @@ #include "xdgicon.h" #include "application_interface.h" // generated interface for DBus org.freedesktop.Application #include "xdgmimeapps.h" +#include "xdgdefaultapps.h" #include <cstdlib> #include <unistd.h> @@ -87,7 +88,6 @@ static const QLatin1String iconKey("Icon"); // Helper functions prototypes -bool checkTryExec(const QString& progName); QString &doEscape(QString& str, const QHash<QChar,QChar> &repl); QString &doUnEscape(QString& str, const QHash<QChar,QChar> &repl); QString &escape(QString& str); @@ -459,21 +459,37 @@ if (startByDBus(action, urls)) return true; } - QStringList args = action.isEmpty() + QStringList args; + QStringList appArgs = action.isEmpty() ? q->expandExecString(urls) : XdgDesktopAction{*q, action}.expandExecString(urls); - if (args.isEmpty()) + if (appArgs.isEmpty()) return false; if (q->value(QLatin1String("Terminal")).toBool()) { - QString term = QString::fromLocal8Bit(qgetenv("TERM")); - if (term.isEmpty()) - term = QLatin1String("xterm"); + XdgDesktopFile *terminal = XdgDefaultApps::terminal(); + QString terminalCommand; + if (terminal != nullptr && terminal->isValid()) + { + terminalCommand = terminal->value(execKey).toString(); + } + else + { + qWarning() << "XdgDesktopFileData::startApplicationDetached(): Using fallback terminal (xterm)."; + terminalCommand = QStringLiteral("xterm"); + } + + delete terminal; - args.prepend(QLatin1String("-e")); - args.prepend(term); + args.append(QProcess::splitCommand(terminalCommand)); + args.append(QLatin1String("-e")); + args.append(appArgs); + } + else + { + args = appArgs; } bool detach = StartDetachTruly::instance(); @@ -613,11 +629,7 @@ if (!q->contains(used_key)) return QStringList(); } -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) return q->value(used_key).toString().split(QLatin1Char(';'), Qt::SkipEmptyParts); -#else - return q->value(used_key).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); -#endif } @@ -710,18 +722,10 @@ if (sect != section) { section = sect; -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) stream << QLatin1Char('[') << section << QLatin1Char(']') << Qt::endl; -#else - stream << QLatin1Char('[') << section << QLatin1Char(']') << endl; -#endif } QString key = path.section(QLatin1Char('/'), 1); -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) stream << key << QLatin1Char('=') << i.value().toString() << Qt::endl; -#else - stream << key << QLatin1Char('=') << i.value().toString() << endl; -#endif ++i; } return true; @@ -934,11 +938,7 @@ QStringList XdgDesktopFile::mimeTypes() const { -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) return value(mimeTypeKey).toString().split(QLatin1Char(';'), Qt::SkipEmptyParts); -#else - return value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); -#endif } @@ -1219,23 +1219,6 @@ } -bool checkTryExec(const QString& progName) -{ - if (progName.startsWith(QDir::separator())) - return QFileInfo(progName).isExecutable(); - - const QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - - for (const QString &dir : dirs) - { - if (QFileInfo(QDir(dir), progName).isExecutable()) - return true; - } - - return false; -} - - QString XdgDesktopFile::id(const QString &fileName, bool checkFileExists) { const QFileInfo f(fileName); @@ -1246,9 +1229,9 @@ } QString id = f.absoluteFilePath(); - const QStringList dataDirs = XdgDirs::dataDirs(); + const QStringList dirs = QStringList() << XdgDirs::dataHome() << XdgDirs::dataDirs(); - for (const QString &d : dataDirs) { + for (const QString &d : dirs) { if (id.startsWith(d)) { // remove only the first occurence id.replace(id.indexOf(d), d.size(), QString()); @@ -1346,14 +1329,23 @@ } // actually installed. If not, entry may not show in menus, etc. - QString s = value(QLatin1String("TryExec")).toString(); - if (!s.isEmpty() && ! checkTryExec(s)) - return false; + if (contains(QLatin1String("TryExec"))) + return tryExec(); return true; } +bool XdgDesktopFile::tryExec() const +{ + const QString progName = value(QLatin1String("TryExec")).toString(); + if (progName.isEmpty()) + return false; + + return (QStandardPaths::findExecutable(progName).isEmpty()) ? false : true; +} + + QString expandDynamicUrl(QString url) { const QStringList env = QProcess::systemEnvironment(); @@ -1472,11 +1464,7 @@ if (value.contains(QLatin1Char(';'))) { -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) map.insert(key, value.split(QLatin1Char(';'), Qt::SkipEmptyParts)); -#else - map.insert(key, value.split(QLatin1Char(';'), QString::SkipEmptyParts)); -#endif } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.h new/libqtxdg-3.8.0/src/qtxdg/xdgdesktopfile.h --- old/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.h 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgdesktopfile.h 2021-11-05 10:57:03.000000000 +0100 @@ -242,6 +242,15 @@ */ bool isSuitable(bool excludeHidden = true, const QString &environment = QString()) const; + /*! Check if the executable file on disk used to determine if the program + is actually installed. If the path is not an absolute path, the file + is looked up in the $PATH environment variable. + Check TryExec entry existence with contains(). + @return false if the file is not present or if it is not executable. + If the TryExec entry isn't present returns false + */ + bool tryExec() const; + protected: virtual QString prefix() const { return QLatin1String("Desktop Entry"); } virtual bool check() const { return true; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgdirs.cpp new/libqtxdg-3.8.0/src/qtxdg/xdgdirs.cpp --- old/libqtxdg-3.7.1/src/qtxdg/xdgdirs.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgdirs.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -263,11 +263,7 @@ QStringList XdgDirs::dataDirs(const QString &postfix) { QString d = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) QStringList dirs = d.split(QLatin1Char(':'), Qt::SkipEmptyParts); -#else - QStringList dirs = d.split(QLatin1Char(':'), QString::SkipEmptyParts); -#endif if (dirs.isEmpty()) { dirs.append(QString::fromLatin1("/usr/local/share")); @@ -295,11 +291,7 @@ if (env.isEmpty()) dirs.append(QString::fromLatin1("/etc/xdg")); else -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) dirs = env.split(QLatin1Char(':'), Qt::SkipEmptyParts); -#else - dirs = env.split(QLatin1Char(':'), QString::SkipEmptyParts); -#endif cleanAndAddPostfix(dirs, postfix); return dirs; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgmenu.cpp new/libqtxdg-3.8.0/src/qtxdg/xdgmenu.cpp --- old/libqtxdg-3.7.1/src/qtxdg/xdgmenu.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgmenu.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -410,11 +410,7 @@ return QDomElement(); -#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) const QStringList names = path.split(QLatin1Char('/'), Qt::SkipEmptyParts); -#else - const QStringList names = path.split(QLatin1Char('/'), QString::SkipEmptyParts); -#endif QDomElement el = baseElement; for (const QString &n : names) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/qtxdg/xdgmenuwidget.cpp new/libqtxdg-3.8.0/src/qtxdg/xdgmenuwidget.cpp --- old/libqtxdg-3.7.1/src/qtxdg/xdgmenuwidget.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/qtxdg/xdgmenuwidget.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -165,7 +165,7 @@ return; Q_Q(XdgMenuWidget); - XdgAction *a = qobject_cast<XdgAction*>(q->actionAt(event->pos())); + XdgAction *a = qobject_cast<XdgAction*>(q->actionAt(mDragStartPosition)); if (!a) return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/tools/mat/CMakeLists.txt new/libqtxdg-3.8.0/src/tools/mat/CMakeLists.txt --- old/libqtxdg-3.7.1/src/tools/mat/CMakeLists.txt 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/tools/mat/CMakeLists.txt 2021-11-05 10:57:03.000000000 +0100 @@ -7,6 +7,7 @@ defwebbrowsermatcommand.cpp defemailclientmatcommand.cpp deffilemanagermatcommand.cpp + defterminalmatcommand.cpp qtxdg-mat.cpp ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/tools/mat/deffilemanagermatcommand.cpp new/libqtxdg-3.8.0/src/tools/mat/deffilemanagermatcommand.cpp --- old/libqtxdg-3.7.1/src/tools/mat/deffilemanagermatcommand.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/tools/mat/deffilemanagermatcommand.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -94,6 +94,11 @@ return CommandLineError; } + if (!isDefFileManagerNameSet && !posArgs.empty()) { + *errorMessage = QSL("To set the default file manager use the -s/--set option"); + return CommandLineError; + } + if (isListAvailableSet && (isDefFileManagerNameSet || !posArgs.empty())) { *errorMessage = QSL("list-available can't be used with other options and doesn't take arguments"); return CommandLineError; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/tools/mat/defterminalmatcommand.cpp new/libqtxdg-3.8.0/src/tools/mat/defterminalmatcommand.cpp --- old/libqtxdg-3.7.1/src/tools/mat/defterminalmatcommand.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/libqtxdg-3.8.0/src/tools/mat/defterminalmatcommand.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -0,0 +1,187 @@ +/* + * libqtxdg - An Qt implementation of freedesktop.org xdg specs + * Copyright (C) 2021 Lu??s Pereira <luis.artur.pere...@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "defterminalmatcommand.h" + +#include "matglobals.h" +#include "xdgmacros.h" +#include "xdgdefaultapps.h" +#include "xdgdesktopfile.h" + +#include <QCommandLineOption> +#include <QCommandLineParser> +#include <QCoreApplication> +#include <QDebug> +#include <QFileInfo> +#include <QString> +#include <QStringList> + +#include <iostream> + +enum DefTerminalCommandMode { + CommandModeGetDefTerminal, + CommandModeSetDefTerminal, + CommandModeListAvailableTerminals, +}; + +struct DefTerminalData { + DefTerminalData() : mode(CommandModeGetDefTerminal) {} + + DefTerminalCommandMode mode; + QString defTerminalName; +}; + +static CommandLineParseResult parseCommandLine(QCommandLineParser *parser, DefTerminalData *data, QString *errorMessage) +{ + parser->clearPositionalArguments(); + parser->setApplicationDescription(QL1S("Get/Set the default terminal")); + + parser->addPositionalArgument(QL1S("def-terminal"), QL1S()); + + const QCommandLineOption defTerminalNameOption(QStringList() << QSL("s") << QSL("set"), + QSL("Terminal to be set as default"), QSL("terminal")); + + const QCommandLineOption listAvailableOption(QStringList() << QSL("l") << QSL("list-available"), + QSL("List available terminals")); + + parser->addOption(defTerminalNameOption); + parser->addOption(listAvailableOption); + const QCommandLineOption helpOption = parser->addHelpOption(); + const QCommandLineOption versionOption = parser->addVersionOption(); + + if (!parser->parse(QCoreApplication::arguments())) { + *errorMessage = parser->errorText(); + return CommandLineError; + } + + if (parser->isSet(versionOption)) { + return CommandLineVersionRequested; + } + + if (parser->isSet(helpOption)) { + return CommandLineHelpRequested; + } + + const bool isListAvailableSet = parser->isSet(listAvailableOption); + const bool isDefTerminalNameSet = parser->isSet(defTerminalNameOption); + QString defTerminalName; + + if (isDefTerminalNameSet) + defTerminalName = parser->value(defTerminalNameOption); + + QStringList posArgs = parser->positionalArguments(); + posArgs.removeAt(0); + + if (isDefTerminalNameSet && !posArgs.empty()) { + *errorMessage = QSL("Extra arguments given: "); + errorMessage->append(posArgs.join(QLatin1Char(','))); + return CommandLineError; + } + + if (!isDefTerminalNameSet && !posArgs.empty()) { + *errorMessage = QSL("To set the default terminal use the -s/--set option"); + return CommandLineError; + } + + if (isListAvailableSet && (isDefTerminalNameSet || !posArgs.empty())) { + *errorMessage = QSL("list-available can't be used with other options and doesn't take arguments"); + return CommandLineError; + } + + if (isListAvailableSet) { + data->mode = CommandModeListAvailableTerminals; + } else { + data->mode = isDefTerminalNameSet ? CommandModeSetDefTerminal: CommandModeGetDefTerminal; + data->defTerminalName = defTerminalName; + } + + return CommandLineOk; +} + +DefTerminalMatCommand::DefTerminalMatCommand(QCommandLineParser *parser) + : MatCommandInterface(QL1S("def-terminal"), + QSL("Get/Set the default terminal"), + parser) +{ + Q_CHECK_PTR(parser); +} + +DefTerminalMatCommand::~DefTerminalMatCommand() = default; + +int DefTerminalMatCommand::run(const QStringList & /*arguments*/) +{ + bool success = true; + DefTerminalData data; + QString errorMessage; + if (!MatCommandInterface::parser()) { + qFatal("DefTerminalMatCommand::run: MatCommandInterface::parser() returned a null pointer"); + } + switch(parseCommandLine(parser(), &data, &errorMessage)) { + case CommandLineOk: + break; + case CommandLineError: + std::cerr << qPrintable(errorMessage); + std::cerr << "\n\n"; + std::cerr << qPrintable(parser()->helpText()); + return EXIT_FAILURE; + case CommandLineVersionRequested: + showVersion(); + Q_UNREACHABLE(); + case CommandLineHelpRequested: + showHelp(); + Q_UNREACHABLE(); + } + + if (data.mode == CommandModeListAvailableTerminals) { + const auto terminals = XdgDefaultApps::terminals(); + for (const auto *terminal : terminals) { + QFileInfo fi{terminal->fileName()}; + std::cout << qPrintable(fi.fileName()) << "\n"; + } + + qDeleteAll(terminals); + return EXIT_SUCCESS; + } + + if (data.mode == CommandModeGetDefTerminal) { // Get default terminal + XdgDesktopFile *defTerminal = XdgDefaultApps::terminal(); + if (defTerminal != nullptr && defTerminal->isValid()) { + QFileInfo f(defTerminal->fileName()); + std::cout << qPrintable(f.fileName()) << "\n"; + delete defTerminal; + } + } else { // Set default terminal + XdgDesktopFile toSetDefTerminal; + if (toSetDefTerminal.load(data.defTerminalName)) { + if (XdgDefaultApps::setTerminal(toSetDefTerminal)) { + std::cout << qPrintable(QSL("Set '%1' as the default terminal\n").arg(toSetDefTerminal.fileName())); + } else { + std::cerr << qPrintable(QSL("Could not set '%1' as the default terminal\n").arg(toSetDefTerminal.fileName())); + success = false; + } + } else { // could not load application file + std::cerr << qPrintable(QSL("Could not find find '%1'\n").arg(data.defTerminalName)); + success = false; + } + } + + return success ? EXIT_SUCCESS : EXIT_FAILURE; +} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/tools/mat/defterminalmatcommand.h new/libqtxdg-3.8.0/src/tools/mat/defterminalmatcommand.h --- old/libqtxdg-3.7.1/src/tools/mat/defterminalmatcommand.h 1970-01-01 01:00:00.000000000 +0100 +++ new/libqtxdg-3.8.0/src/tools/mat/defterminalmatcommand.h 2021-11-05 10:57:03.000000000 +0100 @@ -0,0 +1,34 @@ +/* + * libqtxdg - An Qt implementation of freedesktop.org xdg specs + * Copyright (C) 2021 Lu??s Pereira <luis.artur.pere...@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef DEFTERMINALMATCOMMAND_H +#define DEFTERMINALMATCOMMAND_H + +#include "matcommandinterface.h" + +class DefTerminalMatCommand : public MatCommandInterface { +public: + explicit DefTerminalMatCommand(QCommandLineParser *parser); + ~DefTerminalMatCommand() override; + + int run(const QStringList &arguments) override; +}; + +#endif // DEFTERMINALMATCOMMAND_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/tools/mat/qtxdg-mat.cpp new/libqtxdg-3.8.0/src/tools/mat/qtxdg-mat.cpp --- old/libqtxdg-3.7.1/src/tools/mat/qtxdg-mat.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/tools/mat/qtxdg-mat.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -25,6 +25,7 @@ #include "defwebbrowsermatcommand.h" #include "defemailclientmatcommand.h" #include "deffilemanagermatcommand.h" +#include "defterminalmatcommand.h" #include "xdgmacros.h" @@ -88,6 +89,9 @@ MatCommandInterface *const defFileManagerCmd = new DefFileManagerMatCommand(&parser); manager->add(defFileManagerCmd); + MatCommandInterface *const defTerminalCmd = new DefTerminalMatCommand(&parser); + manager->add(defTerminalCmd); + // Find out the positional arguments. parser.parse(QCoreApplication::arguments()); const QStringList args = parser.positionalArguments(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/src/xdgiconloader/xdgiconloader.cpp new/libqtxdg-3.8.0/src/xdgiconloader/xdgiconloader.cpp --- old/libqtxdg-3.7.1/src/xdgiconloader/xdgiconloader.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/src/xdgiconloader/xdgiconloader.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -48,9 +48,7 @@ #include <QtCore/QList> #include <QtCore/QDir> #include <QtCore/QSettings> -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) #include <QtCore/QStringView> -#endif #include <QtGui/QPainter> #include <QImageReader> #include <QXmlStreamReader> @@ -111,11 +109,7 @@ { public: explicit QIconCacheGtkReader(const QString &themeDir); -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) QVector<const char *> lookup(QStringView); -#else - QVector<const char *> lookup(const QStringRef &); -#endif bool isValid() const { return m_isValid; } bool reValid(bool infoRefresh); private: @@ -226,11 +220,7 @@ For example, this would return { "32x32/apps", "24x24/apps" , ... } */ -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) QVector<const char *> QIconCacheGtkReader::lookup(QStringView name) -#else -QVector<const char *> QIconCacheGtkReader::lookup(const QStringRef &name) -#endif { QVector<const char *> ret; if (!isValid() || name.isEmpty()) @@ -350,7 +340,6 @@ m_parents = indexReader.value( QLatin1String("Icon Theme/Inherits")).toStringList(); m_parents.removeAll(QString()); - m_parents.removeAll(QLatin1String("hicolor")); // Ensure a default platform fallback for all themes if (m_parents.isEmpty()) { @@ -412,11 +401,7 @@ const QString xpmext(QLatin1String(".xpm")); -#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) QStringView iconNameFallback(iconName); -#else - QStringRef iconNameFallback(&iconName); -#endif // Iterate through all icon's fallbacks in current theme if (info.entries.isEmpty()) { @@ -499,6 +484,38 @@ if (!info.entries.isEmpty()) // success break; } + + // make sure that hicolor is also searched before dash fallbacks + if (info.entries.isEmpty() + && !parents.contains(QLatin1String("hicolor")) + && !visited.contains(QLatin1String("hicolor"))) { + info = findIconHelper(QLatin1String("hicolor"), iconName, visited); + } + } + + if (info.entries.isEmpty()) { + // Also, consider Qt's fallback search paths (which are not defined by Freedesktop) + // if the icon is not found in any inherited theme + const auto fallbackPaths = QIcon::fallbackSearchPaths(); + for (const auto &fallbackPath : fallbackPaths) { + const QString pngPath = fallbackPath + QLatin1Char('/') + iconName + pngext; + if (QFile::exists(pngPath)) { + PixmapEntry *iconEntry = new PixmapEntry; + QIconDirInfo dirInfo(fallbackPath); + iconEntry->dir = dirInfo; + iconEntry->filename = pngPath; + info.entries.prepend(iconEntry); + } else { + const QString svgPath = fallbackPath + QLatin1Char('/') + iconName + svgext; + if (gSupportsSvg && QFile::exists(svgPath)) { + ScalableEntry *iconEntry = new ScalableEntry; + QIconDirInfo dirInfo(fallbackPath); + iconEntry->dir = dirInfo; + iconEntry->filename = svgPath; + info.entries.append(iconEntry); + } + } + } } if (dashFallback && info.entries.isEmpty()) { @@ -554,23 +571,18 @@ QStringList visited; auto info = findIconHelper(theme_name, name, visited, true); if (info.entries.isEmpty()) { - const auto hicolorInfo = findIconHelper(QLatin1String("hicolor"), name, visited, true); - if (hicolorInfo.entries.isEmpty()) { - const auto unthemedInfo = unthemedFallback(name, QIcon::themeSearchPaths()); - if (unthemedInfo.entries.isEmpty()) { - /* Freedesktop standard says to look in /usr/share/pixmaps last */ - const QStringList pixmapPath = (QStringList() << QString::fromLatin1("/usr/share/pixmaps")); - const auto pixmapInfo = unthemedFallback(name, pixmapPath); - if (pixmapInfo.entries.isEmpty()) { - return QThemeIconInfo(); - } else { - return pixmapInfo; - } + const auto unthemedInfo = unthemedFallback(name, QIcon::themeSearchPaths()); + if (unthemedInfo.entries.isEmpty()) { + /* Freedesktop standard says to look in /usr/share/pixmaps last */ + const QStringList pixmapPath = (QStringList() << QString::fromLatin1("/usr/share/pixmaps")); + const auto pixmapInfo = unthemedFallback(name, pixmapPath); + if (pixmapInfo.entries.isEmpty()) { + return QThemeIconInfo(); } else { - return unthemedInfo; + return pixmapInfo; } } else { - return hicolorInfo; + return unthemedInfo; } } else { return info; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqtxdg-3.7.1/util/qtxdg-desktop-file-start.cpp new/libqtxdg-3.8.0/util/qtxdg-desktop-file-start.cpp --- old/libqtxdg-3.7.1/util/qtxdg-desktop-file-start.cpp 2021-04-16 11:29:21.000000000 +0200 +++ new/libqtxdg-3.8.0/util/qtxdg-desktop-file-start.cpp 2021-11-05 10:57:03.000000000 +0100 @@ -50,20 +50,21 @@ QStringList userArgs = parser.positionalArguments(); const QString userFileName = userArgs.takeFirst(); - const QFileInfo fileInfo(userFileName); - const QString canonicalFileName = fileInfo.canonicalFilePath(); - if (!fileInfo.exists()) { - printErr(QString::fromLatin1("File %1 does not exist\n").arg(userFileName)); - return EXIT_FAILURE; + const QFileInfo fileInfo(userFileName); + if (fileInfo.isAbsolute()) { + if (!fileInfo.exists()) { + printErr(QString::fromLatin1("File %1 does not exist\n").arg(userFileName)); + return EXIT_FAILURE; + } } XdgDesktopFile f; - const bool valid = f.load(canonicalFileName); + const bool valid = f.load(userFileName); if (valid) { f.startDetached(userArgs); } else { - printErr(QString::fromLatin1("%1 is not a valid .desktop file\n").arg(canonicalFileName)); + printErr(QString::fromLatin1("%1 doesn't exist or isn't a valid .desktop file\n").arg(userFileName)); return EXIT_FAILURE; }