Bug 562676 - StyledText support muliple carets and selection
Summary: StyledText support muliple carets and selection
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.16   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 4.21   Edit
Assignee: Mickael Istria CLA
QA Contact:
URL:
Whiteboard:
Keywords: noteworthy
Depends on: 562677 574886 577737
Blocks: 574616 466532
  Show dependency tree
 
Reported: 2020-04-30 17:05 EDT by Mickael Istria CLA
Modified: 2022-03-18 09:46 EDT (History)
11 users (show)

See Also:


Attachments
Steps to run into error (2.01 MB, video/mp4)
2021-07-03 07:15 EDT, Andrey Loskutov CLA
no flags Details
Broken selection ranges (1.56 MB, video/mp4)
2021-07-07 04:19 EDT, Andrey Loskutov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mickael Istria CLA 2020-04-30 17:05:55 EDT
See bug Bug 466532 for initial story.
In order to support multiple selection in Text Editors, we first need the SWT StyledText to properly deal with multiple selections.
A patch already adds API and code for it: https://git.eclipse.org/r/#/c/154419/ . however, there are still some glitches to deal with before this can be released. Specific issues are added as "Depends on".
Comment 2 Niraj Modi CLA 2021-07-02 06:02:12 EDT
(In reply to Eclipse Genie from comment #1)
> Gerrit change
> https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/154419 was
> merged to [master].
> Commit:
> http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/
> ?id=398bbd8af1b74bbc8f14d6035a44331b0cdeef79

Thanks Mickael for this enhancement.
Please plan to add an N&N entry for this.
Comment 3 Eclipse Genie CLA 2021-07-02 07:58:47 EDT
New Gerrit change created: https://git.eclipse.org/r/c/www.eclipse.org/eclipse/news/+/182701
Comment 5 Andrey Loskutov CLA 2021-07-03 03:45:34 EDT
The latest changes probably caused some regression or uncovered previously hidden issue.

I've got exception below originating from changed code (StyledText.updateCaretVisibility()) while selecting different files of a commit in git history view, where the diff should be shown:

java.lang.ArrayIndexOutOfBoundsException: Index 32 out of bounds for length 32
	at org.eclipse.swt.custom.StyledTextRenderer.getLineSize(StyledTextRenderer.java:312)
	at org.eclipse.swt.custom.StyledTextRenderer.getLineHeight(StyledTextRenderer.java:676)
	at org.eclipse.swt.custom.StyledTextRenderer.getLineHeight(StyledTextRenderer.java:673)
	at org.eclipse.swt.custom.StyledText.getLineIndex(StyledText.java:4414)
	at org.eclipse.swt.custom.StyledText.getPartialBottomIndex(StyledText.java:4730)
	at org.eclipse.swt.custom.StyledText.redraw(StyledText.java:7769)
	at org.eclipse.swt.custom.StyledText.updateCaretVisibility(StyledText.java:11201)
	at org.eclipse.swt.custom.StyledText.setCaretLocations(StyledText.java:8978)
	at org.eclipse.swt.custom.StyledText.setCaretLocations(StyledText.java:8872)
	at org.eclipse.swt.custom.StyledText.setCaretOffsets(StyledText.java:9027)
	at org.eclipse.swt.custom.StyledText.reset(StyledText.java:8222)
	at org.eclipse.swt.custom.StyledText.setContent(StyledText.java:9089)
	at org.eclipse.jface.text.TextViewer.initializeWidgetContents(TextViewer.java:3374)
	at org.eclipse.jface.text.TextViewer.setVisibleDocument(TextViewer.java:3416)
	at org.eclipse.jface.text.source.projection.ProjectionViewer.setVisibleDocument(ProjectionViewer.java:694)
	at org.eclipse.jface.text.TextViewer.setDocument(TextViewer.java:2805)
	at org.eclipse.jface.text.source.SourceViewer.setDocument(SourceViewer.java:663)
	at org.eclipse.jface.text.source.projection.ProjectionViewer.setDocument(ProjectionViewer.java:368)
	at org.eclipse.jface.text.source.SourceViewer.setDocument(SourceViewer.java:603)
	at org.eclipse.egit.ui.internal.history.GitHistoryPage$9$1.runInUIThread(GitHistoryPage.java:2832)
Comment 6 Mickael Istria CLA 2021-07-03 06:41:33 EDT
Thanks Andrey.
Can you please provide some more details about how to reproduce the issue? An example of a Git repo to use, and a commit and file to look at in history would be welcome.
Comment 7 Andrey Loskutov CLA 2021-07-03 06:45:46 EDT
(In reply to Mickael Istria from comment #6)
> Thanks Andrey.
> Can you please provide some more details about how to reproduce the issue?
> An example of a Git repo to use, and a commit and file to look at in history
> would be welcome.

Sorry, I've checked few commits / files, and didn't noticed which one was it.
Comment 8 Mickael Istria CLA 2021-07-03 06:55:19 EDT
(In reply to Andrey Loskutov from comment #7)
> Sorry, I've checked few commits / files, and didn't noticed which one was it.

OK. Do you remember about the repository?
Also, do I get it right that the failing widget seems to be the commit viewer on the left pane of the "Git History" view?
Comment 9 Andrey Loskutov CLA 2021-07-03 07:15:08 EDT
Created attachment 286721 [details]
Steps to run into error

(In reply to Mickael Istria from comment #8)
> (In reply to Andrey Loskutov from comment #7)
> > Sorry, I've checked few commits / files, and didn't noticed which one was it.
> 
> OK. Do you remember about the repository?
> Also, do I get it right that the failing widget seems to be the commit
> viewer on the left pane of the "Git History" view?

OK, I've tried to force the error and it seem to be easy:

Just select commit 398bbd8af1b74bbc8f14d6035a44331b0cdeef79 (for this bug) in the history view (originally I was in JDT core on one of not yet pushed patches).

Click on a file in the files section on the right side.
Scroll to the diff section on the left side.
Select some text there.
Click on the next file on the right side.
Kaboom.
Comment 10 Andrey Loskutov CLA 2021-07-03 07:16:19 EDT
Note, I'm using latest SDK & EGit nightly builds available today.
Comment 11 Andrey Loskutov CLA 2021-07-03 07:52:33 EDT
BTW, the SWT error marker in my video is the API tooling error:

List of compatible changes:
- The non-abstract method org.eclipse.swt.custom.StyledText.
 setSelectionRanges(int[]) has been added

Please fix that too.
Comment 12 Eclipse Genie CLA 2021-07-03 09:28:08 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182737
Comment 13 Mickael Istria CLA 2021-07-03 09:34:00 EDT
(In reply to Andrey Loskutov from comment #9)
> Just select commit 398bbd8af1b74bbc8f14d6035a44331b0cdeef79 (for this bug)
> in the history view (originally I was in JDT core on one of not yet pushed
> patches).
> 
> Click on a file in the files section on the right side.
> Scroll to the diff section on the left side.
> Select some text there.
> Click on the next file on the right side.
> Kaboom.

Thanks, I can easily reproduce. I was missng the part about selecting text.
I'll fix it next week.
Comment 14 Eclipse Genie CLA 2021-07-05 01:58:36 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt.binaries/+/182744
Comment 17 Eclipse Genie CLA 2021-07-05 07:48:48 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182760
Comment 18 Andrey Loskutov CLA 2021-07-05 08:26:31 EDT
Here is another related stack I've found today in the log, looks like "Java Stack Trace" console is affected too (in this case that was a "paste" into the console):

Caused by: java.lang.IllegalArgumentException: Index out of bounds
	at org.eclipse.swt.SWT.error(SWT.java:4874)
	at org.eclipse.swt.SWT.error(SWT.java:4808)
	at org.eclipse.swt.SWT.error(SWT.java:4779)
	at org.eclipse.swt.graphics.TextLayout._getOffset(TextLayout.java:1196)
	at org.eclipse.swt.graphics.TextLayout.getPreviousOffset(TextLayout.java:1401)
	at org.eclipse.swt.custom.StyledText.getPointAtOffset(StyledText.java:5686)
	at java.base/java.util.stream.IntPipeline$1$1.accept(IntPipeline.java:180)
	at java.base/java.util.Spliterators$IntArraySpliterator.forEachRemaining(Spliterators.java:1032)
	at java.base/java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:699)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:550)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517)
	at org.eclipse.swt.custom.StyledText.setCaretLocations(StyledText.java:8871)
	at org.eclipse.swt.custom.StyledText.showCaret(StyledText.java:11132)
	at org.eclipse.swt.custom.StyledText.modifyContent(StyledText.java:7596)
	at org.eclipse.swt.custom.StyledText.sendKeyEvent(StyledText.java:8464)
	at org.eclipse.swt.custom.StyledText.paste(StyledText.java:7654)
	at org.eclipse.jface.text.TextViewer.paste(TextViewer.java:3932)
	at org.eclipse.jface.text.TextViewer.doOperation(TextViewer.java:3863)
	at org.eclipse.jface.text.source.SourceViewer.doOperation(SourceViewer.java:1064)
	at org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsoleViewer.doOperation(JavaStackTraceConsoleViewer.java:70)
	at org.eclipse.ui.console.actions.TextViewerAction.run(TextViewerAction.java:71)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:474)
	at org.eclipse.jface.commands.ActionHandler.execute(ActionHandler.java:121)
	... 55 more
Comment 19 Mickael Istria CLA 2021-07-05 17:34:22 EDT
(In reply to Andrey Loskutov from comment #9)
> Just select commit 398bbd8af1b74bbc8f14d6035a44331b0cdeef79 (for this bug)
> in the history view (originally I was in JDT core on one of not yet pushed
> patches).
> 
> Click on a file in the files section on the right side.
> Scroll to the diff section on the left side.
> Select some text there.
> Click on the next file on the right side.
> Kaboom.

This one should be tested/fixed with https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182760 (to be merged soon, after code freeze probably)

(In reply to Andrey Loskutov from comment #18)
> Caused by: java.lang.IllegalArgumentException: Index out of bounds
> 	at org.eclipse.swt.SWT.error(SWT.java:4874)
> 	at org.eclipse.swt.SWT.error(SWT.java:4808)
> 	at org.eclipse.swt.SWT.error(SWT.java:4779)
> 	at org.eclipse.swt.graphics.TextLayout._getOffset(TextLayout.java:1196)
> 	at
> org.eclipse.swt.graphics.TextLayout.getPreviousOffset(TextLayout.java:1401)
> 	at org.eclipse.swt.custom.StyledText.getPointAtOffset(StyledText.java:5686)
> 	at java.base/java.util.stream.IntPipeline$1$1.accept(IntPipeline.java:180)
> 	at
> java.base/java.util.Spliterators$IntArraySpliterator.
> forEachRemaining(Spliterators.java:1032)
> 	at
> java.base/java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:699)
> 	at
> java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:
> 484)
> 	at
> java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.
> java:474)
> 	at
> java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:
> 550)
> 	at
> java.base/java.util.stream.AbstractPipeline.
> evaluateToArrayNode(AbstractPipeline.java:260)
> 	at
> java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:
> 517)
> 	at org.eclipse.swt.custom.StyledText.setCaretLocations(StyledText.java:8871)
> 	at org.eclipse.swt.custom.StyledText.showCaret(StyledText.java:11132)
> 	at org.eclipse.swt.custom.StyledText.modifyContent(StyledText.java:7596)
> 	at org.eclipse.swt.custom.StyledText.sendKeyEvent(StyledText.java:8464)
> 	at org.eclipse.swt.custom.StyledText.paste(StyledText.java:7654)
> 	at org.eclipse.jface.text.TextViewer.paste(TextViewer.java:3932)
> 	at org.eclipse.jface.text.TextViewer.doOperation(TextViewer.java:3863)
> 	at
> org.eclipse.jface.text.source.SourceViewer.doOperation(SourceViewer.java:
> 1064)
> 	at
> org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsoleViewer.
> doOperation(JavaStackTraceConsoleViewer.java:70)
> 	at
> org.eclipse.ui.console.actions.TextViewerAction.run(TextViewerAction.java:71)
> 	at org.eclipse.jface.action.Action.runWithEvent(Action.java:474)
> 	at org.eclipse.jface.commands.ActionHandler.execute(ActionHandler.java:121)
> 	... 55 more

This one I couldn't reproduce. Any precondition you have in mind? Or some steps to reproduce?
Comment 20 Andrey Loskutov CLA 2021-07-06 00:47:07 EDT
(In reply to Mickael Istria from comment #19)
> This one should be tested/fixed with
> https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182760 (to be
> merged soon, after code freeze probably)

Why not for M1? This is quite a regression. 

> This one I couldn't reproduce. Any precondition you have in mind? Or some
> steps to reproduce?

No. Try to play with pasting stack traces and "Format" - that is what I use all the time.
Comment 22 Andrey Loskutov CLA 2021-07-07 04:19:31 EDT
Created attachment 286744 [details]
Broken selection ranges

I see another big issue: text selection ranges (start & end) are now changed during mouse moving.

Click anywhere in the code and start to select text while holding left mouse button. It can easily happen that start selection offset will change during this, resulting in selection containing completely unrelated text.

This must be fixed!
Comment 23 Mickael Istria CLA 2021-07-07 05:02:02 EDT
(In reply to Andrey Loskutov from comment #22)
> Created attachment 286744 [details]
> Broken selection ranges
> 
> I see another big issue: text selection ranges (start & end) are now changed
> during mouse moving.
> 
> Click anywhere in the code and start to select text while holding left mouse
> button. It can easily happen that start selection offset will change during
> this, resulting in selection containing completely unrelated text.

Thanks for the report and video.
I can reproduce it, this is indeed a regression caused by the multi-selection support. Some piece of code that takes care of keeping track of whether caret is at the beginning or end of the selection seems broken.
I'm looking at it.
Comment 24 Eclipse Genie CLA 2021-07-07 10:07:44 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182855
Comment 25 Andrey Loskutov CLA 2021-07-08 09:16:31 EDT
(In reply to Mickael Istria from comment #23)
> Thanks for the report and video.
> I can reproduce it, this is indeed a regression caused by the
> multi-selection support. Some piece of code that takes care of keeping track
> of whether caret is at the beginning or end of the selection seems broken.
> I'm looking at it.

Mickael, any update? Selecting code is a pain now, I (with my trackball) permanently manage to select more then one line now while selecting *one* line with the mouse...
Comment 26 Mickael Istria CLA 2021-07-08 10:27:35 EDT
(In reply to Andrey Loskutov from comment #25)
> (In reply to Mickael Istria from comment #23)
> Mickael, any update?

Yes, I managed to capture the bug in an automated test (see last Gerrit). I think I'll be able to submit a good fix soon, but cannot really commit I'll have it ready before end of week.

> Selecting code is a pain now, I (with my trackball)
> permanently manage to select more then one line now while selecting *one*
> line with the mouse...

It's not only with mouse, it can be reproduced with keyboard, or even API, It's really the selection modification that seems tp have lost the check for left-to-right/right-to-left to decide which end of the range must stay.
Comment 27 Sarika Sinha CLA 2021-07-08 14:05:39 EDT
@Mickael, 
Can we revert this for M1?
Comment 28 Eclipse Genie CLA 2021-07-08 15:02:46 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182914
Comment 29 Andrey Loskutov CLA 2021-07-08 15:04:00 EDT
(In reply to Sarika Sinha from comment #27)
> @Mickael, 
> Can we revert this for M1?

The revert patch is:  https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182914
Comment 31 Eclipse Genie CLA 2021-07-12 11:48:41 EDT
New Gerrit change created: https://git.eclipse.org/r/c/www.eclipse.org/eclipse/news/+/182528
Comment 33 Eclipse Genie CLA 2021-07-12 13:57:37 EDT
New Gerrit change created: https://git.eclipse.org/r/c/www.eclipse.org/eclipse/news/+/182529
Comment 36 Mickael Istria CLA 2021-07-12 17:36:54 EDT
All known regressions seem to be fixed.
Comment 37 Christoph Kaser CLA 2021-12-10 03:35:03 EST
This change introduced a regression: the caret column does not persist when it is moved from the end of a long line to a short one and back again.

** Steps to reproduce ** 

Open a text editor (I reproduced it in the java editor).

Enter the following text:

a very very very long line
a short line

Position the caret at the end of line 1, press "cursor down", then "cursor up" on your keyboard.

** Observed behavior **
The caret is now in the middle of line 1.

** Expected behavior **
The caret should be at the end of line 1.
This was the behavior before this change, which was accomplished by storing the previous caret position in "StyledText.columnX". However, with this change, columnX is no longer read in 
https://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/bundles/org.eclipse.swt/Eclipse%20SWT%20Custom%20Widgets/common/org/eclipse/swt/custom/StyledText.java?id=4e0d3cef45c6b6512666f9d51e8154ed545bc57b#n2701
nor in
https://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/bundles/org.eclipse.swt/Eclipse%20SWT%20Custom%20Widgets/common/org/eclipse/swt/custom/StyledText.java?id=4e0d3cef45c6b6512666f9d51e8154ed545bc57b#n2805


Should I create a new bug for this regression?
Comment 38 Mickael Istria CLA 2021-12-10 04:09:44 EST
(In reply to ChristophK from comment #37)
> Should I create a new bug for this regression?

Yes please.