A silver MacBook Air seen from behind, its lid open, on a white table that reflects it
Open-source

mintosh — macOS Tahoe's look on a 2013 MacBook Air that Apple stopped updating

9 min read Isaac Rowntree

Zack Design has published mintosh, a set of scripts that makes Linux Mint look and work like the latest macOS. It’s meant for old Macs that Apple no longer updates, and it covers the whole move: back up the Mac, sort the files, install Mint, then run three scripts for the system, the look and the keyboard.

It was built for one person: the owner of a 2013 MacBook Air with 4 GB of memory, whose last macOS was Big Sur, and who shouldn’t have to learn anything new to keep using it. So the bar wasn’t “Linux that looks a bit like a Mac”. It was: the Apple menu is where it was, ⌘C and ⌘Tab do what they did, Spotlight is on ⌘Space, and every file is where it was left.

This post covers:

  • what a theme gives you, and the much bigger part it doesn’t;
  • why, on 4 GB, nothing gets to run in the background;
  • Mission Control, and two bugs that made it look broken;
  • why Launchpad is secretly two windows;
  • three ways the light/dark switch appeared to do nothing;
  • a crash in Ubuntu’s menu-bar plugin, tracked down and fixed;
  • a glass effect that kept switching itself off;
  • what the tests check, and what they deliberately leave alone.

MIT licensed.

Source → github.com/isaacrowntree/mintosh (MIT)

A theme is the easy 20%

The look comes from people who have already done it well. MacTahoe is a careful copy of macOS Tahoe’s windows, icons and cursors. picom draws the frosted-glass blur, Toshy makes the ⌘ key behave, Plank is the dock, and Touchegg reads trackpad gestures.

Install all of that and you get something that looks like a Mac in a screenshot and nothing like one once you use it. Most of mintosh is the glue between those projects:

  • The menu bar. The Apple menu, then the current app’s name in bold and its File, Edit and View menus, moved out of the window and into the bar, as on a Mac. The status icons are in macOS’s order, and the clock reads “Mon 26 Oct 9:41 AM”. There’s no solid bar: as in Tahoe, the text sits straight on the wallpaper.
  • The Apple menu. About This Computer, System Settings, Appearance, App Store, Force Quit, Sleep, Restart, Shut Down, Lock Screen and Log Out, with the dividers where macOS puts them.
  • Keys and gestures. ⌘C, ⌘V, ⌘Q, ⌘W and ⌘Tab. ⌘⇧3 saves “Screenshot 2026-10-26 at 09.41.12.png” to the Desktop without asking where. F3 and F4 do what’s printed on them. Three fingers up opens Mission Control, three fingers sideways changes desktop, and pinching with thumb and three fingers opens Launchpad.
  • The 2013 hardware. Without a startup setting, the Mint installer can’t see this Air’s SSD. Once installed, the desktop froze after about an hour until a power-saving feature for the drive was turned off; the battery saver kept turning it back on, so that needed fixing too. Add Wi-Fi and camera drivers, fan control, and low-battery warnings that agree with the percentage in the menu bar.

The mintosh desktop in light mode, with the Apple menu open (About This Computer, System Settings, Appearance, App Store, Force Quit, Sleep, Restart, Shut Down, Lock Screen, Log Out), a Finder window with macOS folder icons, and a glass dock over a pink and purple wallpaper.

On 4 GB, nothing runs in the background

Chrome alone can fill 4 GB. So the rule was simple: anything macOS keeps running all the time only exists here while it’s on screen.

Spotlight and Launchpad use rofi, a launcher that starts when you call it and quits when you close it. I tried Ulauncher first, the usual Spotlight stand-in on Linux, but it sits in memory at 100 MB or more. On this machine that’s a whole browser tab.

Mission Control is a small Python program that opens, shows live previews of every window (even ones hidden behind others), and quits when you’re done. The bar across the top holds your desktops: click one to go there, + to add one, ✕ to remove the last. Drag a window’s preview onto a desktop to move it there.

Mission Control: "Desktop 1" and + buttons across the top, and previews of a Finder window and a Text Editor window, each labelled with its app's name.

Two bugs in it are worth a mention, because from the outside both just looked like “it doesn’t work”:

  • Dragging a window onto a desktop did nothing. The code that says “this can be dragged” has to be set up before the code that handles clicks. It was the other way round, so the click handler swallowed every press and a drag never started. The fix was swapping two lines.
  • Every Finder window was labelled “Bulk Rename”. Labels use each app’s friendly name (“Calculator”, not gnome-calculator). But Finder’s hidden bulk-rename tool is the same program underneath, and it was found first. Ignoring hidden tools fixed it.

Launchpad is secretly two windows

On a Mac, clicking anywhere outside Launchpad’s icons closes it. rofi can close on an outside click, but only if its window doesn’t cover the whole screen, and Launchpad does.

So Launchpad is two windows:

  1. At the back, a full-screen picture of your wallpaper, blurred and dimmed.
  2. In front, rofi as a box in the middle of the screen, with the matching piece of the same picture as its background.

