Skip to content
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

Wrong cursor position #2548

Closed
captainkovalsky opened this issue Jun 15, 2015 · 37 comments
Closed

Wrong cursor position #2548

captainkovalsky opened this issue Jun 15, 2015 · 37 comments

Comments

@captainkovalsky
Copy link

I've used ace library for formatting json.
I know that we must use monospaced fonts. I use "Consolas", but I've another bug, cusrsor is margined right from last letter
See screen
bug

Do you know how to fix this?

@nightwing
Copy link
Member

Try running

fm = editor.renderer.$textLayer.$fontMetrics;
"xiXbm".split("").map(fm.$measureCharWidth, fm)

if this prints different numbers then font used in the editor is not monospace.

Also note that adding a rule consolas !important is a bad idea since it will break on linux and mac.

@skbly7
Copy link

skbly7 commented Jun 22, 2015

I had got similar issue, and this css addition has fixed it. Might help...

.ace_editor, .ace_editor div{
    font-family:monospace
}

(Reason : As @nightwing has told. This addition of css would insure you are using monospace.)

@matthew-dean
Copy link

I have users seeing this problem on Windows 10 / Chrome 41.0.2272.76.

@nightwing When I ran that piece of code this was the output.

screen shot 2015-09-14 at 12 05 26 pm

This only seems to happen on Windows. Previously I found that cursor position was always wrong on Windows 8+ until I adjusted letter-spacing: #4794

However, my users are still seeing this occasionally. See screenshots here:
Crunch/Crunch-2#39

Does Ace use all CSS properties of the displayed line when measuring? Such as letter-spacing, text-shadow, text-rendering, -webkit-text-size-adjust, and -webkit-font-smoothing? (That is, does it use the computed style of the current font, as applied to the visible editor?) Or only certain ones?

@nightwing
Copy link
Member

@matthew-dean it requires all this properties to be customized on the editor root element, so stiles inherited by ace lines are inherited by the measure div too.
text-rendering:optimizeLegibility is not supported

@matthew-dean
Copy link

@nightwing text-rendering: optimizeLegibility might indeed be the culprit. It's the only thing I could think of that would offset a monospace differently, which has apparently been a problem, specifically in Chrome, specifically Chrome for Windows since Windows 7. See: foundation/foundation-sites#1827 (and other various bugs filed).

I'll try removing that setting, at least for the editor, to see if that changes. @vdzundza Since this is intermittent, I'd be interested to know if that works for you (and if you had that prop / value applied).

@matthew-dean
Copy link

I've changed that setting to text-rendering: geometricPrecision, which should be even more accurate at text character rendering. However, on Windows, it's still drawing the cursor position inaccurately. See more screenshots @ Crunch/Crunch-2#39

@nightwing
Copy link
Member

Could you give me demo page reproducing this issue, or maybe crunch-2 so that i can debug it?

@matthew-dean
Copy link

@nightwing You can get a copy of Crunch 2 here: https://github.com/Crunch/Crunch-2/releases

Then message me on Twitter: https://twitter.com/matthewdeaners. On NWJS, you can get to the Chrome developer tools, but there are a few steps involved for Crunch.

@matthew-dean
Copy link

@nightwing Any ideas? We're still having issues on Windows 10.

@nightwing
Copy link
Member

I couldn't reproduce this on windows 10, could you send me an image showing the issue?

@matthew-dean
Copy link

@nightwing There are several images, some animated to show what's happening, in this thread: Crunch/Crunch-2#39

@matthew-dean
Copy link

@nightwing I think now that this is the Hasklig font (https://github.com/i-tu/Hasklig) + Chromium 41 + text-rendering with either optimizeLegibility or geometricPrecision. Any setting that enables ligatures ends up rendering with inconsistent character widths. I tested it with long lines of ligatures, and by toggling text-rendering on / off, and the lines changed length. So, in my case, it's probably not an Ace issue, since Hasklig does not appear to technically be a monospace font in that environment. Sorry for the wild goose chase; I didn't realize the font was rendering non-monospace.

@matthew-dean
Copy link

Errrr... I may have spoken too soon. I'm having problems with cursor position with Source Code Pro as well, and text-rendering: optimizeLegibility is turned off. However, setting / unsetting text-rendering seems to "reset" cursor measuring, so sometimes you can't reproduce after the first time.

@matthew-dean
Copy link

Okay. So, I don't know exactly the cause, but I have a fix working for me. I am setting text-indent: 0.1px and then text-indent: 0.1px after a short timeout. This triggers layout / paint / composite as noted here: http://csstriggers.com/

@nightwing One reason you haven't encountered this might be because setting an ace theme probably causes a layout / paint / composite in most cases, if any of the "inherent" font settings of the browser don't match the font settings of the theme, which seems likely. Chrome's first paint of a text line might be inaccurate, meaning Ace's measurements would be too, but as long as someone sets even one CSS property that triggers re-layout, no one would ever notice.

So, if you want to reproduce, you could test with some font settings set only in the CSS, and not in a theme, but I'm not sure what the magic combination might be to get the bug reproduced. It's also possible Ace might be able to detect this bug by measuring a particular line of text with particular CSS and comparing it against a known constant (what the result should be), and then if it doesn't match, triggering a repaint in the same manner. (But of course that would mean reproducing the bug in the first place.)

One other thing you could do is have Ace always set a (late) CSS property regardless that would always trigger layout / repaint. (I tried to figure out something that wouldn't be visibly seen, but I'm not sure what that might be.) As far as I can tell, there's no noticeable performance hit from doing this once, which is all you should need.

@kenlimmj
Copy link

kenlimmj commented Jan 3, 2016

I've encountered the exact problem and managed to fix it (for my case).

I was running a function on the output from Ace to extract YAML front matter. Said function runs on Ace's onChange event. When my function threw errors, the cursor started to desynchronize. Contrary to another similar problem in which the cursors go out of sync permanently, this one 'recovers', because if I select-all and delete everything, and start writing without the function throwing any errors, the cursor is positioned correctly.

Not sure if I'm being clear enough, or if it helps in any way, but I suspect that any kind of interruption to the code flow surrounding Ace causes the cursor position to not get updated correctly (ergo the cursor position is updated after certain things are executed, and if those fail, cursor positioning fails?).

@nightwing
Copy link
Member

@kenlimmj throwing error from event listeners will break the editor, since other listeners won't be called.
editor.on("input", might be a better event for what you are doing.

@gaviral
Copy link

gaviral commented Feb 9, 2018

Same problem.

Screenshot:
image

@nightwing
Copy link
Member

@AviralGarg1993 you need to use monospace font.

@gaviral
Copy link

gaviral commented Feb 9, 2018

@wislem
Copy link

wislem commented Mar 20, 2018

For anyone else having this problem, this might help:

If you have a font-size set in rem (like in Bootstrap 4), your cursor would be wacky.
Setting a font size of 12px solved my problem:

.ace_editor .ace_content {
  font-size: 12px !important;
}

@Laithmiehiar
Copy link

Laithmiehiar commented Apr 12, 2018

Basically Ace can display only 'monospace' fonts, you might change the font somehow or you were assign font namein css.
if you are working in firefox there's a default font will change your monospace font. so be aware of that.

@mjaverto
Copy link

mjaverto commented May 16, 2018

@wislem's advice didn't work for me but put me on the right track.

I suspect using this in a global stylesheet would fix all problems regardless of framework. The base problem of using font-size in rem was the same core problem though.

.ace_editor div, .ace_editor span { font-size: 12px !important; }

@pranavq212
Copy link

pranavq212 commented Jun 13, 2018

Ace editor seems to be working with monospace font only. As stated by @skbly7 solution can be applying font-family:monospace but adding !important will prevent overriden by other css applied after words on elements.

.ace_editor, .ace_text-input, .ace_editor div{
    font-family : monospace !important;
}

@matthew-dean
Copy link

I'm building a new site using Ace for Less.js and this is still an issue, with nothing else on the page except for 2 editors. Going to try my old text-indent: 0.1px hack.

@matthew-dean
Copy link

matthew-dean commented Jul 22, 2018

This time these were the default styles in a Vue project that were the culprit:

html {
  word-spacing: 1px;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
}

The Ace default styles should probably reset those settings.

@blurymind
Copy link

blurymind commented Sep 13, 2019

This seems to be an old problem with Ace editor, especially obvious when you paste some text in non-english

My assumption is that some crazy code here is causing it

this.scrollCursorIntoView = function(cursor, offset, $viewMargin) {

try with
Встре́ча с медве́дем мо́жет быть о́чень опа́сна. Ру́сские лю́ди лю́бят ходи́ть в лес и собира́ть грибы́ и я́годы. Они́ де́лают э́то с осторо́жностью, так как медве́ди то́же о́чень лю́бят я́годы и мо́гут напа́сть на челове́ка. Медве́дь ест всё: я́годы, ры́бу, мя́со и да́же насеко́мых. Осо́бенно он лю́бит мёд.

instead of picking weird fonts, dont you want to fix the cause instead? This is not an issue in monaco editor

You havent fixed the cursor issue yet. It's very much still in there and I don't think the problem is the css. It's the crazy cursor logic

var pos = this.$cursorLayer.getPixelPosition(cursor);

and especially

this.screenToTextCoordinates = function(x, y) {

this.textToScreenCoordinates = function(row, column) {

the X coordinate is off!
this affects the gutters too. font width is not taken into consideration at all

or maybe

this.getPixelPosition = function(position, onScreen) {

I am kind of on the verge of refactoring my app to use monaco instead, but also wondering if this can be fixed

even when I set to monospaced font in russian, the issue is still there

@blurymind
Copy link

blurymind commented Sep 13, 2019

One temporary solution for this monospace font hell is to include a monospace font with ace editor that covers all languages, not just russian

I think there is another problem with the pasting of formatted text into ace editor messing up the cursor position. Ace is not sanitising it

@matthew-dean
Copy link

@blurymind I think the long and short is the algorithm for estimating cursor position is terribly naive about how fonts are rendered in a browser engine. So rather than measure how characters are actually drawn, it seem to estimate what they "should be" based on some basic CSS settings and maybe the size of a single character, and assumes the metrics should hold for the rest of the text? I'm not sure what assumptions are being made but they seem to be inherently flawed.

You can't really know where the end of a rendered text block is without getting its actual metrics. I'm not sure what the correct algorithm is, but it seems that because this is so easy to break, however they're reasoning about cursor position and text width is fundamentally flawed.

@xRy-42
Copy link

xRy-42 commented Oct 7, 2019

In my case it only happened after typing "ff" or "fi"...For me turning off ligatures worked.
So just add
.ace_editor, .ace_editor div { font-variant-ligatures: none !important; }
to the css.

Hope it helps ;)

@Copainbig
Copy link

Hi,
weird situation here but I can confirm that the font is not the single issue.
On my project I have a component using Ace editor to input JSON. It always forces font to be "monospace".
Anyway, it works smoothly on Storybook when isolated.
When the component inherits from CSS (when used in the app, not in storybook), I sill have the same issue of malfunctioning cursor.
There are a lot of inherited styles, but the font is monospace.

@nightwing
Copy link
Member

@Copainbig other css rules may interfere as well, e.g. setting font-size for all div elements

@WinHGGG
Copy link

WinHGGG commented Sep 26, 2020

I'm using mediawiki + chrome and encountered the same error.

Problem solved by using

.ace_editor, .ace_editor * { font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", monospace !important; font-size: 12px !important; font-weight: 400 !important; letter-spacing: 0 !important; }

in Mediawiki:Common.css

@Jaagrav
Copy link

Jaagrav commented Nov 9, 2020

@skbly7 I was facing this problem, looks like in the previous version of Ace Editor, your solution worked however for me it didn't.

Here's the solution you were looking for,

.ace_editor * {
    font-family: monospace !important;
}

All you need to know

So apparently you cannot really use some other font when using an ace editor. It's going to mess up a lot of UX for your code editor or whatsoever you might be working on where you're probably trying to implement ace editor. So in case you face this problem in the future, you can use the above stated code in order to get rid of this shitty problem because it's a bitch to solve. And no it wasn't a javascript error it was just a css error/bug due to which it wasn't working the way it was supposed to.

@CeoFred
Copy link

CeoFred commented Nov 24, 2020

.ace_editor, .ace_editor * { font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", monospace !important; font-size: 12px !important; font-weight: 400 !important; letter-spacing: 0 !important; }

works just fine for me, on windows10 using the react ace package

@RayL1991
Copy link

I found for me is the style of the span element.
There was a code that changing the Line-height of the span. because the ace editore set every single word in a span so that was causing the problem of the position.
you can check your style of span, set it to default, or change span to another element.

@ZeroXiphYT
Copy link

If you use chrome(I only know how to do this in chrome) you can go to chrome://settings/ then go to appearance then customize fonts then scroll down to Fixed-width font and select monospace and then it should work, I was facing this problem too but this fixed it for me

@whazor
Copy link
Contributor

whazor commented Feb 28, 2023

This is the same issue as #460 and the recommended workarounds in this issue are advising to use a fixed width font. I am closing this issue as resolving #460 would also resolve this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests