This Only Happens Here

My five year old, driving home from daycare today, unprompted:

I know what lockdown is.

Like when we had to stay home for a long time last year?

It’s when we turn the lights off and lock the door and hide in the fire room because a bad guy is coming.

Pause.

But, daddy. Why do bad guys have swords and kill all the people?

Let’s Reimplement an Amazing First-Party Feature in the Dumbest Way Possible

[Update 2021-12-18: See this post for a better solution.]

Some ideas are just too silly to not try and follow through with.

Earlier this evening, Michael Tsai tweeted

Safari is already less compatible, so if the user interface is going to be worse, too, I just don’t see the point. The main other thing keeping me there is 2FA auto-fill.

and I replied

I’m very, very close to writing a KeyboardMaestro macro to grab the latest 2FA code from Messages.app to work around this.

I was mostly joking.

Until I thought, why not?

Here it is. Just launch the macro, and it grabs the new two-factor code that was just texted to you. Then inserts it into your non-Safari browser.

And here’s how it works…

My first instinct was to try and copy the text of the most recent conversation in Messages.app and then pipe that through a regular expression to parse out the two-factor code.

For very boring reasons that aren’t very interesting, I’ll just say that I spent two days a few years ago trying to hack together something similar using Messages’ AppleScript interface. It wasn’t very good back then, so I didn’t even attempt going down that road tonight – especially since it’s a Catalyst app now.

Instead, I decided to just try “clicking” my way through the UI with KeyboardMaestro. Something along the lines of…

  1. Activate Messages.app
  2. Click a known x,y coordinate from the top-left corner of the window to select the first non-favorite conversation.
  3. Double-click a known x,y coordinate from the bottom-left corner of the window to select a word in the last message of that conversation.
  4. Type ⌘A to select all the text in that message.
  5. ⌘C to put it on the clipboard.
  6. Parse out the code.
  7. Paste the code onto the clipboard to use.

That sort of worked. But it wasn’t very reliable. Mostly because Messages.app takes so long to wake up sometimes. If its window hasn’t been displayed in a while, it can take a not-insignificant amount of time to appear. And then switching to the newest conversation is similarly slow.

As much as I tried to work around this by adding delays in the UI script or other KeyboardMaestro tricks, it was too fragile to be reliable in my testing. I needed another approach.

Here’s what ended up working.

  1. Click the menubar’s clock to activate Notification Center. (By the way, it took me a full damn month after installing Big Sur before I realized what Apple had done with the Notification Center icon and that it was still accessible without needing to use the two-finger-swipe-from-right trackpad gesture.)
  2. Wait for the reveal animation to finish.
  3. Take a screenshot.
  4. Flip the image horizontally. (Because KM’s crop action only works from the top-left corner of an image.)
  5. Crop out the known size/position of the first notification message. (All message bubbles are the same size no matter their contents.)
  6. Flip the image horizontally (back to the original orientation).
  7. OCR the text contained in that cropped image, which should hopefully contain our two-factor code.
  8. Extract the code using a shell script. (Please dear god Apple don’t remove Perl from Monterey.)
  9. Close Notification Center.
  10. Wait for the collapse animation to finish. (This delay is longer because I found I had to wait for the animation to finish and then an additional delay for the active application to regain keyboard focus a moment later.)
  11. Type the code into the current app (probably your non-Safari browser).
  12. Put the code on the clipboard for good measure.

And, boom, in just twelve easy steps… ?‍♀️

You can download the macro here.

Caveats

  • I haven’t tested this yet on multi-monitor systems.
  • The image crop dimensions assume you’re using a retina display.
  • The regular expression will probably fail for you, but it works for Google and my bank.
  • This is all a dumb hack that isn’t actually meant to be taken seriously but illustrates the internet’s collective knee-jerk response to not wanting to use the new Safari.

The Entire Amount of Commerce

It’s that time of year again, and I wanted to expand on a tweet from last year.

This is your iPhone and Mac without 3rd party developers.

Riccardo Mori replied

Impressively carved skeletons with no meat.

Since Apple will stand on a virtual stage tomorrow and tell us how much they love, value, and appreciate third-party developers, here is an alphabetical list of iOS apps that I depend on – from solo developers, small companies, and giant world-eating ones, too.

(And these are not affiliate links because Apple sure put a stop to that.)

1Password, DEVONthink, Day One, Drafts, Dropbox, Due, Fantastical, Fastmail, Firefox, Google Maps, Home+, Instapaper, Noom, OmniFocus, Overcast, PCalc, Pins, Plexamp, Pushover, Reeder, Sonos, Spotify, SwiftScan, The Athletic, Trello, Tweetbot, WolframAlpha, YouTube Music

I want to be crystal clear about the value these apps (and many others) provide. Without them, I would not own an iPhone. Or an iPad. Or an Apple Watch. I would not have purchased an iPad Magic Keyboard. Or any number of first-party Apple Watch bands.

I would not own three Apple TVs. (Well, only one is still in use. The other two are in a closet after being swapped out for Android TV last Summer. But that’s another blog post.)

I would not pay for iCloud storage each month. My seven-year-old son would not use his chore money to pay for Apple Arcade.

And because modern life relies so much on connected ecosystems, if I didn’t use any of the above hardware, dare I say, I would not still be using a Mac, either.

As the head of IT for my family and extended family (is there a better way to phrase that?), I would question if any of them would own iPhones, iPads, Apple Watches, Mac laptops, and pay for iCloud, Apple Music, and even Apple Fitness+.


The iPod halo effect brought millions of people into Apple’s walled garden. But as Tim Cook testified in court last week, no customers are locked in by Apple.

Lawyer: What about references to locking customers into devices?
Cook: It means making all the product work so well together people don’t want to leave.
Lawyer: Is there anything Apple could do to lock people into iOS?
Cook: Not that I’m aware of.

And I agree with Cook. I could switch to Windows and Android. I wouldn’t like it, but I could make the switch.

Except for all those third-party apps. I couldn’t give those up without significant effort – if it would even be possible to find replacements for each.

Third-party apps are what keep me locked into Apple’s lucrative don’t-call-it-a-walled-garden.

In any healthy software ecosystem, third-party developers and the platform vendor are a symbiotic relationship. To pretend otherwise is fanciful gaslighting.


Cook: I view it differently than you do, Your Honor. I view that we are creating the entire amount of commerce on the store

I view it differently than you do, Mr. Cook. I view that developers are creating the entire incentive for consumers to purchase your hardware.

TextBuddy is a Mac|Life Editor’s Choice

If you don’t mind, I’d like to interrupt my not-so-regularly-scheduled posts about silly macOS workflows and tech complaining for a not-so-humble-brag.

TextBuddy received a lovely review in the June issue of Mac|Life – including an Editor’s Choice seal of approval.

The bottom line. A marvel. If you work with text, you need this app.

As a nerdy kid who grew up in the 90s browsing the magazine section of Waldenbooks for the latest issues of Macworld, boot, and Next Generation, seeing one of my apps in a print magazine is a huge thrill.

(Hopefully, it won’t take another twelve years to happen again.)

Extra Searchable Meeting Notes

The timing of this post is entirely accidental, but it arrives almost one year to the day since the last time I wrote about work meetings. And the reason I’m writing about this topic today is that I’ve been so swamped with work meetings the past few months, I’ve neglected to write anything here. I finally decided there’s no better way to get back on the horse and force out a blog post than write about what’s top of mind.

So this is about how my note-taking workflow for meetings has evolved since last year.

As I said last May, I take detailed meeting notes that are almost entirely for my benefit. They serve as a fantastic reference source but are also an insurance policy to cover my ass. I don’t mean that negatively about my workplace. Just that we move so quickly with so many different parties involved, I find having a definitive archive of conversations and decisions is invaluable to keep people (including myself) honest and projects on track.

My old workflow of automatically creating a new note for each meeting in Drafts using a standard template worked great – and still does.

But I settled on that workflow in 2019. And then 2020 arrived, and we all went home.

For a long time.

With video meetings being the new norm, I found myself grabbing screenshots of the meeting window to capture shared slides, documents we were collaborating on, and the latest screens the design team was showing off.

So now, in addition to my detailed text notes, I found myself compiling a visual archive of my team’s communication as designs changed and evolved – as Gantt charts shifted over time.

But where the hell do I store all this stuff? And how do I keep it correlated to the notes I was taking?

I tried lots of solutions. My primary requirement was to keep my notes in as much of a plain text format as possible – mostly because I don’t ever want to find myself locked into an app or ecosystem I can’t leave.

For the most part, Ulysses worked pretty OK. I could take notes and drag and drop screenshots (or other attachments) into the editor and feel good that it was storing everything as future-proof .textbundle files under the hood. But for reasons I don’t want to bore you with (because Ulysses really is a fantastic app – I’m typing this in it now), I wanted something better for accumulating reference material more than a pleasant writing environment.

It turns out, a great solution was hiding in plain sight. DEVONthink.

I’ve used DEVONthink for over a decade to archive documents (primarily PDFs), ebooks, and other long-term storage material. All the stuff that would be in a fire safe. It has incredible search capabilities that always help me find exactly the document I need. It just never occurred to me that power could be applied to my meeting notes as well.

So how am I getting my meeting notes into DEVONthink, how do they remain future-proof, and how am I also keeping those notes tied together with my newfound love of screenshotting video meetings, too?

First off, I did have to make one significant compromise (sort of). As you’ll see, my meeting notes still start as Markdown in Drafts but get converted into .rtf. Is that what I want? Meeehhhh, no. But I can live with it. There are enough tools (most of them scriptable) if I ever need to do a mass-exodus from .rtf back to plain text. Worst case, I could go RTF → HTML → Markdown or something awful like that.

Anyway, the benefits I’ve discovered with this workflow have so far outweighed my long-standing grumpy-old-man-get-off-my-lawn attitude when it comes to Plain Text All The Things™️.

Here’s my workflow.

Like last year, I have an iOS shortcut I run each morning that loops through my work calendar and creates a new note in Drafts for each event using a standard template.

Each empty note is tagged with meeting in Drafts to keep them hidden from cluttering up my day-to-day notes using a workspace filter.

Whenever a meeting starts, I switch to my Meetings workspace in Drafts, which shows all of my notes for the day. I select the appropriate note and type away.

If I need to screenshot anything during the meeting, I just ⇧⌘4, and drag the little floating capture preview into a folder on my Desktop where I keep any pictures or other attachments for that meeting.

Much like cleaning up your Inbox at the end of the day, I reserve 15 minutes before I shut down to process the notes I took that day.

I send all of my meeting notes from Drafts into DEVONthink using a “Send to DEVONthink” action that imports them to the app as Markdown (not plain text).

This drops them into my database’s Inbox. I have a Smart Rule in DEVONthink that automatically converts any new Markdown files into rtf.

This trashes the original Markdown file and leaves a formatted rich text document in its place.

If a meeting note has no files associated with it, I file it away into the folders I use for meeting notes. (I keep them sorted into year/month folders.)

But, if a note does have attachments, that’s when the nerdy fun starts.

In DEVONthink, I select the note and run the Group Items command. This moves the note into a new folder by itself.

Next, I drag the attachments (mostly screenshots) from the meeting folder on my Desktop into that DEVONthink group.

But, wait!

As you’re going to see, I want these attachments ordered chronologically – especially if they’re screenshots – as I captured them. That way, they make sense when I review them in my notes, and they’re not out of order.

What I need to do is sort them by date created rather than filename. As I wrote about last year, I don’t trust file timestamps. It’s too easy to mess those up. I prefer to always sort by filename. So…

I built a tiny little Mac app to handle this next step. I’m sure it could be done with a shell script or some other type of macro, but this was just faster and is super convenient to run.

All I do is drag and drop my folder of note attachments onto this app’s Dock icon, and it renames each file by adding a numeric prefix to make sure they stay sorted by date.

It starts naming at 000 and counts up to 001, 002, etc., leaving the original filename in-tact after the numeric prefix.

Watch:

Boom. Now the files will remain sorted chronologically even if I mess up their timestamps, moving them around in the future.

Here’s the entirety of that little Mac app:

Then I drag them into the folder in DEVONthink with the note.

But here’s the real magic of this whole system. The part that makes it so powerful.

So many of the screenshots I take are presentations, slides, and other documents people are screen sharing. With DEVONthink’s full-text search capabilities, when I’m trying to find an old meeting note months from now, it would be fantastic if I could search inside those screenshots.

With DEVONthink, I can.

Let me explain what I just did.

  1. Drag the meeting screenshots into DEVONthink alongside the meeting note.
  2. Covert them to searchable PDFs. With this command, DEVONthink will create a PDF from each image and OCR any text inside the image and make that text both searchable and selectable/copyable within the PDF itself.
  3. Select all the screenshots and the note.
  4. Merge them into a single .rtfd file that contains my meeting notes and each PDF embedded inside.

What’s the point of doing this?

  1. Now, my notes are kept together with any file attachments I captured.
  2. ALL OF THE TEXT – whether the notes I typed during the meeting or the text contained in the screenshots – is now fully searchable in DEVONthink.

A year from now, when I’m trying to find my notes about a long-ago meeting, I can surface that reference material by searching for text that someone else was presenting on screen in addition to anything I wrote down myself.

Having this capability feels like a secret weapon or a cheat code for finding material that other people talked about beyond my personal meeting notes.

Like I said above, moving away from having all of my notes in plain text made me feel uneasy at first. But I’m confident enough in .rtf and my ability to get my data back out if I ever need to that I got past my obsessive hangups once I realized just how damn useful it is having all of my historical reference material accessible in the future.

Finder Catalog Numbers

Stick with me, folks. This is going to get super nerdy and may take a while to explain. It’s also going to cover some of my favorite topics: a custom-built Mac app, a small server-side script, Keyboard Maestro, the command line, and URL schemes.

Let’s talk about the stuff you need to do and the files, supporting documents, and reference material you need to accomplish those tasks. Here’s a quick example:

This week I need to prepare a PowerPoint slide outlining our upcoming development timeline and include it in a review deck for the executive team.

Easy, right? But what files do I need to build it?

  • an OmniOutliner document that lists our upcoming milestones
  • the PowerPoint slide template
  • a screenshot of those milestones plotted on a calendar
  • a PDF exported from Jira that totals up the development estimates my team added to each ticket
  • the OmniGraffle document I’m going to build this in before exporting to PowerPoint

Here’s the problem I’m trying to solve. For my own dumb, neurotic reasons, most of those files live in different places.

  • The calendar screenshot is in a dedicated ~/Dropbox/Photos/Screenshots/ folder where every screen capture gets saved automatically by CleanShot X.
  • Because I’m old-school and settled on Omni Sync Server years ago, all of my OmniOutliner and OmniGraffle documents live in ~/Documents/Omni/.
  • The Jira PDF is on my Desktop because I just now exported it.
  • And that PowerPoint template is in a folder full of branding guidelines for work.

That seems typical, right? Everyone has an organizational structure that makes sense to them.

Let’s say I find and gather all those documents to get this slide made. Two weeks go by. Oh, shit. Someone on another team needs the slide for their presentation, but with the information slightly tweaked to reflect schedule changes since I created it.

Where did I put all of those source materials? I can guess where the OmniFiles are. But which screenshot was it? And that PDF was on my Desktop two weeks ago, but where did I end up storing it? Do I even still have it?

That’s the problem I started trying to solve for myself and my workflow last Fall: The issue of keeping track of disparate files that all relate to one another through a common task or goal.

Here’s what the solution looks like from my day-to-day point of view. I’ll explain the mechanics in a bit.

What just happened?

In the notes field of that OmniFocus task, I added this URL: clog://RTH2285. (clog stands for “Catalog”.) And when I clicked on it, it revealed all of my reference files in the Finder.

One immutable URL from any app can open any number of associated files – even if they change locations.

I’ve been using this pattern to tie together related files for the past few months. I’ll catalog files as I create them or receive them (more on that in a moment) and then typically begin my working session on a task by summoning them all forward from a common starting point that contains the magic URL.

Sometimes that starting point is an OmniFocus task, as shown above. Other times it’s a note in Drafts or Ulysses. But it could be any app (or command line, as you’ll see) that can open a URL. It also (to a degree) works on iOS.

I’ll start by explaining this from my (the user’s) perspective and then describe the technical details at the end and link to where you can get the code to do this yourself.

At the heart of this workflow is what I call a catalog number. Each unique number groups a set of related files. Catalog files are in the format [a-zA-Z]{3}[0-9]+. That’s three letters followed only by digits. The first three letters are up to you. They should be uncommon enough not to produce false matches with real words (hold on to that thought).

I chose the prefix RTH (my initials) for my catalog numbers since that combination doesn’t come at the start of any common words. So, example numbers in my system might be:

  • RTH2378
  • RTH4591
  • RTH7730

The numeric portion can be random if you want, but I suggest that it always increments upwards as you assign new numbers. At a high level, that lets me see what order the numbers were assigned – which can occasionally be helpful.

Anyway, once you have a catalog number (again – I’ll explain more of those mechanics soon), you need to assign it to a file. About a month before starting on this system, I wrote another blog post in October titled Dot Dee Tee that explained my habit of adding the current date into my filenames as a sort of embedded reference point.

These catalog numbers are similar. The numbers go into the filename. (And file contents, too, as I’ll show.) In my PowerPoint slide task from earlier, my reference files are named:

  • Schedule Screenshot RTH2285.png
  • Exec Slide RTH2285.graffle
  • Project Milestones RTH2285.ooutline
  • Schedule Screenshot RTH2285.png

By putting the catalog number into the filenames like a tag (yes, congratulations to me, I invented tagging a mere 29 years after Finder labels, and then OpenMeta, Mavericks, etc.) I can find those files no matter where they move. It also guarantees that the catalog number won’t be lost if synced to a cloud service or zipped up into an archive format that wouldn’t otherwise handle proper filesystem tags.

As I said before, I prefer that my catalog numbers always increment up as I create them. This also makes sure I don’t reuse one if I were generating them at random. But how to keep track of which catalog number comes next? How do I even know what the current one is? Especially if I want this to work cross-device between multiple Macs and iOS devices?

Enter the world’s smallest web service.

Here’s the entire PHP script I’m hosting on my webserver:

What that does is, if I go to this URL:

https://mywebsite.com/catalog/

it prints out the current catalog number contained in the counter.txt file on my server:

RTH1005

If I load that URL again, it will show the same number.

But if I load

https://mywebsite.com/catalog/?new

it will increment and save the number and print

RTH1006

It’s just an extraordinarily simple counter hosted on a web server so I can access it from any device and stay in sync.

I hear what you’re saying. Having to load a web page just to get a new number every time is cumbersome and slightly insane. I agree. That’s where Keyboard Maestro takes over.

Wherever I am, in a text editor, the Finder, anywhere, if I type

.cat

(which stands for catalog) Keyboard Maestro will detect that phrase, make a call to my web service to retrieve the current catalog number, and replace what I just typed with the number.

If I type

.ncat

(which stands for new catalog) the same thing happens. Keyboard Maestro increments the number and returns the new one.

Here’s a real example of tagging a file in Finder.

When I want to summon a group of related files, if I’m not in an app where I can click the magic URL, I can again use Keyboard Maestro. This time, instead of tagging a file, it prompts me for the catalog number to create and open the particular URL on the fly and reveal my files.

Ok.

  • All of my related files are grouped with a shared catalog number.
  • The current and following catalog numbers are kept in-sync using a straightforward web page to track the current and next number to use.
  • Just put the catalog number into the filename for safekeeping.
  • And a URL in the format of clog://RTH12345 will somehow reveal all of those files for me so I can get to work.

How?

The lynchpin in all of this is a tiny little Mac app that has no UI. It just runs in the background. The whole thing is less than 100 lines of code and takes about 10MB of RAM. (Not GB. Not hundreds of MB. 9.6MB. Like I said, tiny. (By today’s standards.) It doesn’t really do anything.)

It registers the clog:// URL scheme with macOS. And when one of those URLs is opened and matches the correct ABC12345 pattern, it will run a quick Spotlight search for any matching filenames. If found, it reveals each of them in Finder.

That’s it.

There’s also a command-line version. Which lets you reveal files like this

clog RTH2285

Or, you can also do

clog --list RTH2285

which will output this

/Users/thall/Somewhere/Project Milestones RTH2285.ooutline
/Users/thall/Somewhere/Exec Slide RTH2285.graffle
/Users/thall/Somewhere/Schedule Screenshot RTH2285.png
/Users/thall/Somewhere/2021-03-26 Dev Estimates RTH2285.pdf

instead of revealing the files.

I mentioned two sort-of-bonus-features earlier.

  • Full-text search
  • iOS support

There’s a hidden option that will find files that have the catalog number inside their contents instead of just a matching filename. For example, if you are in the habit of keeping an archive of plain-text Markdown notes, you can put catalog numbers inside the Markdown files, and the system will find those.

To do this, you need to end the URL with a Z . Why the letter Z? Just because it’s easy to type on a US English keyboard. So, instead of

clog://RTH2285

you would use

clog://RTH2285Z

and that will instruct the Catalog app to have Spotlight look inside your files.

As for iOS, there are two integration points.

  • Using catalog numbers in your apps
  • Finding matching documents

I’ve set up two Shortcuts and put them in widgets on my home screen. One that grabs the current catalog number and copies it to the clipboard. And the other generates a new one. Then, I can paste them into whatever app or document I’m working with.

Typically, those documents get synced to my Mac. If so, then they’re available there. But I can also search on iOS as well (to an extent).

If you have files in iCloud Drive, you can pull down Spotlight, enter the catalog number, and jump over to the Files app showing your documents.

The same thing works if you keep your files in Dropbox, Google Drive, etc.

So that’s the odd system I’ve been using to jump between tasks and all of their supporting documents. It’s served me well for a while now, along with still using my filename + date strategy, and now I’m open-sourcing the Mac app and PHP script that glue it all together.

I wish I had a better name for the project other than FinderCatalog, but as the old saying goes…

The source code is available on GitHub.

Feedback is welcome.

Mortal Mac App Sins

I apologize upfront for this post. I’m in a mood tonight.

One specific UX sin interrupts my workflow and annoys me more than anything else on macOS.

Applications that quit when you close their primary window.

I want to call out a few of those apps now before offering my dumb solution.

The first is TweetDeck. And I get it. I know it’s some horrible desktop + web app amalgamation, and I should be thrilled a large company is even acknowledging that desktop computers exist. On the other hand, honestly, it’s pretty good at what it does. I’m mostly OK with it being a web app since it’s just a wrapper around a website that is itself a wrapper around a web API. Fair enough.

But why? Why did that product team decide it was OK just to quit the entire app if you ⌘W or otherwise close the window?

Once the app is gone, you stop receiving notifications, which seems the app’s point, no? And then when you do relaunch it, you’re hit with the loading delay while the UI hydrates all over again. (Yes, it’s a web app. That’s how these things work.)

I guess I’m just baffled why you would obviously put some amount of care and attention into even making a desktop app wrapper available if you’re not going to go one or two steps further to make it fit the platform more naturally.

Functionally, for TweetDeck, ⌘Q and ⌘W are equivalent.

Why even have that neutered File menu with a redundant menu item at all? (I know why.)

While I’m at it, what’s that extra Close menu item doing in the Window menu? Or the native macOS Tab Bar that doesn’t work but can still be shown?

I expect better from companies with so many resources. Even if we are talking about a side-project (and pretending the really nice native Mac app they killed never existed).

So that’s what grinds my gears this evening. Apps that quit when you close their windows. Scanning my /Applications folder, we can add these offenders to the list:

  • Plexamp (Electron sigh Will someone please make a nice Plex music app for macOS?)
  • Apple Books (just bizarre and wonky)
  • FaceTime (admittedly an odd one)
  • Find My (no good excuse)
  • Home (no good excuse)
  • Reminders (really no good excuse)
  • Photos (also no good excuse at all)

Maybe I’m just an ornery old man yelling at the new kids running through my lawn. Maybe I should be content to retrain myself to hit ⌘H instead of ⌘W when I no longer want to see a non-document-based app but want to keep it running.

Maybe Apple has done the research and realized that a decade-plus of relearning computers with iOS had taught the over-60 crowd that fullscreen apps are the be-all-end-all. And Gen-Z, who grew up with touch screens, intuits that as well. Maybe there are diminishing numbers of us in the middle reluctantly dragging overlapping windows around like cave people?

But my (least?) favorite. The most hysterically bad example that I want to point out is Microsoft Teams.

