core: Fix LAYER_MODS() and LAYER_TAP()
authortmk <hasu@tmk-kbd.com>
Wed, 11 Jan 2017 01:30:47 +0000 (10:30 +0900)
committertmk <hasu@tmk-kbd.com>
Wed, 11 Jan 2017 01:30:47 +0000 (10:30 +0900)
- LAYER_MODS() accepts either left or right modifiers
- LAYER_TAP() can use modifier as tap key, related to #422

README.md
tmk_core/common/action.c
tmk_core/common/action_code.h
tmk_core/doc/keymap.md

index 68e92b468eb0294aad5080096404489930e967ef..ee44d00d9695f1ade5e23e3140628ceeec9547be 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,6 +7,9 @@ The latest source code is available here: <http://github.com/tmk/tmk_keyboard>
 
 Updates
 -------
+#### 2017/01/11
+Changed action code for `ACTION_LAYER_MODS` and this may cause incompatibility with existent shared URL and downloaded firmwware of keymap editor. If you are using the action you just have to redefine it on keymap editor. Existent keymap code should not suffer.
+
 #### 2016/06/26
 Keymap framework was updated. `fn_actions[]` should be defined as `action_t` instead of `uint16_t`. And default code for keymap handling is now included in core you just need define `uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]` and `action_t fn_actions[]`.
 
index 83b044feb9915b4de30aaba64ad8e2f3d3bfe486..ab6e9d895807898fde8b7112eadfb0eb8053b9e1 100644 (file)
@@ -101,7 +101,7 @@ void process_action(keyrecord_t *record)
             {
                 uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
                                                                     action.key.mods<<4;
-                switch (action.layer_tap.code) {
+                switch (action.key.code) {
     #ifndef NO_ACTION_ONESHOT
                     case MODS_ONESHOT:
                         // Oneshot modifier
@@ -247,14 +247,18 @@ void process_action(keyrecord_t *record)
         case ACT_LAYER_TAP:
         case ACT_LAYER_TAP_EXT:
             switch (action.layer_tap.code) {
-                case 0xe0 ... 0xef:
-                    /* layer On/Off with modifiers(left only) */
+                case 0xc0 ... 0xdf:
+                    /* layer On/Off with modifiers */
                     if (event.pressed) {
                         layer_on(action.layer_tap.val);
-                        register_mods(action.layer_tap.code & 0x0f);
+                        register_mods((action.layer_tap.code & 0x10) ?
+                                (action.layer_tap.code & 0x0f) << 4 :
+                                (action.layer_tap.code & 0x0f));
                     } else {
                         layer_off(action.layer_tap.val);
-                        unregister_mods(action.layer_tap.code & 0x0f);
+                        unregister_mods((action.layer_tap.code & 0x10) ?
+                                (action.layer_tap.code & 0x0f) << 4 :
+                                (action.layer_tap.code & 0x0f));
                     }
                     break;
                 case OP_TAP_TOGGLE:
@@ -532,12 +536,20 @@ bool is_tap_key(keypos_t key)
     switch (action.kind.id) {
         case ACT_LMODS_TAP:
         case ACT_RMODS_TAP:
+            switch (action.key.code) {
+                case MODS_ONESHOT:
+                case MODS_TAP_TOGGLE:
+                case KC_A ... KC_EXSEL:                 // tap key
+                case KC_LCTRL ... KC_RGUI:              // tap key
+                    return true;
+            }
         case ACT_LAYER_TAP:
         case ACT_LAYER_TAP_EXT:
             switch (action.layer_tap.code) {
-                case KC_A ... KC_EXSEL:
-                case KC_KP_00 ... KC_KP_HEXADECIMAL:
-                case KC_LCTRL ... KC_RGUI:
+                case 0xc0 ... 0xdf:         // with modifiers
+                    return false;
+                case KC_A ... KC_EXSEL:     // tap key
+                case KC_LCTRL ... KC_RGUI:  // tap key
                 case OP_TAP_TOGGLE:
                     return true;
             }
index 8dad38b961d8639e182be2a53b7fa3589be6d270..10d040ee0136dc1438409a9703a2b55fa66380b2 100644 (file)
@@ -29,14 +29,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 000r|0000|0000 0001    Transparent code
  * 000r|0000| keycode     Key
  * 000r|mods|0000 0000    Modifiers
- * 000r|mods| keycode     Modifiers+Key(Modified key)
+ * 000r|mods| keycode     Modifiers+key(Modified key)
  *   r: Left/Right flag(Left:0, Right:1)
  *
  * ACT_MODS_TAP(001r):
- * 001r|mods|0000 0000    Modifiers with OneShot
- * 001r|mods|0000 0001    Modifiers with tap toggle
- * 001r|mods|0000 00xx    (reserved)
- * 001r|mods| keycode     Modifiers with Tap Key(Dual role)
+ * 001r|mods|0000 0000    Modifiers with OneShot[TAP]
+ * 001r|mods|0000 0001    Modifiers with tap toggle[TAP]
+ * 001r|mods|0000 00xx    (reserved)            (0x02-03)
+ * 001r|mods| keycode     Modifiers with tap key(0x04-A4, E0-E7)[TAP]
+ *                        (reserved)            (0xA5-DF, E8-FF)
  *
  *
  * Other Keys(01xx)
@@ -70,13 +71,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 1001|oopp|BBBB BBBB   8-bit Bitwise Operation???
  *
  * ACT_LAYER_TAP(101x):
- * 101E|LLLL| keycode    On/Off with tap key    (0x00-DF)[TAP]
- * 101E|LLLL|1110 mods   On/Off with modifiers  (0xE0-EF)[NOT TAP]
+ * 101E|LLLL| keycode    On/Off with tap key    (0x04-A4, E0-E7)[TAP]
+ * 101E|LLLL|110r mods   On/Off with modifiers  (0xC0-DF)[NOT TAP]
+ *                       r: Left/Right flag(Left:0, Right:1)
+ *                       (reserved)             (0xA5-BF, E8-EF)
  * 101E|LLLL|1111 0000   Invert with tap toggle (0xF0)   [TAP]
  * 101E|LLLL|1111 0001   On/Off                 (0xF1)   [NOT TAP]
  * 101E|LLLL|1111 0010   Off/On                 (0xF2)   [NOT TAP]
  * 101E|LLLL|1111 0011   Set/Clear              (0xF3)   [NOT TAP]
- * 101E|LLLL|1111 xxxx   Reserved               (0xF4-FF)
+ * 101E|LLLL|1111 xxxx   (reserved)             (0xF4-FF)
  *   ELLLL: layer 0-31(E: extra bit for layer 16-31)
  *
  *
@@ -267,7 +270,7 @@ enum layer_pram_tap_op {
 #define ACTION_LAYER_ON_OFF(layer)                  ACTION_LAYER_TAP((layer), OP_ON_OFF)
 #define ACTION_LAYER_OFF_ON(layer)                  ACTION_LAYER_TAP((layer), OP_OFF_ON)
 #define ACTION_LAYER_SET_CLEAR(layer)               ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
-#define ACTION_LAYER_MODS(layer, mods)              ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f))
+#define ACTION_LAYER_MODS(layer, mods)              ACTION_LAYER_TAP((layer), 0xc0 | ((mods)&0x1f))
 /* With Tapping */
 #define ACTION_LAYER_TAP_KEY(layer, key)            ACTION_LAYER_TAP((layer), (key))
 #define ACTION_LAYER_TAP_TOGGLE(layer)              ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
index 87b72e059bc249a2e7d48f1a4154cc3955b80828..1321e763b728b28d48bea23585e838da098beeac 100644 (file)
@@ -569,7 +569,7 @@ This registers modifier key(s) simultaneously with layer switching.
 
     ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT)
 
-This function can only register left-sided modifiers. The handedness of the modifier (left/right) is an extra bit that is not able to be passed through into the layer system. See: [`common/action_code.h`](../common/action_code.h), the spec for ACT_LAYER_TAP only allows four bits for the mods, whereas the mods themselves require five bits, with the high bit being the left/right handedness.
+You can combine four modifiers at most but cannot use both left and right modifiers at a time, either left or right modiiers only can be allowed.
 
 
 ## 4. Tapping
Imprint / Impressum