-
-
Notifications
You must be signed in to change notification settings - Fork 40.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
{HOWTO} Can I set a double tap on semicolon ; to send a colon : #127
Comments
Solved by @Eric-L-T in this gist: case 0:
if (record->event.pressed) {
if (record->tap.count <= 1) {
register_code(KC_SCLN);
} else if (record->tap.count = 2) {
register_code(KC_LSFT);
register_code(KC_SCLN);
unregister_code(KC_SCLN);
unregister_code(KC_LSFT);
record->tap.count = 0;
}
} else if (record->tap.count <= 1) {
unregister_code(KC_SCLN);
record->tap.count = 0;
}
break; Thanks!!! |
Actually it did not work, that was Karabiner on my machine that made it "work" - reopening. The I have set the 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:
/* ... */
break;
case 1:
print("macro pressed \n");
if (record->event.pressed) {
print("taps: ");
pdec(record->tap.count);
print("\n");
if (record->tap.count == 1) {
register_code(KC_SCLN);
} else if (record->tap.count == 2) {
register_code(KC_COLN);
}
} else {
if (record->tap.count == 1) {
unregister_code(KC_SCLN);
} else if (record->tap.count == 2) {
unregister_code(KC_COLN);
}
}
break;
}
return MACRO_NONE;
}; I am getting back:
Any ideas what I'm doing wrong? @jackhumbert / @ezuk ? |
I'm not sure how tap.count is implemented, but this might be easier with a timer and a initialiser variable. The timer would be necessary to make sure the semicolon isn't sent every time. Also, |
As Jack said this will never work as first tap of your double tap will be identified as tap.count==1 |
Oh and you need the timer interrupt in loop to check for single tap timeout on fast single tap when no second tap is done but I'm not sure it will allow to register well when taping other keys then, the following code kinda works but do not register fast single tap (note that it handles layer momentary switch on hold as well) : void action_mods_tap_layer_tmp(keyrecord_t *record, uint8_t layer, uint8_t mod_tap, uint8_t key_tap, uint8_t two_tap)
{
timer_init(); // needed to take prescaler value into account
static uint32_t start;
static uint32_t epress;
static uint32_t dpress;
if (record->event.pressed) {
start = timer_read32();
if (record->tap.count > 0) {
if (record->tap.interrupted) {
record->tap.count = 0; // ad hoc: cancel tap
layer_on(layer);
debug("interrupted layer on\n");
} else {
epress = timer_elapsed(start);
dprintf("epress:(%u)\n",epress);
}
} else {
layer_on(layer);
debug("layer on\n");
}
} else {
if (record->tap.count > 0) {
dpress = timer_elapsed32(start);
dprintf("dpress:(%u)\n",dpress);
if (record->tap.count >= 2) {
register_code(two_tap);
debug("two taps\n");
unregister_code(two_tap);
record->tap.count = 0; // ad hoc: cancel tap
} else {
if (epress - dpress > 0) {
debug("one tap\n");
dprintf("elapsed:(%u)\n",timer_elapsed32(start));
if (mod_tap > 0) {
add_weak_mods(MOD_BIT(mod_tap));
send_keyboard_report();
}
register_code(key_tap);
if (mod_tap > 0) {
del_weak_mods(MOD_BIT(mod_tap));
send_keyboard_report();
}
unregister_code(key_tap);
record->tap.count = 0; // ad hoc: cancel tap
}
}
} else {
layer_off(layer);
}
}
} |
The timer approach was the correct one, it worked out great! thank you all for helping out!!! Here's the my solution: static uint16_t key_timer;
static uint16_t semi_colon_taps = 0;
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:
/* ... */
break;
case 1:
if (record->event.pressed) {
// key pressed -> immidiately send ;, start timer
// count time elapsed since last key pressed
// if bigger than 200ms -> reset timer
// if smaller than 200ms -> send backspace and :, reset timer
if (!key_timer || timer_elapsed(key_timer) > 200) {
semi_colon_taps = 1;
} else {
semi_colon_taps += 1;
}
key_timer = timer_read();
if (semi_colon_taps == 1) {
register_code(KC_SCLN);
} else {
// delete semicolon
register_code(KC_BSPC);
unregister_code(KC_BSPC);
// insert colon
register_code(KC_LSFT);
register_code(KC_SCLN);
unregister_code(KC_SCLN);
unregister_code(KC_LSFT);
}
} else {
unregister_code(KC_SCLN);
}
break;
}
return MACRO_NONE;
}; I also implemented sticky shift using a similar idea, if you are interested: |
Just wondering, do you have a layout in keymaps/ that uses this? Would love On 7 February 2016 at 20:03, Dorian Karter [email protected] wrote:
|
Problem with that solution (which is how Karabiner handles single tap noise by adding a backspace output) is that you can't use keys for inputing sequences in software ie if software is waiting for 3-d and you send 3-x-backspace-d, it won't make it. |
Move `LAYOUT` options back into seperate variants
I want to be able to double tap the semicolon button and send a colon but have it behave normally when I press it once, is that possible? What would be the easiest way to do that?
Single press -> semicolon
Double tap -> colon
Shift + Single press -> colon
I'm currently doing that with Karabiner on Mac but would like to have it programmed into the keyboard so that I can take it with me.
The text was updated successfully, but these errors were encountered: