Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Keychron keyboards on Linux + Bluetooth fixes

Here is the best setup (I think so :D) for K-series Keychron keyboards on Linux.

Most of these commands have been tested on Ubuntu 20.04 and should also work on most Debian-based distributions. If a command happens not to work for you, take a look in the comment section.

Make Fn + F-keys work

Keychron Keyboards on Linux use the hid_apple driver (even in Windows/Android mode), both in Bluetooth and Wired modes. By default, this driver uses the F-keys as multimedia shortcuts and you have to press Fn + the key to get the usual F1 through F12 keys.

In order to change this, you need to change the fnmode parameter for the hid_apple kernel module. Here's some documentation on it, but a quick summary can be found below:

  • 0 = disabled: Disable the 'fn' key. Pressing 'fn'+'F8' will behave like you only press 'F8'
  • 1 = fkeyslast: Function keys are used as last key. Pressing 'F8' key will act as a special key. Pressing 'fn'+'F8' will behave like a F8.
  • 2 = fkeysfirst: Function keys are used as first key. Pressing 'F8' key will behave like a F8. Pressing 'fn'+'F8' will act as special key (play/pause).

You can temporarily set the value (for testing, for example) by doing:

# replace <value> below with 0, 1 or 2
# example: echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode
echo <value> | sudo tee /sys/module/hid_apple/parameters/fnmode

Test how the keyboard behaves after each value. Pick the one the works for you. Once you have found the value that works for you, you can make the change permanent:

  1. Create the file /etc/modprobe.d/hid_apple.conf
  2. Add this line to the file: options hid_apple fnmode=<value>, replacing <value> with the one that worked for you in the previous step (0, 1 or 2)
  3. Save the file
  4. Run sudo update-initramfs -u
  5. Reboot

Here's a script, for convenience:

# replace <value> below with the one that worked for you in the previous step (0, 1 or 2)
# example: echo "options hid_apple fnmode=2 | sudo tee /etc/modprobe.d/hid_apple.conf"
# this will erase any pre-existing contents from /etc/modprobe.d/hid_apple.conf
echo "options hid_apple fnmode=<value>" | sudo tee /etc/modprobe.d/hid_apple.conf
# the "-k all" part is not always needed, but it's better to do that for all kernels anyway
sudo update-initramfs -u -k all
sudo systemctl reboot

If get stuck with numpad mode: Double hit F6 or fn + F6.

Enable Bluetooth fast connect config:

If your keyboard takes too long to connect to your computer over Bluetooth (for example, when you press a key and wakes it up), you can enable the Bluetooth fast connect. This usually makes the keyboard connect in less than 1 second.

Some users have reported issues with Bluetooth headphones such as popping audio and general instability, but I haven't experienced anything like that.

  1. Edit the file /etc/bluetooth/main.conf
  2. Uncomment FastConnectable config and set it to true: FastConnectable = true
  3. Uncomment ReconnectAttempts=7 (set the value to whatever number that you want)
  4. Uncomment ReconnectIntervals=1, 2, 3

Disable Autosuspend for USB Bluetooth dongles:

If your keyboard just won't reconnect after sleep, it might be because your Bluetooth card or dongle was automatically suspended by the operating system. You can disable the auto suspend feature for USB Bluetooth dongles by changing the settings for the btusb module.

Note: you might need to target a different module if your Bluetooth controller is somehow using some other module. The options and values themselves might change as well. You need to check the documentation for the module your Bluetooth controller uses. Most USB Bluetooth dongles (and sometimes internal cards that are wired to the USB bus) use btusb. Please check if the btusb module is used by your controller first.

# Disable autosuspend for btusb to make the bluetooth keyboard work again
# this will erase any pre-existing contents from /etc/modprobe.d/btusb_disable_autosuspend.conf
echo "options btusb enable_autosuspend=n" | sudo tee /etc/modprobe.d/btusb_disable_autosuspend.conf
sudo update-initramfs -u

Now reboot your computer, or run:

sudo modprobe -r btusb
sudo systemctl restart bluetooth
sudo modprobe btusb

Enable Bluetooth after waking up from sleep:

When your computer wakes up from sleep mode, the Bluetooth controller might not turn on automatically. In order to force it to do so, we can create a script that will be executed every time the computer comes back from sleep mode.

Note: just like in the previous step, this script assumes your Bluetooth controller uses the btusb module.

# Unload the btusb module, restart the bluetooth service and reload the module again
# post = after the computer wakes up
sudo tee /lib/systemd/system-sleep/bt << EOT
#!/bin/sh
case $1 in
  post)
    modprobe -r btusb
    sleep 1
    service bluetooth restart
    sleep 1
    modprobe btusb
    ;;
esac
EOT
# Now let's make the script executable
sudo chmod +x /lib/systemd/system-sleep/bt

Other resources

If the steps above haven't done it for you, try checking kurgol/keychron. Currently, it only mentions K2 and K6 keyboards, but the tips should work for most Keychron boards.

@sayeg84
Copy link

sayeg84 commented Sep 26, 2022

Is there an alternative that doesn't require root permission?

@andrebrait
Copy link
Author

Is there an alternative that doesn't require root permission?

@sayeg84 I guess not. Every alternative I looked up for changing fnmode requires root.

@dilayn
Copy link

dilayn commented Sep 29, 2022

Hello, I have an issue with the K2 when using Bluetooth and I don't know if this is normal behavior or if it can be fixed. the keyboard seems to go in a semi-asleep state after 3 to 10+ seconds of idling, where the first key press after idling for 3 to 10+ seconds will be slightly delayed. A similar issue seems to occur if I'm holding down a key for 3 to 10+ seconds, where releasing the key won't immediately register

So for example if I'm playing a game and I'm holding W to move forward for 3 to 10+ seconds or more and I release W to stop moving, my character would move a few more steps before stopping. Similarly if I stand idle and do nothing for 3 to 10+ seconds and then I press W to move forward, my character would only move after a short delay.

The reason I say 3 to 10+ seconds and not 3+ seconds is because this sometimes happens if it's between 3 to 10 seconds but will ALWAYS happen if it's more than 10 seconds.

Any ideas? This never happened with the 2.4g wireless keyboard I used before this.

@andrebrait
Copy link
Author

Hello, I have an issue with the K2 when using Bluetooth and I don't know if this is normal behavior or if it can be fixed. the keyboard seems to go in a semi-asleep state after 3 to 10+ seconds of idling, where the first key press after idling for 3 to 10+ seconds will be slightly delayed. A similar issue seems to occur if I'm holding down a key for 3 to 10+ seconds, where releasing the key won't immediately register

So for example if I'm playing a game and I'm holding W to move forward for 3 to 10+ seconds or more and I release W to stop moving, my character would move a few more steps before stopping. Similarly if I stand idle and do nothing for 3 to 10+ seconds and then I press W to move forward, my character would only move after a short delay.

The reason I say 3 to 10+ seconds and not 3+ seconds is because this sometimes happens if it's between 3 to 10 seconds but will ALWAYS happen if it's more than 10 seconds.

Any ideas? This never happened with the 2.4g wireless keyboard I used before this.

Bluetooth is a completely different thing. The K2 has a key combo to disable sleep. You can try that. It's still supposed to sleep, however.

Did you try enabling the FastConnect?

@KuleRucket
Copy link

KuleRucket commented Sep 29, 2022

@dilayn I experienced something similar when using the K7 3m away from the PC while sitting on my sofa. First I was using the on-board bluetooth adapter. Next I tried with a small TP-Link dongle which made it better but didn't fix it. However this problem only went away when I got a long range Class 1 BT adapter and it works perfectly now even at 10m through 2 walls.

None of my other BT devices had a problem but I think the keyboard just has quite a weak BT signal compared to e.g. an xbox controller.

@dilayn
Copy link

dilayn commented Sep 29, 2022

Yes, and I also disabled the AutoSuspend... and I tried disabling the autosleep as well, still the same.

@dilayn
Copy link

dilayn commented Sep 29, 2022

@dilayn I experienced something similar when using the K7 3m away from the PC while sitting on my sofa. First I was using the on-board bluetooth adapter. Next I tried with a small TP-Link dongle which made it better but didn't fix it. However this problem only went away when I got a long range Class 1 BT adapter and it works perfectly now even at 10m through 2 walls.

None of my other BT devices had a problem but I think the keyboard just has quite a weak BT signal compared to e.g. an xbox controller.

hmm, then this could be due to that fact I have the BT dongle plugged into a USB hub? The USB hub is wall powered and is connected to the PC with a 3m cable

@dilayn
Copy link

dilayn commented Sep 29, 2022

yep that fixed it... I gotta find a good class 1 long range adapter then. any recommendation?

@andrebrait
Copy link
Author

yep that fixed it... I gotta find a good class 1 long range adapter then. any recommendation?

What did you do? Move the BT dongle off the hub to a USB port on the computer itself?

Is your USB hub 3.0? USB 3.0 hubs are known to cause interference with some 2.4GHz devices.

@dilayn
Copy link

dilayn commented Sep 29, 2022

Yes and yes, but for some reason the issue is completely fixed now even when I put the dongle back in the hub... I tried unplugging and re-pairing earlier which didn't help. The only different thing I tried right now is pairing the keyboard with the dongle connected to a PC USB port before moving the dongle back to the hub. Interesting...

@KuleRucket
Copy link

I have the Bluetooth 5.0 version of this:
https://www.amazon.de/-/en/Bluetooth-Distance-Transmitter-Compatible-Smartphone-black-gold/dp/B09NVPTS6J?ref_=ast_sto_dp&th=1

The 5.0 version works well in Linux, but can't say whether the 5.1 version would or not.

@lbrealdev
Copy link

Thanks for the solution, performing a quick test, I see a total difference, but I still have some characters not working, for example the "|" (pipe). Can anyone tell me where to go, maybe it would be necessary to remap the keys ?

@lbrealdev
Copy link

lbrealdev commented Oct 21, 2022

Thanks for the solution, performing a quick test, I see a total difference, but I still have some characters not working, for example the "|" (pipe). Can anyone tell me where to go, maybe it would be necessary to remap the keys ?

I come here to say that I managed to solve my problem and configure the keys I needed, and in the end my configuration looked like this:

Fn keys:

echo "options hid_apple fnmode=0" | sudo tee /etc/modprobe.d/hid_apple.conf

Keyboard layout configuration /etc/default/keyboard:

# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="us,br"
XKBVARIANT=""
XKBOPTIONS="grp: alt_shift_toggle"

BACKSPACE="guess"

NOTE: To make everything work correctly it is necessary to switch between the layouts configured on the keyboard, of course as I was already used to this, for me it is not a difficult task.

Switch between configured keyboard layouts:

Ctrl + Alt + Shift

If it helps, my setup is:

Thanks for that!!

@RemcoSchrijver
Copy link

Adding the hid_apple.conf file makes it such that wired mode no longer works for at least the K4 keyboard, when it is working fine for other devices like my android phone. But setting fnmode manually does work so that is a thing to note when doing this.

@rodrmigu
Copy link

Worked on my K1, and solved both issues, Bluetooth slow connection, and Fn+Keys.
Thanks.

@nilsmagnus
Copy link

Thanks. Confirmed on a thinkpad z13 with ubuntu 22.04 and keychron k8.

@madushan1000
Copy link

Looks like ubuntu lts 22.04 5.15 kernel has this patch backported (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/drivers/hid/hid-apple.c?id=v5.19&id2=v5.18). So setting fnmode to 3 works. But for some reason it's not the default.

@kespineira
Copy link

kespineira commented Nov 7, 2022

Hi! I'm trying to connect my K6 by bluetooth but not once it establishes the connection it disconnects instantly. I'm using Ubuntu 22.04.

@tutikaka
Copy link

tnx

@hwilson03
Copy link

Sorted a lot of problems for me on Keychron K3

@ErdemOzgen
Copy link

sudo mkinitcpio -P can be use for arch based system instead of sudo update-initramfs -u

@gavingc
Copy link

gavingc commented Nov 17, 2022

Success & Thanks to Everyone

Keychron K4V2 on Debian 11 (11.5 Bullseye) w/Keychron Firmware

Out of the box, fnmode reported as 1 by:
cat /sys/module/hid_apple/parameters/fnmode

fnmode = 0 or 2 (I chose 2 but both seemed to work the same)

Keyboard switches: Windows/Android, Bluetooth or Cable.

As per included instructions, press "fn + x + l" keys together for 4 seconds.
(until keyboard lights flash; yes lower case works)
This toggles between Multimedia Keys and F1-F12 as first layer.

Caps Lock LED is red only and works as expected.

Num Lock LED is red only and works as expected, but it is possible to get into a state where it is always-off by playing with the NumLock on laptop keyboard or Plasma Startup settings.
Personally, I'd like an always-off state that was reliable as I have the OS force Num Lock function on, so don't need the red LED amongst my chosen RGB.
In either case the Num Lock key still works as expected.

Keyboard 'model' used: Generic 105-key PC (intl.).
Keyboard layout: us.

Bonus:
Fn + F5 adjusts RGB brightness down.
Fn + F6 adjusts RGB brightness up.
Fn + lamp key toggles RGB on/off and keeps brightness setting.

Would be fantastic to see QMK fully support these keyboards + Bluetooth - fingers crossed!

@Raremaa
Copy link

Raremaa commented Dec 13, 2022

Tks!

@edmarola
Copy link

My hero, thank you for this, i was already a bit disaaspointed that my keyboard was not working as expected in the first time but you saved my day! Thank you!

@eniocosta
Copy link

Thank you so much! It worked on my Keychron K2 with Ubuntu 18.04.6!

@Igeljaeger
Copy link

Thank you! It worked on Debian 11 Bullseye

@BiancaCristina
Copy link

Thank you, it worked on Debian 11!

@hughesjs
Copy link

hughesjs commented Jan 21, 2023

I'm having an issue where my K8P will pair with the laptop then immediately disconnect and won't connect again... Any ideas?

Not really sure where I'd even start debugging it

@andrebrait
Copy link
Author

I'm having an issue where my K8P will pair with the laptop then immediately disconnect and won't connect again... Any ideas?

Not really sure where I'd even start debugging it

The K8 Pro is an entirely different beast. It's based on a fork of QMK with some Keychron-specific code (if it hasn't been upstreamed yet). I'd recommend you try to look up information on Bluetooth on QMK boards and the issue you're having.

@hughesjs
Copy link

hughesjs commented Jan 21, 2023

@andrebrait - Gutted, cheers though

Might be worth putting a note in the Gist that it doesn't apply to the K8P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment