I added partial integration KIO with WXConsoleSpawner. I will move code from 
WXConsoleSpawner to KIO and integrate it with QT/KDEFrameworks to displaying 
GUI in place of libgrattao.

My work aims to detect if started process belongs to console or GUI class. It 
uses some assumptions, that (for example) console app will read from terminal 
and GUI not. In other hand, GUI app probably will open Wayland socket or will 
be linked against Xcb/Xlib.

Currently, KIO requires separate app to working with detection. This 
application is mine and hosted on sourceforge.net. It is called 
WXConsoleSpawner. WXConsoleSpawner requires libgreattao. The most annoying 
think is I added to libgreattao features, which is compatible (currently) only 
with GTK4 backend.

Test it.
https://www.youtube.com/watch?v=Ed6oAI3RsyE
>From df7919f58844cddea93c2d54d1e00a749c3b0153 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C5=82awomir=20Lach?= <sla...@lach.art.pl>
Date: Tue, 28 Sep 2021 13:30:05 +0200
Subject: [PATCH] - First path to detect app type

---
 src/gui/openorexecutefileinterface.h          |  2 +
 src/gui/openurljob.cpp                        | 41 ++++++++++++++++---
 src/widgets/executablefileopendialog.cpp      |  8 ++++
 src/widgets/executablefileopendialog_p.h      |  7 ++--
 .../widgetsopenorexecutefilehandler.cpp       |  9 +++-
 5 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/src/gui/openorexecutefileinterface.h b/src/gui/openorexecutefileinterface.h
index 0f7060da..decb3007 100644
--- a/src/gui/openorexecutefileinterface.h
+++ b/src/gui/openorexecutefileinterface.h
@@ -71,6 +71,8 @@ Q_SIGNALS:
      */
     void executeFile(bool enable);
 
+    void executeFileWithTypeDetection(bool enable);
+
     /**
      * Emitted by promptUserOpenOrExecute() if user selects cancel.
      */
diff --git a/src/gui/openurljob.cpp b/src/gui/openurljob.cpp
index 620dfae1..ebe436ea 100644
--- a/src/gui/openurljob.cpp
+++ b/src/gui/openurljob.cpp
@@ -62,6 +62,7 @@ public:
 
 private:
     void executeCommand();
+    void callDetector();
     void handleBinaries(const QMimeType &mimeType);
     void handleBinariesHelper(const QString &localPath, bool isNativeBinary);
     void handleDesktopFiles();
@@ -70,7 +71,7 @@ private:
     void runLink(const QString &filePath, const QString &urlStr, const QString &optionalServiceName);
 
     void showOpenWithDialog();
-    void showOpenOrExecuteFileDialog(std::function<void(bool)> dialogFinished);
+    void showOpenOrExecuteFileDialog(std::function<void(bool)> dialogFinished, std::function<void(bool)>);
     void showUntrustedProgramWarningDialog(const QString &filePath);
 
     void startService(const KService::Ptr &service, const QList<QUrl> &urls);
@@ -373,9 +374,16 @@ void KIO::OpenUrlJobPrivate::handleBinaries(const QMimeType &mimeType)
             handleBinariesHelper(localPath, isNativeBinary);
         };
 
+        auto checkAppTypeAfterStart = [this, localPath, isNativeBinary](bool shouldExecute) {
+            // As above
+            Q_UNUSED(shouldExecute)
+
+            callDetector();
+        };
+
         // Ask the user for confirmation before executing this binary (for binaries
         // the dialog will only show Execute/Cancel)
-        showOpenOrExecuteFileDialog(dialogFinished);
+        showOpenOrExecuteFileDialog(dialogFinished, checkAppTypeAfterStart);
         return;
     }
 
@@ -437,6 +445,18 @@ void KIO::OpenUrlJobPrivate::showUntrustedProgramWarningDialog(const QString &fi
     });
     untrustedProgramHandler->showUntrustedProgramWarning(q, m_url.fileName());
 }
+void KIO::OpenUrlJobPrivate::callDetector()
+{
+    QStringList programPath;
+
+    programPath << this->m_url.toLocalFile();
+
+    KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QString::fromLatin1("WXConsoleSpawner"), programPath);
+    job->setStartupId(m_startupId);
+    job->setWorkingDirectory(m_url.adjusted(QUrl::RemoveFilename).toLocalFile());
+    q->addSubjob(job);
+    job->start();
+}
 
 void KIO::OpenUrlJobPrivate::executeCommand()
 {
@@ -537,7 +557,7 @@ void KIO::OpenUrlJobPrivate::handleDesktopFiles()
                     openInPreferredApp();
                 };
 
-                showOpenOrExecuteFileDialog(dialogFinished);
+                showOpenOrExecuteFileDialog(dialogFinished, NULL);
                 return;
             }
 
@@ -577,7 +597,12 @@ void KIO::OpenUrlJobPrivate::handleScripts()
             }
         };
 
-        showOpenOrExecuteFileDialog(dialogFinished);
+        auto detectAppType = [this](bool shouldExecute) {
+            Q_UNUSED(shouldExecute);
+            callDetector();
+        };
+
+        showOpenOrExecuteFileDialog(dialogFinished, detectAppType);
         return;
     }
 
@@ -636,7 +661,7 @@ void KIO::OpenUrlJobPrivate::showOpenWithDialog()
     openWithHandler->promptUserForApplication(q, {m_url}, m_mimeTypeName);
 }
 
-void KIO::OpenUrlJobPrivate::showOpenOrExecuteFileDialog(std::function<void(bool)> dialogFinished)
+void KIO::OpenUrlJobPrivate::showOpenOrExecuteFileDialog(std::function<void(bool)> dialogFinished, std::function<void(bool)> forDetection)
 {
     QMimeDatabase db;
     QMimeType mimeType = db.mimeTypeForName(m_mimeTypeName);
@@ -664,6 +689,12 @@ void KIO::OpenUrlJobPrivate::showOpenOrExecuteFileDialog(std::function<void(bool
         dialogFinished(shouldExecute);
     });
 
+    if (nullptr != forDetection)
+        QObject::connect(openOrExecuteFileHandler, &KIO::OpenOrExecuteFileInterface::executeFileWithTypeDetection, q, [this, forDetection](bool shouldExecute) {
+            m_runExecutables = shouldExecute;
+            forDetection(shouldExecute);
+        });
+
     openOrExecuteFileHandler->promptUserOpenOrExecute(q, m_mimeTypeName);
 }
 
diff --git a/src/widgets/executablefileopendialog.cpp b/src/widgets/executablefileopendialog.cpp
index 881ec6c2..39d416bd 100644
--- a/src/widgets/executablefileopendialog.cpp
+++ b/src/widgets/executablefileopendialog.cpp
@@ -38,6 +38,10 @@ ExecutableFileOpenDialog::ExecutableFileOpenDialog(ExecutableFileOpenDialog::Mod
 
     buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
 
+    QPushButton *guess = new QPushButton(i18n("&Run and detect app type"), this);
+
+    buttonBox->addButton(guess, QDialogButtonBox::AcceptRole);
+
     QVBoxLayout *layout = new QVBoxLayout(this);
     layout->addWidget(label);
     layout->addWidget(m_dontAskAgain);
@@ -59,6 +63,10 @@ ExecutableFileOpenDialog::ExecutableFileOpenDialog(ExecutableFileOpenDialog::Mod
             done(ExecuteFile);
         });
     }
+
+    connect(guess, &QPushButton::clicked, this, [=] {
+        done(ExecuteAndDetectType);
+    });
     connect(buttonBox, &QDialogButtonBox::rejected, this, &ExecutableFileOpenDialog::reject);
 }
 
diff --git a/src/widgets/executablefileopendialog_p.h b/src/widgets/executablefileopendialog_p.h
index 42ce83bd..213afcb3 100644
--- a/src/widgets/executablefileopendialog_p.h
+++ b/src/widgets/executablefileopendialog_p.h
@@ -9,6 +9,7 @@
 #define EXECUTABLEFILEOPENDIALOG_H
 
 #include <QDialog>
+#include <stdbool.h>
 
 class QCheckBox;
 
@@ -20,11 +21,9 @@ class ExecutableFileOpenDialog : public QDialog
     Q_OBJECT
 
 public:
-    enum ReturnCode {
-        OpenFile = 42,
-        ExecuteFile,
-    };
+    enum ReturnCode { OpenFile = 42, ExecuteFile, ExecuteAndDetectType };
 
+    bool guessAppType;
     enum Mode {
         // For executable scripts
         OpenOrExecute,
diff --git a/src/widgets/widgetsopenorexecutefilehandler.cpp b/src/widgets/widgetsopenorexecutefilehandler.cpp
index 320684d9..e6a7abf1 100644
--- a/src/widgets/widgetsopenorexecutefilehandler.cpp
+++ b/src/widgets/widgetsopenorexecutefilehandler.cpp
@@ -61,8 +61,13 @@ void KIO::WidgetsOpenOrExecuteFileHandler::promptUserOpenOrExecute(KJob *job, co
             return;
         }
 
-        const bool isExecute = result == ExecutableFileOpenDialog::ExecuteFile;
-        Q_EMIT executeFile(isExecute);
+        const bool isExecute = result == ExecutableFileOpenDialog::ExecuteFile || result == ExecutableFileOpenDialog::ExecuteAndDetectType;
+
+        if (result == ExecutableFileOpenDialog::ExecuteFile)
+            Q_EMIT executeFile(isExecute);
+        else {
+            Q_EMIT executeFileWithTypeDetection(isExecute);
+        }
 
         if (dialog->isDontAskAgainChecked()) {
             KConfigGroup cfgGroup(KSharedConfig::openConfig(QStringLiteral("kiorc")), "Executable scripts");
-- 
2.33.0

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to