zmkfirmware / zmk

ZMK Firmware Repository
https://zmk.dev/
MIT License
2.61k stars 2.68k forks source link

Media Eject not Functional on macOS #2383

Open jeffsf opened 1 month ago

jeffsf commented 1 month ago

This key code can be sent by QMK and is used by various macOS shortcuts including lock screen and sleep displays. See further https://support.apple.com/en-us/102650

LS(LC(K_EJECT)) can be seen sending and releasing the modifiers, but the key code for K_EJECT is not seen. C_EJECT was briefly checked and did not have apparently different behavior. No logs were collected.

QMK VIA support works with C(S(KC_EJCT)), sleeping the displays as expected. Confirmed on three different keyboards.

Deficiency documented at https://zmk.dev/docs/codes/media and confirmed on

commit 8c6bda26 (HEAD -> zmk-default)
Author: Peter Johanson <peter@peterjohanson.com>
Date:   Fri Jul 5 15:30:44 2024 -0600
caksoylar commented 1 month ago

I think this is a shortcoming of modifier functions. They only seem to work with keyboard usage page, not consumer usage page. I don't know if there is an exact existing issue for this, but #2329 might be related in cause.

caksoylar commented 1 month ago

Using a macro to send modifiers and the eject key as separate press/release events could be a workaround.

jeffsf commented 4 weeks ago

Perhaps I have misunderstood macros, but the following does not provide the behavior that QMK can

ZMK_MACRO(d_slp, bindings = \
      <&macro_press &kp LSHFT>, \
      <&macro_press &kp LCTRL>, \
      <&macro_tap &kp K_EJECT>, \
      <&macro_release &kp LCTRL>, \
      <&macro_release &kp LSHFT>; \
      )

PacketLogger seems to strip the payload, so I can't snoop over Bluetooth. I'm not seeing the Media Eject key in the QMK trace using the QMK browser tool. I'm guessing it is swallowed by the OS before getting to the browser.

Looking into other ways to diagnose. Suggestions welcomed.

caksoylar commented 4 weeks ago

From what I can dig up in QMK, it uses a different consumer keycode corresponding to HID_USAGE_CONSUMER_STOP_EJECT. It looks like the alias C_STOP_EJECT can be used for that.

jeffsf commented 4 weeks ago

It works as expected with

ZMK_MACRO(d_slp, bindings =     \
      <&macro_press &kp LSHFT>, \
      <&macro_press &kp LCTRL>, \
      <&macro_tap &kp C_STOP_EJECT>, \
      <&macro_release &kp LCTRL>, \
      <&macro_release &kp LSHFT>; \
)

The direct form did not immediately work

#define DISPLAY_SLEEP  LS(LC(C_STOP_EJECT))
#define D_SLP  &kp DISPLAY_SLEEP
caksoylar commented 4 weeks ago

I think that's consistent with my theory above, where modifier functions don't work with consumer keycodes.