Sailfish Community News, 26th August, Silica Constants, PIM Progress

Subscribe to future posts here :bell:

Sailfish OS update from Jolla

As always, we’ve been continuing to work hard behind the scenes on the next release of Sailfish OS (and in fact, the release after that). But while we don’t have any big announcements to make just yet, we do nevertheless have a couple of things we wanted to share with you.

As always, we cover four new or improved apps from the community down below. Before that, a look at some of the Sailfish Silica constants that everybody should be using in their apps, plus an update on the hard work Damien Caliste has been putting in improving the Calendar and Email back-ends for your device.

A Garden of Constants

As regular readers of the newsletter will know, each fortnight we like to pick out four new or recently-updated apps, describe their functions and generally get an idea about the improvements that have been made to them. We’d hoped that, if nothing else, this would give an idea of the number and breadth of actively developed apps for Sailfish OS. Even with this in mind, we’ve been happily surprised at how many apps we’ve had to choose from each fortnight, and how diverse they’ve been. All credit to the amazing developers and contributors for their hard work. So far, picking out four nice apps to try for each newsletter hasn’t been hard. Quite the opposite in fact: there have always been far more apps than we’ve been able to cover.

Having looked at well over fifty separate apps, each has had its own unique purpose, functionality, features and quirks. All of them have been a joy to test out, and there have only been a few occasions when we’ve had to drop an app we planned to cover from the newsletter because we weren’t able to get it to work correctly, or it was just too buggy.

During this process, it’s been impossible to avoid the fact that many apps diverge from the standard UI principles we use at Jolla. Most obvious is when an app has no margin around the edge of the screen, or where user interface elements are smaller or larger than expected, or crammed together.

This isn’t necessarily a bad thing of course; variety is the spice of life, and many of the unique designs have made the user experience more enjoyable. The unexpected flourishes in cover app design stand out particularly for me. Still, it’s a good excuse to cover some of the basic app-design guidelines that are used within Jolla. Before we do that, Joona Petrell, Chief Architect and UI designer at Jolla, has some useful general advice.

The safest bet to develop Sailfish-style apps is to use the standard Silica components when you can, which normally have page margins, other dimensions, colors, etc. designed match the platform style.

But this may not always be possible.

Sometimes there is no applicable standard component available and you need to define a custom layout. Also there are few cases where no good common components exist like active cover layouts, text paragraphs, list and grid items.

In these latter cases, it’s still important to try to conform to the general style guidelines. Silica includes a number of different constants to help with laying out a user interface which should be familiar to all software developers on Sailfish OS.

The Silica documentation already goes into the topic in some detail. You can find a short summary for each of the constants there, and the Common Pitfalls documentation is also a really crucial read for app developers, since it was written to address many common layout mistakes. Nevertheless, unless you’ve read, digested and remembered the information on those pages in full, the details may be easy to miss. And judging by the variety of layouts out there, they often are.

If you don’t want to get in to documentation, then this graphic summarises things nicely.

Let’s start with a list of the main Silica constants related to length. In total there are more than sixty different constants — for too many to cover here — but some are also more obscure than others. We’ll stick to the most common.

Padding Button sizes
qreal horizontalPageMargin
qreal paddingSmall
qreal paddingMedium
qreal paddingLarge
qreal buttonWidthTiny
qreal buttonWidthExtraSmall
qreal buttonWidthSmall
qreal buttonWidthMedium
qreal buttonWidthLarge
Item sizes Icon sizes
qreal itemSizeExtraSmall
qreal itemSizeSmall
qreal itemSizeMedium
qreal itemSizeLarge
qreal itemSizeExtraLarge
qreal itemSizeHuge
qreal iconSizeExtraSmall
qreal iconSizeSmall
qreal iconSizeSmallPlus
qreal iconSizeMedium
qreal iconSizeLarge
qreal iconSizeExtraLarge
qreal iconSizeLauncher

All of these are per-device constants. That means they won’t change while your device is running, but they may change between different devices, depending on factors like the screen dimensions. The most obvious example is the horizontalPageMargin, which is set to be a larger value for tablets than for phones.

