Skip to content

Instantly share code, notes, and snippets.

@andrebrait
Last active October 7, 2024 15:22
Show Gist options
  • Save andrebrait/961cefe730f4a2c41f57911e6195e444 to your computer and use it in GitHub Desktop.
Save andrebrait/961cefe730f4a2c41f57911e6195e444 to your computer and use it in GitHub Desktop.
Keychron keyboards on Linux + Bluetooth fixes

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

Note: many newer Keychron keyboards use QMK as firmware and most tips here do not apply to them. Maybe the ones related to Bluetooth can be useful, but everything related to Apple's keyboard module (hid_apple) on Linux, won't work. As far as I know, all QMK-based boards use the hid_generic module instead. Examples of QMK-based boards are: Q, Q-Pro, V, K-Pro, etc.

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 (NOT FOR QMK-BASED BOARDS)

Older Keychron keyboards (those not based on QMK) use the hid_apple driver on Linux, even in the 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.

@hughesjs
Copy link

hughesjs commented Mar 7, 2023 via email

@noelbautista91
Copy link

My Keychron K8 had connectivity issues with Bluetooth when connecting to my Linux/Windows PC, but not on my MacBook Pro. My symptoms were choppy connection several times an hour, connection taking a while after the keyboard goes on suspend, repeated key presses likeeeeee thisssss. Enabling fast connect fixed ALL my issues on Linux. Thank you! 👍

@ZANX3Y
Copy link

ZANX3Y commented Mar 31, 2023

Never would have figured it out on my own. Thank you!

@flooijdt
Copy link

flooijdt commented Apr 1, 2023

In OpenSUSE with KDE, the main.config file is located at /usr/share/doc/packages/bluez. In OpenSUSE with GNOME, it is in the same directory as related in this gist (/etc/bluetooth/).
Thanks a lot for the gist! This bluetooth problem was getting on my nerves!

@javierspn
Copy link

Just to point out: On Debían 11.6 my Bluetooth connection to my K2 keyboard wasn’t stable between reboots and many times I had to reconfigure it.

Enabling AutoConnect and FastConnect as per the instructions above fixed it. It takes however 5 to 10 seconds to connect but I am a patient man.

@mttkay
Copy link

mttkay commented Apr 21, 2023

Just a side note that this will work with any keyboard that uses the hid_apple driver not just Keychrons. I use the fnmode module setting for my NuPhy Air as well to turn on F-keys by default.

@Katharta
Copy link

Katharta commented Jun 1, 2023

Wow, FastConnectable = true made such a huge difference. I no longer have to fumble with switching the keyboard off and on over and over until it reconnects. Thank you for sharing this!

@cofeek-codes
Copy link

Thanks a lot. There is dracut --regenerate-all --force command to update initramfs for Fedora.

@h-braun
Copy link

h-braun commented Jun 6, 2023

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.

@RemcoSchrijver Thanks! I tried nearly everything, and really was confused as why bluetooth mode is working, but wired mode is not. I suspected a faulty cable but lsusb was clearly showing the keyboard. Is there a workaround to not use hid_apple.conf but somehow still have the fn keys working in fkeysfirst mode?

@RemcoSchrijver
Copy link

RemcoSchrijver commented Jun 7, 2023

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.

@RemcoSchrijver Thanks! I tried nearly everything, and really was confused as why bluetooth mode is working, but wired mode is not. I suspected a faulty cable but lsusb was clearly showing the keyboard. Is there a workaround to not use hid_apple.conf but somehow still have the fn keys working in fkeysfirst mode?

@h-braun what I ended up doing was to make a systemd service that calls a small script to add the manual switch to fix the fnmode.

So to replicate my setup do the following commands:

nano /etc/init/keyboard-fix.sh

Add the following content to the file and save it:

#!bin/bash
sleep 15s
echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode

Now to create the systemd service I did the following:

nano /etc/systemd/system/keyboard-startup-fix.service

Fill the file with the following content:

[Unit]
Description=Keychron enable fn keys mode

[Service]
ExecStart=/etc/init/keyboard-fix.sh

[Install]
WantedBy=multi-user.target

And then of course the standard things to enable your service:

sudo systemctl daemon-reload
sudo systemctl enable keyboard-startup-fix.service
sudo systemctl start keyboard-startup-fix.service

And now at every reboot your fn keys are setup like you want them to.

@jstiefel
Copy link

jstiefel commented Aug 8, 2023

Thanks for the setup instructions. Using Keychron K4 v2 on Ubuntu 20.04, I only needed to apply the following two fixes:

  • Switch Fnmode to mode 2 so that I can select the mode directly on the keyboard
  • Disable autosuspend in GRUB

I had a tiny delay after 5s of inactivity in BT mode on Ubuntu 20.04. Same applied for my BT mouse using the internal BT module. The solution with autosuspend in modprobe.d didn't work for me, but changing it in GRUB (for btusb AND usbcore) did:

sudo nano /etc/default/grub
# Add "GRUB_CMDLINE_LINUX_DEFAULT="quiet splash btusb.enable_autosuspend=n usbcore.autosuspend=-1 usbcore.autosuspend_delay_ms=-1"" to the corresponding line
sudo update-grub

Source: https://askubuntu.com/questions/1235456/issues-with-bluetooth-mouse-in-ubuntu-20-04

@BitesizedLion
Copy link

UPDATE: It seems the blueman applet was doing something weird, after remove the device and pair it again using the CLI, now the keyboard reconnects immediately without any issue. What I did:

$ bluetoothctl
power off
power on
scan on
# press fn+[1,2,3] for 4 secs and wait until appears the K2 device
scan off
pair DC:2C:26:2C:EE:46
trust DC:2C:26:2C:EE:46
connect DC:2C:26:2C:EE:46

@szaffarano Thank you, I've had the exact same issue, it's super frustrating

@khaled4vokalz
Copy link

khaled4vokalz commented Sep 4, 2023

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

  • intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

@532910
Copy link

532910 commented Sep 6, 2023

@ttrueten
Copy link

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

* intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like `exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee` etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

Same here with K10. Very annoying.

@532910
Copy link

532910 commented Sep 11, 2023

k1 (not se) works fine for me on debian sid

@andrebrait
Copy link
Author

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

  • intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

Yes, that's basically the reason why I gave up on Bluetooth keyboards. The firmware is usually poorly implemented, unless it's from some of the big guys like Logitech and whatnot.

Nowadays I run exclusively on wired mode, and I use exclusively QMK. I don't have the patience to deal with poor implementations of whatever feature I want, and QMK gives me the flexibility to do what I want with the board (since I know C, anyway).

I even caught some possible bugs in QMK's default debounce algorithm (which is already a lot better than the default firmware on non-QMK Keychron boards) and improved the OS detection feature so my keyboard now even switches automatically between Windows and Mac mode depending on what it connects to.

@khaled4vokalz
Copy link

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

  • intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

Yes, that's basically the reason why I gave up on Bluetooth keyboards. The firmware is usually poorly implemented, unless it's from some of the big guys like Logitech and whatnot.

Nowadays I run exclusively on wired mode, and I use exclusively QMK. I don't have the patience to deal with poor implementations of whatever feature I want, and QMK gives me the flexibility to do what I want with the board (since I know C, anyway).

I even caught some possible bugs in QMK's default debounce algorithm (which is already a lot better than the default firmware on non-QMK Keychron boards) and improved the OS detection feature so my keyboard now even switches automatically between Windows and Mac mode depending on what it connects to.

Sadly this issue does not occur when connected to a MAC... 🤔

@532910
Copy link

532910 commented Sep 19, 2023

The same as android!

@ipiepiepie
Copy link

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

* intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like `exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee` etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

Same on K6 and fedora

@patrislav1
Copy link

I got a new K8 Pro and Ubuntu 22.04; it uses the hid-generic driver (not hid_apple) so it can be used in the Windows/Android switch position out of the box, w/o any patches or workarounds.
Not sure if this is due to the recent hardware or the recent(ish) OS

[  +2,697336] usb 1-12: new full-speed USB device number 10 using xhci_hcd
[  +0,149526] usb 1-12: New USB device found, idVendor=3434, idProduct=0283, bcdDevice= 1.02
[  +0,000014] usb 1-12: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  +0,000007] usb 1-12: Product: Keychron K8 Pro
[  +0,000006] usb 1-12: Manufacturer: Keychron
[  +0,005350] input: Keychron Keychron K8 Pro as /devices/pci0000:00/0000:00:14.0/usb1/1-12/1-12:1.0/0003:3434:0283.000C/input/input41
[  +0,059489] hid-generic 0003:3434:0283.000C: input,hidraw3: USB HID v1.11 Keyboard [Keychron Keychron K8 Pro] on usb-0000:00:14.0-12/input0
[  +0,002861] hid-generic 0003:3434:0283.000D: hiddev2,hidraw4: USB HID v1.11 Device [Keychron Keychron K8 Pro] on usb-0000:00:14.0-12/input1
[  +0,002764] input: Keychron Keychron K8 Pro System Control as /devices/pci0000:00/0000:00:14.0/usb1/1-12/1-12:1.2/0003:3434:0283.000E/input/input42
[  +0,064351] input: Keychron Keychron K8 Pro Consumer Control as /devices/pci0000:00/0000:00:14.0/usb1/1-12/1-12:1.2/0003:3434:0283.000E/input/input43
[  +0,000487] input: Keychron Keychron K8 Pro Keyboard as /devices/pci0000:00/0000:00:14.0/usb1/1-12/1-12:1.2/0003:3434:0283.000E/input/input44
[  +0,000972] hid-generic 0003:3434:0283.000E: input,hidraw5: USB HID v1.11 Keyboard [Keychron Keychron K8 Pro] on usb-0000:00:14.0-12/input2

@andrebrait
Copy link
Author

@patrislav1 K Pro series are a totally different base (both hardware and software) than the K series. They use QMK as firmware, instead of trying to impersonate an Apple keyboard.

QMK is open source, their version can already be customized with VIA, and if you're willing to checkout the source code and compile/flash it yourself, the sky is the limit.

I've even recently pushed a PR to upstream QMK allowing you to run custom code when the keyboard detects the OS it's plugged to, so you don't even need to switch layers on your own.

@patrislav1
Copy link

Oh wow, I didn't know they were that different under the hood. When I look at the QMK supported hardware platforms however, there are a lot of Keychron models, but none of the K Pro series. Not even on Keychron's fork. Does it maybe use one of the Q or V series variants?

@andrebrait
Copy link
Author

andrebrait commented Nov 30, 2023

@patrislav1 it's because they're on the bluetooth_playground branch. You can find the K Pro and Q Pro lines there.

@JwanKhalaf
Copy link

JwanKhalaf commented Dec 10, 2023

I have the K15 Pro and even though I put the keyboard in Bluetooth (tried Apple and Windows) and held the fn and number 4 key for 4 seconds to put the keyboard into pairing mode. My bluetoothctl just doesn't find/list the keyboard.

Anyone any ideas?

@andrebrait
Copy link
Author

andrebrait commented Dec 10, 2023

@JwanKhalaf
Copy link

Thanks @andrebrait. So, if the K15 Pro uses QMK as firmware, instead of trying to impersonate an Apple keyboard, does that mean I should have the switch on the keyboard pointing at Windows?

Also, my understanding is that VIA has more to do with customising the keyboard mappings. My issue is that the keyboard isn't being detected when searching for Bluetooth devices.

I suspect it might be related to my Asus ProArt X670E-Creator Wifi motherboard because on my ThinkPad T480s laptop (also running Arch), the laptop is detected and paired fine. I also tried it on my iPhone (iOS) and on there, it works fine too (it pairs and I can type on my iPhone using the K15 Pro).

@andrebrait
Copy link
Author

Thanks @andrebrait. So, if the K15 Pro uses QMK as firmware, instead of trying to impersonate an Apple keyboard, does that mean I should have the switch on the keyboard pointing at Windows?
For Linux, yes, but that's only mapping, as yoh noted below as well. For pairing issues, I honestly have no clue. Maybe they have an update on their firmware repository? Probably worth looking at what I mention further down below instead, though.

Also, my understanding is that VIA has more to do with customising the keyboard mappings. My issue is that the keyboard isn't being detected when searching for Bluetooth devices.

I suspect it might be related to my Asus ProArt X670E-Creator Wifi motherboard because on my ThinkPad T480s laptop (also running Arch), the laptop is detected and paired fine. I also tried it on my iPhone (iOS) and on there, it works fine too (it pairs and I can type on my iPhone using the K15 Pro).

Depending on the Bluetooth controller it uses, it could be it. I'm assuming it's an Intel AX210, right? If so, that should work well and it's weird that you're having issues.

Maybe you can try to look up issues with the BT controller on Linux then.

@nmicht
Copy link

nmicht commented Jan 22, 2024

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

* intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like `exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee` etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

Same on K6 and fedora

@ipiepiepie I had the same issue in Ubuntu 22 and K7. It was resolved by enabling the Bluetooth fast connect. I hope this works for you.

@javierspn
Copy link

Does any one see issues with K1 SE having issues when connected via bluetooth to ubuntu? In my case:

* intermittently the keyboard gets mad and starts typing by itself, sometimes just starts adding the last character I made an input for... for example something like `exxxxxaaaaaaaaaaaaaaaaaaaaaaaaammmmplllllllllllleeeee` etc. This is really weird and I've been facing this for a long time. This doesn't happen even once while connected via Cable...

Same on K6 and fedora

@ipiepiepie I had the same issue in Ubuntu 22 and K7. It was resolved by enabling the Bluetooth fast connect. I hope this works for you.

This is confirmed to solve a lot of issues.

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