patch 8.1.1608: the evalfunc.c file is too big

Problem:    The evalfunc.c file is too big.
Solution:   Move sign functionality to sign.c.
diff --git a/src/normal.c b/src/normal.c
index 0ab3db4..2015fd8 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4561,20 +4561,7 @@
 	}
 #ifdef FEAT_TEXT_PROP
 	if (bt_popup(curwin->w_buffer))
-	{
-	    int	    height = curwin->w_height;
-
-	    curwin->w_firstline = curwin->w_topline;
-	    popup_adjust_position(curwin);
-
-	    // we don't want the popup to get smaller, decrement the first line
-	    // until it doesn't
-	    while (curwin->w_firstline > 1 && curwin->w_height < height)
-	    {
-		--curwin->w_firstline;
-		popup_adjust_position(curwin);
-	    }
-	}
+	    popup_set_firstline(curwin);
 #endif
     }
 # ifdef FEAT_GUI
diff --git a/src/popupwin.c b/src/popupwin.c
index aa0bda3..96263bc 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -234,6 +234,58 @@
     popup_adjust_position(wp);
 }
 
+/*
+ * Set w_firstline to match the current "wp->w_topline".
+ */
+    void
+popup_set_firstline(win_T *wp)
+{
+    int	    height = wp->w_height;
+
+    wp->w_firstline = wp->w_topline;
+    popup_adjust_position(wp);
+
+    // we don't want the popup to get smaller, decrement the first line
+    // until it doesn't
+    while (wp->w_firstline > 1 && wp->w_height < height)
+    {
+	--wp->w_firstline;
+	popup_adjust_position(wp);
+    }
+}
+
+/*
+ * Handle a click in a popup window, if it is in the scrollbar.
+ */
+    void
+popup_handle_scrollbar_click(win_T *wp, int row, int col)
+{
+    int	    height = popup_height(wp);
+    int	    old_topline = wp->w_topline;
+
+    if (wp->w_has_scrollbar == 0)
+	return;
+    if (row >= wp->w_popup_border[0]
+	    && row < height - wp->w_popup_border[2]
+	    && col == popup_width(wp) - 1)
+    {
+	if (row >= height / 2)
+	{
+	    // Click in lower half, scroll down.
+	    if (wp->w_topline < wp->w_buffer->b_ml.ml_line_count)
+		++wp->w_topline;
+	}
+	else if (wp->w_topline > 1)
+	    // click on upper half, scroll up.
+	    --wp->w_topline;
+	if (wp->w_topline != old_topline)
+	{
+	    popup_set_firstline(wp);
+	    redraw_win_later(wp, NOT_VALID);
+	}
+    }
+}
+
 #if defined(FEAT_TIMERS)
     static void
 popup_add_timeout(win_T *wp, int time)
