From c2480884aa1321ec4a0364f773476f0e7f7d3069 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Sat, 5 Mar 2016 14:42:17 +0100
Subject: Fix the layer-dependent modifiers handling

Closes #181.
---
 tmk_core/common/action.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 77ea39e942..be06e12aae 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -53,6 +53,26 @@ void action_exec(keyevent_t event)
 #endif
 }
 
+/*
+ * Make sure the action triggered when the key is released is the same
+ * one as the one triggered on press. It's important for the mod keys
+ * when the layer is switched after the down event but before the up
+ * event as they may get stuck otherwise.
+ */
+action_t store_or_get_action(bool pressed, keypos_t key)
+{
+#ifndef NO_ACTION_LAYER
+    static action_t pressed_actions[MATRIX_ROWS][MATRIX_COLS];
+
+    if (pressed) {
+        pressed_actions[key.row][key.col] = layer_switch_get_action(key);
+    }
+    return pressed_actions[key.row][key.col];
+#else
+    return layer_switch_get_action(key);
+#endif
+}
+
 void process_action(keyrecord_t *record)
 {
     keyevent_t event = record->event;
@@ -62,7 +82,7 @@ void process_action(keyrecord_t *record)
 
     if (IS_NOEVENT(event)) { return; }
 
-    action_t action = layer_switch_get_action(event.key);
+    action_t action = store_or_get_action(event.pressed, event.key);
     dprint("ACTION: "); debug_action(action);
 #ifndef NO_ACTION_LAYER
     dprint(" layer_state: "); layer_debug();
-- 
cgit v1.2.3


From 8d55a12a9538742f510087f14fc59eb813b2ef42 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Tue, 8 Mar 2016 08:48:43 +0100
Subject: Document the issue of stuck modifiers

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index be06e12aae..26a5fad7ac 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -61,7 +61,7 @@ void action_exec(keyevent_t event)
  */
 action_t store_or_get_action(bool pressed, keypos_t key)
 {
-#ifndef NO_ACTION_LAYER
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
     static action_t pressed_actions[MATRIX_ROWS][MATRIX_COLS];
 
     if (pressed) {
-- 
cgit v1.2.3


From 20dd9c032616722a54174d53b0f8824f639b5263 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Sun, 13 Mar 2016 00:18:20 +0100
Subject: process_action may be called either with key cache or without it

If one wants to temporarily disable the key cache (for example because
it interferes with a macro), `disable_action_cache` must be set to
`true`. `process_action_nocache` is a simple wrapper doing just that for
a single call.
---
 tmk_core/common/action.c | 15 +++++++++++++++
 tmk_core/common/action.h |  4 ++++
 2 files changed, 19 insertions(+)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 26a5fad7ac..1d3b738110 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -53,6 +53,17 @@ void action_exec(keyevent_t event)
 #endif
 }
 
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+bool disable_action_cache = false;
+
+void process_action_nocache(keyrecord_t *record)
+{
+    disable_action_cache = true;
+    process_action(record);
+    disable_action_cache = false;
+}
+#endif
+
 /*
  * Make sure the action triggered when the key is released is the same
  * one as the one triggered on press. It's important for the mod keys
@@ -64,6 +75,10 @@ action_t store_or_get_action(bool pressed, keypos_t key)
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
     static action_t pressed_actions[MATRIX_ROWS][MATRIX_COLS];
 
+    if (disable_action_cache) {
+        return layer_switch_get_action(key);
+    }
+
     if (pressed) {
         pressed_actions[key.row][key.col] = layer_switch_get_action(key);
     }
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 8a4736d7bc..34a794db29 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -59,6 +59,10 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
 void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
 
 /* Utilities for actions.  */
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+extern bool disable_action_cache;
+void process_action_nocache(keyrecord_t *record);
+#endif
 void process_action(keyrecord_t *record);
 void register_code(uint8_t code);
 void unregister_code(uint8_t code);
-- 
cgit v1.2.3


From 73cb87740bd814c95007f9ef6ce3dcd542a62afd Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Tue, 15 Mar 2016 16:03:30 +0100
Subject: Always provide an implementation of process_action_nocache

---
 tmk_core/common/action.c | 5 +++++
 tmk_core/common/action.h | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 1d3b738110..0a3822a06c 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -62,6 +62,11 @@ void process_action_nocache(keyrecord_t *record)
     process_action(record);
     disable_action_cache = false;
 }
+#else
+void process_action_nocache(keyrecord_t *record)
+{
+    process_action(record);
+}
 #endif
 
 /*
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 34a794db29..533e5d1a01 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -61,8 +61,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
 /* Utilities for actions.  */
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 extern bool disable_action_cache;
-void process_action_nocache(keyrecord_t *record);
 #endif
+void process_action_nocache(keyrecord_t *record);
 void process_action(keyrecord_t *record);
 void register_code(uint8_t code);
 void unregister_code(uint8_t code);
-- 
cgit v1.2.3


From a5cdc3aab1c430916eae66d4d9d751808613e700 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Tue, 15 Mar 2016 16:51:50 +0100
Subject: Expose the pressed_actions_cache global variable

---
 tmk_core/common/action.c | 7 +++----
 tmk_core/common/action.h | 1 +
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 0a3822a06c..fc09383ee0 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,6 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
+action_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
 
 void process_action_nocache(keyrecord_t *record)
 {
@@ -78,16 +79,14 @@ void process_action_nocache(keyrecord_t *record)
 action_t store_or_get_action(bool pressed, keypos_t key)
 {
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
-    static action_t pressed_actions[MATRIX_ROWS][MATRIX_COLS];
-
     if (disable_action_cache) {
         return layer_switch_get_action(key);
     }
 
     if (pressed) {
-        pressed_actions[key.row][key.col] = layer_switch_get_action(key);
+        pressed_actions_cache[key.row][key.col] = layer_switch_get_action(key);
     }
-    return pressed_actions[key.row][key.col];
+    return pressed_actions_cache[key.row][key.col];
 #else
     return layer_switch_get_action(key);
 #endif
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 533e5d1a01..7a60f320e7 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -61,6 +61,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
 /* Utilities for actions.  */
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 extern bool disable_action_cache;
+extern action_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
 #endif
 void process_action_nocache(keyrecord_t *record);
 void process_action(keyrecord_t *record);
-- 
cgit v1.2.3


From b4f442dfeaf4d434ae0d8459dc5199cd8fefc1c7 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Sun, 27 Mar 2016 23:50:07 +0200
Subject: Cut the memory consumption of PREVENT_STUCK_MODIFIERS in half

---
 tmk_core/common/action.c       |  6 +++---
 tmk_core/common/action.h       |  2 +-
 tmk_core/common/action_layer.c | 16 +++++++++-------
 tmk_core/common/action_layer.h |  3 +++
 4 files changed, 16 insertions(+), 11 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index fc09383ee0..acc6d11eab 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-action_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
+int8_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
 
 void process_action_nocache(keyrecord_t *record)
 {
@@ -84,9 +84,9 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     }
 
     if (pressed) {
-        pressed_actions_cache[key.row][key.col] = layer_switch_get_action(key);
+        pressed_actions_cache[key.row][key.col] = layer_switch_get_layer(key);
     }
-    return pressed_actions_cache[key.row][key.col];
+    return action_for_key(pressed_actions_cache[key.row][key.col], key);
 #else
     return layer_switch_get_action(key);
 #endif
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 7a60f320e7..2b43d001e1 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -61,7 +61,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
 /* Utilities for actions.  */
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 extern bool disable_action_cache;
-extern action_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
+extern int8_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
 #endif
 void process_action_nocache(keyrecord_t *record);
 void process_action(keyrecord_t *record);
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index c535615f44..76164adb5d 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -111,8 +111,7 @@ void layer_debug(void)
 #endif
 
 
-
-action_t layer_switch_get_action(keypos_t key)
+int8_t layer_switch_get_layer(keypos_t key)
 {
     action_t action;
     action.code = ACTION_TRANSPARENT;
@@ -124,15 +123,18 @@ action_t layer_switch_get_action(keypos_t key)
         if (layers & (1UL<<i)) {
             action = action_for_key(i, key);
             if (action.code != ACTION_TRANSPARENT) {
-                return action;
+                return i;
             }
         }
     }
     /* fall back to layer 0 */
-    action = action_for_key(0, key);
-    return action;
+    return 0;
 #else
-    action = action_for_key(biton32(default_layer_state), key);
-    return action;
+    return biton32(default_layer_state);
 #endif
 }
+
+action_t layer_switch_get_action(keypos_t key)
+{
+    return action_for_key(layer_switch_get_layer(key), key);
+}
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index b6da353cfd..1a313a2590 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -71,6 +71,9 @@ void layer_xor(uint32_t state);
 #endif
 
 
+/* return the topmost non-transparent layer currently associated with key */
+int8_t layer_switch_get_layer(keypos_t key);
+
 /* return action depending on current layer status */
 action_t layer_switch_get_action(keypos_t key);
 
-- 
cgit v1.2.3


From 317455178d177efc8eccdb8dc69ac18baf9e66e7 Mon Sep 17 00:00:00 2001
From: Eric-L-T <etang2099@gmail.com>
Date: Fri, 1 Apr 2016 13:43:49 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index acc6d11eab..4457d16d86 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-int8_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
+uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS) / 8) ? ((MATRIX_ROWS * MATRIX_COLS) / 8) : 1];
 
 void process_action_nocache(keyrecord_t *record)
 {
@@ -82,11 +82,22 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     if (disable_action_cache) {
         return layer_switch_get_action(key);
     }
-
+    uint8_t key_number = (key.col + (key.row * MATRIX_COLS));
+    uint8_t storage_row = key_number / 8;
+    uint8_t storage_bit = key_number % 8;
+    uint8_t layer;
     if (pressed) {
-        pressed_actions_cache[key.row][key.col] = layer_switch_get_layer(key);
+        layer = layer_switch_get_layer(key);
+        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
+            source_layers_cache[bit_number][storage_row] ^= (-(!!(layer & (1 << bit_number)) ^ source_layers_cache[bit_number][storage_row])) & (1 << storage_bit);
+        }
+    } else {
+        layer = 0;
+        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
+            layer |= (!!(source_layers_cache[bit_number][storage_row] & (1 << storage_bit))) << bit_number;
+        }
     }
