|
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk |
|
index 18f8b0bbfc..4ef3e230e4 100644 |
|
--- a/builddefs/common_features.mk |
|
+++ b/builddefs/common_features.mk |
|
@@ -878,6 +878,10 @@ ifeq ($(strip $(JOYSTICK_ENABLE)), yes) |
|
endif |
|
endif |
|
|
|
+ifeq ($(strip $(APPLE_FN_ENABLE)), yes) |
|
+ OPT_DEFS += -DAPPLE_FN_ENABLE |
|
+endif |
|
+ |
|
USBPD_ENABLE ?= no |
|
VALID_USBPD_DRIVER_TYPES = custom vendor |
|
USBPD_DRIVER ?= vendor |
|
diff --git a/data/constants/keycodes/keycodes_0.0.2_applefn.hjson b/data/constants/keycodes/keycodes_0.0.2_applefn.hjson |
|
new file mode 100644 |
|
index 0000000000..1378413a9e |
|
--- /dev/null |
|
+++ b/data/constants/keycodes/keycodes_0.0.2_applefn.hjson |
|
@@ -0,0 +1,11 @@ |
|
+{ |
|
+ "keycodes": { |
|
+ "0x5300": { |
|
+ "group": "apple_fn", |
|
+ "key": "QK_APPLE_FN", |
|
+ "aliases": [ |
|
+ "AP_FN" |
|
+ ] |
|
+ } |
|
+ } |
|
+} |
|
diff --git a/quantum/action.c b/quantum/action.c |
|
index 6368f7398c..d9bd34f681 100644 |
|
--- a/quantum/action.c |
|
+++ b/quantum/action.c |
|
@@ -555,6 +555,18 @@ void process_action(keyrecord_t *record, action_t action) { |
|
} |
|
break; |
|
#endif // EXTRAKEY_ENABLE |
|
+#ifdef APPLE_FN_ENABLE |
|
+ /* Apple Fn */ |
|
+ case ACT_APPLE_FN: |
|
+ if (event.pressed) { |
|
+ add_apple_fn(keyboard_report); |
|
+ send_keyboard_report(); |
|
+ } else { |
|
+ del_apple_fn(keyboard_report); |
|
+ send_keyboard_report(); |
|
+ } |
|
+ break; |
|
+#endif |
|
/* Mouse key */ |
|
case ACT_MOUSEKEY: |
|
register_mouse(action.key.code, event.pressed); |
|
@@ -1196,6 +1208,9 @@ void debug_action(action_t action) { |
|
case ACT_USAGE: |
|
ac_dprintf("ACT_USAGE"); |
|
break; |
|
+ case ACT_APPLE_FN: |
|
+ dprint("ACT_APPLE_FN"); |
|
+ break; |
|
case ACT_MOUSEKEY: |
|
ac_dprintf("ACT_MOUSEKEY"); |
|
break; |
|
diff --git a/quantum/action_code.h b/quantum/action_code.h |
|
index d9a575b518..f347010c8d 100644 |
|
--- a/quantum/action_code.h |
|
+++ b/quantum/action_code.h |
|
@@ -53,7 +53,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* ACT_SWAP_HANDS(0110): |
|
* 0110|xxxx| keycode Swap hands (keycode on tap, or options) |
|
* |
|
- * 0111|xxxx xxxx xxxx (reserved) |
|
+ * ACT_APPLE_FN(0111): |
|
+ * 0111|0000|0000|0000 Apple Fn |
|
* |
|
* Layer Actions(10xx) |
|
* ------------------- |
|
@@ -95,6 +96,8 @@ enum action_kind_id { |
|
ACT_MOUSEKEY = 0b0101, |
|
/* One-hand Support */ |
|
ACT_SWAP_HANDS = 0b0110, |
|
+ /* Apple Fn */ |
|
+ ACT_APPLE_FN = 0b0111, |
|
/* Layer Actions */ |
|
ACT_LAYER = 0b1000, |
|
ACT_LAYER_MODS = 0b1001, |
|
@@ -182,6 +185,7 @@ enum usage_pages { |
|
|
|
#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id)) |
|
#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id)) |
|
+#define ACTION_APPLE_FN() ACTION(ACT_APPLE_FN, 0) |
|
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key) |
|
|
|
/** \brief Layer Actions |
|
diff --git a/quantum/keycodes.h b/quantum/keycodes.h |
|
index bbf10da36d..b8e894a399 100644 |
|
--- a/quantum/keycodes.h |
|
+++ b/quantum/keycodes.h |
|
@@ -310,6 +310,7 @@ enum qk_keycode_defines { |
|
KC_RIGHT_SHIFT = 0x00E5, |
|
KC_RIGHT_ALT = 0x00E6, |
|
KC_RIGHT_GUI = 0x00E7, |
|
+ QK_APPLE_FN = 0x5300, |
|
QK_SWAP_HANDS_TOGGLE = 0x56F0, |
|
QK_SWAP_HANDS_TAP_TOGGLE = 0x56F1, |
|
QK_SWAP_HANDS_MOMENTARY_ON = 0x56F2, |
|
@@ -938,6 +939,7 @@ enum qk_keycode_defines { |
|
KC_RGUI = KC_RIGHT_GUI, |
|
KC_RCMD = KC_RIGHT_GUI, |
|
KC_RWIN = KC_RIGHT_GUI, |
|
+ AP_FN = QK_APPLE_FN, |
|
SH_TOGG = QK_SWAP_HANDS_TOGGLE, |
|
SH_TT = QK_SWAP_HANDS_TAP_TOGGLE, |
|
SH_MON = QK_SWAP_HANDS_MOMENTARY_ON, |
|
@@ -1406,6 +1408,7 @@ enum qk_keycode_defines { |
|
#define IS_CONSUMER_KEYCODE(code) ((code) >= KC_AUDIO_MUTE && (code) <= KC_LAUNCHPAD) |
|
#define IS_MOUSE_KEYCODE(code) ((code) >= KC_MS_UP && (code) <= KC_MS_ACCEL2) |
|
#define IS_MODIFIER_KEYCODE(code) ((code) >= KC_LEFT_CTRL && (code) <= KC_RIGHT_GUI) |
|
+#define IS_APPLE_FN_KEYCODE(code) ((code) >= QK_APPLE_FN && (code) <= QK_APPLE_FN) |
|
#define IS_SWAP_HANDS_KEYCODE(code) ((code) >= QK_SWAP_HANDS_TOGGLE && (code) <= QK_SWAP_HANDS_ONE_SHOT) |
|
#define IS_MAGIC_KEYCODE(code) ((code) >= QK_MAGIC_SWAP_CONTROL_CAPS_LOCK && (code) <= QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK) |
|
#define IS_MIDI_KEYCODE(code) ((code) >= QK_MIDI_ON && (code) <= QK_MIDI_PITCH_BEND_UP) |
|
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c |
|
index 9a67fad278..36a0b309be 100644 |
|
--- a/quantum/keymap_common.c |
|
+++ b/quantum/keymap_common.c |
|
@@ -70,6 +70,11 @@ action_t action_for_keycode(uint16_t keycode) { |
|
case KC_AUDIO_MUTE ... KC_LAUNCHPAD: |
|
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); |
|
break; |
|
+#endif |
|
+#ifdef APPLE_FN_ENABLE |
|
+ case QK_APPLE_FN: |
|
+ action.code = ACTION_APPLE_FN(); |
|
+ break; |
|
#endif |
|
case KC_MS_UP ... KC_MS_ACCEL2: |
|
action.code = ACTION_MOUSEKEY(keycode); |
|
diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c |
|
index 1ba3be4604..b53d3f687b 100644 |
|
--- a/tmk_core/protocol/report.c |
|
+++ b/tmk_core/protocol/report.c |
|
@@ -299,3 +299,13 @@ __attribute__((weak)) bool has_mouse_report_changed(report_mouse_t* new_report, |
|
return changed; |
|
} |
|
#endif |
|
+ |
|
+#ifdef APPLE_FN_ENABLE |
|
+void add_apple_fn(report_keyboard_t* keyboard_report) { |
|
+ keyboard_report->reserved = 1; |
|
+} |
|
+ |
|
+void del_apple_fn(report_keyboard_t* keyboard_report) { |
|
+ keyboard_report->reserved = 0; |
|
+} |
|
+#endif |
|
diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h |
|
index 9d415a3bfd..8c65b40386 100644 |
|
--- a/tmk_core/protocol/report.h |
|
+++ b/tmk_core/protocol/report.h |
|
@@ -348,6 +348,11 @@ void clear_keys_from_report(report_keyboard_t* keyboard_report); |
|
bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report); |
|
#endif |
|
|
|
+#ifdef APPLE_FN_ENABLE |
|
+void add_apple_fn(report_keyboard_t* keyboard_report); |
|
+void del_apple_fn(report_keyboard_t* keyboard_report); |
|
+#endif |
|
+ |
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c |
|
index e215c90900..e38c0d37f7 100644 |
|
--- a/tmk_core/protocol/usb_descriptor.c |
|
+++ b/tmk_core/protocol/usb_descriptor.c |
|
@@ -75,10 +75,22 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { |
|
HID_RI_REPORT_COUNT(8, 0x08), |
|
HID_RI_REPORT_SIZE(8, 0x01), |
|
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), |
|
+ |
|
+#ifdef APPLE_FN_ENABLE |
|
+ HID_RI_USAGE_PAGE(8, 0xFF), // AppleVendor Top Case |
|
+ HID_RI_USAGE(8, 0x03), // KeyboardFn |
|
+ HID_RI_LOGICAL_MINIMUM(8, 0x00), |
|
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01), |
|
+ HID_RI_REPORT_COUNT(8, 0x01), |
|
+ HID_RI_REPORT_SIZE(8, 0x08), |
|
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), |
|
+#else |
|
// Reserved (1 byte) |
|
HID_RI_REPORT_COUNT(8, 0x01), |
|
HID_RI_REPORT_SIZE(8, 0x08), |
|
HID_RI_INPUT(8, HID_IOF_CONSTANT), |
|
+#endif |
|
+ |
|
// Keycodes (6 bytes) |
|
HID_RI_USAGE_PAGE(8, 0x07), // Keyboard/Keypad |
|
HID_RI_USAGE_MINIMUM(8, 0x00), |
|
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c |
|
index d74f375f66..2ade1350ad 100644 |
|
--- a/tmk_core/protocol/vusb/vusb.c |
|
+++ b/tmk_core/protocol/vusb/vusb.c |
|
@@ -417,10 +417,22 @@ const PROGMEM uchar keyboard_hid_report[] = { |
|
0x95, 0x08, // Report Count (8) |
|
0x75, 0x01, // Report Size (1) |
|
0x81, 0x02, // Input (Data, Variable, Absolute) |
|
+ |
|
+#ifdef APPLE_FN_ENABLE |
|
+ 0x05, 0xFF, // Usage Page (AppleVendor Top Case) |
|
+ 0x09, 0x03, // Usage (KeyboardFn) |
|
+ 0x15, 0x00, // Logical Minimum (0) |
|
+ 0x25, 0x01, // Logical Maximum (1) |
|
+ 0x95, 0x01, // Report Count (1) |
|
+ 0x75, 0x08, // Report Size (8) |
|
+ 0x81, 0x02, // Input (Data, Variable, Absolute) |
|
+#else |
|
// Reserved (1 byte) |
|
0x95, 0x01, // Report Count (1) |
|
0x75, 0x08, // Report Size (8) |
|
0x81, 0x03, // Input (Constant) |
|
+#endif |
|
+ |
|
// Keycodes (6 bytes) |
|
0x05, 0x07, // Usage Page (Keyboard/Keypad) |
|
0x19, 0x00, // Usage Minimum (0) |
To clarify, karabiner does pick up the event. globe+n works, globe+e works, globe+h, and some of the listed behavior doesn't seem to work for me. (with and without karabiner installed)
I tested on several different boards (STM32F411, STM32F303, and RP2040). and seemed to work.
The main different between my implementation and fauxpark's PR is that I've added the code to support it as a keycode