๐Ÿง‘โ€๐Ÿ’ป๐Ÿ John's Blog ๐Ÿฏ

This is both a personal log and a collection of resources for my hobbies.

Six years ago I discovered GNUstep and the world of Open Source implementations using Objective-C as programming language. Just a little later I discovered ObjFW and immediately was haunted by the idea to write apps that would run on at least two platforms: macOS (Mac OS X) and Linux, elementary OS particularly.

=> https://git.nil.im/ObjFW/ObjFW ObjFW

This was when ObjGTK was begun in 2021. The beginnings were really easy because Tyler Burton had written CoreGTK and I only had to port it to ObjFW. Turned out, that was a quick and easy task and Tyler's examples worked almost immediately.

=> https://github.com/coregtk/coregtk CoreGTK

I released that changes as ObjGTK 0.1 and 0.1.1.

=> https://codeberg.org/ObjGTK/gir2objc/src/tag/0.1.1 ObjGTK 0.1.1

But that was only the start and the point where I started learning GTK, or to be more precise, the GObject runtime and type system. It was a great way of learning, because I discovered bits and pieces missing in ObjGTK (or its generator gir2objc), learned about implementation details of GObject C and then wrote the translation to ObjC.

It was a nice community work because especially Sergey Bugaev taught me a lot of the GObjects internals and helped me to implement even the very basic beginner tasks like memory management.

It took some years and in the beginning of this year 2025 some bits and pieces fell together that after 4 years (of admittingly seldom and short spare time work during some evenings) I eventually started writing the GTK interface for my app โ€œcontacts2phoneโ€.

=> https://codeberg.org/Letterus/contacts2phone/src/branch/add-gtk-view GTK branch of my app โ€œcontacts2phoneโ€

Well I did that, to then learn that still a lot more was missing for gir2objc / ObjGTK. That was the time when I eventually started to consider whether to proceed writing that bindings. Not because it couldn't be done, but because I was questioning if I should do it in my very limited spare time.

ObjGTK was my project to learn GObject and C, but apparently there really is a lot more to learn. The issue tracker tracks what I know is missing and it's missing all the pieces that I don't know about.

=> https://codeberg.org/ObjGTK/gir2objc/issues gir2objc issue tracker

Implementing that listed required features would require some major refactoring of gir2objc, because it's based too much on guessing types out of strings instead of using type qualifiers parsed from XML/gir files directly.

So much about the tech side.

For me over that past 4 years it became clear I didn't even finish one app, not to speak about the bindings. And I really wanted to write at least one app since years.

This year two more things happened: Tim Cook made a vassal gift to the big dictator at the other side of the Atlantic Ocean. And Apple released macOS 26 Tahoe, looking like Windows 7 back in the days.

=> https://www.bbc.com/news/videos/cp8zyyygxv7o

