[LyX/master] Fix preedit's caret position on boundary

Koji Yokota <[email protected]>
Newsgroups gmane.editors.lyx.cvs
Message-ID <[email protected]>
commit 89fc1a286cd9d8367d1c5270e0f2db9c1688c1c1
Author: Koji Yokota <[email protected]>
Date:   Wed Apr 22 18:42:34 2026 +0900

    Fix preedit's caret position on boundary
    
    This fixes the position of the preedit caret when the real cursor is
    on boundary.
---
 src/frontends/qt/GuiInputMethod.cpp | 26 ++++++++++++++++++--------
 src/frontends/qt/GuiInputMethod.h   |  1 +
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/src/frontends/qt/GuiInputMethod.cpp b/src/frontends/qt/GuiInputMethod.cpp
index b78bc37d32..654a4af573 100644
--- a/src/frontends/qt/GuiInputMethod.cpp
+++ b/src/frontends/qt/GuiInputMethod.cpp
@@ -826,9 +826,8 @@ std::array<int,2> GuiInputMethod::setCaretOffset(pos_type caret_pos)
 	// vertical offset only applicable to main text
 	caret_offset[1] = 0;
 	for (pos_type i = d->cur_row_idx_ +
-	     (d->real_boundary_ && !d->im_state_.composing_mode_);
-	     i < caret_row.index +
-	     (d->real_boundary_ && d->im_state_.composing_mode_); ++i)
+	                  (d->real_boundary_ && !d->im_state_.composing_mode_);
+	     i < caret_row.index; ++i)
 		caret_offset[1] += d->rows_[i].descent() + d->rows_[i+1].ascent();
 
 	return caret_offset;
@@ -1269,19 +1268,29 @@ GuiInputMethod::PreeditRow GuiInputMethod::getCaretInfo()
 {
 	// the virtual boundary case has the real cusor on the second row of
 	// the preedit inputs
+
+	// row index of the preedit's second row in a paragraph (rows)
 	const pos_type second_row_idx =
 	        d->cur_row_idx_ + 1 + d->real_boundary_ - d->virtual_boundary_;
 
+	LASSERT(d->cur_row_idx_ < (pos_type)d->rows_size_ &&
+	        d->cur_row_idx_ >= 0, return {});
+
 	// accumulate the length of preedit elements within d->rows_[d->cur_row_idx_]
 	// the length of str is used since preedits has zero widths (pos == endpos)
 	// second_row_pos is only useful when preedit string goes over two rows
-	LASSERT(d->cur_row_idx_ < (pos_type)d->rows_size_ &&
-	        d->cur_row_idx_ >= 0, return {});
+
+	// character position of the start of the second row
+	pos_type second_row_pos;
+	// row index as is visual on screen (+1 to d->cur_row_idx_ on boundary)
+	pos_type const & visual_row_idx_ = d->cur_row_idx_ + d->real_boundary_;
+	// first row as is visual on screen
+	Row & first_row = d->rows_[visual_row_idx_];
 	Row::const_iterator begin =
-	        d->rows_[d->cur_row_idx_].findElement(d->cur_pos_, false);
-	pos_type second_row_pos = d->cur_pos_;
+	        first_row.findElement(d->cur_pos_, false);
+	second_row_pos = d->cur_pos_;
 	for (Row::const_iterator eit = begin;
-	     eit < d->rows_[d->cur_row_idx_].end(); ++eit)
+	     eit < d->rows_[visual_row_idx_].end(); ++eit)
 		second_row_pos += eit->str.length();
 
 	PreeditRow caret_row{};
@@ -1291,6 +1300,7 @@ GuiInputMethod::PreeditRow GuiInputMethod::getCaretInfo()
 	// below is the starting point to calculate caret_row.pos
 	caret_row.pos = (d->real_boundary_ && !d->im_state_.composing_mode_) ?
 	            d->cur_pos_ : second_row_pos;
+	LASSERT(caret_row.pos >= 0, return {});
 
 	// if the preedit caret is on the second row or later, count the second row
 	caret_row.index = d->caret_pos_ > second_row_pos ?
diff --git a/src/frontends/qt/GuiInputMethod.h b/src/frontends/qt/GuiInputMethod.h
index 88fd541392..8104107821 100644
--- a/src/frontends/qt/GuiInputMethod.h
+++ b/src/frontends/qt/GuiInputMethod.h
@@ -58,6 +58,7 @@ public:
 		QString ruby_;
 	};
 
+	/// pair of row's \p index and its first char \p pos in a paragraph
 	struct PreeditRow {
 		pos_type pos;
 		pos_type index;
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.