forked from mirrors/qmk_firmware
fix compose bug
This commit is contained in:
parent
c22f25a597
commit
d7aeb6cc5d
11 changed files with 36291 additions and 36244 deletions
|
@ -11,7 +11,7 @@
|
|||
#define MATRIX_COLS 6
|
||||
#define DEBUG_MATRIX_SCAN_RATE
|
||||
|
||||
#define UNICODE_SELECTED_MODES UC_LNX, UC_MAC, UC_WINC
|
||||
#define UNICODE_SELECTED_MODES UNICODE_MODE_LINUX, UNICODE_MODE_MACOS, UNICODE_MODE_WINCOMPOSE, UNICODE_MODE_EMACS
|
||||
|
||||
#define OLED_DISPLAY_128X64
|
||||
|
||||
|
|
|
@ -10,118 +10,115 @@
|
|||
static int charsWritten, currentState;
|
||||
|
||||
static void resetState(void) {
|
||||
print("resetState()\n");
|
||||
charsWritten = 0;
|
||||
currentState = 0;
|
||||
print("resetState()\n");
|
||||
charsWritten = 0;
|
||||
currentState = 0;
|
||||
}
|
||||
|
||||
static void finishCompose(const char* result) {
|
||||
uprintf("Finishing compose with result: %s (%d chars written)\n", result, charsWritten);
|
||||
while(charsWritten) {
|
||||
tap_code(KC_BACKSPACE);
|
||||
charsWritten--;
|
||||
}
|
||||
send_unicode_string(result);
|
||||
resetState();
|
||||
static void finishCompose(const char *result) {
|
||||
uprintf("Finishing compose with result: %s (%d chars written)\n", result, charsWritten);
|
||||
while (charsWritten) {
|
||||
tap_code(KC_BACKSPACE);
|
||||
charsWritten--;
|
||||
}
|
||||
send_unicode_string(result);
|
||||
resetState();
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint16_t first_edge_idx;
|
||||
uint16_t edge_count;
|
||||
uint16_t first_edge_idx;
|
||||
uint16_t edge_count;
|
||||
} compose_node_t;
|
||||
|
||||
typedef struct {
|
||||
const char * value;
|
||||
uint16_t c;
|
||||
uint16_t next_node;
|
||||
const char *value;
|
||||
uint16_t c;
|
||||
uint16_t next_node;
|
||||
} compose_edge_t;
|
||||
|
||||
#include "composeTable.h"
|
||||
|
||||
static void checkComposeState(void) {
|
||||
print("checkComposeState()\n");
|
||||
if(currentState * sizeof(compose_node_t) > sizeof(nodes)) {
|
||||
finishCompose("[error in compose]");
|
||||
}
|
||||
print("checkComposeState()\n");
|
||||
if (currentState * sizeof(compose_node_t) > sizeof(nodes)) {
|
||||
finishCompose("[error in compose]");
|
||||
}
|
||||
}
|
||||
|
||||
static const compose_edge_t *findEdge(uint16_t keycode) {
|
||||
checkComposeState();
|
||||
uint32_t uc = keystroke_to_unicode(keycode);
|
||||
uprintf("Resolved keycode %d: %ld\n", keycode, uc);
|
||||
checkComposeState();
|
||||
uint32_t uc = keystroke_to_unicode(keycode);
|
||||
uprintf("Resolved keycode %d: %ld\n", keycode, uc);
|
||||
|
||||
uint16_t match1 = (uint16_t)uc; // yes only bmp support, keyboard doesn’t have any astral keycodes anyways
|
||||
uint16_t match2 = 0;
|
||||
if(keycode < 256) {
|
||||
match2 = 0xD800 + keycode;
|
||||
print("(low keycode)\n");
|
||||
} else if(keycode == KC_LEAD) {
|
||||
match2 = 0xD800;
|
||||
print("(leader key)\n");
|
||||
}
|
||||
|
||||
for(int i = nodes[currentState].first_edge_idx; i < nodes[currentState].first_edge_idx + nodes[currentState].edge_count; i++) {
|
||||
if(compose_edges[i].c == match1 || compose_edges[i].c == match2) {
|
||||
uprintf("found matching node: %d -> %d\n", currentState, i);
|
||||
return &compose_edges[i];
|
||||
uint16_t match1 = (uint16_t)uc; // yes only bmp support, keyboard doesn’t have any astral keycodes anyways
|
||||
uint16_t match2 = 0;
|
||||
if (keycode < 256) {
|
||||
match2 = 0xD800 + keycode;
|
||||
print("(low keycode)\n");
|
||||
} else if (keycode == QK_LEAD) {
|
||||
match2 = 0xD800;
|
||||
print("(leader key)\n");
|
||||
}
|
||||
}
|
||||
print("no matching edge found.\n");
|
||||
return NULL;
|
||||
|
||||
for (int i = nodes[currentState].first_edge_idx; i < nodes[currentState].first_edge_idx + nodes[currentState].edge_count; i++) {
|
||||
if (compose_edges[i].c == match1 || compose_edges[i].c == match2) {
|
||||
uprintf("found matching node: %d -> %d\n", currentState, i);
|
||||
return &compose_edges[i];
|
||||
}
|
||||
}
|
||||
print("no matching edge found.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// yes this breaks with emoji
|
||||
static size_t charcount_utf8(const char * s) {
|
||||
size_t n = 0;
|
||||
while(*s)
|
||||
if((*(s++) & 0xC0) != 0x80)
|
||||
n++; // only count non-continuation characters
|
||||
return n;
|
||||
static size_t charcount_utf8(const char *s) {
|
||||
size_t n = 0;
|
||||
while (*s)
|
||||
if ((*(s++) & 0xC0) != 0x80) n++; // only count non-continuation characters
|
||||
return n;
|
||||
}
|
||||
|
||||
static void transEdge(const compose_edge_t *edge) {
|
||||
uprintf("Transitioning to node %d\n", edge->next_node);
|
||||
if(edge->value) {
|
||||
uprintf("new node has value %s\n", edge->value);
|
||||
finishCompose(edge->value);
|
||||
if(edge->next_node != 0) // not necessarily the final product
|
||||
charsWritten = charcount_utf8(edge->value);
|
||||
}
|
||||
currentState = edge->next_node;
|
||||
checkComposeState();
|
||||
uprintf("Transitioning to node %d\n", edge->next_node);
|
||||
if (edge->value) {
|
||||
uprintf("new node has value %s\n", edge->value);
|
||||
finishCompose(edge->value);
|
||||
if (edge->next_node != 0) // not necessarily the final product
|
||||
charsWritten = charcount_utf8(edge->value);
|
||||
}
|
||||
currentState = edge->next_node;
|
||||
checkComposeState();
|
||||
}
|
||||
|
||||
static bool isCombining(uint32_t uc) {
|
||||
// yes it is not all of them, but all of them that matter for us
|
||||
if(uc >= 0x300 && uc < 0x370)
|
||||
return true;
|
||||
if(uc == 0x20d7)
|
||||
return true;
|
||||
return false;
|
||||
// yes it is not all of them, but all of them that matter for us
|
||||
if (uc >= 0x300 && uc < 0x370) return true;
|
||||
if (uc == 0x20d7) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void process_compose(uint16_t keycode, keyrecord_t *record) {
|
||||
if(!record->event.pressed)
|
||||
return;
|
||||
uint32_t uc = keystroke_to_unicode(keycode);
|
||||
const compose_edge_t * edge = findEdge(keycode);
|
||||
if(edge == NULL && uc != 0) { // no matching edge found, reset and try again
|
||||
print("No matching edge found, reset.\n");
|
||||
resetState();
|
||||
edge = findEdge(keycode);
|
||||
}
|
||||
if(edge == NULL) {
|
||||
print("No compose edge found.\n");
|
||||
return; // nothing found
|
||||
}
|
||||
// before we can advance the compose state, we need to prepare certain keys (dead keys, the leader key) because otherwise our deletion will delete too much (which of course is something we do not want)
|
||||
if(isCombining(uc)) {
|
||||
print("keycode refers to deadkey, writing space\n");
|
||||
tap_code(KC_SPACE);
|
||||
} else if(keycode == KC_LEAD) {
|
||||
print("keycode refers to leader key, writing compose symbol\n");
|
||||
send_unicode_string("♫");
|
||||
}
|
||||
charsWritten++;
|
||||
transEdge(edge);
|
||||
}
|
||||
if (!record->event.pressed) return;
|
||||
uint32_t uc = keystroke_to_unicode(keycode);
|
||||
const compose_edge_t *edge = findEdge(keycode);
|
||||
if (edge == NULL && uc != 0) { // no matching edge found, reset and try again
|
||||
uprintf("uc: %ld", uc);
|
||||
print("No matching edge found, reset.\n");
|
||||
resetState();
|
||||
edge = findEdge(keycode);
|
||||
}
|
||||
if (edge == NULL) {
|
||||
print("No compose edge found.\n");
|
||||
return; // nothing found
|
||||
}
|
||||
// before we can advance the compose state, we need to prepare certain keys (dead keys, the leader key) because otherwise our deletion will delete too much (which of course is something we do not want)
|
||||
if (isCombining(uc)) {
|
||||
print("keycode refers to deadkey, writing space\n");
|
||||
tap_code(KC_SPACE);
|
||||
} else if (keycode == QK_LEAD) {
|
||||
print("keycode refers to leader key, writing compose symbol\n");
|
||||
send_unicode_string("♫");
|
||||
}
|
||||
charsWritten++;
|
||||
transEdge(edge);
|
||||
}
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "action.h"
|
||||
void process_compose(uint16_t keycode, keyrecord_t *record);
|
||||
void process_compose(uint16_t keycode, keyrecord_t *record);
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -5,17 +5,7 @@
|
|||
#include "raw_hid.h"
|
||||
#include "neo2.h"
|
||||
#include "compose.h"
|
||||
enum {
|
||||
_MAIN,
|
||||
_NUMPAD,
|
||||
_PLOVER,
|
||||
_MOUSE,
|
||||
_GAMING,
|
||||
_SYS,
|
||||
_NAV,
|
||||
_FN,
|
||||
_EMPTY
|
||||
};
|
||||
enum { _MAIN, _NUMPAD, _PLOVER, _MOUSE, _GAMING, _SYS, _NAV, _FN, _EMPTY };
|
||||
|
||||
#define LAYOUT(k0A, k0B, k0C, k0D, k0E, k0F, k5A, k5B, k5C, k5D, k5E, k5F, k1A, k1B, k1C, k1D, k1E, k1F, k6A, k6B, k6C, k6D, k6E, k6F, k2A, k2B, k2C, k2D, k2E, k2F, k7A, k7B, k7C, k7D, k7E, k7F, k3A, k3B, k3C, k3D, k3E, k3F, k8A, k8B, k8C, k8D, k8E, k8F, k4C, k4D, k4E, k4F, k9C, k9D, k9E, k9F) LAYOUT_ortho_4x6_2x2uc(k0A, k0B, k0C, k0D, k0E, k0F, k1A, k1B, k1C, k1D, k1E, k1F, k2A, k2B, k2C, k2D, k2E, k2F, k3A, k3B, k3C, k3D, k3E, k3F, k4C, k4D, k4E, k4F, k5A, k5B, k5C, k5D, k5E, k5F, k6A, k6B, k6C, k6D, k6E, k6F, k7A, k7B, k7C, k7D, k7E, k7F, k8A, k8B, k8C, k8D, k8E, k8F, k9C, k9D, k9E, k9F)
|
||||
#define STN_PLS STN_NB
|
||||
|
@ -27,8 +17,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||
[_MAIN] = LAYOUT(
|
||||
KC_ESC , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_LBRC,
|
||||
KC_TAB , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN , KC_QUOT,
|
||||
KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_LEAD,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_NUBS , TT(_FN), _______, KC_LOCK, TG(_PLOVER), KC_RALT , KC_RGUI, KC_APP , KC_RCTL,
|
||||
KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , QK_LEAD,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_NUBS , TT(_FN), _______, QK_LOCK, TG(_PLOVER), KC_RALT , KC_RGUI, KC_APP , KC_RCTL,
|
||||
KC_CAPS, TT(_GAMING), KC_SPC , KC_LSFT, TT(_MOUSE), TT(_NUMPAD), TT(_NAV), TT(_SYS)
|
||||
),
|
||||
[_NUMPAD] = LAYOUT(
|
||||
|
@ -166,7 +156,7 @@ void register_unicode(uint32_t codepoint) {
|
|||
buffer[1] = 0x80 | (uint8_t)(codepoint & 0x3F);
|
||||
codepoint >>= 6;
|
||||
buffer[0] = 0xC0 | (uint8_t)(codepoint);
|
||||
size = 2;
|
||||
size = 2;
|
||||
} else if(codepoint < 0x10000) {
|
||||
buffer[2] = 0x80 | (uint8_t)(codepoint & 0x3F);
|
||||
codepoint >>= 6;
|
||||
|
|
|
@ -247,4 +247,4 @@ for edge in edges:
|
|||
if "next_node" in edge:
|
||||
print(f" .next_node = {edge['next_node']},")
|
||||
print(" },")
|
||||
print("};")
|
||||
print("};")
|
||||
|
|
|
@ -57,7 +57,7 @@ bool caps_word_press_user(uint16_t keycode) {
|
|||
// Keycodes that continue Caps Word, with shift applied.
|
||||
case KC_A ... KC_Z:
|
||||
case KC_MINS:
|
||||
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
|
||||
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
|
||||
return true;
|
||||
|
||||
// Keycodes that continue Caps Word, without shifting.
|
||||
|
@ -74,6 +74,6 @@ bool caps_word_press_user(uint16_t keycode) {
|
|||
return true;
|
||||
|
||||
default:
|
||||
return getLayer() != 3; // Deactivate Caps Word.
|
||||
return getLayer() != 3; // Deactivate Caps Word.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
#include "quantum/action.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void track_neo2_modifier_state(uint16_t keycode, keyrecord_t *record);
|
||||
void track_neo2_modifier_state(uint16_t keycode, keyrecord_t *record);
|
||||
uint32_t keystroke_to_unicode(uint16_t keycode);
|
||||
|
|
|
@ -1 +1 @@
|
|||
SRC += neo2.c compose.c
|
||||
SRC += neo2.c compose.c
|
||||
|
|
|
@ -79,4 +79,4 @@ struct SparseTable<T, 0, entryBits> {
|
|||
const T *operator[](size_t index) const {
|
||||
return &value;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue