clients: keyboard: fix backspace deleting two characters with qt

The implementation of the
'zwp_input_method_context_v1_delete_surrounding_text' function in
'qtwayland' interprets the first index parameter as the number of
characters to be deleted before the cursor and the second as the number
of characters to be deleted after the cursor.
In the current implementation of the keyboard, this means that if the
cursor is between two characters, both the character before the cursor
and the character after the cursor are deleted.
As only the character before the cursor is to be deleted, it is
sufficient to pass a '0' as the second parameter.

Deleting a character at the end of the preedit string now also
takes UTF-8 characters into account.

Signed-off-by: Joscha.Wloch <Joscha.Wloch@bruker.com>
This commit is contained in:
Joscha.Wloch 2024-06-06 13:56:33 +02:00 committed by Joscha Wloch
parent 589f92d883
commit a3a8cf0cf4

View file

@ -570,6 +570,22 @@ prev_utf8_char(const char *s, const char *p)
return NULL;
}
static int utf8_char_size(const char* c)
{
if (c != NULL)
{
if ((*c & 0x80) == 0)
return 1;
if ((*c & 0xe0) == 0xc0)
return 2;
if ((*c & 0xf0) == 0xe0)
return 3;
if ((*c & 0xf8) == 0xf0)
return 4;
}
return 0;
}
static void
delete_before_cursor(struct virtual_keyboard *keyboard)
{
@ -590,8 +606,8 @@ delete_before_cursor(struct virtual_keyboard *keyboard)
end = keyboard->surrounding_text + keyboard->surrounding_cursor;
zwp_input_method_context_v1_delete_surrounding_text(keyboard->context,
start - keyboard->surrounding_text,
end - start);
(start - keyboard->surrounding_text) - keyboard->surrounding_cursor,
0);
zwp_input_method_context_v1_commit_string(keyboard->context,
keyboard->serial,
"");
@ -673,7 +689,23 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
if (strlen(keyboard->keyboard->preedit_string) == 0) {
delete_before_cursor(keyboard->keyboard);
} else {
keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0';
const size_t len = strlen(keyboard->keyboard->preedit_string);
const char *prev_utf8 = prev_utf8_char(keyboard->keyboard->preedit_string + (len - MIN(len, 4)),
keyboard->keyboard->preedit_string + strlen(keyboard->keyboard->preedit_string));
if (prev_utf8)
{
const int pref_utf8_offset = prev_utf8 - keyboard->keyboard->preedit_string;
if ((strlen(keyboard->keyboard->preedit_string + pref_utf8_offset) - utf8_char_size(prev_utf8)) == 0)
{
keyboard->keyboard->preedit_string[pref_utf8_offset] = '\0';
}
else
{
keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0';
}
}
virtual_keyboard_send_preedit(keyboard->keyboard, -1);
}
break;