-
-
Notifications
You must be signed in to change notification settings - Fork 38.4k
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
[Feature Request] [PR Planning] macOS Mission Control and Launchpad keys #10111
Comments
There was already a similar PR here: #4762 |
Hi Ryan, I agree -- if those Is this what you meant by "one spot left"? Were you referring to the |
From one of my comments on that PR:
Basically, it would be best if there were a single contiguous range for these keycodes, instead of placing them wherever just because there is free space. |
Hi Ryan, I got it. Having the media keys fragmented all over the space isn't good for maintainability in the long term. I don't think I'll push through with this PR using the current keycode assignments. I think this issue can be closed unless anyone would like to chime in with additional comments. For people who wish to have "AC Desktop Show All Windows" and "AC Desktop Show All Applications" keys on their keyboards right now, there is a way to do this using user-defined keycodes and calling |
Feel free to leave this issue open, as I'd also like to see these keycodes added. It's really just the removal of those deprecated FN keycodes blocking this, and I've already done a ton of work to migrate most of the instances over in user keymaps. I think there's just a handful left to do. |
Here's some code I came up with that lets me use those two keycodes in the meantime: https://github.com/controlxcv/qmk_firmware/commit/d1aab46cf76edd3ab630678582722f1af758662f The summary of it is that I use the Custom Keycodes feature, and call Of course, there might be better approaches. I'm very much open to comments and suggestions. |
This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity occurs. |
@controlxcv , is there a full list of hex keycodes that Mac uses? May you share it. I am curious where you found these?
|
They're taken from the HID usage tables, in the Consumer page (page 117). There are a lot of usages defined here, but most of them are not actually implemented in Windows/macOS/Linux. |
Thanks @fauxpark I'm blind I just saw the comment which links to that PDF |
@controlxcv I tried your code but its not working on my Mac 10.14.6 . Is there any additional configuration? I have logged it by doing this and it is showing successfully on QMK Toolbox. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if(_KC_MCON == keycode || _KC_LPAD == keycode){
uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed);
}
// switch case for handling mac keycodes goes here
} |
@geocine Can you share the full text of your keymap.c, and maybe an excerpt of your log? |
@controlxcv This is my entire keymap, excuse for the wall of text #include QMK_KEYBOARD_H
/*----------------------------------------------------------
* Key codes
* https://www.usb.org/sites/default/files/hut1_2.pdf
*/
#define _KC_MCON _KC_SHOW_ALL_WINDOWS
#define _KC_LPAD _KC_SHOW_ALL_APPS
enum my_keycodes {
_KC_SHOW_ALL_WINDOWS = SAFE_RANGE,
_KC_SHOW_ALL_APPS
};
enum my_consumer_usages {
_AC_SHOW_ALL_WINDOWS = 0x29F,
_AC_SHOW_ALL_APPS = 0x2A0
};
enum my_layers {
_BASE = 0,
_RISE = 1
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
BL_BRTG, _KC_MCON, LT(1,KC_MUTE),
RGB_M_T, KC_1, KC_KP_2,
RGB_TOG, KC_LCTRL, KC_9),
[_RISE] = LAYOUT(
_______, _______, _______,
_______, _______, _______,
_______, _______, _______)
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// If console is enabled, it will print the matrix position and status of each key pressed
#ifdef CONSOLE_ENABLE
if(_KC_MCON == keycode || _KC_LPAD == keycode){
uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed);
}
#endif
switch (keycode) {
case _KC_SHOW_ALL_WINDOWS:
if (record->event.pressed) {
host_consumer_send(_AC_SHOW_ALL_WINDOWS);
uprint("_AC_SHOW_ALL_WINDOWS\n");
} else {
host_consumer_send(0);
}
return false; /* Skip all further processing of this key */
case _KC_SHOW_ALL_APPS:
if (record->event.pressed) {
host_consumer_send(_AC_SHOW_ALL_APPS);
uprint("_AC_SHOW_ALL_APPS\n");
} else {
host_consumer_send(0);
}
return false; /* Skip all further processing of this key */
default:
return true; /* Process all other keycodes normally */
}
}
void keyboard_post_init_user(void) {
#ifdef RGBLIGHT_ENABLE
// Call the post init code.
rgblight_disable();
rgblight_enable(); // enables Rgb, without saving settings
rgblight_sethsv(180, 255, 255); // sets the color to teal/cyan without saving
#endif
breathing_toggle();
backlight_level(2);
}
#ifdef ENCODER_ENABLE
void encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
switch(layer_state){
case _RISE:
if (clockwise){
tap_code(KC_RIGHT);
} else{
tap_code(KC_LEFT);
}
break;
default:
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
break;
}
}
}
#endif
#ifdef OLED_DRIVER_ENABLE
void oled_task_user(void) {
// Host Keyboard Layer Status
oled_write_P(PSTR("Hello STM32F103CBT6!"), false);
// Host Keyboard LED Status
led_t led_state = host_keyboard_led_state();
oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
}
#endif Below is my logs
|
@geocine Gut feel tells me that the problem has something to do with the order of the defines and enums. I suspect that _AC_SHOW_ALL_WINDOWS isn't being substituted properly in process_record_user(). Can you try plugging in the actual hex code for _AC_SHOW_ALL_WINDOWS into host_consumer_send()? Basically this:
You can also try logging the actual value of _AC_SHOW_ALL_WINDOWS in your uprintf() statements. Let me know how it goes. |
@controlxcv I'm running out of clues , I added some logs to show the actual value here , which is correct
I also passed the actual value directly, but that didn't work either
I am on tag |
@geocine 0x29F is the hexadecimal representation of decimal 671 -- they're the same. It's been a while since I ran this code, to be honest. Let me bring out my macropad and compile against the current codebase to see if anything has changed. |
@geocine I compiled your code against the latest master and it worked on my 3x3 macropad. Pressing the (0,1) key on my pad successfully launches Mission Control. I'm running macOS Catalina 10.15.7 (19H114) on a 2017 MacBook Air (Intel). My macropad is I did comment out the If you have a tag here in GitHub that you can share so I can see your entire codebase, it might be able to help. Meanwhile let me dig around a bit more. |
@controlxcv Here is the source https://github.com/geocine/f103x2 I am using an STM32F103 controller, I don't think that should be an issue as the keycodes are being sent based on the logs. |
@geocine This is an original hardware design, I presume? Let me take a bit of time to read your files. |
@controlxcv Yes it is , its a 3x3 matrix, but the (0,2) is an encoder |
@geocine Can you check if EXTRAKEY_ENABLE is really defined where it's supposed to be defined? I mean, not just by checking if it's in rules.mk but by doing For common boards like Preonic and XD75, it's enough to check rules.mk, but since you're making a full custom, it might be worthwhile to do deeper checks. I'm not sure, but this might be a good place to put in a debug uprint:
Unfortunately, full custom boards are beyond my understanding of QMK. What I can say is that you need to make sure that Usage IDs from the Consumer page in the USB HID spec are being properly sent by your board to your computer. As to how exactly, I think I'll have to defer this to someone with better understanding of lower level stuff. |
So... based upon what I'm reading here, it seems like this issue has not yet been fixed and is still floating out there hoping for some soul to come by and resolve. I'm trying to get a Monstargear XO87 RGB working with MacOS-specific media keys, like launching Mission Control and Launchpad, and it looks like I'm hitting a brick wall here since I don't exactly see any sort of solid instructions to make this happen anywhere on the web other than downloading yet another app to like BetterTouchTool to try to work around the issue. What I'm also reading here is that @controlxcv 's program didn't quite resolve the issue, either.... This is really frustrating to see, especially as custom keebs are starting to become much more popular with working from home now a global phenomenon. There's probably other folks out there in my position that kinda gave up, too. It's a strange irony that QMK and its assorted tools function perfectly on the MacOS Terminal, but aren't able to flash a keyboard to make it work with all Mac-specific keycodes. If Keychron was able to get their MacOS media keys working on their boards, there must be some way QMK can get it working, too. |
@DeepSeaDelight My conversation with geocine was a bit of a sidetrack; he was designing a full custom board that he couldn't get to work, and it was only minimally related to this issue. You will want to look at the first comment of @fauxpark -- I was able to create working code, but we need to wait for some refactorings in the framework code before we can introduce more keycodes. Simply put, there are currently no more free slots and the refactor will solve that. If you're just programming firmware for a personal keyboard, you can implement Mac keys in your keymap.c instead of putting them in framework-level code. Let me share the proof-of-concept code for my macropad that has proper Launchpad and Mission Control support: https://github.com/controlxcv/qmk_firmware/tree/dev/keyboards/ymdk/ymd09/keymaps/controlxcv Let me know if you have any questions. Regards, |
@DeepSeaDelight I edited the link just now. Please refresh. Sorry about that! |
@controlxcv Wow, quick response! Thank you for letting me know what happened! So, I'm seeing what you did in the keymap.c file, but now I'm trying to figure out how to integrate that bit of code into the .HEX file that generates from the online QMK Configurator. I then take that .HEX file and shove it into the QMK Toolbox and flash from there. Any ideas? What portion of your proof-of-concept do I change in order to trigger Mission Control/Expose and Launchpad on F3 and F4 of an ANSI TKL layout, respectively? |
@DeepSeaDelight First, some non-ideal news: QMK Configurator can't compile custom C code. https://docs.qmk.fm/#/configurator_default_keymaps?id=custom-code
In addition to this, I don't think what you said about integrating code into the HEX file is possible. HEX files are compiled machine code and are practically impossible to modify by hand. You'll really need to take the C code route at the moment if you want to have those two keycodes on your keyboard. It will be a different story of course if those two codes have already been integrated into the framework. Perhaps now is a good time to challenge yourself with writing your firmware in C. :) The extra code to enable those two keys isn't really that much. That said, the underlying principle is straightforward. Mission Control and Launchpad are defined in the USB HID standard's "Consumer" page as shown below. (source: https://www.usb.org/sites/default/files/hut1_2.pdf)
QMK on the other hand supports the creation of new keycodes that can do practically anything you want through the QMK also has a function called Put those three concepts together and you'd come up with code like this: enum my_keycodes {
KC_MISSION_CONTROL = SAFE_RANGE,
KC_LAUNCHPAD
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case KC_MISSION_CONTROL:
if (record->event.pressed) {
host_consumer_send(0x29F);
} else {
host_consumer_send(0);
}
return false; /* Skip all further processing of this key */
case KC_LAUNCHPAD:
if (record->event.pressed) {
host_consumer_send(0x2A0);
} else {
host_consumer_send(0);
}
return false; /* Skip all further processing of this key */
default:
return true; /* Process all other keycodes normally */
}
} With that code in your keymap.c, you'd be able to use Do let me know if you have any questions. Compile the default firmware for your board as a starting point, and then expand from there. Good luck! |
I'm seeing some odd behavior in my implementation of this. In my macOS System Preferences, I have mapped 'Show Launchpad' to F4. I have Notably this isn't the case with |
I was just trying to do this & came across this thread, for the benefit of future travellers I'm probably gonna stick with the default key sequences & use e.g. |
closing: #19884 |
Feature Request Type
Description
Hello, I'm getting ready to submit a Pull Request to add Mission Control and Launchpad keycodes (link below).
https://github.com/controlxcv/qmk_firmware/tree/pr_mac_desktop_keys
I'm not sure whether to target
master
ordevelop
for this one. The PR Checklist says to targetdevelop
for changes to Core, but in this case I'm not sure if this falls into "real" Core territory even if the changes are to files inquantum
andtmk_core
. My current impression is that Core functionality refers to more of low level microcontroller code and less of adding new keycodes.I've already tested my changes by running
make all:default
. I've also flashed the keycodes on my development macropad and tried them out on my computers without problems.I'd appreciate any comments or advice. Thanks!
The text was updated successfully, but these errors were encountered: