Skip to content

Releases

v2.3.0

Choose a tag to compare

@theshiver theshiver released this 04 Nov 20:35
  • New: you can hide a meeting from the menu bar once it has started, right away or after 5, 10 or 15 minutes. Find it in Settings under Menu bar. By default nothing changes.
  • Fixed: turning off reminders only hid them from the list. "Show reminders" now removes them from the menu bar, notifications and full-screen alerts too, and it has moved to the Alerts section of Settings.

v2.2.3

Choose a tag to compare

@theshiver theshiver released this 02 Nov 07:25
  • Fixed: a full-screen alert left on screen while your Mac slept was still there when you woke it, even after the meeting had ended. Slapss now closes the alert once the meeting is over.
  • After you've joined a few meetings with Slapss, it may ask once per version whether you'd like to rate it. The question is Apple's standard rating prompt, it shows up when you open the menu bar popup and never on the full-screen alert, and macOS shows it at most three times a year.

Thanks to @shawnburke for reporting the stale alert (#7).

The App Store update is on its way. Once it's live: https://apps.apple.com/app/id6767488326

v2.2.2

Choose a tag to compare

@theshiver theshiver released this 12 Oct 17:54
  • Fixed: snoozing the full-screen alert brought it straight back when the snooze was shorter than your Show alert time (for example, snoozing 3 minutes with the alert set to 10 minutes before). Snooze now waits the time you picked.
  • Fixed: Slapss kept your Mac from going to sleep on its own while it was running. Your Mac now sleeps on its normal schedule again, and when it wakes up, Slapss still shows any meeting that started while it was asleep.
  • Slapss now speaks Ukrainian. You can pick it in Preferences, and it's chosen automatically on first launch if Ukrainian is your Mac's language.
  • Join Yandex Telemost meetings directly from links in calendar event descriptions and locations.

Thanks to @kedrzu (#6), @Alozavr (#3) and @Disconnecter (#4) for their contributions.

The App Store update is on its way. Once it's live: https://apps.apple.com/app/id6767488326

v2.2.1

Choose a tag to compare

@theshiver theshiver released this 25 Sep 11:25
  • The Show alert setting is now a menu instead of a slider: at meeting start, 10 or 30 seconds before, or 1, 2, 5, 10 or 15 minutes before. Custom… covers anything in between, from 5 seconds to 15 minutes. If you had picked a time that isn't in the menu, it stays exactly as it was and shows under Custom.
  • You can now switch off the alert for meetings by keyword. In Preferences, General, Alerts, add words like "Lunch" or "PTO" under Don't alert for meetings containing. A meeting whose title has one of them gets no full-screen alert and no heads-up notification. It stays in the menu bar agenda, marked "No full-screen alert". Words match at the start of a word and ignore capitals and accents, so "lunch" catches "Team lunch" but not "Brunch".
  • The Join button now works when your company's email security has wrapped the meeting link: Microsoft Safe Links, Proofpoint URL Defense and Barracuda Link Protection. Slapss unwraps the link on your Mac, without any network request, and opens the meeting directly, Teams meetings in the Teams app. This skips the security scanner's click-through page, and only happens when the link inside is a Zoom, Teams, Google Meet, Webex, Whereby or Around meeting. Mimecast links can't be unwrapped without contacting Mimecast, so they still aren't recognized.
  • Fixed: the alert timing read "1 minutes before".

The App Store build is in review. Once approved: https://apps.apple.com/app/id6767488326

v2.2.0

Choose a tag to compare

@theshiver theshiver released this 23 Sep 05:44

A release about how Slapss looks and feels.

  • A new app icon: the same Slapss hand, now on the warm sunset colors of the new look, with the proper rounded macOS shape. The menu bar icon was redrawn to match.

  • The full-screen alert now glides in and fades out instead of snapping on and off. The card rises into place and its contents follow one after another.

  • The status at the top of the alert changes with the meeting: a clock while it's still a few minutes away, a ringing bell in the last minute, green once it has started, orange when you're late. The countdown numbers roll instead of jumping.

  • The background comes alive as the meeting gets closer. Once it's about to start, a glow runs around the edge of the card and a sweep of light crosses the Join button.

  • If you're running late, the card gives a small shake to get your attention.

  • The Snooze menu springs open, with its options cascading in.

  • Pressing Return now visibly presses the Join button, the same as clicking it.

  • The menu bar popup has a new look to match the alert. The next-meeting card now carries the same colors as your full-screen alert and comes alive as the meeting gets close: in the five minutes around the start, a glow runs around it and its Join button catches the light. The countdown rolls from minute to minute, and the Join button opens the meeting straight away.

  • Meetings in the list show their calendar's color, and the popup's cards and buttons share one cleaner style.

  • The welcome window now names the right step when it asks you to allow calendar access (it always said step 1, but that step moved to 3 when language and theme were added in front of it). Fixed in all seven languages.

  • The welcome window and Settings follow the same look. The theme picker now shows a preview of each theme's actual full-screen alert, and Settings → About has a small brand card.

  • Fixed: after you opened the menu bar popup once, its animations kept running in the background after it closed, using battery for nothing. They now stop as soon as the popup closes.

  • The full-screen alert keeps its dark look even when your Mac is in light mode, so the text on it stays easy to read.

  • All of this motion switches off when Reduce Motion is on in System Settings.

  • Slapss now needs macOS 15 Sequoia or later. On macOS 14, the App Store keeps offering version 2.1.1.

The App Store build is in review. Once approved: https://apps.apple.com/app/id6767488326

v2.1.1

Choose a tag to compare

@theshiver theshiver released this 11 Sep 11:11

Two emails and an afternoon of using the app with two test meetings running side by side. One of the emails came with a screenshot of a Zoom logo where a meeting should have been.

Install: Mac App Store — free, no subscription, no account.
2.1.1 is on its way through App Store review; until it is approved that link still installs 2.1.0.

Changes in 2.1.1

  • Fixed: for some Zoom invitations the Join button opened a small Zoom logo image instead of the meeting. Zoom's Outlook add-in puts that logo above the join link in the invitation, and Slapss was picking up the first Zoom address it saw. It now skips images and other page assets and finds the actual join link.
  • Snooze now offers 30 minutes and 1 hour on top of 1, 5, 10 and 15 minutes.
  • Fixed: the snooze menu on the full-screen alert was cut off at the top of the card, hiding the shorter options.
  • Fixed: when two meetings overlap, the menu bar agenda showed only one of them. The other was neither "later" nor "earlier", so it dropped out of the list entirely. Meetings running right now that aren't the highlighted one are listed under Later today.
  • Fixed: a reminder you hadn't completed dropped into Earlier today once its time passed, greyed out and drawn as if it were done. It now stays at the top of the list, marked with how long ago it was due, until you complete it. Earlier today is for finished meetings only.
  • Every meeting in the agenda that has an online link now has a small Join button on its row, so you can jump into a meeting that is running in parallel, or one that starts later, without expanding it first. Finished meetings don't get one.
  • Slapss now speaks Japanese. Contributed by @satotakumi in #2, the first outside contribution since the app went open source.

About the Zoom bug

MeetingLinkDetector scans an event's notes, location and URL with one regex per provider, first match wins. The Zoom pattern is [a-zA-Z0-9.-]*zoom\.us/…, which matches us06st2.zoom.us/static/…/ZoomLogo_110_25.png just as happily as us06web.zoom.us/j/…. HTML invitations from the Zoom Outlook add-in carry that logo image above the join link, and the image URL survives into the plain-text notes macOS Calendar hands over. The detector now walks every match and skips URLs whose path extension is a static asset. The regex was deliberately not narrowed to /j/, /w/ and friends: skipping a known-bad shape is safer than enumerating every join variant Zoom has ever produced.

v2.1.0

Choose a tag to compare

@theshiver theshiver released this 07 Sep 11:20

A user turned on "Show the next meeting in the menu bar", looked up at 10:30 with an 11:30 meeting ahead of him, and saw nothing but the Slapss icon. He asked whether the lead-time picker was the cause, since it stops at 30 minutes. It wasn't, and the real answer was less defensible.

Install: Mac App Store — free, no subscription, no account.
2.1.0 is on its way through App Store review; until it is approved that link still installs 2.0.1.

Changes in 2.1.0

  • The menu bar can show your next meeting further ahead. It used to appear only once the meeting was within 15 minutes, so anything further out showed just the icon.
  • New setting: Preferences → General → Menu bar → Show the next meeting. Off for just the icon, When it's close to follow your lead-time setting, or Anytime today to keep the next meeting you have left today in view however far off it is.
  • Meetings more than an hour away show their start time instead of a countdown, so you get Standup · 11:30 rather than a minute count that means nothing at that distance.
  • The old behaviour is still the default. When it's close is what you had, with one difference: it now respects your lead time, so a 30 minute heads-up shows meetings 30 minutes out instead of 15.

About that horizon

The menu bar label and the popover's hero card are both driven by AlertScheduler.priorityMeeting, deliberately, so the two can never disagree about which meeting is "current". It picks in three passes: a meeting starting within 5 minutes wins outright, then whatever is currently running, then the soonest one still ahead.

That third pass was written as untilStart > 5 * 60 && untilStart <= 15 * 60. The 15 was a literal. No setting reached it, nothing in the app mentioned it, and the toggle beside it just said "show the next meeting" with no qualifier. So the behaviour was intended and the report was still correct: an app that promises the next meeting and then silently defines "next" as "within a quarter of an hour" has misled you.

The bound is now a horizon parameter, and its default is the interesting part. It stays at 15 minutes, and only the menu-bar call passes anything else. Widening it globally would have dragged the popover's hero card along, and that card is answering a different question — what is happening now, not what is left today. Same function, two callers, two horizons.

The 5-minute floor stayed fixed. It looks like a visibility setting and isn't one: it is the boundary that lets an imminent meeting preempt a running one, so it has to hold however wide the horizon gets.

Anytime today clips at the start of tomorrow rather than running unbounded, because the aggregator fetches 24 hours ahead — without the clip, a 22:00 glance would have shown you tomorrow morning's first meeting as though it were still today's problem.

One thing worth knowing if you had it switched off

The setting used to be a boolean and is now a three-way choice. Your existing preference is migrated: on becomes When it's close, off becomes Off. Off now also removes the meeting title from the right-click menu and the "hide from menu bar" link in the popover, both of which used to appear even with the label hidden. There is no label left to hide, so they had nothing to act on.

Notes for this repository

  • Code is Apache-2.0. The Slapss name and icon assets are not — see TRADEMARK.md.
  • Building requires Xcode 26 or later; older versions fail with actor-isolation errors. See README.
  • No binaries are attached. The only official build of Slapss is the App Store one.

Full history: CHANGELOG.md

v2.0.1

Choose a tag to compare

@theshiver theshiver released this 25 Aug 05:47

A Microsoft 365 user wrote in: the menu bar was counting down to his next meeting, but opening it showed "Calendar access denied" in red instead of his agenda. He doesn't use Calendar.app at all. Both halves of that sentence turned out to be the diagnosis.

Install: Mac App Store — free, no subscription, no account.
2.0.1 is on its way through App Store review; until it is approved that link still installs 2.0.0.

Changes in 2.0.1

  • Fixed: your agenda was hidden if you use Microsoft 365 and haven't granted macOS calendar access. The menu bar showed the meeting; opening it said access was denied. Access to the macOS Calendar app is optional, and always was.
  • Fixed: Microsoft 365 calendars could stop refreshing in the background — while a menu was open, or after macOS put Slapss to sleep. New and changed meetings arrive on time again.
  • Slapss no longer asks macOS for read-only access to files you pick yourself. Nothing in the app ever used it.

About that bug

CalendarAggregator.permissionState mirrors EventKit only. Microsoft Graph is a separate source with its own sign-in state, and performRefresh fetches it regardless of what EventKit says — so for a Microsoft 365 user with calendar access denied, the meetings were loaded the whole time.

The popover gated the entire agenda on permissionState and swapped in the red denial screen. The menu bar label doesn't gate on anything: it reads the merged event list, which has never been permission-filtered. Hence the split-brain symptom — one surface counting down to a meeting the other claimed it couldn't see. It reads as "the agenda is broken" rather than "a permission is missing", which is exactly how it was reported.

OnboardingView.canFinishOnboarding has had the right rule since 1.8: local calendar access or a signed-in Microsoft account is enough. The popover now short-circuits on the same condition, through a new isGraphSignedIn published on the aggregator. It mirrors graph.$state through Combine rather than hanging off graph.onChange, which fires only on completed sign-in and sign-out — an expired token would have left the flag stuck at true.

Settings needed no change: its denied state, with the "Open System Settings" button, is scoped to the macOS-calendars section, and that is still where you grant the permission if you want Calendar.app's calendars too.

The background-refresh fix is the same story from a different angle. GraphSource's poll was the last Timer.scheduledTimer in the codebase — .default runloop mode, so it stalls while a menu is tracking and App Nap can throttle it. Everything else here uses Timer(...) plus RunLoop.main.add(_:forMode: .common). It matters most for Microsoft 365-only users: EventKit's 30-second safety net is gated on calendar permission and never starts for them, so the Graph timer was their only refresh path.

The fourth entitlement

Up to 2.0.0 the shipped binary carried an entitlement that is not in slapss.entitlements: com.apple.security.files.user-selected.read-only. An Xcode build setting (ENABLE_USER_SELECTED_FILES) injected it at build time. No code path in the app opens a file picker, so it was never used by anything.

Small permission, large claim. The point of publishing the source was to make "your calendar goes nowhere" checkable, and the entitlements are the first thing worth checking. 2.0.1 removes it. Read it off your own copy:

codesign -d --entitlements :- /Applications/slapss.app

Three entries: app sandbox, outbound network client (Microsoft Graph), calendar access. A build you make yourself will also show com.apple.security.get-task-allow, which Xcode adds to non-distribution builds so a debugger can attach — App Store builds don't have it.

Notes for this repository

  • Code is Apache-2.0. The Slapss name and icon assets are not — see TRADEMARK.md.
  • Building requires Xcode 26 or later; older versions fail with actor-isolation errors. See README.
  • No binaries are attached. The only official build of Slapss is the App Store one.

Full history: CHANGELOG.md

v2.0.0

Choose a tag to compare

@theshiver theshiver released this 24 Aug 12:06

Slapss 2.0 is out on the Mac App Store. The source has been public since 1.8.2, so what actually changes here is that the app now points at its own code, and a recurring-meeting bug is fixed.

Install: Mac App Store — free, no subscription, no account.

Changes in 2.0.0

  • Fixed: a repeating meeting stopped showing its full-screen alert after you dismissed it once. Dismissing Monday's stand-up also dismissed every following one, while the menu bar countdown kept working normally. Snoozing and hiding from the menu bar leaked across occurrences in the same way, and are fixed too.
  • Settings → About has a new Source Code link.

Everything else is unchanged. Same features, still free, still no accounts and no tracking.

About that bug

Worth writing down, because the symptom pointed away from the cause.

EKEvent.eventIdentifier is identical for every occurrence of a recurring event — Monday's stand-up and Tuesday's share one identifier. MeetingEvent.id was just "ek:" + eventIdentifier, so an entire series collapsed into a single id. dismissedIDs is insert-only and never cleared, so one dismissal suppressed the whole series from then on: the scheduler skipped every future occurrence and no timer was ever created again.

The menu bar reads the aggregator directly and applies no dismissal filter, so the countdown kept looking perfectly healthy throughout. That is why it was reported as "the full-screen alert never fires for the first meeting of each day" rather than as a dismissal problem — a daily stand-up is exactly what that looks like from the outside.

Event ids now carry the occurrence start time. Microsoft Graph was never affected: calendarView returns per-occurrence objects with distinct ids.

Written up in CLAUDE.md, along with the other macOS and SwiftUI traps this app has run into.

Why 2.0.0 rather than 1.9

The version marks the open-source release for App Store users, who meet it for the first time in the About tab. If you are reading this on GitHub you already had the code at 1.8.2.

Notes for this repository

  • Code is Apache-2.0. The Slapss name and icon assets are not — see TRADEMARK.md.
  • Building requires Xcode 26 or later; older versions fail with actor-isolation errors. See README.
  • No binaries are attached. The only official build of Slapss is the App Store one.

Full history: CHANGELOG.md

v1.8.2

Choose a tag to compare

@theshiver theshiver released this 21 Aug 09:55

First public release of the Slapss source. The app itself is unchanged — this is
the same v1.8.2 that's on the Mac App Store, now with its code open so the
"reads your calendar locally and sends it nowhere" claim can be verified rather
than taken on faith.

Install: Mac App Store — free, no subscription, no account.

Changes in 1.8.2

  • Fixed: Snooze could appear to do nothing on the full-screen alert in macOS 27 beta. The snooze choices now open reliably inside the alert.
  • Fixed: Calendars now reappear in Settings without restarting Slapss after you remove and re-add a macOS Calendar account.

Notes for this repository

  • Code is Apache-2.0. The Slapss name and icon assets are not — see TRADEMARK.md.
  • Building requires Xcode 26 or later; older versions fail with actor-isolation errors. See README.
  • No binaries are attached. The only official build of Slapss is the App Store one.

Full history: CHANGELOG.md