<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="https://mastorakis.com/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    
    <title>Konstantinos Mastorakis</title>
    <link>https://mastorakis.com/</link>
    <atom:link href="https://mastorakis.com/feed.xml" rel="self" type="application/rss+xml" />
    <description>Notes on things I find interesting, and the projects I build along the way.</description>
    <language>en</language>
    <item>
      <title>From .hqx and .sit to mountable disk images for Mini vMac</title>
      <link>https://mastorakis.com/blog/mac-plus-hqx-sit-to-dsk/</link><description>&lt;p&gt;I&#39;m trying to revive my old Macintosh Plus. The plan is to put a BlueSCSI in it, so instead of a real hard drive it boots from an SD card, and I&#39;ve started building the hard disk image that will go on that card: System 6.0.8 plus the software I want on the machine. I&#39;m putting it together in Mini vMac, an emulator of the same Mac Plus, so I can set everything up on my modern Mac before any of it touches the real hardware.&lt;/p&gt;
&lt;p&gt;Most of the old games and apps I wanted come as &lt;code&gt;.hqx&lt;/code&gt; or &lt;code&gt;.sit&lt;/code&gt; files, and that&#39;s where last night went.&lt;/p&gt;
&lt;h2&gt;Getting files into the emulator&lt;/h2&gt;
&lt;p&gt;Mini vMac can&#39;t see files on your Mac&#39;s disk. It only mounts disk images, so dragging a &lt;code&gt;.sit&lt;/code&gt; straight onto its window gets you nowhere:&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://mastorakis.com/blog/images/amfv-sit-unsupported.png&quot; alt=&quot;Mini vMac showing an Unsupported Disk Image message: I do not recognize the format of the Disk Image, and so will not try to mount it.&quot;&gt;
  &lt;figcaption&gt;Dragging the A Mind Forever Voyaging &lt;code&gt;.sit&lt;/code&gt; onto Mini vMac: &quot;Unsupported Disk Image&quot;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For single files there&#39;s a small utility called ImportFl: you run it inside the emulated Mac, drag a file onto the Mini vMac window, and it saves a copy onto the emulated disk. So my first approach was to import the &lt;code&gt;.sit&lt;/code&gt; files with ImportFl and expand them inside System 6 with StuffIt Expander, the way you would have done it back in the day.&lt;/p&gt;
&lt;h2&gt;StuffIt Expander didn&#39;t recognise them&lt;/h2&gt;
&lt;p&gt;That mostly didn&#39;t work. StuffIt Expander either didn&#39;t recognise the files at all or refused to open them. It took me a while to work out why, and it turned out to be three separate problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Double wrapping.&lt;/strong&gt; Some downloads are a StuffIt archive wrapped in BinHex (&lt;code&gt;.hqx&lt;/code&gt;, the text encoding used to send Mac files safely over email and the early internet). The StuffIt versions that run on System 6 can&#39;t decode BinHex; that needs a separate tool first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Newer StuffIt formats.&lt;/strong&gt; A lot of archives are saved in the StuffIt 5 format from 1998. No version of StuffIt that runs on System 6 can open those, however you get them onto the machine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lost file types.&lt;/strong&gt; Classic Mac files carry a hidden type and creator code, and that&#39;s how the old tools know what a file is. ImportFl brings files in without them, so even a perfectly good archive just looks like an unknown document to StuffIt Expander.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The fix: unpack on the host, mount a .dsk&lt;/h2&gt;
&lt;p&gt;In the end I stopped fighting it inside the emulator. I unpack everything on my modern Mac instead, with &lt;code&gt;unar&lt;/code&gt; (the command-line version of The Unarchiver). It handles BinHex and every StuffIt version, and on macOS it keeps the resource forks and type and creator codes that old Mac files depend on.&lt;/p&gt;
&lt;p&gt;What comes out is either a disk image or a pile of loose Mac files, so a small Python script turns each download into a raw &lt;code&gt;.dsk&lt;/code&gt; image that Mini vMac can mount:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Existing disk images, such as Disk Copy 4.2 images, get converted to raw &lt;code&gt;.dsk&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Loose files get packed into a fresh HFS volume, with their folders, resource forks and type and creator codes intact.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now it&#39;s simple: I drag a &lt;code&gt;.dsk&lt;/code&gt; onto the Mini vMac window, it mounts as a disk in System 6, and I copy the game or app onto the emulated hard disk. No ImportFl, no StuffIt, no guessing why a file won&#39;t open.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://mastorakis.com/blog/images/amfv-dsk-mount.gif&quot; alt=&quot;The .sit and the converted .dsk on the Mac desktop. The .dsk is dragged onto the Mini vMac window, mounts as AMFV Disk, and opens to show A Mind Forever Voyaging and a System Folder.&quot;&gt;
  &lt;figcaption&gt;The converted &lt;code&gt;.dsk&lt;/code&gt; dragged onto Mini vMac mounts straight away as AMFV Disk.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://mastorakis.com/blog/images/amfv-running.png&quot; alt=&quot;A Mind Forever Voyaging running in Mini vMac, showing the opening text in Communications Mode.&quot;&gt;
  &lt;figcaption&gt;A Mind Forever Voyaging, Infocom&#39;s 1985 text adventure, running in Mini vMac.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2&gt;Next&lt;/h2&gt;
&lt;p&gt;The next step is to test everything in the emulator, finish the hard disk image, and then copy it to the SD card for the BlueSCSI and try it on the real Plus.&lt;/p&gt;
</description><pubDate>Wed, 30 Sep 2026 02:00:00 +0200</pubDate>
      <dc:creator>Konstantinos Mastorakis</dc:creator>
      <guid>https://mastorakis.com/blog/mac-plus-hqx-sit-to-dsk/</guid>
    </item>
    <item>
      <title>What&#39;s new in Barista 1.1</title>
      <link>https://mastorakis.com/blog/barista-1-1/</link><description>&lt;p&gt;Barista 1.1 is out on the App Store. The 1.0.x updates were mostly fixes and small additions; this is the first release that adds real features. Here are the main ones.&lt;/p&gt;
&lt;h2&gt;Command palette&lt;/h2&gt;
&lt;p&gt;Press ⌥⌘K and a Spotlight-style search box appears. Type part of a widget&#39;s name, pick it with the arrow keys and Return, and its popover opens. If the widget isn&#39;t in your menu bar, choosing it adds it and opens it.&lt;/p&gt;
&lt;h2&gt;Your own global shortcuts&lt;/h2&gt;
&lt;p&gt;Settings now has a Shortcuts pane where you can rebind the built-in shortcuts (the Barista bar, Search, Clipboard and the command palette), clear any of them, and add new ones: quick-add a reminder, quick-add a calendar event, or open any specific widget with its own key combination. Restore defaults puts everything back.&lt;/p&gt;
&lt;h2&gt;Popovers you can unpin&lt;/h2&gt;
&lt;p&gt;A popover no longer has to stay under its menu-bar icon. Unpin it (the corner button or ⌘P) and it becomes a small floating window with a title strip: drag it anywhere, resize it from the corner, and close it when you&#39;re done. It reopens where you left it, and a reset button folds it back under the menu bar.&lt;/p&gt;
&lt;h2&gt;Notifications open the right thing&lt;/h2&gt;
&lt;p&gt;Clicking a notification now opens the widget it came from, on the exact item. A new-mail notification opens that email, not just the inbox. Calendar notifications still open the meeting link.&lt;/p&gt;
&lt;h2&gt;Calendar: a horizontal layout&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://mastorakis.com/blog/images/barista-1-1-calendar-horizontal.jpg&quot; alt=&quot;The Barista calendar in its horizontal layout: the Next up card on top, the day&#39;s events and reminders on the left, and the month grid on the right&quot;&gt;&lt;/p&gt;
&lt;p&gt;The calendar has a new Orientation setting. The original vertical layout is still there, and the new horizontal one works as a day dashboard: the day&#39;s events and reminders on the left, with an Upcoming section below them, and the month grid on the right. On a wide screen it shows a lot more at a glance.&lt;/p&gt;
&lt;h2&gt;Email: filters, VIPs and clearer unread mail&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://mastorakis.com/blog/images/barista-1-1-email.jpg&quot; alt=&quot;The Barista email widget in 1.1: messages from two accounts, with unread messages on a tinted row&quot;&gt;&lt;/p&gt;
&lt;p&gt;The email widget can now show only unread or only starred messages. You can mark senders as VIPs so their mail floats to the top, or mute senders so they disappear from the list. Unread messages are also easier to spot, with a tinted row and separators between messages.&lt;/p&gt;
&lt;h2&gt;Weather and News&lt;/h2&gt;
&lt;p&gt;Weather gets a 10-day forecast, a wide layout with the forecast on the right, and next-hour rain and severe-weather alerts where WeatherKit provides them. News gets read and unread state with Mark all read, a saved list for reading later, notifications when a headline matches a keyword, and OPML import and export so you can bring your feeds from another reader.&lt;/p&gt;
&lt;h2&gt;Fixes&lt;/h2&gt;
&lt;p&gt;1.1 also fixes a crash when opening the calendar after an event had been deleted elsewhere, some emails showing up as raw encoded text instead of the message, and the Webpage and Email widgets going blank when macOS reclaimed their web renderer. They now recover on their own.&lt;/p&gt;
&lt;p&gt;The full list is in the app&#39;s What&#39;s New window.&lt;/p&gt;
&lt;p&gt;Barista is on the &lt;a href=&quot;https://apps.apple.com/app/barista-35-menu-bar-widgets/id6773448655&quot;&gt;Mac App Store&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Tue, 15 Sep 2026 02:00:00 +0200</pubDate>
      <dc:creator>Konstantinos Mastorakis</dc:creator>
      <guid>https://mastorakis.com/blog/barista-1-1/</guid>
    </item>
    <item>
      <title>No sound in Mac games? Check for leftover audio drivers</title>
      <link>https://mastorakis.com/blog/mac-games-no-sound-teams-audio-driver/</link><description>&lt;p&gt;I originally posted this elsewhere some time ago. The problem is long solved, but I&#39;m putting it here too, as a note for my future self and for anyone who lands here from a search.&lt;/p&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;At some point, a few games on my Apple silicon Mac mini stopped playing any sound at all. Other games were completely fine. The ones I noticed it in were Cities: Skylines, StarCraft II and Heroes of the Storm.&lt;/p&gt;
