My sixth day with Haiku: Under the hood of resources, icons, and packages

probono
25 min readJul 15, 2019

--

TL;DR: Haiku is an operating system explicitly designed for the personal computer desktop. As such, it has a few tricks on board that make the desktop experience far superior to other systems. But how does it work?

Hello again?

Recently, I discovered Haiku, a “shockingly good” desktop operating system. I am still amazed how smoothly it can do things on the desktop that other systems, especially “the Linux desktop”, have been struggling with. So today, I will have a look “under the hood”. Where useful to increase the understanding, I will draw comparisons with the original Macintosh, Mac OS X, and “the Linux desktop” (freedesktop.org XDG standards).

Resources in ELF files

Yesterday we saw that IconOMatic can save icons into rdef resources in ELF binaries. Today we will see how this actually works.

Resources? Wrote Bruce Horn, original author of the Macintosh Finder and the father of the Macintosh Resource Manager (source):

The rigid nature of traditional programming bothered me. The idea of an application frozen in code, with no way to change anything dynamically, was anathema to my ideals. I wanted to be able to change as much as possible at runtime. Of course, the application code itself couldn’t be changed, but what could be changed without having to recompile the code?

The solution was that files on the original Macintosh had a “data fork” and a “resource fork”, something that made it incredibly easy to store things like icons, translations etc. along with binary files.

On the Mac, there used to be ResEdit, a GUI tool dedicated to — surprise — editing resources.

ResEdit on the original Macintosh. Source: https://macgui.com/kb/article/12

This made it very easy to have icons, menu items, translations, etc. editable but still have them “travel with” the applications.

However, there was a big downside to this approach: It only worked on Apple’s own filesystems, which is probably part of the reason why resource forks where abandoned entirely when Apple switched to Mac OS X.

With Mac OS X, Apple wanted a solution that would work cross-platform on any filesystem, and hence adopted (from NeXT) the concept of bundles, directories that are not treated as folders in the file manager but as “opaque objects” like files. An .app application bundle contains, among other things, an Info.plist file (think of it as Apple’s version of a JSON or YAML file) that contains an application’s metadata.

Info.plist keys in a Mac OS X application bundle

Resources like icons, UI files, and such, are stored in the .app application bundle as files. In fact, this concept goes back to the very early days of NeXT.

Mathematica.app in NeXTSTEP 1.0 from 1989 appears as one object in the GUI but is actually a directory as seen on the Terminal

Enter BeOS, which Haiku is conceptually based upon. When BeOS switched from the PEF on the PowerPC to x86 and the ELF Executable and Linkable Format (the same that Linux uses as well), they decided to append a resources section to the end of ELF files. They did not put this resources section into its own proper ELF section but merely appended it to (concatenated to the end of) the ELF, which means that tools like strip or other tools using binutils that are not aware of this will simply delete it. So better avoid manipulating BeOS ELF files with Linux tools after adding resources to them.

What is Haiku doing these days? Well, more or less exactly what BeOS did.

Haiku could, in theory, put the resources section into a proper ELF section. According to a developer in #haiku on irc.freenode.net, “with ELF a section would have made a lot more sense”, “the only reason we don’t is ‘BeOS did it that way’”, and changing it now would not be worth it.

Manipulating resources

Resources are in a structured “resources” format, essentially a list of resources and their size, and then the raw data. Reminds me of the ar format.

How can we inspect resources in Haiku? Is there something like ResEdit?

The Haiku documentation says:

To see the resources that are bundled with an application, you can drop the executable on a tool like Resourcer. You can also go into a Terminal and type listres filename.

Resourcer is available from HaikuDepot, but it just seems to crash on me.

Now, how can we manipulate resources in ELF files? Using rsrc and rdef. rdef files compile into rsrc. rdef, being a text format, are much easier to work with. The rsrc format is what is actually appended to the binary. Let’s play with them:

