[frameworks/kio] src/gui: openurljob: open a shell script rather than refuse it as a program

Méven Car <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 329e84b859525482a5a293ff8372bef95dc2f644 by Méven Car.
Committed on 10/08/2026 at 10:13.
Pushed by meven into branch 'master'.

openurljob: open a shell script rather than refuse it as a program

shared-mime-info 2.5.1 renamed application/x-shellscript to
text/x-shellscript and left application/x-executable as its only parent,
where a script used to be a kind of text/plain as well.

Being both is how a script was told apart from a binary, so a shell script
now reads as a binary and opening one where running is not allowed ends in
an error rather than in the editor. The same loss took the text editors
away from scripts, so one that nothing else claims is opened with whatever
opens text.

BUG: 522948
FIXED-IN: 6.30

M  +17   -1    src/gui/openurljob.cpp

https://invent.kde.org/frameworks/kio/-/commit/329e84b859525482a5a293ff8372bef95dc2f644

diff --git a/src/gui/openurljob.cpp b/src/gui/openurljob.cpp
index 5fc0b93261..f3701661e4 100644
--- a/src/gui/openurljob.cpp
+++ b/src/gui/openurljob.cpp
@@ -367,7 +367,13 @@ static bool isBinary(const QMimeType &mimeType)
 // e.g. ".sh", ".csh", ".py", ".js"
 static bool isTextScript(const QMimeType &mimeType)
 {
-    return (mimeType.inherits(QStringLiteral("application/x-executable")) && mimeType.inherits(QStringLiteral("text/plain")));
+    if (!mimeType.inherits(QStringLiteral("application/x-executable"))) {
+        return false;
+    }
+
+    // A type under text/ holds text whether or not the database spells out that it is a
+    // kind of text/plain, and shared-mime-info stopped saying so for shell scripts.
+    return mimeType.inherits(QStringLiteral("text/plain")) || mimeType.name().startsWith(QLatin1String("text/"));
 }
 
 // Helper function that returns whether a file has the execute bit set or not.
@@ -645,6 +651,16 @@ void KIO::OpenUrlJobPrivate::handleScripts()
 void KIO::OpenUrlJobPrivate::openInPreferredApp()
 {
     KService::Ptr service = KApplicationTrader::preferredService(m_mimeTypeName);
+    if (!service) {
+        // A script is text, and the program someone picked for text is the one to show it
+        // to them in. The MIME database used to say a script is a kind of text/plain and
+        // no longer does for every script, so the text program is asked for by name.
+        const QMimeType mimeType = QMimeDatabase().mimeTypeForName(m_mimeTypeName);
+        if (isTextScript(mimeType)) {
+            service = KApplicationTrader::preferredService(QStringLiteral("text/plain"));
+        }
+    }
+
     if (service) {
         // If file mimetype is set to xdg-open or kde-open, the file will be opened in endless loop
         // In these cases, showOpenWithDialog instead
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.