-
Notifications
You must be signed in to change notification settings - Fork 27.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cursor width changes randomly because window.zoomLevel interacts with system DPI settings. #28542
Comments
In all cases the primary cursor is "painted" as a AFAIK there is no possible code change we can do on our side to workaround this snapping / rounding-error quirks. I am thinking this is reproducible using Chrome at https://jsfiddle.net/b4hkeLew/ It is just a matter of playing with the left offset position until the snapping / rounding-error happens. |
@alexandrudima Interesting, that explains why there's no artifacts at 150% zoom (because it yields 3px exactly). And why there still are artifacts at 150% with "editor.cursorStyle": "line-thin". Look at this though: https://jsfiddle.net/655jcnmf/2/ when I specify 1.6px width (2 / 1.25), there's no width artifacts! So, if you could somehow determine OS DPI and also keep track of your own zoomLevel, you could pre-round line width based on that and use it everywhere. Or at least it would be nice if you exposed it as some sort of an advanced option. Because vscode is otherwise Literally Unplayable™ for me without tweaking anyway, and I'd prefer a tweaking option that reliably works with any zoomLevel (especially 0). |
I have been down this road only last week. The problem is that I could not come up with any formula that makes sense and uses the values I have at my disposal: Perhaps I am missing something obvious but here is what I observed on a mac book pro's built-in monitor:
|
I found this: https://chromium.googlesource.com/chromium/src.git/+/refs/heads/lkcr/content/common/page_zoom.cc And the formula there matches your observed zoomFactor perfectly and pixel values pretty close (if we assume a 2x factor coming from the device DPI or something): edit: and pixelRatio = zoomFactor * 2, except it's limited to a minimum of 0.5 (or 0.25 as per the linked code, with the 2x factor coming from somewhere else)
(also, this means that I was wrong about the way zoom works, and it worked for me both times accidentally, because edit2: also I checked, at least on JSFiddle window.devicePixelRatio shows 1.25 to me (at normal zoom), so it already takes into account system DPI, so I guess you can just go and use it? And ignore the maybe applied but maybe not cutoff at zoomFactor: -8. |
Thank you for looking and helping out with this. To sum up:
So we could programmatically set the cursor width with the following formula:
The idea is that we don't want to have the cursor be always 2 screen pixels. If the user zooms in at 200%, the cursor should be 4 screen pixels, or at least I think that's what we'd want. In your case it would be |
Sounds good. By the way, this function should also be used for drawing rulers (see #9634) and the newly enabled by default Indent Guides, they too are drawn with varying screen widths for me. |
Steps to Reproduce:
"window.zoomLevel": 0
, move the cursor around, observe it occasionally being twice as wide:This is more or less a duplicate of #22904, except the workaround there was to not use
window.zoomLevel
at all, while in my case I'm not using it, it's Chromium deciding to respect the OS setting in a way that breaks vscode rendering if I understand it correctly.Anyway, I want to add an actual work-around, two even.
Set
window.zoomLevel
to-1.25-1.2239 (edit: see below comments, that was close enough though) , this will negate the OS setting.The actual formula
seems to beactually it's 1.2 raised to the power of zoomLevel, positive or negative.-(OS_zoom - 100) / 20
: each negative point in zoomLevel decreases text size by 20%, in a sense of dividing text size by1 + 0.2 * zoomLevel
. So if we need to compensate for a 25% increase, we need -1.25 points, and for 50% it's -2.5 points.Or if you'd prefer a larger UI instead, you can set zoomLevel to 1, this gives you
1.25 * 1.2 = 1.5
combined zoom factor, which apparently doesn't produce the same artifacts.The text was updated successfully, but these errors were encountered: