GUAC-728: Take character width into account when displaying (and retrieving) selection.

This commit is contained in:
Michael Jumper 2014-06-06 14:05:41 -07:00
parent 6433115468
commit d19100ca6b
2 changed files with 77 additions and 11 deletions

View File

@ -737,22 +737,67 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal,
void guac_terminal_select_redraw(guac_terminal* terminal) { void guac_terminal_select_redraw(guac_terminal* terminal) {
guac_terminal_display_select(terminal->display, int start_row = terminal->selection_start_row + terminal->scroll_offset;
terminal->selection_start_row + terminal->scroll_offset, int start_column = terminal->selection_start_column;
terminal->selection_start_column,
terminal->selection_end_row + terminal->scroll_offset, int end_row = terminal->selection_end_row + terminal->scroll_offset;
terminal->selection_end_column); int end_column = terminal->selection_end_column;
/* Update start/end columns to include character width */
if (start_row > end_row || (start_row == end_row && start_column > end_column))
start_column += terminal->selection_start_width - 1;
else
end_column += terminal->selection_end_width - 1;
guac_terminal_display_select(terminal->display, start_row, start_column, end_row, end_column);
}
/**
* Locates the beginning of the character at the given row and column, updating
* the column to the starting column of that character. The width, if available,
* is returned. If the character has no defined width, 1 is returned.
*/
static int __guac_terminal_find_char(guac_terminal* terminal, int row, int* column) {
int start_column = *column;
guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(terminal->buffer, row, 0);
if (start_column < buffer_row->length) {
/* Find beginning of character */
guac_terminal_char* start_char = &(buffer_row->characters[start_column]);
while (start_column > 0 && start_char->value == GUAC_CHAR_CONTINUATION) {
start_char--;
start_column--;
}
/* Use width, if available */
if (start_char->value != GUAC_CHAR_CONTINUATION) {
*column = start_column;
return start_char->width;
}
}
/* Default to one column wide */
return 1;
} }
void guac_terminal_select_start(guac_terminal* terminal, int row, int column) { void guac_terminal_select_start(guac_terminal* terminal, int row, int column) {
int width = __guac_terminal_find_char(terminal, row, &column);
terminal->selection_start_row = terminal->selection_start_row =
terminal->selection_end_row = row; terminal->selection_end_row = row;
terminal->selection_start_column = terminal->selection_start_column =
terminal->selection_end_column = column; terminal->selection_end_column = column;
terminal->selection_start_width =
terminal->selection_end_width = width;
terminal->text_selected = true; terminal->text_selected = true;
guac_terminal_select_redraw(terminal); guac_terminal_select_redraw(terminal);
@ -761,9 +806,16 @@ void guac_terminal_select_start(guac_terminal* terminal, int row, int column) {
void guac_terminal_select_update(guac_terminal* terminal, int row, int column) { void guac_terminal_select_update(guac_terminal* terminal, int row, int column) {
if (row != terminal->selection_end_row || column != terminal->selection_end_column) { /* Only update if selection has changed */
terminal->selection_end_row = row; if (row != terminal->selection_end_row
terminal->selection_end_column = column; || column < terminal->selection_end_column
|| column >= terminal->selection_end_column + terminal->selection_end_width) {
int width = __guac_terminal_find_char(terminal, row, &column);
terminal->selection_end_row = row;
terminal->selection_end_column = column;
terminal->selection_end_width = width;
guac_terminal_select_redraw(terminal); guac_terminal_select_redraw(terminal);
} }
@ -805,15 +857,19 @@ void guac_terminal_select_end(guac_terminal* terminal, char* string) {
int end_row, end_col; int end_row, end_col;
/* Ensure proper ordering of start and end coords */ /* Ensure proper ordering of start and end coords */
if (terminal->selection_start_row <= terminal->selection_end_row) { if (terminal->selection_start_row < terminal->selection_end_row
|| (terminal->selection_start_row == terminal->selection_end_row
&& terminal->selection_start_column < terminal->selection_end_column)) {
start_row = terminal->selection_start_row; start_row = terminal->selection_start_row;
start_col = terminal->selection_start_column; start_col = terminal->selection_start_column;
end_row = terminal->selection_end_row; end_row = terminal->selection_end_row;
end_col = terminal->selection_end_column; end_col = terminal->selection_end_column + terminal->selection_end_width - 1;
} }
else { else {
end_row = terminal->selection_start_row; end_row = terminal->selection_start_row;
end_col = terminal->selection_start_column; end_col = terminal->selection_start_column + terminal->selection_start_width - 1;
start_row = terminal->selection_end_row; start_row = terminal->selection_end_row;
start_col = terminal->selection_end_column; start_col = terminal->selection_end_column;
} }

View File

@ -244,6 +244,11 @@ struct guac_terminal {
*/ */
int selection_start_column; int selection_start_column;
/**
* The width of the character at selection start.
*/
int selection_start_width;
/** /**
* The row that the selection ends at. * The row that the selection ends at.
*/ */
@ -254,6 +259,11 @@ struct guac_terminal {
*/ */
int selection_end_column; int selection_end_column;
/**
* The width of the character at selection end.
*/
int selection_end_width;
/** /**
* Whether the cursor (arrow) keys should send cursor sequences * Whether the cursor (arrow) keys should send cursor sequences
* or application sequences (DECCKM). * or application sequences (DECCKM).