&lt;h2&gt;The fix&lt;/h2&gt;
&lt;p&gt;A quick disclaimer first: this is what worked on my machine, so do it at your own risk.&lt;/p&gt;
&lt;p&gt;The cause was an extra audio driver that Microsoft Teams installs as a plug-in. I deleted its folder, restarted the Mac, and the sound came back:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/Library/Audio/Plug-Ins/HAL/MSTeamsAudioDevice.driver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While looking into it, I found other people with silent games who fixed them the same way, by removing extra audio drivers. Some of those reports were about the audio driver that Zoom installs, so it&#39;s not only a Teams thing. If you have similar symptoms, &lt;code&gt;/Library/Audio/Plug-Ins/HAL/&lt;/code&gt; is a good place to look.&lt;/p&gt;
&lt;p&gt;One more thing: removing the driver didn&#39;t break Teams. It kept working normally for me, so I&#39;m honestly not sure what the driver is for. It&#39;s an optional component in the Teams installer, so you can also just leave it unchecked when you install.&lt;/p&gt;
</description><pubDate>Wed, 15 Jul 2026 02:00:00 +0200</pubDate>
      <dc:creator>Konstantinos Mastorakis</dc:creator>
      <guid>https://mastorakis.com/blog/mac-games-no-sound-teams-audio-driver/</guid>
    </item>
    <item>
      <title>Three problems that surprised me building Barista</title>
      <link>https://mastorakis.com/blog/building-barista-technical-challenges/</link><description>&lt;p&gt;In the &lt;a href=&quot;https://mastorakis.com/blog/why-i-built-barista/&quot;&gt;last post&lt;/a&gt; I wrote about what Barista is and why I built it. This one is about the building part: three problems that took far longer to figure out than they should have, and what I learned from each.&lt;/p&gt;
&lt;h2&gt;1. The app that died before it started&lt;/h2&gt;
&lt;p&gt;Barista&#39;s weather widget uses WeatherKit, Apple&#39;s weather service. Adding it was supposed to be a small change: enable the service for the app, add one entitlement, call the API. Instead, the next development build refused to launch. No crash report, no error, nothing in the logs under the app&#39;s name. The process was simply killed the moment it started (exit code 137, a SIGKILL).&lt;/p&gt;
&lt;p&gt;The cause turned out to be a chain of things I didn&#39;t know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As soon as an app carries any &lt;code&gt;com.apple.developer.*&lt;/code&gt; entitlement (WeatherKit is one), macOS fully checks its provisioning profile at launch. Without such an entitlement, that check is mostly skipped, which is why every earlier build had worked fine.&lt;/li&gt;
&lt;li&gt;A development profile only works on the Macs listed in it.&lt;/li&gt;
&lt;li&gt;On Apple Silicon Macs, the ID the developer portal needs is the &lt;strong&gt;Provisioning UDID&lt;/strong&gt;, not the &lt;strong&gt;Hardware UUID&lt;/strong&gt;. Both appear in System Information, and the Hardware UUID looks like the obvious choice, so that&#39;s the one I had registered.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So my own Mac wasn&#39;t in the profile, and the system killed the app before any of my code ran. The fix was registering the right ID, which you can find with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;system_profiler SPHardwareDataType | grep &amp;quot;Provisioning UDID&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One more catch: I build Barista with Swift Package Manager and a shell script rather than Xcode, and Xcode normally adds two entitlements (the application identifier and team identifier) behind the scenes. Without them the same check fails too, so they now sit explicitly in the entitlements file.&lt;/p&gt;
&lt;p&gt;TestFlight and App Store builds never had the problem, because distribution profiles aren&#39;t tied to specific Macs. Which made it even more confusing: the &amp;quot;real&amp;quot; builds worked and only my local ones died.&lt;/p&gt;
&lt;h2&gt;2. Writing a small email client&lt;/h2&gt;
&lt;p&gt;I didn&#39;t want the email widget to depend on Mail.app, so Barista talks to mail servers itself, using IMAP to read and SMTP to send. The client is written on top of Apple&#39;s &lt;code&gt;Network&lt;/code&gt; framework and only implements the handful of commands the widget needs.&lt;/p&gt;
&lt;p&gt;It only supports servers that accept a TLS connection straight away (ports 993 and 465). The older way, where a connection starts unencrypted and upgrades to TLS partway through (STARTTLS), has no clean path in Apple&#39;s &lt;code&gt;NWConnection&lt;/code&gt;, and the direct approach is the more secure one anyway. When someone adds a server that only supports STARTTLS, the setup says so plainly instead of failing with a vague error.&lt;/p&gt;
&lt;p&gt;A few lessons from the first weeks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sequence numbers move.&lt;/strong&gt; IMAP gives each message in a mailbox a position number and a separate, stable ID (the UID). I originally marked messages as read using the position number, remembered from when the list was loaded. But if anything removes a message in between (a server-side filter, Gmail sorting mail into categories, your phone), every position after it shifts, and the server marks the wrong message as read. Switching every action to UIDs fixed it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not all mail is UTF-8.&lt;/strong&gt; Older mail and some languages still use legacy encodings like Windows-1252, ISO-8859-7 (Greek) or Shift_JIS. They showed up as &lt;code&gt;=E9&lt;/code&gt; artifacts or garbled text until the client started reading the declared charset of each message and header and decoding with it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reconnecting is slow.&lt;/strong&gt; At first, every page of the inbox opened a fresh connection: TCP, TLS handshake, login, fetch, logout. That&#39;s 500 to 800 ms per click. Keeping one logged-in connection per account brought paging down to around 250 ms. Later I did the same for opening a message, and added a small in-memory cache so recently fetched messages open instantly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Data&lt;/code&gt; indices can surprise you.&lt;/strong&gt; I buffered server responses in Swift&#39;s &lt;code&gt;Data&lt;/code&gt;, trimming bytes off the front as they were parsed. After enough trimming, the indices returned by one &lt;code&gt;Data&lt;/code&gt; method stopped lining up with what another expected, which crashed on long responses. Switching the buffer to a plain &lt;code&gt;[UInt8]&lt;/code&gt; array, whose indices always start at zero, made the problem go away.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. One process, many widgets&lt;/h2&gt;
&lt;p&gt;Having all the widgets in one app is the whole point of Barista, but it has a downside: if one widget crashes, the whole app goes down with it. And some crashes can&#39;t be caught in Swift. An early example was a text-formatting tool that, given a bare value like &lt;code&gt;42&lt;/code&gt; instead of a full JSON document, triggered an Objective-C exception that &lt;code&gt;try?&lt;/code&gt; doesn&#39;t catch.&lt;/p&gt;
&lt;p&gt;I can&#39;t prevent every crash, but I can stop the same widget from taking the app down again and again. So Barista has a small crash quarantine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Right before a widget does something risky (starting up, or building its popover), Barista writes a small note saying &amp;quot;this widget is doing this now&amp;quot;, and clears it afterwards.&lt;/li&gt;
&lt;li&gt;When the app quits normally, it records a clean exit.&lt;/li&gt;
&lt;li&gt;On the next launch, if the last exit wasn&#39;t clean and a note was still there, Barista knows which widget was busy when things went wrong.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That widget gets switched off before it can run, and a banner in Settings explains what happened, with a button to turn it back on. A popover crash quarantines the widget immediately, since popovers open one at a time and it&#39;s clear who was responsible. A crash during start-up needs to happen twice in a row, because many widgets start together, and one unlucky force-quit shouldn&#39;t blame an innocent widget.&lt;/p&gt;
&lt;p&gt;None of this is visible when things work, which is exactly how it should be. But it means a bug in one widget stays a bug in one widget, instead of an app that won&#39;t start.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;There were plenty of smaller puzzles too (getting text fields to accept typing inside a menu bar popover deserves its own post), but these three are the ones I&#39;ll remember.&lt;/p&gt;
</description><pubDate>Fri, 03 Jul 2026 02:00:00 +0200</pubDate>
      <dc:creator>Konstantinos Mastorakis</dc:creator>
      <guid>https://mastorakis.com/blog/building-barista-technical-challenges/</guid>
    </item>
    <item>
      <title>Why I built Barista</title>
      <link>https://mastorakis.com/blog/why-i-built-barista/</link><description>&lt;p&gt;Ten days ago I shipped Barista. This is a short write-up of what it is, what problem it solves for me, and a few decisions I made along the way.&lt;/p&gt;
