Open probonopd opened 1 month ago
Version 0.1
Native Support for Application Bundles in Desktop Environments
As desktop environments continue to evolve, it's essential to provide a seamless user experience for applications packaged in various application bundle formats, such as .app
, .AppDir
, and .AppImage
. Currently, many desktop environments are lacking features to handle these bundles, resulting in a subpar user experience. In this article, we'll outline the necessary steps to natively support application bundles, providing a better experience for users and developers alike.
Native support for application bundles is essential for providing a seamless user experience in desktop environments. By implementing the features outlined here, desktop environment developers can improve the usability and functionality of their platforms. We hope that this guide will inspire developers of KDE, XFCE, Cosmic, and other desktop environments to take interest in supporting application bundles natively.
Application bundles are self-contained packages that include an application's executable, libraries, and resources. They provide a convenient way to distribute and run applications without requiring complex installation procedures. The most common bundle formats are:
.app
(used on macOS and by GNUstep on Linux and other OSes).AppDir
(used on Linux and other OSes).AppImage
(used on Linux and other OSes)Application bundles and packages are two different ways to distribute and manage applications on a computer system. While both provide a way to deliver software to users, they differ significantly in their approach and implications.
Traditional packages (as used on many Linux distributions) are typically installed on the system. They are often installed in a specific location, such as /usr/bin
, and are managed by the package manager. Once installed, packages are typically not moved or relocated, as this can break dependencies and cause system instability.
In contrast, application bundles are directories or files that include all the necessary files and resources for an application to run. They are essentially a collection of files and folders that are packaged together to form a single, portable unit. Unlike packages, application bundles do not require installation and can be moved freely around the file system. Users can simply download an application bundle, move it to their desired location, and run it without the need for any additional setup or installation process.
This difference in approach has significant implications for desktop environments, as they can no longer rely on icons or desktop files being placed in specific directories by the installer. Instead, desktop environments must be able to discover and manage applications dynamically, regardless of their location on the system. This requires a more flexible and adaptive approach to application management.
To provide native support for application bundles, desktop environments should implement the following features:
When a user attempts to open an ELF binary without the executable bit set, prompt them to set the bit. This ensures that the application can be executed correctly.
Extract and display the application icon embedded in the bundle. This provides a visual representation of the application, making it easier for users to identify and launch the app in the file manager.
Treat .app
and .AppDir
bundles as opaque files, rather than folders.
If an application exits with an error code within a few seconds after launch, display the error message in the GUI. This provides users with valuable feedback and helps them troubleshoot issues.
Implement bundle-specific launching mechanisms to ensure that applications are launched correctly. For example, .AppDir
bundles require the AppRun
file to be executed, while .AppImage
files just need to be executed.
The above should already give a reasonably good user experience. However, it can be further improved by also implementing:
(Section to be detailed)
When a user attempts to open an ELF binary without the executable bit set, the system should prompt them to set the bit via a GUI dialog box.
The GUI dialog box should include a message indicating that the file is an executable binary, and should ask the user if they trust the application and want to execute the application. If the user confirms, the system requests administrative privileges if necessary for changing the permissions, and sets the executable bit (chmod +x
). After setting the executable bit, the system retries the original attempt to open the ELF binary. If the bit is now set correctly, the application should execute correctly.
Best practice implementation: TBD (TODO: Add screenshot)
When displaying application bundles, they should not use the folder icon. Instead, they should load the application icon from the following locations:
.app
: Contents/Resources/Icon.icns
or Contents/Resources/Icon.png
inside the directory.AppDir
: .DirIcon
inside the directory. Should be png (preferred), but might not hurt to also check for other usable formats such as ico, icns, jpg, svg(z), etc..AppImage
: .DirIcon
inside the disk image file. Should be png (preferred), but might not hurt to also check for other usable formats such as ico, icns, jpg, svg(z), etc. To access files inside the disk image file, zisofs compressed ISO images at an offset and squashfs images at an offset must be read, e.g., using appropriate libraries. (It is said that 7z can do this; to be verified.) The offset at which the filesystem image begins is equal to the length of the ELF binary prepended to it, and will differ between AppImages. See the AppImageSpec on details of the file format. To determine the offset to the filesystem image, calculate the size of the ELF on disk. https://github.com/probonopd/elfsize and https://github.com/probonopd/libelfsize contain C code to do this. When extracting files from the squashfs filesystem image, symlinks need to be followed. See https://github.com/linuxmint/xapp-thumbnailers/blob/master/files/usr/bin/xapp-appimage-thumbnailer for an example using Python and unsquashfs
to extract the icon from a type-2 (squashfs) AppImage.The icons should not be copied to some location outside of the application bundle such as /usr/share/icons
or ~/.local/share/icons
, but only be used for display in the window. If a caching mechanism is desired, then there must also be a cleanup mechanism (e.g., similar to the cleanup mechanism for XDG thumbnailers).
If no application icon is found at these locations, then a fallback default application icon (e.g., the same one shown for generic ELF files) should be used.
This applies to the file manager but also to file open/save dialogs, etc.
When a directory with the .app
or .AppDir
suffix is double-clicked in the file manager, then it should be checked whether it contains a launchable executable (see the section on application launching) and if it does, trying to open the directory should not open it as a folder, but should launch the executable instead.
A context menu item should be there to open the directory as a folder, e.g., called "Show Contents".
Most desktop environments just disregard application output to stderr
when launched outside of a terminal. To provide a better user experience, desktop environments should implement a mechanism to capture and display error messages from launched applications and display them in the GUI. This can be achieved through the following steps:
dup2()
on Unix-like systems or SetStdHandle()
on Windows.QMessageBox
on Qt or gtk_message_dialog_new()
on Gtk,Best practice implementation: Haiku (TODO: Add screenshot)
(Section to be written)
(Section to be written)
(Section to be written)
Feel free to ping me @probonopd if you have something I could give feedback on or could test. Thank you!
TODO: Write an article/section for desktop environment developers on how to handle application bundles.
The plethora of currently available "desktop integration" "solutions" are crude workarounds for the fact that most desktop environments do not handle application bundles like .app, .AppDir, and .AppImage natively:
Since i have written file managers (e.g., https://github.com/probonopd/Filer) which do this properly, maybe I should write a description of how to support such application bundles, in the hope that developers of KDE, XFCE, Cosmic, etc. might take interest.
Thanks to @ivan-hc for triggering this idea in a discussion.