From 8268d41410b722567aca4a8dc30f3171681350a0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 29 Jun 2012 11:35:24 -0400 Subject: [PATCH] terminal: Handle selection for pointer positions outside widget correctly That is, don't crash and select entire first/last line when the pointer is above or below widget. --- clients/terminal.c | 70 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/clients/terminal.c b/clients/terminal.c index 28d8ada..62bb020 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -2279,8 +2279,9 @@ recompute_selection(struct terminal *terminal) side_margin = allocation.x + (allocation.width - width) / 2; top_margin = allocation.y + (allocation.height - height) / 2; - start_row = (terminal->selection_start_y - top_margin) / ch; - end_row = (terminal->selection_end_y - top_margin) / ch; + start_row = (terminal->selection_start_y - top_margin + ch) / ch - 1; + end_row = (terminal->selection_end_y - top_margin + ch) / ch - 1; + if (start_row < end_row || (start_row == end_row && terminal->selection_start_x < terminal->selection_end_x)) { @@ -2295,39 +2296,50 @@ recompute_selection(struct terminal *terminal) end_x = terminal->selection_start_x; } - x = side_margin + cw / 2; - data = terminal_get_row(terminal, terminal->selection_start_row); - word_start = 0; - for (col = 0; col < terminal->width; col++, x += cw) { - if (col == 0 || wordsep(data[col - 1].ch)) - word_start = col; - if (start_x < x) - break; - } - - switch (terminal->dragging) { - case SELECT_LINE: + if (terminal->selection_start_row < 0) { + terminal->selection_start_row = 0; terminal->selection_start_col = 0; - break; - case SELECT_WORD: - terminal->selection_start_col = word_start; - break; - case SELECT_CHAR: - terminal->selection_start_col = col; - break; - } + } else { + x = side_margin + cw / 2; + data = terminal_get_row(terminal, + terminal->selection_start_row); + word_start = 0; + for (col = 0; col < terminal->width; col++, x += cw) { + if (col == 0 || wordsep(data[col - 1].ch)) + word_start = col; + if (start_x < x) + break; + } - x = side_margin + cw / 2; - data = terminal_get_row(terminal, terminal->selection_end_row); - for (col = 0; col < terminal->width; col++, x += cw) { - if (terminal->dragging == SELECT_CHAR && end_x < x) + switch (terminal->dragging) { + case SELECT_LINE: + terminal->selection_start_col = 0; + break; + case SELECT_WORD: + terminal->selection_start_col = word_start; break; - if (terminal->dragging == SELECT_WORD && - end_x < x && wordsep(data[col].ch)) + case SELECT_CHAR: + terminal->selection_start_col = col; break; + } } - terminal->selection_end_col = col; + if (terminal->selection_end_row >= terminal->height) { + terminal->selection_end_row = terminal->height; + terminal->selection_end_col = 0; + } else { + x = side_margin + cw / 2; + data = terminal_get_row(terminal, terminal->selection_end_row); + for (col = 0; col < terminal->width; col++, x += cw) { + if (terminal->dragging == SELECT_CHAR && end_x < x) + break; + if (terminal->dragging == SELECT_WORD && + end_x < x && wordsep(data[col].ch)) + break; + } + + terminal->selection_end_col = col; + } return 1; } -- 2.7.4