From: Jürgen Spitzmüller Date: Mon, 17 Dec 2007 18:13:02 +0000 (+0000) Subject: * fix bug 4055, overdue patch from Stefan Schimanski: X-Git-Tag: 1.6.10~6892 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=8672364e1e1f0e082678d0cf0f03e7e84c99d35d;p=lyx.git * fix bug 4055, overdue patch from Stefan Schimanski: "The idea of the beforeDispX/Y_ variables in the Cursor is to hold the position of the cursor on screen before the lyxfunc is dispatched. But to get this the metrics must be valid. It's updated in Cursor::dispatch before the dispatch loop. After inserting/deleting stuff (like when deleting the selected text before inserting the alpha) the metrics are invalid. But the handler for the alpha calls Cursor::dispatch after the deletion and hence the crash with your second patch. Here is a patch fixing that: The beforeDispatchXY variable do not belong into the Cursor::dispatch because Cursor::dispatch is often called "manually" by many handlers to some followup action. So this logic must go somewhere else where it is sure that is not updated after the metrics got invalidated." git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22193 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/Cursor.cpp b/src/Cursor.cpp index a1a078df0a..4552983b55 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -296,7 +296,6 @@ void Cursor::dispatch(FuncRequest const & cmd0) Cursor safe = *this; // store some values to be used inside of the handlers - getPos(beforeDispX_, beforeDispY_); beforeDispatchCursor_ = *this; for (; depth(); pop()) { LYXERR(Debug::DEBUG, "Cursor::dispatch: cmd: " @@ -1074,8 +1073,8 @@ bool Cursor::upDownInMath(bool up) int xo = 0; int yo = 0; getPos(xo, yo); - xo = beforeDispX_; - + xo = theLyXFunc().cursorBeforeDispatchX(); + // check if we had something else in mind, if not, this is the future // target if (x_target_ == -1) @@ -1124,8 +1123,9 @@ bool Cursor::upDownInMath(bool up) int x; int y; getPos(x, y); - if ((!up && y <= beforeDispY_) || - (up && y >= beforeDispY_)) + int oy = theLyXFunc().cursorBeforeDispatchY(); + if ((!up && y <= oy) || + (up && y >= oy)) operator=(old); else return true; @@ -1144,8 +1144,9 @@ bool Cursor::upDownInMath(bool up) int x; int y; getPos(x, y); - if ((!up && y <= beforeDispY_) || - (up && y >= beforeDispY_)) + int oy = theLyXFunc().cursorBeforeDispatchY(); + if ((!up && y <= oy) || + (up && y >= oy)) operator=(old); else return true; @@ -1167,8 +1168,9 @@ bool Cursor::upDownInMath(bool up) //lyxerr << "updown: popBackward succeeded" << endl; int xnew; int ynew; + int yold = theLyXFunc().cursorBeforeDispatchY(); getPos(xnew, ynew); - if (up ? ynew < beforeDispY_ : ynew > beforeDispY_) + if (up ? ynew < yold : ynew > yold) return true; } @@ -1186,8 +1188,8 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded) int xo = 0; int yo = 0; getPos(xo, yo); - xo = beforeDispX_; - + xo = theLyXFunc().cursorBeforeDispatchX(); + // update the targetX - this is here before the "return false" // to set a new target which can be used by InsetTexts above // if we cannot move up/down inside this inset anymore diff --git a/src/Cursor.h b/src/Cursor.h index ba269f806d..d75891b7ef 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -254,10 +254,6 @@ private: // of a big inset spanning a whole row and computing coordinates for // displaying the cursor. bool logicalpos_; - /// x position before dispatch started - int beforeDispX_; - /// y position before dispatch started - int beforeDispY_; /// position before dispatch started DocIterator beforeDispatchCursor_; diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index 4e1f808c74..d4536dbc70 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -1764,6 +1764,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // Let the current Cursor dispatch its own actions. BOOST_ASSERT(lyx_view_->view()); + view()->cursor().getPos(cursorPosBeforeDispatchX_, + cursorPosBeforeDispatchY_); view()->cursor().dispatch(cmd); updateFlags = view()->cursor().result().update(); if (!view()->cursor().result().dispatched()) diff --git a/src/LyXFunc.h b/src/LyXFunc.h index 5914c53c66..3a0dd617db 100644 --- a/src/LyXFunc.h +++ b/src/LyXFunc.h @@ -91,6 +91,15 @@ public: Buffer * loadAndViewFile(support::FileName const & name, ///< File to load. bool tolastfiles = true); ///< append to the "Open recent" menu? + /// cursor x position before dispatch started + int cursorBeforeDispatchX() const { + return cursorPosBeforeDispatchX_; + } + /// cursor y position before dispatch started + int cursorBeforeDispatchY() const { + return cursorPosBeforeDispatchY_; + } + private: /// BufferView * view() const; @@ -108,6 +117,10 @@ private: /// KeyModifier meta_fake_bit; + /// cursor position before dispatch started + int cursorPosBeforeDispatchX_; + int cursorPosBeforeDispatchY_; + /// Error status, only Dispatch can change this flag mutable bool errorstat; diff --git a/src/Text3.cpp b/src/Text3.cpp index bd0e67eec5..da8b11a834 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -1450,12 +1450,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MATH_MATRIX: case LFUN_MATH_DELIM: case LFUN_MATH_BIGDELIM: { - if (cur.selection()) - cur.clearSelection(); - // FIXME: instead of the above, this one - // should be used (but it asserts with Bidi enabled) - // cf. http://bugzilla.lyx.org/show_bug.cgi?id=4055 - // cap::replaceSelection(cur); + cap::replaceSelection(cur); cur.insert(new InsetMathHull(hullSimple)); checkAndActivateInset(cur, true); BOOST_ASSERT(cur.inMathed());