Cross-Platform Development with LiveCode

Posted  

Recently I’ve read this post about the sad state of cross platform GUI frameworks and was quite impressed by how much I agree with it and how much I think we should focus more on desktop apps instead of SaaS and mobile stuff. This post is not an attempt to contradict the post mentioned above but another datapoint for those wanting to learn more about cross-platform development tools. In it I’ll talk about a real world application I’ve built for my own personal use to help me blog more.

What are my needs anyway?

I really enjoy blogging and wish to do more of it, but I regret the amount of friction I’ve pilled upon myself by using a static site generator instead of something with a proper interface. Using an SSG allows my own small VPS to survive large inbound traffic spikes on the rare occasions that a post I made gets popular, all I need is a better workflow for posting. I could use one of the hip SaaS that behave like a CMS for SSG, but I’m trying to remove my reliance on both online tools and services outside my control. I want to get back to the desktop, and I don’t want to use electron.

My workflow is not the same as many bloggers using SSG. I don’t rely on some version control pipeline to generate my site using CI/CD stuff. I generate the site using scripts on the local machine and upload the resulting HTML files to the server using good old rsync. My site still versioned using git though, mostly as a convenience, because I have multiple machines and I want the site to be present in all of them so that I can post from any of my devices. I need this application I’m building to work on:

MachineOSArchSurface GoWindows 10x86_64Surface Pro XWindows 10aarch64MacbookmacOS Craptalinax86_64Thinkpad x230KDE Neonx86_64

I’m no stranger to blogging apps

The first application I’ve built and released on the wild was actually a blogging client for Mac OS classic. It was called iBlog, it was built with REALBasic and was a client for Blogger API enabled sites allowing the user to create new posts and edit past ones. It was built in a time where we didn’t always had an internet connection available so it was good to be able to write posts offline and push them once a connection was available.

my iBlog is not the same as lifli iBlog which was bundled with macs at a later date. I used that name before they did, years before they did, but since I was a teenager in Brazil and they were a company in the U.S., I ended up without a way to keep that name. I ended up reimplementing the app and releasing it with a different name later.

7th public beta of iBlog running on MacOS 9.

I really like the artwork it used for the splash screen:

iBlog splash screen.

Later, I reimplemented the most features in a new application I called Blogworks using Objective-C and Cocoa as I learned how to develop stuff for the then new MacOS X. I don’t remember if I ever added support for Apple Script an other clever stuff I had in iBlog.

Beta of Blogworks running in a very old MacOS X.

It also had a really nice splash screen:

Applications always look better with splash screens.

So, when I decided to build an application to help me post to my blog, I basically decided to recreate iBlog/Blogworks.

LiveCode to the rescue

LiveCode has many versions available.

There are commercial versions at LiveCode.com with different features. I’m running LiveCode Indy these days. They have a nice stay-at-home offer going on for those that want to learn programming while in quarantine, it is LiveCode Indy for a pay-what-you-want deal.

If you’d rather program using the GPL, you can fetch the free GPL version at LiveCode.org. It doesn’t contain many of the goodies present in the proprietary versions but for what I’m building here it would work just the same.

LiveCode is a cross-platform language and environment that allows the creation and deployment of applications for macOS, Windows, Linux, Android and iOS. It runs on all the previously listed desktops and cross-compiles between all of the above except that for compiling to iOS you need to be on a Mac.

In a previous post I’ve described LiveCode as a a modern-day HyperCard. It works basically the same as HyperCard but with current age features. I’ve been programming with it for close to 20 years and feel quite at home in its environment regardless of the operating system I’m using (even though it works better with a Mac).

I toyed with the idea of rebuilding Blogworks with Racket since my site is actually built with it, but I don’t know enough Racket and Racket/Gui to build a full application. Electron was the obvious choice when I spoke with my friends about it, but I dislike Electron and think it is a waste of resources for many use cases. LiveCode is the obvious choice for me. I know it well and it is able to deploy to all the platforms I listed in the previous section with the exception of aarch64 but since Windows 10 on ARM can actually run Windows applications compiled for x86_32 with a built-in emulation layer, all I need is to compile for 32bits for Windows and have it running on all my Surface devices.

Rebuilding Blogworks

The minimalist interface I used before still good enough for my own personal use. All I want is three fields–title, tags, content–and a post button. More advanced features will come later.

If you’re used to LiveCode you might noticed that my IDE is looking odd. Where are the menus and tools palette? I’m a user of the Devolution toolkit plugin for LiveCode. With it I can hide the all those UI elements to save screen realstate and much more.

Blogworks stack open inside LiveCode indy editing the post you’re reading.

Instead of building the full app. I’m doing it the LiveCode (or HyperCard, or Smalltalk) way, which is through iterative development and refinement of the application while it is in actual use. I’m writing this post at the same time I’m rebuilding Blogworks. For example, at the moment I’m writing this paragraph, the Post button does nothing. I’ll implement it once it is time to actually deploy the blog post.

I’ll release it once it matures into something that is usable beyond my own personal blog. At the moment there is a lot in it that is hard coded to my own environment. I want to build something that works for me first and use it for a while before tweaking it to be more generic and usable by others.

The stacks

The new Blogworks (from now onwards, just Blogworks) uses two stacks. LiveCode stacks can be thought of as windows. They can contain cards, which are analogous to views. It is better to think of them as either a deck of cards or a rolodex, where you can add as many cards as you want and switch between them as you see fit. Each card can contain its own controls.

My site is built with a fork of frog which is a SSG for Racket. I have two templates in Blogworks for it, one for Markdown content and another for Scribble, which is the Racket documentation language I used for this post.

One stack is the blogworks poster and is the main UI used to post to the blog. On the top of it there are menu buttons disguised as text labels that allow me to select which site I’m posting to and which template I’m using. On the screenshot above, the site is set to my blog and the template is called scribble.

From that interface, I’m able to preview or post. I haven’t implemented editing old posts yet. Both actions work basically the same as my SSG makes almost no distinction between previewing or deploying. The post content, title and tags are interpolated in the selected template and saved to a file. A shell command is used to render the site.

The other stack is called preferences but what it actually holds is information about each site. It is more like an blog accounts stack and that one is the clever one. If I was building this application using some different language, I’d probably use JSON or a SQLite file to hold this information but for the sake of simplicity, I decided to simply use a LiveCode stack in this case. See, LiveCode stacks can be altered and saved at runtime, this means that just like a rolodex, I can create a stack that is a form, make the controls in that form into a background group, which means that they are placed into all the cards, and just use it as a database. Below is a screenshot of it with the templates tab selected:

The preferences stack holds its data by altering itself.

And with the general configuration tab selected:

So much better than editing JSON.

So when Blogworks start, it looks for a file called blogworks.preferences, which is actually just a LiveCode stack, in a known location in the machine. It loads it and opens its own stack with the UI and data from the preferences.

Since there is no code-compile-debug cycle with LiveCode, I can build this as I write this post switching between interaction tool to write the post and browse tool (which puts the stack into edit mode) to alter stuff. It is a very pleasant way of working. I now have it working well enough to do this post but before it I must compile it and run it on the machines I mentioned above.

Running on different machines

As I mentioned before, cross-compiling with LiveCode is dead easy. You just go to the Standalone Application Settings for your stack and configure each platform:

Showing the settings for building for Windows.

Each platform with a green checkbox, is a platform were building for. Once I select Save as Standalone Application, the stack is compiled for each platform and you end up with a folder contained all the versions of the application.

Running on Windows

I developed this application using my Surface Go. This is the standalone version running:

Blogworks on Surface Go, notice the icon.

The application compiled for x86_32 is 15.4mb and when running it consumes very little CPU and memory, usually around 2% to 5% when doing complex stuff for some seconds and about 20mb to 30mb of RAM. Much better than Electron.

It consumes very little.

Since it was built for x86_32, it also runs on the Surface Pro X:

32bits app running on aarch64.

Running on a Mac

In my opinion, macOS is where LiveCode runs best. The IDE is much faster and snappier on that platform, mostly because there aren’t many Windows and Linux users submitting bugs and helping the GPL version out. I should do more of that...

Of course it works well on a Mac.

Running on Linux

This actually gave me some trouble. Basically there were missing shared libraries and the application wouldn’t start. Then I realized I compiled for 32bits and what I was missing was the 32bits versions of things such as libexpat and so on. A quick recompile to 64bits solved everything and it run well:

I don’t remember how to set the icon on Linux...

Conclusion & Next Steps

LiveCode can also compile for iOS and Android, so I could have this working on mobile as well but since my SSG doesn’t run on Android or iOS, I decided not to put any time into it

I’ve timed myself. It took me seven hours to create this app, the blog post, and have lunch. Most of the time was actually spent writing the blog post and fishing for old screenshots from 18 years ago. LiveCode is a wonderful tool for creating cross-platform desktop applications.

I’m building a simple UI to start experimenting with a desktop blogging client again. I want it to run in all platforms and to mature into something I can share with others. The next steps will be implementing support for MetaWeblog API, WP Rest and Micropub. With those in place I’ll cover a large part of the blogging community.

As for the source code, I’m still thinking about what is the best way forward. I want to have it available but I am also thinking about going commercial with the application. My plan is to release it as a paid app and when you buy, you also get the source code. I’m a freelancer eager to work on my own projects and content but I live in a very expensive city. It is not clear to me what is the best way forward. Still, the current source code contains lots of hard-coded paths and commands that are unique to my site as I wanted to make it work for me first, so it is not as useful to others as it is, but as the current week moves along, I should clean it up and find out how to release this.

Dear reader, if you know a way to release something as open source and still charge for it, please reply to me on Twitter or Mastodon. I know I can simply slap the GPL into it and still sell the binaries, I just don’t know if that is the best way (but it is what I’m tempted to do). Another potential way is just releasing everything as FOSS and make an Open Collective or Patreon but I wonder if it would be cost-effective when compared with some other solution.

Did you enjoyed reading this content? Want to support me?

You can buy me a coffee at ko-fi.

Comments? Questions? Feedback?

You can reach out to me on Twitter, or Mastodon, Secure Scuttlebutt, or through WebMentions.

Mentions