Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
This fixes the negative delta scroll by correctly allowing for 16-bit to 32-bit sign extension by implicit type promotion.
References and Relevant Issues
#19484 #19391 (I might be wrong about the second one, but it looks similar since the thumb of the scrollbar is stuck on the top)
Detailed Description of the Pull Request / Additional comments
Hello!
After updating to the latest Windows Terminal Preview version, I've been experiencing an issue with the touchpad, when scrolling.
To be more precise, it started since v1.24.2682.0.
The issue happens only when scrolling down (that is to say when the thumb of the scrollbar should move down).
And, basically, it scrolls in reverse all the way up even with a minimum amount of scroll.
Scrolling up, instead, works as expected.
Given the premise, I decided to give it a chance and see if I could fix it.
I don't have the needed VS environment to compile the code, so I used a debugger (x64dbg) to adventure myself in this "quest".
After literally 3 hours of misplaced breakpoints I started to notice a pattern.
For starters the interesting code path is the
AppHost::_WindowMouseWheeledmethod.I'll add a visual screenshot diff between the Preview and Stable version and I'll try my best to explain in words what I discovered.
By the way, I made sure to scroll the same amount in both versions so they are easily comparable.
Screenshots
Windows Terminal Preview
Windows Terminal Stable
What's really interesting is the R8 register. It contains the delta scroll and it corresponds to the second parameter of the
_WindowMouseWheeledmethod.int32_tstored as 32-bit in the second half of the register.winrt::Microsoft::Terminal::Core::Pointwhich seems to be nicely packed into the R8 register as Y + X (32-bit + 32-bit, which is cool!).However, despite this, there's another important difference between the two versions: it's the sign part of the delta scroll.
In the Stable version it's correctly stored as a 32-bit signed integer, but in the Preview version it's stored as a 16-bit signed integer which is wrong, because it's going to be read as a 32-bit signed integer.
Basically:
0xFFFFFF58->-1680x0000FF58->65368In the Preview version it becomes a huge positive number and that's why the thumb of the scrollbar goes all the way up.
Just to be sure I tried to manually patch the R8 register to its correct value
FFFFFF5800000000and it works as expected.When looking at the source code and, specifically, the b53d7df commit, there's this code change to the
IslandWindow.cppfile which seems to be the source of the issue:I literally went by exclusion since that's where the param is set and nothing else happens in-between (there's also a
std::swap, but it's not really relevant).So I had an idea and I tried to write a really small C++ program to test the integer conversion. And, indeed, I could replicate the same issue.
I also mocked the
HIWORDmacro just to be sure I had a similar approach to that of the original code.Here's the snippet:
Code Snippet
I compiled the snippet with
gcc --pedantic --std=c++17 -Wall -O0 -o test main.cpp, but I suppose the same output should apply for Visual Studio.That being said, I think there are two potential approaches to fix the issue:
The first fix is much more verbose and it was the one I wanted to commit, just to be safe (since I can't really test the whole Terminal compilation).
The second one, which I ended up choosing, relies on the implicit type promotion, but it also should work (or at least I hope so!).
As a bonus, since I was already in the debugger rabbit hole, I wanted to see where the proper sign conversion happened in the Stable version and here it is:
Screenshot
Windows Terminal Stable
There's an intermediate function call where the
movsx eax, word ptr ds:[r8]instruction is used.Which is literally
Move with Sign-Extension. It takes the delta scroll from the stack to "fix" it intoeax.One last fun thing: if I enable the precision touchpad, in Windows settings, the issue doesn't happen at all.
That's because a completely different code path is executed, namely
TermControl::_MouseWheelHandler.I apologize for the long message considering the fix is really tiny!
Validation Steps Performed
Tested with a debugger and wrote a code snippet
PR Checklist