Subject: patch 5.4p.4 (was: gvimole5.4o : vertical scrollbar jumping bug?)
From: Bram Moolenaar <[email-masked]>
To: "John Mullin" <[email-masked]>
Cc: <[email-masked]>

------------

John Mullin wrote:

> I noticed a problem with gvimole5.4n
> 
> With the vertical scrollbar enabled,
> open file about "32767 - &lines" long.
> (with text in at least some of the lines (32767i<cr> won't work:) )
> 
> hit G to goto end,
> 
> click the up arrow scroll bar button a few times
> and the thumb (and the cursor) moves up to the middle of the file
> (approx line 32767/2)
>
> click again, and the thumb and the cursor moves up by half the remaining file

Hmm, don't see this.

> Unfortunately I don't have visual C installed but my  best guess
> points to a problem in 
> 
> gui_win32.c: function gui_mch_set_scrollbar_thumb,
> 
> I'm guessing something about the left shifting by one

Probably.  There is one problem that someone reported that I can reproduce:
When the file is longer than 32768 lines, the up arrow moves two lines at a
time (OK, can accept that), and the down arrow doesn't move at all (oops).

Another thing I noticed: the scroll_shift, which is used to remember by how
much the values are shifted, is used for all scrollbars.  There should be a
separate value for each scrollbar.  Otherwise things go very wrong when using
more than one window.

> sorry it's not more specific,
> 
> I've included my vimrc and gvimrc

Hmm, it's too long to search for specific settings.  You better try this with
"gvim -u NONE -U NONE", or rename your vimrc for a moment.

Anyway, I fixed the mixup of scroll_shift between windows.  I worked around
the down-arrow not working by having it scroll several lines.  It's not a real
solution, but at least it does scroll now.

A real solution could be tricky, because there are roundoff problems.  I
notice that there is first a scroll of one line when the mouse button goes
down, and then an extra line when the button goes up.  This means there is an
extra event that reports the scrollbar position.  If we can avoid that it
would work.  But that might be a bit tricky.

Patch 5.4p.4
Problem:    Win32 GUI: The scrollbar values were reduced for a file with more
	    than 32767 lines.  But this info was kept global for all
	    scrollbars, causing a mixup between the windows.
	    Using the down arrow of a scrollbar in a large file didn't work.
	    Because of round-off errors there is no scroll at all.
Solution:   Give each scrollbar its own scroll_shift field.  When the down
	    arrow is used, scroll several lines.
Files:	    src/gui.h, src/gui_w32.c

*** ../vim-5.4p/src/gui.h	Mon Jul 19 11:08:54 1999
--- src/gui.h	Tue Jul 20 11:17:36 1999
***************
*** 175,180 ****
--- 175,184 ----
  #endif
  #ifdef USE_GUI_MSWIN
      HWND	id;		/* Id of real scroll bar */
+     int		scroll_shift;	/* The scrollbar stuff can handle only up to
+ 				   32767 lines.  When the file is longer,
+ 				   scroll_shift is set to the number of shifts
+ 				   to reduce the count.  */
  #endif
  #if USE_GUI_BEOS
      VimScrollBar *id;		/* Pointer to real scroll bar */
*** ../vim-5.4p/src/gui_w32.c	Mon Jul 19 11:09:06 1999
--- src/gui_w32.c	Tue Jul 20 12:05:09 1999
***************
*** 323,334 ****
  
  static int dialog_default_button = -1;
  
- /*
-  * The scrollbar stuff can handle only up to 32767 lines.  When the file is
-  * longer, scroll_shift is set to the number of shifts to reduce the count.
-  */
- static int scroll_shift = 0;
- 
  /* Intellimouse support */
  static int mouse_scroll_lines = 0;
  static UINT msh_msgmousewheel = 0;
--- 323,328 ----
***************
*** 1140,1151 ****
  	    /* TRACE("SB_THUMBTRACK, %d\n", pos); */
  	    val = pos;
  	    dragging = TRUE;
! 	    if (scroll_shift > 0)
! 		val <<= scroll_shift;
  	    break;
  	case SB_LINEDOWN:
  	    /* TRACE("SB_LINEDOWN\n"); */
! 	    val++;
  	    break;
  	case SB_LINEUP:
  	    /* TRACE("SB_LINEUP\n"); */
--- 1134,1150 ----
  	    /* TRACE("SB_THUMBTRACK, %d\n", pos); */
  	    val = pos;
  	    dragging = TRUE;
! 	    if (sb->scroll_shift > 0)
! 		val <<= sb->scroll_shift;
  	    break;
  	case SB_LINEDOWN:
  	    /* TRACE("SB_LINEDOWN\n"); */
! 	    /* Because of round-off errors we can't move one line when
! 	     * scroll_shift is non-zero.  Scroll some extra. */
! 	    if (sb->scroll_shift > 0)
! 		val += (1 << sb->scroll_shift);
! 	    else
! 		val++;
  	    break;
  	case SB_LINEUP:
  	    /* TRACE("SB_LINEUP\n"); */
***************
*** 1175,1182 ****
  	     */
  	    /* TRACE("SB_ENDSCROLL\n"); */
  	    val = GetScrollPos(hwndCtl, SB_CTL);
! 	    if (scroll_shift > 0)
! 		val <<= scroll_shift;
  	    break;
  
  	default:
--- 1174,1181 ----
  	     */
  	    /* TRACE("SB_ENDSCROLL\n"); */
  	    val = GetScrollPos(hwndCtl, SB_CTL);
! 	    if (sb->scroll_shift > 0)
! 		val <<= sb->scroll_shift;
  	    break;
  
  	default:
***************
*** 1186,1193 ****
  
      si.cbSize = sizeof(si);
      si.fMask = SIF_POS;
!     if (scroll_shift > 0)
! 	si.nPos = val >> scroll_shift;
      else
  	si.nPos = val;
      SetScrollInfo(hwndCtl, SB_CTL, &si, TRUE);
--- 1185,1192 ----
  
      si.cbSize = sizeof(si);
      si.fMask = SIF_POS;
!     if (sb->scroll_shift > 0)
! 	si.nPos = val >> sb->scroll_shift;
      else
  	si.nPos = val;
      SetScrollInfo(hwndCtl, SB_CTL, &si, TRUE);
***************
*** 2229,2244 ****
  {
      SCROLLINFO	info;
  
!     scroll_shift = 0;
      while (max > 32767)
      {
  	max = (max + 1) >> 1;
  	val  >>= 1;
  	size >>= 1;
! 	++scroll_shift;
      }
  
!     if (scroll_shift > 0)
  	++size;
  
      info.cbSize = sizeof(info);
--- 2228,2243 ----
  {
      SCROLLINFO	info;
  
!     sb->scroll_shift = 0;
      while (max > 32767)
      {
  	max = (max + 1) >> 1;
  	val  >>= 1;
  	size >>= 1;
! 	++sb->scroll_shift;
      }
  
!     if (sb->scroll_shift > 0)
  	++size;
  
      info.cbSize = sizeof(info);

--
hundred-and-one symptoms of being an internet addict:
171. You invent another person and chat with yourself in empty chat rooms.

--/-/---- Bram Moolenaar ---- [email-masked] ---- [email-masked] ---\-\--
  \ \    www.vim.org/iccf      www.moolenaar.net       www.vim.org    / /