-
-
Notifications
You must be signed in to change notification settings - Fork 39.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The Apple Fn Key #2179
Comments
This is very cool, but I don't know how we possibly include this. Leaving this open to discus the possibility for now. |
@skullydazed Short of maybe a feature option that overrides the normal 6KRO code. (eg "APPLE_NKRO", maybe). But not sure how Apple would feel about us doing that, given that we have to use their VID and PID to get this working. |
There would have to be some kind of warning if the feature is enabled, reminding users that it won't work unless they change their VID/PID - putting those values into the repo, even for checking, is probably a bad idea. I can see this may not be very "QMK". I've also found that the PID can determine functionality amongst Apple keyboards - on my 2011 MBP, the F4 key has a little gauge symbol on it and opens the Dashboard. On my 2017 MBP it has a different symbol, and opens Launchpad. QMK is meant to be customised though, even if you can't push your cool "Apple" keyboard back to the repo, we should at least be able to say that it is technically possible. |
From https://gist.github.com/fauxpark/010dcf5d6377c3a71ac98ce37414c6c4, see qmk#2179 for the full background on it.
I noticed that matias keyboards offer a Mac version with an fn key. So I picked up a matias wired aluminum keyboard, plugged it into my Mac, and checked out what happened. This is really interesting: `Matias Wired Keyboard: Product ID: 0x024f Looks like they just straight up lie about their Vendor ID. 0x024f is not a known Apple product ID, in that it doesn't appear in pci.ids: https://usb-ids.gowdy.us/read/UD/05ac |
Karabiner Elements can remap arbitrary keys to mission_control, launchpad, or other Mac uses for function keys. It is good engineering to choose the right layer in which to work. I'm constantly revising VSCode-specific key mappings as I work, by editing a CSV file that updates Karabiner via Goku, and an on-screen crib sheet. One wants one's keyboard firmware to be fully functional in case a software layer like Karabiner isn't present, but it makes no sense to be reflashing a keyboard's firmware all the time. Rather, you're here to design a keyboard you can live with. So involving Karabiner is a good thing. For example, it can implement tap or hold without a timer, so the key fires on key-up no matter what the delay, if it isn't used as a modifier. I haven't figured out how to do this yet in QMK. I use the Mac function key internally in Karabiner, as a modifier flag for internal use that I can be sure no application is expecting. I won't be using that trick with QMK. However, the Mac also equivalences left and right modifiers, so no app can be looking for both left control and right control, for example. This is another way that QMK can set modifiers to be trapped by Karabiner, without interfering with any downstream app. Karabiner sees the left, right distinctions, but apps don't. |
Karabiner Elements does its remapping with a kernel driver. It's the "right" way, inasmuch as having to hack the kernel to work around the USB stack is considered right. Apple is constantly trying to clamp down on kernel development. Karabiner Elements was itself a rewrite of Karabiner. In that regard QMK is more "stable" across OSes. |
I'm likely to contribute to QMK once I get my sea legs. Yes, there was a lapse without Karabiner, and Apple is warning again of impending changes to kexts. The "Oryx" key on an ErgoDox EZ or Planck EZ sets up two-way communication with QMK firmware. It would be ideal to continually tweak key macros on the fly, through a program that helped the user as the Oryx trainer does, without having to either reflash the keyboard or rely on kexts. The Proton C, for example, certainly has the memory and processing power. I can live without mission_control, and I'd love not to be worried about the future of kexts. |
It's April 2020 and things seem to have changed. I have a 2019 MacBook Pro with a Microsoft full-size ANSI keyboard:
and it has the "Insert" key mapped to the "fn" key under macOS 10.15 Catalina. Even the Mac Keyboard Viewer shows the insert key as labeled "fn" (under El Capitan, the keycap was labeled "?⃝" for "Help"). I also note that the "fn" key on the built-in keyboard sends a keycode just like every other key; it does not seem to be special in any way. So I would hope that QMK can now map a key to "fn", or failing that, can map a key in such a way that Karabiner can map it to "fn". At the moment, the Dygma Raise (using QMK) can do neither, and is not going to try, citing this QMK issue as the reason. It would be great to have this feature at least workable if not fully supported. |
@Nuru That's an interesting observation. Do you have the microsoft software installed for your keyboard? |
@Nuru that's really interesting. I wonder if this is related to particular keyboards, particular versions of the macOS, particular systems (can't rule out macOS behaving differently on your 2019 system), or if this indicates kernel level change in the macOS. I did not see this behavior on earlier versions of macOS 10.15. I have a Mid-2012 MacBook Air running 10.15.4. I definitely don't see this behavior with my Novatouch. Could it be specific to the VID/PID mentioned earlier? It would be a good experiment to flash a QMK keyboard with this VID/PID to see if we can reproduce this result. |
@skullydazed No, I do not have any special software installed for the keyboard. @jsoltren I have an 2013 MacBook running 10.14 Mojave and the "fn" key sends a keydown and keyup event. It is not just some internal modifier. Also, I just got my 34 key keypad
and Karabiner maps its "Insert" key to "fn" no problem. It's possible a lot of this is being done by the Karabiner kernel extension. I have quit the application and seen the mapping go away, but the keycap stays and the built-in keyboard's function key stays the same. I have not tried fully uninstalling Karabiner yet. The other interesting thing is that Karabiner-EventViewer reports the "fn" keycode as 65538. That is outside the range of a 16 bit number. It is binary 1 0000 0000 0000 0010. This suggest the kernel extension is at play. My general attitude about all this is that Karabiner is a thing, lots of people use Macs, and it is not unreasonable to ask QMK to implement a feature that only works in conjunction with Karabiner. It would be great if QMK could get the "fn" key to work without Karabiner, but if that is too hard, it would still be helpful for QMK to support a special keycode that you then feed into Karabiner as "fn" so that I don't have to give up an existing key for it. |
@Nuru Karabiner, being implemented with an actual kernel extension, enables emulation of the true fn key at the kernel level. I use this myself on some systems and I've glanced at the Karabiner sources. @skullydazed may have a different opinion but my view is that the firmware should not be doing anything special for some particular kernel or user program. You can program any key to send any key code, and catch that in kernel or user space for your need. This seems sufficient to me. What I do support, is an optional build flag for faking an Apple VID/PID. Apple wouldn't be too happy about this shipping, but what you do on your own keyboard is between you and your console. @Nuru, if you have a chance, could you try completely uninstalling Karabiner, restarting, and trying again? There are instructions for a full Karabiner uninstall (which is necessary in this case) on pqrs.org. |
At the very least, I can say that one thing that has changed since this issue was created is that it is no longer true that "there are no third-party keyboards with Apple Fn keys". @jsoltren I did a full uninstall of Karabiner and rebooted, and nothing changed that didn't change when I quit Karabiner. I recall now that what got me started down this path was seeing Apple's external Magic Keyboard with Numeric Keypad, which I thought was a normal USB keyboard, has the "fn" key where ANSI keyboards have the "Insert" key. So I thought any USB keyboard could do it. Now I realize that (1) it is a Bluetooth keyboard, not USB, and (2) Apple provides special treatment for their own peripherals. It does, at least, explain how "fn" ended up on the "Insert" key on the Keyboard viewer and why I tried that mapping in Karabiner. On the other hand, I note that the Logitech Wireless Solar Keyboard K750 (Mac version) also has the "fn" key in the same place (replacing the "Insert" key), so it is not strictly limited to Apple keyboards, and although that keyboard is wireless, it wirelessly connects to its own USB dongle, so it connects to the computer via USB, not Bluetooth. And it says it requires no software installation, so it is not using its own kernel extension. I don't know how to sniff the USB connection between the Logitech Keyboard and the computer to see what its "fn" key is generating on the bus, but I'm hoping someone else can sniff that and see about duplicating it in QMK. The Logitech keyboard is sold by Apple, so it is certainly possible it has special support of some kind, but if you need to go down the route of faking a Vendor ID, it might be safer to fake Logitech than to fake Apple. |
Wireshark on macOS is able to sniff USB packets, though from Mojave or Catalina onwards you need to disable SIP for the interfaces to show up (and then you have to |
This is hack. These keys are unused by the default macOS keybindings, so I'm sending these when pressing the equivalent of the Mission Control and Launchpad keys (i.e. Fn+3, Fn+4) so they can be configured to do the thing. Both can be set in System Preferences > Keyboard. Why exactly these keys don't have normal codes is explained here: qmk/qmk_firmware#2179 tldr: Apple ignores the codes unless the USB vendor and product ID match one of their keyboards.
qmk#2179 From Issue qmk#2179 of qmk/qmk_firmware, user fauxpark mentions how to enable the Apple 'fn' key in QMK. A link to applefn.patch is in the issue link above, and was patched into qmk_firmware with this command: (applefn.patch was already copied into ./qmk_firmware) ```c % cd qmk_firmware % patch -ruN -d ./ < applefn.patch ``` In order to be able to use the Apple fn key keycode -- KC_APPLE_FN, or alternatively, KC_APFN, you must define the following directives in the config.h file for your keyboard's config.h: ```c #define VENDOR_ID 0x05ac #define PRODUCT_ID 0x024f #define APPLE_FN_ENABLE ``` macOS must "think" your keyboard is one of their own -- the PRODUCT_ID corresponds to the Apple Pro Keyboard. This commit already has the patch applied, so the KC_APPLE_FN (KC_APFN) keycode may be used in all layouts from here on out.
Were these merged in by a PR at all? |
@uchuugaka unfortunately due to the legal implications of imitating an Apple device (by setting their VID and PID), this probably won't be able to be merged. Unless you have managed to get it working using some other VID, in which case that is quite interesting. |
@fauxpark @uchuugaka FWIW I have the |
Maybe things have changed since High Sierra. I think that was when I last properly tested this. I'll try it again in the morning. |
I'd be surprised if it were an issue since Matias has been using the vendor ID for decades. Effectively, it's like registering a port number like 666 the port for Doom for network play. Nobody can or will really chase it because it is 100% spoofable like a web browser's User Agent string or Caller ID. The USB standard also handles this because each device gets a unique ID assigned automagically by the bus itself and no OS in their right mind would predicate anything secure against VID or PID. FWIW, Apple even share it in constants… If it helps, the driver is 100% Apple's HID device driver unless you provide something via their DriverKit. |
I'm aware of all that - my suspicion is more that Apple maintains a list of "allowed" VIDs that the Fn key will work on. It feels very in keeping with them to do something like that. Obviously it's not meant to be "secure", just a first-level deterrent against impersonating Apple. RE Matias, it seems as though they have/had some kind of relationship with Apple, if this (admittedly quite old) press release is anything to go by. So it is possible they have been granted permission to use Apple's VID, or Apple has whitelisted Matias devices somehow. |
Dunno if this changes anything, but they made a change to how they’re reported: |
Makes sense, the |
I can confirm that the path works without modifying VID using my Idobao ID80v2 and MacOS Big Sur. This is what I'm running
|
I can also confirm that this patch works without modifying VID on the DURGOD Taurus K320 on MacOS Catalina. This is what I'm running
|
Can someone explain how to use the patch? Thanks. |
@LazaroFilm I haven't tried it, but my guess is you could clone @dkjer’s fork ( |
As a macOS user who has recently gotten into mechanical keyboards but basically doesn't understand almost any of the things described here, except how complicated the Apple "fn" key is, would anyone be able to clear up a few things for me?
Thanks so much! |
Other implementations of the Fn key usually are done through ACPI (you often see this on laptops since the keyboard is integrated anyway), or are completely internal to the keyboard (eg. Corsair).
Some of them may simply be sending the standard media keys instead of the F-row keys when the Fn key (which does not send anything to the host) is pressed. Volume up/down/mute as well as play/pause/rewind/forward are all part of the HID spec and are quite well supported on all OSes.
The main issue with my patch is that it requires you to trick macOS into thinking the board is an actual Apple keyboard - in my testing it did not want to recognise the Fn key event unless the USB vendor and product IDs were ones it "allowed". My theory is that this was done to prevent Apple keyboard clones by way of possible legal repercussions from using their USB vendor ID.
I'm pretty sure Karabiner has the ability to map the Fn key on a keyboard that does not otherwise have it. It doesn't change anything about the keyboard, just hooks into the keyboard events and intercepts them before they hit the kernel (my vague understanding).
Probably not. For keyboards with internal Fn keys, nothing will be sent to the host (and nothing would be received), so it cannot be picked up by Karabiner or BTT. And if you're mapping Insert to the Apple Fn, all the keyboard is doing is sending Insert, which Karabiner simply intercepts and turns into a Fn event. |
I emailed Matias because their boards do use the Apple identifiers. They said it’s necessary and not a problem as they’ve been doing it for decades.
Karabiner intercepts keys and replaces the value.
…
On Feb 4, 2021, at 18:34, Ryan ***@***.***> wrote:
What exactly does the Apple "fn" key do differently than a third party "fn" key? I imagine it has something to do with Apple's special function row, but is it not possible to take advantage of the actual functions (such as volume up/down, media pause/play/forward/back, etc.) by remapping a key to talk to macOS and trigger those actions? I believe the app BetterTouchTool is able to map any key command to those functions.
Other implementations of the Fn key usually are done through ACPI (you often see this on laptops since the keyboard is integrated anyway), or are completely internal to the keyboard (eg. Corsair).
Apple does a unique thing here though; when you press the Fn key, something is actually sent over the wire and is handled by macOS, although it is not exactly a keycode in itself as there is no such thing in the HID spec. Pressing the function row keys with Fn held doesn't change the keycodes that are sent, but macOS knows that the Fn key is held and will decide what to do based on that. This is how Karabiner and BetterTouchTool are able to mess with Fn key actions.
I know of some keyboards that replicate the functionality of the special Apple function row functions, such as Keychron keyboards and the Varmilo V87Mac. Are they somehow recreating the Apple function key to do that?
Some of them may simply be sending the standard media keys instead of the F-row keys when the Fn key (which does not send anything to the host) is pressed. Volume up/down/mute as well as play/pause/rewind/forward are all part of the HID spec and are quite well supported on all OSes.
If someone wanted to build their own keyboard from a PCB design, are you saying it's not possible to put Apple's "fn" key anywhere? (In which case, I circle back to my question of how Keychron and Varmilo are able to do it).
The main issue with my patch is that it requires you to trick macOS into thinking the board is an actual Apple keyboard - in my testing it did not want to recognise the Fn key event unless the USB vendor and product IDs were ones it "allowed". My theory is that this was done to prevent Apple keyboard clones by way of possible legal repercussions from using their USB vendor ID.
Maybe most to the point, is it currently possible to buy just about any mechanical keyboard and remap the "fn" key to the right of the spacebar to be "option" and remap the "Ins" key to be the Apple "fn" key? I read here that someone did this with Karabiner, but I keep reading mixed things about this.
I'm pretty sure Karabiner has the ability to map the Fn key on a keyboard that does not otherwise have it. It doesn't change anything about the keyboard, just hooks into the keyboard events and intercepts them before they hit the kernel (my vague understanding).
If I were able to remap, e.g. the Ins key to the Apple "fn" key, would that also be able to function as the keyboard's own specific "fn" key? For instance to control keyboard backlight settings.
Probably not. For keyboards with internal Fn keys, nothing will be sent to the host (and nothing would be received), so it cannot be picked up by Karabiner or BTT. And if you're mapping Insert to the Apple Fn, all the keyboard is doing is sending Insert, which Karabiner simply intercepts and turns into a Fn event.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
I looked into this a while back in great detail. I was doing some
consulting work for a keyboard vendor that wanted to develop a Mac specific
keyboard.
The Fn key behavior is defined in the macOS kernel. I haven't checked for
Big Sur but as of Catalina the Fn key was a special thing. It was defined
by a certain scan code from certain keyboards. I don't have the link handy
but a good deal of poking around on https://opensource.apple.com found
exactly where this is defined.
The only way to truly emulate the behavior of the Fn key is to either
pretend to be an Apple keyboard with a fake identifier, or to have a kernel
module. Karabiner Elements implements exactly such a module which is why
they are able to do this. It's far from plug-and-play but for my personal
use Karabiner's remapping is perfect.
That's interesting that Matias responded to you. I asked him the same exact
question ages ago and never got a response.
You can simulate something like an Fn key in firmware easily enough. Just,
say, make Fn+F1 return "Volume Up" or whatever. This is what Topre does
with their Realforce Mac.
…--José / XMIT
On Thu, Feb 4, 2021 at 4:04 AM John Joyce ***@***.***> wrote:
I emailed Matias because their boards do use the Apple identifiers. They
said it’s necessary and not a problem as they’ve been doing it for decades.
Karabiner intercepts keys and replaces the value.
>
> On Feb 4, 2021, at 18:34, Ryan ***@***.***> wrote:
>
>
> What exactly does the Apple "fn" key do differently than a third party
"fn" key? I imagine it has something to do with Apple's special function
row, but is it not possible to take advantage of the actual functions (such
as volume up/down, media pause/play/forward/back, etc.) by remapping a key
to talk to macOS and trigger those actions? I believe the app
BetterTouchTool is able to map any key command to those functions.
>
> Other implementations of the Fn key usually are done through ACPI (you
often see this on laptops since the keyboard is integrated anyway), or are
completely internal to the keyboard (eg. Corsair).
> Apple does a unique thing here though; when you press the Fn key,
something is actually sent over the wire and is handled by macOS, although
it is not exactly a keycode in itself as there is no such thing in the HID
spec. Pressing the function row keys with Fn held doesn't change the
keycodes that are sent, but macOS knows that the Fn key is held and will
decide what to do based on that. This is how Karabiner and BetterTouchTool
are able to mess with Fn key actions.
>
> I know of some keyboards that replicate the functionality of the special
Apple function row functions, such as Keychron keyboards and the Varmilo
V87Mac. Are they somehow recreating the Apple function key to do that?
>
> Some of them may simply be sending the standard media keys instead of
the F-row keys when the Fn key (which does not send anything to the host)
is pressed. Volume up/down/mute as well as play/pause/rewind/forward are
all part of the HID spec and are quite well supported on all OSes.
>
> If someone wanted to build their own keyboard from a PCB design, are you
saying it's not possible to put Apple's "fn" key anywhere? (In which case,
I circle back to my question of how Keychron and Varmilo are able to do it).
>
> The main issue with my patch is that it requires you to trick macOS into
thinking the board is an actual Apple keyboard - in my testing it did not
want to recognise the Fn key event unless the USB vendor and product IDs
were ones it "allowed". My theory is that this was done to prevent Apple
keyboard clones by way of possible legal repercussions from using their USB
vendor ID.
>
> Maybe most to the point, is it currently possible to buy just about any
mechanical keyboard and remap the "fn" key to the right of the spacebar to
be "option" and remap the "Ins" key to be the Apple "fn" key? I read here
that someone did this with Karabiner, but I keep reading mixed things about
this.
>
> I'm pretty sure Karabiner has the ability to map the Fn key on a
keyboard that does not otherwise have it. It doesn't change anything about
the keyboard, just hooks into the keyboard events and intercepts them
before they hit the kernel (my vague understanding).
>
> If I were able to remap, e.g. the Ins key to the Apple "fn" key, would
that also be able to function as the keyboard's own specific "fn" key? For
instance to control keyboard backlight settings.
>
> Probably not. For keyboards with internal Fn keys, nothing will be sent
to the host (and nothing would be received), so it cannot be picked up by
Karabiner or BTT. And if you're mapping Insert to the Apple Fn, all the
keyboard is doing is sending Insert, which Karabiner simply intercepts and
turns into a Fn event.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or unsubscribe.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2179 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJHBHPQAK7LUCSPNU6FFXLS5JWLVANCNFSM4EJBG7RA>
.
--
__o
_`\<,_
(_)/ (_)
José Hiram Soltren
+1 (347) 503-9558
|
So... this can be done from software side, meaning no modification to the firmware is needed... Or, you can make the changes in your own fork, and compile it. But having this in the official repo ... I'm actively opposed to. "i've been doing it for years" is not a defense if Apple decides to take you to court. And if that were to happen to QMK, who would be willing to help pay the astronomical legal fees? Not worth the risk, especially when you can do this yourself in several ways. |
I wouldn't ship a keyboard commercially with an Apple dev ID unless I had a
penchant for paying lawyers. It's possible Apple wouldn't notice or care
but why risk it?
If I were shipping a keyboard commercially, I'd provide a profile for use
with Karabiner.
Any individual cherry-picking some change to give their personal firmware
build an Apple dev ID is probably harmless.
Part of the problem is that this story does change with each major macOS
release.
…On Thu, Feb 4, 2021 at 10:25 AM Drashna Jaelre ***@***.***> wrote:
So... this can be done from software side, meaning no modification to the
firmware is needed...
Or, you can make the changes in your own fork, and compile it.
But having this in the official repo ... I'm actively opposed to. "i've
been doing it for years" is not a defense if Apple decides to take you to
court. And if that were to happen to QMK, who would be willing to help pay
the astronomical legal fees?
Not worth the risk, especially when you can do this yourself in several
ways.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2179 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJHBHPEAT7PUCURSSFNWILS5LDATANCNFSM4EJBG7RA>
.
--
__o
_`\<,_
(_)/ (_)
José Hiram Soltren
+1 (347) 503-9558
|
This is extremely helpful, thank you! I don't understand ACPI (read up a little bit and I'm lost), but it sounds like, in a nutshell, Fn keys don't usually send anything to the computer because there is no "Fn" keycode, but Apple sends a non-keycode piece of data with theirs.
So if I understand this right, this is what happens when you press Fn+F8, assuming System Prefs is set to use F1, F2, etc. as standard function keys:
So, I could use Karabiner to map Fn to the Ins key and still wind up with the same practical functionality as a real Apple Fn key. But if I wanted a third-party keyboard with just Command+Option+Control to the right of the spacebar, I'm stuck on how to change a keyboard's non-Apple "Fn" key (which is always to the right of the spacebar) to be the "Option" key. Is it the circuitry/PCB that makes it the keyboard's own Fn key, or is it something in the firmware? Can QMK change a QMK-compatible keyboard's "Fn" key to be "Option"? Cannot thank all of you enough for all of the incredibly insightful info! |
I am not a lawyer and you should check with one, but AFAIK the doctrine of laches says "I've been doing it for years" is a completely valid defense for something like this. Also, in practice, Apple or any company is not likely to go from zero to filing a lawsuit over something like this. First step would be to send you a "cease and desist" letter demanding you stop doing whatever it is they don't like, and generally if you then comply with the terms of the notice, that is the end of it. The bad publicity from Apple abusing an open-source project by suing them is just not worth it. |
Thanks for the active and healthy debate here everyone. At this point I think all sides have had a fair chance to be heard. Our official position is that we do not use VIDs we don't have permission for regardless of legality. We have always sought permission before including a VID we know is owned by an organization, and at times have coordinated with the owner to select the proper PID as well. Since it is exceedingly unlikely we will get this permission from Apple, or any other company that can send the Fn key, I'm going to close this issue to further comments. |
I've made this an issue instead of a PR because it probably warrants some discussion on whether or not to add this feature into QMK, but either way I think it's a good idea to at least put it in the documentation in the event that it's not implemented, so that anyone sufficiently determined can at least get some pointers on how to do so on their own. Anyway...
I wanted to see if I could get QMK to send the infamous "Apple Fn" key. It turns out I can, and it's fairly simple.
First of all, I discovered this interesting Xcode project called HID Explorer, which details all of the usage pages and usages of all your HID devices, and shows their current values. You may want to be somewhat familiar with Xcode and Objective-C to use it, though -- I had to do a little fiddling to get it to compile. Someone should really fork this and patch it up!
If you look at an Apple keyboard in HID Explorer, you can see that right at the bottom of the list is a strange entry: page
0xFF
, usage0x03
. This just so happens to correspond to the usage pageAppleVendorTopCase
and the usageKeyboardFn
, which Apple has kindly documented for us. Sure enough, pressing the Fn key causes the value of this usage to become1
.You can also see the keyboard is indeed 5KRO as has been mentioned in previous discussions on this key. The reason for this is because the keyboard report has an extra field for the Fn key, which replaces the sixth keycode:
But it doesn't have to take up a keycode slot. Because the report descriptor tells the host how to interpret the report, we can just repurpose the reserved byte for the Fn key field and it will work perfectly fine, at least within macOS. I don't know why Apple didn't just do this considering it doesn't have to deal with old BIOSes.
So, I set about replacing the declaration of the reserved byte with the Fn key descriptor elements. Then, I created a new action,
ACT_APPLE_FN
, and a new keycodeKC_APPLE_FN
and glued it all together, with an additional check inadd_key_to_report()
anddel_key_from_report()
so that they modifykeyboard_report->reserved
instead. In my keymap I addedKC_APFN
andKC_F3
, compiled & flashed, and wouldn't you know it, I can toggle Exposé!Here is the diff - it's only a proof of concept, but IMO it's pretty minimal.
But there's a catch. And it's a big one. The keyboard's vendor and product ID need to match those of a real Apple keyboard -- probably only ones with a Fn key. The product ID also seems to determine whether certain F-keys work eg. Launchpad/Mission Control and keyboard backlighting. The Manufacturer and Product strings can still be whatever you like, but this explains why there are no third-party keyboards with Apple Fn keys, and most likely rules out QMK compatible PCB/keyboard sellers from shipping boards with the key available out of the box too. I can imagine that being a bit of a dealbreaker.
Lastly, something funny I discovered: with my WASD V2 in Mac mode, it shows up in HID Explorer with the Fn key usage. When you press 6 keys at once, the value of this "Fn key" becomes the keycode of the sixth key! It looks as if WASD simply copied and pasted the report descriptor from a real Apple keyboard, but kept the same report format. So you still only get 5KRO in Mac mode, and the Fn key also does not trigger, because the vendor and product IDs are not Apple's.
The text was updated successfully, but these errors were encountered: