A macOS menu bar app that shows your next meeting at a glance.
- Displays the next meeting time in the menu bar
- Shows "In Progress" when a meeting is currently active
- Popup list of all remaining meetings today
- Auto-detects video conferencing links (Zoom, Google Meet, Teams, Webex, Whereby)
- One-click join button for detected meeting links; Settings sets App vs browser per provider (Zoom, Google Meet, Teams, Webex, Whereby)
- Calendar selection: in Settings, use the Calendars tab to limit which Apple Calendar sources are read
- Refreshes every 60 seconds and on calendar changes
- Daily update check (GitHub Releases) with in-app update link
- Supports English and Traditional Chinese (follows system language)
- macOS 13 Ventura or later
- macOS Calendar app synced with your Google account
- To build with
./build.sh: Xcode Command Line Tools only (~500 MB) — full Xcode is not required - To open the generated
.xcodeproj: full Xcode (Option B)
Open Calendar.app → Preferences → Accounts → add your Google account. ProxiMeeting reads events directly from the system calendar — no API keys or OAuth required.
Install the Homebrew tap (GUI app via Cask):
brew tap dytsou/proximeeting
brew install --cask proximeetingbrew upgrade --cask proximeetingIf the upgrade fails, try:
brew update
brew upgrade --cask proximeeting --verbose
brew reinstall --cask proximeeting
brew doctorIf not using Homebrew, build the app manually.
Option A — Command Line Tools only (no full Xcode app):
-
Install the tools if needed. If
xcode-select --installreports they are already installed, you can skip this; install updates via System Settings → General → Software Update when offered.xcode-select --install
-
Point the active developer directory at the standalone CLI tools (only if
xcode-select -pshows a path insideXcode.app):sudo xcode-select -s /Library/Developer/CommandLineTools
For CLI-only builds,
xcode-select -pshould print/Library/Developer/CommandLineTools. -
Build:
git clone https://github.com/dytsou/ProxiMeeting.git cd ProxiMeeting ./build.sh
The script compiles with swiftc, creates ProxiMeeting.app, and offers to install it to /Applications.
Option B — With Xcode (uses xcodegen to generate the project):
git clone https://github.com/dytsou/ProxiMeeting.git
cd ProxiMeeting
./setup.shsetup.sh installs xcodegen via Homebrew if needed, generates ProxiMeeting.xcodeproj, and opens it.
- Go to Signing & Capabilities and select your Apple ID team
- Press Command+R to build and run
- Grant calendar access when prompted
-
Menu bar app: ProxiMeeting runs in the menu bar and may not appear in the Dock after launch. Look for its icon near the clock.
-
Opening from Terminal: An
.appbundle is a folder, not a shell command. Useopen, for example:open /Applications/ProxiMeeting.app
Or use Finder → Applications → ProxiMeeting. If Homebrew installed to your user folder, try
open ~/Applications/ProxiMeeting.app. -
Gatekeeper (“Apple could not verify…”): Releases are built with ad-hoc signing and are not Apple-notarized, so macOS may show a warning the first time you open the app. This means the binary is not stapled with Apple’s notarization ticket—not that Apple detected malware. If you trust this source, you can proceed: Control-click (or right-click) the app in Finder → Open, then confirm Open; or go to System Settings → Privacy & Security and use Open Anyway when ProxiMeeting is listed. Avoid turning off Gatekeeper entirely for the whole Mac.
You installed ProxiMeeting, it launched, but no icon shows up near the clock — and if you rename the bundle before building (e.g. APP_NAME=MeetingTrayTest make install), the tray suddenly works. That's the telltale sign of stale Launch Services registrations for com.proximeeting.app, usually left behind by interrupted Homebrew cask upgrades (directories like /usr/local/Caskroom/proximeeting/1.3.x.upgrading/ that no longer exist). macOS resolves the bundle id to one of those ghost rows, finds it flagged launch-disabled, and silently no-ops.
The one-liner recovery is:
make reset && make installWhat make reset removes (nuclear — irreversible):
- All on-disk copies:
/Applications/ProxiMeeting.app,~/Applications/ProxiMeeting.app, and the repo-local build artifact (plus theMeetingTrayTestdiagnostic sibling if present). - Stale Launch Services rows for
com.proximeeting.appandcom.proximeeting.app.traytest(via per-pathlsregister -ufollowed bylsregister -gc). - Per-bundle-id state under
~/Library:Containers/,Group Containers/,Preferences/,Caches/,HTTPStorages/,Saved Application State/,WebKit/,Application Support/, and cookie stores. - Calendar and AddressBook TCC grants for those bundle ids — macOS will re-prompt for calendar access the next time the app launches.
- Restarts Dock (~1 s flicker) to reload its Launch Services icon cache. Does not touch
cfprefsdor any unrelated app's preferences.
Before destroying anything, the script prints the detected ghost rows and the exact list of paths it will remove, then asks Continue? [y/N]. Pass --yes (or set PROXIMEETING_RESET_YES=1) to skip the prompt in scripts/CI.
A diagnostic before/after snapshot is written to /tmp/proximeeting-reset-<epoch>.log — if reset-plus-install doesn't fix your tray, attach that file when reporting the issue.
If make reset finishes with Reset INCOMPLETE (exit code 1), either a ghost row survived lsregister -gc or a path needed sudo. The final banner prints the exact next command (lsregister -delete + reboot, or a specific sudo rm -rf).
ProxiMeeting/
├── build.sh # Build with swiftc (no Xcode needed)
├── setup.sh # Generate xcodeproj with xcodegen and open
├── project.yml # xcodegen config
└── ProxiMeeting/
├── ProxiMeetingApp.swift # App entry point + menu bar label
├── CalendarManager.swift # EventKit + video link detection
├── CalendarSelectionStore.swift # UserDefaults: which calendars to include
├── JoinPreferenceStore.swift # UserDefaults: App vs browser per service
├── MeetingMenuView.swift # Popup UI
├── Info.plist # Calendar permission descriptions
├── ProxiMeeting.entitlements # Sandbox + calendar entitlements
├── en.lproj/
│ └── Localizable.strings
└── zh-Hant.lproj/
├── Localizable.strings
└── InfoPlist.strings
| Service | Domain |
|---|---|
| Zoom | zoom.us |
| Google Meet | meet.google.com |
| Microsoft Teams | teams.microsoft.com |
| Webex | webex.com |
| Whereby | whereby.com |
Links are detected from the event URL, notes, and location fields.
Join behavior: Use Settings to set each listed provider to App (default) or Browser. Browser always opens a web-safe HTTPS link in your default browser and closes the panel first. App asks macOS to open the original URL; if no handler is installed, it closes the panel and falls back to the same HTTPS mapping as before (zoommtg:// → https://zoom.us/j/…, gmeet:// → Meet web, Teams/Meet hosts normalized to https, etc.). Links that are not matched to those providers always use the Browser path. Preferences are stored in UserDefaults.
See CONTRIBUTING.md for how to propose changes, build locally, and open pull requests.
- Create
ProxiMeeting/<locale>.lproj/Localizable.strings - Copy keys from
en.lproj/Localizable.stringsand translate the values - Add the locale string to
CFBundleLocalizationsinInfo.plist - Add the lproj path to
resourcesinproject.ymland re-run./setup.sh