@@ -631,7 +683,8 @@
 {
     return wp->w_width
 	+ wp->w_popup_padding[3] + wp->w_popup_border[3]
-	+ wp->w_popup_padding[1] + wp->w_popup_border[1];
+	+ wp->w_popup_padding[1] + wp->w_popup_border[1]
+	+ wp->w_has_scrollbar;
 }
 
 /*
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index 2f66946..7ac8612 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -2,6 +2,8 @@
 int popup_on_border(win_T *wp, int row, int col);
 void popup_start_drag(win_T *wp);
 void popup_drag(win_T *wp);
+void popup_set_firstline(win_T *wp);
+void popup_handle_scrollbar_click(win_T *wp, int row, int col);
 int popup_height(win_T *wp);
 int popup_width(win_T *wp);
 void popup_adjust_position(win_T *wp);
diff --git a/src/structs.h b/src/structs.h
index b368c9e..208a11e 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2903,7 +2903,7 @@
     int		w_wantcol;	    // "col" for popup window
     int		w_firstline;	    // "firstline" for popup window
     int		w_want_scrollbar;   // when zero don't use a scrollbar
-    int		w_has_scrollbar;    // scrollbar displayed
+    int		w_has_scrollbar;    // 1 if scrollbar displayed, 0 otherwise
     char_u	*w_scrollbar_highlight; // "scrollbarhighlight"
     char_u	*w_thumb_highlight; // "thumbhighlight"
     int		w_popup_padding[4]; // popup padding top/right/bot/left
diff --git a/src/testdir/dumps/Test_popupwin_scroll_8.dump b/src/testdir/dumps/Test_popupwin_scroll_8.dump
new file mode 100644
index 0000000..34b1638
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_scroll_8.dump
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @73
+|3| @73
+|4| @31|f+0#0000001#ffd7ff255|o|u|r| @3| +0#0000000#ff404010| +0&#ffffff0@32
+|5| @31|f+0#0000001#ffd7ff255|i|v|e| @3| +0#0000000#4040ff13| +0&#ffffff0@32
+|6| @31|s+0#0000001#ffd7ff255|i|x| @4| +0#0000000#4040ff13| +0&#ffffff0@32
+|7| @31|s+0#0000001#ffd7ff255|e|v|e|n| @2| +0#0000000#ff404010| +0&#ffffff0@32
+|8| @73
+|9| @73
+|:|c|a|l@1| |C|l|i|c|k|T|o|p|(|)| @40|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_popupwin_scroll_9.dump b/src/testdir/dumps/Test_popupwin_scroll_9.dump
new file mode 100644
index 0000000..d2b7134
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_scroll_9.dump
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @73
+|3| @73
+|4| @31|f+0#0000001#ffd7ff255|i|v|e| @3| +0#0000000#ff404010| +0&#ffffff0@32
+|5| @31|s+0#0000001#ffd7ff255|i|x| @4| +0#0000000#ff404010| +0&#ffffff0@32
+|6| @31|s+0#0000001#ffd7ff255|e|v|e|n| @2| +0#0000000#4040ff13| +0&#ffffff0@32
+|7| @31|e+0#0000001#ffd7ff255|i|g|h|t| @2| +0#0000000#4040ff13| +0&#ffffff0@32
+|8| @73
+|9| @73
+|:|c|a|l@1| |C|l|i|c|k|B|o|t|(|)| @40|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 1cb0734..f4bc33c 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -1436,7 +1436,15 @@
     func ScrollDown()
       call feedkeys("\<F3>\<ScrollWheelDown>", "xt")
     endfunc
+    func ClickTop()
+      call feedkeys("\<F4>\<LeftMouse>", "xt")
+    endfunc
+    func ClickBot()
+      call feedkeys("\<F5>\<LeftMouse>", "xt")
+    endfunc
     map <silent> <F3> :call test_setmouse(5, 36)<CR>
+    map <silent> <F4> :call test_setmouse(4, 42)<CR>
+    map <silent> <F5> :call test_setmouse(7, 42)<CR>
   END
   call writefile(lines, 'XtestPopupScroll')
   let buf = RunVimInTerminal('-S XtestPopupScroll', {'rows': 10})
@@ -1464,6 +1472,14 @@
   call term_sendkeys(buf, ":call ScrollDown()\<CR>")
   call VerifyScreenDump(buf, 'Test_popupwin_scroll_7', {})
 
+  call term_sendkeys(buf, ":call ClickTop()\<CR>")
+  sleep 100m
+  call term_sendkeys(buf, ":call ClickTop()\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_scroll_8', {})
+
+  call term_sendkeys(buf, ":call ClickBot()\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_scroll_9', {})
+
   " clean up
   call StopVimInTerminal(buf)
   call delete('XtestPopupScroll')
diff --git a/src/ui.c b/src/ui.c
index 00e8887..d09e0ab 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -2998,7 +2998,7 @@
 	    return IN_OTHER_WIN;
 #endif
 #ifdef FEAT_TEXT_PROP
-	// Continue a modeless selection in a popup window.
+	// Continue a modeless selection in a popup window or dragging it.
 	if (in_popup_win)
 	{
 	    if (popup_dragwin != NULL)
@@ -3056,6 +3056,9 @@
 		popup_start_drag(wp);
 		return IN_UNKNOWN;
 	    }
+	    if (which_button == MOUSE_LEFT)
+		// If the click is in the scrollbar, may scroll up/down.
+		popup_handle_scrollbar_click(wp, row, col);
 # ifdef FEAT_CLIPBOARD
 	    return IN_OTHER_WIN;
 # else
@@ -3517,7 +3520,7 @@
 	{
 	    if (*rowp >= wp->w_winrow && *rowp < wp->w_winrow + popup_height(wp)
 		    && *colp >= wp->w_wincol
-					 && *colp < wp->w_wincol + popup_width(wp))
+				    && *colp < wp->w_wincol + popup_width(wp))
 		pwp = wp;
 	}
 	if (pwp != NULL)
diff --git a/src/version.c b/src/version.c
index aa0b8be..f1bf262 100644
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1607,
+/**/
     1606,
 /**/
     1605,