Both events made me finally loose any interest in the Apple platform that practices peak capitalism, uglyness and missing ethical values. I love the old golden tech of the 2005 to 2012 era, but I don't want to use any of this company's stuff today (I still have to and do, but that's a different story). I don't want them to earn money and I am not interested any more to earn any money using their platform.

To summarize:

  1. I've got no more interest in the Apple platform(s), my cross platform aim from the beginning of ObjGTK vanished.
  2. I didn't complete a single app featuring an UI using the Objective-C only approach.
  3. I really don't manage to learn all that stuff about GObject and C implementation details.

Speaking reasonably that's enough for me to finally give up that approach and choose a different one. But, I'm really bad at giving up. I seldom admit a task is too big for me, but this one is. And I liked the approach of writing apps, I really enjoy writing Objective-C (a language I really learned quite a bit) and I really like ObjFW. Jonathan is doing great work since many years to keep ObjFW working on a multitude of platforms and he ensures that it's a joy to use. Using ObjFW you may use a compiled, fast and clean object oriented language without the need to know too much about C implementations details.

But one more thing I learned over the years: Free Software is not about how nice or well done a certain technology or library is. There are approaches seemingly very haunting, because they are done so well. But eventually Free Software is about how strong communities are to actually perceive the goal of delivering working and useful software. That task most often won't be done by individuals alone, it's done by communities.

As a conclusion: It's hard, but I'm giving up ObjGTK and leaving it as is โ€“ as a learning project that brought a lot of joy to me. It may be picked up by whoever likes to further improve it. Contact me, I am happy to get you going.

For me I'm now in need to consider how to โ€œfinishโ€ contacts2phone (read: make it actually work like I want it to).

Will I try a complete rewrite using Vala? Will I try to replace ObjGTK/GObjects bindings in ObjC for the recently published peel (from Sergey)? The latter would require me to learn C++, but at least I could keep some core business logic written in ObjC. Currently that seems most interesting to me.

=> https://gitlab.gnome.org/bugaevc/peel

Almost a year went by since my last post. Autuum is coming slowly, so it's time to get back to hacking. Or, at least, prepare some stuff.

Over the last 5 years of mainly using Linux and having tryied many different distributions, I detected I got a little tired of that and longed back of the profound experience of mac OS. There's quite some nostalgia involved of course, but also I was just missing some conveniences and beauty.

Since I wanted to use a โ€œgood oldโ€ device and got a very good MacBook Air 11โ€ from 2014, I first gave an implementation of the project โ€œMavericks Foreverโ€ a try.

=> https://mavericksforever.com/

And, omg, it looked and felt so great!

=> https://fosstodon.org/@lazarus/115150153203375007

It really fit the 2014 device just perfectly. But soon I recognized the troubles due to outdated SSL implementation (and not fully working MITM proxy) were quite serious (I couldn't connect to my uberspace anymore, even the generous help of Benny, the developer of MailMate, didn't help), also there were quite some Open Source apps I needed I would have to โ€œbackportโ€ and the work just accumulated. (If I wanted that I could just got back to any Linux desktop, obvious amounts of necessary development work would appear on any of them.)

So I threw away the โ€œMavericks Foreverโ€ approach (at least it were some happy days) and went on to Mojave (Mac OS X 10.14). It runs more modern software, SSL works, modern ObjC features work and it still runs 32 bit apps in case I needed one of them. Very modern apps require macOS 12 or later these days, but there are quite some that work from 10.13 onwards (sadly not LibreOffice, but hey, maybe time to use a Mac app or just Markdown/pandoc/LaTeX for writing).

So it was project โ€œMavericks Foreverโ€ became โ€œMojave a little longerโ€.

=> https://fosstodon.org/@lazarus/115185699923864597

Update from 2025-10-30: Currently I'm not intrigued to develop for an Apple platform anymore. Maybe I left that retro cave behind. Let's see.

Looking at my Linux Desktop usage. What UI toolkits do I really use?

  • Firefox: Own (integrated with GTK3)
  • LibreOffice: Own
  • Lagrange: Own
  • Sublime Text/Merge: Own
  • Evolution: GTK3
  • KeepassXC: Qt
  • QOwnNotes: Qt
  • Scribus: Qt
  • GIMP: GTK3
  • Fractal: GTK4
  • Pantheon Tasks: GTK3
  • Canonical Document Scanner: GTK3
  • Element: Electron
  • WhatsApp: Electron
  • Threema: Electron
  • Cider: Electron
  • Nextcloud Desktop: Qt
  • Nextcloud Tasks: Web App
  • Seafile Client: Qt
  • Recoll: Qt
  • Charm: Qt
  • Synapse Launcher: GTK3
  • PDF Arranger: GTK3
  • Zoom: Own
  • Jitsi Meet: Electron
  • VLC: Qt
  • OBS Studio: Qt
  • OpenLP: Qt
  • FileZila: wxWidgets

Own/Proprietary: 5 GTK3: 6 GTK4: 1 Qt: 9 Electron/Web: 5 wxWidgets: 1

Or: GTK: 7 (most still using GTK3) Qt: 9 Other: 11

DE dependend: Files, Settings, Terminal

Most important (kind of โ€œbusiness hubโ€, where linked and integrated data is most important): Evolution

Very important as well: Printing. But I don't really know of any good PDF viewer and/or printing dialog on Linux. They all have their own issues. The software set Linux Mint provides is ok.

In the end I currently tend to choose UI Toolkit and Desktop Environment depending on the PIM suite. That of KDE (Akonadi) is awful. So I'm going for an Evolution based one. Document Scanner is important as well. Mint/Cinnamon works best, Pantheon I like more. Ubuntu Touch uses the same backend as well, which is very interesting, but only Calendar looks nice for now (missing/not functional: Contacts, Tasks, Mail).

Our media workstation for video streaming and projection uses Kubuntu and KDE.

Changed the site structure: Gave it more subpages.

Updated information. โ€œNow pageโ€ will be updated as I go.

You are a former Mac user and want to get the most perfect Linux distribution out there?

  1. Install Ubuntu MATE.

=> https://ubuntu-mate.org/

  1. Use MATE Tweaks tool to switch desktop layout to โ€œCupertinoโ€ (yes, that's the codeword for a Mac like desktop layout providing a global menu bar).

  2. You may get a little bit annoyed by the full size Brisk menu. If you want it smaller change its dconf value to 'classic'.

=> https://ubuntu-mate.community/t/changing-brisk-menu-to-full-screen-on-contemporary-layout/17972 Ubuntu MATE Community: How to change the configuration of Brisk menu.

  1. When you are changing your display setup often (f.e. when using a laptop), you may get annoyed by the Plank dock floating around. Apply this patch:

=> https://discourse.ubuntubudgie.org/t/fix-plank-location-when-changing-resolution/5198

  1. Choose a color setup of your taste (I like it rather blue than green).

Enjoy!

Update from 2024-10-05: While Ubuntu MATE is a very decent distribution it falls behind as it is not adapting to GTK4 and Wayland. I'm also missing the GNOME Online Accounts feature very much. That is provided by Linux Mint (LMDE). If you're looking for GTK4 and Wayland consider elementary OS. If you want Online Accounts, GTK4 and Wayland you need to bother with GNOME (I don't like to though).

How to write a Free and Open Source (FLOSS) application, that works cross platform โ€“ at least on some (mobile) platforms?

2nd take, the poor man's approach

In a first attempt of writing this gemlog post I tried to put in place and utilize the business-solid Java ecosystem. But when trying it out I recognized that it is not sane at all. At least to me. Its heavy resource usage, complexity and, uhm, heaviness, make it too hard to handle for me. The process eats the joy of development instead of spreading it as soon as you start one of the common Java IDEs (knowing that JetBrain's IDE is one of the better examples).

=> 2023-09-02-Sane-app-architecture-the-Java-way.gmi

Now I'm writing this blogpost using Sublime Text again and put in place a collaboration of solutions I consider sane because it fits to my resources available and hopefully to the possibilities of people using a solution I built upon this plan.

It's built upon the foundation of the C language, its Free and Open Source compilers, the GObject/GLib ecosystem and easy to handle wrappers around it like Objective-C (leveraging ObjFW) and PHP.

As a foundational layer for structuring data I'd try to utilize Midgard accessed through an Objective-C wrapper for ObjFW.

That said, the approach below is heavily based upon upcycling old, mostly abondoned, but slim and slick software.

=> /tech/app_development.gmi See notes about app development regarding Midgard

Apps should be beautiful and at least behave native. You have to make compromises on cross platform solutions, but native GUI kits are important. (Qt is ugly.)

App development using local data storage

  โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
  โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ               โ•‘
  โ•‘ โ”‚   Database:         โ”‚      ___      โ•‘
  โ•‘ โ”‚       SQLite        โ”‚     /\  \     โ•‘
  โ•‘ โ”‚                     โ”‚    /::\  \    โ•‘
  โ•‘ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ   /::\:\__\   โ•‘
  โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ   \/\::/  /   โ•‘
  โ•‘ โ”‚      libgda         โ”‚     /:/  /    โ•‘
  โ•‘ โ”‚โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”‚     \/__/     โ•‘
  โ•‘ โ”‚                     โ”‚      ___      โ•‘
  โ•‘ โ”‚      Midgard2       โ”‚     /\  \     โ•‘
  โ•‘ โ”‚                     โ”‚    /::\  \    โ•‘
  โ•‘ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚   /::\:\__\   โ•‘
  โ•‘ โ”‚ โ”โ•บโ•บโ•บโ•บโ•บโ•บโ•บโ•บโ•บโ”“         โ”‚   \/\::/  /   โ•‘
  โ•‘ โ”‚ โ•Midgard  โ• ObjC/   โ”‚      \/__/    โ•‘
  โ•‘ โ”‚ โ•based    โ• ObjFW   โ”‚               โ•‘
  โ•‘ โ”‚ โ•Models   โ• wrapper โ”‚      ___      โ•‘
  โ•‘ โ”‚ โ”—โ•บโ•บโ•บโ•บโ•บโ•บโ•บโ•บโ•บโ”›         โ”‚     /\  \     โ•‘
  โ•‘ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚    /::\  \    โ•‘
  โ•‘ โ”‚ UI:     โ”‚           โ”‚   /::\:\__\   โ•‘
  โ•‘ โ”‚    GTK  โ”‚  UIKit    โ”‚   \/\::/  /   โ•‘
  โ•‘ โ”‚         โ”‚           โ”‚      \/__/    โ•‘
  โ•‘ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ               โ•‘
  โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

What needs to be done to achieve this type of app?

  1. Finish the Objective-C bindings for GTK(4) and the GObject ecosystem

=> https://codeberg.org/ObjGTK/ObjGTKGen ObjGTKGen: Generates GObject/GTK bindings for ObjFW

  1. Update Midgard and libgda to work with current dependencies

As Midgard depends on libgda both need to be updated to work with current databases. This concerns sqlite3 and PostgreSQL since libgda 5 only supported PostgreSQL up to version 11 but needs to work with version 15.

Well, that's it. From this I should make a working app using a solid foundation. Let's see what I come up with.

Sane app architecture

Further elaborting:

Running an app directly connected to a networked database solution like PostgreSQL or only using SQLite is no permanent solution for deployments that address more than only personal use cases of course. I'm thinking of organizational use cases which depend on a single common data source and service providing it.

So make let's make the approach above a more grown architecture by putting in place PostgreSQL and some well established PHP solutions:

 โ”Œโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”
 โ•Ž    โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                     +-+         โ•Ž
 โ•Ž    โ”‚Database:         โ”‚                                     |S|         โ•Ž
 โ•Ž    โ”‚    PostgreSQL    โ”‚                                     +-+         โ•Ž
 โ•Ž    โ”‚                  โ”‚                                     +-+         โ•Ž
 โ•Ž    โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                     |e|         โ•Ž
 โ•Ž  โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—        +-+         โ•Ž
 โ•Ž  โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ•ฎ                         โ•‘        +-+         โ•Ž
 โ•Ž  โ•‘ โ”‚      Midgard     โ”‚  โ•Žโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”                โ•‘        |r|         โ•Ž
 โ•Ž  โ•‘ โ”‚      PHPCR       โ”‚  โ•Ž   S    โ•Ž    PHP         โ•‘        +-+         โ•Ž
 โ•Ž  โ•‘ โ””โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”˜  โ•Ž   y    โ•Ž                โ•‘        +-+         โ•Ž
 โ•Ž  โ•‘  โ”‚Doctrine/CR ODM โ”‚   โ•Ž   m    โ•Ž    FastCGI     โ•‘        |v|         โ•Ž
 โ•Ž  โ•‘ โ•ญโ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ•ฎ  โ•Ž   f    โ•Ž                โ•‘        +-+         โ•Ž
 โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   o    โ•Ž    Nginx/      โ•‘        +-+         โ•Ž
 โ•Ž  โ•‘ โ”‚   FOSRestBundle  โ”‚  โ•Ž   n    โ•Ž    Apache      โ•‘        |e|         โ•Ž
 โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   y    โ•Ž                โ•‘        +-+         โ•Ž
 โ•Ž  โ•‘ โ•ฐโ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”˜                โ•‘        +-+         โ•Ž
 โ•Ž  โ•šโ•โ•โ•โ•โ•โ”‚  โ•โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•        |r|         โ•Ž
 โ•Ž        โ”‚ HTTPSโ”‚                                             +-+         โ•Ž
 โ””โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”‚โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”‚โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”˜
          โ”‚      โ”‚
      GET โ”‚      โ”‚ PUT / UPDATE / DELETE
          โ”‚      โ”‚
  โ”Œโ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”          C
  โ”‚  โ”‚ Mantle/ โ”‚ Local   โ”‚   โ”‚
  โ”‚  โ”‚ RestKit โ”‚ Midgard โ”‚   โ”‚          L
  โ”‚  โ”‚         โ”‚ Cache   โ”‚   โ”‚
  โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚          I
  โ”‚  โ”‚                   โ”‚   โ”‚
  โ”‚  โ”‚   Midgard based   โ”‚   โ”‚          E
  โ”‚  โ”‚                   โ”‚   โ”‚
  โ”‚  โ”‚      Models       โ”‚   โ”‚          N
  โ”‚  โ”‚                   โ”‚   โ”‚
  โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚          T
  โ”‚  โ”‚ GUI:    โ”‚         โ”‚   โ”‚
  โ”‚  โ”‚  GTK    โ”‚  UIKit  โ”‚   โ”‚
  โ”‚  โ”‚         โ”‚         โ”‚   โ”‚          A
  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
  โ”‚   Mobile App (ObjFW)     โ”‚          P
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        P

                                        S

=> http://midgard-project.org/midgard2/ Midgard2 => http://midgard-project.org/phpcr/ Midgard2 PHPCR => https://symfony.com/ Symfony framework => https://www.doctrine-project.org/projects/orm.html Doctrine ORM => https://www.doctrine-project.org/projects/phpcr-odm.html Doctrine PHPCR ODM => https://github.com/FriendsOfSymfony/FOSRestBundle GitHub โ€“ FOSRestBundle

What needs to be done to achieve the further elaborated architecture?

  1. Wait for ObjFW to have KVO/OFCoding support

=> https://objfw.nil.im/tktview/a7760ac9cb ObjFW: Ticket: OFCoding support (FR) => https://objfw.nil.im/tktview/d4627ee499 ObjFW: Ticket: KVO support (FR)

  1. Port Mantle or RestKit to ObjFW. Currently I don't know yet which ones suites better. I consider it important to still have Midgard to cache data locally since you don't want to depend on the REST service (aka โ€œthe cloudโ€).

=> https://github.com/Mantle/Mantle GitHub: Mantle => https://github.com/RestKit/RestKit GitHub: RestKit (this one was not mainted 3 years longer)

  1. Add a plugin to either Midgard or Doctrine to generate fitting Objective-C and PHP models (for Mantle/RestKit)

Todo list for first preparations

Making Glom work again could be useful for quick database prototyping (only for PostgreSQL though).

If I update libgda to work with PostgreSQL 15, Glom may work out of the box (maybe). Glom then generally could be used to test libgda's capabilities.

=> https://gitlab.gnome.org/Archive/glom/-/issues/9

The next step could be to add the generation of Midgard description files out of the database schema (โ€œreverse engineeringโ€) to Glom.

Disclaimer: I restored this post after having deleted it. Probably not going to make anything work this way, but it is a nice study I think.

So let's start. Lots could be said. Let it keep short: I don't like web apps. The web is meant to transfer information. Browser are meant do display information, not ads nor apps.

Apps should be beautiful and at least behave native. You have to make compromises on cross platform solutions, but native GUI kits are important. (Qt is ugly.)

While I like to code, I have got few time, I'm lazy and I don't like to write boilerplate code.

The heart of every application are data structures. Programming languages are secondary. They just need to be easy, fun and understandable to work with (ok, quite some requirements, I admit).

So I begin with designing database structures and generating code templates from there.

From the great time of Apple's WebObjects there is a free port (or reimplementation) of the good old Enterprise Objects Frameworks (EOF), which is Apache Cayenne. While it is Java as well (just like the posterior WebObjects), it's maintained up to today (praise to Andrus Adamchik) and integrates into modern Java web apps without being as bloated as Spring et. al.

Fast prototyping

Using Apache Cayenne and it's great CayenneModeler one should be able to quickly prototype a simple desktop app quite well.

This could look like this:

                     โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
                     โ”‚Database:         โ”‚
                     โ”‚    PostgreSQL    โ”‚
                     โ”‚                  โ”‚
                     โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
                   โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
                   โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”                            โ•‘
                   โ•‘ โ”‚                  โ”‚                SWT         โ•‘
           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  Apache Cayenne  โ”‚                            โ•‘
           โ”‚       โ•‘ โ”‚                  โ”‚                Java App    โ•‘
Code       โ”‚       โ•‘ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                            โ•‘
generation โ”‚       โ•‘                     M  V  V  M                  โ•‘
           โ”‚       โ•‘ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ•‘
           โ”‚       โ•‘ โ”‚                  โ”‚     โ”‚                  โ”‚   โ•‘
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ  Models          โ”‚     โ”‚ GUI: SWT / JFace โ”‚   โ•‘
                   โ•‘ โ”‚                  โ”‚     โ”‚                  โ”‚   โ•‘
                   โ•‘ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘
                   โ•‘                                                 โ•‘
                   โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

GUI modeling for SWT is done using Eclipse WindowBuilder.

=> https://dbeaver.io/ DBeaver โ€“ Manage any SQL database (PostgreSQL in this case) => https://cayenne.apache.org/ Apache Cayenne => https://cayenne.apache.org/docs/4.2/getting-started-guide/ Apache Cayenne: Getting started guide. See how to use Cayenne Modeler to model data structures (you may you use DBeaver and the database first approach as well) => https://www.adamchik.org/ Personal website of Andrus Adamchik => https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel Wikipedia: The Modelโ€“viewโ€“viewmodel pattern => https://github.com/renber/jface_mvvm GitHub: Implementation of the MVVM pattern for JFace => https://eclipse.dev/windowbuilder/ Eclipse WindowBuilder

Sane app design

For prototyping you maybe could even use SQLite instead of PostgreSQL. But chances are high you need to change lots of the database layout for later migration.

Running an app directly connected to a networked database solution like PostgreSQL is no solution for more than personal use deployments of course.

Also you won't be able to run a Java SWT app on many devices nowadays. The biggest market share is mobile. So we need to design an interface for mobile apps. While Cayenne supported Remote Object Persistence (ROP) via Hessian protocol until version 4.2 it is deprecated by that version. And of course you would use a RESTful API for this purpose these days.

Adopting more solutions you get something like this:

         โ”Œโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”
         โ•Ž    โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                     +-+         โ•Ž
         โ•Ž    โ”‚Database:         โ”‚                                     |S|         โ•Ž
         โ•Ž    โ”‚    PostgreSQL    โ”‚                                     +-+         โ•Ž
         โ•Ž    โ”‚                  โ”‚                                     +-+         โ•Ž
         โ•Ž    โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                     |e|         โ•Ž
         โ•Ž  โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—        +-+         โ•Ž
         โ•Ž  โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”                โ•‘        +-+         โ•Ž
         โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   B    โ•Ž    Java App    โ•‘        |r|         โ•Ž
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  Apache Cayenne  โ”‚  โ•Ž   o    โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   o    โ•Ž    Container   โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ•ฐโ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ•ฏ  โ•Ž   t    โ•Ž                โ•‘        |v|         โ•Ž
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ–บ     Models     โ”‚   โ”‚   i    โ”‚                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ•ญโ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ•ฎ  โ•Ž   q    โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   u    โ•Ž                โ•‘        |e|         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚    Agrest.io     โ”‚  โ•Ž   e    โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž        โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ•ฐโ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”˜                โ•‘        |r|         โ•Ž
โ”‚        โ•Ž  โ•šโ•โ•โ•โ•โ•โ• โ”‚โ•โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•        +-+         โ•Ž
โ”‚        โ•Ž          HTTPSโ”‚                                                         โ•Ž
โ”‚        โ””โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถ โ”‚โ•ถโ•ถโ•ถโ•ถโ”‚โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถ โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”˜
โ”‚                   โ”‚    โ”‚        PUT / UPDATE / DELETE
โ”‚Code               โ”‚    โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚generation         โ”‚    โ”‚        GET                               โ”‚
โ”‚                   โ—„โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚              C
โ”‚                   โ”‚    โ”‚                                    โ”‚     โ”‚
โ”‚        โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”               โ”Œโ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”   L
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚               โ”‚  โ”‚                  โ”‚   โ”‚
โ”‚        โ”‚   โ”‚ JAX-RS / Jersey โ”‚     โ”‚               โ”‚  โ”‚ Mantle/RestKit?  โ”‚   โ”‚   I
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚               โ”‚  โ”‚                  โ”‚   โ”‚
โ”‚        โ”‚   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค     โ”‚               โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚   E
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚               โ”‚  โ”‚                  โ”‚   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ–บ  Models         โ”‚  M  โ”‚          โ”Œโ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–บ  Models          โ”‚ M โ”‚   N
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚          โ”‚    โ”‚  โ”‚                  โ”‚   โ”‚
โ”‚        โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  V  โ”‚          โ”‚    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ V โ”‚   T
โ”‚        โ”‚                           โ”‚          โ”‚    โ”‚                         โ”‚
โ”‚        โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  V  โ”‚          โ”‚    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  V โ”‚
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚          โ”‚    โ”‚  โ”‚ GUI:   โ”‚        โ”‚    โ”‚   A
โ”‚        โ”‚   โ”‚GUI: SWT / JFace โ”‚  M  โ”‚          โ”‚    โ”‚  โ”‚  GTK   โ”‚  UIKit โ”‚  M โ”‚
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚          โ”‚    โ”‚  โ”‚        โ”‚        โ”‚    โ”‚   P
โ”‚        โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚          โ”‚    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚        โ”‚  SWT Java Desktop App     โ”‚          โ”‚    โ”‚   Mobile App (ObjFW)    โ”‚   P
โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚                                               โ”‚                                  S
โ”‚                                               โ”‚
โ”‚                                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
   Code generation by ObjC plugin

=> https://bootique.io/ Bootique.io โ€“ Framework for runnable Java apps => https://agrest.io/ Agrest.io (Framework for REST data services) => https://eclipse-ee4j.github.io/jersey/ Eclipse Jersey (JAX-RS implementation, client and server) => https://objfw.nil.im/ ObjFW: Lightweight, portable Objective-C framework

What needs to be done to achieve this?

  1. Finish the Objective-C bindings for GTK(4)

=> https://codeberg.org/ObjGTK/ObjGTKGen ObjGTKGen: Generates GObject/GTK bindings for ObjFW

  1. Wait for ObjFW to have KVO/OFCoding support

=> https://objfw.nil.im/tktview/a7760ac9cb ObjFW: Ticket: OFCoding support (FR) => https://objfw.nil.im/tktview/d4627ee499 ObjFW: Ticket: KVO support (FR)

  1. Port Mantle or RestKit to ObjFW. Currently I don't know yet which ones suites better. I consider it important to bring up a good solution to cache data locally since you don't want to depend on the REST service (aka โ€œthe cloudโ€).

=> https://github.com/Mantle/Mantle GitHub: Mantle => https://github.com/RestKit/RestKit GitHub: RestKit (this one was not mainted 3 years longer)

  1. Add a plugin to Apache Cayenne to generate fitting Objective-C models (for Mantle/RestKit)

Problems

Java IDEs like Eclipse are anything but light on resources and do not work on my old ThinkPad running on 8GB of RAM. Still Apache Cayenne provides abilities that would cost > 495โ‚ฌ if you take PHP, Doctrine ORM and Skipper18 under consideration.

It also seems SWT is maintained badly by the Eclipse community. I did not manage to make up an Eclipse configuration to build a SWT app after 4 hours of work.

Update from November 2024: Seems they updated their docs. Managed to get SWT up and running within some minutes. Just had to follow the docs.

=> https://www.eclipse.org/swt/eclipse.php

Linux on a iMac 5,1

This is a machine having an Intel Core (2) Duo 64 bit processor (I think it's Core Duo without the โ€œ2โ€), but does only have a 32 bit EFI. So you can't use a regular boot loaders and install media to install and boot from this machine.

In addition there is the problem that, if you manage to accomplish a (32 bit) EFI install, it breaks the AMD GPU drivers. The Linux kernel will only run properly when using nomodeset which leads to further problems (missing accleration, energy/heat management, quicker hardware breakage).

So, you need a legacy BIOS/MBR bootloader, install the OS the same way (most installers will do that if you have booted the install medium that way) and it's going to work! You may even use a 64 bit OS then.

This page contains everything you need to know about installing Linux on such a machine:

=> https://github.com/jmstriegel/linux_2006_imac_5.1 Linux 2006 iMac 5.1, Markdown page on GitHub

This page contains a tutorial and software to create boot media having cut of the 64 bit EFI bootloader so the machine is going to use the MBR boot way:

=> https://mattgadient.com/linux-dvd-images-and-how-to-for-32-bit-efi-macs-late-2006-models/ Matt Gadient: Linux DVD images (and how-to) for 32-bit EFI Macs (late 2006 models)

โ€ฆ and own hardware.

After first having started this Gemini capsule on SDFeu, I now moved it to my own home cellar server running Yunohost.

In between I thought about moving my Gemini capsule to uberspace, but I then recognized that won't work since uberspace allows the operation of own services, but only on unprivileged ports. That's no problems for web services since they provide a reverse proxy, but won't work using Gemini.

So I decided to use my own hardware, based on IPv6 routing only (no IPv4 here).

Yunohost provides two nice apps to accomplish this quite quickly:

=> https://yunohost.org/en/app_gemserv Gemserv, which is the server software, written in Rust => https://yunohost.org/en/app_my_capsule my_capsule, which is the template for a Gemini capsule, also providing a PHP translation to HTML

The latter needed to have applied some patches I submitted over here including a bugfix:

=> https://tildegit.org/sbgodin/HtmGem/pulls Pull requests at HtmGem repo at tildegit

Those were merged as of writing this, so I hope Yunohost will ship an updated app quite soon.

Der vor kurzem verstorbene Abenteurer und Weltumsegler Wilfried Erdmann hat kurz vor seinem Ableben noch ein Buch verรถffentlicht: รœber seine Schwiegermutter Ingeborg von Heister, die erste deutsche Seglerin, die allein den Atlantik รผberquerte und โ€“ so erfรคhrt man(n) nebenbei โ€“ nach ihrer Scheidung noch erfolgreiche Geschรคftsfrau und alleinerziehende Mutter war.

In groรŸen Teilen des Buches lรคsst Erdmann seine Schwiegermutter durch ihre Logbucheintrรคge, die eher Tagebucheintrรคge sind, selbst sprechen. Zum Glรผck. Denn auรŸer ein paar seglerischen Kommentaren hat er wenig zu der Darstellung beizutragen. Auch, dass er selbst ohne diese Frau vielleicht nie zum Segeln gekommen wรคre, wird nur wenig gelobt. Ebenso weiรŸ der Autor auch ihre tiefen, emotionalen Introspektionen und auch die durch das Segeln erlangte Emanzipation nur wenig wertzuschรคtzen. Vielleicht hat er sie gar nicht wahrgenommen.

Ingeborg von Heister spricht fรผr sich selbst. Das Boot heiรŸt nicht ohne Grund โ€œUltima Ratioโ€.

Hรคtte jemand ihr frรผh genug genug Mut gemacht, wรคren vermutlich mehr als ein phantastisches Buch entstanden. So ist es die Erinnerung an eine beeindruckende Frau, die selbstzweifelnd scheinbar mit sich selbst, in Wirklchkeit aber vermutlich viel mehr mit den Widrigkeiten und dem Frauenbild ihrer Zeit kรคmpft. Das lรคsst sich in dem kleinen Buch wirklich schรถn nachlesen.