patch 8.1.1597: cannot scroll a popup window with the mouse

Problem:    Cannot scroll a popup window with the mouse.
Solution:   If the popup window has a scrollbar let the mouse scroll wheel
            scroll the window.
diff --git a/src/normal.c b/src/normal.c
index cf9026f..5bd2e5e 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4521,9 +4521,13 @@
 	col = mouse_col;
 
 	/* find the window at the pointer coordinates */
-	wp = mouse_find_win(&row, &col, FAIL_POPUP);
+	wp = mouse_find_win(&row, &col, FIND_POPUP);
 	if (wp == NULL)
 	    return;
+#ifdef FEAT_TEXT_PROP
+	if (bt_popup(wp->w_buffer) && !wp->w_has_scrollbar)
+	    return;
+#endif
 	curwin = wp;
 	curbuf = curwin->w_buffer;
     }
@@ -4543,10 +4547,35 @@
 	}
 	else
 	{
-	    cap->count1 = 3;
-	    cap->count0 = 3;
+	    // Don't scroll more than half the window height.
+	    if (curwin->w_height < 6)
+	    {
+		cap->count1 = curwin->w_height / 2;
+		if (cap->count1 == 0)
+		    cap->count1 = 1;
+	    }
+	    else
+		cap->count1 = 3;
+	    cap->count0 = cap->count1;
 	    nv_scroll_line(cap);
 	}
+#ifdef FEAT_TEXT_PROP
+	if (bt_popup(wp->w_buffer))
+	{
+	    int	    height = wp->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);
+	    }
+	}
+#endif
     }
 # ifdef FEAT_GUI
     else
diff --git a/src/popupwin.c b/src/popupwin.c
index b9526c7..5611cba 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -1547,6 +1547,7 @@
 	dict_add_number(dict, "core_height", wp->w_height);
 
 	dict_add_number(dict, "scrollbar", wp->w_has_scrollbar);
+	dict_add_number(dict, "firstline", wp->w_topline);
 	dict_add_number(dict, "visible",
 		      win_valid(wp) && (wp->w_popup_flags & POPF_HIDDEN) == 0);
     }
@@ -2238,12 +2239,13 @@
 	{
 	    linenr_T linecount = wp->w_buffer->b_ml.ml_line_count;
 
-	    sb_thumb_height = wp->w_height * wp->w_height / linecount;
+	    sb_thumb_height = (wp->w_height * wp->w_height + linecount / 2)
+								   / linecount;
 	    if (sb_thumb_height == 0)
 		sb_thumb_height = 1;
-	    sb_thumb_top = ((wp->w_topline * (wp->w_height - sb_thumb_height)
-			    + (linecount - wp->w_height) / 2))
-			      / (linecount - (wp->w_height - sb_thumb_height));
+	    sb_thumb_top = (wp->w_topline - 1 + (linecount / wp->w_height) / 2)
+				* (wp->w_height - sb_thumb_height)
+						  / (linecount - wp->w_height);
 	}
 
 	for (i = wp->w_popup_border[0];
diff --git a/src/screen.c b/src/screen.c
index 56bbee3..5136c13 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -875,7 +875,7 @@
 #endif
 #ifdef FEAT_TEXT_PROP
     // Update popup_mask if needed.
-    may_update_popup_mask(0);
+    may_update_popup_mask(must_redraw);
 #endif
 }
 
