summaryrefslogtreecommitdiffstats
path: root/keyboards/xd60/keymaps/Jos/keymap.c
blob: 87dbad159a53ef964667570af192aa0afb9e5809 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#include QMK_KEYBOARD_H
#include "action_layer.h"

// TODO: THOSE ARE IDEAS:
// TODO:
// TODO: - Proper support for "GUI+TAB" application switching, with the GUI holding and shift, etc.
// TODO:     - Maybe implement a process_record instead of a tap-dance, or complex tap dance?
// TODO: - Media keys on Fn1 layer, *hjklm,.* or arrow cluster?
// TODO: - What more than NumPad + RGB on the Fn3 toggled layer?
// TODO: - Add an in-keymap way to toggle LGUI/F(0) key, HELD_ESC_IS_SHIFT and BSPC_BLOCKS_DEL.
// TODO:
// TODO: THOSE ARE BUGS TO FIX:
// TODO: - None (found so far)

// Adjusting process_record_user functionnalities, comment to disable.
#define ISOLIKE_ALT_ENTER
#define TWO_SFT_CAPS
#define APP_IS_RALT_RCTRL
#define HELD_ESC_IS_SHIFT
#define BSPC_BLOCKS_DEL
#define ALT_MINSEQL_IS_ALT_78

// Cases where the GUI key will actually do what the GUI key normally does.
#define AC_G_W    LGUI(KC_W)   // Ubuntu: Shows windows on current desktop
#define AC_G_S    LGUI(KC_S)   // Ubuntu: Overview of all desktops
#define AC_G_D    LGUI(KC_D)   // Windows: Show/Toggle desktop
#define AC_G_L    LGUI(KC_L)   // Ubuntu/Windows: Lock session
#define AC_G_T    LGUI(KC_T)   // Ubuntu: Shows Trash // elementary: Opens terminal
#define AC_G_E    LGUI(KC_E)   // Windows: Opens file explorer
#define AC_G_H    LGUI(KC_H)   // Windows: Show/Hide hidden files
#define AC_G_SPC  LGUI(KC_SPC) // elementary: Shows application launcher


const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

  // 0: Base Layer
  LAYOUT_all(
      KC_GRAVE, KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,     KC_0,     KC_MINS,   KC_EQL,   KC_BSPC,   KC_DEL,    \
      KC_TAB,   KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,     KC_P,     KC_LBRC,   KC_RBRC,             KC_BSLS,   \
      KC_ESC,   KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,     KC_SCLN,  KC_QUOT,   KC_NO,               KC_ENT,    \
      KC_LSFT,  KC_LGUI, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM,  KC_DOT,   KC_SLSH,   KC_RSFT,  KC_UP,     F(0),      \
      KC_LCTL,  TD(0),   KC_LALT,                            KC_SPC ,                             KC_RALT,  KC_RCTRL,  KC_LEFT,  KC_DOWN,   KC_RIGHT),
                                                                                                                                           
  // 1: Function 1 Layers                                                                                                                  
  LAYOUT_all(                                                                                                                                  
      RESET,   KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,    KC_F10,   KC_F11,    KC_F12,   KC_PAUS,   KC_PSCR,    \
      KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_TRNS,             KC_TRNS,    \
      KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MPRV, KC_MNXT,  KC_MSTP,  KC_TRNS,   KC_NO,               KC_TRNS,    \
      KC_TRNS, F(2),    KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MUTE, KC_VOLD,  KC_VOLU,  KC_TRNS,   KC_TRNS,  KC_PGUP,   KC_TRNS,    \
      KC_TRNS, KC_TRNS, KC_TRNS,                            KC_TRNS,                             KC_TRNS,  KC_TRNS,   KC_HOME,  KC_PGDOWN, KC_END),
                                                                                                                                           
  // 2: GUI/Function 2 Layer                                                                                                                   
  LAYOUT_all(                                                                                                                                  
      KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,    KC_F10,   KC_F11,    KC_F12,   KC_PAUS,    KC_PSCR,   \
      KC_TRNS, KC_TRNS, AC_G_W,  AC_G_E,  KC_TRNS, AC_G_T,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_TRNS,              KC_TRNS,   \
      KC_TRNS, KC_TRNS, AC_G_S,  AC_G_D,  KC_TRNS, KC_TRNS, AC_G_H,  KC_TRNS, KC_TRNS, AC_G_L,   KC_TRNS,  KC_TRNS,   KC_NO,                KC_TRNS,   \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_TRNS,  KC_PGUP,    KC_TRNS,   \
      KC_TRNS, KC_TRNS, KC_TRNS,                            AC_G_SPC,                            KC_TRNS,  KC_TRNS,   KC_HOME,  KC_PGDOWN,  KC_END),
                                                                                                                                           
  // 3: NumPad/Function 3 Toggle Layer                                                                                                                   
  LAYOUT_all(                                                                                                                                  
      KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_7,    KC_8,    KC_9,     KC_PSLS,  KC_PMNS,   KC_PPLS,  KC_TRNS,    KC_TRNS,   \
      KC_TRNS, KC_NO,   KC_NO,   RGB_HUI, RGB_SAI, RGB_VAI, KC_NO,   KC_4,    KC_5,    KC_6,     KC_PAST,  KC_NO,     KC_NO,                KC_NO,     \
      KC_TRNS, KC_NO,   KC_NO,   RGB_HUD, RGB_SAD, RGB_VAD, KC_NO,   KC_1,    KC_2,    KC_3,     KC_PMNS,  KC_PENT,   KC_NO,                KC_TRNS,   \
      KC_NO,   KC_TRNS, KC_NO,   KC_NO,   RGB_TOG, RGB_MOD, KC_NO,   KC_NO,   KC_0,    KC_COMM,  KC_DOT,   KC_PPLS,   KC_NO,    KC_TRNS,    KC_TRNS,   \
      KC_NO,   KC_TRNS, KC_NO,                              KC_TRNS,                             KC_PENT,  KC_PENT,   KC_TRNS,  KC_TRNS,    KC_TRNS)  ,

// TRaNSparent layer for reference
/*  LAYOUT_all(                                                                                                                                  
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_TRNS,  KC_TRNS,    KC_TRNS,   \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_TRNS,              KC_TRNS,   \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_NO,                KC_TRNS,   \
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,   KC_TRNS,  KC_TRNS,    KC_TRNS,   \
/      KC_TRNS, KC_TRNS, KC_TRNS,                            KC_TRNS,                             KC_TRNS,  KC_TRNS,   KC_TRNS,  KC_TRNS,    KC_TRNS), */
};

// Custom Actions
const uint16_t PROGMEM fn_actions[] = {
    [0] = ACTION_LAYER_MOMENTARY(1),  // to Fn1 layer
    [1] = ACTION_LAYER_MOMENTARY(2),  // to GUI/Fn2 layer
    [2] = ACTION_LAYER_TOGGLE(3),     // to Fn3/Num toggle layer
};

// Macros
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {

  // MACRODOWN only works in this function
  switch(id) {
    case 0:
      if (record->event.pressed) { register_code(KC_RSFT); }
      else { unregister_code(KC_RSFT); }
      break;
  }

  return MACRO_NONE;
};


// Loop
void matrix_scan_user(void) {
  // Empty
};

// LGUI acts as F(1) if held or as a tapped LGUI if tapped. Adapted from https://goo.gl/WnqGNS
// Commented lines are for the "sticky" layer on two presses. Left it here for reference.
static const int GUILAY = 2; // GUI Layer is layer #2

typedef struct {
  bool layer_toggle;
  bool sticky;
} td_ta_state_t;

static void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) {
  td_ta_state_t *td_ta = (td_ta_state_t *) user_data;

//  if (td_ta->sticky) {
//    td_ta->sticky = false;
//    td_ta->layer_toggle = false;
//    layer_off (GUILAY);
//    return;
//  }
//
  if (state->count == 1 && !state->pressed) {
    register_code (KC_LGUI);
//    td_ta->sticky = false;
    td_ta->layer_toggle = false;
  } else {
    td_ta->layer_toggle = true;
    layer_on(GUILAY);
//    td_ta->sticky = (state->count == 2);
  }
}

// Added this one to make it more reactive on keyup
static void ang_tap_dance_ta_each (qk_tap_dance_state_t *state, void *user_data) {
  td_ta_state_t *td_ta = (td_ta_state_t *) user_data;

  if (!td_ta->layer_toggle) {   // Braces added for clarity
    unregister_code (KC_LGUI);
  }
}


static void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) {
  td_ta_state_t *td_ta = (td_ta_state_t *) user_data;

  if (!td_ta->layer_toggle) {   // Braces added for clarity
    unregister_code (KC_LGUI);
  }
//  if (!td_ta->sticky)
    layer_off (GUILAY); // We don't verify it was swithed on, switching off regardless
}


qk_tap_dance_action_t tap_dance_actions[] = {
   [0]  = {
     .fn = { ang_tap_dance_ta_each, ang_tap_dance_ta_finished, ang_tap_dance_ta_reset },
     .user_data = (void *)&((td_ta_state_t) { false, false })
   }
};

#if defined ISOLIKE_ALT_ENTER  || defined TWO_SFT_CAPS  || defined APP_IS_RALT_RCTRL || defined ALT_MINSEQL_IS_ALT_78
// Function for the special modifiers actions below, makes it cleaner and yields smaller firmware.
static bool special_mods(uint16_t keycode, keyrecord_t *record, uint16_t modifier) {
  if (record->event.pressed && (keyboard_report->mods & MOD_BIT(modifier))) {
    register_code(keycode);
    return false;
  } else {
    unregister_code(keycode);
    return true;
  }
}
#endif

#ifdef BSPC_BLOCKS_DEL
static bool del_blocked = false; // Static as to not be defined elsewhere
#endif

// This function is processed before the key events on each key press/release.
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode){
    #ifdef ISOLIKE_ALT_ENTER
    // RALT + ENT is the same as RALT+BSLS. 
    // For logical placement of *{* and *}* (the former being RALT+BSLS) with ANSI enter on 
    // ISO-based Canadian Multilingual layout (or any other ISO layout on ANSI keyboards).
    case KC_ENT:    return special_mods(KC_BSLS, record, KC_RALT);  // RALT + ENT -> RALT + BSLS            // See comment above
    #endif
    #ifdef TWO_SFT_CAPS
    case KC_LSFT:   return special_mods(KC_CAPS, record, KC_RSFT);  // Both shifts together -> Caps Lock    // RSFT  pressed first case
    case KC_RSFT:   return special_mods(KC_CAPS, record, KC_LSFT);  // Both shifts together -> Caps Lock    // LSFT  pressed first case
    #endif
    #ifdef APP_IS_RALT_RCTRL
    case KC_RCTRL:  return special_mods(KC_APP,  record, KC_RALT);  // RALT + RCTRL -> APP                  // RCTRL pressed first case
    case KC_RALT:   return special_mods(KC_APP,  record, KC_RCTRL); // RALT + RCTRL -> APP                  // RALT  pressed first case
    #endif
    #ifdef ALT_MINSEQL_IS_ALT_78
    case KC_MINS:  return special_mods(KC_7,  record, KC_RALT); // RALT + MINS -> RALT+7                  // {} in CAN Mult. softawre layout
    case KC_EQL:   return special_mods(KC_8,  record, KC_RALT); // RALT + EQL  -> RALT+8                  // ½¬ normally... Less finger stretch.
    #endif
    #ifdef HELD_ESC_IS_SHIFT
    case KC_ESC:    // Physically *ESC* is *CAPS*                   // Holding ESC -> SHIFT  (0 delay)      // Less awkward *<ESC>:wq* in vim
      if (record->event.pressed) {
        register_code(KC_ESC);      // Tapping ESC
        unregister_code(KC_ESC);
        register_code(KC_LSFT);     // Holding LSFT
        return false;
      } else {
        unregister_code(KC_LSFT);   // Releasing LSFT
        return false;
      }
    #endif
    #ifdef BSPC_BLOCKS_DEL
    // If BSPC is held, we flag DEL as disabled. To avoids acidental presses of DEL with split backspace key.
    case KC_BSPC:
      del_blocked = record->event.pressed;
      return true;
    // We don't handle DEL if it is pressed and flagged as disabled
    case KC_DEL:
      if (del_blocked && record->event.pressed) {
        return false;
      } else {
        return true;
      }
    #endif
    default: return true;   // Let QMK handle the rest as usual
  }
}