skhd
skhd copied to clipboard
Blacklist doesn't work for Raycast and Alfred
Hello,
First thank you for your tool.
Unfortunately, .blacklist
doesn't work for the Raycast app (a Spotlight alternative). I saw the same thing for the Alfred app ( #158).
I've tried this:
.blacklist [
"raycast.app"
"raycast"
"/Applications/Raycast.app/Contents/MacOS/Raycast"
"/Applications/Raycast.app"
]
The paths come from a ps
command. Nothing changes. Raycast is not ignored. Could you help us?
Best,
I hit this issue a bit ago as well and and decided I wanted to dig around and figure out what was going on. After some digging, I think the issue is that Alfred/Raycast won't work with the blacklist because skhd's blacklist code is comparing the blacklist to the current process based on data from a MacOS notification that the front app switched and this event doesn't fire for Alfred. The reason it doesn't fire for Alfred is I believe that Alfred (as well as Raycast and Spotlight) render their search bars with an NSPanel that sets the nonactivatingPanel
flag which I think is supressing this particular alert.
Details
I'm not that familiar with skhd's source code, but looking around I found the blacklist checking code is here and here. I added some debug statements to the code and built my own version of the binary to do some investigating (diff of changes here). After running my modified binary and playing around, I noticed that whenever Alfred or Spotlight came up, skhd thought that they were the previous process (i.e. the app I was using just before activating those apps). Here's a video of this in action:
Finding this peculiar, I looked around to see where skhd was getting the process name and I found that it was getting them from some code that was listening for a notification from MacOS(code here).
I haven't dabbled in Mac or iOS programming in a long time, but I wondered if using these older APIs maybe resulted in a glitch where the notifications weren't being delivered. I created a very basic app in Xcode that just spit out details from this event (gist here). Playing around with it, I noticed that when I would activate Alfred or Spotlight the event never fired. Here's a video of this:
I still wasn't quite sure what was going on, and since neither Alfred or Spotlight are open source, I found an open source launcher called Sol and was able to reproduce the issue with that as well. Digging through their source code, I found that the app was using a NSPanel
(code here) and it set a property called nonactivatingPanel
. According to Apple's documentation(link) this property makes it so an NSPanel
doesn't activate the owning app.
Wanting to see if I could get a little more data, I used Accessibility Inspector on Alfred,Spotlight and Sol and all three indicated that they were AXSystemDialog
which led me to this code which led me to this doc page which seemed to hint that Alfred/Spotlight set things up similarly to Sol. For reference, here's the accessibility inspector output for Alfred, Spotlight, and Sol.
I should add, I'm not sure this is fixable unless there's some other event that skhd can use instead of kEventAppFrontSwitched
that will provide the data this event seems to be missing. Looking through the options - I'm not sure anything really jumps out at me (caveat - I'm not a Mac developer so someone who is might have a better idea).
Hello @sendhil ,
Thank you for your detailed answers and your great efforts!
I thought the same thing, that Raycast or Alfred rely on another system (may be NSPanel as you suggested) than the one used by Skhd.
Finally, I have optimized my hotkeys. Everything on the left side (fn, ctrl, option and cmd) are for Yabai and everything on the right side (cmd and option) are for apps like Raycast. We can do this with the latest version of Skhd. For instance, the left cmd is called with lcmd
.
Everything is better that way (personal opinion).