fig. 1: Applescript variant

Published: 2021-09-13 | Last edited: 2023-08-23

The first version

In august of 2020, I posted a preset to the BetterTouchTool forums, along with the following description:

TL;DR: I got tired of waiting while macOS "force quits" frozen applications, so I made my own Force Quit dialog that kills the app instantly.

It's almost admirable how macOS does everything in its power to ensure every app is gracefully quit.

"Give the app a chance to explain itself", the system says, "just a minute to work things out!"

"How would you feel if I turned YOU off all of a sudden?", it asks judgingly.

The thing is, Apple, that you already had a command for that kind of stuff. A command called Quit. This is Force Quit and it has a purpose. If I tell you to do that, it means I don't give a flying flubber about how the app feels about being shut down. You make those memory addresses available, and you do it now!

This preset is for those who fondly remembers the swiftness of Mac OS back in the 80's/early 90's. It might not have been very stable, but when you pressed Cmd-Opt-Esc it shut the frigging application down (or at least froze up entirely, screeching loudly until you pulled the plug. Point is, it tried!). Today you can enter "kill -9 PID" in a terminal to achieve the same result, and that is what this script does for you.

It comes assigned to the keyboard shortcut Cmd-Opt-ยง, but that can of course be changed to anything you like.

There is a caveat (apart from the risk of upsetting your apps/system), and it is that the misbehaving app needs to be in focus for this to work. There is no list of open apps to choose from, so if you can't get it focused you're on your own..

Tested only in macOS Mojave, not sure how Catalina/Big Sur would feel about it. Please let me know if you try it out!

fig. 2: cocoaDialog variant

The cursed version

Shortly after my first "release", I actually did make a version of this preset that offered the user an option to choose from a list of running apps to quit. I wasn't entirely happy with it though, and couldn't in good conscience release it to the (surely anxiously awaiting) world.

Not only did it rely on a precompiled binary (cocoaDialog) to display the custom alert, a fact which in and by itself made trying to navigate the various security obstacles in macOS a feverish dream verging on kafkaesque in nature...

The nail in the coffin for this ill-fated version was the fact that the last update of said binary first saw the light of day at a time when pope Benedict XVI was still waving and smiling from his balcony. A time when Carly Rae Jepsen's Call Me Maybe was everybody's hot new guilty pleasure. A time when... Well, you get it, it's old. Basically abandonware. Although it still works in Big Sur for this specific purpose, I knew it was only a matter of time.

Disheartened, I put my dreams to rest. My magnum opus - this wonderful tool that properly implemented could have helped dozens of people save literally seconds each month - was nothing but a wild goose chase. A fool's errand. Sure, I would still use the tool in private whenever the need arose, but never without a bitter aftertaste of failure.

The project had died, and my hopes along with it.

fig. 3: Swift variant

The blursed version

Fast-forward to september of 2021, and no resurrection attempts had been made. But then a week ago, I read somewhere that the swift binary that comes with the XCode Command Line Tools could be used as an interpreter to run Swift scripts on the fly.

That got me thinking about this old thing again. I had no interest in WYSIWYG-ing my way to a fully fledged app in XCode (nor learning how to, right now), but perhaps producing a native Cocoa dialog box with a couple of options could be done with a few lines of code in a script? That could make for a fun evening or weekend project!

Knowing very little about how macOS security actually works, and absolutely nothing about Swift/Cocoa programming, I somehow reached the conclusion that if I could just squeeze everything into a single script, written in Apple's own language, directly interpreted by their own tool, macOS would simply have no choice but to obey me unconditionally.

I figured macOS couldn't with a straight face then suddenly decide not to run my code for the usual, arbitrary reasons like "I've got a funny feeling about it" or "It just smelled a bit off, you know?".

And so - happy with this bullet-proof piece of hot logic - I decided to have a go at learning me some Swift.

I won't describe this journey in excessive detail. I assure you, there'd be no educational or even entertainment value to gain from that. I just want you to understand a thing or two about why the final product turned out the way it did.

Now, don't get me wrong, I'm very proud of my little box. It does exactly what I set out for it to do, using no external tools other than macOS built-in's. So what more could one ask?

First of all, the script could have been written purely in Swift and not be a hodgepodge of osascript, ps, kill, lsof, cut and grep wrapped in 700 lines of Swift spaghetti. But since that would have made it an actual app - which again, wasn't my goal - I'm not beating myself up over it.

Secondly - and more importantly - I could really do without the uncanny resemblance to a generic, low-effort WinAmp skin from 2002. Not that I think it looks particularly bad, I mean, I did choose the colors myself. It's got more to do with the reasons why I went with this "ascii art" kind of UI, rather than using the actual Cocoa bits and parts at my disposal...

On second thought, I shan't go into any detail at all. I just tried to retrace my steps leading up to whatever is shown in fig. 3, but all I got was a headache and a strong urge to flee civilisation and live off the land.

I'm still posting this though. Partly because I actually do find the script useful myself, partly as a warning for other opportunistic adventurers aspiring to learn this language exclusively from lazy googling and copy-paste. But also on the off chance this could help some poor coder out there who took a few days off and now need to learn this week's basic Swift syntax from scratch.

GitLab project page

<< Back to projects