Hello Jean-Marc, > What may happen is that DecorationUpdate redraw is triggerred when > moving the mouse. In this case, the rows would be recretated and change > value. > > A way to avoid that would be to remember the position of the start of > the row (a cursor slice pointing at the first character of the row, > instead of a pointer to a row. This should be stable when the row is > redrawn. > > If you do not know how to do that, I'll take a look tomorrow. In the > meantime, look at the other problems (tabular inset, targetx...).
Yes, it seems like new row objects are created. I do not know how to get a CursorSlice that points the start character of a row. So I tried with the following, within the Cursor.cpp. &bottom() - This remains unchanged for the the entire document. So, no use. &top() - This changes when moving in to a math inset and a table inset and remains same within that inset. At all the other places of the document, remains same at a different value. The beginning and end positions are not belonging to the math inset or table inset, they having different value from when in the math inset. So, this value also changed within a row. So it is not suitable. So, for further testing I thought of a way to fix this bug temporary. So I came up with following method. (I have corrected according to your early patch and replaced this method as follows) Sorry for introducing early return again and moving left_edge calculations before setCurrentRow(). void checkCursorLeftEdge(PainterInfo & pi, Cursor const & cur, ScreenUpdateStrategy & strategy) { Bidi bidi; Row const & row = cur.bottomRow(); BufferView const & bv = cur.bv(); // Left edge value of the screen in pixels int left_edge = cur.getLeftEdge(); bool row_moved = false; // Set the row on which the cursor lives. cur.setCurrentRow(&row); // Force the recomputation of inset positions bool const drawing = pi.pain.isDrawingEnabled(); pi.pain.setDrawingEnabled(false); // No need to care about vertical position. RowPainter rp(pi, bv.buffer().text(), cur.bottom().pit(), row, bidi, 0, 0); rp.paintText(); pi.pain.setDrawingEnabled(drawing); if(left_edge != cur.getLeftEdge() && !cur.selectionEnd().inMathed()) return; // Current x position of the cursor in pixels int const cur_x = bv.getPos(cur).x_; // If need to slide right if (cur_x < left_edge + 10) { left_edge = cur_x - 10; row_moved = true; } // If need to slide left () else if (cur_x > left_edge + bv.workWidth() - 10) { left_edge = cur_x - bv.workWidth() + 10; row_moved = true; } if (strategy == NoScreenUpdate && (row_moved || cur.getPreviousRow())) { // FIXME: if one uses SingleParUpdate, then home/end // will not work on long rows. Why? LYXERR0("Strategy Change"); strategy = FullScreenUpdate;//DecorationUpdate;//FullScreenUpdate; } lyxerr << "Cursor row=" << cur.getCurrentRow() << ", strategy=" << strategy << ", prerow=" << cur.getPreviousRow() << ", left_edge=" << left_edge << endl; cur.setLeftEdge(left_edge); } However we need a proper mechanism to identify a particular row and set the code according to your early patch. I tried a lot to find a proper identifier, but failed. I checked the current implementation with too wide tables by commenting the content in void InsetTabular::resetPos(Cursor & cur) const. It seems to work with tables, but the proper behaviour seems to appearing with fullpaint updates. Encountered a new bug, When deleting the content of a too wide row using backspace, the row does not slide. Results is: https://dl.dropboxusercontent.com/u/105510128/Bug_4.webm Thank you Hashini