~> rc -h
Haiku Resource Compiler 1.1
To compile an rdef script into a resource file:
rc [options] [-o <file>] <file>...
To convert a resource file back into an rdef script:
rc [options] [-o <file>] -d <file>...
Options:
-d --decompile create an rdef script from a resource file
--auto-names construct resource names from ID symbols
-h --help show this message
-I --include <dir> add <dir> to the list of include paths
-m --merge do not erase existing contents of output file
-o --output specify output file name, default is out.xxx
-q --quiet do not display any error messages
-V --version show software version and license

We can use xres to inspect and manipulate them:

/> xres
Usage: xres ( -h | --help )
xres -l <file> ...
xres <command> ...
The first form prints this help text and exits.The second form lists the resources of all given files.The third form manipulates the resources of one or more files according to
the given commands.
(...)

So let’s give this a try, shall we?

/> xres -l /Haiku/system/apps/WebPositive/Haiku/system/apps/WebPositive resources:type           ID        size  name
------ ----------- ----------- --------------------
'MIMS' 1 36 BEOS:APP_SIG
'APPF' 1 4 BEOS:APP_FLAGS
'MSGG' 1 421 BEOS:FILE_TYPES
'VICN' 101 7025 BEOS:ICON
'VICN' 201 91 kActionBack
'VICN' 202 91 kActionForward
'VICN' 203 300 kActionForward2
'VICN' 204 101 kActionStop
'VICN' 206 243 kActionGoStart
'MSGG' 205 1342 kActionGo
'APPV' 1 680 BEOS:APP_VERSION

More on resources and rdef: https://www.haiku-os.org/documents/dev/compile_them_resources/

Standard resource types

While you can put anything into resources, there are a few defined standard resource types:

  • app_signature: MIME type of app, for file associations, lauching, IPC messaging, etc
  • app_name_catalog_entry : Since the application’s name usually is in English, this specifies where translated names can be found, so users in a different language can see a translated name if so desired
  • app_version: Exactly what you’d imagine it to be
  • app_flags: Specifies how the registrar should treat this application. I can smell there is more to this than meets the eye at first glance.
    For example, there is B_SINGLE_LAUNCH which makes the system launch a new instance of the app each time the user requests it (this is how most apps behave on Linux by default).
    Then, there is B_MULTIPLE_LAUNCH which makes the system launch an instance of the app per file.
    Finally, there is B_EXCLUSIVE_LAUNCH which makes the system launch just one instance of the application at any time for any reason, no matter how often the users requests to launch it (this is how e.g, Firefox behaves on Linux, and what QtSingleApplication can be used for to achieve a similar result on other systems). Applications with B_EXCLUSIVE_LAUNCH will be notified when the user tries to launch them again, e.g. they will get the path of the file the user tried to open with them
  • vector_icon: The app’s vector icon. (BeOS did not have vector icons, most apps had 2 bitmap icons in their binary instead.)

Of course, you can add resources with whatever IDs and types you want and read them in the app itself or other apps using the BResources class. But let’s stay with the fascinating topic of icons for a moment.

Vector icons, Haiku style

Of course Haiku didn’t settle with the first best format for icons. After all, the situation on the Linux desktop is far from ideal in this department:

me@host:~$ ls /usr/share/icons/hicolor/
128x128 256x256 512x512 index.theme
160x160 28x28 64x64 scalable
16x16 32x32 72x72 symbolic
192x192 36x36 8x8
22x22 42x42 96x96
24x24 48x48 icon-theme.cache

By just looking at it, you can already feel what a kludge this is.

Yes, there is scalable, and as you would imagine, it contains vector icons. Why is there then all the rest? Because if you render a vector graphic to small sizes, then the result may be less than ideal. What you want is different renditions optimized for different sizes. On the Linux desktop, this is achieved by scattering around multiple icons in different sizes in the filesystem:

me@host:~$ find /usr/share/icons/ -name 'firefox.*'
/usr/share/icons/HighContrast/16x16/apps/firefox.png
/usr/share/icons/HighContrast/22x22/apps/firefox.png
/usr/share/icons/HighContrast/24x24/apps/firefox.png
/usr/share/icons/HighContrast/256x256/apps/firefox.png
/usr/share/icons/HighContrast/32x32/apps/firefox.png
/usr/share/icons/HighContrast/48x48/apps/firefox.png
/usr/share/icons/elementary-xfce/apps/128/firefox.png
/usr/share/icons/elementary-xfce/apps/16/firefox.png
/usr/share/icons/elementary-xfce/apps/22/firefox.png
/usr/share/icons/elementary-xfce/apps/24/firefox.png
/usr/share/icons/elementary-xfce/apps/32/firefox.png
/usr/share/icons/elementary-xfce/apps/48/firefox.png
/usr/share/icons/elementary-xfce/apps/64/firefox.png
/usr/share/icons/elementary-xfce/apps/96/firefox.png
/usr/share/icons/hicolor/128x128/apps/firefox.png

Notice how there is no notion of different Firefox versions. So this system simply can’t handle multiple versions of an app being present on the system elegantly.

Different Firefox versions have different ícons, stupid! Yet the Linux desktop can’t handle it without crude workarounds

Mac OS X does this way more elegantly:

Mac:~ me$ find /Applications/Firefox.app | grep icns/Applications/Firefox.app/Contents/MacOS/crashreporter.app/Contents/Resources/crashreporter.icns
/Applications/Firefox.app/Contents/MacOS/updater.app/Contents/Resources/updater.icns
/Applications/Firefox.app/Contents/Resources/document.icns
/Applications/Firefox.app/Contents/Resources/firefox.icns

There is only one firefox.icns file in the Firefox.app bundle that handles all sizes, and different versions of the same application can have different icons.

Much better! The icon travels along with the application, and all resolutions are in one file.

Enter Haiku. Except nothing less than a mind-blowing solution.

The documentation says

A special Haiku Vector Icon Format (HVIF) was developed that is highly optimized for small file sizes and fast rendering. That’s why our icons are for the most part much smaller than either a bitmap or the widely used SVG format.

And boy is it optimized:

HVIF icon file size compared to other formats. Source: https://www.haiku-os.org/docs/userguide/en/applications/icon-o-matic.html

This is a factor of ten!

But the magic doesn’t end here. Despite being a vector format, one and the same HVIF can also show different levels of details depending which size it is rendered in:

Different Levels of Detail (LOD) depending on render size

Now, turns out the downside is that you have to go through some hoops to produce a HVIF icon, you can’t just throw a SVG onto ImageMagick and be done with it. https://www.haiku-os.org/docs/userguide/en/applications/icon-o-matic.html explains it. However, IconOMatic can (imperfectly) import SVG; probably about 90% of SVG details are imported and then you can just manually tweak and modify to get remaining 10%.

Learn more about how HVIF does its magic in this blog post by Leah Hanson:

Adding an icon to an application

With all of this information under the belt, I think I can now add an icon to the package I have created yesterday.

Since I don’t feel like painting my own icon at the moment, I am going to borrow the icon from Qt Creator for my “hello world” QtQuickApp:

/Haiku/home> xres /Haiku/system/apps/QtCreator/bin/Qt\ Creator  -o /Haiku/home/QtQuickApp/QtQuickApp  -a VICN:101:BEOS:ICON /Haiku/system/apps/QtCreator/bin/Qt\ Creator

Let’s check whether the icon was copied over:

/Haiku/home> xres -l /Haiku/home/QtQuickApp/QtQuickApp/Haiku/home/QtQuickApp/QtQuickApp resources:type           ID        size  name
------ ----------- ----------- --------------------
'VICN' 101 152238 BEOS:ICON

Looks good to me. So why is it, then, that the copied icon is not showing up?

The copied VICN:101:BEOS:ICONs not used as the appliction icon by the file manager yet

What am I missing here?

A developer explains to me

Create an rdef file with all the resources, then rc your.rdef — this will generate an .rsrc file. Then resattr -o yourbinary your.rsrc. At least i used this commands to add vector icon to my shellscripts

Well, I want to write a resource, not an attribute. I am lost.

Clever caching using the filesystem

Opening an ELF and then reading its resources is slow.

As described above, the icon is first written as a resource inside the file. This is robust and survives copying to other filesystems, etc. However, it is then also copied to a filesystem attribute, i.e. BEOS:ICON . This works on certain filesystems like BFS only.

The icons which are displayed by the system (e.g., Tracker and Deskbar) come from the BEOS:ICON extended attribute, because reading it from there is very fast. In some places (where speed is not of the essence, for example the standard about box) the system will get the icon from the resource instead.

But it doesn’t end there.

Remember that on the Mac, users can paste their own icons over the “standard” icons for applications, folders, and documents, allowing you to do “important” things such as changing the new Slack logo back to the original one on your Mac?

On Haiku, you can think of the resource (in the file) as the original icon that ships with the app, and of the attribute (in the BFS filesystem) as something that can be customized by the user as they want (although the GUI for pasting a custom icon over the default icon in the information window is not implemented yet, hint hint).

Inspecting attributes in the filesystem

resattr can be used for inspecting and manipulating filesystem attributes.

/> resattr 
Usage: resattr [ <options> ] -o <outFile> [ <inFile> ... ]
Reads resources from zero or more input files and adds them as attributes
to the specified output file, or (in reverse mode) reads attributes from
zero or more input files and adds them as resources to the specified output
file. If not existent the output file is created as an empty file.
(...)

Essentially, it is the “glue” that can be used to convert back and forth between (robust) resources and (fast) filesystem attributes. But since the system is supposed to take resources and do the copying automatically, I am not going to bother further.

The wizardy of hpkg packages

When you get software for Haiku, it nowadays (mostly) comes in the form of .hpkg packages. Don’t let the unpretentious name fool you: The .hpkg format works very differently than similarly-named package formats you may already be familiar with, and it has true superpowers.

With traditional package formats, I have long been annoyed with the fact that what you download (the package) is different from what becomes part of your system (the files inside the package). Once you have installed a traditional package, it becomes very hard to manage the files (e.g., remove them). This is because once a traditional package is installed, the files contained inside it are scattered all around the filesystem, including locations to which normal users don’t have write access to. Which is why a whole class of utilities had to be invented — package managers. It becomes even more difficult, if not outright impossible, to transfer already-installed software to, say, another machine, an external drive, or a file server. A traditional Linux system can easily consist of many hundreds of thousands to millions of individual files. It goes without saying that this is both fragile and slow, e.g., when initially installing the system, when installing, updating, and removing additional packages, and when copying the boot volume (root partition) to another disk.

As a partial workaround for end-user applications, I have been working on AppImage, a software distribution format that puts an application and everything it needs to run into a single filesystem image, which is mounted when then application is executed. This makes things significantly more straightforward, since something like e.g., ImageMagick suddenly becomes a single file that can easily be managed in the file manager by mere mortals. As the name implies, this only works for applications, and has its own set of downsides, as Linux distribution people have been keen to point out to me all the time.

Enter Haiku. Has it found the optimal balance between a traditional packaging system and image-based software distribution?

Its .hpkg packages are, in fact, compressed filesystem images. During system boot, the kernel mounts all of the installed and active packages, with messages like:

KERN: package_daemon [16042853:   924] active package: "gawk-4.2.1-1-x86_64.hpkg"KERN: package_daemon [16043023:   924] KERN: active package: "ca_root_certificates_java-2019_01_23-1-any.hpkg"KERN: package_daemon [16043232:   924] KERN: active package: "python-2.7.16-3-x86_64.hpkg"KERN: package_daemon [16043405:   924] KERN: active package: "openjdk12_default-12.0.1.12-1-x86_64.hpkg"KERN: package_daemon [16043611:   924] KERN: active package: "llvm_libs-5.0.0-3-x86_64.hpkg"

Cool, eh? Hold on, it gets even better.

There is a very special package:

KERN: package_daemon [16040020:   924] KERN: active package: "haiku-r1~beta1_hrev53242-1-x86_64.hpkg"

This contains the very core of the operating system, including the kernel. Believe it or not, even the kernel itself is not extracted to the boot volume (root filesystem), but is neatly loaded in-place from inside a .hpkg package. How cool is that! I mentioned before that I believe part of the overall elegance and consistency of Haiku comes from the fact that the whole system is developed together, by one team that looks at the full stack — from the kernel over basic userland over package management to the desktop infrastructure to the UX. Here is a great example of this factor at work. Imagine how many different gropus and teams would need to be involved to get something this up and running in Linux land. Then imagine how long it would take for this to be integrated into distributions.

There is the saying that in an organization,no matter how easy a task, if you split the task among enough heads, it will become complicated to the point that you get nothing done anymore.

Haiku is an eye opener for me — I think this is exactly what has been going on in Linux land for a while (and with “Linux land” I don’t mean the kernel here, but the typical Linux/GNU/dpkg/apt/systemd/Xorg/dbus/Gtk/GNOME/XDG/Ubuntu stack).

Rollbacks using the hpkg system

How often has it occurred to you that you have updated something, only to find out afterwards that it does not work properly anymore?

After traditional packages have been installed, it is hard to go back to an earlier point in time, before the new packages had been installed (e.g., in case something is going wrong). Some systems work around this by providing filesystem-level snapshots, but far from all systems use those and they are rather cumbersome.

Haiku solves this rather elegantly with .hpkg packages. Whenever you make changes to the packages on your system, the old packages do not get thrown away, but they are kept around on the system in /Haiku/system/packages/administrative/state-<...>/ forever. In-progress operations store their data in /Haiku/system/packages/administrative/transaction-<...>/ .

/Haiku/system/packages/administrative. "state..." contains text files listing the filenames of active packages, "transaction-..." contains the packages themselves

After each file manager operation, the “old activation state”, a list of the .hpkg packages that were active before the change, gets written to a text file in /Haiku/system/packages/administrative/state-<...>/activated-packages. Similarly, the new, current “activation state” is written to a text file in /Haiku/system/packages/administrative/activated-packages.

The /Haiku/system/packages/administrative/state-<...>/ directory may contain only the text file listing the activated packages in that state (in case you installed a package and removed none); if you uninstalled or upgraded packages, the state directory will also hold the old ones.

When the system boots, it decides based on this list which .hpkg packages to activate (mount) based on this list. Simple as that. How straightforward! Now, when something goes wrong, you simply tell the boot manager to use another, earlier list. Problem solved!

The Haiku Boot Loader. Each entry reflects an “activation state”

I like the fact that the “activation state” lists are approachable, simple text files with clear to understand .hpkgfile names in it — a stark contrast to the made-for-machines-not-people mess that systems like OSTree and Flatpak make in the filesystem (almost as bad as Microsoft GUIDs).

The list of activated packages for any given point in time

Configuration data

Looks like /Haiku/system/packages/administrative/writable-files contains the configuration files that come with packages but are read-write for the user. .hpkg packages are mounted read-only, remember? So those files need to be copied out of the packages before they can be written to. Makes sense.

GUI integration of the hpkg system

Let’s now have a look at how those shiny .hpkg packages are integrated into the desktop user experience (UX). Haiku is for the desktop, after all. Personally, I set the bar high, comparing the experience of .hpkg packages with the experience of .app bundles on the Macintosh. I won’t even begin talking about the situation on the Linux desktop, because it is absymal in comparison to either.

The following scenarios come to mind:

  • I want to inspect the contents of a .hpkg package
  • I want to install a .hpkg package
  • I want to delete a .hpkg package
  • I want to delete something that came to the system as part of a .hpkg package
  • I want to copy something that came to the system as part of a .hpkg package to another system
  • I want to download all dependencies of a .hpkg package that cannot be assumed to be part of every Haiku installation (e.g., because I have an air-gapped machine that is not connected to the Internet)
  • I want to keep my .hpkg packages (or some of them) in a special place, separate from the usual location in the boot volume (root partition) (e.g., because I am running out of space)

That should cover the most basic cases that I run into in my daily work. So, let’s begin.

Inspecting the contents of a .hpkg package

On the Mac, I can just right-click an .app bundle to open it and inspect its contents in Finder. It’s really just a directory in disguise, after all! (I know, the Mac also has .pkg packages for system-level stuff that is not applications, but normal users don’t usually interact with them all too often.)

