textbox: advance cursor correctly for multi-char input

Thanks to eigengrau
fixes: #280
This commit is contained in:
Dave Davenport 2015-11-22 20:41:45 +01:00
parent ca1b590bf8
commit 4510f65d5a
6 changed files with 23 additions and 22 deletions

View File

@ -100,7 +100,7 @@ void textbox_draw ( textbox *tb, cairo_t *draw );
*
* @returns if the key was handled (1), unhandled(0) or handled and return was pressed (-1)
*/
int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, KeySym key, Status stat );
int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, int pad_len, KeySym key, Status stat );
/**
* @param tb Handle to the textbox
@ -127,13 +127,14 @@ void textbox_cursor ( textbox *tb, int pos );
void textbox_move ( textbox *tb, int x, int y );
/**
* @param tb Handle to the textbox
* @param pos The position to insert the string at
* @param str The string to insert.
* @param tb Handle to the textbox
* @param pos The position to insert the string at
* @param str The string to insert.
* @param slen The length of the string.
*
* Insert the string str at position pos.
*/
void textbox_insert ( textbox *tb, int pos, char *str );
void textbox_insert ( textbox *tb, int pos, char *str, int slen );
/**
* Setup the cached fonts. This is required to do

View File

@ -196,7 +196,7 @@ static int combi_mode_match ( char **tokens, int not_ascii,
abort ();
return 0;
}
static char * combi_mgrv ( unsigned int selected_line,const Switcher *sw, int *state, int get_entry )
static char * combi_mgrv ( unsigned int selected_line, const Switcher *sw, int *state, int get_entry )
{
CombiModePrivateData *pd = sw->private_data;
if ( !get_entry ) {

View File

@ -326,11 +326,11 @@ static int window_match ( char **tokens,
{
SwitcherModePrivateData *rmpd = (SwitcherModePrivateData *) sw->private_data;
int match = 1;
const winlist *ids = ( winlist * ) rmpd->ids;
const winlist *ids = ( winlist * ) rmpd->ids;
// Want to pull directly out of cache, X calls are not thread safe.
int idx = winlist_find ( cache_client, ids->array[index]);
g_assert ( idx >= 0 ) ;
client *c = cache_client->data[idx];
int idx = winlist_find ( cache_client, ids->array[index] );
g_assert ( idx >= 0 );
client *c = cache_client->data[idx];
if ( tokens ) {
for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) {
@ -577,9 +577,9 @@ static int window_is_not_ascii ( const Switcher *sw, unsigned int index )
const SwitcherModePrivateData *rmpd = sw->private_data;
const winlist *ids = ( winlist * ) rmpd->ids;
// Want to pull directly out of cache, X calls are not thread safe.
int idx = winlist_find ( cache_client, ids->array[index]);
g_assert ( idx >= 0 ) ;
client *c = cache_client->data[idx];
int idx = winlist_find ( cache_client, ids->array[index] );
g_assert ( idx >= 0 );
client *c = cache_client->data[idx];
return is_not_ascii ( c->role ) || is_not_ascii ( c->class ) || is_not_ascii ( c->title ) || is_not_ascii ( c->name );
}

View File

@ -1076,7 +1076,7 @@ static void menu_paste ( MenuState *state, XSelectionEvent *xse )
dl--;
}
// Insert string move cursor.
textbox_insert ( state->text, state->text->cursor, text );
textbox_insert ( state->text, state->text->cursor, text, dl );
textbox_cursor ( state->text, state->text->cursor + dl );
// Force a redraw and refiltering of the text.
state->update = TRUE;
@ -1562,7 +1562,7 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
continue;
}
int rc = textbox_keypress ( state.text, &ev, pad, key, stat );
int rc = textbox_keypress ( state.text, &ev, pad, len, key, stat );
// Row is accepted.
if ( rc < 0 ) {
shift = ( ( ev.xkey.state & ShiftMask ) == ShiftMask );

View File

@ -410,9 +410,9 @@ void textbox_cursor_end ( textbox *tb )
}
// insert text
void textbox_insert ( textbox *tb, int pos, char *str )
void textbox_insert ( textbox *tb, int pos, char *str, int slen )
{
int len = ( int ) strlen ( tb->text ), slen = ( int ) strlen ( str );
int len = ( int ) strlen ( tb->text );
pos = MAX ( 0, MIN ( len, pos ) );
// expand buffer
tb->text = g_realloc ( tb->text, len + slen + 1 );
@ -491,7 +491,7 @@ static void textbox_cursor_del_word ( textbox *tb )
// 0 = unhandled
// 1 = handled
// -1 = handled and return pressed (finished)
int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, KeySym key, Status stat )
int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, int pad_len, KeySym key, Status stat )
{
if ( !( tb->flags & TB_EDITABLE ) ) {
return 0;
@ -562,11 +562,11 @@ int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, KeySym key, Status st
return -1;
}
}
if ( *pad != 0 && ( stat == XLookupBoth || stat == XLookupChars ) ) {
if ( pad_len > 0 && ( stat == XLookupBoth || stat == XLookupChars ) ) {
// Filter When alt/ctrl is pressed do not accept the character.
if ( !g_ascii_iscntrl ( *pad ) ) {
textbox_insert ( tb, tb->cursor, pad );
textbox_cursor_inc ( tb );
textbox_insert ( tb, tb->cursor, pad, pad_len );
textbox_cursor ( tb, tb->cursor + pad_len );
return 1;
}
}

View File

@ -105,7 +105,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
TASSERT ( box->cursor == 4 );
textbox_cursor ( box, 2 );
TASSERT ( box->cursor == 2 );
textbox_insert ( box, 3, "bo" );
textbox_insert ( box, 3, "bo", 2 );
TASSERT ( strcmp ( box->text, "tesbot" ) == 0 );
textbox_cursor_end ( box );
TASSERT ( box->cursor == 6 );