emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Emacs + LessTif serious scroll judder when point-max is visible


From: Stefan Monnier
Subject: Re: Emacs + LessTif serious scroll judder when point-max is visible
Date: Fri, 30 Nov 2001 16:54:03 -0500

> > Richard Stallman <address@hidden> writes:
> > 
> > > Could you please respond?
> > > 
> > > From: "Marshall, Simon" <address@hidden>
> > > Subject: FW: Emacs + LessTif serious scroll judder when 
> > point-max is visible
> > > To: "'Emacs Developers'" <address@hidden>
> > > Date: Thu, 29 Nov 2001 11:43:09 -0000
> > > 
> > > Hi folks, I seem to remember someone (Gerd?) saying that 
> > there could be
> > > a workaround for this problem, but that it would have to wait until
> > > after 21.1.
> > 
> > If I've said that, which I don't remember, I don't remember what I had
> > in mind.  Maybe it was Stefan?
> 
> That rings a bell, maybe it was...  Stefan?

Yes, it might have been me.
If you feel like it, you can try the patch below which I've
been using but am not satisfied with.  I haven't actually tried in
with Motif/Lesstif, but (modulo bugs) it should solve the jitter
problem at the cost of a less useful thumb-positioning.

Could people on emacs-devel try it out and tell me what they think
about it ?

Maybe we should use this patch for Motif but not for Xaw3d
(the jitter is usually less severe with Xaw3d) ?


        Stefan


Index: xterm.c
===================================================================
RCS file: /cvs/emacs/src/xterm.c,v
retrieving revision 1.689
diff -u -r1.689 xterm.c
--- xterm.c     2001/11/28 17:07:59     1.689
+++ xterm.c     2001/11/30 21:50:44
@@ -847,8 +847,8 @@
       break;
       
     case OVERLAY_ARROW_BITMAP:
-      wd = left_width;
-      h = left_height;
+      wd = ov_width;
+      h = ov_height;
       bits = ov_bits;
       x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
           - wd
@@ -864,8 +864,8 @@
       break;
 
     case CONTINUED_LINE_BITMAP:
-      wd = right_width;
-      h = right_height;
+      wd = continued_width;
+      h = continued_height;
       bits = continued_bits;
       x = window_box_right (w, -1);
       x += (FRAME_X_RIGHT_FRINGE_WIDTH (f) - wd) / 2;
@@ -8264,13 +8264,6 @@
 
 static Boolean xaw3d_arrow_scroll;
 
-/* Whether the drag scrolling maintains the mouse at the top of the
-   thumb.  If not, resizing the thumb needs to be done more carefully
-   to avoid jerkyness.  */
-
-static Boolean xaw3d_pick_top;
-
-
 /* Action hook installed via XtAppAddActionHook when toolkit scroll
    bars are used..  The hook is responsible for detecting when
    the user ends an interaction with the scroll bar, and generates
@@ -8481,31 +8474,10 @@
        XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
        UNBLOCK_INPUT;
 
-       /* At the max position of the scroll bar, do a line-wise
-          movement.  Without doing anything, we would be called with
-          the same cs->value again and again.  If we want to make
-          sure that we can reach the end of the buffer, we have to do
-          something.
-
-          Implementation note: setting bar->dragging always to
-          cs->value gives a smoother movement at the max position.
-          Setting it to nil when doing line-wise movement gives
-          a better slider behavior. */
-       
-       if (cs->value + slider_size == XM_SB_MAX
-           || (dragging_down_p
-               && last_scroll_bar_part == scroll_bar_down_arrow))
-         {
-           part = scroll_bar_down_arrow;
-           bar->dragging = Qnil;
-         }
-       else
-         {
-           whole = XM_SB_RANGE;
-           portion = min (cs->value - XM_SB_MIN, XM_SB_MAX - slider_size);
-           part = scroll_bar_handle;
-           bar->dragging = make_number (cs->value);
-         }
+       whole = XM_SB_RANGE - slider_size;
+       portion = min (cs->value - XM_SB_MIN, whole);
+       part = scroll_bar_handle;
+       bar->dragging = make_number (cs->value);
       }
       break;
       
@@ -8524,6 +8496,7 @@
 
 #else /* !USE_MOTIF, i.e. Xaw.  */
 
+#define XAW_SB_RANGE 10000000
 
 /* Xaw scroll bar callback.  Invoked when the thumb is dragged.
    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
@@ -8546,19 +8519,10 @@
   XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
   UNBLOCK_INPUT;
 
-  whole = 10000000;
-  portion = shown < 1 ? top * whole : 0;
+  whole = XAW_SB_RANGE - (XAW_SB_RANGE * shown);
+  portion = min (XAW_SB_RANGE * top, whole);
+  part = scroll_bar_handle;
 
-  if (shown < 1 && (abs (top + shown - 1) < 1.0/height))
-    /* Some derivatives of Xaw refuse to shrink the thumb when you reach
-       the bottom, so we force the scrolling whenever we see that we're
-       too close to the bottom (in x_set_toolkit_scroll_bar_thumb
-       we try to ensure that we always stay two pixels away from the
-       bottom).  */
-    part = scroll_bar_down_arrow;
-  else
-    part = scroll_bar_handle;
-
   window_being_scrolled = bar->window;
   bar->dragging = make_number (portion);
   last_scroll_bar_part = part;
