diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 911331861d..b427f8cbed 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -322,6 +322,15 @@ void Cursor::dispatch(FuncRequest const & cmd0) // object will be used again. if (!disp_.dispatched()) { LYXERR(Debug::DEBUG, "RESTORING OLD CURSOR!"); + // We might have invalidated the cursor when removing an empty + // paragraph while the cursor could not be moved out the inset + // while we initially thought we could. This might happen when + // a multiline inset becomes an inline inset when the second + // paragraph is removed. + if (safe.pit() > safe.lastpit()) { + safe.pit() = safe.lastpit(); + safe.pos() = safe.lastpos(); + } operator=(safe); disp_.update(Update::None); disp_.dispatched(false); @@ -1790,9 +1799,35 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded) row = pm.pos2row(pos() - 1); else row = pm.pos2row(pos()); - - if (atFirstOrLastRow(up)) + + if (atFirstOrLastRow(up)) { + // Is there a place for the cursor to go ? If yes, we + // can execute the DEPM, otherwise we should keep the + // paragraph to host the cursor. + Cursor dummy = *this; + bool valid_destination = false; + for(; dummy.depth(); dummy.pop()) + if (!dummy.atFirstOrLastRow(up)) { + valid_destination = true; + break; + } + + // will a next dispatch follow and if there is a new + // dispatch will it move the cursor out ? + if (depth() > 1 && valid_destination) { + // The cursor hasn't changed yet. This happens when + // you e.g. move out of an inset. And to give the + // DEPM the possibility of doing something we must + // provide it with two different cursors. (Lgb, vfr) + dummy = *this; + dummy.pos() = dummy.pos() == 0 ? dummy.lastpos() : 0; + dummy.pit() = dummy.pit() == 0 ? dummy.lastpit() : 0; + + updateNeeded |= bv().checkDepm(dummy, *this); + updateTextTargetOffset(); + } return false; + } // with and without selection are handled differently if (!selection()) { diff --git a/src/Text3.cpp b/src/Text3.cpp index 4d861f83a4..721355ba94 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -569,6 +569,19 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) && cur.boundary() == oldBoundary) { cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_FORWARD); + + // we will probably be moving out the inset, so we should execute + // the depm-mechanism, but only when the cursor has a place to + // go outside this inset, i.e. in a slice above. + if (cur.depth() > 1 && cur.pos() == cur.lastpos() + && cur.pit() == cur.lastpit()) { + // The cursor hasn't changed yet. To give the + // DEPM the possibility of doing something we must + // provide it with two different cursors. + Cursor dummy = cur; + dummy.pos() = dummy.pit() = 0; + cur.bv().checkDepm(dummy, cur); + } } break; @@ -582,6 +595,19 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) && cur.boundary() == oldBoundary) { cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_BACKWARD); + + // we will probably be moving out the inset, so we should execute + // the depm-mechanism, but only when the cursor has a place to + // go outside this inset, i.e. in a slice above. + if (cur.depth() > 1 && cur.pos() == 0 && cur.pit() == 0) { + // The cursor hasn't changed yet. To give the + // DEPM the possibility of doing something we must + // provide it with two different cursors. + Cursor dummy = cur; + dummy.pos() = cur.lastpos(); + dummy.pit() = cur.lastpit(); + cur.bv().checkDepm(dummy, cur); + } } break; diff --git a/status.16x b/status.16x index d01badb771..cd0987362f 100644 --- a/status.16x +++ b/status.16x @@ -211,6 +211,8 @@ What's new - Do not open files during startup that were closed in the previous session by Close View or Close Window (bug 5458). +- Remove empty paragraphs and superfluous spaces when leaving an inset + (bug 5435). * DOCUMENTATION AND LOCALIZATION