]> git.lyx.org Git - features.git/commitdiff
Fix bug 2195: Slowness in rendering inside insets, especially on the Mac
authorMartin Vermeer <martin.vermeer@hut.fi>
Fri, 10 Mar 2006 16:10:35 +0000 (16:10 +0000)
committerMartin Vermeer <martin.vermeer@hut.fi>
Fri, 10 Mar 2006 16:10:35 +0000 (16:10 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13328 a592a061-630c-0410-9148-cb99ea01b6c8

14 files changed:
src/BufferView.C
src/BufferView.h
src/BufferView_pimpl.C
src/BufferView_pimpl.h
src/ChangeLog
src/LyXAction.C
src/debug.C
src/debug.h
src/insets/ChangeLog
src/insets/insetcollapsable.C
src/insets/insettext.C
src/insets/insettext.h
src/rowpainter.C
src/text3.C

index 75544d062319dc9cb6f3d831b609f71f90ae4f23..d5160a74205274b997ceecacc2882329254a6197 100644 (file)
@@ -369,6 +369,18 @@ void BufferView::putSelectionAt(DocIterator const & cur,
 }
 
 
+bool const BufferView::repaintAll() const
+{ 
+       return pimpl_->repaintAll();
+}
+
+       
+void const BufferView::repaintAll(bool r) const
+{ 
+       pimpl_->repaintAll(r);
+}
+
+
 LCursor & BufferView::cursor()
 {
        return pimpl_->cursor_;
index 426e90a293d2d273f46d390b64374bc07020c540..2940d7758660adc54e47d477dbf2a9811a6951a8 100644 (file)
@@ -40,7 +40,8 @@ namespace Update {
        enum flags {
                FitCursor = 1,
                Force = 2,
-               SinglePar = 4
+               SinglePar = 4,
+               MultiParSel = 8
        };
 
 inline flags operator|(flags const f, flags const g)
@@ -198,7 +199,10 @@ public:
         */
        void putSelectionAt(DocIterator const & cur,
                int length, bool backwards);
-
+       ///
+       bool const repaintAll() const;
+       ///
+       void const repaintAll(bool r) const;
 
 private:
        ///
index 87bc17b337dc08f9d20164516d85a075869f9b52..776bb78c08623b8056f0e0afa82bb8233467a417 100644 (file)
@@ -658,6 +658,17 @@ bool BufferView::Pimpl::fitCursor()
 }
 
 
+bool BufferView::Pimpl::multiParSel()
+{
+       if (!cursor_.selection())
+               return false;
+       bool ret = multiparsel_cache_;
+       multiparsel_cache_ = cursor_.selBegin().pit() != cursor_.selEnd().pit();
+       // Either this, or previous selection spans paragraphs
+       return ret || multiparsel_cache_;
+}
+
+
 void BufferView::Pimpl::update(Update::flags flags)
 {
        lyxerr[Debug::DEBUG]
@@ -682,12 +693,16 @@ void BufferView::Pimpl::update(Update::flags flags)
 
                // First drawing step
                ViewMetricsInfo vi = metrics(flags & Update::SinglePar);
-               bool forceupdate(flags & Update::Force);
+               bool forceupdate(flags & (Update::Force | Update::SinglePar));
 
                if ((flags & Update::FitCursor) && fitCursor()) {
                        forceupdate = true;
                        vi = metrics();
                }
+               if ((flags & Update::MultiParSel) && multiParSel()) {
+                       forceupdate = true;
+                       vi = metrics();
+               }
                if (forceupdate) {
                        // Second drawing step
                        screen().redraw(*bv_, vi);
@@ -989,7 +1004,7 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
                if (cur.result().update())
                        update(Update::FitCursor | Update::Force);
                else
-                       update();
+                       update(Update::FitCursor | Update::MultiParSel);
        }
 
        // See workAreaKeyPress
index b55cf924e27bcc0e73c52ba1ef0e44f893a0da0e..c6ac78f6f7af61561e1dd911ede071772871df26 100644 (file)
@@ -59,6 +59,8 @@ public:
        void resizeCurrentBuffer();
        //
        bool fitCursor();
+       //
+       bool multiParSel();
        ///
        void update(Update::flags flags = Update::Force);
        ///
@@ -103,6 +105,10 @@ public:
        FuncStatus getStatus(FuncRequest const & cmd);
        /// a function should be executed
        bool dispatch(FuncRequest const & ev);
+       /// Flag: do a full redraw of inside text of inset
+       bool repaintAll() { return refresh_inside_; }
+       ///
+       void repaintAll(bool r) {refresh_inside_ = r; }
 private:
        /// An error list (replaces the error insets)
        ErrorList errorlist_;
@@ -183,13 +189,15 @@ private:
        ///
        LCursor cursor_;
        ///
+       bool multiparsel_cache_;
        ///
        lyx::pit_type anchor_ref_;
        ///
        int offset_ref_;
        ///
        ViewMetricsInfo metrics(bool singlepar = false);
-
-
+       /// Working variable indicating a full screen refresh
+       mutable bool refresh_inside_;
+       
 };
 #endif // BUFFERVIEW_PIMPL_H
index 760a4b65f332a94723f5442b89dfddcd05665a38..5b32b815d876a02c7d246d31709f340a836b6311 100644 (file)
@@ -1,3 +1,12 @@
+2006-03-10  Martin Vermeer  <martin.vermeer@hut.fi>
+
+       * BufferView.[Ch]:
+        * BufferView_pimpl.[Ch]: 
+       * LyXAction.C:
+       * debug.[Ch]:
+       * rowpainter.C:
+       * text3.C: Inside-inset speedup, esp. for the Mac (bug 2195)
+
 2006-03-07  Georg Baum  <Georg.Baum@post.rwth-aachen.de>
 
        * pch.h: fix nullstream.hpp location for boost 1.33.0
index 9c98b95881f240a21594b5be70ce639512bc289e..911bef3d4c1354b551fb5b6372d24ece45ac460f 100644 (file)
@@ -97,7 +97,7 @@ void LyXAction::init()
                { LFUN_UNDERBAR, "accent-underbar", Noop },
                { LFUN_UNDERDOT, "accent-underdot", Noop },
                { LFUN_APPENDIX, "appendix", Noop },
-               { LFUN_LEFTSEL, "backward-select", ReadOnly },
+               { LFUN_LEFTSEL, "backward-select", ReadOnly | SingleParUpdate },
                { LFUN_BOOKMARK_GOTO, "bookmark-goto", ReadOnly },
                { LFUN_BOOKMARK_SAVE, "bookmark-save", ReadOnly },
                { LFUN_BREAKLINE, "break-line", Noop },
@@ -143,8 +143,8 @@ void LyXAction::init()
                { LFUN_DEPTH_MIN, "depth-decrement", Noop },
                { LFUN_DEPTH_PLUS, "depth-increment", Noop },
                { LFUN_LDOTS, "dots-insert", Noop },
-               { LFUN_DOWN, "down", ReadOnly | NoUpdate},
-               { LFUN_DOWNSEL, "down-select", ReadOnly },
+               { LFUN_DOWN, "down", ReadOnly | NoUpdate },
+               { LFUN_DOWNSEL, "down-select", ReadOnly | SingleParUpdate },
                { LFUN_DROP_LAYOUTS_CHOICE, "drop-layouts-choice", ReadOnly },
                { LFUN_END_OF_SENTENCE, "end-of-sentence-period-insert", Noop },
                { LFUN_ENVIRONMENT_INSERT, "environment-insert", Noop },
@@ -173,7 +173,7 @@ void LyXAction::init()
                { LFUN_FONT_STATE, "font-state", ReadOnly },
                { LFUN_UNDERLINE, "font-underline", Noop },
                { LFUN_INSET_FOOTNOTE, "footnote-insert", Noop },
-               { LFUN_RIGHTSEL, "forward-select", ReadOnly },
+               { LFUN_RIGHTSEL, "forward-select", ReadOnly | SingleParUpdate },
                { LFUN_HFILL, "hfill-insert", Noop },
                { LFUN_HELP_OPEN, "help-open", NoBuffer | Argument},
                { LFUN_HTMLURL, "html-insert", Noop },
@@ -198,10 +198,10 @@ void LyXAction::init()
                { LFUN_LAYOUT_PARAGRAPH, "layout-paragraph", ReadOnly },
                { LFUN_LAYOUT_TABULAR, "layout-tabular", Noop },
                { LFUN_HOME, "line-begin", ReadOnly | NoUpdate},
-               { LFUN_HOMESEL, "line-begin-select", ReadOnly },
+               { LFUN_HOMESEL, "line-begin-select", ReadOnly | SingleParUpdate },
                { LFUN_DELETE_LINE_FORWARD, "line-delete-forward", Noop },
                { LFUN_END, "line-end", ReadOnly | NoUpdate},
-               { LFUN_ENDSEL, "line-end-select", ReadOnly },
+               { LFUN_ENDSEL, "line-end-select", ReadOnly | SingleParUpdate },
 #if 0
                { LFUN_INSET_LIST, "list-insert", Noop },
 #endif
@@ -283,7 +283,7 @@ void LyXAction::init()
                { LFUN_TOGGLECURSORFOLLOW, "toggle-cursor-follows-scrollbar", ReadOnly },
                { LFUN_UNDO, "undo", Noop },
                { LFUN_UP, "up", ReadOnly | NoUpdate},
-               { LFUN_UPSEL, "up-select", ReadOnly },
+               { LFUN_UPSEL, "up-select", ReadOnly | SingleParUpdate },
                { LFUN_URL, "url-insert", Noop },
                { LFUN_VC_CHECKIN, "vc-check-in", ReadOnly },
                { LFUN_VC_CHECKOUT, "vc-check-out", ReadOnly },
@@ -291,14 +291,14 @@ void LyXAction::init()
                { LFUN_VC_REVERT, "vc-revert", ReadOnly },
                { LFUN_VC_UNDO, "vc-undo-last", ReadOnly },
                { LFUN_WORDLEFT, "word-backward", ReadOnly | NoUpdate},
-               { LFUN_WORDLEFTSEL, "word-backward-select", ReadOnly },
+               { LFUN_WORDLEFTSEL, "word-backward-select", ReadOnly | SingleParUpdate },
                { LFUN_CAPITALIZE_WORD, "word-capitalize", Noop },
                { LFUN_DELETE_WORD_BACKWARD, "word-delete-backward", Noop },
                { LFUN_DELETE_WORD_FORWARD, "word-delete-forward", Noop },
                { LFUN_WORDFINDBACKWARD, "word-find-backward", ReadOnly },
                { LFUN_WORDFINDFORWARD, "word-find-forward", ReadOnly },
                { LFUN_WORDRIGHT, "word-forward", ReadOnly | NoUpdate},
-               { LFUN_WORDRIGHTSEL, "word-forward-select", ReadOnly },
+               { LFUN_WORDRIGHTSEL, "word-forward-select", ReadOnly | SingleParUpdate },
                { LFUN_LOWCASE_WORD, "word-lowcase", Noop },
                { LFUN_WORDSEL, "word-select", ReadOnly },
                { LFUN_UPCASE_WORD, "word-upcase", Noop },
@@ -348,7 +348,7 @@ void LyXAction::init()
                { LFUN_FINISHED_UP, "", ReadOnly },
                { LFUN_FINISHED_DOWN, "", ReadOnly },
                { LFUN_MOUSE_PRESS, "", ReadOnly },
-               { LFUN_MOUSE_MOTION, "", ReadOnly },
+               { LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate },
                { LFUN_MOUSE_RELEASE, "", ReadOnly },
                { LFUN_MOUSE_DOUBLE, "", ReadOnly },
                { LFUN_MOUSE_TRIPLE, "", ReadOnly },
index 24977bc1b88a17dfe5eb83a8a822fa603d839345..2b4badfcfabc86a6175d55a892d596b174911f25 100644 (file)
@@ -63,6 +63,7 @@ error_item errorTags[] = {
        { Debug::GRAPHICS,  "graphics",  N_("Graphics conversion and loading")},
        { Debug::CHANGES,   "changes",   N_("Change tracking")},
        { Debug::EXTERNAL,  "external",  N_("External template/inset messages")},
+       { Debug::PAINTING,  "painting",  N_("RowPainter profiling")},
        { Debug::DEBUG,     "debug",     N_("Developers' general debug messages")},
        { Debug::ANY,       "any",       N_("All debugging messages")}
 };
index af7b04067e08b20c66e9dd7f6fa18cfe8e4dc012..c338b7a228edea93633a38dad9508acc0a301148 100644 (file)
@@ -74,6 +74,8 @@ public:
                ///
                EXTERNAL   = (1 << 23),
                ///
+               PAINTING   = (1 << 24),
+               ///
                DEBUG      = (1 << 31),
                ///
                ANY = 0xffffffff
index 6c79f3a4d6b06bd99ab041c7545ef0e943c18b8f..7bf7d9691309fa56287a05eabdfa9471221f3397 100644 (file)
@@ -1,4 +1,8 @@
-2005-02-25  Martin Vermeer  <martin.vermeer@hut.fi>
+2005-03-10  Martin Vermeer  <martin.vermeer@hut.fi>
+
+       * insetcollapsable.C:
+       * insettext.[Ch]: Inside-inset speedup, esp. for the Mac (bug 2195)
+
 2006-02-25  Georg Baum  <Georg.Baum@post.rwth-aachen.de>
 
        * insetert.[Ch] (read): new, force all paragraphs to latex_language
index 11b02bb1d2ec8ea154d7b57d51967ad2f766898f..02a6b375dbf9f6ef6dafa0230462f8eda29a46ca 100644 (file)
@@ -138,7 +138,7 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
                dim = dimensionCollapsed();
                if (status() == Open) {
                        InsetText::metrics(mi, textdim_);
-                       openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth);
+                       openinlined_ = textdim_.wid + 2 * dim.wid <= mi.base.textwidth;
                        if (openinlined_) {
                                dim.wid += textdim_.wid;
                                dim.des = max(dim.des - textdim_.asc + dim.asc, textdim_.des);
@@ -171,6 +171,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
                button_dim.y2 = top + dimc.height();
 
                pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_);
+
                if (status() == Open) {
                        int textx, texty;
                        if (openinlined_) {
index 99ff0b318646cfa0a6a19ee5667ff65c15f7fb13..bd02ffcc4a92ce79b4475641f17f4968b2d80c0b 100644 (file)
@@ -200,6 +200,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
        // update our idea of where we are
        setPosCache(pi, x, y);
 
+       text_.background_color_ = backgroundColor();
        text_.draw(pi, x + border_, y);
 
        if (drawFrame_) {
@@ -207,7 +208,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
                int const a = text_.ascent() + border_;
                int const h = a + text_.descent() + border_;
                int const ww = pi.base.bv->workWidth();
-               if (w > ww - 40)  {
+               if (w > ww - 40 || Wide())  {
                        pi.pain.line(0, y - a, ww, y - a, frameColor());
                        pi.pain.line(0, y - a + h, ww, y - a + h, frameColor());
                } else {
@@ -219,13 +220,16 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
 
 void InsetText::drawSelection(PainterInfo & pi, int x, int y) const
 {
-       if (backgroundColor() != LColor::background) {
-               // repaint the background if needed
-               int const w = text_.width() + 2 * border_;
-               int const a = text_.ascent() + border_;
-               int const h = a + text_.descent() + border_;
-               pi.pain.fillRectangle(x, y - a, w, h, backgroundColor());
-       }
+       int const w = text_.width() + 2 * border_;
+       int const a = text_.ascent() + border_;
+       int const h = a + text_.descent() + border_;
+       int const ww = pi.base.bv->workWidth();
+       if (Wide())
+               pi.pain.fillRectangle(0, y - a, ww, h, 
+                       backgroundColor());
+       else
+               pi.pain.fillRectangle(x, y - a, w, h, 
+                       backgroundColor());
        text_.drawSelection(pi, x, y);
 }
 
index c6ba640afb10b98661f4b0526766c69a52fa5d17..dadc5593a19cd7264b5e8b9595cfa9af12cf5f29 100644 (file)
@@ -137,7 +137,9 @@ public:
        bool neverIndent() const;
        ///
        InsetText(InsetText const &);
-
+       ///
+       bool & Wide() const { return wide_inset_; }
+       
 protected:
        ///
        virtual void doDispatch(LCursor & cur, FuncRequest & cmd);
@@ -158,6 +160,8 @@ private:
        mutable lyx::pit_type old_pit;
        ///
        static int border_;
+       ///
+       mutable bool wide_inset_;
 public:
        ///
        mutable LyXText text_;
index 2b8193f5ea9d8c38cbb7271a59563e4d8d48a383..deaf1d7209aec39ccd18a5c0a7e9338b12f80892 100644 (file)
@@ -151,6 +151,15 @@ int RowPainter::leftMargin() const
 }
 
 
+bool isTrueTextInset(InsetBase * in)
+{
+       // Math and tabular insets have isTextInset = true, though they are
+       // not derived from InsetText. Paint them fully
+       return (in && in->isTextInset() && in->asMathInset() == 0
+               && in->lyxCode() != InsetBase::TABULAR_CODE);
+}
+
+
 void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
 {
        InsetBase const * inset = par_.getInset(pos);
@@ -164,8 +173,15 @@ void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
        pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
        pi.erased_ = erased_ || isDeletedText(par_, pos);
        theCoords.insets().add(inset, int(x_), yo_);
-       inset->drawSelection(pi, int(x_), yo_);
+       InsetBase * in = const_cast<InsetBase *>(inset);
+       // non-wide insets are painted completely. Recursive
+       bool tmp = bv_.repaintAll();
+       if (!isTrueTextInset(in) || !static_cast<InsetText*>(in)->Wide())
+               bv_.repaintAll(true);
+       if (bv_.repaintAll())
+               inset->drawSelection(pi, int(x_), yo_);
        inset->draw(pi, int(x_), yo_);
+       bv_.repaintAll(tmp);
        x_ += inset->width();
 }
 
@@ -720,25 +736,52 @@ void RowPainter::paintText()
 }
 
 
-lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par)
+lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par,
+       int x, int y)
 {
        boost::crc_32_type crc;
        for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) {
                const unsigned char b[] = { par.getChar(i) };
                crc.process_bytes(b, 1);
        }
+       const unsigned char b[] = { x, y, row.width() };
+       crc.process_bytes(b, 3);
        return crc.checksum();
 }
 
 
-bool isCursorOnRow(PainterInfo & pi, pit_type pit, RowList::const_iterator rit)
+bool CursorOnRow(PainterInfo & pi, pit_type const pit, 
+       RowList::const_iterator rit, LyXText const & text)
 {
+       // Is there a cursor on this row (or inside inset on row)
        LCursor & cur = pi.base.bv->cursor();
-       for (lyx::size_type d = 0; d < cur.depth(); d++)
-               if (cur[d].pit() == pit
-                   && cur[d].pos() >= rit->pos()
-                   && cur[d].pos() <= rit->endpos())
+       for (lyx::size_type d = 0; d < cur.depth(); d++) {
+               CursorSlice const & sl = cur[d];
+               if (sl.text() == &text
+                   && sl.pit() == pit
+                   && sl.pos() >= rit->pos()
+                   && sl.pos() < rit->endpos())
                        return true;
+       }
+       return false;
+}
+
+
+bool innerCursorOnRow(PainterInfo & pi, pit_type pit, 
+       RowList::const_iterator rit, LyXText const & text)
+{
+       // Is there a cursor inside an inset on this row, and is this inset
+       // the only "character" on this row
+       LCursor & cur = pi.base.bv->cursor();
+       if (rit->pos() + 1 != rit->endpos())
+               return false;
+       for (lyx::size_type d = 0; d < cur.depth(); d++) {
+               CursorSlice const & sl = cur[d];
+               if (sl.text() == &text
+                   && sl.pit() == pit 
+                   && sl.pos() == rit->pos())
+                       return d < cur.depth() - 1;
+       }
        return false;
 }
 
@@ -762,17 +805,31 @@ void paintPar
        lyx::size_type rowno(0);
        for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
                y += rit->ascent();
+               // Allow setting of bv->repaintAll() for nested insets in
+               // this row only
+               bool tmp = pi.base.bv->repaintAll();
 
                // Row signature; has row changed since last paint?
-               lyx::size_type const row_sig = calculateRowSignature(*rit, par);
-
-               bool cursor_on_row = isCursorOnRow(pi, pit, rit);
+               lyx::size_type const row_sig = calculateRowSignature(*rit, par, x, y);
+               bool row_has_changed = par.rowSignature()[rowno] != row_sig;
                
-               // If selection is on, the current row signature differs from
+               bool cursor_on_row = CursorOnRow(pi, pit, rit, text);
+               bool in_inset_alone_on_row = innerCursorOnRow(pi, pit, rit,
+                       text);
+
+               // If this is the only object on the row, we can make it wide
+               for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
+                       InsetBase* in 
+                           = const_cast<InsetBase*>(par.getInset(i));
+                       if (isTrueTextInset(in))
+                               static_cast<InsetText*>(in)->Wide()
+                                   = in_inset_alone_on_row;
+               }
+
+               // If selection is on, the current row signature differs 
                // from cache, or cursor is inside an inset _on this row_, 
                // then paint the row
-               if (repaintAll || par.rowSignature()[rowno] != row_sig
-                           || cursor_on_row) {
+               if (repaintAll || row_has_changed || cursor_on_row) {
                        // Add to row signature cache
                        par.rowSignature()[rowno] = row_sig;
 
@@ -781,15 +838,25 @@ void paintPar
                        RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y);
                        // Clear background of this row 
                        // (if paragraph background was not cleared)
-                       if (!repaintAll) {
-                               pi.pain.fillRectangle(x, y - rit->ascent(), 
+                       if (!repaintAll && 
+                           (!in_inset_alone_on_row || row_has_changed)) {
+                               pi.pain.fillRectangle(( rowno ? 0 : x - 10 ), y - rit->ascent(), 
                                    pi.base.bv->workWidth(), rit->height(),
                                    text.backgroundColor());
+                               // If outer row has changed, force nested
+                               // insets to repaint completely
+                               if (row_has_changed)
+                                       pi.base.bv->repaintAll(true);
                        }
                        
                        // Instrumentation for testing row cache (see also
                        // 12 lines lower):
-                       //lyxerr << "#";
+                       if (text.isMainText())
+                               lyxerr[Debug::PAINTING] << "#";
+                       else
+                               lyxerr[Debug::PAINTING] << "[" <<
+                                   repaintAll << row_has_changed <<
+                                   cursor_on_row << "]";
                        rp.paintAppendix();
                        rp.paintDepthBar();
                        rp.paintChangeBar();
@@ -800,8 +867,10 @@ void paintPar
                        rp.paintText();
                }
                y += rit->descent();
+               // Restore, see above
+               pi.base.bv->repaintAll(tmp);
        }
-       //lyxerr << "." << endl;
+       lyxerr[Debug::PAINTING] << "." << endl;
 }
 
 } // namespace anon
@@ -814,8 +883,11 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
        bool const select = bv.cursor().selection();
 
        PainterInfo pi(const_cast<BufferView *>(&bv), pain);
-       if (select || !vi.singlepar) {
-               // Clear background (Delegated to rows if no selection)
+       // Should the whole screen, including insets, be refreshed?
+       bool repaintAll(select || !vi.singlepar);
+       
+       if (repaintAll) {
+               // Clear background (if not delegated to rows)
                pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
                        text->backgroundColor());
        }
@@ -826,9 +898,10 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
        int yy = vi.y1;
        // draw contents
        for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) {
+               bv.repaintAll(repaintAll);
                Paragraph const & par = text->getPar(pit);
                yy += par.ascent();
-               paintPar(pi, *bv.text(), pit, 0, yy, select || !vi.singlepar);
+               paintPar(pi, *bv.text(), pit, 0, yy, repaintAll);
                yy += par.descent();
        }
 
@@ -865,9 +938,11 @@ void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y)
 //     lyxerr << "  paintTextInset: y: " << y << endl;
 
        y -= text.getPar(0).ascent();
+       // This flag can not be set from within same inset:
+       bool repaintAll = pi.base.bv->repaintAll();
        for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) {
                y += text.getPar(pit).ascent();
-               paintPar(pi, text, pit, x, y, true);
+               paintPar(pi, text, pit, x, y, repaintAll);
                y += text.getPar(pit).descent();
        }
 }
index 9acb2a761065e78c8b9341dcc08f07ea087c6f28..a06748a0a2dc6ccc65f4c829f9f9c88a772be57a 100644 (file)
@@ -628,12 +628,16 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
 
        case LFUN_DELETE:
                if (!cur.selection()) {
+                       if (cur.pos() == cur.paragraph().size())
+                               // Par boundary, force full-screen update
+                               singleParUpdate = false;
                        needsUpdate = Delete(cur);
                        cur.resetAnchor();
                        // It is possible to make it a lot faster still
                        // just comment out the line below...
                } else {
                        cutSelection(cur, true, false);
+                       singleParUpdate = false;
                }
                moveCursor(cur, false);
                break;
@@ -656,6 +660,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_BACKSPACE:
                if (!cur.selection()) {
                        if (bv->owner()->getIntl().getTransManager().backspace()) {
+                               // Par boundary, full-screen update
+                               if (cur.pos() == 0)
+                                       singleParUpdate = false;
                                needsUpdate = backspace(cur);
                                cur.resetAnchor();
                                // It is possible to make it a lot faster still
@@ -663,6 +670,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
                        }
                } else {
                        cutSelection(cur, true, false);
+                       singleParUpdate = false;
                }
                bv->switchKeyMap();
                break;
@@ -1532,10 +1540,14 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
 
        if (singleParUpdate)
                // Inserting characters does not change par height
-               if (cur.bottom().paragraph().dim().height() 
+               if (cur.bottom().paragraph().dim().height() 
                    == olddim.height()) {
                        // if so, update _only_ this paragraph
-                       cur.bv().update(Update::SinglePar | Update::Force);
+                       cur.bv().update(Update::SinglePar |
+                                       Update::FitCursor |
+                                       Update::MultiParSel);
+                       cur.noUpdate();
+                       return;
                } else
                        needsUpdate = true;
        if (!needsUpdate