Subject: [PATCH 2/2 staging] gnu: qtbase: Open links properly without xdg-utils in profile

From: Jakub Kądziołka <[email-masked]>
Date: Sun, 12 Jan 2020 16:47:09 +0100

* gnu/packages/patches/qtbase-use-xdg-open-in-store.patch: New file.
* gnu/packages/qt.scm (qtbase)[source][patches]: Apply the patch.
  [inputs]: Add a dependency on xdg-utils to get its store path.
  [arguments]: Add a new phase to patch the path into the source code.
---
 .../qtbase-use-xdg-open-in-store.patch        | 103 ++++++++++++++++++
 gnu/packages/qt.scm                           |  10 +-
 2 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/qtbase-use-xdg-open-in-store.patch

diff --git a/gnu/packages/patches/qtbase-use-xdg-open-in-store.patch b/gnu/packages/patches/qtbase-use-xdg-open-in-store.patch
new file mode 100644
index 0000000000..505fff13c2
--- /dev/null
+++ b/gnu/packages/patches/qtbase-use-xdg-open-in-store.patch
@@ -0,0 +1,103 @@
+To make Qt respect the user's settings for the preferred browser, use xdg-open
+even if it is not installed in the profile. The patch makes Qt always use
+xdg-open, and makes the path used easy to substitute when building.
+========================================================================
+--- qtbase-everywhere-src-5.12.6.orig/src/platformsupport/services/genericunix/qgenericunixservices.cpp	2020-01-01 20:47:16.775671802 +0100
++++ qtbase-everywhere-src-5.12.6/src/platformsupport/services/genericunix/qgenericunixservices.cpp	2020-01-01 20:56:22.167662035 +0100
+@@ -117,47 +117,6 @@
+     return QByteArrayLiteral("UNKNOWN");
+ }
+ 
+-static inline bool checkExecutable(const QString &candidate, QString *result)
+-{
+-    *result = QStandardPaths::findExecutable(candidate);
+-    return !result->isEmpty();
+-}
+-
+-static inline bool detectWebBrowser(const QByteArray &desktop,
+-                                    bool checkBrowserVariable,
+-                                    QString *browser)
+-{
+-    const char *browsers[] = {"google-chrome", "firefox", "mozilla", "opera"};
+-
+-    browser->clear();
+-    if (checkExecutable(QStringLiteral("xdg-open"), browser))
+-        return true;
+-
+-    if (checkBrowserVariable) {
+-        QByteArray browserVariable = qgetenv("DEFAULT_BROWSER");
+-        if (browserVariable.isEmpty())
+-            browserVariable = qgetenv("BROWSER");
+-        if (!browserVariable.isEmpty() && checkExecutable(QString::fromLocal8Bit(browserVariable), browser))
+-            return true;
+-    }
+-
+-    if (desktop == QByteArray("KDE")) {
+-        // Konqueror launcher
+-        if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+-            browser->append(QLatin1String(" exec"));
+-            return true;
+-        }
+-    } else if (desktop == QByteArray("GNOME")) {
+-        if (checkExecutable(QStringLiteral("gnome-open"), browser))
+-            return true;
+-    }
+-
+-    for (size_t i = 0; i < sizeof(browsers)/sizeof(char *); ++i)
+-        if (checkExecutable(QLatin1String(browsers[i]), browser))
+-            return true;
+-    return false;
+-}
+-
+ static inline bool launch(const QString &launcher, const QUrl &url)
+ {
+     const QString command = launcher + QLatin1Char(' ') + QLatin1String(url.toEncoded());
+@@ -297,6 +256,8 @@
+     return result;
+ }
+ 
++static QString xdg_open = QStringLiteral("@@GUIX:XDG-OPEN@@");
++
+ bool QGenericUnixServices::openUrl(const QUrl &url)
+ {
+     if (url.scheme() == QLatin1String("mailto")) {
+@@ -320,11 +281,7 @@
+     }
+ #endif
+ 
+-    if (m_webBrowser.isEmpty() && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) {
+-        qWarning("Unable to detect a web browser to launch '%s'", qPrintable(url.toString()));
+-        return false;
+-    }
+-    return launch(m_webBrowser, url);
++    return launch(xdg_open, url);
+ }
+ 
+ bool QGenericUnixServices::openDocument(const QUrl &url)
+@@ -337,11 +294,7 @@
+     }
+ #endif
+ 
+-    if (m_documentLauncher.isEmpty() && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) {
+-        qWarning("Unable to detect a launcher for '%s'", qPrintable(url.toString()));
+-        return false;
+-    }
+-    return launch(m_documentLauncher, url);
++    return launch(xdg_open, url);
+ }
+ 
+ #else
+diff -ur qtbase-everywhere-src-5.12.6.orig/src/platformsupport/services/genericunix/qgenericunixservices_p.h qtbase-everywhere-src-5.12.6/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+--- qtbase-everywhere-src-5.12.6.orig/src/platformsupport/services/genericunix/qgenericunixservices_p.h	2020-01-01 20:47:16.775671802 +0100
++++ qtbase-everywhere-src-5.12.6/src/platformsupport/services/genericunix/qgenericunixservices_p.h	2020-01-01 20:54:12.135664364 +0100
+@@ -65,10 +65,6 @@
+ 
+     bool openUrl(const QUrl &url) override;
+     bool openDocument(const QUrl &url) override;
+-
+-private:
+-    QString m_webBrowser;
+-    QString m_documentLauncher;
+ };
+ 
+ QT_END_NAMESPACE
diff --git a/gnu/packages/qt.scm b/gnu/packages/qt.scm
index 514577678e..0b1d372d8b 100644
--- a/gnu/packages/qt.scm
+++ b/gnu/packages/qt.scm
@@ -14,6 +14,7 @@
 ;;; Copyright © 2019, 2020 Marius Bakke <[email-masked]>
 ;;; Copyright © 2018 John Soo <[email-masked]>
 ;;; Copyright © 2020 Mike Rosset <[email-masked]>
+;;; Copyright © 2020 Jakub Kądziołka <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -349,7 +350,8 @@ developers using C++ or QML, a CSS & JavaScript like language.")
               (base32
                "09wz7zs1x5mpgs2y4xnl2zv3naqls4sz6v2arwl1fz2dsx4jddba"))
              ;; Use TZDIR to avoid depending on package "tzdata".
-             (patches (search-patches "qtbase-use-TZDIR.patch"))
+             (patches (search-patches "qtbase-use-TZDIR.patch"
+                                      "qtbase-use-xdg-open-in-store.patch"))
              (modules '((guix build utils)))
              (snippet
                ;; corelib uses bundled harfbuzz, md4, md5, sha3
@@ -407,6 +409,7 @@ developers using C++ or QML, a CSS & JavaScript like language.")
        ("xcb-util-keysyms" ,xcb-util-keysyms)
        ("xcb-util-renderutil" ,xcb-util-renderutil)
        ("xcb-util-wm" ,xcb-util-wm)
+       ("xdg-utils" ,xdg-utils)
        ("zlib" ,zlib)))
     (native-inputs
      `(("bison" ,bison)
@@ -428,6 +431,11 @@ developers using C++ or QML, a CSS & JavaScript like language.")
                             "qmake/library/qmakebuiltins.cpp")
                           (("/bin/sh") (which "sh")))
              #t))
+         (add-after 'configure 'patch-xdg-open
+           (lambda _
+             (substitute* '("src/platformsupport/services/genericunix/qgenericunixservices.cpp")
+                          (("@@GUIX:XDG-OPEN@@") (which "xdg-open")))
+             #t))
          (replace 'configure
            (lambda* (#:key outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
-- 
2.24.1