@@ -8762,8 +8726,7 @@
   {
     char *initial = "";
     char *val = initial;
-    XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
-                  XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
+    XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val, NULL);
     if (val == initial)
       {        /* ARROW_SCROLL */
        xaw3d_arrow_scroll = True;
@@ -8807,8 +8770,24 @@
   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
   float top, shown;
+
+  /* We use an estimate of 30 chars per line rather than the real
+     `portion' value.  This has the disadvantage that the thumb size
+     is not very representative, but it makes our life a lot easier.
+     Otherwise, we have to constantly adjust the thumb size, which
+     we can't always do quickly enough: while dragging, the size of
+     the thumb might prevent the user from dragging the thumb all the
+     way to the end.  but Motif and some versions of Xaw3d don't allow
+     updating the thumb size while dragging.  Also, even if we can update
+     its size, the update will often happen too late.
+     If you don't believe it, check out revision 1.650 of xterm.c to see
+     what hoops we were going through and the still poor behavior we got.  */
+  portion = XWINDOW (bar->window)->height * 30;
+  /* When the thumb is at the bottom, position == whole.
+     So we need to increase `whole' to make space for the thumb.  */
+  whole += portion;
 
-  if (whole == 0)
+  if (whole <= 0)
     top = 0, shown = 1;
   else
     {
@@ -8818,96 +8797,30 @@
 
   BLOCK_INPUT;
 
+  if (NILP (bar->dragging))
 #ifdef USE_MOTIF
-  {
-    int size, value;
-
-    /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
-       is the scroll bar's maximum and MIN is the scroll bar's minimum
-       value.  */
-    size = shown * XM_SB_RANGE;
-    size = min (size, XM_SB_RANGE);
-    size = max (size, 1);
-
-    /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
-    value = top * XM_SB_RANGE;
-    value = min (value, XM_SB_MAX - size);
-    value = max (value, XM_SB_MIN);
+    {
+      int size, value;
 
-    if (NILP (bar->dragging))
+      /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
+         is the scroll bar's maximum and MIN is the scroll bar's minimum
+        value.  */
+      size = shown * XM_SB_RANGE;
+      size = min (size, XM_SB_RANGE);
+      size = max (size, 1);
+
+      /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
+      value = top * XM_SB_RANGE;
+      value = min (value, XM_SB_MAX - size);
+      value = max (value, XM_SB_MIN);
+      
       XmScrollBarSetValues (widget, value, size, 0, 0, False);
-    else if (last_scroll_bar_part == scroll_bar_down_arrow)
-      /* This has the negative side effect that the slider value is
-        not what it would be if we scrolled here using line-wise or
-        page-wise movement.  */
-      XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False);
-    else
-      {
-       /* If currently dragging, only update the slider size.
-          This reduces flicker effects.  */
-       int old_value, old_size, increment, page_increment;
-       
-       XmScrollBarGetValues (widget, &old_value, &old_size,
-                             &increment, &page_increment);
-       XmScrollBarSetValues (widget, old_value,
-                             min (size, XM_SB_RANGE - old_value),
-                             0, 0, False);
-      }
-  }
+    }
 #else /* !USE_MOTIF i.e. use Xaw */
-  {
-    float old_top, old_shown;
-    Dimension height;
-    XtVaGetValues (widget,
-                  XtNtopOfThumb, &old_top,
-                  XtNshown, &old_shown,
-                  XtNheight, &height,
-                  NULL);
-
-    /* Massage the top+shown values.  */
-    if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow)
-      top = max (0, min (1, top));
-    else
-      top = old_top;
-    /* Keep two pixels available for moving the thumb down.  */
-    shown = max (0, min (1 - top - (2.0 / height), shown));
-
     /* If the call to XawScrollbarSetThumb below doesn't seem to work,
        check that your system's configuration file contains a define
        for `NARROWPROTO'.  See s/freebsd.h for an example.  */
-    if (top != old_top || shown != old_shown)
-      {
-       if (NILP (bar->dragging))
-         XawScrollbarSetThumb (widget, top, shown);
-       else
-         {
-#ifdef HAVE_XAW3D
-           ScrollbarWidget sb = (ScrollbarWidget) widget;
-           int scroll_mode = 0;
-           
-           /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR.  */
-           if (xaw3d_arrow_scroll)
-             {
-               /* Xaw3d stupidly ignores resize requests while dragging
-                  so we have to make it believe it's not in dragging mode.  */
-               scroll_mode = sb->scrollbar.scroll_mode;
-               if (scroll_mode == 2)
-                 sb->scrollbar.scroll_mode = 0;
-             }
-#endif
-           /* Try to make the scrolling a tad smoother.  */
-           if (!xaw3d_pick_top)
-             shown = min (shown, old_shown);
-           
-           XawScrollbarSetThumb (widget, top, shown);
-           
-#ifdef HAVE_XAW3D
-           if (xaw3d_arrow_scroll && scroll_mode == 2)
-             sb->scrollbar.scroll_mode = scroll_mode;
-#endif
-         }
-      }
-  }
+    XawScrollbarSetThumb (widget, top, shown);
 #endif /* !USE_MOTIF */
 
   UNBLOCK_INPUT;
@@ -9879,7 +9792,7 @@
 
    EXPECTED is nonzero if the caller knows input is available.  */
 
-int
+static int
 XTread_socket (sd, bufp, numchars, expected)
      register int sd;
      /* register */ struct input_event *bufp;
@@ -14710,7 +14623,6 @@
   
 #ifdef USE_TOOLKIT_SCROLL_BARS
   xaw3d_arrow_scroll = False;
-  xaw3d_pick_top = True;
 #endif
 
   /* Note that there is no real way portable across R3/R4 to get the




reply via email to

[Prev in Thread] Current Thread [Next in Thread]