SUMMARY Launching application from Dolphin without having .desktop file results in parsing the application by kwin. producing following logs for every single line of executable file: kwin_wayland[3242]: kf.config.core: "KConfigIni: In file /home/julus/factorio/bin/x64/factorio, line 28857:" Invalid entry (missing '=') This also causes KDE to completely freeze for few seconds depending on executable filesize. creating empty .desktop file with the app filename in app folder fixes the issue. STEPS TO REPRODUCE 1. Launch application without having .desktop file OBSERVED RESULT System hangs for few seconds dependig on executable size. EXPECTED RESULT No KDE freeze, no parsing of the application data as desktop file SOFTWARE/OS VERSIONS Linux/KDE Plasma: Nobara OS KDE Plasma Version: 6.1.3 KDE Frameworks Version: 6.5.0 Qt Version: qt6 6.7.2 ADDITIONAL INFORMATION Occurs only via Dolphin. Running app from console or Konqueror does not result in this issue. Issue took place after upgrading from 6.0.5 to 6.1.3 perf showed the kwin as most likely responsible, most of the time by perf was spent in: KWin::XdgActivationV1Integration::requestToken(bool, KWin::SurfaceInterface*, unsigned int, KWin::SeatInterface*, QString const&) KDesktopFile::KDesktopFile(QStandardPaths::StandardLocation, QString const&) per strace of kwin_wayland, the issue started immediately failure search for .desktop and opening application directly, producing the error messages. snip (as I was stracing, the issue caused system to hang for much longer, basically for the whole duration of the sendmsg(): 10:40:09.515383 access("/home/julus/factorio/bin/x64/factorio.desktop", F_OK) = -1 ENOENT (No such file or directory) ... 10:40:09.515977 openat(AT_FDCWD, "/home/julus/factorio/bin/x64/factorio", O_RDONLY|O_CLOEXEC) = 247 <0.000011> ... 10:40:09.627286 sendmsg(15, {msg_name={sa_family=AF_UNIX, sun_path="/run/systemd/journal/socket"}, msg_namelen=30, msg_iov=[{iov_base="MESSAGE=kf.config.core: \"KConfig"..., ... 10:40:31.243019 sendmsg(15, {msg_name={sa_family=AF_UNIX, sun_path="/run/systemd/journal/socket"}, msg_namelen=30, msg_iov=[{iov_base="MESSAGE=kf.config.core: \"KConfig"..., /snip
If I am reading source properly, the fault seems to be in XdgActivationV1Integration::requestToken() in xdgactivationv1.cpp: Particulary following code: QString XdgActivationV1Integration::requestToken(bool isPrivileged, SurfaceInterface *surface, uint serial, SeatInterface *seat, const QString &appId) { ... if (const QString desktopFilePath = Window::findDesktopFile(appId); !desktopFilePath.isEmpty()) { KDesktopFile df(desktopFilePath); Window *window = Workspace::self()->activeWindow(); if (!window || appId != window->desktopFileName()) { const auto desktop = df.desktopGroup(); showNotify = desktop.readEntry("X-KDE-StartupNotify", desktop.readEntry("StartupNotify", true)); } icon = QIcon::fromTheme(df.readIcon(), icon); } ... } The Window::findDesktopFile(appId) returns .desktop file if it exists, otherwise returns application filepath. However no further check if it is actual desktop file is made and KDesktopFile object is created with the non-desktop file and accessed as such which triggers parsing of binary file. This would explain why creating even empty .desktop file for the app fixes the issue, however I am not sure why I did not encountered the issue until now as the code seems to be several years old. Possibly there are new ways to reach this execution path in the recent KDE version? Nevertheless this appears to be genuine bug as binary file is handled like .desktop file.
Good investigation! > This would explain why creating even empty .desktop file for the app fixes the issue, however I am not sure why I did not encountered the issue until now as the code seems to be several years old. Possibly there are new ways to reach this execution path in the recent KDE version? Not sure either, maybe there were some changes in KDesktopFile or KConfig that made the issue worse. Anyways, do you want to make a MR to fix this, or should I do it? Replacing the isEmpty() check with KDesktopFile::isDesktopFile should be enough to fix it afaict
Created attachment 173356 [details] Window::iconFromDesktopFile returns only .desktop file >> Anyways, do you want to make a MR to fix this, or should I do it? Replacing the isEmpty() check with KDesktopFile::isDesktopFile should be enough to fix it afaict Just to be sure, I've checked the other places where Window::findDesktopFile is used, and there is one other place where similar/same bug might be triggered - Window::iconFromDesktopFile which is called either by X11Window::getIcons and WaylandWindow::updateIcon QString Window::iconFromDesktopFile(const QString &desktopFileName) { const QString absolutePath = findDesktopFile(desktopFileName); if (absolutePath.isEmpty()) { return {}; } KDesktopFile df(absolutePath); return df.readIcon(); } As such, wouldn't be better to correct Window::findDesktopFile behavior to make sure only proper .desktop file or empty string? This way it would also help any new code in the future using this function to expect proper data. Something like attached diff (it just simply does the same check as KDesktopFile::isDesktopFile before returning)
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/6418
Git commit f3f2a338d42c18fe2ad8d8175eb2328501be4d51 by Vlad Zahorodnii. Committed on 19/09/2024 at 11:35. Pushed by vladz into branch 'master'. Locate desktop files more carefully It may happen that the specified app id is a file path to a binary file. In which case, the findDesktopFile() function will return that file path and KConfig will try to parse a binary file. On other hand, the findDesktopFile() function should ideally always append the ".desktop" suffix. If there's no file with such a file name, nothing should be returned. But due to some Qt applications providing app ids with the ".desktop" suffix, the findDesktopFile() function also tries to find a desktop file without appending the ".desktop" suffix. However, the fallback code doesn't actually try to verify that the desktop file name contains the ".desktop" suffix, which can result in the findDesktopFile() function providing values that it shouldn't. In this case, returning the file path to a binary executable. M +19 -12 src/window.cpp https://invent.kde.org/plasma/kwin/-/commit/f3f2a338d42c18fe2ad8d8175eb2328501be4d51
Git commit 7797f2b22d76ec8c07e4003bc88c335215a63710 by Vlad Zahorodnii. Committed on 19/09/2024 at 11:50. Pushed by vladz into branch 'Plasma/6.2'. Locate desktop files more carefully It may happen that the specified app id is a file path to a binary file. In which case, the findDesktopFile() function will return that file path and KConfig will try to parse a binary file. On other hand, the findDesktopFile() function should ideally always append the ".desktop" suffix. If there's no file with such a file name, nothing should be returned. But due to some Qt applications providing app ids with the ".desktop" suffix, the findDesktopFile() function also tries to find a desktop file without appending the ".desktop" suffix. However, the fallback code doesn't actually try to verify that the desktop file name contains the ".desktop" suffix, which can result in the findDesktopFile() function providing values that it shouldn't. In this case, returning the file path to a binary executable. (cherry picked from commit f3f2a338d42c18fe2ad8d8175eb2328501be4d51) Co-authored-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org> M +19 -12 src/window.cpp https://invent.kde.org/plasma/kwin/-/commit/7797f2b22d76ec8c07e4003bc88c335215a63710