This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Kio.KRun Segmentation fault in plasma2 widget

Tags: None
(comma "," separated)
nicolaf
Registered Member
Posts
4
Karma
0
I'm playing with plasma widget development, I am currently trying to write a widget to launch a .desktop file. I have some problems finding the documentation but finally I found a way to launch a program looking in the official SystemLoadViewer sources.
[kdeplasma-addons.git] / applets / systemloadviewer / package / contents / ui / SystemLoadViewer.qml
Initialization at line 79 and launch at line 238.

Watching the program run I undestand that
Code: Select all
kRun.openUrl()

accepts a string representing a file to be opened with the default associated application or a .desktop file to launch.

The segmentation fault
I tested with various files.
  • Copy-paste from the example to launch "sysguard" with the url obtained from the "apps" DataSource works
  • Using the url "/usr/share/applications/org.kde.ksysguard.desktop" (it is the same string returned by the "apps" DataSource) works
  • If I try with another .desktop file inside my home folder segfault
  • If I copy the file "org.kde.ksysguard.desktop" in another directory and try with the new path segfault
  • If I try to execute a bash script, the script will instead open in kate. Not what I was expecting but it works
  • Using the url of a PDF file will open the file with Okular works
  • Using the url of a binary application "/usr/bin/ksysguard" don't work and the openUrl() function returns an error value. No segfault so I think this is the expected behaviour.

I tested the widget directly in my plasma desktop and also using "plasmawindowed". The segfault happen in both cases but with the former I can see the console log.
Even if I am feeding the wrong data to the function I don't think the segfault is the expected behaviour. Maybe someone more expert can take a loot at this problem.
I'm using an updated kubuntu 15.04.
Code: Select all
$ kf5-config --version
Qt: 5.4.1
KDE Frameworks: 5.9.0
kf5-config: 1.0

Plasma version 5.3.1.
I'm available to give more info if needed, just ask.

Still searching a solution
If I can't launch an executable this way maybe this isn't the correct function. I am unable to find a documentation or source code for the QML implementation of "Kio.KRun". Inspecting the properties with javascript shows only
Code: Select all
qml: krun property: objectName =
qml: krun property: objectNameChanged = function() { [code] }
qml: krun property: openUrl = function() { [code] }

So "openUrl()" appears to be the only function available, maybe KRun it's the wrong tool.

I found the interesting Plasma2 / Service but I don't know how to find the available DataSource ID's and the" operationDescription". I'm currently stuck and need some direction.

Thanks for the help.

---
Edit 2015-07-26:
Fix the report about the bash script

Last edited by nicolaf on Sun Jul 26, 2015 3:24 pm, edited 1 time in total.
User avatar
einar
Administrator
Posts
3402
Karma
7
OS
You may want to send your enquiries also to the plasma-devel mailing list.


"Violence is the last refuge of the incompetent."
Image
Plasma FAQ maintainer - Plasma programming with Python
nicolaf
Registered Member
Posts
4
Karma
0
einar wrote:You may want to send your enquiries also to the plasma-devel mailing list.

Thanks, I sent a message to the plasma-devel mailing list. The message had probably too few informations and for now nobody replied.

Meanwhile I finally succeeded in obtaining an useful backtrace:

Code: Select all
#0 KSycocaEntry::entryPath() at /build/buildd/kservice-5.9.0/obj-x86_64-linux-gnu/src/../../src/sycoca/ksycocaentry.cpp:59
#1 KRun::runService() at /build/buildd/kio-5.9.0/obj-x86_64-linux-gnu/src/widgets/../../../src/widgets/krun.cpp:709
#2 KRun::run() at /build/buildd/kio-5.9.0/obj-x86_64-linux-gnu/src/widgets/../../../src/widgets/krun.cpp:703
#3 KRunProxy::openUrl() at /build/buildd/kdeclarative-5.9.0/obj-x86_64-linux-gnu/src/qmlcontrols/kioplugin/../../../../src/qmlcontrols/kioplugin/krunproxy.cpp:48
#4 qt_static_metacall() at /build/buildd/kdeclarative-5.9.0/obj-x86_64-linux-gnu/src/qmlcontrols/kioplugin/moc_krunproxy.cpp:69
#5 KRunProxy::qt_metacall() at /build/buildd/kdeclarative-5.9.0/obj-x86_64-linux-gnu/src/qmlcontrols/kioplugin/moc_krunproxy.cpp:102
#6 CallMethod() at /build/buildd/qtdeclarative-opensource-src-5.4.1/src/qml/jsruntime/qv4qobjectwrapper.cpp:1152
#7 CallPrecise() at /build/buildd/qtdeclarative-opensource-src-5.4.1/src/qml/jsruntime/qv4qobjectwrapper.cpp:1404
#8 QV4::QObjectMethod::callInternal() at /build/buildd/qtdeclarative-opensource-src-5.4.1/src/qml/jsruntime/qv4qobjectwrapper.cpp:1889
#9 call() at /build/buildd/qtdeclarative-opensource-src-5.4.1/src/qml/jsruntime/qv4object_p.h:278
#10 QV4::Runtime::callProperty() at /build/buildd/qtdeclarative-opensource-src-5.4.1/src/qml/jsruntime/qv4runtime.cpp:934

In frame #3 I discovered the "krun" used in QML is implemented in KRunProxy. The only method available is effectively openUrl():
Code: Select all
bool KRunProxy::openUrl(const QString &filePath)
{
    QMimeDatabase db;
    QMimeType mime = db.mimeTypeForFile(filePath);
    const QString fileMymeType = mime.name();

    if (fileMymeType == QStringLiteral("application/x-executable") || !mime.isValid()) {
        //for security reasons we should not be able to execute applications.
        //We should use its desktop file to access it.
        return false;
    }

    if (fileMymeType == QStringLiteral("application/x-desktop")) {
        // If our mimetype is a desktop file, then we don't won't to open
        // the desktop file itself but the application in which it is associated
        // with.
        KService::Ptr service = KService::serviceByDesktopPath(filePath);
        return KRun::run(*service, QList<QUrl>(), 0);
    } else {
        return KRun::runUrl(QUrl(filePath), fileMymeType, 0);
    }
}

I'm still trying to understand how everything works. For now I think the most likely cause is the variable "service". If serviceByDesktopPath() can't get a service it will return "0". I'm still trying to understand what is "KService::Ptr" but I don't see a check on the validity of the pointer here or in the next frames. Then in frame #1 in the method runService() of the class KRun, "_service" is used this way:
Code: Select all
qint64 KRun::runService(const KService &_service, const QList<QUrl> &_urls, QWidget *window,
                      bool tempFiles, const QString &suggestedFileName, const QByteArray &asn)
{
    if (!_service.entryPath().isEmpty() &&
            !KDesktopFile::isAuthorizedDesktopFile(_service.entryPath()) &&
            !::makeServiceExecutable(_service, window)) {
        return 0;
    }
[...]
}

But I'm still reading documentation and downloading repositories, I want to understand better this stuff.

Back to "how to make a launcher".
In the source of KRunProxy::openUrl() they explicitly wrote:
//for security reasons we should not be able to execute applications.

so this is not the correct tool to use if I want to build a launcher.

I'm still trying to use "Service" and "DataSource". For listing the available data sources I found the program "plasmaengineexplorer". I even remember using it in KDE4 when I was playing with another plasma widget. I remember it worked in KDE4 but now in KDE5 not any more. Now it only displays two DataEngines, "kget" and "org.kde.kdevelopsessions". Even the existing engines "time" and "mpris2" are not listed.

Well, I think I wrote enough, it's time to go back to reading documentation 8)

---

Update 2015-07-26:
I finally understood why plasmaengineexplorer was broken. Thanks to [RISOLTO] Info su plasma engine explorer I discovered I was using the version provided with the not any more supported "plasmate". Replacing "plasmate" with "plasma-sdk" fixed the problem, now all the services are listed. The program is not very stable but at least it's a step ahead.
Still searching for a solution...


Bookmarks



Who is online

Registered users: abc72656, Bing [Bot], daret, Google [Bot], Sogou [Bot], Yahoo [Bot]