qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
17.97k stars 38.64k forks source link

How to set NUM_LOCK On regardless it's state? #2164

Closed K-rnivoro closed 6 years ago

K-rnivoro commented 6 years ago

For my Commodore 64 (and it's joysticks) project, I need to set Num Lock to be always on in order to get the joysticks mapped as numpad keys. Thing is I don't want/need the Num Lock key in my keymap because there is no numpad, so I need a way to check the Num Lock status and activate it in case it is off.\ Any ideas?

drashna commented 6 years ago

This is pretty simple to do, and I do so for my numpad: https://github.com/qmk/qmk_firmware/blob/master/keyboards/handwired/woodpad/keymaps/drashna/keymap.c#L111

Just add this to your keymap file:

void led_set_keymap(uint8_t usb_led) {
  if (!(usb_led & (1<<USB_LED_NUM_LOCK))) {
    register_code(KC_NUMLOCK);
    unregister_code(KC_NUMLOCK);
  }
}
K-rnivoro commented 6 years ago

Good! I'll try it ASAP!! Thanks Drashna!

drashna commented 6 years ago

Welcome!

And just to explain what's happening, the "led_set_keymap" is called in initialization and any time the "lock" state is changed for any of the states.

This checks the NUM LOCK state, and if it's disabled, sends the "numlock" key press to enable it.

skullydazed commented 6 years ago

Did this work for you @K-rnivoro?

K-rnivoro commented 6 years ago

Oh, sorry I didn't reply!! It worked like a charm!! Thanks Skully!!

2018-02-01 17:12 GMT-03:00 skullydazed notifications@github.com:

Did this work for you @K-rnivoro https://github.com/k-rnivoro?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-362387614, or mute the thread https://github.com/notifications/unsubscribe-auth/AacoqIs1QpctJs3fIWq3uMQQo_hfVSpRks5tQhqogaJpZM4RE-7x .

lukaus commented 6 years ago

If I wanted to just check numlock status one time when my board is plugged in and set numlock on if it is off, how would I do that? I'm using an Ergodox EZ if that makes any difference

Also, drashna, I keep running into you for help with QMK (here and on reddit), just want to say I appreciate your help a lot!

drashna commented 6 years ago

Untested:

void matrix_init_user (void) {
  if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) {
      register_code(KC_NUMLOCK);
      unregister_code(KC_NUMLOCK);
  }
}

I think that should force numlock on, but only when the keyboard starts.

K-rnivoro commented 6 years ago

Yes. I tried and works ok ONLY when the keyboard starts. Try with two KB. Turn off NumLock with a normal one and plug the hacked one after that.

El 8 mar. 2018 15:53, "Drashna Jaelre" notifications@github.com escribió:

Untested:

void matrix_init_user (void) { if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) { register_code(KC_NUMLOCK); unregister_code(KC_NUMLOCK); } },

I think that should force numlock on, but only when the keyboard starts.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-371586236, or mute the thread https://github.com/notifications/unsubscribe-auth/AacoqMb3Vr9FM5b2EMAechdsucWmsWv_ks5tcX4wgaJpZM4RE-7x .

drashna commented 6 years ago

Any issues with having this closed?

K-rnivoro commented 6 years ago

No. Sorry. Do I close it or you do it?

El dom., 25 mar. 2018 0:27, Drashna Jaelre notifications@github.com escribió:

Any issues with having this closed?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-375942599, or mute the thread https://github.com/notifications/unsubscribe-auth/AacoqPQtuFD-_fcO-7ms588wH_jJxtU2ks5thw6sgaJpZM4RE-7x .

drashna commented 6 years ago

Either of us can. I've just been cleaning up issues.

I've closed it now. If needed, reopen it or open a new issue.

K-rnivoro commented 6 years ago

I'm fine with the solución you gave me. Anyway I found that VICE emulator works either way, doesn't matter if NUMLOCK is on or off. I've had a very warm reception on the Retro Computer Community with my Commodore 64 keyboard. (Turns out to be better than a commercial stuff like Keyrah). I'm planning to publish it, also as part of qmk, would you help me with the formalities and stuff?

Thanks for everything.

El 25 mar. 2018 16:45, "Drashna Jaelre" notifications@github.com escribió:

Either of us can. I've just been cleaning up issues.

I've closed it now. If needed, reopen it or open a new issue.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-375997653, or mute the thread https://github.com/notifications/unsubscribe-auth/AacoqPicujK2KbuFC4DV1M64eZjwfctQks5th_PFgaJpZM4RE-7x .

drashna commented 6 years ago

Awesome.

And nice to hear that.

As for making part of QMK, definitely. It should probably go into the handwired section though. And if you want/would, create a new issue for discussion on that.

u17194907425 commented 3 years ago

I hope it is OK to use this issue to continue answering the initial question as the initial one seems to get outdated.

This code works now. The code posted by @drashna 3 years ago does not seems to work any more

void led_set_user(uint8_t usb_led) {
  if (!(usb_led & (1<<USB_LED_NUM_LOCK))) {
    tap_code(KC_NLCK);
  }
}

Note that the led_set_user seems to be marked as deprecated in here https://beta.docs.qmk.fm/using-qmk/hardware-features/feature_led_indicators

K-rnivoro commented 3 years ago

Thank

I hope it is OK to use this issue to continue answering the initial question as the initial one seems to get outdated.

This code works now. The code posted by @drashna 3 years ago does not seems to work any more

void led_set_user(uint8_t usb_led) {
  if (!(usb_led & (1<<USB_LED_NUM_LOCK))) {
    tap_code(KC_NLCK);
  }
}

Note that the led_set_user seems to be marked as deprecated in here https://beta.docs.qmk.fm/using-qmk/hardware-features/feature_led_indicators

Thanks!!! I'll try it!

Shfty commented 2 years ago

As a heads-up to anyone else looking to force numlock, the code above will render a ZSA Moonlander unusable if added to a custom keymap.c

I'm unsure if this is an artifact of using the ZSA fork for compatibility with their Oryx software, or a consequence of some underlying LED implementation. The board powers on and displays a single blue LED, but is otherwise unresponsive until being reflashed with a backup firmware.

Myridium commented 2 years ago

Does anyone have a solution that works today??

K-rnivoro commented 2 years ago

Kind of funny I wrote this question almost four years ago and still no absolute answer...

El dom, 3 oct 2021 a las 23:22, Myridium @.***>) escribió:

Does anyone have a solution that works today??

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-933093368, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGTSRKBZB2FXFWRQJRNLHVLUFEMX5ANCNFSM4EIT53YQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

fauxpark commented 2 years ago

The problem is that the num/caps/scroll lock state is not managed by the keyboard, so all you have to go on is whether the host has told the keyboard to turn on the LED, and the exact behaviour is inconsistent across OSes. On Windows, for example, the state is shared across all keyboards, but macOS treats each keyboard individually and doesn't recognise num lock as num lock anyway.

Zereef commented 2 years ago

So does any have a good way to do it? NUM_LOCK always on regardless of its state

ErinCall commented 1 year ago

Hello from the future! I have this working. Drashna's "untested" suggestion was largely correct, except for putting it in matrix_init_user. It seems like that's just too early in the process.

I have my numpad on a separate layer, so I moved the "turn it on if it's off" code to layer_state_set_user:

uint32_t layer_state_set_user(uint32_t state) {
  switch(biton32(state)) {
  case NUMPAD:
    // turn on numlock, if it isn't already on.
    if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) {
      register_code(KC_NUMLOCK);
      unregister_code(KC_NUMLOCK);
    }
    break;
  }
  return state;
};

If you aren't using a separate layer I imagine you could do something similar in process_record_user. Sending a keypress depending on the LED state is a sound approach, it's just a question of when and where it happens.

(I don't know if any of y'all're still thinking about this, but since this is one of the top search results I figured I'd fix the DenverCoder9 situation 🙂)

K-rnivoro commented 1 year ago

Thanks Erin!! It seems this has been around for years. Look how old my question is...

El sáb, 15 abr 2023 a las 12:38, Erin Call @.***>) escribió:

Hello from the future! I have this working. Drashna's "untested" suggestion https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-371586236 was largely correct, except for putting it in matrix_init_user. It seems like that's just too early in the process.

I have my numpad on a separate layer, so I moved the "turn it on if it's off" code to layer_state_set_user:

uint32_t layer_state_set_user(uint32_t state) { switch(biton32(state)) { case NUMPAD: // turn on numlock, if it isn't already on. if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) { register_code(KC_NUMLOCK); unregister_code(KC_NUMLOCK); } break; } return state; };

If you aren't using a separate layer I imagine you could do something similar in process_record_user. Sending a keypress depending on the LED state is a sound approach, it's just a question of when and where it happens.

(I don't know if any of y'all're still thinking about this, but since this is one of the top search results I figured I'd fix the DenverCoder9 https://xkcd.com/979/ situation 🙂)

— Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-1509873916, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGTSRKHJ6LJA3RNPB64URN3XBK6I7ANCNFSM4EIT53YQ . You are receiving this because you were mentioned.Message ID: @.***>

u17194907425 commented 6 months ago

It looks like now the above methods with USB_LED_NUM_LOCK will no longer work. For me the following works in the keymap.c:

bool led_update_user(led_t led_state) {
    if (!led_state.num_lock) {
        tap_code(KC_NUM_LOCK);
    }
    return true;
}
K-rnivoro commented 6 months ago

Good to know! Thanks!

El vie, 23 de feb de 2024, 18:27, u17194907425 @.***> escribió:

It looks like now the above methods with USB_LED_NUM_LOCK will no longer work. For me the following works in the keymap.c:

bool led_update_user(led_t led_state) { if (!led_state.num_lock) { tap_code(KC_NUM_LOCK); } return true; }

— Reply to this email directly, view it on GitHub https://github.com/qmk/qmk_firmware/issues/2164#issuecomment-1962011905, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGTSRKGYTH3G3XKWKXY3D73YVECUHAVCNFSM4EIT53Y2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOJWGIYDCMJZGA2Q . You are receiving this because you were mentioned.Message ID: @.***>