-    return action_for_key(pressed_actions_cache[key.row][key.col], key);
+    return action_for_key(layer, key);
 #else
     return layer_switch_get_action(key);
 #endif
-- 
cgit v1.2.3


From cd8dd1b6d6a68c1d6ba48ba58e6ddad7dbbce6c2 Mon Sep 17 00:00:00 2001
From: Eric-L-T <etang2099@gmail.com>
Date: Fri, 1 Apr 2016 13:45:01 -0700
Subject: Update action.h

---
 tmk_core/common/action.h | 1 -
 1 file changed, 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 2b43d001e1..533e5d1a01 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -61,7 +61,6 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
 /* Utilities for actions.  */
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 extern bool disable_action_cache;
-extern int8_t pressed_actions_cache[MATRIX_ROWS][MATRIX_COLS];
 #endif
 void process_action_nocache(keyrecord_t *record);
 void process_action(keyrecord_t *record);
-- 
cgit v1.2.3


From 9a35f01c5516081a8c503d2344f0d082b1a29cd5 Mon Sep 17 00:00:00 2001
From: Eric-L-T <etang2099@gmail.com>
Date: Fri, 1 Apr 2016 13:49:03 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 4457d16d86..9ba03675a1 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -82,7 +82,7 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     if (disable_action_cache) {
         return layer_switch_get_action(key);
     }
-    uint8_t key_number = (key.col + (key.row * MATRIX_COLS));
+    uint8_t key_number = key.col + (key.row * MATRIX_COLS);
     uint8_t storage_row = key_number / 8;
     uint8_t storage_bit = key_number % 8;
     uint8_t layer;
-- 
cgit v1.2.3


From 420fc8620bfd47604848066b9d3798fb68a12e03 Mon Sep 17 00:00:00 2001
From: Eric-L-T <etang2099@gmail.com>
Date: Fri, 1 Apr 2016 18:26:43 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 9ba03675a1..e4cbac9e80 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -82,18 +82,18 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     if (disable_action_cache) {
         return layer_switch_get_action(key);
     }
-    uint8_t key_number = key.col + (key.row * MATRIX_COLS);
-    uint8_t storage_row = key_number / 8;
-    uint8_t storage_bit = key_number % 8;
-    uint8_t layer;
+    int8_t key_number = key.col + (key.row * MATRIX_COLS);
+    int8_t storage_row = key_number / 8;
+    int8_t storage_bit = key_number % 8;
+    int8_t layer;
     if (pressed) {
         layer = layer_switch_get_layer(key);
-        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
+        for (int8_t bit_number = 0; bit_number <= 4; bit_number++) {
             source_layers_cache[bit_number][storage_row] ^= (-(!!(layer & (1 << bit_number)) ^ source_layers_cache[bit_number][storage_row])) & (1 << storage_bit);
         }
     } else {
         layer = 0;
-        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
+        for (int8_t bit_number = 0; bit_number <= 4; bit_number++) {
             layer |= (!!(source_layers_cache[bit_number][storage_row] & (1 << storage_bit))) << bit_number;
         }
     }
-- 
cgit v1.2.3


From 307f1dee21ba8ffc94d50b6b9338d54fa2e4d191 Mon Sep 17 00:00:00 2001
From: Eric-L-T <etang2099@gmail.com>
Date: Fri, 1 Apr 2016 19:54:02 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index e4cbac9e80..eecfdbb6da 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -82,19 +82,19 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     if (disable_action_cache) {
         return layer_switch_get_action(key);
     }
-    int8_t key_number = key.col + (key.row * MATRIX_COLS);
-    int8_t storage_row = key_number / 8;
-    int8_t storage_bit = key_number % 8;
-    int8_t layer;
+    uint8_t key_number = key.col + (key.row * MATRIX_COLS);
+    uint8_t storage_row = key_number / 8;
+    uint8_t storage_bit = key_number % 8;
+    uint8_t layer;
     if (pressed) {
         layer = layer_switch_get_layer(key);
-        for (int8_t bit_number = 0; bit_number <= 4; bit_number++) {
-            source_layers_cache[bit_number][storage_row] ^= (-(!!(layer & (1 << bit_number)) ^ source_layers_cache[bit_number][storage_row])) & (1 << storage_bit);
+        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
+            source_layers_cache[bit_number][storage_row] ^= (-(!!(layer & (1U << bit_number)) ^ source_layers_cache[bit_number][storage_row])) & (1U << storage_bit);
         }
     } else {
         layer = 0;
-        for (int8_t bit_number = 0; bit_number <= 4; bit_number++) {
-            layer |= (!!(source_layers_cache[bit_number][storage_row] & (1 << storage_bit))) << bit_number;
+        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
+            layer |= (uint8_t)(!!(source_layers_cache[bit_number][storage_row] & (1U << storage_bit))) << bit_number;
         }
     }
     return action_for_key(layer, key);
-- 
cgit v1.2.3


From f5365d1c1c619c5cb85b9b1ba97ebd04a7f56e05 Mon Sep 17 00:00:00 2001
From: Eric-L-T <etang2099@gmail.com>
Date: Fri, 1 Apr 2016 20:04:13 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index eecfdbb6da..f6fc8b0056 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -89,7 +89,7 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     if (pressed) {
         layer = layer_switch_get_layer(key);
         for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
-            source_layers_cache[bit_number][storage_row] ^= (-(!!(layer & (1U << bit_number)) ^ source_layers_cache[bit_number][storage_row])) & (1U << storage_bit);
+            source_layers_cache[bit_number][storage_row] ^= (-(bool)((layer & (1U << bit_number)) != 0) ^ source_layers_cache[bit_number][storage_row])) & (1U << storage_bit);
         }
     } else {
         layer = 0;
-- 
cgit v1.2.3


From 680301e3e3f837aa4f8bda403af3fc42156516fa Mon Sep 17 00:00:00 2001
From: eltang <etang2099@gmail.com>
Date: Sat, 2 Apr 2016 06:48:44 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index f6fc8b0056..8735c7d648 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -91,7 +91,8 @@ action_t store_or_get_action(bool pressed, keypos_t key)
         for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
             source_layers_cache[bit_number][storage_row] ^= (-(bool)((layer & (1U << bit_number)) != 0) ^ source_layers_cache[bit_number][storage_row])) & (1U << storage_bit);
         }
-    } else {
+    }
+    else {
         layer = 0;
         for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
             layer |= (uint8_t)(!!(source_layers_cache[bit_number][storage_row] & (1U << storage_bit))) << bit_number;
-- 
cgit v1.2.3


From fddccc95fe480a2ed039ffdac6aa9f3fac1f444f Mon Sep 17 00:00:00 2001
From: eltang <etang2099@gmail.com>
Date: Sat, 2 Apr 2016 09:13:13 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 8735c7d648..a3c5b4c5a9 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -95,7 +95,7 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     else {
         layer = 0;
         for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
-            layer |= (uint8_t)(!!(source_layers_cache[bit_number][storage_row] & (1U << storage_bit))) << bit_number;
+            layer |= (uint8_t)((source_layers_cache[bit_number][storage_row] & (1U << storage_bit)) != 0) << bit_number;
         }
     }
     return action_for_key(layer, key);
-- 
cgit v1.2.3


From da101b886689b3d2a8e4246ed20dee5f066bb1a1 Mon Sep 17 00:00:00 2001
From: eltang <etang2099@gmail.com>
Date: Sat, 2 Apr 2016 09:29:32 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index a3c5b4c5a9..ae4e5545cf 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS) / 8) ? ((MATRIX_ROWS * MATRIX_COLS) / 8) : 1];
+uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS) / 8) ? ((MATRIX_ROWS * MATRIX_COLS) / 8) : 1] = {};
 
 void process_action_nocache(keyrecord_t *record)
 {
-- 
cgit v1.2.3


From f4f592910c51c048b1e1a08408ce16fd14eb3c32 Mon Sep 17 00:00:00 2001
From: eltang <etang2099@gmail.com>
Date: Sat, 2 Apr 2016 09:34:01 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index ae4e5545cf..43d03f744c 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS) / 8) ? ((MATRIX_ROWS * MATRIX_COLS) / 8) : 1] = {};
+uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS) / 8) ? ((MATRIX_ROWS * MATRIX_COLS) / 8) : 1] = {0};
 
 void process_action_nocache(keyrecord_t *record)
 {
-- 
cgit v1.2.3


From 6c8e374d572f1cf0b62beb2a9718de84202c8a41 Mon Sep 17 00:00:00 2001
From: eltang <etang2099@gmail.com>
Date: Sat, 2 Apr 2016 09:59:53 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 43d03f744c..f47256de77 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS) / 8) ? ((MATRIX_ROWS * MATRIX_COLS) / 8) : 1] = {0};
+uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS + 7) / 8)] = {0};
 
 void process_action_nocache(keyrecord_t *record)
 {
-- 
cgit v1.2.3


From 5a9091689c3e1b4c444f56c9cb335817dc9fc2bb Mon Sep 17 00:00:00 2001
From: eltang <etang2099@gmail.com>
Date: Sat, 2 Apr 2016 10:00:31 -0700
Subject: Update action.c

---
 tmk_core/common/action.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index f47256de77..bf609f5e7b 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,7 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-uint8_t source_layers_cache[5][((MATRIX_ROWS * MATRIX_COLS + 7) / 8)] = {0};
+uint8_t source_layers_cache[5][(MATRIX_ROWS * MATRIX_COLS + 7) / 8] = {0};
 
 void process_action_nocache(keyrecord_t *record)
 {
-- 
cgit v1.2.3


From 4dce7258d1b31be0d91f6de0693a10917f514dd8 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Sat, 2 Apr 2016 18:00:28 +0200
Subject: Cleanup after merge

- remove a superfluous parenthesis
- wrap lines longer than 80 characters
- add const specifiers where appropriate
- remove unnecessary casts
---
 tmk_core/common/action.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index bf609f5e7b..78596a69cf 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -82,20 +82,26 @@ action_t store_or_get_action(bool pressed, keypos_t key)
     if (disable_action_cache) {
         return layer_switch_get_action(key);
     }
-    uint8_t key_number = key.col + (key.row * MATRIX_COLS);
-    uint8_t storage_row = key_number / 8;
-    uint8_t storage_bit = key_number % 8;
+    const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
+    const uint8_t storage_row = key_number / 8;
+    const uint8_t storage_bit = key_number % 8;
     uint8_t layer;
     if (pressed) {
         layer = layer_switch_get_layer(key);
-        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
-            source_layers_cache[bit_number][storage_row] ^= (-(bool)((layer & (1U << bit_number)) != 0) ^ source_layers_cache[bit_number][storage_row])) & (1U << storage_bit);
+        for (uint8_t bit_number = 0; bit_number < 5; bit_number++) {
+            source_layers_cache[bit_number][storage_row] ^=
+                (-((layer & (1U << bit_number)) != 0)
+                 ^ source_layers_cache[bit_number][storage_row])
+                & (1U << storage_bit);
         }
     }
     else {
         layer = 0;
-        for (uint8_t bit_number = 0; bit_number <= 4; bit_number++) {
-            layer |= (uint8_t)((source_layers_cache[bit_number][storage_row] & (1U << storage_bit)) != 0) << bit_number;
+        for (uint8_t bit_number = 0; bit_number < 5; bit_number++) {
+            layer |=
+                ((source_layers_cache[bit_number][storage_row]
+                  & (1U << storage_bit)) != 0)
+                << bit_number;
         }
     }
     return action_for_key(layer, key);
-- 
cgit v1.2.3


From 567f256c5d4598adb4dcd63fa4e4a7b4df553b12 Mon Sep 17 00:00:00 2001
From: Wojciech Siewierski <wojciech.siewierski@onet.pl>
Date: Tue, 5 Apr 2016 10:54:47 +0200
Subject: Refactor the source layer cache encoding

---
 tmk_core/common/action.c       | 41 ---------------------------
 tmk_core/common/action_layer.c | 63 ++++++++++++++++++++++++++++++++++++++++++
 tmk_core/common/action_layer.h |  8 ++++++
 3 files changed, 71 insertions(+), 41 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 20e1fc6149..6aa6dc2601 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,7 +55,6 @@ void action_exec(keyevent_t event)
 
 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
 bool disable_action_cache = false;
-uint8_t source_layers_cache[5][(MATRIX_ROWS * MATRIX_COLS + 7) / 8] = {0};
 
 void process_action_nocache(keyrecord_t *record)
 {
@@ -70,46 +69,6 @@ void process_action_nocache(keyrecord_t *record)
 }
 #endif
 
-/*
- * Make sure the action triggered when the key is released is the same
- * one as the one triggered on press. It's important for the mod keys
- * when the layer is switched after the down event but before the up
- * event as they may get stuck otherwise.
- */
-action_t store_or_get_action(bool pressed, keypos_t key)
-{
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
-    if (disable_action_cache) {
-        return layer_switch_get_action(key);
-    }
-    const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
-    const uint8_t storage_row = key_number / 8;
-    const uint8_t storage_bit = key_number % 8;
-    uint8_t layer;
-    if (pressed) {
-        layer = layer_switch_get_layer(key);
-        for (uint8_t bit_number = 0; bit_number < 5; bit_number++) {
-            source_layers_cache[bit_number][storage_row] ^=
-                (-((layer & (1U << bit_number)) != 0)
-                 ^ source_layers_cache[bit_number][storage_row])
-                & (1U << storage_bit);
-        }
-    }
-    else {
-        layer = 0;
-        for (uint8_t bit_number = 0; bit_number < 5; bit_number++) {
-            layer |=
-                ((source_layers_cache[bit_number][storage_row]
-                  & (1U << storage_bit)) != 0)
-                << bit_number;
-        }
-    }
-    return action_for_key(layer, key);
-#else
-    return layer_switch_get_action(key);
-#endif
-}
-
 __attribute__ ((weak))
 void process_action_kb(keyrecord_t *record) {}
 
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index 76164adb5d..fc721a7323 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -110,6 +110,69 @@ void layer_debug(void)
 }
 #endif
 
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+uint8_t source_layers_cache[MAX_LAYER_BITS][(MATRIX_ROWS * MATRIX_COLS + 7) / 8] = {0};
+
+void update_source_layers_cache(keypos_t key, uint8_t layer)
+{
+    const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
+    const uint8_t storage_row = key_number / 8;
+    const uint8_t storage_bit = key_number % 8;
+
+    for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
+        source_layers_cache[bit_number][storage_row] ^=
+            (-((layer & (1U << bit_number)) != 0)
+             ^ source_layers_cache[bit_number][storage_row])
+            & (1U << storage_bit);
+    }
+}
+
+uint8_t read_source_layers_cache(keypos_t key)
+{
+    const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
+    const uint8_t storage_row = key_number / 8;
+    const uint8_t storage_bit = key_number % 8;
+    uint8_t layer = 0;
+
+    for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
+        layer |=
+            ((source_layers_cache[bit_number][storage_row]
+              & (1U << storage_bit)) != 0)
+            << bit_number;
+    }
+
+    return layer;
+}
+#endif
+
+/*
+ * Make sure the action triggered when the key is released is the same
+ * one as the one triggered on press. It's important for the mod keys
+ * when the layer is switched after the down event but before the up
+ * event as they may get stuck otherwise.
+ */
+action_t store_or_get_action(bool pressed, keypos_t key)
+{
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+    if (disable_action_cache) {
+        return layer_switch_get_action(key);
+    }
+
+    uint8_t layer;
+
+    if (pressed) {
+        layer = layer_switch_get_layer(key);
+        update_source_layers_cache(key, layer);
+    }
+    else {
+        layer = read_source_layers_cache(key);
+    }
+    return action_for_key(layer, key);
+#else
+    return layer_switch_get_action(key);
+#endif
+}
+
 
 int8_t layer_switch_get_layer(keypos_t key)
 {
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 1a313a2590..3a4b1e3349 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -70,6 +70,14 @@ void layer_xor(uint32_t state);
 #define layer_debug()
 #endif
 
+/* pressed actions cache */
+#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+/* The number of bits needed to represent the layer number: log2(32). */
+#define MAX_LAYER_BITS 5
+void update_source_layers_cache(keypos_t key, uint8_t layer);
+uint8_t read_source_layers_cache(keypos_t key);
+#endif
+action_t store_or_get_action(bool pressed, keypos_t key);
 
 /* return the topmost non-transparent layer currently associated with key */
 int8_t layer_switch_get_layer(keypos_t key);
-- 
cgit v1.2.3


From 08871e56f78c08340bb229300c457c852105d155 Mon Sep 17 00:00:00 2001
From: Didier Loiseau <didierloiseau+git@gmail.com>
Date: Wed, 6 Apr 2016 00:19:12 +0200
Subject: Fix issue #221: LGUI(KC_LSFT) does not work

on mod keys, register LGUI, LSFT etc. as normal mods
 instead of weak mods:
 - they won't be cleared when pressing another key (#188)
 - they won't be cleared by layer switching
 - LSFT(KC_LGUI) will now have the same behavior as LGUI(KC_LSFT)
---
 tmk_core/common/action.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

(limited to 'tmk_core/common')

diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 2ccc0e0b94..9010896343 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -88,14 +88,24 @@ void process_action(keyrecord_t *record)
                                                                 action.key.mods<<4;
                 if (event.pressed) {
                     if (mods) {
-                        add_weak_mods(mods);
+                        if (IS_MOD(action.key.code)) {
+                            // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
+                            // this also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT)
+                            add_mods(mods);
+                        } else {
+                            add_weak_mods(mods);
+                        }
                         send_keyboard_report();
                     }
                     register_code(action.key.code);
                 } else {
                     unregister_code(action.key.code);
                     if (mods) {
-                        del_weak_mods(mods);
+                        if (IS_MOD(action.key.code)) {
+                            del_mods(mods);
+                        } else {
+                            del_weak_mods(mods);
+                        }
                         send_keyboard_report();
                     }
                 }
-- 
cgit v1.2.3