Skip to content

Advanced usage: Custom Defined Behaviors

The current version of Glove80 Layout Editor does not support every ZMK feature directly. Missing features include combo, macros, hold-tap and tap-dance.

However these functions can still be supported via Glove80 Layout Editor’s Custom Defined Behavior feature.

This is an advanced feature that allows a layout designer to inject text into the keymap DTSI file. It is very powerful and also requires a good understanding of the ZMK DTSI keymap file.

Custom Defined Behaviors

The layout has a section named Custom Defined Behaviors. This is where you define the text to inject into the keymap DTSI file to define new behaviors such as macros, combos, hold-tap and tap-dance.

Custom defined behaviors

Custom defined behaviors

For example, you could try the following text to define a macro named &glove80_macro. This macro will “type” glove80.

    /* Macro to emit glove80 */
    macros {
        glove80_macro: glove80_macro {
            label = "glove80_macro";
            compatible = "zmk,behavior-macro";
            #binding-cells = <0>;
            wait-ms = <40>;
            tap-ms = <40>;
            bindings
            = <&kp G &kp L &kp O &kp V &kp E>
            , <&kp N8 &kp N0>
            ;
        };
    };

In general, if your Custom Defined Behaviors refer to a layer, the layer number should not be hardcoded as a value. If layers are re-ordered, the hardcoded layer numbers will be wrong. It is better to use the symbol reference. See Reference to layers for details.

Key binding for Custom Defined Behavior

To bind a key to a Custom Defined Behavior you have defined:

  1. Click on the top left of the key to select the behavior
  2. Choose Custom

Custom pseudo-behavior

Selecting Custom pseudo-behavior
  1. Then in the parameter type the actual binding. For example, if you want to bind to a macro named &glove80_macro, then type the binding as “&glove80_macro”.

Custom behavior binding

Defining custom behavior binding

Reference to layers

The exported ZMK keymap automatically generate C #define statement to define each layer. This allows the code in your Custom Defined Behavior to refer to layers symbolically.

For example:

The factory default layout has 4 layers defined

4 layers of the factory default layout

4 layers of the factory default layout

The automatically generated keymap has the following #define:

/* Automatically generated layer name #define */
#define LAYER_Base 0
#define LAYER_Lower 1
#define LAYER_Magic 2
#define LAYER_Factory 3

An example custom behaviour code snippet that uses the generated layer #define

/* A modified &lower function that switches to the layer with the name Lower rather than layer 1 */
    behaviors {
        realLower: realLower {
            compatible = "zmk,behavior-tap-dance";
            label = "LAYER_TAP_DANCE";
            #binding-cells = <0>;
            tapping-term-ms = <200>;
            bindings = <&mo LAYER_Lower>, <&to LAYER_Lower>;
        };
    };

Key positions

Certain ZMK features such as Combo (https://zmk.dev/docs/features/combos) and Hold-Tap identify the keys using their key positions.

Key positions

Key positions

You can also use the pre-defined #define in the Custom Defined Behaviors to refer to key positions. This is the recommended approach. The macro names are in the format of POS_&lt;LH|RH>_&lt;position>, such as:

#define POS_LH_T1 52

#define POS_LH_T6 71
#define POS_LH_C1R2 15

#define POS_LH_C1R5 51
#define POS_LH_C2R1 4

#define POS_LH_C2R6 68

#define POS_RH_T1 57

#define POS_RH_T6 72
#define POS_RH_C1R2 16

#define POS_RH_C1R5 58
#define POS_RH_C2R1 5