(OK, funny sidebar. You know they’re pushing this app down customers’ throats when what you think would be the Teams website at

https://www.microsoft.com/en-us/microsoft-teams/

redirects to

https://www.microsoft.com/en-us/microsoft-teams/group-chat-software/

(Even $1.3T companies gotta SEO.)

Of course, Teams is Electron-based. So, of course, it comes with all the caveats and compromises that Electron brings. OK, fine.

I want to drag this app because I truly have so much respect for Microsoft software historically. The Office suite is just a mind-blowing multi-decade achievement in my mind. And in recent years, getting all that business logic ported competently to iOS and the web is astounding. The backward compatibility that Windows is forced to maintain while somehow moving forward is inspiring. And while using Visual Studio Code makes me want to gouge my eyes out and write novels in a log cabin far off the grid, I really do respect what they’ve built.

So please, compare what Microsoft can do against Teams.

For so many reasons, it is a nightmare of awfulness that should make my workday better but really only gets in the way. And here is the most glaring fault that convinces me no one who cares or knows better is really using the app as customers do. (Or is empowered to make a difference.)

  1. Use Teams.
  2. Resize and position the one window they limit you to using.
  3. Close that window.
  4. Re-activate Teams by either clicking the Dock icon or using a launcher like Spotlight, Alfred, etc.

OK, first of all. Teams does have the courtesy of not quitting when the window is closed. But rather than reopening the only window where you last placed it or even reopening it to some sane default size and position, it reopens in…full screen.

Not macOS Full Screen that takes over the entire screen – Dock, menu bar, and all. But maximized. What people used to call full screen. Just, boom. Hello. Taking up every pixel of available space.

I would normally share a screen recording of this happening, but everything in Teams is work-related, and I don’t want to start spreading company secrets. (And blurring out an entire window would be silly.)

So, please. Microsoft. Do better. I know you can.

And for all the other big companies out there. Please start caring again. When you take care out of the work, wrapping your web app into a desktop app is no better an idea than ticking a box and thinking your iOS app will make a good Mac app.

Anyway, here’s my fix. And, once again, Keyboard Maestro to the rescue.

I have a special macro group called Stupid Fucking Misbehaving Apps that only applies to a select group of software.

And in that group, a single macro titled Hide Because ⌘W Doesn't Fucking Work The Way It Should.

All it does is override ⌘W to hide the app instead of whatever broken behavior it would normally do.

I should have thought of this years ago.

Calendar Hero

Let’s be honest. I’m an idiot. If it weren’t for technology holding my hand and functioning as a second brain, I wouldn’t be able to make it through this modern world.

That’s why I trust software to remember all the things I would otherwise forget.

And with the number of meetings I’m in now, it really helps if my calendar is front and center.

So, another week, another app. This time it’s a small little open-source calendar for your macOS Desktop I call Calendar Hero. I made it last week after I was late to a meeting because, well, I was vacuuming and not thinking about the day ahead.

I used another Mac app to do this, but it stopped working for me sometime during Catalina in 2019. I missed what it did, so I reimplemented a simple version of it last week.

This is Calendar Hero.

It sits on your Desktop, below all of your other windows, and…shows your weekly calendar. It highlights the current day, the current hour of that day, and shows a countdown until your next event.

That’s it. That’s all I want.

I will live and die and swear that Fantastical 3 is the best Mac app I’ve ever used. But for this one particular use case where I want my calendar front and center, just an F11 glance away, Calendar Hero is what I want.

Here’s how it works.

  • Open the app
  • Move and resize the window where you want it
  • Do something else

That’s it. When Calendar Hero loses focus, the window will become transparent and settle onto your Desktop. You can move other windows on top of it. You can even position your Desktop files and folders on top of it. Your mouse and keyboard clicks will be ignored. And it’ll stay in place as you swipe between spaces and Exposé. It just sits there being helpful.

If you need to reposition Calendar Hero, click its Dock icon or ⌘-tab to it. The window will become normal again, letting you resize it until you switch to another app.

That’s it. That’s the whole thing.

Calendar Hero is free to use, and the source code is available on GitHub. I hope you find it helpful.

You can download a notarized build here. I’ve only tested it on Big Sur, but it should run on Catalina.

Technical Notes

Calendar Hero is a very dumb app. I did not write it to be perfectly correct. If you look closely, you’ll see that the event bubbles are not always to scale. That’s because I just wanted to build something very quickly that solved my problem: seeing what’s next. Seeing a perfectly accurate and proportional view of my day was not the goal.

The app is built using a giant mess of stack views because that was the fastest way to make this app and get on with my real work. I just let them do their thing, and it looks mostly OK.

Also, anything involving dates and calendars scares the crap out of me. If your Mac is set to use a non-Gregorian calendar, or the first day of your week is not Sunday, I cannot promise this app will not eat your hard drive.

TextBuddy for macOS

You either die a programmer, or you live long enough to see yourself build a text editor.
—Harvey Dent (or someone)

Good artists copy. Great artists steal.
—Probably not Harvey Dent

Two weeks ago, I released TextBuddy – a new text editor for macOS. And now I’m finally getting around to sharing why I built it.

It started as an “ugh, I wish I had a small little app that did this” thought going through my head. And followed soon by “Ok, I can make that really quick.”

Sure enough, I had something passable by lunch. But then my dumb brain was like, “Hey, it sure would be great if it also did this…Oh, and this, too…And that!”

As I explained to a friend in an email:

Programmers know all too well where that line of thinking ends. (Hint: madness) In my case, it ends with this blog post announcing TextBuddy.

I typically bounce around between three text editors throughout the day.

Ulysses is where I keep meeting notes and draft long-form writing since it excels in being a very comfortable writing environment, handles Markdown well, and supports file attachments. (I’m writing this post in it right now.)

Drafts is where I jot down quick notes, ideas, and triage ad-hoc to-do lists. While some of my drafts grow larger and graduate to Ulysses, most of the stuff I capture might be considered “throw-away” by other people. Still, to me, Drafts has become this massive, chronological archive of all the ideas I’ve had every day over the last decade or so. Computers are powerful, storage is cheap, and having that corpus of my historical train of thought is a powerful weapon for knowledge workers.

And then, of course, there’s TextMate. Which, for sixteen years, has been my go-to editor for manipulating text.

But now and then, I’ve felt a need for something to drop truly temporary text into — a staging ground to do a few quick edits before taking that text elsewhere. There’s mental overhead to using those other three apps.

Ulysses, while incredibly powerful, is slow and cumbersome to move around. TextMate, being a document editor, requires thinking about files. Making a new one, and then choosing where to save the file or discard my changes. Drafts solves the problem of thinking in files, and I know it’s a fine line, but there’s an obvious (to me) category of “stuff” that I don’t want polluting my Drafts library, which means I need to think about deleting any temporary drafts I create.

I fully realize the above must sound insane to a lot of people. But going back to the old Getting Things Done philosophy of “mind like water,” the fewer decisions I have to make about unrelated tasks while focusing on my work, the better job I can do at the stuff that matters.

So, I found myself in need of a middle ground app between Drafts and TextMate.

TextBuddy is what I came up with.

What started on January 14th as a single text field in a window that automatically saved what you typed kept growing.

The app now offers over 130 nerdy, plain-text commands you can run with a keystroke or two. From Unix-y shell script type stuff to common tasks programmers use daily to crazy workflows like capturing text from screenshots and images and even transcribing spoken words from audio and video files. (All done locally. Nothing sent over the network.)

And it syncs over iCloud, too.

I’m also excited to say that, over the last two weeks, TextBuddy has become the most well-received app I’ve ever built.

VirtualHostX is my main app. It’s the cornerstone of my little software company, and over fourteen years has been a large (and small) source of my income.

And, yet, TextBuddy has already had more downloads in thirteen days than VHX had in all of 2020.

(Should I use 😭 or 🤷)

I don’t say that to announce my retirement to a tropical island (I prefer the mountains anyway), but to say that it feels amazing to find out I’m not crazy. To learn that there are lots of other nerdy people out there like me who find use in an app that I originally built just for myself.

How can you not feel like you’re onto something when the Internet’s Resident Mad Scientist says

I tried it out for 5 minutes and immediately purchased.

I could probably go on for ten-thousand words about all the random ways I find TextBuddy helpful throughout the day. But if you’re interested in hearing that, go check out the website.

Instead, I’ll leave you with this 42-second intro of a typical text editing session with TextBuddy. And then a couple of videos of what I think are some fun features.

TextBuddy requires Big Sur and is free to download and use. Like my other app, Ears, you can optionally support TextBuddy at one of three tiers to remove the nag screen at startup.

Any feedback you have is very much welcome.

42 Second Intro

Rearranging Text

Capturing Text From Screenshots

Transcribing Text from Video and Audio Files