The two line up exactly, so it looks like one surface. A click outside the box lands on the back window, and both close. It lists the same apps as Mint’s own menu, so nothing goes missing in the move.

Launchpad in dark mode: a search field at the top and a grid of app icons with their names over a blurred, darkened wallpaper.

Then a worse surprise. If you typed something that matched no app and pressed Return, rofi tried to run your words as a command. “settings manager” + Return gave a full-screen error, Failed to execute: ‘settings manager’. The error was the harmless part. The real problem was that typed text was being run at all. Now Spotlight and Launchpad only ever start installed apps, and anything else does nothing, which is also what a Mac does.

Three ways the light/dark switch seemed to do nothing

Apple menu → Appearance… switches between Light, Dark and Auto (light from 7 am to 7 pm). It changes everything that has two looks: windows, icons, the menu bar, the dock, Spotlight, Launchpad, Mission Control, notifications, the wallpapers, and apps like Chrome that follow the system setting.

Each of these bugs looked like the switch simply hadn’t happened:

What you saw Why Fix
Plain grey window buttons instead of red, yellow and green On the first run the theme was selected a few seconds before it was installed, and Xfce only reloads a theme when its name changes Select a different theme for a moment first, then the right one
Black menu-bar text on a dark wallpaper The menu bar only reads its colours when it starts Restart the menu bar after switching
No blur, no rounded corners, no shadows picom didn’t understand one line of its settings, printed an error nobody saw, and quit Two characters in that line

The third went unnoticed longest, because Xfce quietly took over with its own, plainer effects and it looked almost right.

A crash in the menu bar, tracked down and fixed

On the real Air, moving a Chrome window to another desktop popped up an Xfce error: “plugin unexpectedly left the panel”. The crash report pointed at the part of the menu bar that shows each app’s File and Edit menus. It’s a plugin called xfce4-appmenu-plugin, and Ubuntu 24.04, and so Mint 22, ships version 0.7.6.

With Ubuntu’s debugging information downloaded, the crash pointed to one function. In plain terms: when an app’s menu disappears, as Chrome’s does when its window changes desktop, the plugin cancels its pending request for that menu and throws the menu away. The cancelled request still reports back, though, and the first thing the reply handler does is look at the menu that’s already been thrown away. Here’s the start of it, for anyone who reads C:

static void get_layout_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
	if (!DBUS_MENU_IS_MODEL(user_data))   /* looks at the menu first ...            */
		return;
	...
	dbus_menu_xml_call_get_layout_finish(..., &error);
	if (error != NULL)                    /* ... before checking it was cancelled   */
		return;

The plugin’s other handlers already do these two steps the right way round; this one doesn’t. The fix swaps them.

There’s no fixed version to install, so mintosh’s system script now builds one. It downloads Ubuntu’s own source code for the plugin, applies the fix, builds just the menu-bar part, and puts it in place. Then it removes the build tools again, so they don’t take up space on a small drive. It only does this for that exact version, and a future Ubuntu update simply replaces it.

A glass effect that kept switching itself off

picom, the program that draws the glass, had its own problem. Every so often, usually when the menu bar restarted, it hit one of its own internal safety checks and shut down, and the glass stayed off until the next login.

I didn’t go digging into picom. Instead it now runs inside a tiny wrapper that starts it again whenever it crashes, and leaves it alone when it’s stopped on purpose:

while :; do
  picom "$@"; rc=$?
  [ "$rc" -eq 134 ] || exit "$rc"   # 134 means it crashed; anything else was deliberate
  sleep 1
done

On the Air, three menu-bar restarts in a row caused two crashes, and neither was visible.

What the tests check, and what they leave alone

mintosh is tested in a Mint virtual machine on a Mac (using OrbStack), at the Air’s screen size. The test presses keys and clicks the mouse, and finds buttons by their names the way a screen reader does, so it doesn’t break when something moves. It checks that:

  • each shortcut opens the right thing;
  • Launchpad fills the screen, opens an app with one click, opens the best match on Return, ignores Return when nothing matches, and closes with Esc, with F4 again, or with a click outside;
  • Mission Control names windows after their apps, adds and removes desktops, moves a dragged window, brings a clicked window to the front, and closes all three ways;
  • each trackpad gesture does what it should.

It doesn’t test Toshy or Touchegg, the keyboard and gesture projects mintosh builds on; both are well tested by their own authors. An earlier version did try, using fake keyboards and trackpads, and mostly ended up testing the virtual machine instead: it turned out the VM only ever set up two of them, so the rest silently didn’t exist. Now the test sends the keys Toshy would send and runs the commands mintosh gives Touchegg. That’s the part mintosh is responsible for.

The other test is the Air itself, and the person who uses it.

Try it

On any computer running Linux Mint 22 Xfce, Mac or not, run scripts 3, 4 and 5 from the README. The Mac hardware fixes only switch on when that hardware is there. Everything is in English by default, with a second language as an option. If you’re moving someone off an old Mac, steps 1 and 2 back it up and sort their files before anything is wiped.

Issues and pull requests are welcome, especially from anyone with a 2014 or 2015 MacBook to try it on.

Header photo by Markus Spiske on Unsplash.