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.
[EMAIL PROTECTED]                 |
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

Reply via email to