-
-
Notifications
You must be signed in to change notification settings - Fork 314
/
Contributing.md
162 lines (116 loc) · 10.3 KB
/
Contributing.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# Contributing
There are many ways to contribute:
* Come discuss with us on the [Discord server](https://discord.gg/CVEPeDufJa).
* [Suggest an enhancement or discuss an issue on github](https://github.com/lwouis/alt-tab-macos/issues), or use the feedback form in the app.
* [Localize the app in your language](https://poeditor.com/join/project/8AOEZ0eAZE)
## Technical overview
This document gives a technical overview of the project, for newcomers who want to contribute.
## Building the project locally
This project has minimal dependency on Xcode-only features (e.g. InterfaceBuilder, Playgrounds). You can build it by doing:
* `scripts/codesign/setup_local.sh` to generate a local self-signed certificate, to avoid having to re-check the `System Preferences > Security & Privacy` permissions on every build
* Either open `alt-tab-macos.xcworkspace` with XCode, or use the cli: `xcodebuild -workspace alt-tab-macos.xcworkspace -scheme Debug` to build the .app with the `Debug` build configuration
## Raising a pull-request
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
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](https://cocoapods.org/) 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](https://github.com/lwouis/alt-tab-macos/blob/master/src/api-wrappers/PrivateApis.swift) the ones we are using, as well as ones we investigated in the past.
## This project specifically
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:
* 1 xib (InterfaceBuilder UI file, describing the menubar items like “Edit” or “Format”)
* `alt-tab-macos.xcodeproj` file describing AltTab itself. It contains some settings for the app
* `alt-tab-macos.xcworkspace` file describing an xcode workspace containing AltTab + cocoapods dependencies. You open that file to open the project in XCode or AppCode
* `Alt-tab-macos.entitlements` and Info.plist which are static files describing some app config for XCode
* `PodFile` and `PodFile.lock` describe dependencies on open-source libraries (e.g. [Sparkle](https://github.com/sparkle-project/Sparkle))
* Some `.xcconfig` files in `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:
| Path | Role |
|------|-------|
| `config/` | XCode build settings |
| `docs/` | supporting material to document the project |
| `resources/` | files that are shipped inside the final `.app` (e.g. icons) |
| `scripts/` | bash scripts useful for CI and local workflows |
| `src/` | Swift source code |
| `src/api-wrappers` | Wrapping some unfriendly APIs (usually C-APIs) |
| `src/logic` | Business logic (i.e. "models") |
| `src/ui` | UI code (e.g. sublasses of NSView or NSCollectionView) |
Other folders/files are either tooling or auto-generated (e.g. `Pods/` and `Frameworks/` are generated by `pod install`)
## QA
**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.
## List of use-cases
### Which windows to list, and be able to focus
* Minimized windows
* Windows from hidden apps
* Windows of fullscreen apps
* Windows of fullscreen apps with split-screen
* Windows merged into 1 as tabs (e.g. Finder "Merge All Windows", drag-and-drop a window onto an existing window, etc)
* Windows on multiple monitors
* Windows on multiple Spaces
* Should not show: dialogs, pop-overs, context menus (e.g. Outlook meeting reminder, iStats Pro menus)
### App is summoned during an OS animation
* The UI should only appear after the animation completes for:
* Space transition
* an app going fullscreen
* The UI should not show at all (i.e. ignore the shortcut) if Mission Control is open
* The UI should show instantly during:
* Window minimizing/de-minimizing
* Window maximizing (i.e. double-click the titlebar)
* An app is launching/quitting
### Thumbnail layout corner-cases
* Very small windows (i.e. smaller than the thumbnail min size)
* Very wide/tall windows
* Should show the app name for windows without a title
* Long titles should be truncated
* Many windows are opened
* There is no open window
* AltTab should appear on top of all windows, dialogs, pop-overs, the Dock, etc
### OS events to handle while AltTab’s UI is shown
* An app is launching/quitting
* A new window opens
* An existing window is closed
### Drag-and-drop on top of the thumbnails
* Drag-and-dropping a URL onto a window thumbnail should open it with that window’s app
* Drag-and-dropping a file onto a window thumbnail should open it with that window’s app
### System Preferences
* General > Appearance > "Dark": switches to Dark Mode
* General > Accent color > "Graphite": traffic lights on thumbnails should be gray
* Accessibility > Display > Reduce transparency: AltTab background should be a solid color
* General > Show scroll bars > "Always": regenerates all scrollbars
* Display > Resolution > Scaled: changes DPI and rescale AltTab
* Mission Control > "Displays have separate Spaces": changes Spaces behavior on multi-displays setups
### Spaces
* Spaces get created/destroyed
* A window is moved to another space by drag-and-dropping on the Spaces thumbnails at the top of the Mission Control UI
* A window is moved to another space by dragging it on the side of the current Space, and waiting for a Space transition, then dropping it
* A window is moved to another space by destroying the Space it is in
* An app is assigned to a specific space or all spaces by clicking its Dock icon > Options > Assign to
### Shortcuts
* The hold "key" can be multiple modifiers (e.g. `⌥⇧`)
* Shortcuts should have priority over system shortcuts such as `cmd+tab`, so the user can replace these
* The "select next window" shortcut can be modifiers, modifiers+key, or just key; it can also contain the same modifiers as the hold "key"
* All shortcuts, except the hold key, can be disabled by the user
* Shortcuts can include the `escape` and `delete` key; these should not stop recording shortcuts
* [Secure Input](https://github.com/lwouis/alt-tab-macos/issues/157#issuecomment-659170293) can prevent AltTab from listening to the keyboard
* Some shortcuts should only work when AltTab is open
* These shortcuts should active whether the hold shortcut is held or not
* Shortcuts should work with capslock active or inactive
* Shortcuts should repeat if kept pressed
* Repeat rate and initial delay should match the values set in `System Preference` > `Keyboard`
* when navigating left/right/up/down, the repeating behavior should stop when hitting the last window in the list. The user can then manually do the shortcut once more to cycle to the other side; it then repeats again
* The shortcut sets 1 and 2 should not interact with each other (e.g. opening AltTab with one, then using the other to navigate)
* Shortcuts can focus the window on release, or be pressing a key or using the mouse
* Keyboards from other countries have different layout which impact shortcuts
* e.g. the default ``` ⌥` ``` shortcut should become `⌥<` on a Spanish ISO keyboard
### Localization
* Right-to-left languages (e.g. arabic) have the whole layout reversed
* For the main window, even navigation is reversed
* For preferences and feedback windows, all layout is reversed
* Text length can vary per languages which can create layout issues
### Misc
* AltTab is launched after some apps/windows are already opened
* Displays/mouses/trackpads/keyboards get connected/disconnected while AltTab is used
* Sudden Termination