vte r2296 - in trunk: . src
- From: behdad svn gnome org
- To: svn-commits-list gnome org
- Subject: vte r2296 - in trunk: . src
- Date: Tue, 2 Dec 2008 12:51:10 +0000 (UTC)
Author: behdad
Date: Tue Dec 2 12:51:10 2008
New Revision: 2296
URL: http://svn.gnome.org/viewvc/vte?rev=2296&view=rev
Log:
2008-12-02 Behdad Esfahbod <behdad gnome org>
Bug 471480 â select single character
Bug 110371 â Cannot select newline at end of full line
* src/vte-private.h:
* src/vte.c (find_start_column), (find_end_column),
(vte_terminal_start_selection), (math_div),
(vte_terminal_extend_selection):
Make selection work more I-beam-like.
Modified:
trunk/ChangeLog
trunk/src/vte-private.h
trunk/src/vte.c
Modified: trunk/src/vte-private.h
==============================================================================
--- trunk/src/vte-private.h (original)
+++ trunk/src/vte-private.h Tue Dec 2 12:51:10 2008
@@ -296,7 +296,7 @@
} selection_origin, selection_last, selection_restart_origin;
struct selection_cell_coords {
long row, col;
- } selection_start, selection_end;
+ } selection_start, selection_end, last_selection_start, last_selection_end;
/* Miscellaneous options. */
VteTerminalEraseBinding backspace_binding, delete_binding;
Modified: trunk/src/vte.c
==============================================================================
--- trunk/src/vte.c (original)
+++ trunk/src/vte.c Tue Dec 2 12:51:10 2008
@@ -6149,6 +6149,8 @@
find_start_column (VteTerminal *terminal, glong col, glong row)
{
VteRowData *row_data = _vte_terminal_find_row_data (terminal, row);
+ if (G_UNLIKELY (col < 0))
+ return col;
if (row_data != NULL) {
struct vte_charcell *cell = _vte_row_data_find_charcell(row_data, col);
while (cell != NULL && cell->attr.fragment && col > 0) {
@@ -6162,6 +6164,8 @@
{
VteRowData *row_data = _vte_terminal_find_row_data (terminal, row);
gint columns = 0;
+ if (G_UNLIKELY (col < 0))
+ return col;
if (row_data != NULL) {
struct vte_charcell *cell = _vte_row_data_find_charcell(row_data, col);
while (cell != NULL && cell->attr.fragment && col > 0) {
@@ -6195,6 +6199,12 @@
terminal->pvt->selection_last.y = event->y - VTE_PAD_WIDTH +
(terminal->char_height * delta);
+ /* Clear cached coords */
+ terminal->pvt->last_selection_start.row = -1;
+ terminal->pvt->last_selection_start.col = -1;
+ terminal->pvt->last_selection_end.row = -1;
+ terminal->pvt->last_selection_end.col = -1;
+
/* Decide whether or not to restart on the next drag. */
switch (selection_type) {
case selection_type_char:
@@ -6247,6 +6257,15 @@
_vte_terminal_disconnect_pty_read(terminal);
}
+long
+math_div (long a, long b)
+{
+ if (G_LIKELY (a >= 0))
+ return a / b;
+ else
+ return (a / b) - 1;
+}
+
/* Extend selection to include the given event coordinates. */
static void
vte_terminal_extend_selection(VteTerminal *terminal, double x, double y,
@@ -6254,7 +6273,7 @@
{
VteScreen *screen;
VteRowData *rowdata;
- long delta, height, width, i, j;
+ long delta, height, width, residual, i, j;
struct vte_charcell *cell;
struct selection_event_coords *origin, *last, *start, *end;
struct selection_cell_coords old_start, old_end, *sc, *ec, tc;
@@ -6264,14 +6283,6 @@
height = terminal->char_height;
width = terminal->char_width;
- /* If the pointer hasn't moved to another character cell, then we
- * need do nothing. */
- if (force == FALSE &&
- floor (x / width) == floor (terminal->pvt->mouse_last_x / width) &&
- floor (y / height) == floor (terminal->pvt->mouse_last_y / height)) {
- return;
- }
-
screen = terminal->pvt->screen;
old_start = terminal->pvt->selection_start;
old_end = terminal->pvt->selection_end;
@@ -6342,23 +6353,54 @@
start->x, start->y, end->x, end->y);
/* Recalculate the selection area in terms of cell positions. */
- terminal->pvt->selection_start.col = MAX (0, start->x / width);
- terminal->pvt->selection_start.row = MAX (0, start->y / height);
- terminal->pvt->selection_end.col = MAX (0, end->x / width);
- terminal->pvt->selection_end.row = MAX (0, end->y / height);
- /* Re-sort using cell coordinates to catch round-offs that make two
- * coordinates "the same". */
sc = &terminal->pvt->selection_start;
ec = &terminal->pvt->selection_end;
- if ((sc->row > ec->row) || ((sc->row == ec->row) && (sc->row > ec->row))) {
- tc = *sc;
- *sc = *ec;
- *ec = tc;
+
+ /* Rows are easy. But we try to be a bit lenient by discounting
+ * one fourth of the height on each side as wiggle room */
+ residual = (height + 1) / 4;
+ sc->row = MAX (0, ((long)start->y + residual) / height);
+ ec->row = MAX (0, ((long)end->y - residual) / height);
+
+ /* Re-sort using row cell coordinates */
+ if ((sc->row == ec->row) && (start->x > end->x)) {
+ struct selection_event_coords *tmp;
+ tmp = start;
+ start = end;
+ end = tmp;
+ }
+
+ /* Columns are trickier. We want to be more I-beam-like, so we round
+ * to closest logical position (positions are located between cells).
+ * But we don't want to fully round. So we divide the char width into
+ * three parts. The side parts round to their nearest position. The
+ * middle part is always inclusive in the selection. XXXXXXX */
+ residual = (width + 1) / 3;
+ sc->col = math_div ((long)start->x + residual, width);
+ ec->col = math_div ((long)end->x - residual, width);
+
+#if 0
+ THIS CURRENTLY DOESN'T WORK AS WE HAVE INVALIDATED ALREADY. GOT TO MOVE
+ INVALIDATION AFTER THIS CHECK AND ENABLE IT.
+
+ /* If the endpoint cells have not changed, then we need do nothing. */
+ if (force == FALSE &&
+ sc->row == terminal->pvt->last_selection_start.row &&
+ sc->col == terminal->pvt->last_selection_start.col &&
+ ec->row == terminal->pvt->last_selection_end.row &&
+ ec->col == terminal->pvt->last_selection_end.col) {
+ return;
}
+ terminal->pvt->last_selection_start = *sc;
+ terminal->pvt->last_selection_end = *ec;
+#endif
+
+ /* Extend them to full multi-col characters. */
sc->col = find_start_column (terminal, sc->col, sc->row);
ec->col = find_end_column (terminal, ec->col, ec->row);
+
/* Extend the selection to handle end-of-line cases, word, and line
* selection. We do this here because calculating it once is cheaper
* than recalculating for each cell as we render it. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]