Wednesday, March 11, 2026

Upgrading Quickbar from SFOS 3 to SFOS 5 #7

 It's been a while since the last post. Life can be hectic for many reasons; but there is _always_ time for SailfishOS development \o/ !

 So to come back on topic; we left the last post in the situation where basically we realized the sandboxing is rendering the current, i.e. at the time of writing, version of libcontentaction incompatible with it. This may sound as harsh news, but it is a consequence of moving towards a more user-controlled environment. Think about it, the control is moved from the system to the hands of the user. Isnt SFOS awesome? 

"Okay Tone, that is all great, but wtf are we supposed to do now? How the hell shall quickbar w0rk3z it's 4w3z0m3z  sk1lz0rz?"

Well, I tell you what. There is a few things to consider here. On SFOS, we have the opportunity to "publish" (if you pass me the term) an applicaton via two ways: one is the "classic" Jolla Harbour , the next one is the familiar OpenRepos . OpenRepos is the "far west", you could say, as it is a free hosted service (kindly provided by basil, you rock btw!), without prejudices and / or opinions on the content. Freely downloadable software, it's a ground of passion from people who like to develop for SFOS (amongs others).

So placing Quickbar on OpenRepos is not a challenge, per-se. And it has been done; which in turn has brought in many downloads (kudos!). This has been a "fallback" for up to SFOS3, when limitations from either bugs, or otherwise difficult integration "challenges" were hindering a quality result. However, this also "externalizes" the app from the "usual" user flow - i.e. download from _within_ the ecosystem, ie. from Jolla Harbor. This has been always a strategic decision (if you pass me the wording) for Quickbar; to be "easy" and feel "natural" to use for the user.

This means that accomodating the Harbour requirements (I prefer this word over "limitations" btw) will require compromises. But don't panic! Luckily the freedesktop foundation has a solution for us. Quoting:

interfaces should require that application is DBusActivatable, including the requirement that the application's desktop file is named using the D-Bus "reverse DNS" convention
What does this mean? It basically suggest that _all_ applications should implement the openApp-specific endpoints. There you go. A simple, UNIX-style solution. #melikes.

Let's see what the sailors think about this interface

Sailfish OS 4.5.0 and later support using org.freedesktop.Application D-Bus interface for opening files and activating windows. However, Sailfish’s implementation extends the specification in two important ways: Firstly, in addition to DBusActivatable=true key in Desktop Entry section, a prefixed custom X-DBusActivatable=true key is also supported. They behave identically. Secondly, Lipstick also supports using D-Bus bus name derived from X-Sailjail section instead of deriving it from the file name of the Desktop Entry file.
Ideally, libcontentaction would have support for this

So there it is, the sailors adhere to the standard. This is awesome for Quickbar. One aspect is, the implementation is not _required_. What this means, is that for those applications which do _not_ support the openApp endpoints, for Quickbar installed from Harbour, we wont be able to execute them. Unless, of course, there's a workaround :-). But we will see how to and more about this later. This btw is totally in line with the freedesktop initiative:

For instance, listing an interface here does not necessarily mean that this application implements that D-Bus interface or even that such a D-Bus interface exists.

Focussing on the change in question, at the moment, seems simple: Quickbar relies fully on libcontentaction to handle application dispatching (=launching). As libcontentaction however is lacking the support for the openApp (a PR is in the works), this is clearly not enough. So we need to add the handling for these DesktopFile entries into the application dispatcher logic.

The code from lancia/fondamonta/mdebotaexesync.cpp handles eventual DBus registrations (yes I know its messy blabla #sowhat); so that is the appropriate place for our code to handle the FreeDesktop spec:

            //Supporteia FreeDesktop DBusActivatable
            if (service == "" && tempDE->contains("Desktop Entry","DBusActivatable")) {
                if (tempDE->contains("X-Sailjail", "OrganizationName") && tempDE->contains("X-Sailjail", "ApplicationName")){
                    service = tempDE->contains("X-Sailjail", "OrganizationName") + QString(".") + tempDE->contains("X-Sailjail", "ApplicationName");
                } else  //Do a FreeDesktop spec
                    service = ennomFile.mid(0, ennomFile.indexOf(".desktop") - 1);
                path = service.replace(".", "/");
                method = path + ".openApp";
            }

this should cover most of the cases, where:

  • An app is DBusActivatable (as per FreeDesktop spec) 
  • An app has overridden the service name in the X-Sailjal/OrganizationName|ApplicationName settings
  • An app did not override the service name thus we expect the desktop file name to be taken for it. In this case, it will need to be a proper DNS entry name 

 There! That's it! :)

Now, of course this doesnt cover the cases of applications that do not implement hte DBusActivatable. These will still remain "unlaunchable" from Quickbar (as the sandboxing prevents it). For these, we need a workaround. Enter debota-tools ; a repository with convenient tools. The only way to work around the sandbox limitation is to leverage this repo to provide a simple DBus service via an rpm package (to be installed via developer mode previous user configuration).

No comments: