Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 552014

Summary: [console] Input problem with fixed width console and IME
Product: [Eclipse Project] Platform Reporter: Paul Pazderski <paul-eclipse>
Component: DebugAssignee: Paul Pazderski <paul-eclipse>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: sarika.sinha
Version: 4.13   
Target Milestone: 4.14 M3   
Hardware: All   
OS: All   
See Also: https://git.eclipse.org/r/150921
https://git.eclipse.org/c/platform/eclipse.platform.debug.git/commit/?id=b61668507b32b353ea60da3fbd24bcbf7717afda
Whiteboard:
Bug Depends on:    
Bug Blocks: 552030    
Attachments:
Description Flags
IME at fixed console wrapping none

Description Paul Pazderski CLA 2019-10-10 18:32:37 EDT
An IME started at fixed width border in console leaves some unwanted characters.

How to reproduce:
 - Get a org.eclipse.ui.console plugin where bug 544970 is fixed (the old ConsoleDocumentAdapter implementation had much bigger problems with any input at fixed width border)
 - Start a console with fixed width enabled.
 - Fill the console so you can type at the fixed width border.
 - Place cursor at end/start of a line wrap and start an inline character composition (e.g. by typing Korean as described in bug 525966 comment 6)
 
Result: the first input of character composition remains in console and the inline composition is continued behind it. I.e. the IME is shifted one step while composing a character.

This problem arise from the way the fixed width console is implemented. Quote from bug 544970 comment 1:
> And now for the last - and by far worst - edge case. The fact that wrapped
> lines do not have separate line delimiters leads to problems with
> getLineAtOffset. Imagine a console with fixed with 10 and content "01234".
> getLineAtOffset(0) is 0 and getLineAtOffset(5) is also 0. Now expand the
> content to "0123456789". Still one non wrapped line and getLineCount returns
> 1. In this state getLineAtOffset(10) returns 0 and it can only be 0 as long
> as getLineCount says there is only one line. Now expand the content to
> "0123456789+". The '+' must be wrapped and since it is the 11th character
> (offset 10) and it is on the 2nd line getLineAtOffset(10) now must return 1
> for the same offset as before.
> 
> If you now remove the '+' we get a change event at offset 10 and as stated
> above getLineAtOffset returns different lines for this offset before and
> after the change. That is something StyledText does not expect and does not
> handle well. StyledText requires that the line where the change event starts
> is the same before and after the change.
> 
> I think it's impossible to solve this as long as the line wraps have no own
> offset (for usual line breaks you can address the line delimiter character).
> My solution is not to let this problematic situation happen ever. Every time
> a change starts at begin of a wrapped line the TextChangingEvent is
> calculated as if the previous character was also included in the change.
> Using the example above when removing the last '+' the document change event
> is [offset=10, length=1, text=""] but the event is changed for the
> calculation of the TextChangingEvent to [offset=9, length=2, text="9"].

So if a character composition is started at fixed width border the partial composed character is written to console but the ConsoleDocumentAdapter includes the previous character in the text change event. StyledText recognizes the content before the IME is changed and tries to updates the IME's position but does not notice the partial composed character itself is part of the text change.

I finally found a better workaround for this problem. I just need to lie a bit. StyledTextRenderer calculates the affected lines by asking for the line where change event starts and using the number of new and replaced lines (all before the change is applied). This can fail if line index for this same offset is not the same before and after change. The new workaround is to return (in this problematic situation) the line index it will have after the change already before the change is actually applied.

This also fix another minor problem arising from the old workaround. When console output is appended the caret position is not changed. But when caret is at fixed width border and output appended the caret moves after the output.
Comment 1 Eclipse Genie CLA 2019-10-10 18:33:38 EDT
New Gerrit change created: https://git.eclipse.org/r/150921
Comment 2 Sarika Sinha CLA 2019-10-11 03:06:02 EDT
@Paul,
Can you create a root enhancement for Console Improvements and mark all these bugs as children ?
We can have a N&N entry also for the overall summary.
Comment 3 Paul Pazderski CLA 2019-10-11 03:07:01 EDT
Will do. There are also a few more coming.
Comment 4 Paul Pazderski CLA 2019-10-11 07:22:42 EDT
Created attachment 280233 [details]
IME at fixed console wrapping

And by the way, if my description of the problem is hard to understand (and it might be some effort to reproduce) here is a screenshot showing the difference.