On Haiku, I can double-click a .hpkg package, then click on “Contents”, to see what is inside. But it is only a list of files without a possibility to open them by double-clicking. It would be nicer if there was a way to (temporarily) mount the a .hpkg package to peek inside using the file manager, all without the user needing to care about the implementation details. (In the meantime, I can open a .hpkg packages in Expander, which will extract them like any other archive.)

The HaikuDepot GUI can list the contents of packages, but there is no way to, say, double-click on README.md

In this category the Mac wins but adding such functionality to HaikuDepot should be not that hard.

Installing a .hpkg package in the GUI

On the Mac, most applications come as .dmg disk images that contain .app bundles. One double-clicks the .dmg disk image and then copies the .app bundle to, e.g., /Applications by drag-and-drop in the Finder. To me this is second nature, but I hear that some new users are struggling with it. By default, Apple only “advertises” the system-wide/Applications directory (there used to be a network-wide and a per-user one, going back to NeXT), but you can easily just put your applications on a file server or into $HOME/Applications if you like to.

On Haiku, you double-click a .hpkg package and click “install”, simple enough. I wonder what happens if such a package has a dependency that is available in HaikuPorts but is not installed on the local system yet. Many Linux desktops don’t really know what to do in this situation, although the solution is obvious — ask the user whether to download and install the dependencies.

Which is precisely what Haiku does.

I downloaded sanity manualleand double-clicked its .hpkg, the packge manager knows where to get its dependencies from (as long as they are in a repository already known by the system). Not every Linux distribution can do this.

Alternatively, it is also possibly to use drag-and-drop in the file manager, and simply move the .hpkg package to either /Haiku/system/packages (for system-wide installation, which is the default) or to /Haiku/home/config/packages (for per-user installation, which is not available by double-clicking — I am still irritated by the term “config” in there, which for me is a synonym for “settings”). Heck, the concept of multiple users is not even yet available in Haiku (which may be part of why things are so simple — I am undecided as to whether adding multi-user capabilities does not unnecessarily complicate things on a personal computer desktop).

In this category Haiku wins, because it not only works with applications but also with system software.

Deleting a .hpkg package in the GUI

On the Mac, you drag the application icon to the Trash, that’s it. Easy!

On Haiku, first of all you need to find out where a .hpkg package landed on the system, because most of the time you will not have been the one who has moved it in place (the system has), usually/Haiku/system/packages (for system-wide installation, which is the default) and /Haiku/home/config/packages (did I say that I find the “config” a misnomer?). From there, you drag the application icon to the trash, and that’s it. Easy! Except that it isn’t. This is what actually happens:

This is what happens when you try to move a .hpkg package to the trash from /Haiku/system/packages

I have literally just tried to move my QtQuickApp “hello world” application that I had packaged yesterday to the Trash. I did not attempt to move the system folder. But since all packages land in the system folder, I cannot seem to remove a .hpkg package without modifying “its contents”. A normal user is frightened here and will press “Cancel”, which fittingly is the default button.

Explains Haiku developer mr. waddlesplash:

This message has existed for over a decade, likely we should tweak it to only warn when moving the Haiku package itself. General users should not modify packages this way, anyway.

OK, maybe we need to do this through the HaikuDepot package manager GUI. So I double-click the .hpkg package in /Haiku/system/packages, suspecting that it will show an “Uninstall” button. Nope. There is (still) “Install”, but no “Uninstall”.

Just for fun, I see what happens when you “Install” the already-installed package. This is what happens:

This is what happens when you “Install” the already-installed package

Followed by:

This is what happens after you click “Apply changes”

I think this is a bug. There is already a ticket for it. (Link or it didn’t happen.)

Quick fix: Put an “Uninstall” button there if the package is already in /Haiku/system/packages or /Haiku/home/config/packages

If I view the list of packages installed in HaikuDepot, my package appears and I can uninstall it.

In this category the Mac currently wins. I can imagine that with some tweaking, the Haiku user experience could overtake the Mac. (A Haiku developer estimates this to take “an hour or less to add said functionality to HaikuDepot if you know some C++” — volunteers?)

Deleting something that came in a .hpkg package in the GUI

Now, let’s try to delete the application itself, not the .hpkg package it came in (I doubt that “mere mortals” would understand the difference anyhow).

On the Mac, well actually, the user has to deal with the .dmg file an application came in, and the the .app bundle itself. Usually the former pile up in the Downloads directory while the latter get copied by the user to /Applications. I suspect many users don’t really know what they are doing, a hypothesis that is confirmed by a former Apple employee. (This is something I don’t like on the Mac. Hence, with AppImage, there is no difference between “the application itself” and “the package it came in”. You drag the application icon to the Trash, that’s it. Easy!)

On Haiku, there is also the distinction between apps/ and packages/ that I doubt users will understand any better. This is what happens when you move an application from apps/ to the trash:

This is what happens if you try to delete an application that came in a .hpkg file

This may be technically true (the application is on a read-only filesystem image, after all) it is not really helpful for the user.

Quick fix: Have the GUI offer to uninstall the .hpkg instead

Just for fun, I am trying to duplicate the application by pressing Alt-D. I get “You can’t move or copy items to read-only volumes.” This is because /system (aside from /system/packages and /system/settings) is a packagefs volume (remember it appeared in df as a separate mount?). Unfortunately, the mount command is not really helpful (as pointed out in an earlier installment of this article series), mountvolume does not show what I am looking for (apparently loop-mounted .hpkg packages are not considered “volumes”), and I have already forgotten the alternative commands.

In this category neither Haiku nor the Mac really wins; AppImage does (full disclosure: I am biased). I can imagine that with some tweaking, the Haiku user experience could overtake the Mac.

Side note, need to find out what is a “volume” really, compared to “partition”. Probably similar to what a “folder” is, related to a “directory” — most directories are shown as folders in the file manager, but not all of them (e.g., bundles, which are treated like files). Does this now make me officially a nerd?

Copying something that came in a .hpkg package to another system in the GUI

On the Mac, drag-and-drop the .app bundle. Dependencies are inside the .app bundle, so they are moved along.

On Haiku, drag-and-drop the application. Dependencies are not handled at all.

Quick fix: Have the GUI offer to move the .hpkg instead, and optionally the dependency .hpkg packages as well

In this category the Mac clearly wins. For me, anyway, as someone who likes the Mac paradigm. Haiku wants me to copy the .hpkg instead — only it does not tell me so…

Downloading a .hpkg package with all its dependencies in the GUI

Not every machine is online all the time, although some systems (yes, I am looking at you, contemporary Windows, Mac, and Linux) seem to be forgetting this. For me, it is important that I can go e.g., to an internet cafe, download software, put it on a removable medium, insert that medium at home into the computer, and be sure that it will work. More often than not, I am greeted by unmet dependencies on Windows and Linux.

On the Mac, usually one file, downloading the .dmg is all you need. Most of the time it has no dependencies other than what comes with macOS by default. Exceptions apply for more complex applications that need runtimes such as Java.

On Haiku, downloading the .hpkg package for, say, a Java application is not sufficient since Java may or may not be present on the target machine. Is there a way to download all .hpkg dependencies for a given package, except for those that are part of the default installation of Haiku and can hence safely be assumed to be present on every Haiku system?

In this category the Mac slightly wins.

Says Haiku developer mr. waddlesplash:

Writing a tool to collect all the dependencies of an application into one set of .hpkg packages would probably take about 15 minutes for someone who knew Haiku package internals. So if there is really a demand for this, adding support for it is not hard. But it seems like a rare thing to me.

Hold your breath for tomorrow’s installment of this series.

Keeping .hpkg packages in a special place

As written above, I want to keep my .hpkg packages (or some of them) in a special place, separate from the usual location in the boot volume (root partition). A common (and not too theoretical) reason for this is that I am constantly running out of space on my main (built-in) disks, no matter how large they are, and then usually resort to attaching external drives or network shares on which my applications reside.

On the Mac, I can just drag .app bundles to a removable drive or network share in the Finder, and be done with it. I can still double-click the applications just like if they were on the boot volume. Simple!

On Haiku, so I am told, this might be possible to achieve by moving my .hpkg packages to a removable drive or network share, but then you’d need some undocumented command-line voodoo to get them mounted into the system. I don’t know how to do that, and it is clearly not GUI UX.

In this category the Mac wins.

Haiku developer mr. waddlesplash:

We optimized for the most usual usecases here. If there is actually a demand for this beyond one user, we can implement. Otherwise, 3rd party opportunity

This will be a topic for tomorrow’s episode.

Speaking of network shares: Simple, discoverable, network-wide applications (think Zeroconf advertising applications) that can either be launched from the local network, or copied to the local machine would be neat (think LAN parties). Of course application developers could opt out through app_flags.

Summary regarding GUI integration of the hpkg system

Overall, .hpkg integration still leaves a bit to be deserved, but I think only because it is all relatively fresh. Anyhow, here are a few things I think could be improved in the UX department…

One more thing: Kernel Debug Land

Wouldn’t it be great if you could, when you encouter a kernel panic, continue to enter commands like syslog | grep usb ? Well, with Haiku, you can, thanks to Kernel Debug Land. Now, if you are lucky you will not be running into a kernel panic anytime soon, so what to do if you want to see this magic in action? Easy, press Alt-PrintScn-D (arguably for “debug”). I feel instantly reminded of the “Programmer’s Key” https://en.wikipedia.org/wiki/Programmer%27s_key that had let original Macintosh developers enter a debugger (had they one installed).

Conclusion

I begin to see how the elegance of the Haiku system comes from the fact that it is developed by a small team with a clear focus on the desktop, with access to all layers of the stack.

A stark contrast to the Linux/GNU/dpkg/apt/systemd/Xorg/dbus/Gtk/GNOME/XDG/Ubuntu world, where everything is fragmented to the degree that abstraction is stacked over abstraction and workaround is stacked over workaround.

I begin to see how the .hpkg system combines the best aspects of traditional package managers, Snappy, Flatpak, AppImage, even btrfs and blends them with the “it just works” elegance of the Mac.

It just “clicks” with me. I was able to understand how the .hpkg system system works its rollbacks magic by just glancing at it quickly. It’s not me, it’s the beauty and simplicity of the system. Much in the spirit of the original Mac.

Yes, web browsing may be broken and slow as molasses, applications may be scarce (after all, no Gtk, no Electron — developers have concluded they don’t mix well with their sense of elegance) and video and 3D acceleration may be missing altogether. Yet still I like this system. Those things can be fixed, and they eventually will be. It is only a matter of time, and maybe of eyeballs.

I can’t help but wonder when will be the Year of Haiku on the Desktop.

Random nitpicks

Are there already tickets for those or should I open them?

  • BeScreenCapture should have an option to export to animated GIFs, like Peek does. It can be done with ffmpeg, which is available on Haiku. Ticket
  • The Screenshot tool fails to capture modal dialogs with “Capture active window”, capturing the whole screen instead
  • Cropping screenshots with the crop tool in Wonderbrush and then saving cripples the file
  • I am not especially fond of the “hand” cursor in Haiku, but i guess people have warm historic feelings attached to it. It gets especially annoying when trying to use the crop tool in Krita, resulting in imprecise cutouts (as evidenced by the modal dialog screenshots in this article). A crosshairs cursor would do wonders for the crop tool. Ticket

Try it out for yourself today! The Haiku project provides nightly images that can be booted from DVD or USB. Installation consists of downloading the nightly 64-bit image and writing it to a USB stick using Etcher.

probono is the founder and lead developer of the AppImage project, the founder of the PureDarwin project, and a contributor to various open source projects. Screenshots were made on a Haiku system. Grateful acknowledgment is made to the developers in #haiku on irc.freenode.net, particularly mr. waddlesplash, @PulkoMandy, @diver, @begasus, and @humdinger.

--

--

probono

Author of #AppImage and contributor to hundreds of open source projects. #LinuxUsability, digital privacy, typography, computer history, software conservation