As an application developer, if you use these constants correctly, the intention is that your app will elegantly adjust to the layout of different screen sizes.

In addition, many of the constants are also good reminders about where spaces should be included in your app. Good use of spacings is after all a crucial way to improve usability.

Horizontal margins

Perhaps the most common misuse of spacing is in the margins around the screen. It’s quite common to see apps with text that runs right up to the left or right hand edges of the display. It might feel like this is a good way to maximise screen space, but in practice it can be problematic for a number of reasons.

For example, if you have text starting at the left hand edge of the display it can make it hard to read, especially if you have a phone case. It can also result in text appearing very close together when you swipe between pages, which can be unattractive. For action items it’s even more problematic, because the edge of the display is reserved for swiping back to the homescreen. Items right at the edge of the display become less usable in terms of interaction.

The solution is to ensure you use horizontalPageMargin on both the left and right hand edges of the display. The spacing in the images has been exaggerated to make things more obvious.

We can see the code for this in the snippet below. Note how the ListItem goes right up to the edge of the display for the background highlight, with the margin added to the Label inside.

Page {
    SilicaListView {
          anchors.fill: parent
          model: listModel

          header: PageHeader {
              title: "Horizontal spacing"

          delegate: ListItem {
              Label {
                  x: Theme.horizontalPageMargin
                  width: parent.width - 2 * Theme.horizontalPageMargin
                  anchors.verticalCenter: parent.verticalCenter
                  text: (model.index+1) + ". " + model.text
                  truncationMode: TruncationMode.Fade
          VerticalScrollDecorator {}

When it comes to the horizontal margin there is some complexity in the fact that not all Silica components require the margin to be included. In particular, if you have a ComboBox or ListItem with a background highlight for when it’s being selected by the user, then you should explicitly not include the horizontal page margin. Otherwise the highlight won’t go up to the edge of the screen. Another exception is the TextSwitch, which already includes the margins in order to better accommodate the glass highlight toggle on the left hand side.

Vertical spacing

There are no hard-and-fast rules here, but if you’re creating a Column it’s typically the case that the item spacing should be set to paddingLarge or paddingMedium. However, in many cases it’s not necessary to leave any spacing at all, as Joona explains.

If you are stacking compound Silica components, such as a Settings page PageHeader + Switch + SectionHeader + ComboBox + Slider, they normally have vertical margins inbuilt so no additional spacing is needed.

If you have various interactive items in a column inside a SilicaFlickable component it’s typical to include a gap of size paddingLarge at the bottom of the page. If you’re using an Xperia 10 or Xperia 10 II with their long tall displays you may not realise it’s necessary, but if you have a device with a shorter display (or your app supports landscape mode) then having items that press up against the bottom edge of the display can look lazy. Note however that there isn’t usually a gap at the end of a long list, such as a SilicaListView.

The following QML snippet shows how these items were defined. The page is much shorter than usual, and the size of Theme.paddingLarge has been exaggerated to aid clarity. We’re also using buttons here as visually their dimensions are really clear, but in a real app you’d be better off using ButtonLayout to ensure the button widths are also aligned and to better handle different display sizes.

Page {
    SilicaFlickable {
        anchors.fill: parent
        // Additional space at the end of the page
        bottomMargin: Theme.paddingLarge
        contentHeight: column.height

        Column {
                id: column
                width: parent.width
                spacing: Theme.paddingLarge

                PageHeader {
                    title: "Vertical spacing"

                Button {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "First"

                Button {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "Second"

                Button {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "Third"
        VerticalScrollDecorator {}


Vertical lists of items are a very common design pattern on Sailfish OS. So common in fact that they have their own special components in SilicaListView and ColumnView.

There are three rules to remember when creating lists:

First, for items containing a single line of text itemSizeSmall is the ideal height for each item. The ListItem container will default to this height or the height of the contained elements, whichever is larger.

Second there are typically no gaps added between items, or at the end of the list.

Third, in practice it’s best to calculate the ListItem contents height and use this. In this case, the constants are still important for specifying the minimum height of an item.

For the third rule, Joona makes the following comment.

Often it is good to bind contentHeight to list item contents, for example contentHeight: Math.max(Theme.itemSizeMedium, labelColumn.height + 2 * Theme.paddingMedium) . Otherwise something that looks great with the normal font size setting can grow out of bounds when the user chooses to increase the system font size.

Most of the time you’ll have a header at the start of your list, in which case the padding at the top of the list will be dealt with for you. Here’s an example of a perfectly formed list, taken from the Component Gallery example app.

And here’s a copy of the code. It’s slightly modified and has the model snipped for brevity, but otherwise this code is taken from the Component Gallery. Note how the ListItem doesn’t need to be given a height here, since it defaults to Theme.itemSizeSmall anyway.

Page {
    id: root

    SilicaListView {
        id: listView

        anchors.fill: parent
        model: listModel

        header: PageHeader {
            title: "List and menus"

        delegate: ListItem {
            Label {
                x: Theme.horizontalPageMargin
                width: parent.width - 2 * x
                anchors.verticalCenter: parent.verticalCenter
                text: (model.index+1) + ". " + model.text
                truncationMode: TruncationMode.Fade
        VerticalScrollDecorator {}


We’ve included the icon sizes in the table of constants above, but in practice icons are used in many different ways, and the size you need will be highly context-dependent. Joona nevertheless has some useful advice, which is in fact, to avoid using these constants where possible.

While mostly harmless it is better to not set the dimensions for icons to avoid accidentally up- or downscaling them, which can lead to lower quality (scaling artefacts, fuzziness). For example large vector icon outlines are not designed to be viewed in small icon dimensions. Using fixed icon sizes can mask the fact that you are actually using the wrong icon. Icons components already implicitly follow these values.

How to make icons work really well in a Sailfish OS app is a topic in its own right, and something which we may cover in a future newsletter.


Colours are a particularly important part of Sailfish OS, and go a long way to marking out its unique design. Using the colour constants correctly is especially important if you want your app to work well across the range of possible ambiences a user might apply, including light and dark variants. Here are the main constants related to foreground colouring.

Colours Opacities
QColor highlightColor
QColor highlightBackgroundColor
QColor highlightDimmerColor
QColor primaryColor
QColor secondaryColor
QColor overlayBackgroundColor
QColor secondaryHighlightColor
QColor backgroundGlowColor
QColor errorColor
QColor lightPrimaryColor
QColor lightSecondaryColor
QColor darkPrimaryColor
QColor darkSecondaryColor
qreal opacityFaint
qreal opacityLow
qreal opacityHigh

Of these the three most important are primaryColor, highlightColor and secondaryColor.

And the most important rule is that text and selectable items use Theme.primaryColor as their foreground colour. Headings and unselectable items have Theme.highlightColor as their foreground colour. For selectable items which contain a main feature and a secondary feature (for example buttons with a main piece of text followed by a description), the main text should use Theme.primaryColor and the follow-on text should use Theme.secondaryColor.

There is also Theme.secondaryHighlightColor for where there’s some secondary text in an unselectable item.

So, the main distinction here is: selectable items vs. unselectable items.

These rules are applied pretty consistently within the operating system user interface, and the colouring gives an important hint to the user, so it’s important to follow this where you can.

For selectable items, when they are being pressed by the user they become highlighted. In this case Theme.primaryColor should become Theme.highlightColor and Theme.secondaryColor should become Theme.secondaryHiglightColor. For the standard items (e.g. ComboBox, TextSwitch, Button items) this will already happen automatically unless you explicitly set the colours to be different.

It’s not uncommon in a user interface to have elements which are “greyed out” to indicate that, while the option exists, it’s currently uneselectable or unavailable. In the Sailfish OS user interface this is dealt with using opacity rather than colour. In general, disabled items like this should have their opacity set to Theme.opacityLow (as opposed to a full opacity of 1.0 for selectable items). In practice though, it’s best to use the built-in disabling capability of components where you can, as Joona explains.

A common bug is to disable the action but not the press effect, so set enabled to false. Or even better, keep the touch action, but when the user taps the item give a Notice explaining why the feature is not available (e.g. if you tap the “Mobile data” switch it says “you first need to select SIM card” in a multi-sim scenario).

All of these colouring rules apply equally to text and graphics. Most of the icons used in Sailfish OS are monochromatic line drawings, to which these colouring changes apply cleanly. The standard selectable icon items (IconButton, IconTextSwitch, etc.) will automatically apply the correct highlight colour when the item is being selected by the user, but if you build your own you should be careful to include it. There is some nuance here though, and Joona has some useful additional advice.

If you use Icon instead of Image to show the icons, it will know if the container highlight goes to true and colour the icon appropriately. Though for colored icons it can produce a too-strong effect, e.g. the launcher icons use HighlightImage { monochromeWeight: colorWeight; highlightColor: Theme.highlightBackgroundColor } for better results.


In life every rule is meant to be broken and designing a good user interface is more art than science. However, the wonder of art comes from creating something beautiful that still satisifies the constraints of the medium. This applies to creating a great user interface for your app using Silica just as it does for everything else.

Hopefully the advice here is practical and you’ll be able to use it in your own apps. If you’re ever unsure of the canonical way to use a Silica component, or how to space your items, by far the best place to look is in the Component Gallery. Follow the layouts you find there and you’ll end up with a beautifully consistent, nicely laid-out app.

Recent PIM improvements

Damien Caliste has continued his excellent work making both back-end and front-end improvements to the calendar and email stacks. We covered some of his changes in the newsletter on 22nd April and we wanted to keep you up-to-date with progress.

As we saw back in that newsletter on the 22nd April, Damien and Chris Adams (privateer software engineer for Jolla) ported upstream QMF so that it now supports Qt6. QMF is the email back-end, allowing your phone to speak to email servers (using POP3, IMAP and SMTP), collect and send emails, manage attachments and so on.

After upstream was updated to build against Qt6 (including passing all unit tests), Damien then backported as many of those changes as possible to the Sailfish OS QMF tree (which is still Qt5.6-based). You can see the results in the Messaging Framework repository. His efforts mean that the delta between the Sailfish OS repository and the upstream repository are minimal, which will generally make maintenance far more straightforward in future (especially, upstreaming future patches from our tree should be simple).

As Damien explains, there are still some areas where it’s not possible to upstream changes from the Sailfish OS implementation to the Qt upstream:

The main difference that still remains between upstream and the version used in Sailfish OS is the patch bringing support to the account framework. This patch is not upstreamable though, because QMF already has support for accounts internally and the patch is replacing it with the libaccounts-qt one used in Sailfish OS. QMF should be reworked in the sense of introducing a generic account interface and plugins to implement it, providing a default one with its current implementation.

All the changes made so far have already been merged into the mainline code, so will be available to users in an upcoming Sailfish OS release. The result will be a better-maintained stack which should benefit everyone. But what will the result be for end users of Sailfish OS phones? Chris explains:

End users should not be affected by the changes, as the changes solely affect implementation details of the email sync service (QMF). Their POP and IMAP content should continue to be synced in exactly the same way. This change will reach users in the release after next. We believe that the risk of regressions will be low by the time it’s released, however if you do encounter any issue with POP or IMAP synchronisation, please let us know via the forum or on IRC!

That’s a lot of changes to the email stack already, but Damien has also been making some long-overdue and deep but important changes to the Calendar stack as well. Damien wrote about the Calendar stack in fascinating detail back in the newsletter on 1st July. It’s quite complex, so worth referring back to if you’re keen to better understand the various components.

Inherited from the early days of KCal, mKCal provides a method to return all of the events from a specific calendar that fall into of a given period. For events that recur, they are automatically duplicated according to the rules set on them. This is a useful method, used for example to display events in the month view of the calendar application.

But event recurrence can be quite complex. Not only can you set events to recur periodically (every week, say), you can also set exceptions. This method was obviously taking into account these exceptions, when the occurrence of a recurring series of events is modified, such as for instance a recurring meeting that is shifting one hour later on a given date.

The implementation of exceptions was done in a smart way so as not to duplicate code by automatically adding the exceptions as EXDATEs to the recurring rule of the parent event*. This was a smart move because the expanding code from KCalendarCore then automatically removed the “normal” occurrence thanks to the additional EXDATE and the exception occurrence was present at its peculiar date and time.

But, while this sounds clear, mismatches between our implementation and the rest of the world were causing additional complexity in our code, as Damien explains:

This smart idea has a significant drawback: it’s not RFC compliant, which means that recurring events coming from servers don’t follow this rule; they skip the additional EXDATE. So when we send the event to the server we had to conform to the RFC compliant definition, and temporarily modify the event accordingly before sending it.

In every synchronisation plugin there is code thus to add (and remove) EXDATEs for exceptions on download (and upload respectively). Since our recent move to upstream KCalendarCore, we can use a new method that has been added there by KDE developers to tackle this problem.

The KCalendarCore::OccurrenceIterator class was internally taking into account exceptions without the need to put them in the EXDATE list. So the main changes were to the parts of the stack above this.

The QML plugin for calendar is now using this upstream method instead of the old method from mKCal. The changes allowed me to remove the code from the synchronisation plugins to convert between RFC and mKCal conventions, see pull request 2 and pull request 1 in the buteo-sync-plugins-social repository. The specific code from mKCal has also been removed.

Chris also worked closely with Damien to integrate his changes, and explains how this will affect maintainability in the future:

Damien has been doing considerable work to ensure that our internal representation of calendar event data matches as closely as possible to the interchange format (.ics as defined by the relevant RFCs). This latest change removes one of the last inconsistencies between our internal storage format and the expectation of the interchange format, reducing the work our sync plugins need to do when downsyncing calendar event content from remote services.

Aside from this, changes continue to be made to the calendar capabilities in Sailfish OS, most recently to explore attachment support for calendar events. This started out as a work-in-progress pull request in nemo-qml-plugin-calendar with the discussion now continuing on a GitHub issue created by Pekka Vuorela (Chief Engineer at Jolla), which nicely sumarises the main issues involved and provides some clear direction. Attachment support is currently missing from the QML bindings, so even if an attachment is added to an event externally and then synced on to your Sailfish device, this attachment is not exposed in the UI.

But more importantly, attachments were not yet fully supported by mKCal either:

Only the URL to a given resource could be saved in the database, no inline document for instance. In fact, upstream KCalendarCore already provides an API for accessing attachment data or attachment URLs, but also attachment properties like the mime-type. The mKCal internal database has thus been expanded to support these missing bits in a recent merge request.

This is the first milestone to get attachment support at the UI level. It still requires some work, like proper exposure at QML level and of course UI design.

Hopefully we’ll see these changes moving forwards and eventually making their way into a future release.

For the next newsletter, Damien has offered to write a special article about Buteo, which isn’t a bird of prey, but rather the framework used to support syncing with various backend providers, including the calendar sync capability on your phone. It’s something we probably all make extensive use of, but is mostly hidden, and sure to be an interesting journey.

* RFC: EXDATE is a list of dates for recurring events when there is *no* event, for instance, the regular daily meeting at the coffee machine is obviously cancelled January 1st.

Energy from the Community

As always we have a bumper crop of apps to choose from. Here are four that caught our eye. In addition, we were pleased to see a new architecture-independent installer for Storeman. More details on that below too.


Last newsletter we looked at Watchlist and I pretended to know something about stock markets. This time I’ve managed to find a topic I know even less about. BeamCalc, originally written by Tobias Planitzer and now maintained by Mark Washeim (poetaster), is an app for performing static calculations for beams and pillars. Essentially, if you’re building something substantial, the likelihood is that it will involve a beam or pillar of some sort. Some of the characteristics of the beam — its length, how much load it must support, how the load is spread, the material — are likely to be set in advance, while others will need to be determined. With BeamCalc you enter the characteristics based on the configuration in your design, and it will calculate the thickness of the beam needed to ensure safety (i.e. that the beam can support the load).

The app supports several different configurations: a single span beam supporting weight from above, a cantilever beam that extends beyond its supports, a beam with multiple supports, a beam clamped at right angles to a wall (like a shelf) and a pillar, where the load is compressing the beam longitudinally. It seems like a comprehensive set of options to me, but as I mentioned, I’m not really fit to judge. If anyone has thoughts on this, please share the benefit of your experience in the comments. I’m also not able to judge the accuracy of the calculations, which is rather important. The app is open source so you could conceivably check this yourself.

What is clear to me is that the presentation of the app is excellent, with numerous clear and clean diagrams at each step, which honestly makes understanding the various parameters far clearer. This is a real tour-de-force in clarity in my opinion.

It’s rather a niche app then, but if you have need for it, and are satisfied that the calculations it performs are safe, then I can see how it would be a superbly useful app, and a joy to use. The latest version has some small updates, most notably the addition of the all-important “About” page. It’s great to see development continuing on the app, which is available from the Jolla Store and OpenRepos.


There have been no shortage of chat protocols and services to choose from over the years. IRC, ICQ, MSNM, SMS, MMS, Wave, WhatsApp, FBM, iMessage, Telegram, Signal, Slack, Teams, Matrix. How many dozen did I miss? Matrix has the outward appearance of being a Slack clone designed for use by teams. Underneath it’s quite different though, being a federated, self-hostable, end-to-end encrypted communication tool that shares its encryption protocol with Signal. With these positives, it’s maybe not surprising that it’s become popular for security-conscious team communication. Sailfish enjoys the benefit of several different native Matrix clients, including Konheko from deepbluev7, Bluepill from cy8aer and Determinant from R1tschY. Unfortunately none of these clients have supported the E2E encryption that’s needed for some uses (without E2E the connection may still be secured using TLS, but the security and privacy characteristics are different). Sailtrix is the first Sailfish OS Matrix client to support E2E encryption. It’s enjoyed really rapid development recently and Heng Ye (HengYeDev) has been doing amazing work on it. You may know Heng Ye for another amazing Sailfish project: Sailfish x86.

The app itself is quite new and still developing, so it still also has some rough edges here and there. I usually use the official desktop Element client to access Matrix, but with Sailtrix I found I wasn’t able to access all of the groups that I’m enrolled in. I was able to access some other E2E encrypted channels, although no emoji-enrolling for verifying the keys just yet. The UI is clean and nice, it’s really easy to follow the conversation and it was lovely to see all the avatars of the people I was communicating with. Image attachments also seem to be working nicely.

Sailtrix is a really promising new Matrix client. It needs a little more maturity before it can be reliably used as your only Matrix client, but already it has some unique features. I’ll be keeping an eye on it and with any luck will be able to include it here again when it’s more feature-complete and stable. In the meantime, Sailtrix is definitely worth following and is available from OpenRepos


Going to the cinema seems pretty exotic nowadays, but many countries are now opening up and it seems like there’s hope that, wherever you are, there will at least come a time when it becomes an option again. SailKino by Pekka Heinisuo (skvark) and with contributions from Matti Viljanen, is a cinemagoers app for users living in Finland, Estonia, Latvia and Lithuania. If you live outside one of these countries, you may gain some pleasure like I did from just using the app and imagining what it might be like to go to the cinema again. The name “SailKino” comes from FinnKino, the largest chain of cinemas in Finland. But it also supports Forum Cinemas too. The app offers a window onto current and upcoming releases filtered based on location and date. The app provides the main details you might want to know about each available film, including genre, length and description. It’s not IMDB, so if you want reviews and goofs you’ll have to look elsewhere, but that’s not really the purpose. You can view the trailers (in my experience most of these get delegated to the browser for viewing, an approach which works well) and check showing dates and times. The one thing you can’t do in the app is actually purchase tickets, but if you select one of the showings you’ll be automatically redirected to the website for the final step. The app generally worked excellently, but at least for Finnkino, it was necessary for me to switch to Finnish language before the app would recognise any films.

The app has benefited from a whole host of improvements recently, including fixes for accessing the updated server API, support for opening trailers in the browser, improved support for different screen sizes and enhanced theatre filtering. If you’re a cinemagoer in one of the supported countries then you should definitely have it on your device. And if you’re somewhere that’s still in lockdown, you have my sympathy, and the app may give you a positive glimpse of things to come. SailKino is available from the Jolla Store.


Base64 is, as the name suggests, is a tool for converting text to and from Base64 encoding. It’s published by Andrea Scarpino (ilpianista), whose Lyrics app we featured back in June. In case you’re not familiar with Base64 encoding, it takes standard ASCII or UTF text (or, indeed any binary data) and converts it into an ASCII string. Essentially, every three binary characters from the original text gets converted into four base64 characters taken from the base64 alphabet. This may sound inefficient, but while binary data can be hard to present (not all of the 256 possible characters in each byte can be presented on screen, let alone typed easily), the base64 alphabet is made up of just the 64 characters A-Z, a-z, 0-9, + and /. All of which can be easily typed (there’s also the = symbol that sometimes appears at the end to represent padding). Converting text to base64 isn’t a security encoding, but it does make it easier to transmit binary data across a network under certain circumstances. For example historically email was restricted to 7-bit data, and so one method of sending attachments is to convert them into base64 format first.

The Base64 app lets you easily convert text in both directions: both encoding and decoding. It’s a simple app that does the job effectively. I’d like to see the output font slightly larger, but in practice the most common usage will probably be to copy the result to the clipboard, which the app supports nicely. Credit must go to Andrea and the army of translators who’ve managed to translate the app into many different languages: Chinese (Simplified), Chinese (Traditional), Croatian, Esperanto, Estonian, Finnish, French, Galician, German, Hebrew, Italian, Norwegian Bokmål, Polish (not yet fully complete), Serbian, Swedish and Turkish. It’s quite an accomplishment and something for other apps to aspire to. The latest version has updated translations and is available from the Jolla Store and OpenRepos.

Storeman Installer

Most readers will be familiar with Storeman, the main gateway for installing apps from OpenRepos. As an app itself it suffers from a bit of a Catch-22: how to install the app that’s used for installing other apps? For perhaps obvious reasons it’s not an app that can pass harbour validation (installing apps requires root privileges, which aren’t allowed in the Jolla Store). Until now the typical approach a user has had to take has been to enable installation of untrusted software, then download the correct version of the app from the web and install it manually. One downside of this is that it leaves it up to the user to select the correct version, depending on the processor architecture and Sailfish OS version they’re running. The latest release has seven different versions to choose between, which is a big problem for new users.

To work around this, Petr Tsymbarovich (mentaljam) has released a new Storeman Installer. This is a single package that can be installed on any Sailfish OS device that will select and install the appropriate version of the app for your phone. Petr explains:

The Chum Team’s experience prompted me to develop a simple architecture-independent installer that adds an OBS repository to the device and selects an appropriate version of Storeman RPM using standard tools like PackageKit, Zypper and libsolv.

Petr’s aim is to make the whole process much more straightforward.

After “installing the installer” you will see its icon in the apps grid. Tapping on it would call a two-line bash script that simply refreshes the local repository cache and installs the harbor-storeman RPM. The installer itself is removed automatically.

You can download the package yourself direclty from GitHub, and Petr is keen to receive feedback from users.

Please feed us your news

This is a community update, and frankly we can’t always keep up with all the exciting stuff happening in the Sailfish community. Plus, the less of this we have to actually write ourselves the better. So please help us out by posting your Sailfish news updates to the forum as a reply to this post. We’ll collate as much of it as possible into one easily digestable post for the next update.

And don’t forget to join us at the community meeting every other Thursday on IRC. It’s a great place to discuss any of the content you see here, or to share your ideas for future updates. The next meeting will be on the 2nd September full details here.


As alway, thanks for this nice read. The stuff with the margins is actually quite hard to get right. I already spent frustrated hours on this. Is this nice explanation somewhere in the documentation and I missed it? It would be good to have a cheatsheet handy for this.

Especially because different components apperantly have different ways to set the margin, or do not require it.


Again, even as a mere user I enjoy reading your behind the scene insights (which, btw, helps me to understand why I have some trouble with importing calendar entries via ical files representing reoccurring events). Thank you!

1 Like

Thank you very much for the UI guidelines! I’ll do my best to reflect them in my apps.

And an additional thank you for mentioning Base64. It has been my first SailfishOS application that I made “just for fun”, but that made me love Qt and QML.


Thank you very much for this update. It’s great to know how much is going on behind the scenes, rather than just waiting for a couple of months with no knowledge of what is going on! Such an interesting read.

Sailtrix is an amazing Matrix client! Can’t wait to see how good it gets as it matures.


wht does privateer mean in this context?


Correct - but to clarify; people all over the world work for Jolla and it often doesn’t make sense for those in different countries to be direct employees so we’re privateers.


I have some trouble with importing calendar entries via ical files representing reoccurring events

Feel free to send me these problematic ICS files, I will give a look why they don’t import properly.

1 Like

@dcaliste Damien, thank you for caring - I just copied the text of the ics-file in a message to you since I do not know to append the ics file directly. OIn the ICS file there is the entry:


Of the three calendar entries listed under “RDATE” only the first entry (30. June) shows up in my SFOS calendar after importing the ICS-file. The other two entries (25. August, 27. November) are missing.

And seriously, send me a note if calculations in Beamcalc seem off. I’ve not built a test rig yet, but it’s in process to be able to confirm calculations. Also, the input fields are being reworked.

Thanks for the in depth … time to rebuild my list views!

From the sources in KDE::KCalendarCore::ICalFormat :

            } else {
                // TODO: RDates as period are not yet implemented!

So, I need to read a bit more the RFC 5545 to see what this PERIOD definition means and if it can be implemented in KCalendarCore.


as far as understand, in the case above, one of the periods, i.e. a periode from 30. June 10:00 to 30. June 11:00 is defined by
isn’t it? So it is not just reoccuring dates but reoccurring periods.

Yes, you’re right. The KCalendarCore deserialisation routine from iCal format is ignoring PERIOD time definitions in RDATE (that’s the meaning of the snippet from the code that I copied in my previous reply). It is doing so for the reason that the internal representation of incidences and recurring dates has no API to store and use such a definition.

After reading the RFC5545, the PERIOD definition can be used for occurrences of a recurring incidence that would have a different duration than the parent one. There is another way to achieve this by declaring an exception with a specific end date. That’s the more common way it is implemented, but the PERIOD way is more concise and seems to be used by your iCal provider.

I have a preliminary idea on how to implement this in a simple way in KCalendarCore. I’m going to try it this week and propose a MR to the KDE developpers. It can be a bit tricky to achieve this by being backward compatible in term of API… I’ll keep posting developments here.


Here comes the MR adding support for PERIOD definition in RDATE : Implement period support in RDATE (!53) · Merge requests · Frameworks / KCalendarCore · GitLab

Let’s wait now for the discussion that may start with KDE developpers. If accepted, I’ll need to update mKCal also to store the PERIOD definition in the calendar database so it can be used in SailfishOS.


Upstream support for PERIOD in RDATE has been accepted today and merged into master by KDE developpers, see Implement period support in RDATE (!53) · Merge requests · Frameworks / KCalendarCore · GitLab

I’ve created a PR for Sailfish accordingly :

I need to think on how to save this properly with mKCal now for a complete support.


This topic was automatically closed after 11 days. New replies are no longer allowed.