Repository: microsoft/terminal (language: cpp)

Issue:
Enabling "Disable Scroll-Forward" causes incorrect display of vertical scrollbar
<!-- 
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨

I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING:
1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement.
2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement.
3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number).
4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement.
5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement.

All good? Then proceed!
-->

<!--
This bug tracker is monitored by Windows Terminal development team and other technical folks.

**Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**.
Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue.

If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link.

Please use this form and describe your issue, concisely but precisely, with as much detail as possible.

-->

# Environment

```none
Microsoft Windows [Version 10.0.18362.239]
```

# Steps to reproduce

In a standard CMD console window, from the properties dialog:

1. Terminal ~ ENABLE "Disable Scroll-Forward"
1. Layout ~ decrease "Screen Buffer Size / Height" to be equal to "Window Size / Height"

# Expected behavior

The vertical scrollbar should disappear.

# Actual behavior

The vertical scrollbar remains, fully or partially obscuring the last column of text characters (depending on font/size?).

![Screenshot](https://user-images.githubusercontent.com/80132/63137052-45e4c480-bf9a-11e9-8403-e0b9628a50cd.png)

The obscuring behavior can be seen on the longer lines in the screenshot.


Discussion / hints:
Parenthetically, I'm trying to enable a work-around for this bug for [`less`](https://github.com/rivy/less), but I see no way to detect the "Disable Scroll-Forward" feature.

Is there any way to detect whether this or other features are enabled?
This bug aside, the better way for `less` to ensure that there is no scrollbar (or one doesn't take up active screen space) is for it to use the (xterm) _alternate buffer_. That thing is really cool: it snapshots the display state, contents, etc. and switches the terminal emulator to a new pristine empty buffer that has no history and cannot scroll. When you exit the alt buffer, everything that was being displayed before snaps right back into place and overwrites the application's output.
It's also a little more "standards-compliant" than `SetConsoleActiveScreenBuffer`.
@DHowett-MSFT , thanks. I'll look into it.

I've hacked a work-around, for the time being, by just increasing the screen buffer vertical size by window size + one to force a scrollbar. All characters are displayed and the application function is unaffected, even if the scrollbar is redundant.
This, after 3+ years, seems to be a `won't-fix`.
Please open as a new issue elsewhere if/when you want to fix it.
I'm sorry about that. In the time since this was filed, I believe we improved the "disable scroll-forward" feature (which we had been calling "virtual bottom") in a number of ways... but none of those changes are, or will be, released to Windows 10. We never found a specific cause for this, nor did we get a strong local repro (which is puzzling)...

I'd love to know if it's still happening. I also respect that you may not want to engage with us about it any longer 🙂 
@DHowett I can reproduce this (on Windows 10), but it looks to me like it might be a bug in the scrollbar implementation itself. Quoting the documentation [here](https://learn.microsoft.com/en-us/windows/win32/controls/about-scroll-bars#scroll-bar-visibility):

> The system also hides and disables a standard scroll bar if you specify a page size that includes the entire scroll range of the scroll bar.

But that doesn't seem to be the case. I can get it to work if I manually hide the scrollbar when we're setting the scroll range, and the page size is greater than the max value (i.e. it includes the entire range). So something like this:

```cpp
const auto scrollBarVisible = static_cast<int>(pageSize) <= maxSize;
ShowScrollBar(_hWnd, isVertical ? SB_VERT : SB_HORZ, scrollBarVisible);
```

inserted in the `Window::UpdateScrollBar` method here:

https://github.com/microsoft/terminal/blob/6567201e0e1e72f82bfd3b565a8c3cb95ef2a75d/src/interactivity/win32/window.cpp#L890-L898

I'm not sure if that's exactly what we want, or there's a better way of fixing it, but that at least feels like an improvement.

If this is a Windows bug though, and it has already been fixed in Windows 11, then I assume there is no point in trying to fix it in our code (assuming Windows 10 isn't getting updates anymore).
@j4james, I'm more than happy to take your suggestion on a fix for this! It does still reproduce in Windows 11 conhost. Thanks for investigating. :smile:

(We may want to make certain that `scrollBarVisible` is actually `TRUE` or `FALSE`; I've seen Win32 APIs get up to no good when confronted with non-Win32-BOOL booleans.)

EDIT: (Ah, that parameter controls _redraw_, not visibility. Hmm.)
> EDIT: (Ah, that parameter controls _redraw_, not visibility. Hmm.)

@DHowett Just to be clear, I wasn't suggesting changing the final parameter of the `SetScrollInfo` call (that's the _redraw_ flag). I'm suggesting adding an additional call to [`ShowScrollBar`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showscrollbar).
Oh. Derp. Sorry :smile:

Fix patch:
diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp
index e0631290026..0260304547c 100644
--- a/src/host/screenInfo.cpp
+++ b/src/host/screenInfo.cpp
@@ -682,7 +682,7 @@ VOID SCREEN_INFORMATION::InternalUpdateScrollBars()
         }
 
         pWindow->UpdateScrollBar(true,
-                                 _IsAltBuffer() || gci.IsTerminalScrolling(),
+                                 _IsAltBuffer(),
                                  _viewport.Height(),
                                  gci.IsTerminalScrolling() ? _virtualBottom : buffer.BottomInclusive(),
                                  _viewport.Top());


Test patch: