On Tue, Jan 11, 2005 at 01:38:09PM +0100, Vincent Lefevre wrote: > On 2005-01-11 05:15:09 -0500, Branden Robinson wrote: > > I still want to hear what Thomas Dickey as to say about this. I'm > > also not sure the semantics of selections vs. cut buffers are as you > > describe. > > I don't think the end user should be exposed to differences between > implementations (e.g. primary selection vs cut buffer), at least with > a default configuration. I'm attaching the patch that Thomas Dickey has put into XTerm #200. I expect to include this in the next package release, and plan to close this bug accordingly. As you will see from reviewing the patch, the new code has been instrumented. I will expect anyone who has a gripe with the new behavior to be willing to run a trace-enabled version of xterm to help Thomas Dickey understand the problem and/or the exact behavior that is desired. -- G. Branden Robinson | Debian GNU/Linux | De minimis non curat lex. branden@debian.org | http://people.debian.org/~branden/ |
diff -urN xterm-199/util.c xterm-200/util.c
--- xterm-199/util.c 2005-01-13 20:50:03.000000000 -0500
+++ xterm-200/util.c 2005-02-06 16:42:38.000000000 -0500
@@ -1,10 +1,10 @@
-/* $XTermId: util.c,v 1.220 2005/01/14 01:50:03 tom Exp $ */
+/* $XTermId: util.c,v 1.223 2005/02/06 21:42:38 tom Exp $ */
/*
* $Xorg: util.c,v 1.3 2000/08/17 19:55:10 cpqbld Exp $
*/
-/* $XFree86: xc/programs/xterm/util.c,v 3.87 2005/01/14 01:50:03 dickey Exp $ */
+/* $XFree86: xc/programs/xterm/util.c,v 3.88 2005/02/06 21:42:38 dickey Exp $ */
/*
* Copyright 1999-2004,2005 by Thomas E. Dickey
@@ -203,6 +203,122 @@
}
/*
+ * If we're scrolling, leave the selection intact if possible.
+ * If it will bump into one of the extremes of the saved-lines, truncate that.
+ * If the selection is not contained within the scrolled region, clear it.
+ */
+static void
+adjustHiliteOnFwdScroll(TScreen * screen, int amount, Boolean all_lines)
+{
+ int lo_row = (all_lines
+ ? (screen->bot_marg - screen->savelines)
+ : screen->top_marg);
+ int hi_row = screen->bot_marg;
+
+ TRACE2(("adjustSelection FWD %s by %d (%s)\n",
+ screen->alternate ? "alternate" : "normal",
+ amount,
+ all_lines ? "all" : "visible"));
+ TRACE2((" before highlite %d.%d .. %d.%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ screen->endHRow,
+ screen->endHCol));
+ TRACE2((" margins %d..%d\n", screen->top_marg, screen->bot_marg));
+ TRACE2((" limits %d..%d\n", lo_row, hi_row));
+
+ if (screen->startHRow >= lo_row
+ && screen->startHRow - amount < lo_row) {
+ /* truncate the selection because its start would move out of region */
+ if (lo_row + amount <= screen->endHRow) {
+ TRACE2(("truncate selection by changing start %d.%d to %d.%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ lo_row + amount,
+ 0));
+ screen->startHRow = lo_row + amount;
+ screen->startHCol = 0;
+ } else {
+ TRACE2(("deselect because %d.%d .. %d.%d shifted %d is outside margins %d..%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ screen->endHRow,
+ screen->endHCol,
+ -amount,
+ lo_row,
+ hi_row));
+ ScrnDisownSelection(screen);
+ }
+ } else if (screen->startHRow <= hi_row && screen->endHRow > hi_row) {
+ ScrnDisownSelection(screen);
+ } else if (screen->startHRow < lo_row && screen->endHRow > lo_row) {
+ ScrnDisownSelection(screen);
+ }
+
+ TRACE2((" after highlite %d.%d .. %d.%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ screen->endHRow,
+ screen->endHCol));
+}
+
+/*
+ * This is the same as adjustHiliteOnFwdScroll(), but reversed. In this case,
+ * only the visible lines are affected.
+ */
+static void
+adjustHiliteOnBakScroll(TScreen * screen, int amount)
+{
+ int lo_row = screen->top_marg;
+ int hi_row = screen->bot_marg;
+
+ TRACE2(("adjustSelection BAK %s by %d (%s)\n",
+ screen->alternate ? "alternate" : "normal",
+ amount,
+ "visible"));
+ TRACE2((" before highlite %d.%d .. %d.%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ screen->endHRow,
+ screen->endHCol));
+ TRACE2((" margins %d..%d\n", screen->top_marg, screen->bot_marg));
+
+ if (screen->endHRow >= hi_row
+ && screen->endHRow + amount > hi_row) {
+ /* truncate the selection because its start would move out of region */
+ if (hi_row - amount >= screen->startHRow) {
+ TRACE2(("truncate selection by changing start %d.%d to %d.%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ hi_row - amount,
+ 0));
+ screen->endHRow = hi_row - amount;
+ screen->endHCol = 0;
+ } else {
+ TRACE2(("deselect because %d.%d .. %d.%d shifted %d is outside margins %d..%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ screen->endHRow,
+ screen->endHCol,
+ amount,
+ lo_row,
+ hi_row));
+ ScrnDisownSelection(screen);
+ }
+ } else if (screen->endHRow >= lo_row && screen->startHRow < lo_row) {
+ ScrnDisownSelection(screen);
+ } else if (screen->endHRow > hi_row && screen->startHRow > hi_row) {
+ ScrnDisownSelection(screen);
+ }
+
+ TRACE2((" after highlite %d.%d .. %d.%d\n",
+ screen->startHRow,
+ screen->startHCol,
+ screen->endHRow,
+ screen->endHCol));
+}
+
+/*
* scrolls the screen by amount lines, erases bottom, doesn't alter
* cursor position (i.e. cursor moves down amount relative to text).
* All done within the scrolling region, of course.
@@ -218,6 +334,9 @@
int refreshheight;
int scrolltop;
int scrollheight;
+ Boolean scroll_all_lines = (screen->scrollWidget
+ && !screen->alternate
+ && screen->top_marg == 0);
TRACE(("xtermScroll count=%d\n", amount));
@@ -227,12 +346,12 @@
if (screen->cursor_state)
HideCursor();
- if (ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg))
- ScrnDisownSelection(screen);
-
if (amount > i)
amount = i;
+ if (ScrnHaveSelection(screen))
+ adjustHiliteOnFwdScroll(screen, amount, scroll_all_lines);
+
if (screen->jumpscroll) {
if (screen->scroll_amt > 0) {
if (screen->refresh_amt + amount > i)
@@ -253,15 +372,17 @@
screen->cursor_busy -= 1;
return;
}
+
shift = -screen->topline;
bot = screen->max_row - shift;
scrollheight = i - amount;
refreshheight = amount;
+
if ((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
(i = screen->max_row - refreshheight + 1))
refreshtop = i;
- if (screen->scrollWidget && !screen->alternate
- && screen->top_marg == 0) {
+
+ if (scroll_all_lines) {
scrolltop = 0;
if ((scrollheight += shift) > i)
scrollheight = i;
@@ -289,7 +410,9 @@
CopyWait(screen);
screen->scrolls++;
}
+
scrolling_copy_area(screen, scrolltop + amount, scrollheight, amount);
+
if (refreshheight > 0) {
ClearCurBackground(screen,
(int) refreshtop * FontHeight(screen) + screen->border,
@@ -300,10 +423,9 @@
refreshheight = shift;
}
}
+
if (amount > 0) {
- if (screen->scrollWidget
- && !screen->alternate
- && screen->top_marg == 0) {
+ if (scroll_all_lines) {
ScrnDeleteLine(screen,
screen->allbuf,
screen->bot_marg + screen->savelines,
@@ -319,10 +441,12 @@
(unsigned) (screen->max_col + 1));
}
}
+
if (refreshheight > 0) {
ScrnRefresh(screen, refreshtop, 0, refreshheight,
screen->max_col + 1, False);
}
+
screen->cursor_busy -= 1;
return;
}
@@ -352,12 +476,12 @@
if (screen->cursor_state)
HideCursor();
- if (ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg))
- ScrnDisownSelection(screen);
-
if (amount > i)
amount = i;
+ if (ScrnHaveSelection(screen))
+ adjustHiliteOnBakScroll(screen, amount);
+
if (screen->jumpscroll) {
if (screen->scroll_amt < 0) {
if (-screen->refresh_amt + amount > i)
@@ -390,7 +514,9 @@
CopyWait(screen);
screen->scrolls++;
}
+
scrolling_copy_area(screen, scrolltop - amount, scrollheight, -amount);
+
if (refreshheight > 0) {
ClearCurBackground(screen,
(int) refreshtop * FontHeight(screen) + screen->border,
@@ -435,8 +561,10 @@
if (screen->cursor_state)
HideCursor();
- if (ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg))
+ if (ScrnHaveSelection(screen)
+ && ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg)) {
ScrnDisownSelection(screen);
+ }
screen->do_wrap = 0;
if (n > (i = screen->bot_marg - screen->cur_row + 1))
@@ -504,8 +632,10 @@
if (screen->cursor_state)
HideCursor();
- if (ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg))
+ if (ScrnHaveSelection(screen)
+ && ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg)) {
ScrnDisownSelection(screen);
+ }
screen->do_wrap = 0;
if (n > (i = screen->bot_marg - screen->cur_row + 1))
Attachment:
signature.asc
Description: Digital signature