AndrewCrewKuznetsov/xneur-devel

Клавиша "б"/запятая неправильно переводится - порча в методе _keymap->convert_text_to_ascii

Opened this issue · 1 comments

Ввод русских слов, которые включают в себя буквы, расположенные на клавишах со знаками препинания в английской раскладке, заменяет эти знаки препинания на другие знаки. В частности можно заметить, что знак "запятая" в латинской раскладке, соответствующей букве "б" в русской, заменяется на знак "вопрос", который в латинской раскладке расположен на той же клавише, что и знак "запятая" в русской.

 Ожидалось: будет добавлен
   Набрано: ,eltn lj,fdkty
Исправлено: ?удет до?авлен

В таблице ниже для наглядности показана связь. Каждая строка соответствует одной клавише, в колонке Клавиша перечислены все символы на ней (в порядке латинская, латинская+Shift, русская, русская+Shift). В колонке Модификатор нажатая клавиша. В колонках Латинская и Русская символ, который появляется в тексте, если нажати указанную клавишу с указанным модификатором в соответствующей раскладке.

Клавиша Модификатор Латинская Русская
,<бБ нет , б
/?., Shift ? ,

Как видно, символ "запятая" из латинской раскладки без Shift был принят за набранный в русской раскладке с Shift, а затем странслирован в соответствующий латинский символ на той же клавише, т.е. "вопрос".

Я добавил некоторую отладку, в частности, по посылаемым приложению событиям, содержимому буфера и событиям очистки/сохранения буфера.

[TRA] 14:10:48 Received XI_KeyRelease 'Left'== 113 (event type 35)
[TRA] 14:10:51 Received XI_KeyPress 'space' == 65 (event type 35)
[TRA] 14:10:51 Received XI_KeyRelease 'space'== 65 (event type 35)
[TRA] 14:10:51 Received XI_KeyPress 'comma' == 59 (event type 35)
[TRA] 14:10:51 Received XI_KeyPress 'e' == 26 (event type 35)
[TRA] 14:10:51 Received XI_KeyRelease 'comma'== 59 (event type 35)
[TRA] 14:10:51 Received XI_KeyRelease 'e'== 26 (event type 35)
[TRA] 14:10:51 Received XI_KeyPress 'l' == 46 (event type 35)
[TRA] 14:10:51 Received XI_KeyPress 't' == 28 (event type 35)
[TRA] 14:10:52 Received XI_KeyRelease 'l'== 46 (event type 35)
[TRA] 14:10:52 Received XI_KeyRelease 't'== 28 (event type 35)
[TRA] 14:10:52 Received XI_KeyPress 'n' == 57 (event type 35)
[TRA] 14:10:52 Received XI_KeyPress 'space' == 65 (event type 35)
[TRA] 14:10:52 Received XI_KeyRelease 'n'== 57 (event type 35)
[TRA] 14:10:52 Received XI_KeyRelease 'space'== 65 (event type 35)
[TRA] 14:10:52 Received XI_KeyPress 'l' == 46 (event type 35)
[TRA] 14:10:52 Received XI_KeyRelease 'l'== 46 (event type 35)
[TRA] 14:10:52 Received XI_KeyPress 'j' == 44 (event type 35)
[TRA] 14:10:52 Received XI_KeyRelease 'j'== 44 (event type 35)
[TRA] 14:10:54 Received XI_KeyPress 'comma' == 59 (event type 35)
[TRA] 14:10:54 Received XI_KeyRelease 'comma'== 59 (event type 35)
[TRA] 14:10:54 Received XI_KeyPress 'f' == 41 (event type 35)
[TRA] 14:10:54 Received XI_KeyRelease 'f'== 41 (event type 35)
[TRA] 14:10:54 Received XI_KeyPress 'd' == 40 (event type 35)
[TRA] 14:10:54 Received XI_KeyRelease 'd'== 40 (event type 35)
[TRA] 14:10:54 Received XI_KeyPress 'k' == 45 (event type 35)
[TRA] 14:10:54 Received XI_KeyRelease 'k'== 45 (event type 35)
[TRA] 14:10:54 Received XI_KeyPress 't' == 28 (event type 35)
[TRA] 14:10:54 Received XI_KeyRelease 't'== 28 (event type 35)
[TRA] 14:10:54 Received XI_KeyPress 'y' == 29 (event type 35)
[TRA] 14:10:55 Received XI_KeyRelease 'y'== 29 (event type 35)
[TRA] 14:10:55 Received XI_KeyPress 'space' == 65 (event type 35)
[DBG] 14:10:55 Remove word 'добавлен' from Russian pattern
[LOG] 14:10:55 Saving Russian pattern
[TRA] 14:10:55 Received XI_KeyRelease 'space'== 65 (event type 35)
[TRA] 14:10:55 Received XI_KeyPress 'Control_R' == 105 (event type 35)
[TRA] 14:10:55 Received XI_KeyPress 'Shift_R' == 62 (event type 35)
[TRA] 14:10:56 Received XI_KeyPress 'Left' == 113 (event type 35)
[TRA] 14:10:56   buffer saved to log & cleared
[TRA] 14:10:56   correction buffer cleared
[TRA] 14:10:56 Received XI_KeyRelease 'Left'== 113 (event type 35)
[TRA] 14:10:56 Received XI_KeyPress 'Left' == 113 (event type 35)
[TRA] 14:10:56   buffer saved to log & cleared
[TRA] 14:10:56   correction buffer cleared
[TRA] 14:10:56 Received XI_KeyRelease 'Left'== 113 (event type 35)
[TRA] 14:10:56 Received XI_KeyPress 'Left' == 113 (event type 35)
[TRA] 14:10:56   buffer saved to log & cleared
[TRA] 14:10:56   correction buffer cleared
[TRA] 14:10:56 Received XI_KeyRelease 'Left'== 113 (event type 35)
[TRA] 14:10:56 Received XI_KeyPress 'Left' == 113 (event type 35)
[TRA] 14:10:56   buffer saved to log & cleared
[TRA] 14:10:56   correction buffer cleared
[TRA] 14:10:56 Received XI_KeyRelease 'Left'== 113 (event type 35)
[TRA] 14:10:56 Received XI_KeyRelease 'Control_R'== 105 (event type 35)
[TRA] 14:10:57 Received XI_KeyPress 'Control_R' == 105 (event type 35)
[TRA] 14:10:57 Received XI_KeyPress 'Right' == 114 (event type 35)
[TRA] 14:10:57   buffer saved to log & cleared
[TRA] 14:10:57   correction buffer cleared
[TRA] 14:10:57 Received XI_KeyRelease 'Control_R'== 105 (event type 35)
[TRA] 14:10:57 Received XI_KeyRelease 'Right'== 114 (event type 35)
[TRA] 14:10:57 Received XI_KeyPress 'Pause' == 127 (event type 35)
[TRA] 14:10:57 Received XI_KeyRelease 'Pause'== 127 (event type 35)
[LOG] 14:10:57 Execute action "Correct selected text"
[DBG] 14:10:57 Received selected text from buffer 0 ' ,eltn lj,fdkty '
[TRA] 14:10:57   buffer content replaced, new: ' ?eltn lj?fdkty ' // buffer->content
[DBG] 14:10:57 Language rotated next: English (US) -> Russian
[DBG] 14:10:57 Processing string ' ?eltn lj?fdkty '
[TRA] 14:10:57   ru: ' .удет до.авлен ' // buffer->i18n_content[lang].content
[TRA] 14:10:57       ' ,удет до,авлен ' // buffer->i18n_content[lang].content_unchanged
[TRA] 14:10:57   us: ' /eltn lj/fdkty ' // buffer->i18n_content[lang].content
[TRA] 14:10:57       ' ?eltn lj?fdkty ' // buffer->i18n_content[lang].content_unchanged
[TRA] 14:10:57     Send KeyPress   'slash' == 94, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'slash' == 94, state 1, X server CurrentTime
[TRA] 14:10:57 Send backspaces, count = 1
[TRA] 14:10:57     Send KeyPress   'BackSpace' == 22, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'BackSpace' == 22, state 0, X server CurrentTime
[TRA] 14:10:57 Send backspaces, count = 0
[TRA] 14:10:57 Send string from buffer, count = 16, content:  ?eltn lj?fdkty 
[TRA] 14:10:57     Send KeyPress   'space' == 65, state 8192, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'space' == 65, state 8192, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'slash' == 61, state 8193, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'slash' == 61, state 8193, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'e' == 26, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'e' == 26, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'l' == 46, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'l' == 46, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   't' == 28, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 't' == 28, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'n' == 57, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'n' == 57, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'space' == 65, state 8192, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'space' == 65, state 8192, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'l' == 46, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'l' == 46, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'j' == 44, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'j' == 44, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'slash' == 61, state 8193, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'slash' == 61, state 8193, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'f' == 41, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'f' == 41, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'd' == 40, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'd' == 40, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'k' == 45, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'k' == 45, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   't' == 28, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 't' == 28, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'y' == 29, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'y' == 29, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'space' == 65, state 8192, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'space' == 65, state 8192, X server CurrentTime
[TRA] 14:10:57 Send selection, count = 16
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Left' == 113, state 0, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyPress   'Right' == 114, state 1, X server CurrentTime
[TRA] 14:10:57     Send KeyRelease 'Right' == 114, state 1, X server CurrentTime

В частности видно, что содержимое, текста, полученного из буфера обмена, на момент завершения функции buffer_set_content портится (лог buffer content replaced, new: '%s' оттуда) -- латинские буквы остались нетронутыми, а вот знаки припинания изменились:

static void buffer_set_content(struct _buffer *p, const char *new_content)
{
if (new_content == NULL)
return;
char *content = strdup(new_content);
if (content == NULL)
return;
p->clear(p);
p->cur_pos = strlen(content);
if (p->cur_pos >= p->cur_size)
set_new_size(p, p->cur_pos + 1);
p->content[p->cur_pos] = NULLSYM;
if (!p->cur_pos)
{
free(content);
return;
}
memcpy(p->content, content, p->cur_pos);
free(content);
p->keymap->convert_text_to_ascii(p->keymap, p->content, p->keycode, p->keycode_modifiers);
p->cur_pos = strlen(p->content);
set_new_size(p, p->cur_pos + 1);
buffer_set_i18n_content(p);
}

Как видно, ни в одном из буферов в классе _buffer нет оригинального текста (я добавил в лог комментарии о том, какое именно поле где выводится).

Порча происходит при вызове метода convert_text_to_ascii:

static void keymap_convert_text_to_ascii(struct _keymap *p, char *text, KeyCode *kc, int *kc_mod)
{
int text_len = strlen(text);
int j = 0;
size_t symbol_len = 0;
int preferred_lang = 0;
for (int i = 0; i < text_len; i += symbol_len)
{
char new_symbol = p->get_ascii(p, &text[i], &preferred_lang, &kc[j], &kc_mod[j], &symbol_len);
if (new_symbol != NULLSYM && symbol_len > 0)
text[j++] = new_symbol;
else
symbol_len = 1;
}
text[j] = NULLSYM;
}

Вероятно проблема в том, что код в
https://github.com/AndrewCrewKuznetsov/xneur-devel/blob/master/xneur/lib/main/keymap.c#L246
пытается по набранному тексту угадать, какие клавиши были нажаты, чтобы его получить. И для случая, когда текст мог получиться нажатием разных клавиш, он находит неправильную клавишу. Скорее всего, используется неправильный язык, хотя там в коде есть какие-то безумные приседания вокруг некоего preferred_lang. Вероятно, здесь код пытается одновременно определить, на каком языке написан текст и получить клавиши, которые были нажаты, чтобы его написать. В результате буквы могут распознаться каждая в своем языке, но буферу потом в целом присвоится какой-то один язык.