Vscode: Smooth Scrolling not working on HiDPI displays if Display Scaling is higher than 100%

Created on 6 Oct 2017  ·  33Comments  ·  Source: microsoft/vscode

  • VSCode Version: Code 1.17.0 (be377c0faf7574a59f84940f593a6849f12e4de7, 2017-10-04T23:45:46.804Z)
  • OS Version: Windows_NT x64 10.0.15063
  • Extensions: none

Steps to Reproduce:

  1. set "editor.smoothScrolling": true
  2. close and re-open VS Code
  3. try scrolling the editor - it will jump as if "editor.smoothScrolling" were set to False

Reproduces without extensions: Yes (tried to launch with _code --disable-extensions_, same issue)

To be honest I don't know whether this is an issue related to this specific version as it's the first time I'm using VS Code.

My mouse is an MX Master and I'm using an ASUS N550 laptop.
Anybody else experiencing this issue?

Thanks

bug editor-scrollbar insiders-released linux trackpascroll verified windows

Most helpful comment

_UPDATE:_

My setup is a laptop with a second screen plugged in via HDMI.
The laptop screen scaling is set at 150%, while the external monitor scaling is set at 100%.

I've noticed that the smooth scrolling actually works on the external screen (100%) and it stops working as soon as I drag VScode on my laptop screen (150%). Once I drag it back to the external screen (100%) it works again.

Then if I change the laptop's scaling to 100%, it works on this too.

So the problem here seems to be the smooth scrolling not working with a scaling bigger than 100%. Why is that?

Scaling at 100%:

image

external monitor - 100

Scaling at 150%:

image

laptop - 150

All 33 comments

_UPDATE:_

My setup is a laptop with a second screen plugged in via HDMI.
The laptop screen scaling is set at 150%, while the external monitor scaling is set at 100%.

I've noticed that the smooth scrolling actually works on the external screen (100%) and it stops working as soon as I drag VScode on my laptop screen (150%). Once I drag it back to the external screen (100%) it works again.

Then if I change the laptop's scaling to 100%, it works on this too.

So the problem here seems to be the smooth scrolling not working with a scaling bigger than 100%. Why is that?

Scaling at 100%:

image

external monitor - 100

Scaling at 150%:

image

laptop - 150

@solid-pixel

The root problem is that we receive a mousewheel event both when scrolling using a touch pad and when scrolling using a physical mouse wheel.

There is no way (flag or anything really) on those events to distinguish a scroll that occurs on the touch pad vs. a scroll that occurs on a physical mouse wheel. We should not begin any form of smooth scrolling on our side when scrolling with the touchpad because the touchpad itself emits already smooth scrolling events, and us applying our animation on top of it results in subtle, weird, nausea-inducing scrolling.

We therefore have a MouseWheelClassifier which tries to classify a series of mousewheel events as ones coming from a touchpad vs ones coming from a physical mouse wheel.

I have recorded a set of mice and what sort of properties their mousewheel events contain, and so far, the only correlation I have seen is that events coming in from a physical mouse wheel have integer deltaX and deltaY, while events coming in from a touchpad do not.

That is what is implemented in _computeScore and in the tests at MouseWheelClassifier

My instinct is that, for you, the mousewheel events have integer values when Windows is configured at 100% scale and non-integer values when it is configured at 150% scale. Therefore, in the 150% case, our MouseWheelClassifier probably fails and believes the mousewheel events come in from a touch pad.

This is a very tricky problem, as we simply lack the needed information on the mousewheel event. I'm not sure how to tackle it, please let me know if you have any ideas.

Thanks @alexandrudima for taking the time to write down such a detailed explanation! Everything you said makes perfect sense.

I'm really sorry but unfortunately I lack the skills needed to come up with any idea. I just thought it would have been useful for the community to point this problem out.

Hopefully, one day, someone more skilled than me will be able to address this minor issue :)

Thank you!

have the same issue. Two monitors, one scaled to 125%, the other to 150%, smooth scrolling with mouse works on neither, unless i set scaling to 100%...

i also tried to override the scaling with compatibility setting - using "System ( Enhanced )" or "System" fixes the smooth scrolling issue, but in first case it downscales the whole window
screenshot 33

and in the second case it makes everything blurry

edit:
seems that starting vscode with "--force-device-scale-factor=1.0" is the best workaround. Fixes the smooth scrolling, without the need of setting compatibility scaling settings or changing DPI back to 100%. The interface can still be scaled with "window.zoomLevel"
the only downside is the small size of popup and dialog windows, but it's manageable

@alexandrudima

Parameter "editor.smoothScrolling" is disabled by default in settings and smooth scroll works perfectly with touchpad. Maybe add comment to use this parameter for mouse wheel only and force using smooth scrolling without checking scroll type?

Because all modern screens has big resolution and most people using screen scaling. And smooth scroll didn't work in this case. Playing with "--force-device-scale-factor=1.0" and "window.zoomLevel" works but small menus and dialogs looking terrible.

Any news on this issue?

There are a lot of users who will never use a touchpad to scroll in vscode. What about having a setting for those, so that smooth scrolling also works with 4k monitors?

Same problem experienced here 🙋‍♂️. Smooth when scaling is 100%, rigid when scaling is higher.

Probably should use the smooth scrolling experience that is used for Microsoft Word itself because it works on whatever scaling (maybe re-use the code or something? Idk).

just use --force-device-scale-factor=1.0 and scale with window.zoomLevel instead. Vscode now renders its own menus and popups, so everything gets scaled properly.

I see, interesting. Also, how will I launch Visual Studio Code with that setting? Through Command Prompt? If yes, is there a way to launch Visual Studio Code with that setting every single time without using command prompt (or any other command-line interface)?

UPDATE: Ok, so I know how to launch Visual Studio Code the way I want using flags, but... how do I make it so that it will run with that settings everytime Visual Studio Code is launched? I have a shortcut that targets the executable so... I have to go into the compatibility settings?

Any news on this? Trying the --force-device-scale-factor workaround while using a 4K monitor makes it almost unusable without zooming in, which is just inconvenient.

More and more Windows devices (laptops and desktops alike) have 1080p monitors, where 125% scaling is default, and is required (at least on laptops) to view elements (100% scaling is too small).

This is a bug which affects all laptops with 1080p screens by default. Surprisingly, the Extension pages scroll smoothly, just the actual text files and the Settings UI does not follow the smooth scrolling flag.

Any news on this? Adding flags to shortcuts is possible, but I think an option should be provided to do that within the UI itself as a workaround until this issue is fixed. This issue still persists in Version 1.36.1.

also the --force-device-scale-factor=1.0 workaround doesnt work for multiple displays with different DPI. And even then having to constantly switch back and forth when im either on my laptop or have an external monitor plugged in is annoying. Chrome/Chromium scrolls just fine with every DPI combination imaginable.

There is no way (flag or anything really) on those events to distinguish a scroll that occurs on the touch pad vs. a scroll that occurs on a physical mouse wheel. We should not begin any form of smooth scrolling on our side when scrolling with the touchpad because _the touchpad itself emits already smooth scrolling events_, and us applying our animation on top of it results in subtle, weird, nausea-inducing scrolling.

@alexandrudima Are you talking about Windows Precision touchpads only? I have a Lenovo Z50-70 which has a Synaptics touchpad. There is no smooth scrolling built into the touchpad and I've toggled all the available settings and seen no difference.

This is evident when I use apps like Notepad or Acrobat Reader DC, the scrolling is choppy, and it does not feel any different when I use my mouse, except that the mouse scroll wheel causes text to move in groups of 3 lines, while in touchpads it can be made to much more precisely (which is what I think you mean with lower values of deltaX and deltaY.)

@solid-pixel Is it possible to rename the post to something like "Smooth Scrolling does not work in HIDPI displays with display scaling > 100%"? The current title is kind of misleading and makes the issue seem like an obscure and specific issue, which it isn't.

@SubhamSatyajeet you're right, I've updated it. I didn't know in the beginning what caused it so that's why the generic title. Thanks for pointing that ou!

Using --force-device-scale-factor=2 requires me to change "window.zoomLevel": 0 to "window.zoomLevel": -1 in order to see the window as properly as before.
Since I share the same settings.json on different machines and different monitors, I wouldn't like the changed zoom property be applied to all my devices.

@alexandrudima Are you talking about Windows Precision touchpads only? I have a Lenovo Z50-70 which has a Synaptics touchpad. There is no smooth scrolling built into the touchpad and I've toggled all the available settings and seen no difference.

This is evident when I use apps like Notepad or Acrobat Reader DC, the scrolling is choppy, and it does not feel any different when I use my mouse, except that the mouse scroll wheel causes text to move in groups of 3 lines, while in touchpads it can be made to much more precisely (which is what I think you mean with lower values of deltaX and deltaY.)

This was my understanding as well. Yes, Logitech touchpads for example will have a separate option for 'smooth scrolling' which does indeed give an obnoxiously 'floaty' feel to apps which already incorporate it (such as any web browser), which is why I turn it off - and in that case, it's only available if the Logitech Options is installed and by default does not incorporate any additional smooth scrolling. I'm not aware by default any touchpad adding smooth scrolling out of the gate, but that may just be my limited experience with different vendors.

Regardless of the complexities, hopefully this can be resolved as using display scaling is exceedingly common now. The smooth scrolling is so much better, but unfortunately due to two 4K displays with 150% scaling I can't really take advantage of it.

@DaveACG I agree. This bug was reported about 3 years ago (!) and scrolling on my good old 1080p screen still causes the text to jump around. Hopefully this gets the attention of the developers.

Update: This issue persists in Visual Studio Code 1.38.1.
It affects Windows 10, Version 1903 and Ubuntu 19.04. This problem is not Windows-specific.

In Ubuntu 19.04, the problem occurs when font scaling is set to 1.25/any value other than 1.00. When the font scaling property is set to 1.00, the problem goes away. To verify the problem, the user can install Gnome Tweaks (package gnome-tweaks) and use it to change the font scaling.

我遇到了相同的问题,期待修复

@solid-pixel

The root problem is that we receive a mousewheel event both when scrolling using a touch pad and when scrolling using a physical mouse wheel.

There is no way (flag or anything really) on those events to distinguish a scroll that occurs on the touch pad vs. a scroll that occurs on a physical mouse wheel. We should not begin any form of smooth scrolling on our side when scrolling with the touchpad because the touchpad itself emits already smooth scrolling events, and us applying our animation on top of it results in subtle, weird, nausea-inducing scrolling.

We therefore have a MouseWheelClassifier which tries to classify a series of mousewheel events as ones coming from a touchpad vs ones coming from a physical mouse wheel.

I have recorded a set of mice and what sort of properties their mousewheel events contain, and so far, the only correlation I have seen is that events coming in from a physical mouse wheel have integer deltaX and deltaY, while events coming in from a touchpad do not.

That is what is implemented in _computeScore and in the tests at MouseWheelClassifier

My instinct is that, for you, the mousewheel events have integer values when Windows is configured at 100% scale and non-integer values when it is configured at 150% scale. Therefore, in the 150% case, our MouseWheelClassifier probably fails and believes the mousewheel events come in from a touch pad.

This is a very tricky problem, as we simply lack the needed information on the mousewheel event. I'm not sure how to tackle it, please let me know if you have any ideas.

Please correct me if I'm saying something really, really dumb, but if this is the only issue, wouldn't it be enough to replace this line with this.deltaY = (e1.wheelDeltaY / 120) / window.devicePixelRatio;?

Edit: any update on this, @alexdima?

I confirm that it affects Linux as well. Ubuntu 18.04 on ASUS ZenBook UX430UA here, Visual Studio Code installed from the official deb package. More information:

Version: 1.44.1
Commit: a9f8623ec050e5f0b44cc8ce8204a1455884749f
Date: 2020-04-13T14:40:29.529Z
Electron: 7.1.11
Chrome: 78.0.3904.130
Node.js: 12.8.1
V8: 7.8.279.23-electron.0
OS: Linux x64 4.15.0-96-generic

I am using Large Text, which is equal to 1.25 font scaling. Once I turn it off, the mouse scroll animation works properly. The touchpad scroll animation works properly in both cases.

Should I be of any help, feel free to let me know... :rocket: Unfortunately, I do not understand TypeScript... :smile:

Experiencing the same bug on a 4k screen. Windows 10

The bug should be fixed by applying the inverse of DPI scaling to mouse events per @alexdima's bug explanation. This is probably what @DamianoMagrini just said. Might need a little rounding to get crisp integers. I can't try it myself.

@JVimes yes, that's the idea. In the next few days (weeks, at most), I'll fork this repo and see if I can fix it myself. If so, I'll submit a PR.

@JVimes @DamianoMagrini
This actually works (Windows 10, 125% scaling).

For Windows: just replace this.deltaY=t.wheelDeltaY/120 in %LocalAppData%\Programs\Microsoft VS Code\resources\app\out\vs\workbench\workbench.desktop.main.js with this.deltaY=(t.wheelDeltaY/120)/window.devicePixelRatio as @DamianoMagrini suggested.

Thank you for this simple fix idea! @JVimes @DamianoMagrini @krlvm

@alexdima platform.isWindows would only detect Windows systems. Can the commit be improved to also include Linux platforms?

@alexdima platform.isWindows would only detect Windows systems. Can the commit be improved to also include Linux platforms?

The commit modified scrollableElement.ts, which listens StandardWheelEvent from mouseEvents.ts. Perhaps @alexdima had reasons to do not modify the root cause of the problem, because the real delta can be needed somewhere, for example, scrolling distance has become smaller for me after manual fix.

Indeed, this will have effect only on Windows systems, but the issue can be reproduced on other systems, including all Linux distributions and macOS. I can reproduce the issue right now on Ubuntu 20.04.

@alexdima, @DamianoMagrini fix works on Linux too (Ubuntu 20.04, 120 DPI, .deb package): replace this.deltaY=t.wheelDeltaY/120 in /usr/share/code/resources/app/out/vs/workbench/workbench.desktop.main.js with this.deltaY=(t.wheelDeltaY/120)/window.devicePixelRatio.
UPD: Seems it depends on window manager/desktop environment, doesn't work with xfce.

The fix should work on macOS too, not only on Windows and Linux.

@JVimes @DamianoMagrini
This actually works (Windows 10, 125% scaling).

For Windows: just replace this.deltaY=t.wheelDeltaY/120 in %LocalAppData%\Programs\Microsoft VS Code\resources\app\out\vs\workbench\workbench.desktop.main.js with this.deltaY=(t.wheelDeltaY/120)/window.devicePixelRatio as @DamianoMagrini suggested.

Thanks for the fix! However, with that fix in effect, I noticed that when I set the zoom setting (window.zoomLevel) in VS Code to some value that isn't 0 (yes, even a value of 0.01 stops smooth scrolling), the smooth scrolling is gone. I'm using the same scaling as what @krlvm used, which is 125%, and I'm using a mouse and not a trackpad.

Smooth Scroll and Scaling

Reopening since there are two problems left:

  • this change does not cover linux
  • The setting window.zoomLevel also affects window.devicePixelRatio, but it does not affect the deltaX / deltaY of mouse wheel events.

@alexdima

Taking about Linux (and, perhaps, macOS), I assume the problem is with floating-point numbers and scroll behavior on Linux. I did some research with GNOME, KDE and Xfce, and probably know how to fix it, I'll make a pull request:

| DPI Scaling | deltaY | devicePixelRatio | deltaY / devicePixelRatio |
| -------------- | ------- | --------------------------- | ----------- |
| 100% (96) | 53 | 1 | 53 |
| 125% (120) | 68.89999389648438 | 1.2999999523162842 | 52.999997249016296 |
| 150% (144) | 79.5 | 1.5 | 53 |
| 175% (168) | 95.39999389648438 | 1.7999999523162842 | 52.999998013178455 |
| 200% (192) | 106 | 2 | 53 |

I've submitted a pull request

One of the recent Insiders updates seems to have made the launch flag --force-device-scale-factor=1.0 trick (on Windows 10) no longer allow one to freely alter zoom levels while preserving smooth scrolling. Settings the factor to a multiple like 1.5 via the flag is a workaround, but any additional zoom level changes within vscode turn smoothscroll off.

Was this page helpful?
0 / 5 - 0 ratings