Welcome back! As you may have realized, Horizon EDA has seen less development activity in the last year than it did before. This is mostly due to me having started developing another CAD software - Dune 3D a parametric 3D CAD. Go check it out on dune3d.org. It greatly benefited from the experience I gained from developing Horizon EDA and reuses many concepts both in implementation and user interface. If you like Horizon EDA, I’m sure you’ll like Dune 3D as well!

Compared to Horizon EDA using Gtk3 it’s built with Gtk4 since it had the higher version number, i.e. longer time to deprecation and I wanted to know where Gtk is headed. I should probably write a blog post reviewing Gtk4, but it’s safe to say that Horizon EDA will stay on Gtk3 for the foreseeable future since porting it to Gtk4 will take a lot of time and effort and will ultimately result in a worse user experience.

With that out of the way, let’s dive into what has happened since the last release.

User layers

Even though it’s still a fairly expensive process, every now and then users were asking they could do rigid-flex PCBs with Horizon EDA. Since I want Horizon EDA to be an enterprise-class PCB design tool, supporting rigid-flex seemed like an interesting challenge.

From a PCB layout tool perspective, this mostly means supporting layers inserted at arbitrary positions in the stackup for denoting features such as flex areas, rigid areas or stiffeners.

In Horizon EDA, layers are referenced by hardcoded integers. Since these layer numbers are also used in the design files, they’re effectively set in stone as any change to them would either break compatibility with older files or require fragile conversions. Back when defining the layer numbers I realized that and spaced them in increments of 10 so it’d be possible to insert layers in-between existing layers without changing existing layer numbers. Unfortunately I didn’t have that much foresight when it came to the inner copper layer numbers though as they’re numbered -1, -2, etc., making it impossible to squeeze extra layers in between them which is just what we need for flex PCBs.

To work around this, user layers are assigned numbers outside out of the board stackup ranging from 1000 to 1007, allowing for up to 8 user layers. Their position in the stackup is defined by a newly-introduced position attribute that’s a floating-point number, making it possible to put them anywhere in the stackup. This however required some refactoring in various places since it’s now a layer’s position that determines its place in the stackup and not just its number.

User layers can be added, removed and rearranged in the Stackup dialog:

Screenshot of stackup dialog

The user layer types are aligned with what’s defined in the ODB++ specification to simplify communicating design intent to board manufacturers.

Selection enhancements

The true-and-tested interaction model for most interactive applications is selecting things and then doing something with them. Horizon EDA is no different in that regard. In some cases the first part of selecting the right things can get quite complicated. To narrow down selectable items, Horizon EDA supported a selection filter since day 1. While that already helps a lot in dense multi-layer boards, there were still some rough spots left:

Holding down Ctrl always toggled items from the selection, making it very hard to just add or remove items from the selection. To improve on that, it’s now configurable whether holding down Ctrl should toggle, add or remove items from the selection.

When making a complex selection, holding down Ctrl can become rather awkward and unergonomic, especially on laptops. To fix that, we’ve now got a ‘sticky selection’ option to invert the behavior of the Ctrl key so that the selection behaves as described above if it’s not pressed.

Without sticky selection enabled, clicking anywhere without Ctrl held down clears the selection, potentially destroying a minute worth of tediously selecting things. Wouldn’t it be nice if there was a way to undo and redo selection changes? With version 2.6 there is! The selection undo/redo buffer also comes in handy as way to recall past selections for moving a group of objects after something else has been selected.

All of these new options are available from the selection popover:

Screenshot of the selection popover

Thanks to Horizon EDA’s unified editor, they’re available in all editors from symbol to board.

Improved wayland support

TL;DR: switching between schematic and board editor isn’t broken on wayland anymore

About a year or so ago I finally moved from i3 on X11 to sway after people told me about waybar since sway’s builtin bar doesn’t support menus as they’re used by the networkmanager applet which was deal-breaker for me.

Apart from pointer warping everything was working more or less as it did on X11. Only after a recent sway update, switching between windows such as by pressing Tab in the schematic editor stopped working and the to-be focused window only got highlighted. Clearly something was something wasn’t working quite right to not trigger sway’s focus stealing preventions since the schematic and board editor are separate processes.

In pretty much all major windowing systems there are mechanisms that prevent applications from stealing focus, i.e. making their window the active one if none of their windows has focus right now. To still allow a non-focused application to get the focus, the windowing system requires some proof that the request originated from an application that currently has focus.

On X11 this is accomplished by passing the timestamp from the triggering event to the other process for raising the window. On Windows this is even simpler by calling AllowSetForegroundWindow with the PID for the process of the to-be focused window which can then gain focus.

In wayland land, there is the XDG activation protocol. It works by creating a token in the currently-focused application and passing that token to the process that wants to raise its window. I tried directly calling the wayland API but didn’t get very far since I couldn’t get the required event serial from Gtk. After asking on the GNOME discourse forum I got pointed to APIs that superficially only seem to be concerned with application startup IDs, but actually do exactly what I want.

New build system

TL;DR: Horizon EDA now builds using meson.

In March 2023 the PDF library podofo Horizon EDA uses for PDF output released version 0.10 that is API-incompatible to the prior version 0.9. While this isn’t a problem by itself, the way some distributions such as Arch Linux handled it made it one. Instead of keeping podofo package at the old 0.9 version and packaging the new 0.10 version as podofo-0.10 or such, they upgraded the podofo package to 0.10 and provided a podofo-0.9 package with non-standard include and pkg-config paths. Since I initially didn’t want to spend the effort of adding support for podofo 0.10 and maintaining two PDF export implementations, the build system now had to discover the right paths for podofo 0.9.

Since its early beginnings in late 2016 Horizon EDA was using plain GNU make as its build system as that’s all I knew back then. Over time, with the help of other people, it grew with the project’s needs, supporting various Linux distributions, FreeBSD and Windows.

However, discovering include paths isn’t something that’s easily doable with make, so it was time to go shopping for a new build system. The contenders were:

  • GNU autotools
  • cmake
  • meson

GNU autotools was out early on since its main selling point of providing compatibility with mid-90s UNIXes isn’t of any use to Horizon EDA and it’s overly obtuse.

Cmake is used by by many C++ projects, but looking at some random CMakeLists.txt, its syntax made no sense at all to me.

So meson it is. Many GNOME-adjacent projects switched to it from autotools in the past couple of years, so it can’t be that bad I figured. Having significant usage on the Linux desktop also meant that downstream packagers will already be familiar with it and I’ll be less likely to run into problems no one has seen before.

Despite I don’t usually have the spoons for build system touching, getting started with meson was surprisingly easy and there was a good solution for all challenges I encountered along the way and felt much cleaner than plain old make. A+++ would buy again.

New Forum

Due to inactivity, the Discourse forum at horizon-eda.discourse.group was shut down. The new place to discuss all things Horizon EDA is GitHub Discussions.

In case someone needs anything from the discourse forum, I have a full backup in the form of an SQL dump.

Version 2.6

Finally, version 2.6 “Luna” is out! See the changelog for a list of all enhancements and bugfixes included in this release.

Also keep in mind that Horizon EDA is mostly a one-person show that I run in my spare time, so bear with me if things take a little longer.