docs/ChangeLog/20210828.md
Combo processing has been reordered with respect to keypress handling, allowing for much better compatibility with mod taps.
It is also now possible to define combos that have keys overlapping with other combos, triggering only one. For example, a combo of A, B can coexist with a longer combo of A, B, C -- previous functionality would trigger both combos if all three keys were pressed.
QMK now has a new feature: key overrides. This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
To illustrate, it's now possible to use the key overrides feature to translate <kbd>Shift + Backspace</kbd> into <kbd>Delete</kbd> -- an often-requested example of where this functionality comes in handy.
There's far more to describe that what lives in this changelog, so head over to the key overrides documentation for more examples and info.
QMK gained the ability to pretend to be a digitizer device -- much like a tablet device. A mouse uses delta-coordinates -- move up, move right -- but a digitizer works with absolute coordinates -- top left, bottom right.
The following keyboards have had their source moved within QMK:
| Old Keyboard Name | New Keyboard Name |
|---|---|
| aeboards/constellation | aeboards/constellation/rev1, aeboards/constellation/rev2 |
| bakeneko65 | bakeneko65/rev2, bakeneko65/rev3 |
| bm16a | kprepublic/bm16a |
| bm16s | kprepublic/bm16s |
| bm40hsrgb | kprepublic/bm40hsrgb |
| bm43a | kprepublic/bm43a |
| bm60poker | kprepublic/bm60poker |
| bm60rgb | kprepublic/bm60rgb |
| bm60rgb_iso | kprepublic/bm60rgb_iso |
| bm68rgb | kprepublic/bm68rgb |
| clawsome/gamebuddy | clawsome/gamebuddy/v1_0, clawsome/gamebuddy/v1_m |
| cospad | kprepublic/cospad |
| custommk/genesis | custommk/genesis/rev1, custommk/genesis/rev2 |
| daisy | ktec/daisy |
| durgod/k320 | durgod/k3x0/k320 |
| dztech/volcano660 | ilumkb/volcano660 |
| ergodone | ktec/ergodone |
| gmmk/pro | gmmk/pro/ansi, gmmk/pro/iso |
| handwired/p1800fl | team0110/p1800fl |
| jj40 | kprepublic/jj40 |
| jj4x4 | kprepublic/jj4x4 |
| jj50 | kprepublic/jj50 |
| kyria | splitkb/kyria |
| lazydesigners/the60 | lazydesigners/the60/rev1, lazydesigners/the60/rev2 |
| matrix/m12og | matrix/m12og/rev1, matrix/m12og/rev2 |
| mechlovin/hannah65/mechlovin9 | mechlovin/mechlovin9/rev1, mechlovin/mechlovin9/rev2 |
| peiorisboards/ixora | coarse/ixora |
| ramonimbao/mona | ramonimbao/mona/v1, ramonimbao/mona/v1_1 |
| staryu | ktec/staryu |
| tokyo60 | tokyokeyboard/tokyo60 |
| vinta | coarse/vinta |
| xd002 | xiudi/xd002 |
| xd004 | xiudi/xd004 |
| xd60 | xiudi/xd60 |
| xd68 | xiudi/xd68 |
| xd75 | xiudi/xd75 |
| xd84 | xiudi/xd84 |
| xd84pro | xiudi/xd84pro |
| xd87 | xiudi/xd87 |
| xd96 | xiudi/xd96 |
As noted during last breaking changes cycle, QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
This pull request changes the behavior of BOOTMAGIC_ENABLE such that specifying full results in an error, allowing only no, yes, or lite.
Currently lite is the equivalent of yes in rules.mk. Next cycle the use of the lite keyword will be prevented in favour of yes -- any new submissions should now be using yes or no to minimise disruption.
This is the current roadmap for the behavior of BOOTMAGIC_ENABLE:
BOOTMAGIC_ENABLE = yes will enable Bootmagic Lite instead of full Bootmagic.BOOTMAGIC_ENABLE must be either yes, lite, or no – setting BOOTMAGIC_ENABLE = full will cause compilation to fail.BOOTMAGIC_ENABLE must be either yes or no – setting BOOTMAGIC_ENABLE = lite will cause compilation to fail.To match the encoder change last breaking changes cycle, DIP switch callbacks now return bool, too.
Example code before change:
void dip_switch_update_kb(uint8_t index, bool active) {
dip_switch_update_user(index, active);
}
void dip_switch_update_user(uint8_t index, bool active) {
switch (index) {
case 0:
if(active) { audio_on(); } else { audio_off(); }
break;
}
}
void dip_switch_update_mask_kb(uint32_t state) {
dip_switch_update_mask_user(state);
}
void dip_switch_update_mask_user(uint32_t state) {
if (state & (1UL<<0) && state & (1UL<<1)) {
layer_on(_ADJUST); // C on esc
} else {
layer_off(_ADJUST);
}
}
Example code after change:
bool dip_switch_update_kb(uint8_t index, bool active) {
if !(dip_switch_update_user(index, active)) { return false; }
return true;
}
bool dip_switch_update_user(uint8_t index, bool active) {
switch (index) {
case 0:
if(active) { audio_on(); } else { audio_off(); }
break;
}
return true; // Returning true allows keyboard code to execute, false will tell the keyboard code "I've already handled it".
}
bool dip_switch_update_mask_kb(uint32_t state) {
if (!dip_switch_update_mask_user(state)) { return false; }
return true;
}
bool dip_switch_update_mask_user(uint32_t state) {
if (state & (1UL<<0) && state & (1UL<<1)) {
layer_on(_ADJUST); // C on esc
} else {
layer_off(_ADJUST);
}
return true; // Returning true allows keyboard code to execute, false will tell the keyboard code "I've already handled it".
}
Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically:
::: warning If you're updating your split keyboard, you will need to flash both sides of the split with the your firmware. :::
Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062.
QMK's pursuit of data-driven keyboards has progressed, allowing substantially more configurable options to be specified in info.json.
Tags will let you categorize your keyboard, and will be used in the future to allow browsing and sorting through keyboards in QMK. Tags are free-form text identifiers that identify attributes about your keyboard. To add tags you simply add a tags key to your info.json:
"tags": ["tkl", "backlight", "encoder"]
With this release we are moving towards using JSON dot notation in more places. For example, when using qmk info -f text:
$ qmk info -f text -kb clueboard/card
bootloader: atmel-dfu
debounce: 20
diode_direction: ROW2COL
features.audio: True
features.backlight: True
features.bluetooth: False
features.bootmagic: False
features.command: True
features.console: True
features.extrakey: True
features.lto: True
features.midi: False
features.mousekey: True
features.nkro: False
features.rgblight: True
features.unicode: False
height: 8
keyboard_folder: clueboard/card
keyboard_name: Cluecard
layout_aliases.LAYOUT: LAYOUT_all
layouts: LAYOUT_all
maintainer: skullydazed
manufacturer: Clueboard
matrix_pins.cols: F1, F6, F7
matrix_pins.rows: B4, F0, F4, F5
platform: unknown
processor: atmega32u4
processor_type: avr
protocol: LUFA
rgblight.brightness_steps: 17
rgblight.hue_steps: 10
rgblight.led_count: 4
rgblight.pin: E6
rgblight.saturation_steps: 17
split.transport.protocol: serial
usb.device_ver: 0x0001
usb.pid: 0x2330
usb.vid: 0xC1ED
width: 10
We've added dozens of new keys to info.json so that you can configure more than ever without writing a single line of code. A quick overview of the new items you can configure:
audio.pins, audio.voicesbacklight.breathing, backlight.breathing_period, backlight.levels, backlight.pin,bluetooth.driver, bluetooth.ltobootloader_instructionsbuild.debounce_type, build.firmware_format, build.ltocombo.count, combo.termleader_key.timing, leader_key.strict_processing, leader_key.timeoutmatrix.custom, matrix.custom_lite, matrix.ghost, matrix.io_delaymouse_key.enabled, mouse_key.delay, mouse_key.interval, mouse_key.max_speed, mouse_key.time_to_max, mouse_key.wheel_delayoneshot.tap_toggle, oneshot.timeoutrgblight.layers.blink, rgblight.layers.enabled, rgblight.layers.max, rgblight.layers.override_rgb, rgblight.rgbwsplit.enabled, split.matrix_grid, split.matrix_pins, split.main, split.soft_serial_pin, split.soft_serial_speed, split.transport.protocol, split.transport.sync_matrix_state, split.transport.sync_modifiers, split.usb_detecttapping.force_hold, tapping.force_hold_per_key, tapping.ignore_mod_tap_interrupt, tapping.ignore_mod_tap_interrupt_per_key, tapping.permissive_hold, tapping.permissive_hold_per_key, tapping.retro, tapping.retro_per_key, tapping.term, tapping.term_per_key, tapping.toggleusb.force_nkro, usb.max_power, usb.no_startup_check, usb.polling_interval, usb.shared_endpoint.keyboard, usb.shared_endpoint.mouse, usb.suspend_wakeup_delay, usb.wait_forqmk.keys_per_scan, qmk.tap_keycode_delay, qmk.tap_capslock_delayQMK was originally based on TMK, and has grown in size considerably since its first inception. To keep moving things forward, restructure of some of the core areas of the code is needed to support new concepts and new hardware, and progress is happening along those lines:
lib/ (#13973)Core:
quantum/command.{c,h} for code size & {read,maintain}ability (#11842)keymap_extras: Remove deprecated defines (#12949)spi_master Kinetis support (#13098)SERIAL_NUMBER (#13403)SENDSTRING_BELL code to send_string.h (#13566)--parallel improvements (#13800)qmk console (#14038)CLI:
width and height in CLI (#13728)qmk doctor more lenient about system config (#13804)Submodule updates:
lib/ (#13973)Keyboards:
fn_actions to Grave Escape and RGB keycodes (#13360)API_SYSEX_ENABLEs from rules.mk (#13389)fn_actions stuff (#13502)Keyboard fixes:
massdrop/alt, cest73/tkm. (#14048)Others:
Bugs:
combo_disable (#13988)