Skip to content

Commit da9fb81

Browse files
committed
Merge pull request #89556 from smntic/single-char
Fix words not being selected by endpoints
2 parents eb9fcf8 + 899bb9e commit da9fb81

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

scene/gui/text_edit.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8407,7 +8407,7 @@ void TextEdit::_update_selection_mode_word(bool p_initial) {
84078407
int end = beg;
84088408
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
84098409
for (int i = 0; i < words.size(); i = i + 2) {
8410-
if ((words[i] < caret_pos && words[i + 1] > caret_pos) || (i == words.size() - 2 && caret_pos == words[i + 1])) {
8410+
if ((p_initial && words[i] <= caret_pos && words[i + 1] >= caret_pos) || (!p_initial && words[i] < caret_pos && words[i + 1] > caret_pos)) {
84118411
beg = words[i];
84128412
end = words[i + 1];
84138413
break;
@@ -8426,7 +8426,10 @@ void TextEdit::_update_selection_mode_word(bool p_initial) {
84268426
int origin_col = is_new_selection_dir_right ? carets[caret_index].selection.word_begin_column : carets[caret_index].selection.word_end_column;
84278427
int caret_col = is_new_selection_dir_right ? end : beg;
84288428

8429-
select(origin_line, origin_col, line, caret_col, caret_index);
8429+
// Expand the word selection only if the caret is not at the start of the selection.
8430+
if (column != carets[caret_index].selection.word_begin_column || line != origin_line || carets[caret_index].selection.word_begin_column == carets[caret_index].selection.word_end_column) {
8431+
select(origin_line, origin_col, line, caret_col, caret_index);
8432+
}
84308433
}
84318434
adjust_viewport_to_caret(caret_index);
84328435

tests/scene/test_text_edit.h

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,30 +1869,43 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
18691869
CHECK(text_edit->get_caret_line() == 0);
18701870
CHECK(text_edit->get_caret_column() == 0);
18711871

1872-
// Can start word select mode when not on a word.
1872+
// Can select word from left endpoint.
1873+
SEND_GUI_DOUBLE_CLICK(text_edit->get_rect_at_line_column(0, 8).get_center() + Point2i(2, 0), Key::NONE);
1874+
CHECK(text_edit->has_selection());
1875+
CHECK(text_edit->get_selected_text() == "some");
1876+
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
1877+
CHECK(text_edit->get_caret_line() == 0);
1878+
CHECK(text_edit->get_caret_column() == 12);
1879+
CHECK(text_edit->get_selection_origin_line() == 0);
1880+
CHECK(text_edit->get_selection_origin_column() == 8);
1881+
1882+
// Can select word from right endpoint.
18731883
SEND_GUI_DOUBLE_CLICK(text_edit->get_rect_at_line_column(0, 12).get_center() + Point2i(2, 0), Key::NONE);
1884+
CHECK(text_edit->has_selection());
1885+
CHECK(text_edit->get_selected_text() == "some");
18741886
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
1875-
CHECK_FALSE(text_edit->has_selection());
18761887
CHECK(text_edit->get_caret_line() == 0);
18771888
CHECK(text_edit->get_caret_column() == 12);
1889+
CHECK(text_edit->get_selection_origin_line() == 0);
1890+
CHECK(text_edit->get_selection_origin_column() == 8);
18781891

18791892
SEND_GUI_MOUSE_MOTION_EVENT(text_edit->get_rect_at_line_column(1, 9).get_center(), MouseButtonMask::LEFT, Key::NONE);
18801893
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
18811894
CHECK(text_edit->has_selection());
1882-
CHECK(text_edit->get_selected_text() == " text\nfor selection");
1895+
CHECK(text_edit->get_selected_text() == "some text\nfor selection");
18831896
CHECK(text_edit->get_caret_line() == 1);
18841897
CHECK(text_edit->get_caret_column() == 13);
18851898
CHECK(text_edit->get_selection_origin_line() == 0);
1886-
CHECK(text_edit->get_selection_origin_column() == 12);
1899+
CHECK(text_edit->get_selection_origin_column() == 8);
18871900

18881901
SEND_GUI_MOUSE_MOTION_EVENT(text_edit->get_rect_at_line_column(0, 10).get_center(), MouseButtonMask::LEFT, Key::NONE);
18891902
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
18901903
CHECK(text_edit->has_selection());
18911904
CHECK(text_edit->get_selected_text() == "some");
18921905
CHECK(text_edit->get_caret_line() == 0);
1893-
CHECK(text_edit->get_caret_column() == 8);
1906+
CHECK(text_edit->get_caret_column() == 12);
18941907
CHECK(text_edit->get_selection_origin_line() == 0);
1895-
CHECK(text_edit->get_selection_origin_column() == 12);
1908+
CHECK(text_edit->get_selection_origin_column() == 8);
18961909

18971910
SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(text_edit->get_rect_at_line_column(0, 15).get_center(), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
18981911

@@ -1904,9 +1917,9 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
19041917
CHECK(text_edit->has_selection(0));
19051918
CHECK(text_edit->get_selected_text(0) == "some");
19061919
CHECK(text_edit->get_caret_line(0) == 0);
1907-
CHECK(text_edit->get_caret_column(0) == 8);
1920+
CHECK(text_edit->get_caret_column(0) == 12);
19081921
CHECK(text_edit->get_selection_origin_line(0) == 0);
1909-
CHECK(text_edit->get_selection_origin_column(0) == 12);
1922+
CHECK(text_edit->get_selection_origin_column(0) == 8);
19101923

19111924
CHECK(text_edit->has_selection(1));
19121925
CHECK(text_edit->get_selected_text(1) == "ele");
@@ -1921,11 +1934,11 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
19211934
SEND_GUI_DOUBLE_CLICK(text_edit->get_rect_at_line_column(1, 7).get_center() + Point2i(2, 0), Key::NONE | KeyModifierMask::SHIFT);
19221935
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
19231936
CHECK(text_edit->has_selection());
1924-
CHECK(text_edit->get_selected_text() == " text\nfor selection");
1937+
CHECK(text_edit->get_selected_text() == "some text\nfor selection");
19251938
CHECK(text_edit->get_caret_line() == 1);
19261939
CHECK(text_edit->get_caret_column() == 13);
19271940
CHECK(text_edit->get_selection_origin_line() == 0);
1928-
CHECK(text_edit->get_selection_origin_column() == 12);
1941+
CHECK(text_edit->get_selection_origin_column() == 8);
19291942

19301943
// Cannot select when disabled, but caret still moves to end of word.
19311944
text_edit->set_selecting_enabled(false);
@@ -1934,6 +1947,41 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
19341947
CHECK(text_edit->get_caret_line() == 1);
19351948
CHECK(text_edit->get_caret_column() == 3);
19361949
text_edit->set_selecting_enabled(true);
1950+
1951+
// Can start word select mode when not on a word.
1952+
text_edit->set_text("this is some text\nwith an extra space\n");
1953+
MessageQueue::get_singleton()->flush();
1954+
SEND_GUI_DOUBLE_CLICK(text_edit->get_rect_at_line_column(0, 8).get_center() + Point2i(2, 0), Key::NONE);
1955+
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
1956+
CHECK_FALSE(text_edit->has_selection());
1957+
CHECK(text_edit->get_caret_line() == 0);
1958+
CHECK(text_edit->get_caret_column() == 8);
1959+
1960+
SEND_GUI_MOUSE_MOTION_EVENT(text_edit->get_rect_at_line_column(1, 13).get_center(), MouseButtonMask::LEFT, Key::NONE);
1961+
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
1962+
CHECK(text_edit->has_selection());
1963+
CHECK(text_edit->get_selected_text() == " some text\nwith an extra");
1964+
CHECK(text_edit->get_caret_line() == 1);
1965+
CHECK(text_edit->get_caret_column() == 13);
1966+
CHECK(text_edit->get_selection_origin_line() == 0);
1967+
CHECK(text_edit->get_selection_origin_column() == 8);
1968+
1969+
// Can reverse selection direction without retaining previous selection.
1970+
SEND_GUI_MOUSE_MOTION_EVENT(text_edit->get_rect_at_line_column(0, 0).get_center(), MouseButtonMask::LEFT, Key::NONE);
1971+
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
1972+
CHECK(text_edit->has_selection());
1973+
CHECK(text_edit->get_selected_text() == "this is ");
1974+
CHECK(text_edit->get_caret_line() == 0);
1975+
CHECK(text_edit->get_caret_column() == 0);
1976+
CHECK(text_edit->get_selection_origin_line() == 0);
1977+
CHECK(text_edit->get_selection_origin_column() == 8);
1978+
1979+
// Can deselect by moving to initial selection point.
1980+
SEND_GUI_MOUSE_MOTION_EVENT(text_edit->get_rect_at_line_column(0, 8).get_center() + Point2i(2, 0), MouseButtonMask::LEFT, Key::NONE);
1981+
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
1982+
CHECK_FALSE(text_edit->has_selection());
1983+
CHECK(text_edit->get_caret_line() == 0);
1984+
CHECK(text_edit->get_caret_column() == 8);
19371985
}
19381986

19391987
SUBCASE("[TextEdit] mouse line select") {

0 commit comments

Comments
 (0)