aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/feature_bluetooth.md5
-rw-r--r--docs/feature_oled_driver.md4
-rw-r--r--docs/ja/understanding_qmk.md195
-rw-r--r--docs/ref_functions.md6
-rw-r--r--docs/tap_hold.md42
5 files changed, 228 insertions, 24 deletions
diff --git a/docs/feature_bluetooth.md b/docs/feature_bluetooth.md
index 7b450b1ac..08e5f24ac 100644
--- a/docs/feature_bluetooth.md
+++ b/docs/feature_bluetooth.md
@@ -26,7 +26,10 @@ A Bluefruit UART friend can be converted to an SPI friend, however this [require
26 26
27<!-- FIXME: Document bluetooth support more completely. --> 27<!-- FIXME: Document bluetooth support more completely. -->
28## Bluetooth Rules.mk Options 28## Bluetooth Rules.mk Options
29Use only one of these 29
30The currently supported Bluetooth chipsets do not support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro), so `rules.mk` must contain `NKRO_ENABLE = no`.
31
32Use only one of these to enable Bluetooth:
30* BLUETOOTH_ENABLE = yes (Legacy Option) 33* BLUETOOTH_ENABLE = yes (Legacy Option)
31* BLUETOOTH = RN42 34* BLUETOOTH = RN42
32* BLUETOOTH = AdafruitBLE 35* BLUETOOTH = AdafruitBLE
diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md
index d106d3d13..9e33a321c 100644
--- a/docs/feature_oled_driver.md
+++ b/docs/feature_oled_driver.md
@@ -300,6 +300,10 @@ bool oled_on(void);
300// Returns true if the screen was off or turns off 300// Returns true if the screen was off or turns off
301bool oled_off(void); 301bool oled_off(void);
302 302
303// Returns true if the oled is currently on, false if it is
304// not
305bool is_oled_on(void);
306
303// Basically it's oled_render, but with timeout management and oled_task_user calling! 307// Basically it's oled_render, but with timeout management and oled_task_user calling!
304void oled_task(void); 308void oled_task(void);
305 309
diff --git a/docs/ja/understanding_qmk.md b/docs/ja/understanding_qmk.md
new file mode 100644
index 000000000..74b37398f
--- /dev/null
+++ b/docs/ja/understanding_qmk.md
@@ -0,0 +1,195 @@
1# QMK のコードの理解
2
3<!---
4 original document: 0.9.55:docs/understanding_qmk.md
5 git diff 0.9.55 HEAD -- docs/understanding_qmk.md | cat
6-->
7
8このドキュメントでは、QMK ファームウェアがどのように機能するかを非常に高いレベルから説明しようとしています。基本的なプログラミングの概念を理解していることを前提としていますが、(実例を示す必要がある場合を除き) C に精通していることを前提にはしていません。以下のドキュメントの基本的な知識があることを前提としています。
9
10* [入門](ja/getting_started_introduction.md)
11* [キーボードがどのように動作するか](ja/how_keyboards_work.md)
12* [FAQ](ja/faq.md)
13
14## スタートアップ
15
16QMK は他のコンピュータプログラムと何ら変わりないと考えることができます。開始され、タスクを実行し、そして終了します。プログラムのエントリーポイントは、他の C プログラムと同様に、`main()` 関数です。ただし、QMK を初めて触る人は、`main()` 関数が複数の場所に現れるため、混乱するかもしれません。また、どれを見ればよいか分かりにくいかもしれません。
17
18複数ある理由は、QMK は様々なプラットフォームをサポートするからです。最も一般的なプラットフォームは `lufa` です。これは atmega32u4 のような AVR プロセッサ上で実行されます。また、`chibios` および `vusb` もサポートします。
19
20ここでは AVR プロセッサに焦点を当てます。これは `lufa` プラットフォームを使います。`main()` 関数は [tmk_core/protocol/lufa/lufa.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1028) にあります。関数にざっと目を通すと、(ホストへの USB も含めて)設定された全てのハードウェアが初期化され、プログラムのコア部分が [`while(1)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1069) で開始されることが分かります。これが[メインループ](#the-main-loop)です。
21
22## メインループ
23
24コードのこの部分は、同じ命令セットを永久にループ処理するため、「メインループ」と呼ばれます。ここはキーボードに必要なことを実行させる関数を QMK が呼び出す場所です。一見、多くの機能を持つように見えるかもしれませんが、大抵の場合、コードは `#define` によって無効にされます。
25
26```
27 keyboard_task();
28```
29
30ここで、全てのキーボードの固有の機能が実行されます。`keyboard_task()` のソースコードは [tmk_core/common/keyboard.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/keyboard.c#L216) にあり、マトリックスの変化を検知し、LED の状態をオンオフする責任があります。
31
32`keyboard_task()` に以下を処理するコードがあります:
33
34* [マトリックスのスキャン](#matrix-scanning)
35* マウスの処理
36* シリアルリンク
37* ビジュアライザ
38* キーボードの状態の LED (Caps Lock, Num Lock, Scroll Lock)
39
40#### マトリックスのスキャン
41
42マトリックスのスキャンはキーボードファームウェアのコアの機能です。これは今どのキーが押されているかを検知するプロセスであり、キーボードはこの機能を1秒間に何度も何度も実行します。ファームウェアの CPU 時間の 99% はマトリックスのスキャンに費やされていると言っても過言ではありません。
43
44実際のマトリックスの検知には様々な方法がありますが、それはこのドキュメントの対象外です。マトリックスのスキャンをブラックボックスとして扱っても問題ありません。マトリックスの現在の状態を求めると、以下のようなデータ構造を取得します:
45
46
47```
48{
49 {0,0,0,0},
50 {0,0,0,0},
51 {0,0,0,0},
52 {0,0,0,0},
53 {0,0,0,0}
54}
55```
56
57これは 4行x5列のテンキー(訳注: 5行x4列の間違いと思われます)のマトリックスを表す直接的な表現のデータ構造です。キーが押されると、マトリックス内のそのキーの位置が、 `0` ではなく `1` として返されます。
58
59マトリックスのスキャンは1秒間に何度も実行されます。正確なレートは様々ですが、知覚できるような遅延を避けるために、秒間に少なくとも10回実行します。
60
61##### マトリックスから物理的なレイアウトへのマップ
62
63キーボード上の各スイッチの状態が分かると、それをキーコードへマップする必要があります。QMK ではキーコードへのマップは C マクロを使うことで行われ、C マクロにより物理的なレイアウトの定義はキーコードの定義から分離されています。(訳注:「キーコードの定義」は「キーコードのマトリクス配列による定義」と思われる)
64
65キーボードレベルで、キーボードのマトリックスを物理キーにマップする C マクロ (一般的には、`LAYOUT()` という名前)を定義します。マトリックスにスイッチがない場所がある場合、このマクロを使って KC_NO を事前に埋め込むことができ、キーマップの定義を扱いやすくすることができます。以下は、テンキー用の `LAYOUT()` マクロです:
66
67```c
68#define LAYOUT( \
69 k00, k01, k02, k03, \
70 k10, k11, k12, k13, \
71 k20, k21, k22, \
72 k30, k31, k32, k33, \
73 k40, k42 \
74) { \
75 { k00, k01, k02, k03, }, \
76 { k10, k11, k12, k13, }, \
77 { k20, k21, k22, KC_NO, }, \
78 { k30, k31, k32, k33, }, \
79 { k40, KC_NO, k42, KC_NO } \
80}
81```
82
83`LAYOUT()` マクロの2つ目のブロックが、上記のマトリックススキャン配列とどのように一致しているかに注目してください。このマクロはマトリックスのスキャン配列をキーコードにマップするものです。ただし、17キーのテンキーを見ると、マトリックスにはスイッチが置けるが、キーが大きいために実際にはスイッチが無い箇所が3つあることが分かります。これらのスペースに `KC_NO` を設定したので、キーマップ定義には必要ありません。
84
85このマクロを使って、少し変わったマトリックスのレイアウト、例えば [Clueboard rev 2](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/66/rev2/rev2.h) を扱うこともできます。その説明はこのドキュメントの範囲外です。
86
87##### キーコードの割り当て
88
89キーマップレべルでは、上記の `LAYOUT()` マクロを使って、物理的な場所からマトリックスの場所にマッピングします。以下のようになります:
90
91```
92const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
93[0] = LAYOUT(
94 KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
95 KC_P7, KC_P8, KC_P9, KC_PPLS, \
96 KC_P4, KC_P5, KC_P6, \
97 KC_P1, KC_P2, KC_P3, KC_PENT, \
98 KC_P0, KC_PDOT)
99}
100```
101
102これら全ての引数が、前のセクションの `LAYOUT()` マクロの前半とどのように一致しているかについて注目してください。このようにして、キーコードを取得して、それを前述のマトリックススキャンにマップします。
103
104##### 状態変更の検知
105
106上記のマトリックススキャンはある時点のマトリックスの状態を伝えますが、コンピュータは変更のみを知りたいだけで、現在の状態を気にしません。QMK は最後のマトリックススキャンの結果を格納し、このマトリックスから結果を比較して、いつキーが押されたか放されたかを決定します。
107
108例を見てみましょう。キーボードスキャンループの途中に移動して、前のスキャンが以下のようになっていることがわかったとします:
109
110```
111{
112 {0,0,0,0},
113 {0,0,0,0},
114 {0,0,0,0},
115 {0,0,0,0},
116 {0,0,0,0}
117}
118```
119
120現在のスキャンが完了すると、以下のように見えるとします:
121
122```
123{
124 {1,0,0,0},
125 {0,0,0,0},
126 {0,0,0,0},
127 {0,0,0,0},
128 {0,0,0,0}
129}
130```
131
132キーマップと比較すると、押されたキーが KC_NLCK であることが分かります。ここから、`process_record` 関数群を呼び出します。
133
134<!-- FIXME: Magic happens between here and process_record -->
135
136##### Process Record
137
138`process_record()` 関数自体は一見簡単に見えますが、その内部は QMK の様々なレベルで機能を上書きするためのゲートウェイが隠されています。キーボード/キーマップレベルの機能について調べる必要があるときは、以下に列挙した一連のイベントを手引帳として使います。`rules.mk` またはほかの場所で設定されたオプションに応じて、最終的なファームウェアに以下の関数のサブセットのみが含まれます。
139
140* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/action.c#L172)
141 * [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L206)
142 * [このレコードをキーコードにマップする](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L226)
143 * [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/c1c5922aae7b60b7c7d13d3769350eed9dda17ab/quantum/velocikey.c#L27)
144 * [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L119)
145 * [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_key_lock.c#L62)
146 * [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_clicky.c#L79)
147 * [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/2cee371bf125a6ec541dd7c5a809573facc7c456/drivers/haptic/haptic.c#L216)
148 * [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/card.c#L20)
149 * [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/keymaps/default/keymap.c#L58)
150 * [`bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/rgb_matrix.c#L139)
151 * [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_midi.c#L81)
152 * [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_audio.c#L19)
153 * [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_steno.c#L160)
154 * [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_music.c#L114)
155 * [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L141)
156 * [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode_common.c#L169) は、以下のいずれかを呼び出します:
157 * [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode.c#L20)
158 * [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicodemap.c#L46)
159 * [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_ucis.c#L95)
160 * [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_leader.c#L51)
161 * [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
162 * [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
163 * [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
164 * [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264)
165 * [Quantum 固有のキーコードを識別して処理する](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)
166
167この一連のイベントの中の任意のステップで (`process_record_kb()` のような)関数は `false` を返して、以降の処理を停止することができます。
168
169この呼び出しの後で、`post_process_record()` が呼ばれます。これはキーコードが通常処理された後に実行する必要がある追加のクリーンアップを処理するために使うことができます。
170
171* [`void post_process_record(keyrecord_t *record)`]()
172 * [`void post_process_record_quantum(keyrecord_t *record)`]()
173 * [このレコードをキーコードにマップする]()
174 * [`void post_process_clicky(uint16_t keycode, keyrecord_t *record)`]()
175 * [`void post_process_record_kb(uint16_t keycode, keyrecord_t *record)`]()
176 * [`void post_process_record_user(uint16_t keycode, keyrecord_t *record)`]()
177
178<!--
179#### Mouse Handling
180
181FIXME: This needs to be written
182
183#### Serial Link(s)
184
185FIXME: This needs to be written
186
187#### Visualizer
188
189FIXME: This needs to be written
190
191#### Keyboard state LEDs (Caps Lock, Num Lock, Scroll Lock)
192
193FIXME: This needs to be written
194
195-->
diff --git a/docs/ref_functions.md b/docs/ref_functions.md
index 997c3fa2e..176095070 100644
--- a/docs/ref_functions.md
+++ b/docs/ref_functions.md
@@ -43,7 +43,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
43### `update_tri_layer_state(state, x, y, z)` 43### `update_tri_layer_state(state, x, y, z)`
44The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from the [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check. 44The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from the [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check.
45 45
46The caveat to this method is that you cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it. 46There are a couple of caveats to this method:
471. You cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it.
482. Because layers are processed from the highest number `z` should be a higher layer than `x` and `y` or you may not be able to access it.
47 49
48#### Example 50#### Example
49 51
@@ -97,7 +99,7 @@ To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset m
97 99
98## Tap random key 100## Tap random key
99 101
100If you want to send a random character to the host computer, you can use the `tap_random_base64()` function. This [pseudorandomly](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) selects a number between 0 and 63, and then sends a key press based on that selection. (0–25 is `A`–`Z`, 26–51 is `a`–`z`, 52–61 is `0`–`9`, 62 is `+` and 63 is `/`). 102If you want to send a random character to the host computer, you can use the `tap_random_base64()` function. This [pseudorandomly](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) selects a number between 0 and 63, and then sends a key press based on that selection. (0–25 is `A`–`Z`, 26–51 is `a`–`z`, 52–61 is `0`–`9`, 62 is `+` and 63 is `/`).
101 103
102?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords. 104?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords.
103 105
diff --git a/docs/tap_hold.md b/docs/tap_hold.md
index 589ec3181..9ffbfde8f 100644
--- a/docs/tap_hold.md
+++ b/docs/tap_hold.md
@@ -1,22 +1,22 @@
1# Tap-Hold Configuration Options 1# Tap-Hold Configuration Options
2 2
3While Tap-Hold options are fantastic, they are not without their issues. We have tried to configure them with reasonable defaults, but that may still cause issues for some people. 3While Tap-Hold options are fantastic, they are not without their issues. We have tried to configure them with reasonable defaults, but that may still cause issues for some people.
4 4
5These options let you modify the behavior of the Tap-Hold keys. 5These options let you modify the behavior of the Tap-Hold keys.
6 6
7## Tapping Term 7## Tapping Term
8 8
9The crux of all of the following features is the tapping term setting. This determines what is a tap and what is a hold. And the exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key. 9The crux of all of the following features is the tapping term setting. This determines what is a tap and what is a hold. And the exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key.
10 10
11You can set the global time for this by adding the following setting to your `config.h`: 11You can set the global time for this by adding the following setting to your `config.h`:
12 12
13```c 13```c
14#define TAPPING_TERM 200 14#define TAPPING_TERM 200
15``` 15```
16 16
17This setting is defined in milliseconds, and does default to 200ms. This is a good average for a majority of people. 17This setting is defined in milliseconds, and does default to 200ms. This is a good average for a majority of people.
18 18
19For more granular control of this feature, you can add the following to your `config.h`: 19For more granular control of this feature, you can add the following to your `config.h`:
20```c 20```c
21#define TAPPING_TERM_PER_KEY 21#define TAPPING_TERM_PER_KEY
22``` 22```
@@ -45,9 +45,9 @@ As of [PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/), there is a new
45#define PERMISSIVE_HOLD 45#define PERMISSIVE_HOLD
46``` 46```
47 47
48This makes tap and hold keys (like Mod Tap) work better for fast typists, or for high `TAPPING_TERM` settings. 48This makes tap and hold keys (like Mod Tap) work better for fast typists, or for high `TAPPING_TERM` settings.
49 49
50If you press a Mod Tap key, tap another key (press and release) and then release the Mod Tap key, all within the tapping term, it will output the "tapping" function for both keys. 50If you press a Mod Tap key, tap another key (press and release) and then release the Mod Tap key, all within the tapping term, it will output the tapping function for both keys.
51 51
52For Instance: 52For Instance:
53 53
@@ -56,7 +56,7 @@ For Instance:
56- `KC_X` Up 56- `KC_X` Up
57- `SFT_T(KC_A)` Up 57- `SFT_T(KC_A)` Up
58 58
59Normally, if you do all this within the `TAPPING_TERM` (default: 200ms) this will be registered as `ax` by the firmware and host system. With permissive hold enabled, this modifies how this is handled by considering the Mod Tap keys as a Mod if another key is tapped, and would registered as `X` (`SHIFT`+`x`). 59Normally, if you do all this within the `TAPPING_TERM` (default: 200ms) this will be registered as `ax` by the firmware and host system. With permissive hold enabled, this modifies how this is handled by considering the Mod Tap keys as a Mod if another key is tapped, and would registered as `X` (`SHIFT`+`x`).
60 60
61?> If you have `Ignore Mod Tap Interrupt` enabled, as well, this will modify how both work. The regular key has the modifier added if the first key is released first or if both keys are held longer than the `TAPPING_TERM`. 61?> If you have `Ignore Mod Tap Interrupt` enabled, as well, this will modify how both work. The regular key has the modifier added if the first key is released first or if both keys are held longer than the `TAPPING_TERM`.
62 62
@@ -87,7 +87,7 @@ To enable this setting, add this to your `config.h`:
87#define IGNORE_MOD_TAP_INTERRUPT 87#define IGNORE_MOD_TAP_INTERRUPT
88``` 88```
89 89
90Similar to Permissive Hold, this alters how the firmware processes inputs for fast typists. If you press a Mod Tap key, press another key, release the Mod Tap key, and then release the normal key, it would normally output the "tapping" function for both keys. This may not be desirable for rolling combo keys. 90Similar to Permissive Hold, this alters how the firmware processes inputs for fast typists. If you press a Mod Tap key, press another key, release the Mod Tap key, and then release the normal key, it would normally output the tapping function for both keys. This may not be desirable for rolling combo keys.
91 91
92Setting `Ignore Mod Tap Interrupt` requires holding both keys for the `TAPPING_TERM` to trigger the hold function (the mod). 92Setting `Ignore Mod Tap Interrupt` requires holding both keys for the `TAPPING_TERM` to trigger the hold function (the mod).
93 93
@@ -126,27 +126,27 @@ bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
126 126
127## Tapping Force Hold 127## Tapping Force Hold
128 128
129To enable `tapping force hold`, add the following to your `config.h`: 129To enable `tapping force hold`, add the following to your `config.h`:
130 130
131```c 131```c
132#define TAPPING_FORCE_HOLD 132#define TAPPING_FORCE_HOLD
133``` 133```
134 134
135When the user holds a key after tap, this repeats the tapped key rather to hold a modifier key. This allows to use auto repeat for the tapped key. 135When the user holds a key after tapping it, the tapping function is repeated by default, rather than activating the hold function. This allows keeping the ability to auto-repeat the tapping function of a dual-role key. `TAPPING_FORCE_HOLD` removes that ability to let the user activate the hold function instead, in the case of holding the dual-role key after having tapped it.
136 136
137Example: 137Example:
138 138
139- SFT_T(KC_A) Down 139- `SFT_T(KC_A)` Down
140- SFT_T(KC_A) Up 140- `SFT_T(KC_A)` Up
141- SFT_T(KC_A) Down 141- `SFT_T(KC_A)` Down
142- wait more than tapping term... 142- wait until the tapping term expires...
143- SFT_T(KC_A) Up 143- `SFT_T(KC_A)` Up
144 144
145With default settings, `a` will be sent on the first release, then `a` will be sent on the second press allowing the computer to trigger its auto repeat function. 145With default settings, `a` will be sent on the first release, then `a` will be sent on the second press allowing the computer to trigger its auto repeat function.
146 146
147With `TAPPING_FORCE_HOLD`, the second press will be interpreted as a Shift, allowing to use it as a modifier shortly after having used it as a tap. 147With `TAPPING_FORCE_HOLD`, the second press will be interpreted as a Shift, allowing to use it as a modifier shortly after having used it as a tap.
148 148
149!> `TAPPING_FORCE_HOLD` will break anything that uses tapping toggles (Such as the `TT` layer keycode, and the One Shot Tapping Toggle). 149!> `TAPPING_FORCE_HOLD` will break anything that uses tapping toggles (Such as the `TT` layer keycode, and the One Shot Tap Toggle).
150 150
151For more granular control of this feature, you can add the following to your `config.h`: 151For more granular control of this feature, you can add the following to your `config.h`:
152 152
@@ -169,7 +169,7 @@ bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) {
169 169
170## Retro Tapping 170## Retro Tapping
171 171
172To enable `retro tapping`, add the following to your `config.h`: 172To enable `retro tapping`, add the following to your `config.h`:
173 173
174```c 174```c
175#define RETRO_TAPPING 175#define RETRO_TAPPING
@@ -179,11 +179,11 @@ Holding and releasing a dual function key without pressing another key will resu
179 179
180For instance, holding and releasing `LT(2, KC_SPACE)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPACE` instead. 180For instance, holding and releasing `LT(2, KC_SPACE)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPACE` instead.
181 181
182## Why do we include the key record for the per key functions? 182## Why do we include the key record for the per key functions?
183 183
184One thing that you may notice is that we include the key record for all of the "per key" functions, and may be wondering why we do that. 184One thing that you may notice is that we include the key record for all of the "per key" functions, and may be wondering why we do that.
185 185
186Well, it's simply really: customization. But specifically, it depends on how your keyboard is wired up. For instance, if each row is actually using a row in the keyboard's matrix, then it may be simpler to use `if (record->event.row == 3)` instead of checking a whole bunch of keycodes. Which is especially good for those people using the Tap Hold type keys on the home row. So you could fine tune those to not interfere with your normal typing. 186Well, it's simple really: customization. But specifically, it depends on how your keyboard is wired up. For instance, if each row is actually using a row in the keyboard's matrix, then it may be simpler to use `if (record->event.row == 3)` instead of checking a whole bunch of keycodes. Which is especially good for those people using the Tap Hold type keys on the home row. So you could fine tune those to not interfere with your normal typing.
187 187
188## Why is there no `*_kb` or `*_user` functions?! 188## Why is there no `*_kb` or `*_user` functions?!
189 189