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);
+ 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;
case XmCR_VALUE_CHANGED:
Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
float top, shown;
- if (whole == 0)
+ BLOCK_INPUT;
+
+#ifdef USE_MOTIF
+
+ /* 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 = XFASTINT (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)
top = 0, shown = 1;
else
{
shown = (float) portion / whole;
}
- BLOCK_INPUT;
-
-#ifdef USE_MOTIF
+ if (NILP (bar->dragging))
{
int size, value;
- XmScrollBarWidget sb;
/* 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 = min (value, XM_SB_MAX - size);
value = max (value, XM_SB_MIN);
- if (NILP (bar->dragging))
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 */
+
+ if (whole == 0)
+ top = 0, shown = 1;
+ else
+ {
+ top = (float) position / whole;
+ shown = (float) portion / whole;
+ }
+
{
float old_top, old_shown;
Dimension height;
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;