@@ -1555,7 +1555,11 @@
 	if (mid_start == 0)
 	{
 	    mid_end = wp->w_height;
-	    if (ONE_WINDOW)
+	    if (ONE_WINDOW
+#ifdef FEAT_TEXT_PROP
+		    && !bt_popup(wp->w_buffer)
+#endif
+		    )
 	    {
 		/* Clear the screen when it was not done by win_del_lines() or
 		 * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
diff --git a/src/testdir/dumps/Test_popupwin_firstline.dump b/src/testdir/dumps/Test_popupwin_firstline.dump
index 7efcf3e..1371297 100644
--- a/src/testdir/dumps/Test_popupwin_firstline.dump
+++ b/src/testdir/dumps/Test_popupwin_firstline.dump
@@ -3,7 +3,7 @@
 |3| @73
 |4| @33|3+0#0000001#ffd7ff255@4| +0#0000000#a8a8a8255| +0&#ffffff0@33
 |5| @33|4+0#0000001#ffd7ff255@1| @2| +0#0000000#0000001| +0&#ffffff0@33
-|6| @33|5+0#0000001#ffd7ff255| @3| +0#0000000#a8a8a8255| +0&#ffffff0@33
+|6| @33|5+0#0000001#ffd7ff255| @3| +0#0000000#0000001| +0&#ffffff0@33
 |7| @33|6+0#0000001#ffd7ff255@4| +0#0000000#a8a8a8255| +0&#ffffff0@33
 |8| @73
 |9| @73
diff --git a/src/testdir/dumps/Test_popupwin_scroll_1.dump b/src/testdir/dumps/Test_popupwin_scroll_1.dump
index dd0e0b3..2f623e7 100644
--- a/src/testdir/dumps/Test_popupwin_scroll_1.dump
+++ b/src/testdir/dumps/Test_popupwin_scroll_1.dump
@@ -2,7 +2,7 @@
 |2| @73
 |3| @73
 |4| @31|o+0#0000001#ffd7ff255|n|e| @4| +0#0000000#0000001| +0&#ffffff0@32
-|5| @31|t+0#0000001#ffd7ff255|w|o| @4| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|5| @31|t+0#0000001#ffd7ff255|w|o| @4| +0#0000000#0000001| +0&#ffffff0@32
 |6| @31|t+0#0000001#ffd7ff255|h|r|e@1| @2| +0#0000000#a8a8a8255| +0&#ffffff0@32
 |7| @31|f+0#0000001#ffd7ff255|o|u|r| @3| +0#0000000#a8a8a8255| +0&#ffffff0@32
 |8| @73
diff --git a/src/testdir/dumps/Test_popupwin_scroll_2.dump b/src/testdir/dumps/Test_popupwin_scroll_2.dump
index 21d33da..f081d6a 100644
--- a/src/testdir/dumps/Test_popupwin_scroll_2.dump
+++ b/src/testdir/dumps/Test_popupwin_scroll_2.dump
@@ -1,7 +1,7 @@
 >1+0&#ffffff0| @73
 |2| @73
 |3| @73
-|4| @31|t+0#0000001#ffd7ff255|w|o| @4| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|4| @31|t+0#0000001#ffd7ff255|w|o| @4| +0#0000000#0000001| +0&#ffffff0@32
 |5| @31|t+0#0000001#ffd7ff255|h|r|e@1| @2| +0#0000000#0000001| +0&#ffffff0@32
 |6| @31|f+0#0000001#ffd7ff255|o|u|r| @3| +0#0000000#a8a8a8255| +0&#ffffff0@32
 |7| @31|f+0#0000001#ffd7ff255|i|v|e| @3| +0#0000000#a8a8a8255| +0&#ffffff0@32
diff --git a/src/testdir/dumps/Test_popupwin_scroll_3.dump b/src/testdir/dumps/Test_popupwin_scroll_3.dump
index 656e058..4a44896 100644
--- a/src/testdir/dumps/Test_popupwin_scroll_3.dump
+++ b/src/testdir/dumps/Test_popupwin_scroll_3.dump
@@ -3,7 +3,7 @@
 |3| @73
 |4| @31|s+0#0000001#ffd7ff255|i|x| @4| +0#0000000#a8a8a8255| +0&#ffffff0@32
 |5| @31|s+0#0000001#ffd7ff255|e|v|e|n| @2| +0#0000000#a8a8a8255| +0&#ffffff0@32
-|6| @31|e+0#0000001#ffd7ff255|i|g|h|t| @2| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|6| @31|e+0#0000001#ffd7ff255|i|g|h|t| @2| +0#0000000#0000001| +0&#ffffff0@32
 |7| @31|n+0#0000001#ffd7ff255|i|n|e| @3| +0#0000000#0000001| +0&#ffffff0@32
 |8| @73
 |9| @73
diff --git a/src/testdir/dumps/Test_popupwin_scroll_5.dump b/src/testdir/dumps/Test_popupwin_scroll_5.dump
new file mode 100644
index 0000000..2ce9964
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_scroll_5.dump
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @73
+|3| @73
+|4| @31|o+0#0000001#ffd7ff255|n|e| @4| +0#0000000#0000001| +0&#ffffff0@32
+|5| @31|t+0#0000001#ffd7ff255|w|o| @4| +0#0000000#0000001| +0&#ffffff0@32
+|6| @31|t+0#0000001#ffd7ff255|h|r|e@1| @2| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|7| @31|f+0#0000001#ffd7ff255|o|u|r| @3| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|8| @73
+|9| @73
+|:|c|a|l@1| |S|c|r|o|l@1|U|p|(|)| @40|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_popupwin_scroll_6.dump b/src/testdir/dumps/Test_popupwin_scroll_6.dump
new file mode 100644
index 0000000..02c5958
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_scroll_6.dump
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @73
+|3| @73
+|4| @31|t+0#0000001#ffd7ff255|h|r|e@1| @2| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|5| @31|f+0#0000001#ffd7ff255|o|u|r| @3| +0#0000000#0000001| +0&#ffffff0@32
+|6| @31|f+0#0000001#ffd7ff255|i|v|e| @3| +0#0000000#0000001| +0&#ffffff0@32
+|7| @31|s+0#0000001#ffd7ff255|i|x| @4| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|8| @73
+|9| @73
+|:|c|a|l@1| |S|c|r|o|l@1|D|o|w|n|(|)| @38|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_popupwin_scroll_7.dump b/src/testdir/dumps/Test_popupwin_scroll_7.dump
new file mode 100644
index 0000000..f4f0363
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_scroll_7.dump
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @73
+|3| @73
+|4| @31|s+0#0000001#ffd7ff255|i|x| @4| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|5| @31|s+0#0000001#ffd7ff255|e|v|e|n| @2| +0#0000000#a8a8a8255| +0&#ffffff0@32
+|6| @31|e+0#0000001#ffd7ff255|i|g|h|t| @2| +0#0000000#0000001| +0&#ffffff0@32
+|7| @31|n+0#0000001#ffd7ff255|i|n|e| @3| +0#0000000#0000001| +0&#ffffff0@32
+|8| @73
+|9| @73
+|:|c|a|l@1| |S|c|r|o|l@1|D|o|w|n|(|)| @38|1|,|1| @10|T|o|p| 
diff --git a/src/version.c b/src/version.c
index fa4e50d..b4d568c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1597,
+/**/
     1596,
 /**/
     1595,