fe02abc47921428fe6eb59ca817bfd082f0de4bf
- Author
- Drashna Jaelre <drashna@live.com>
- Committer
- GitHub <noreply@github.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
2index 4e032f9dcfaf0ed16c432823e086656452aa1413..0880934e95790f79e230cc830eb757a3b338bc30 100644
3--- a/builddefs/common_features.mk
4+++ b/builddefs/common_features.mk
5@@ -620,6 +620,7 @@ ifeq ($(strip $(VIA_ENABLE)), yes)
6 DYNAMIC_KEYMAP_ENABLE := yes
7 RAW_ENABLE := yes
8 BOOTMAGIC_ENABLE := yes
9+ TRI_LAYER_ENABLE := yes
10 SRC += $(QUANTUM_DIR)/via.c
11 OPT_DEFS += -DVIA_ENABLE
12 endif
13diff --git a/builddefs/generic_features.mk b/builddefs/generic_features.mk
14index 0d897bc1c8288375903d91d2984078e953361328..5a1ef5c6f0a523ec43e096d9f2b4c58d326f82dc 100644
15--- a/builddefs/generic_features.mk
16+++ b/builddefs/generic_features.mk
17@@ -39,6 +39,7 @@ GENERIC_FEATURES = \
18 VELOCIKEY \
19 WPM \
20 DYNAMIC_TAPPING_TERM \
21+ TRI_LAYER
22
23 define HANDLE_GENERIC_FEATURE
24 # $$(info "Processing: $1_ENABLE $2.c")
25diff --git a/builddefs/show_options.mk b/builddefs/show_options.mk
26index e9f7e7d0471fd61dc5ee6df06518fe59af007b24..9723b45438a823bd2b28555aeec146b74e114710 100644
27--- a/builddefs/show_options.mk
28+++ b/builddefs/show_options.mk
29@@ -84,7 +84,8 @@ OTHER_OPTION_NAMES = \
30 PROGRAMMABLE_BUTTON_ENABLE \
31 SECURE_ENABLE \
32 CAPS_WORD_ENABLE \
33- AUTOCORRECT_ENABLE
34+ AUTOCORRECT_ENABLE \
35+ TRI_LAYER_ENABLE
36
37 define NAME_ECHO
38 @printf " %-30s = %-16s # %s\\n" "$1" "$($1)" "$(origin $1)"
39diff --git a/data/constants/keycodes/keycodes_0.0.2_quantum.hjson b/data/constants/keycodes/keycodes_0.0.2_quantum.hjson
40new file mode 100644
41index 0000000000000000000000000000000000000000..960afa4e5152206839c783ba395b227686ee7c99
42--- /dev/null
43+++ b/data/constants/keycodes/keycodes_0.0.2_quantum.hjson
44@@ -0,0 +1,18 @@
45+{
46+ "keycodes": {
47+ "0x7C77": {
48+ "group": "quantum",
49+ "key": "QK_TRI_LAYER_LOWER",
50+ "aliases": [
51+ "TL_LOWR"
52+ ]
53+ },
54+ "0x7C78": {
55+ "group": "quantum",
56+ "key": "QK_TRI_LAYER_UPPER",
57+ "aliases": [
58+ "TL_UPPR"
59+ ]
60+ }
61+ }
62+}
63diff --git a/docs/_summary.md b/docs/_summary.md
64index d2d4bb9b326ab9e39816c535a3bebc5e8aee0151..b038f08a4dcbe6789235ae22648ce3814f0c7f3c 100644
65--- a/docs/_summary.md
66+++ b/docs/_summary.md
67@@ -93,6 +93,7 @@
68 * [Swap Hands](feature_swap_hands.md)
69 * [Tap Dance](feature_tap_dance.md)
70 * [Tap-Hold Configuration](tap_hold.md)
71+ * [Tri Layer](feature_tri_layer.md)
72 * [Unicode](feature_unicode.md)
73 * [Userspace](feature_userspace.md)
74 * [WPM Calculation](feature_wpm.md)
75diff --git a/docs/feature_tri_layer.md b/docs/feature_tri_layer.md
76new file mode 100644
77index 0000000000000000000000000000000000000000..aa6c87719ca62baf38cc66e35e91ca35d96427d6
78--- /dev/null
79+++ b/docs/feature_tri_layer.md
80@@ -0,0 +1,48 @@
81+# Tri Layers :id=tri-layers
82+
83diff --git a/quantum/action_layer.c b/quantum/action_layer.c
84index 74e81379207871bca8b29f4084b71462fdf1db31..35f494df8f1698808bc4f6effc72b1b22ad6867f 100644
85--- a/quantum/action_layer.c
86+++ b/quantum/action_layer.c
87@@ -349,3 +349,13 @@ uint8_t layer_switch_get_layer(keypos_t key) {
88 action_t layer_switch_get_action(keypos_t key) {
89 return action_for_key(layer_switch_get_layer(key), key);
90 }
91+
92+layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
93+ layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2);
94+ layer_state_t mask3 = (layer_state_t)1 << layer3;
95+ return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
96+}
97+
98+void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
99+ layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
100+}
101diff --git a/quantum/action_layer.h b/quantum/action_layer.h
102index 3fe272652999e8869ea7da303c79ecd0938df0cd..ff783bb3e7fc92b6469940c3b2d60560e584e36d 100644
103--- a/quantum/action_layer.h
104+++ b/quantum/action_layer.h
105@@ -113,6 +113,25 @@ void layer_and(layer_state_t state);
106 void layer_xor(layer_state_t state);
107 layer_state_t layer_state_set_user(layer_state_t state);
108 layer_state_t layer_state_set_kb(layer_state_t state);
109+
110+/**
111+ * @brief Applies the tri layer to global layer state. Not be used in layer_state_set_(kb|user) functions.
112+ *
113+ * @param layer1 First layer to check for tri layer
114+ * @param layer2 Second layer to check for tri layer
115+ * @param layer3 Layer to activate if both other layers are enabled
116+ */
117+void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
118+/**
119+ * @brief Applies the tri layer behavior to supplied layer bitmask, without using layer functions.
120+ *
121+ * @param state Original layer bitmask to check and modify
122+ * @param layer1 First layer to check for tri layer
123+ * @param layer2 Second layer to check for tri layer
124+ * @param layer3 Layer to activate if both other layers are enabled
125+ * @return layer_state_t returns a modified layer bitmask with tri layer modifications applied
126+ */
127+layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);
128 #else
129 # define layer_state 0
130
131@@ -131,6 +150,8 @@ layer_state_t layer_state_set_kb(layer_state_t state);
132 # define layer_xor(state) (void)state
133 # define layer_state_set_kb(state) (void)state
134 # define layer_state_set_user(state) (void)state
135+# define update_tri_layer(layer1, layer2, layer3)
136+# define update_tri_layer_state(state, layer1, layer2, layer3) (void)state
137 #endif
138
139 /* pressed actions cache */
140diff --git a/quantum/keycodes.h b/quantum/keycodes.h
141index f24ccf01b8fcc9faace757a8dcfc3d24ef19445a..4fa4306ed61736b824e7510dc4bbcb0c83b7ae06 100644
142--- a/quantum/keycodes.h
143+++ b/quantum/keycodes.h
144@@ -717,6 +717,8 @@ enum qk_keycode_defines {
145 QK_AUTOCORRECT_ON = 0x7C74,
146 QK_AUTOCORRECT_OFF = 0x7C75,
147 QK_AUTOCORRECT_TOGGLE = 0x7C76,
148+ QK_TRI_LAYER_LOWER = 0x7C77,
149+ QK_TRI_LAYER_UPPER = 0x7C78,
150 SAFE_RANGE = 0x7E00,
151
152 // Alias
153@@ -1282,6 +1284,8 @@ enum qk_keycode_defines {
154 AC_ON = QK_AUTOCORRECT_ON,
155 AC_OFF = QK_AUTOCORRECT_OFF,
156 AC_TOGG = QK_AUTOCORRECT_TOGGLE,
157+ TL_LOWR = QK_TRI_LAYER_LOWER,
158+ TL_UPPR = QK_TRI_LAYER_UPPER,
159 };
160
161 // Range Helpers
162@@ -1333,4 +1337,4 @@ enum qk_keycode_defines {
163 #define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31)
164 #define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING)
165 #define IS_RGB_KEYCODE(code) ((code) >= RGB_TOG && (code) <= RGB_MODE_TWINKLE)
166-#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_AUTOCORRECT_TOGGLE)
167+#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_TRI_LAYER_UPPER)
168diff --git a/quantum/process_keycode/process_tri_layer.c b/quantum/process_keycode/process_tri_layer.c
169new file mode 100644
170index 0000000000000000000000000000000000000000..1e681b9a1c2e5663f0a6980833c1c46281664dab
171--- /dev/null
172+++ b/quantum/process_keycode/process_tri_layer.c
173@@ -0,0 +1,30 @@
174+// Copyright 2023 QMK
175+// SPDX-License-Identifier: GPL-2.0-or-later
176+
177+#include "process_tri_layer.h"
178+#include "tri_layer.h"
179+#include "action_layer.h"
180+
181+bool process_tri_layer(uint16_t keycode, keyrecord_t *record) {
182+ switch (keycode) {
183+ case QK_TRI_LAYER_LOWER:
184+ if (record->event.pressed) {
185+ layer_on(get_tri_layer_lower_layer());
186+ update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
187+ } else {
188+ layer_off(get_tri_layer_lower_layer());
189+ update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
190+ }
191+ return false;
192+ case QK_TRI_LAYER_UPPER:
193+ if (record->event.pressed) {
194+ layer_on(get_tri_layer_upper_layer());
195+ update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
196+ } else {
197+ layer_off(get_tri_layer_upper_layer());
198+ update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer());
199+ }
200+ return false;
201+ }
202+ return true;
203+}
204diff --git a/quantum/process_keycode/process_tri_layer.h b/quantum/process_keycode/process_tri_layer.h
205new file mode 100644
206index 0000000000000000000000000000000000000000..9c4e3df1c2f4bc47215a51d9110e9e5c1217dff4
207--- /dev/null
208+++ b/quantum/process_keycode/process_tri_layer.h
209@@ -0,0 +1,16 @@
210+// Copyright 2023 QMK
211+// SPDX-License-Identifier: GPL-2.0-or-later
212+
213+#pragma once
214+
215+#include "action.h"
216+
217+/**
218+ * @brief Handles tri layer behavior
219+ *
220+ * @param keycode the keycode
221+ * @param record the key record structure
222+ * @return true continue handling keycodes
223+ * @return false stop handling keycodes
224+ */
225+bool process_tri_layer(uint16_t keycode, keyrecord_t *record);
226diff --git a/quantum/quantum.c b/quantum/quantum.c
227index 5554ecab327b07d67ff927172276d65fd0327b2a..0587f215fe3a8933b789ad5b956fdd56e9d9942a 100644
228--- a/quantum/quantum.c
229+++ b/quantum/quantum.c
230@@ -342,6 +342,9 @@ bool process_record_quantum(keyrecord_t *record) {
231 #endif
232 #ifdef AUTOCORRECT_ENABLE
233 process_autocorrect(keycode, record) &&
234+#endif
235+#ifdef TRI_LAYER_ENABLE
236+ process_tri_layer(keycode, record) &&
237 #endif
238 true)) {
239 return false;
240@@ -443,16 +446,6 @@ void set_single_persistent_default_layer(uint8_t default_layer) {
241 default_layer_set((layer_state_t)1 << default_layer);
242 }
243
244-layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
245- layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2);
246- layer_state_t mask3 = (layer_state_t)1 << layer3;
247- return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
248-}
249-
250-void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
251- layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
252-}
253-
254 //------------------------------------------------------------------------------
255 // Override these functions in your keymap file to play different tunes on
256 // different events such as startup and bootloader jump
257diff --git a/quantum/quantum.h b/quantum/quantum.h
258index 615ec2382c5075cb4f3bef804ab83de30672b03f..708d325a3219b7be439b5bb16d2210c70f92753e 100644
259--- a/quantum/quantum.h
260+++ b/quantum/quantum.h
261@@ -240,9 +240,10 @@ extern layer_state_t layer_state;
262 # include "process_autocorrect.h"
263 #endif
264
265-// For tri-layer
266-void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
267-layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);
268+#ifdef TRI_LAYER_ENABLE
269+# include "tri_layer.h"
270+# include "process_tri_layer.h"
271+#endif
272
273 void set_single_persistent_default_layer(uint8_t default_layer);
274
275diff --git a/quantum/tri_layer.c b/quantum/tri_layer.c
276new file mode 100644
277index 0000000000000000000000000000000000000000..a5e3f8cb477f7681c6917a03d0ba74550ea8baec
278--- /dev/null
279+++ b/quantum/tri_layer.c
280@@ -0,0 +1,39 @@
281+// Copyright 2023 QMK
282+// SPDX-License-Identifier: GPL-2.0-or-later
283+
284+#include "tri_layer.h"
285+#include <stdint.h>
286+
287+static uint8_t tri_layer_lower_layer = TRI_LAYER_LOWER_LAYER;
288+static uint8_t tri_layer_upper_layer = TRI_LAYER_UPPER_LAYER;
289+static uint8_t tri_layer_adjust_layer = TRI_LAYER_ADJUST_LAYER;
290+
291+void set_tri_layer_lower_layer(uint8_t layer) {
292+ tri_layer_lower_layer = layer;
293+}
294+
295+void set_tri_layer_upper_layer(uint8_t layer) {
296+ tri_layer_upper_layer = layer;
297+}
298+
299+void set_tri_layer_adjust_layer(uint8_t layer) {
300+ tri_layer_adjust_layer = layer;
301+}
302+
303+void set_tri_layer_layers(uint8_t lower, uint8_t raise, uint8_t adjust) {
304+ tri_layer_lower_layer = lower;
305+ tri_layer_upper_layer = raise;
306+ tri_layer_adjust_layer = adjust;
307+}
308+
309+uint8_t get_tri_layer_lower_layer(void) {
310+ return tri_layer_lower_layer;
311+}
312+
313+uint8_t get_tri_layer_upper_layer(void) {
314+ return tri_layer_upper_layer;
315+}
316+
317+uint8_t get_tri_layer_adjust_layer(void) {
318+ return tri_layer_adjust_layer;
319+}
320diff --git a/quantum/tri_layer.h b/quantum/tri_layer.h
321new file mode 100644
322index 0000000000000000000000000000000000000000..3341ebffb288cf355f909e1a0d5d68c5316282b5
323--- /dev/null
324+++ b/quantum/tri_layer.h
325@@ -0,0 +1,59 @@
326+// Copyright 2023 QMK
327+// SPDX-License-Identifier: GPL-2.0-or-later
328+
329+#include <stdint.h>
330+
331+#ifndef TRI_LAYER_LOWER_LAYER
332+# define TRI_LAYER_LOWER_LAYER 1
333+#endif
334+#ifndef TRI_LAYER_UPPER_LAYER
335+# define TRI_LAYER_UPPER_LAYER 2
336+#endif
337+#ifndef TRI_LAYER_ADJUST_LAYER
338+# define TRI_LAYER_ADJUST_LAYER 3
339+#endif
340+
341+/**
342+ * @brief Set the tri layer lower layer index
343+ *
344+ * @param layer
345+ */
346+void set_tri_layer_lower_layer(uint8_t layer);
347+/**
348+ * @brief Set the tri layer upper layer index
349+ *
350+ * @param layer
351+ */
352+void set_tri_layer_upper_layer(uint8_t layer);
353+/**
354+ * @brief Set the tri layer adjust layer index
355+ *
356+ * @param layer
357+ */
358+void set_tri_layer_adjust_layer(uint8_t layer);
359+/**
360+ * @brief Set the tri layer indices
361+ *
362+ * @param lower
363+ * @param upper
364+ * @param adjust
365+ */
366+void set_tri_layer_layers(uint8_t lower, uint8_t upper, uint8_t adjust);
367+/**
368+ * @brief Get the tri layer lower layer index
369+ *
370+ * @return uint8_t
371+ */
372+uint8_t get_tri_layer_lower_layer(void);
373+/**
374+ * @brief Get the tri layer upper layer index
375+ *
376+ * @return uint8_t
377+ */
378+uint8_t get_tri_layer_upper_layer(void);
379+/**
380+ * @brief Get the tri layer adjust layer index
381+ *
382+ * @return uint8_t
383+ */
384+uint8_t get_tri_layer_adjust_layer(void);
385diff --git a/tests/test_common/keycode_table.cpp b/tests/test_common/keycode_table.cpp
386index ab9c292e95dbae28195f064a40ee5d5f4a73703f..337bc8fb5f5c5e5726f22acf2e8609d52838346b 100644
387--- a/tests/test_common/keycode_table.cpp
388+++ b/tests/test_common/keycode_table.cpp
389@@ -659,5 +659,7 @@ std::map<uint16_t, std::string> KEYCODE_ID_TABLE = {
390 {QK_AUTOCORRECT_ON, "QK_AUTOCORRECT_ON"},
391 {QK_AUTOCORRECT_OFF, "QK_AUTOCORRECT_OFF"},
392 {QK_AUTOCORRECT_TOGGLE, "QK_AUTOCORRECT_TOGGLE"},
393+ {QK_TRI_LAYER_LOWER, "QK_TRI_LAYER_LOWER"},
394+ {QK_TRI_LAYER_UPPER, "QK_TRI_LAYER_UPPER"},
395 {SAFE_RANGE, "SAFE_RANGE"},
396 };
397diff --git a/tests/tri_layer/config.h b/tests/tri_layer/config.h
398new file mode 100644
399index 0000000000000000000000000000000000000000..b68bf0c2d5aa19e7439bf7f3ecd2d224ba78e74c
400--- /dev/null
401+++ b/tests/tri_layer/config.h
402@@ -0,0 +1,6 @@
403+// Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
404+// SPDX-License-Identifier: GPL-2.0-or-later
405+
406+#pragma once
407+
408+#include "test_common.h"
409diff --git a/tests/tri_layer/test.mk b/tests/tri_layer/test.mk
410new file mode 100644
411index 0000000000000000000000000000000000000000..50548c3e1c0e0d9698d14c7c08743acd33af73df
412--- /dev/null
413+++ b/tests/tri_layer/test.mk
414@@ -0,0 +1,8 @@
415+# Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
416+# SPDX-License-Identifier: GPL-2.0-or-later
417+
418+# --------------------------------------------------------------------------------
419+# Keep this file, even if it is empty, as a marker that this folder contains tests
420+# --------------------------------------------------------------------------------
421+
422+TRI_LAYER_ENABLE = yes
423diff --git a/tests/tri_layer/test_tri_layer.cpp b/tests/tri_layer/test_tri_layer.cpp
424new file mode 100644
425index 0000000000000000000000000000000000000000..fffc124f4c6aa2390d5531dc7794ac6b5f6d2e61
426--- /dev/null
427+++ b/tests/tri_layer/test_tri_layer.cpp
428@@ -0,0 +1,103 @@
429+// Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
430+// SPDX-License-Identifier: GPL-2.0-or-later
431+
432+#include "test_common.hpp"
433+
434+using testing::_;
435+using testing::InSequence;
436+
437+class TriLayer : public TestFixture {};
438+
439+TEST_F(TriLayer, TriLayerLowerTest) {
440+ TestDriver driver;
441+ KeymapKey lower_layer_key = KeymapKey{0, 0, 0, QK_TRI_LAYER_LOWER};
442+
443+ set_keymap({lower_layer_key, KeymapKey{1, 0, 0, KC_TRNS}});
444+
445+ /* Press Lower. */
446+ EXPECT_NO_REPORT(driver);
447+ lower_layer_key.press();
448+ run_one_scan_loop();
449+ EXPECT_TRUE(layer_state_is(get_tri_layer_lower_layer()));
450+ EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
451+ EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
452+ VERIFY_AND_CLEAR(driver);
453+
454+ /* Release Lower. */
455+ EXPECT_NO_REPORT(driver);
456+ lower_layer_key.release();
457+ run_one_scan_loop();
458+ EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
459+ EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
460+ EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
461+ VERIFY_AND_CLEAR(driver);
462+}
463+
464+TEST_F(TriLayer, TriLayerUpperTest) {
465+ TestDriver driver;
466+ KeymapKey upper_layer_key = KeymapKey{0, 0, 0, QK_TRI_LAYER_UPPER};
467+
468+ set_keymap({upper_layer_key, KeymapKey{2, 0, 0, KC_TRNS}});
469+
470+ /* Press Raise. */
471+ EXPECT_NO_REPORT(driver);
472+ upper_layer_key.press();
473+ run_one_scan_loop();
474+ EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
475+ EXPECT_TRUE(layer_state_is(get_tri_layer_upper_layer()));
476+ EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
477+ VERIFY_AND_CLEAR(driver);
478+
479+ /* Release Raise. */
480+ EXPECT_NO_REPORT(driver);
481+ upper_layer_key.release();
482+ run_one_scan_loop();
483+ EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
484+ EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
485+ EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
486+ VERIFY_AND_CLEAR(driver);
487+}
488+
489+TEST_F(TriLayer, TriLayerAdjustTest) {
490+ TestDriver driver;
491+ KeymapKey lower_layer_key = KeymapKey{0, 0, 0, QK_TRI_LAYER_LOWER};
492+ KeymapKey upper_layer_key = KeymapKey{0, 1, 0, QK_TRI_LAYER_UPPER};
493+
494+ set_keymap({
495+ upper_layer_key,
496+ lower_layer_key,
497+ KeymapKey{1, 0, 0, KC_TRNS},
498+ KeymapKey{1, 1, 0, KC_TRNS},
499+ KeymapKey{2, 0, 0, KC_TRNS},
500+ KeymapKey{2, 1, 0, KC_TRNS},
501+ KeymapKey{3, 0, 0, KC_TRNS},
502+ KeymapKey{3, 1, 0, KC_TRNS},
503+ });
504+
505+ /* Press Lower, then upper, and release upper and then lower. */
506+ EXPECT_NO_REPORT(driver);
507+ lower_layer_key.press();
508+ run_one_scan_loop();
509+ EXPECT_TRUE(layer_state_is(get_tri_layer_lower_layer()));
510+ EXPECT_FALSE(layer_state_is(get_tri_layer_upper_layer()));
511+ EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
512+
513+ upper_layer_key.press();
514+ run_one_scan_loop();
515+ EXPECT_TRUE(layer_state_is(get_tri_layer_lower_layer()));
516+ EXPECT_TRUE(layer_state_is(get_tri_layer_upper_layer()));
517+ EXPECT_TRUE(layer_state_is(get_tri_layer_adjust_layer()));
518+
519+ lower_layer_key.release();
520+ run_one_scan_loop();
521+ EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));
522+ EXPECT_TRUE(layer_state_is(get_tri_layer_upper_layer()));
523+ EXPECT_FALSE(layer_state_is(get_tri_layer_adjust_layer()));
524+
525+ upper_layer_key.release();
526+ run_one_scan_loop();
527+ EXPECT_FALSE(layer_state_is(get_tri_layer_lower_layer()));