]> git.lyx.org Git - lyx.git/blobdiff - src/Cursor.cpp
Fix crash on OS-switch of dark/light mode (#12786)
[lyx.git] / src / Cursor.cpp
index fae9d85c3f3c98bf743fc89592aa3e52b8fdf1eb..7afefcf372e3b7cd26558c69af60f8dd28ecf55d 100644 (file)
@@ -322,6 +322,7 @@ DocIterator CursorData::selectionEnd() const
        if (di.depth() > depth()) {
                di.resize(depth());
                ++di.pos();
+               di.boundary(true);
        }
        return di;
 }
@@ -1712,8 +1713,11 @@ void Cursor::handleNest(MathAtom const & a)
 {
        idx_type const idx = a.nucleus()->asNestInset()->firstIdx();
        //lyxerr << "Cursor::handleNest: " << idx << endl;
+       InsetMath const * im = selectionBegin().inset().asInsetMath();
+       Parse::flags const f = im && im->currentMode() != InsetMath::MATH_MODE
+               ? Parse::TEXTMODE : Parse::NORMAL;
        MathAtom t = a;
-       asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx));
+       asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx), f);
        insert(t);
        editInsertedInset();
 }
@@ -2037,20 +2041,39 @@ bool Cursor::mathForward(bool word)
                                        posForward();
                                while (pos() < lastpos() && mc == nextMath().mathClass());
                } else if (openable(nextAtom())) {
+                       InsetMathScript const * n = nextMath().asScriptInset();
+                       bool to_brace_deco = n && !n->nuc().empty()
+                               && n->nuc().back()->lyxCode() == MATH_DECORATION_CODE
+                               && n->nuc().back()->mathClass() == MC_OP;
                        // single step: try to enter the next inset
                        pushBackward(nextMath());
                        inset().idxFirst(*this);
+                       // Make sure the cursor moves directly to an
+                       // \overbrace or \underbrace inset (bug 2264)
+                       if (to_brace_deco) {
+                               pushBackward(nextMath());
+                               inset().idxFirst(*this);
+                       }
                } else
                        posForward();
                return true;
        }
        if (inset().idxForward(*this))
                return true;
+       InsetMath const * m = inset().asInsetMath();
+       bool from_brace_deco = m
+               && m->lyxCode() == MATH_DECORATION_CODE
+               && m->mathClass() == MC_OP;
        // try to pop forwards --- but don't pop out of math! leave that to
        // the FINISH lfuns
        int s = depth() - 2;
-       if (s >= 0 && operator[](s).inset().asInsetMath())
-               return popForward();
+       if (s >= 0 && operator[](s).inset().asInsetMath() && popForward()) {
+               // Make sure the cursor moves directly to an
+               // \overbrace or \underbrace inset (bug 2264)
+               bool to_script = inset().asInsetMath()
+                       && inset().asInsetMath()->asScriptInset();
+               return from_brace_deco && to_script ? mathForward(word) : true;
+       }
        return false;
 }
 
@@ -2072,21 +2095,41 @@ bool Cursor::mathBackward(bool word)
                                while (pos() > 0 && mc == prevMath().mathClass());
                        }
                } else if (openable(prevAtom())) {
+                       InsetMathScript const * p = prevMath().asScriptInset();
+                       bool to_brace_deco = p && !p->nuc().empty()
+                               && p->nuc().back()->lyxCode() == MATH_DECORATION_CODE
+                               && p->nuc().back()->mathClass() == MC_OP;
                        // single step: try to enter the preceding inset
                        posBackward();
                        push(nextMath());
                        inset().idxLast(*this);
+                       // Make sure the cursor moves directly to an
+                       // \overbrace or \underbrace inset (bug 2264)
+                       if (to_brace_deco) {
+                               posBackward();
+                               push(nextMath());
+                               inset().idxLast(*this);
+                       }
                } else
                        posBackward();
                return true;
        }
        if (inset().idxBackward(*this))
                return true;
+       InsetMath const * m = inset().asInsetMath();
+       bool from_brace_deco = m
+               && m->lyxCode() == MATH_DECORATION_CODE
+               && m->mathClass() == MC_OP;
        // try to pop backwards --- but don't pop out of math! leave that to
        // the FINISH lfuns
        int s = depth() - 2;
-       if (s >= 0 && operator[](s).inset().asInsetMath())
-               return popBackward();
+       if (s >= 0 && operator[](s).inset().asInsetMath() && popBackward()) {
+               // Make sure the cursor moves directly to an
+               // \overbrace or \underbrace inset (bug 2264)
+               bool to_script = inset().asInsetMath()
+                       && inset().asInsetMath()->asScriptInset();
+               return from_brace_deco && to_script ? mathBackward(word) : true;
+       }
        return false;
 }