Making proper use of Touchbar inside Xcode.
You can see it in action in here
If you don't wana bother with downloading the code and change the app to your needs, go to release section in this repo (one above the bar with programming language used) and download the binary :)
Disclaimer: This tool uses the default shortcuts, if you customized some of your shortcuts, you can customize this easily to your desires.
Before everything, if you are using any other keyboard than the one with American-US layout, add this keyboard as secondary inside you keyboard options
Settings -> Keyboard -> Input Sources -> click on plus and ADD
American international - PC.
After you added this keyboard you should be able to use this app.
The reason why this is needed is that I was only able to get the
US keyboard layout (qwerty) GOLDEN STANDART KEY ADDRESSES
Key.swift) from where I call the shortcut. Look down at
TL;DR section if you wanna learn more.
Just run the application and... Let it work for you. For the first time you might need to enable something in accessibility to let this app press the keys.
I won't tell you to enable it, but I recommend you to do so :D But it's up to you now.
This application has build in system which observes which application is currently on foreground and according to it,
it sets the touchbar application on foreground. So whenever you need
some shortcut which you don't remember, this touchbar tool is there for you :) Also if you don't like it and rather use the native
debug touchbar screen, you can always dismiss it. Whenever you come back to the application, it will pop right back to be presented again.
If you don't find any of the given shortcut on the list, feel free to add it inside
Shortcut+Instances.swift(Don't worry, I dumped all the shortcuts with script, not manually :D )
TouchBarCustomizationPalleteand assign it the right shortcut (Probably from Xcode Settings)
TouchBar+Identifiers.swift(Follow for example add documentation)
Basically keylogger which wil blow up your macbook, call shortcuts on fly and help you more with your workflow :)
There goes my special thanks to JK_Kross who at that time wasn't employed as iOS Dev but music teacher and did a great job by helping me with this project :)
Guys at MTMR from which I took inspiration, but not the code :)
Megg on Instagram for providing me some icons for some actions. :)
This would be great honor to me because I never tought it is possible to make some return at least at money for the time I spend on some tool.
If you want to support this project, feel free to send some coffee money to this link
If you don't want to spend money, you can still support me if you will share this tool with your colleagues and tell them how nice it is and how it improved your workflow. I personally love to use the documentation button :D:D
Oh yeah and, take a look at guys at Showmax, they are doing really cool stuff in a great way :)
NSApplication.shared.toggleTouchBarCustomizationPalette(self.presenter)so it is smoother UX. (Actually App needs to be active)
The first thing to do is to class-dump private Touchbar API from
AppKit I really would love to know what
DFR Prefix means, but let's put that aside :D
After we got this API, we can do pretty much what we want with the touchbar. We can replace the whole touchbar screen, or just the part we are supposed to, replace the
control buttons, add Nyan cat etc. You can read more inside
Okay, so now we have control of touchbar, what we need now is to create some of our view. At first I had some nice approaches in mind, the first one was to use da native approach
NSTouchBarItems and refresh the items every time there is some change in UI. Don't get me wrong, this approach is good. But I don't like it. I have seen MTMR
(Project that inspired me to do this) and I tought I want to do this the other way. Basically the function
presentSystemModal(touchBar:position:identifier) is called there every single
milisecond because there is always something going on. I don't believe in this approach so I decided that we should probably use some view on it.
After that we decided to be hipsters af and create SwiftUI View on the touchbar which contains the buttons to call our desired actions. However this would cause issues on drag'n'drop touchbar Items. So we went to classic native solution.
The main problem in this project is handling of shortcuts / quick actions / menu actions. There came 3 ideas into my mind:
IDEKitand figuring out how to call actions via some private API.
IDEKitmodule I decided to gave up. If you look into my class-dump -> https://awesomeopensource.com/project/DominikBucher12/IDEKit-Class-dump You will find there very nice class
IDECommandManagerwhich should be responsible for caling the actions from random menus. As I acknowledged from Xcode stack trace (SIP off :/) you need always to call
cacheCommandDefinitionsAndHandlers()to buffer the commands into memory. Also I figured out I need to run Xcode AKA
IDEApplicationone more to store all the commands and get them from different stables. However there is a lot of more steps to this to finally get
sendActionForCommandWithIdentifier(identifier:from:)to work. I had a lot of fun with
IDEKeyBindingSetand other stuff which is related to the calling of commands. If you are bored, hacking Xcode is great entertainment for you, but don't expect quick results. Note, if you don't know IDEKit, it's basically framework for Xcode and everything around it :) Also for this project you probably don't want to run Xcode twice just to run some app that runs small portion of it.
Keywhich represents the keys on the keyboard. Also there are some special keys like
option(called modifiers) which modify the key press. You can take a look at
Key.swiftfor the list of keys and their addresses. There is this nice object
KeyPresserwhich virtually presses the keys. The keys are wrapped in
Shortcutobject which holds the keys which should be pressed by
KeyPresser. Things get pretty interesting when user has his custom keybindings defined at
~/Library/Developer/Xcode/UserData/KeyBindings/. Then we need to parse the
idekeybindingfile and map the identifiers with different keys into our system and override the default ones. After we do that, we just call the overriden shortcut instead of the default one.
PS. I Hate