From d7586cb66c1beaf810b3ea433007e6d0e33ad51c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 29 Jul 2016 12:07:46 +0200 Subject: [PATCH] Fix clear screen behaviour of console when user scrolled up or down We must call SetConsoleCursorPosition prior to SetConsoleWindowInfo, otherwise the scroll bars will not be updated by the OS. Make sure to scroll the console window by just the right amount to have the new cursor position one line after the used console buffer area at the top of the console window, no matter the scroll state. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_console.cc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 9c490c530..f083f7e67 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -1248,7 +1248,16 @@ dev_console::scroll_window (HANDLE h, int x1, int y1, int x2, int y2) else { /* The reminder of the console buffer is big enough to simply move - the console window. */ + the console window. We have to set the cursor first, otherwise + the scroll bars will not be corrected. */ + SetConsoleCursorPosition (h, dwEnd); + /* If we scroll backwards, setting the cursor position will scroll + the console window up so that the cursor is at the bottom. Correct + the action by moving the window down again so the cursor is one line + above the new window position. */ + if (toscroll < 0) + toscroll = b.srWindow.Bottom - b.srWindow.Top; + /* Move the window accordingly. */ sr.Top = sr.Bottom = toscroll; SetConsoleWindowInfo (h, FALSE, &sr); } @@ -1268,6 +1277,8 @@ void __reg3 fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2) { HANDLE h = get_output_handle (); + SHORT oldEndY = con.dwEnd.Y; + con.fillin (h); int x1 = con.set_cl_x (xc1); @@ -1275,6 +1286,15 @@ fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2) int x2 = con.set_cl_x (xc2); int y2 = con.set_cl_y (yc2); + /* Make correction for the following situation: The console buffer + is only partially used and the user scrolled down into the as yet + unused area. */ + if (oldEndY < con.dwEnd.Y) + { + con.dwEnd.Y = con.b.dwCursorPosition.Y = oldEndY; + y1 = con.b.srWindow.Top; + } + /* Detect special case - scroll the screen if we have a buffer in order to preserve the buffer. */ if (!con.scroll_window (h, x1, y1, x2, y2))