]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/xd60/keymaps/Jos/keymap.c
1c530ed9ae3d26d9bfb7a88809fcc66a8e050aaa
[qmk_firmware.git] / keyboards / xd60 / keymaps / Jos / keymap.c
1 #include "xd60.h"
2 #include "action_layer.h"
3
4 // TODO: THOSE ARE IDEAS:
5 // TODO:
6 // TODO: - Proper support for "GUI+TAB" application switching, with the GUI holding and shift, etc.
7 // TODO:     - Maybe implement a process_record instead of a tap-dance, or complex tap dance?
8 // TODO: - Media keys on Fn1 layer, *hjklm,.* or arrow cluster?
9 // TODO: - What more than NumPad + RGB on the Fn3 toggled layer?
10 // TODO: - Add an in-keymap way to toggle LGUI/F(0) key, HELD_ESC_IS_SHIFT and BSPC_BLOCKS_DEL.
11 // TODO:
12 // TODO: THOSE ARE BUGS TO FIX:
13 // TODO: - None (found so far)
14
15 // Adjusting process_record_user functionnalities, comment to disable.
16 #define ISOLIKE_ALT_ENTER
17 #define TWO_SFT_CAPS
18 #define APP_IS_RALT_RCTRL
19 #define HELD_ESC_IS_SHIFT
20 #define BSPC_BLOCKS_DEL
21 #define ALT_MINSEQL_IS_ALT_78
22
23 // Cases where the GUI key will actually do what the GUI key normally does.
24 #define AC_G_W    LGUI(KC_W)   // Ubuntu: Shows windows on current desktop
25 #define AC_G_S    LGUI(KC_S)   // Ubuntu: Overview of all desktops
26 #define AC_G_D    LGUI(KC_D)   // Windows: Show/Toggle desktop
27 #define AC_G_L    LGUI(KC_L)   // Ubuntu/Windows: Lock session
28 #define AC_G_T    LGUI(KC_T)   // Ubuntu: Shows Trash // elementary: Opens terminal
29 #define AC_G_E    LGUI(KC_E)   // Windows: Opens file explorer
30 #define AC_G_H    LGUI(KC_H)   // Windows: Show/Hide hidden files
31 #define AC_G_SPC  LGUI(KC_SPC) // elementary: Shows application launcher
32
33
34 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
35
36   // 0: Base Layer
37   KEYMAP(
38       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,    \
39       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,   \
40       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,    \
41       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),      \
42       KC_LCTL,  TD(0),   KC_LALT,                            KC_SPC ,                             KC_RALT,  KC_RCTRL,  KC_LEFT,  KC_DOWN,   KC_RIGHT),
43                                                                                                                                            
44   // 1: Function 1 Layers                                                                                                                  
45   KEYMAP(                                                                                                                                  
46       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,    \
47       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,    \
48       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,    \
49       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,    \
50       KC_TRNS, KC_TRNS, KC_TRNS,                            KC_TRNS,                             KC_TRNS,  KC_TRNS,   KC_HOME,  KC_PGDOWN, KC_END),
51                                                                                                                                            
52   // 2: GUI/Function 2 Layer                                                                                                                   
53   KEYMAP(                                                                                                                                  
54       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,   \
55       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,   \
56       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,   \
57       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,   \
58       KC_TRNS, KC_TRNS, KC_TRNS,                            AC_G_SPC,                            KC_TRNS,  KC_TRNS,   KC_HOME,  KC_PGDOWN,  KC_END),
59                                                                                                                                            
60   // 3: NumPad/Function 3 Toggle Layer                                                                                                                   
61   KEYMAP(                                                                                                                                  
62       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,   \
63       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,     \
64       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,   \
65       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,   \
66       KC_NO,   KC_TRNS, KC_NO,                              KC_TRNS,                             KC_PENT,  KC_PENT,   KC_TRNS,  KC_TRNS,    KC_TRNS)  ,
67
68 // TRaNSparent layer for reference
69 /*  KEYMAP(                                                                                                                                  
70       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,   \
71       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,   \
72       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,   \
73       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,   \
74 /      KC_TRNS, KC_TRNS, KC_TRNS,                            KC_TRNS,                             KC_TRNS,  KC_TRNS,   KC_TRNS,  KC_TRNS,    KC_TRNS), */
75 };
76
77 // Custom Actions
78 const uint16_t PROGMEM fn_actions[] = {
79     [0] = ACTION_LAYER_MOMENTARY(1),  // to Fn1 layer
80     [1] = ACTION_LAYER_MOMENTARY(2),  // to GUI/Fn2 layer
81     [2] = ACTION_LAYER_TOGGLE(3),     // to Fn3/Num toggle layer
82 };
83
84 // Macros
85 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
86
87   // MACRODOWN only works in this function
88   switch(id) {
89     case 0:
90       if (record->event.pressed) { register_code(KC_RSFT); }
91       else { unregister_code(KC_RSFT); }
92       break;
93   }
94
95   return MACRO_NONE;
96 };
97
98
99 // Loop
100 void matrix_scan_user(void) {
101   // Empty
102 };
103
104 // LGUI acts as F(1) if held or as a tapped LGUI if tapped. Adapted from https://goo.gl/WnqGNS
105 // Commented lines are for the "sticky" layer on two presses. Left it here for reference.
106 static const int GUILAY = 2; // GUI Layer is layer #2
107
108 typedef struct {
109   bool layer_toggle;
110   bool sticky;
111 } td_ta_state_t;
112
113 static void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) {
114   td_ta_state_t *td_ta = (td_ta_state_t *) user_data;
115
116 //  if (td_ta->sticky) {
117 //    td_ta->sticky = false;
118 //    td_ta->layer_toggle = false;
119 //    layer_off (GUILAY);
120 //    return;
121 //  }
122 //
123   if (state->count == 1 && !state->pressed) {
124     register_code (KC_LGUI);
125 //    td_ta->sticky = false;
126     td_ta->layer_toggle = false;
127   } else {
128     td_ta->layer_toggle = true;
129     layer_on(GUILAY);
130 //    td_ta->sticky = (state->count == 2);
131   }
132 }
133
134 // Added this one to make it more reactive on keyup
135 static void ang_tap_dance_ta_each (qk_tap_dance_state_t *state, void *user_data) {
136   td_ta_state_t *td_ta = (td_ta_state_t *) user_data;
137
138   if (!td_ta->layer_toggle) {   // Braces added for clarity
139     unregister_code (KC_LGUI);
140   }
141 }
142
143
144 static void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) {
145   td_ta_state_t *td_ta = (td_ta_state_t *) user_data;
146
147   if (!td_ta->layer_toggle) {   // Braces added for clarity
148     unregister_code (KC_LGUI);
149   }
150 //  if (!td_ta->sticky)
151     layer_off (GUILAY); // We don't verify it was swithed on, switching off regardless
152 }
153
154
155 qk_tap_dance_action_t tap_dance_actions[] = {
156    [0]  = {
157      .fn = { ang_tap_dance_ta_each, ang_tap_dance_ta_finished, ang_tap_dance_ta_reset },
158      .user_data = (void *)&((td_ta_state_t) { false, false })
159    }
160 };
161
162 #if defined ISOLIKE_ALT_ENTER  || defined TWO_SFT_CAPS  || defined APP_IS_RALT_RCTRL || defined ALT_MINSEQL_IS_ALT_78
163 // Function for the special modifiers actions below, makes it cleaner and yields smaller firmware.
164 static bool special_mods(uint16_t keycode, keyrecord_t *record, uint16_t modifier) {
165   if (record->event.pressed && (keyboard_report->mods & MOD_BIT(modifier))) {
166     register_code(keycode);
167     return false;
168   } else {
169     unregister_code(keycode);
170     return true;
171   }
172 }
173 #endif
174
175 #ifdef BSPC_BLOCKS_DEL
176 static bool del_blocked = false; // Static as to not be defined elsewhere
177 #endif
178
179 // This function is processed before the key events on each key press/release.
180 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
181   switch (keycode){
182     #ifdef ISOLIKE_ALT_ENTER
183     // RALT + ENT is the same as RALT+BSLS. 
184     // For logical placement of *{* and *}* (the former being RALT+BSLS) with ANSI enter on 
185     // ISO-based Canadian Multilingual layout (or any other ISO layout on ANSI keyboards).
186     case KC_ENT:    return special_mods(KC_BSLS, record, KC_RALT);  // RALT + ENT -> RALT + BSLS            // See comment above
187     #endif
188     #ifdef TWO_SFT_CAPS
189     case KC_LSFT:   return special_mods(KC_CAPS, record, KC_RSFT);  // Both shifts together -> Caps Lock    // RSFT  pressed first case
190     case KC_RSFT:   return special_mods(KC_CAPS, record, KC_LSFT);  // Both shifts together -> Caps Lock    // LSFT  pressed first case
191     #endif
192     #ifdef APP_IS_RALT_RCTRL
193     case KC_RCTRL:  return special_mods(KC_APP,  record, KC_RALT);  // RALT + RCTRL -> APP                  // RCTRL pressed first case
194     case KC_RALT:   return special_mods(KC_APP,  record, KC_RCTRL); // RALT + RCTRL -> APP                  // RALT  pressed first case
195     #endif
196     #ifdef ALT_MINSEQL_IS_ALT_78
197     case KC_MINS:  return special_mods(KC_7,  record, KC_RALT); // RALT + MINS -> RALT+7                  // {} in CAN Mult. softawre layout
198     case KC_EQL:   return special_mods(KC_8,  record, KC_RALT); // RALT + EQL  -> RALT+8                  // ½¬ normally... Less finger stretch.
199     #endif
200     #ifdef HELD_ESC_IS_SHIFT
201     case KC_ESC:    // Physically *ESC* is *CAPS*                   // Holding ESC -> SHIFT  (0 delay)      // Less awkward *<ESC>:wq* in vim
202       if (record->event.pressed) {
203         register_code(KC_ESC);      // Tapping ESC
204         unregister_code(KC_ESC);
205         register_code(KC_LSFT);     // Holding LSFT
206         return false;
207       } else {
208         unregister_code(KC_LSFT);   // Releasing LSFT
209         return false;
210       }
211     #endif
212     #ifdef BSPC_BLOCKS_DEL
213     // If BSPC is held, we flag DEL as disabled. To avoids acidental presses of DEL with split backspace key.
214     case KC_BSPC:
215       del_blocked = record->event.pressed;
216       return true;
217     // We don't handle DEL if it is pressed and flagged as disabled
218     case KC_DEL:
219       if (del_blocked && record->event.pressed) {
220         return false;
221       } else {
222         return true;
223       }
224     #endif
225     default: return true;   // Let QMK handle the rest as usual
226   }
227 }
228
229