&lt;h2&gt;Small tasks, many times a day&lt;/h2&gt;
&lt;p&gt;A lot of what I do on my Mac during a day is small: check when the next meeting starts, glance at the weather, convert a unit, paste something I copied an hour ago, see what just landed in my inbox, jot down a note. Each one takes a couple of seconds. But doing it usually means stepping away from what I&#39;m working on: switching to another app, opening yet another window, or hiding everything to get to the widgets on the desktop. And then finding my way back to where I was.&lt;/p&gt;
&lt;p&gt;The menu bar is the one place that&#39;s always there, above whatever I&#39;m doing. Clicking something there, doing the task in two seconds and carrying on doesn&#39;t move a single window or break my train of thought. That&#39;s what I wanted for all of those small tasks: click, done, back to work.&lt;/p&gt;
&lt;h2&gt;One app for all of it&lt;/h2&gt;
&lt;p&gt;The idea behind Barista is to put those small tasks in the menu bar, in one app. Each widget is one item in the menu bar, and clicking it opens a small popover that behaves like a proper little app rather than a dropdown menu. They all share the same look, spacing and keyboard handling (arrow keys, Return, Esc to close), so once you&#39;ve used one you know how the others work. Everything is configured from a single settings window.&lt;/p&gt;
&lt;p&gt;It started with a handful of widgets and grew to more than 35: calendar, reminders, weather, email, clipboard history, CPU, memory and battery, a calculator, a unit converter, world clocks, a colour picker, and a few small games for when a build is taking its time. A fresh install starts with none of them switched on. You pick the ones you want, so the bar only holds the things you actually reach for.&lt;/p&gt;
&lt;h2&gt;Calendar&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://mastorakis.com/blog/images/barista-calendar.jpg&quot; alt=&quot;The Barista calendar widget: a month grid with event dots, a &amp;quot;Next up&amp;quot; card, and the day&#39;s agenda with a Join button for a video call&quot;&gt;&lt;/p&gt;
&lt;p&gt;The calendar is the widget I use most. It&#39;s something I was used to from GNOME, where clicking the clock in the top bar opens a small calendar with your upcoming events. macOS doesn&#39;t have that (clicking the clock opens Notification Center instead), and I missed it.&lt;/p&gt;
&lt;p&gt;The menu bar shows the next event and its time. Clicking it opens a month grid with dots for busy days, a &amp;quot;Next up&amp;quot; card, and the agenda for whichever day you select. Meetings with a video link get a Join button. It reads from the calendars already set up on your Mac, so there&#39;s nothing new to connect.&lt;/p&gt;
&lt;h2&gt;Email&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://mastorakis.com/blog/images/barista-email.jpg&quot; alt=&quot;The Barista email widget: a list of messages across two accounts, with a New button, search and refresh&quot;&gt;&lt;/p&gt;
&lt;p&gt;The email widget was the most work by far. The menu bar shows the unread count. The popover lists recent messages across all your accounts, and you can read, reply and write new mail without leaving it. It talks to mail servers directly, so it doesn&#39;t need Mail.app running. Gmail, iCloud, Yahoo and AOL are set up with a few clicks, and other servers work too if they accept a direct TLS connection (the setup runs a quick test and tells you if yours doesn&#39;t). It&#39;s not trying to replace a full mail client. It&#39;s for glancing at what came in and dealing with the quick ones.&lt;/p&gt;
&lt;h2&gt;Running out of room&lt;/h2&gt;
&lt;p&gt;With enough widgets turned on, the menu bar fills up quickly, especially next to the notch. So Barista can fold everything behind a single icon. Clicking it drops down a separate Barista bar that holds all the widgets, with its own space independent of the system menu bar. This is set per display, so a laptop screen can stay tidy while an external monitor shows everything.&lt;/p&gt;
&lt;h2&gt;A few decisions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mac App Store only.&lt;/strong&gt; Barista runs in Apple&#39;s sandbox and uses only public APIs. That ruled out a few things I wanted, such as showing what&#39;s playing in any app, a widget for switching Spaces, and a small terminal, because each of them would need private APIs or permissions the sandbox doesn&#39;t allow. I&#39;d rather drop a feature than ship something that could break with the next macOS update.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nothing leaves your Mac unless a widget needs it.&lt;/strong&gt; There&#39;s no analytics. Clipboard history and the scratchpad are encrypted on disk, and email passwords live in the Keychain.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Light on resources.&lt;/strong&gt; All the widgets run in one lightweight process. A menu bar app should never be the reason your fans spin up.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What&#39;s next&lt;/h2&gt;
&lt;p&gt;This is the first version, and there&#39;s plenty I want to improve. If you try it and something annoys you, I&#39;d genuinely like to hear about it. There&#39;s a &lt;a href=&quot;https://mastorakis.com/barista/support.html&quot;&gt;support page&lt;/a&gt; with ways to reach me, and more about the app on its &lt;a href=&quot;https://mastorakis.com/barista/&quot;&gt;project page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the next post I&#39;ll write about a few of the technical problems that took far longer to solve than I expected.&lt;/p&gt;
</description><pubDate>Mon, 29 Jun 2026 02:00:00 +0200</pubDate>
      <dc:creator>Konstantinos Mastorakis</dc:creator>
      <guid>https://mastorakis.com/blog/why-i-built-barista/</guid>
    </item>
    <item>
      <title>Hello, World</title>
      <link>https://mastorakis.com/blog/hello-world/</link><description>&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;lt;stdio.h&amp;gt;

int main(void) {
    printf(&amp;quot;Hello, World!&#92;nThis is the first post on the blog.&#92;n&amp;quot;);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Sun, 28 Jun 2026 02:00:00 +0200</pubDate>
      <dc:creator>Konstantinos Mastorakis</dc:creator>
      <guid>https://mastorakis.com/blog/hello-world/</guid>
    </item>
  </channel>
</rss>