SUMMARY In the course of discussing Bug 425154, we discovered several inheritance issues that make having a fallback association much more irritating than it is supposed to be. One of these issues was fixed, the other got missed. I'm filing this report so that the defect is clearly documented and doesn't slip through the cracks. File associations form a directed acyclic graph (DAG), not a tree, which means that there's not a obvious right answer for the order to traverse the graph (which matters when determining priority for file associations). Right now KDE appears to traverse it in depth-first order, which means that some associations intended to be fallbacks will be hit before some associations that are not. For correct behavior, KDE needs to special-case certain fallback associations so that they always appear last, move to breadth-first graph traversal, or both. (Or potentially other workarounds for the issue that I'm not seeing.) The reproduction steps below reference the following file association inheritance graph, turned into a tree (with duplicate nodes): > application/json > │ > text/javascript > │ > application/ecmascript > │ > ┌────────────┴────────────┐ > │ │ > application/x-executable text/plain > │ │ > application/octet-stream application/octet-stream STEPS TO REPRODUCE 1. Have an application like Kate set to open text/plain, and a fallback application like Okteta set to open application/octet-stream. 2. Don't have any applications set to open JS / JSON files directly. 3. Click to open a JSON file in Dolphin. OBSERVED RESULT The file opens in Okteta. EXPECTED RESULT Given the configuration stated above, JSON files should open with the text/plain association, not with application/octet-stream. Given the structure above, traversing the graph in breadth-first order would give the correct associations, and it seems like a much better default. Note however that there is no guarantee of this always holding true. For example, if application/ecmascript inherited something like text/script instead, and *that* inherited text/plain, then breadth first order would still result in application/octet-stream being hit first. SOFTWARE/OS VERSIONS Operating System: Arch Linux KDE Plasma Version: 5.27.7 KDE Frameworks Version: 5.109.0 Qt Version: 5.15.10 Kernel Version: 6.4.12-arch1-1 (64-bit) Graphics Platform: X11 ADDITIONAL INFORMATION This is made more annoying by the fact that some applications (e.g. Firefox) are reported to sometimes tamper with the system file associations. Users have ended up with Okular (in particular) set to open application/octet-stream as a result of PDFs not always having a mimetype available, which has led to a lot of confusion. Bug 425154 is about the pain points that result from having an application/octet-stream association set, this bug is specifically about inheritance ordering that sometimes results in this association being preferred even when a better association is available.
I think you are right. The spec says in the section about selecting an application "The above process is repeated for each mimetype from the most specific to the least specific. Note in particular that an application that can handle a more specific type will be used in preference to an application explicitly marked as the default for a less-specific type." In the example text/plain is more specific then octet-stream
A possibly relevant merge request was started @ https://invent.kde.org/frameworks/kservice/-/merge_requests/167
Created attachment 162411 [details] plot of multiply inheriting mime types I'm attaching a directed graph I generated showing all mimetypes installed on my system that involve multiple inheritance, to make debugging potential issues with these easier. The problem with application/json is shown clearly.
Thanks!
Git commit f424bd3aab78bf1e3a6c93aed7f4562d56c776a7 by David Redondo. Committed on 24/10/2023 at 10:19. Pushed by davidre into branch 'master'. Fix preferred apps order for multiple level mime inheritance We should prefer more specific mime types to less specific for that reason offers are sorted by inheritance level first. When constructing the offers for inherited types, the associated services for parent types are queried. However these can already contain services that are associated with a parent type of the parent type as the offers are build from the bottom-up starting with the least specific mime type. For example when constructing offers for a mime-type that inherits text/plain, the returned offers for text/plain will already contain services associated with application/octet-stream. By incrementing the inheritance levels instead of overwriting the relative ordering of inherited mime types is preserved. M +24 -0 autotests/kmimeassociationstest.cpp M +4 -4 src/sycoca/kbuildservicefactory.cpp M +1 -1 src/sycoca/kbuildservicefactory_p.h https://invent.kde.org/frameworks/kservice/-/commit/f424bd3aab78bf1e3a6c93aed7f4562d56c776a7