Skip to content

Commit 7cad843

Browse files
Thomas Wolfmickaelistria
authored andcommitted
Bug 545846 - StyledText: wrong word selected on double-click
This resurrects Thomas Singer's commit cafa676, which had been reverted in commit 29806b6. Amend that code to not trigger if the mouse click occurs beyond the end of the line or on a whitespace character, so in those cases, the behavior is unchanged. Also keep the selection code the same so that it always first finds the start, then the end of the word. Also add tests for word selection on double click. This resolves the problem that led to the revert: {} block selections on double click didn't work anymore in Java and other editors. With this modification, they do. Word selection on double click in a pure SWT StyledText works, and double-click behavior in JFace-enhanced StyledTexts in SourceViewers with ICharacterPairMatchers is unchanged as far as I see. Change-Id: I38258c001576ebb2c43caa95d0e0dc32143a2928 Also-by: Thomas Singer <[email protected]> Signed-off-by: Thomas Wolf <[email protected]> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/183868 Tested-by: Platform Bot <[email protected]> Reviewed-by: Mickael Istria <[email protected]>
1 parent 039a261 commit 7cad843

File tree

2 files changed

+150
-1
lines changed

2 files changed

+150
-1
lines changed

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6337,8 +6337,16 @@ void handleMouseDown(Event event) {
63376337
int lineIndex = content.getLineAtOffset(offset);
63386338
int lineOffset = content.getOffsetAtLine(lineIndex);
63396339
if (wordSelect) {
6340+
String line = content.getLine(lineIndex);
6341+
int lineLength = line.length();
63406342
int min = blockSelection ? lineOffset : 0;
6341-
int max = blockSelection ? lineOffset + content.getLine(lineIndex).length() : content.getCharCount();
6343+
int max = blockSelection ? lineOffset + lineLength : content.getCharCount();
6344+
final Point offsetPoint = getPointAtOffset(offset);
6345+
if (event.x > offsetPoint.x
6346+
&& offset < Math.min(max, lineOffset + lineLength) // Not beyond EOL
6347+
&& !Character.isWhitespace(line.charAt(offset - lineOffset))) { // Not on whitespace
6348+
offset++;
6349+
}
63426350
int start = Math.max(min, getWordPrevious(offset, SWT.MOVEMENT_WORD_START));
63436351
int end = Math.min(max, getWordNext(start, SWT.MOVEMENT_WORD_END));
63446352
setSelection(new int[] {start, end - start }, false, true);

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5183,6 +5183,147 @@ public void test_doubleClickWithRightMouseButtonDoesNotSelectWord() {
51835183
assertEquals("", text.getSelectionText());
51845184
}
51855185

5186+
@Test
5187+
public void test_doubleClickAtStartOfWordSelectsNextWord() {
5188+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5189+
Point onW = text.getLocationAtOffset(6);
5190+
5191+
Event event = new Event();
5192+
event.button = 1;
5193+
event.count = 2;
5194+
event.x = onW.x + 1;
5195+
event.y = onW.y;
5196+
text.notifyListeners(SWT.MouseDown, event);
5197+
5198+
assertEquals("world", text.getSelectionText());
5199+
}
5200+
5201+
@Test
5202+
public void test_doubleClickAtEndOfWordSelectsCurrentWord() {
5203+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5204+
Point onWs = text.getLocationAtOffset(5);
5205+
5206+
Event event = new Event();
5207+
event.button = 1;
5208+
event.count = 2;
5209+
event.x = onWs.x - 1;
5210+
event.y = onWs.y;
5211+
text.notifyListeners(SWT.MouseDown, event);
5212+
5213+
assertEquals("Hello", text.getSelectionText());
5214+
}
5215+
5216+
@Test
5217+
public void test_doubleClickAtEndOfWordSelectsCurrentWord2() {
5218+
// Same as above, but at line end
5219+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5220+
Point onD = text.getLocationAtOffset(10);
5221+
5222+
Event event = new Event();
5223+
event.button = 1;
5224+
event.count = 2;
5225+
event.x = onD.x + 1;
5226+
event.y = onD.y;
5227+
text.notifyListeners(SWT.MouseDown, event);
5228+
5229+
assertEquals("world", text.getSelectionText());
5230+
}
5231+
5232+
@Test
5233+
public void test_doubleClickBetweenWordsSelectsPrevWord() {
5234+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5235+
Point onW = text.getLocationAtOffset(6);
5236+
Point onWs = text.getLocationAtOffset(5);
5237+
5238+
Event event = new Event();
5239+
event.button = 1;
5240+
event.count = 2;
5241+
event.x = (onWs.x + onW.x) / 2; // Middle of the blank before 'w'
5242+
event.y = onWs.y;
5243+
text.notifyListeners(SWT.MouseDown, event);
5244+
5245+
assertEquals("Hello", text.getSelectionText());
5246+
}
5247+
5248+
@Test
5249+
public void test_doubleClickJustBeforeNextWordSelectsPrevWord() {
5250+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5251+
Point onW = text.getLocationAtOffset(6);
5252+
5253+
Event event = new Event();
5254+
event.button = 1;
5255+
event.count = 2;
5256+
event.x = onW.x;
5257+
event.y = onW.y;
5258+
text.notifyListeners(SWT.MouseDown, event);
5259+
5260+
assertEquals("Hello", text.getSelectionText());
5261+
}
5262+
5263+
@Test
5264+
public void test_doubleClickBeyondEolSelectsLastWord() {
5265+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5266+
text.setSize(1000, 1000);
5267+
Point onD = text.getLocationAtOffset(10);
5268+
5269+
Event event = new Event();
5270+
event.button = 1;
5271+
event.count = 2;
5272+
event.x = Math.min(onD.x + 100, 999);
5273+
event.y = onD.y;
5274+
text.notifyListeners(SWT.MouseDown, event);
5275+
5276+
assertEquals("world", text.getSelectionText());
5277+
}
5278+
5279+
@Test
5280+
public void test_doubleClickBeyondEndOfTextSelectsLastWord() {
5281+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5282+
text.setSize(1000, 1000);
5283+
Point onE = text.getLocationAtOffset(text.getOffsetAtLine(1) + 6);
5284+
5285+
Event event = new Event();
5286+
event.button = 1;
5287+
event.count = 2;
5288+
event.x = Math.min(onE.x + 100, 999);
5289+
event.y = Math.min(onE.y + 100, 999);
5290+
text.notifyListeners(SWT.MouseDown, event);
5291+
5292+
assertEquals("bye", text.getSelectionText());
5293+
}
5294+
5295+
@Test
5296+
public void test_doubleClickAtStartOfWordLastLineNoEol() {
5297+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5298+
text.setSize(1000, 1000);
5299+
Point onB = text.getLocationAtOffset(text.getOffsetAtLine(1) + 4);
5300+
5301+
Event event = new Event();
5302+
event.button = 1;
5303+
event.count = 2;
5304+
event.x = onB.x + 1;
5305+
event.y = onB.y;
5306+
text.notifyListeners(SWT.MouseDown, event);
5307+
5308+
assertEquals("bye", text.getSelectionText());
5309+
}
5310+
5311+
@Test
5312+
public void test_doubleClickAtEndOfWordLastLineNoEol() {
5313+
text.setText("Hello world" + System.lineSeparator() + "Bye bye");
5314+
text.setSize(1000, 1000);
5315+
Point onB = text.getLocationAtOffset(text.getOffsetAtLine(1) + 6);
5316+
5317+
Event event = new Event();
5318+
event.button = 1;
5319+
event.count = 2;
5320+
event.x = onB.x + 1;
5321+
event.y = onB.y;
5322+
text.notifyListeners(SWT.MouseDown, event);
5323+
5324+
assertEquals("bye", text.getSelectionText());
5325+
}
5326+
51865327
@Test
51875328
public void test_doubleClickDoesNotSelectIfDoubleClickIsDisabled() {
51885329
text.setText("Test1 Test2");

0 commit comments

Comments
 (0)