Random Haiku development and debugging stories

Ok, so, I have explained in another topic that I won’t do livestreams with my Haiku development, but I would occasionally blog about stuff. There isn’t always enough material for a blogpost, so here I will do somewhat shorter posts telling how my day (or week) went.

This and next week I am off work, so I have more time than usual for opensource software development, which I plan to spend on finishing various projects that I have started a few time ago and had to put on the side for lack of time.

The first is the ACE Amstrad CPC Emulator. More about it at https://ace.cpcscene.net

Yesterday, I made a new release of it with several small bugfixes that accumulated in my Git repository over the last 6 months. So far so good, no problems with that. Then I started looking into “acepansions”, these are add-ons to ACE that allow to emulate various peripherals for the Amstrad CPC machine. I already have the framework set up to port each add-on to Haiku easily. I should mention that this is a “native port”, which means, I completely rewrote the GUI for ACE and all of the plugins, and made a compatibility wrapper for the core of the emulator (which is originally developped for MorphOS). So, I worked on some of the add-ons and started adding them to ACE website. Again, no problem so far.

One thing I need to do is draw a nice icon for each add-on, so that it looks nice in Tracker. Handmaus did provide me with some icons, which look great. But there are more add-ons. And so I need to make new icons. I turned, of course to Icon-O-Matic. My goal was simple: I want to make an icon for the Multiplay expansion, which allows connecting a mouse and joystick to the CPC. An obvious icon for this can be obtained by merging the icons for Mouse and Joystick preferences. So, I opened the Joystick icon, appended the Mouse icon, went to resize and move things around and… Icon-O-Matic crashed. Uh-oh.

So, I made a bug report. I looked at other bug reports and found that another one for a crash on saving was a bit similar. I could confirm that after appending a file to another (if the first had transforms), I could reproduce the crash. So I started adding traces in the code and, with the help of Debugger, finally identified the problem. You can find the patch here: https://review.haiku-os.org/c/haiku/+/7052

Interesting story? I don’t know. The problem is, that last paragraph is what took me most of the day to figure out (not fully focused on it, of course, I’m off work and trying to relax a bit!).

So, what did you work on today? Did you fix a bug? Did you implement a new cool feature in Haiku or in your own app? Let us know!

20 Likes

The latest “big”-ish thing I’ve been working on in ArtPaint is reworking how selections are stored.

Selections are generated as a bitmap in black and white, with black being unselected pixels and white are the selected pixels. Then the shapes are traced via a contour-tracing algorithm, and the contours are stored as polygons. This is very convenient because if you want to store a selection and retrieve it, or manipulate a selection (like rotate or scale), you can just use the polygons which take a lot less space in memory than a bitmap. To regenerate the selection bitmap, you walk through the polygons, and if a polygon is drawn clockwise, you fill it in white, and if a polygon is drawn anti-clockwise, you fill it in black. Works great.

However, to do fancier things with selections, like painting or blurring, you can’t just have black and white selections, you need grayscale values. This breaks the polygon-manipulation paradigm, because there’s no way to store which pixels are not pure black nor pure white. The easiest solution is to work with the selection bitmaps directly. The fun part is that something as fundamental as selecting pixels means that there are a lot of places and possibilities for breaking things. I’ve been slowly migrating ArtPaint to use these bitmaps, and along the way I have found and fixed several other issues.

As of last night, I think I am down to only the Scale manipulator behaving oddly in some cases. Undo/Redo was a bit of a headache because only the polygons were stored. There were also multiple places where the code helpfully regenerated the selection bitmap by filling the polygons black or white as I described above.

Anyway it’s been the type of feature that seems easy enough until you realize you have opened a can of worms and they are wriggling everywhere. I had to close the worm can, put it back on the shelf, and take a break for a while because I didn’t see an easy way to solve all the problems. Now, I’m happy to say that I think I have figured out all the issues and just need to fix up some bugs in Scale. The downside is it’s a foundational piece so from a user standpoint you won’t notice a difference (in fact a user-visible difference is likely to be a bug), but it will allow for some neat new features in the future.

I don’t know if this is an interesting story either, but it’s what I’ve been doing the past couple of days!

12 Likes

I really like this series @PulkoMandy! I hope that more and more people share their dev stories here, it’s a good way to let our community know what we are working on (and how things are going).

In the past few weeks (months?) I’ve been busy with three projects (TL;DR):

  • an input filter that enables scrolling on thinkpads (middle mouse button + trackpad up/down)
  • a plugin for Claws Mail that provides some integration with Haiku
  • Genio which usually is my main focus

Input filter

There is little to say here, this filter works but there are a few aspects that need to be ironed out and polished. It supports natural and reverse scrolling and both horizontal and vertical scrolling.
I’m not 100% with the way horizontal scrolling is implemented, the area tends to scroll in all directions and it’s quite annoying. Either I’m able to “predict” the direction and lock it or I need to dismiss this future.
Currently the filter intercepts the press of the middle button (and/or keyboard modifiers) and the trackpad gestures and translates this into a traditional mouse wheel scrolling message. This leads to a very fast scrolling allowing for little control on the trackpad. I need to figure out how to make it smoother and more precise.
This filter is not published yet but if you are interested to test it let me know!

Claws Mail plugin

I use iCloud mail and like all Apple products or services it has its own quirks when it’s used outside of the Apple ecosystem.
Mail daemon can receive but not send, Beam can send but is unable to receive. Other clients have problems, too.
Unfortunately mail daemon does not like iCloud or the opposite… Establishing an SSL connection is unreliable most of the times ending with a connection refused by the server (there’s a ticket about this)
The only one that works consistently and reliably with it is Claws. It has several problems and limitations, of course. As a non-native glib/gtk app it does not integrate at all with Haiku let alone other critical issues like the keymap and the inability to use the @ symbol. Nevertheless, it is what it is…
I started an effort to create a plugin for Claws which somehow works for me, see the details here.
The most annoying part was to deal with glib/gtk which I think nobody is interested in.
During the development I’ve instead come across a few interesting things.
A mixed C/C++ shared library apparently does not export all the symbols correctly so a Deskbar can’t be “embedded” into it. I had to create a separate application that is launched by the plugin upon loading and quit upon exit.
I have chosen this path also because the wrapping BApplication allows me to send messages to the application more easily.
The replicant lives in the Deskbar and there is no easy way to get its instance to send BMessages to.
One can either traverse the tree of all the views living inside the Deskbar (extremely annoying, complex and error prone) or let the BView subscribe (watch) specific messages hitting the BApplication:

if (LockLooper()) {
	StartWatching(fAppMessenger, UPDATE_STATISTICS);
	UnlockLooper();
}

It then receives the messages notified via SendNotices() by the BApplication in MessageReceived():

case B_OBSERVER_NOTICE_CHANGE:
{
	int32 code;
	msg->FindInt32(B_OBSERVE_WHAT_CHANGE, &code);
	switch (code) {			
		case UPDATE_STATISTICS:
		{ ... }

Thanks to @jackburton for pointing me in this direction!

Another interesting thing I’ve consequently achieved is to inject some features in the Claws application under the form form of a Message filter coupled with a custom BHandler atteached to the main application. The idea came after using and customizing spybmessage.cpp which is available in the Haiku source code but is not built by default and shipped with a typical installation.
By hijacking the existing messaging system, I was able to receive messages that Claws was not designed to handle like B_ARGV_RECEIVED and B_REFS_RECEIVED along with custom ones from the Deskbar replicant like COMPOSE_MESSAGE.

Genio

I’m setting the foundation for an overhaul of the git subsystem. I’ve taken some code and inspiration from TrackGit but in the end this is going to a different path.
The first feature that found its way is Cloning a remote repository and opening it in the workspace (available in the main branch here).
At the core of this feature there is a new Task class which is a polimorfic perfect-forwarding template that accepts all kind of callables (free functions, lambdas, class methods, etc.), runs a thread and returns a BMessage to the BMessenger provided when the task is complete.
The BMessage includes a TaskResult instance serialized that holds the result if available and any exception eventually raised in the task that is transported to the TaskResult and is rethrown when calling GetResult().
If you want to know more about this, please have a look at how it is implemented in Genio here and here. There’s also a standalone repository with some tests built-in here.

Is it interesting? I don’t know but I hope someone enjoys it as much as I enjoyed writing it.

9 Likes

Would it be good to store this dev stories as cathegorie/stories in our knowledge base?

If we get the allownes to do this we can store them there, so people can found them better.

Only a idea

1 Like

I got Luau to compile on Haiku and got the patch pushed upstream. Nothing currently uses it outside of Roblox but it looked useful at the time.

1 Like

I’m fine with it! Just be carefu! Duplicating contents can negatively impact Google rankings.
If you really want to make a verbatim copy (again, fine by me) you should use the tag canonical, there are tons of examples around to solve this SEO problem.

The forum contents is unlikely to disappear. You could just add a link to this very thread

1 Like