Windows alt-tab on macOS
There are many ways to contribute:
This document gives a technical overview of the project, for newcomers who want to contribute.
This project has minimal dependency on Xcode-only features (e.g. InterfaceBuilder, Playgrounds). You can build it by doing:
scripts/codesign/setup_local.shto generate a local self-signed certificate, to avoid having to re-check the
System Preferences > Security & Privacypermissions on every build
alt-tab-macos.xcworkspacewith XCode, or use the cli:
xcodebuild -workspace alt-tab-macos.xcworkspace -scheme Debugto build the .app with the
If you want to contribute a PR, please run
npm install once. It will add the pre-commit hook to ensure that your commits follow the convention and will pass the PR.
Mac development ecosystem is pretty terrible in general. They keep piling on the tech stacks on top of each other, so you have C APIs, ObjC APIs, Swift APIs, Interface builder, Playgrounds, Swift UI, Mac Catalyst. All these are bridging with each other with a bunch of macros, SDKs glue, compiler flags, compatibility mode, XCode legacy build system, etc. For alt-tab, we are on Swift 5.0. Note that swift just recently started being stable, but overall any change of version breaks a lot of stuff. Swift itself is the mainstream language with the worst governance I’ve seen in modern times.
Regarding SDKs, it’s very different from other (better) ecosystems like Java. Here the SDK is bundled with XCode, and XCode is bundled with the OS. This means that from a machine running let’s say macOS 10.10, you have access to only a specific range of XCode versions (you can’t run the latest for instance), and these give you access to a specific range of SDKs (i.e. Swift + objc + c + bridges + compiler + toolchain + etc)
Documentation is abysmal. Very simple things are not documented at all, and good information is hard to find. Compared to other ecosystem I’ve worked on in the past like Android, nodejs, Java, rust, this is really a bad spot. You can truly tell Apple doesn’t care about supporting third-parties. They are in such a good position that people will struggle and just push through to deliver on their ecosystem because it is so valuable, and because they don’t have to care, they don’t. They could pay an intern to update the docs over the summer for instance, just to give you context of the lack of care we are talking about here.
Dependencies were historically never handled by Apple. The community came up with Cocoapods which is the de-facto dependency manager for Apple ecosystem projects these days, even though Apple is now trying to push their own.
OS APIs are quite limited for the kind of low-level, system-wide app AltTab is. This means often we just don’t have an API to do something. For instance, there is no API to ask the OS “how many Spaces does the user have?” or “Can you focus the window on Space 2?”. There are however, retro-engineered private APIs which you can call. These are not documented at all, not guaranteed to be there in future macOS releases, and prevent us from releasing AltTab on the Mac AppStore. We have tried my best to document the ones we are using, as well as ones we investigated in the past.
To mitigate the issues listed above, we took some measures.
We minimize reliance on XCode, InterfaceBuilder, Playground, and other GUI tools. You can’t cut the dependency completely though as only XCode can build macOS apps. Currently, the project has these files:
alt-tab-macos.xcodeprojfile describing AltTab itself. It contains some settings for the app
alt-tab-macos.xcworkspacefile describing an xcode workspace containing AltTab + cocoapods dependencies. You open that file to open the project in XCode or AppCode
Alt-tab-macos.entitlementsand Info.plist which are static files describing some app config for XCode
PodFile.lockdescribe dependencies on open-source libraries (e.g. Sparkle)
config/which contain XCode settings that people typically change using XCode UI, but that I want to be version controlled
The project directory is organized in the following way:
||XCode build settings|
||supporting material to document the project|
||files that are shipped inside the final
||bash scripts useful for CI and local workflows|
||Swift source code|
||Wrapping some unfriendly APIs (usually C-APIs)|
||Business logic (i.e. “models”)|
||UI code (e.g. sublasses of NSView or NSCollectionView)|
Other folders/files are either tooling or auto-generated (e.g.
Frameworks/ are generated by
alt-tab-macos is deeply integrated with the OS and other apps. Thus doing end-to-end automated QA would be a nightmare. For the time being QA is done manually.
In an attempt to not have too many regressions, this documents will list OS interactions. This should be useful as some of them are very exotic and not many people know about them.
cmd+tab, so the user can replace these
deletekey; these should not stop recording shortcuts
⌥`shortcut should become
⌥<on a Spanish ISO keyboard