[4966] in Athena Bugs

home help back first fref pref prev next nref lref last post

Xaw Text widget cursor movement

daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Tue May 22 01:07:25 1990

Date: Tue, 22 May 90 01:06:54 -0400
From: "Jonathan I. Kamens" <jik@pit-manager.MIT.EDU>
To: xbugs@expo.lcs.mit.edu
Cc: bugs@ATHENA.MIT.EDU

			  X Window System Bug Report
			    xbugs@expo.lcs.mit.edu


VERSION:
    R4

CLIENT MACHINE and OPERATING SYSTEM:
    NA

DISPLAY TYPE:
    NA

WINDOW MANAGER:
    NA

AREA:
    Xaw Text widget

SYNOPSIS:
    Cursor movement commands do not always verify that the insertion
    point is visible after the movement is done.

DESCRIPTION:
    The commands to move the insertion point (e.g. M-b, M-f, C-b, C-f,
    etc.), i.e. the commands which use the "Move" function in
    TextAction.c, do not verify that the insertion point is visible
    after the cursor movement is complete.

REPEAT BY:
    Create a one-line text widget, with auto-fill disabled and
    word-wrap enabled.  Type enough text on one line to overfill the
    visible portion of the text widget (once again, it should scroll
    to keep the insertion point visible, and it doesn't, but that's
    another bug).  Type M-b, and see how your insertion point still
    isn't visible.

SAMPLE FIX:
    Provided below.  The solution provided may not be elegant or
    optimal, because I don't really understand the inner workings of
    the text widget completely.  It does, however, work.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

*** /tmp/,RCSt1000229	Tue May 22 00:40:19 1990
--- TextAction.c	Tue May 22 00:24:19 1990
***************
*** 295,300 ****
--- 295,341 ----
    if (ctx->text.insertPos == old_pos)
        ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
  				    type, dir, ctx->text.mult + 1, include);
+ 
+ /*
+  * If the movement moved the insertion point out of view, then scroll
+  * to bring it back into view.
+  */
+ #define IsBeforeStart(ctx) ctx->text.insertPos < ctx->text.lt.info[0].position
+ #define IsAfterEnd(ctx) ctx->text.insertPos >= \
+   ctx->text.lt.info[ctx->text.lt.lines].position
+ 
+ /*
+  * There are two things you have to realize here.  First of all, you
+  * *must* check to see if the position is before the first displayed
+  * position *before* you check to see if the position is after the
+  * last displayed position.  Second, even though it appears that if
+  * the body of the first while loop ever gets executed, the cursor
+  * will be visible when it's done executing the last time, this is not
+  * true, and that's why it's necessary to do the second while loop
+  * even if the first one is executed at least once.
+  *
+  * The reason for this is that when the text widget is scrolled down
+  * (the scroll of "-1"), it always scrolls in such a way that the
+  * beginning of the text line (as opposed to the beginning of the
+  * widget line) is displayed when it's done scrolling.  This could
+  * leave you looking at the beginning of a wrapped line, while the
+  * insertion point is in the middle of the same line and not visible,
+  * after the first while loop is done.  On the other hand, scrolling
+  * forward scrolls by widget lines rather than text lines, and
+  * therefore will fix up any misadjustments by the first loop.
+  */
+   while (IsBeforeStart(ctx)) {
+        _XawTextVScroll(ctx, -1);
+        _XawTextBuildLineTable(ctx, ctx->text.lt.top, FALSE);
+   }
+   while (IsAfterEnd(ctx)) {
+        _XawTextVScroll(ctx, 1);
+        _XawTextBuildLineTable(ctx, ctx->text.lt.top, FALSE);
+   }
+ 
+ #undef IsBeforeStart
+ #undef IsAfterEnd
+   
    EndAction(ctx);
  }
  


home help back first fref pref prev next nref lref last post