From a683500118a001b1185b6aee480c1289550bd08c Mon Sep 17 00:00:00 2001 From: Martin Vermeer Date: Tue, 31 May 2005 14:40:30 +0000 Subject: [PATCH] Axe processEvents, fix cursor draw artifacts, put update flags into an enum, allow single-paragraph update git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9986 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView.C | 4 ++-- src/BufferView.h | 24 +++++++++++++++++++++++- src/BufferView_pimpl.C | 33 ++++++++++++++++++--------------- src/BufferView_pimpl.h | 4 ++-- src/ChangeLog | 14 ++++++++++++++ src/dimension.h | 6 ++++++ src/frontends/ChangeLog | 5 +++++ src/frontends/screen.C | 26 +++++++------------------- src/frontends/screen.h | 7 +++---- src/lyxfunc.C | 5 ++++- src/lyxtext.h | 2 +- src/metricsinfo.h | 6 ++++-- src/rowpainter.C | 2 ++ src/text.C | 7 ++++++- src/text3.C | 11 +++++++---- 15 files changed, 104 insertions(+), 52 deletions(-) diff --git a/src/BufferView.C b/src/BufferView.C index 9b33d6567b..5009b2961d 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -142,9 +142,9 @@ bool BufferView::fitCursor() } -void BufferView::update(bool fitcursor, bool forceupdate) +void BufferView::update(Update::flags flags) { - pimpl_->update(fitcursor, forceupdate); + pimpl_->update(flags); } diff --git a/src/BufferView.h b/src/BufferView.h index b41d2df19b..477a9e927f 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -35,6 +35,27 @@ class LyXView; class Painter; class ParIterator; + +namespace Update { + enum flags { + FitCursor = 1, + Force = 2, + SinglePar = 4 + }; + +inline flags operator|(flags const f, flags const g) +{ + return static_cast(int(f) | int(g)); +} + +inline flags operator&(flags const f, flags const g) +{ + return static_cast(int(f) & int(g)); +} + +} // namespace + + /** * A buffer view encapsulates a view onto a particular * buffer, and allows access to operate upon it. A view @@ -81,7 +102,8 @@ public: * position changes. \c forceupdate means to force an update * in any case. */ - void update(bool fitcursor = true, bool forceupdate = true); + + void update(Update::flags flags = Update::FitCursor | Update::Force); /// move the screen to fit the cursor. Only to be called with /// good y coordinates (after a bv::metrics) bool fitCursor(); diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index ce12c3d10a..0617392056 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -521,8 +521,10 @@ void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key, * dispatch() itself, because that's called recursively. */ if (available()) { + screen().prepareCursor(); + cursor_timeout.setTimeout(100); cursor_timeout.restart(); - screen().showCursor(*bv_); + cursor_timeout.setTimeout(400); } } @@ -606,11 +608,12 @@ bool BufferView::Pimpl::fitCursor() } -void BufferView::Pimpl::update(bool fitcursor, bool forceupdate) +void BufferView::Pimpl::update(Update::flags flags) { lyxerr << BOOST_CURRENT_FUNCTION - << "[fitcursor = " << fitcursor << ',' - << " forceupdate = " << forceupdate + << "[fitcursor = " << (flags & Update::FitCursor) + << ", forceupdate = " << (flags & Update::Force) + << ", singlepar = " << (flags & Update::SinglePar) << "] buffer: " << buffer_ << endl; // Check needed to survive LyX startup @@ -621,10 +624,6 @@ void BufferView::Pimpl::update(bool fitcursor, bool forceupdate) CoordCache backup; std::swap(theCoords, backup); - // This call disallows cursor blink to call - // processEvents. It is necessary to prevent screen - // redraw being called recursively. - screen().unAllowSync(); // This, together with doneUpdating(), verifies (using // asserts) that screen redraw is not called from // within itself. @@ -632,10 +631,11 @@ void BufferView::Pimpl::update(bool fitcursor, bool forceupdate) // First drawing step ViewMetricsInfo vi = metrics(); + bool forceupdate(flags & Update::Force); - if (fitcursor && fitCursor()) { + if ((flags & Update::FitCursor) && fitCursor()) { forceupdate = true; - vi = metrics(); + vi = metrics(flags & Update::SinglePar); } if (forceupdate) { // Second drawing step @@ -934,7 +934,10 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) if (cur.result().dispatched()) { // Redraw if requested or necessary. - update(cur.result().update(), cur.result().update()); + if (cur.result().update()) + update(Update::FitCursor | Update::Force); + else + update(); } // See workAreaKeyPress @@ -1246,7 +1249,7 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) } -ViewMetricsInfo BufferView::Pimpl::metrics() +ViewMetricsInfo BufferView::Pimpl::metrics(bool singlepar) { // Remove old position cache theCoords.clear(); @@ -1274,7 +1277,7 @@ ViewMetricsInfo BufferView::Pimpl::metrics() // Redo paragraphs above cursor if necessary int y1 = y0; - while (y1 > 0 && pit1 > 0) { + while (!singlepar && y1 > 0 && pit1 > 0) { y1 -= text->getPar(pit1).ascent(); --pit1; text->redoParagraph(pit1); @@ -1298,7 +1301,7 @@ ViewMetricsInfo BufferView::Pimpl::metrics() // Redo paragraphs below cursor if necessary int y2 = y0; - while (y2 < bv.workHeight() && pit2 < int(npit) - 1) { + while (!singlepar && y2 < bv.workHeight() && pit2 < int(npit) - 1) { y2 += text->getPar(pit2).descent(); ++pit2; text->redoParagraph(pit2); @@ -1321,5 +1324,5 @@ ViewMetricsInfo BufferView::Pimpl::metrics() << " y2: " << y2 << endl; - return ViewMetricsInfo(pit1, pit2, y1, y2); + return ViewMetricsInfo(pit1, pit2, y1, y2, singlepar); } diff --git a/src/BufferView_pimpl.h b/src/BufferView_pimpl.h index a6ac1ad32a..73d6d4262d 100644 --- a/src/BufferView_pimpl.h +++ b/src/BufferView_pimpl.h @@ -60,7 +60,7 @@ public: // bool fitCursor(); /// - void update(bool fitcursor = false, bool forceupdate = true); + void update(Update::flags flags = Update::Force); /// void newFile(std::string const &, std::string const &, bool); /// @@ -186,7 +186,7 @@ private: /// int offset_ref_; /// - ViewMetricsInfo metrics(); + ViewMetricsInfo metrics(bool singlepar = false); }; diff --git a/src/ChangeLog b/src/ChangeLog index 7fb5ea2934..3772e314a4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2005-05-31 Martin Vermeer + + * BufferView.[Ch] (update): + * BufferView_pimpl.[Ch] (update, metrics): + * dimension.h (operator==): + * lyxfunc.C (dispatch): + * metricsinfo.h (ViewMetricsInfo): + * rowpainter.C (paintText): + * lyxtext.h: + * text.C (redoParagraph): + * text3.C (dispatch): Make LyX only repaint current paragraph in + case of character insert --> speedup. Also fix cursor draw + artifacts + 2005-05-31 Jean-Marc Lasgouttes * bufferview_funcs.C (gotoInset): fix the wrap-around code to diff --git a/src/dimension.h b/src/dimension.h index de5691cb2f..8bca47a93d 100644 --- a/src/dimension.h +++ b/src/dimension.h @@ -61,4 +61,10 @@ public: int des; }; +inline +bool operator==(Dimension const & a, Dimension const & b) +{ + return a.wid == b.wid && a.asc == b.asc && a.des ==b.des ; +} + #endif diff --git a/src/frontends/ChangeLog b/src/frontends/ChangeLog index 8b41ca10f4..f247b65346 100644 --- a/src/frontends/ChangeLog +++ b/src/frontends/ChangeLog @@ -1,3 +1,8 @@ +2005-05-31 Martin Vermeer + + * screen.[hC]: better fix, processEvents -related screen update + bug + 2005-05-20 Lars Gullik Bjonnes * Move the gnome subdir to the Attic diff --git a/src/frontends/screen.C b/src/frontends/screen.C index 537a13a8aa..ae796390b3 100644 --- a/src/frontends/screen.C +++ b/src/frontends/screen.C @@ -122,7 +122,7 @@ SplashScreen::SplashScreen() LyXScreen::LyXScreen() - : greyed_out_(true), cursor_visible_(false), sync_allowed_(true) + : greyed_out_(true), cursor_visible_(false) { // Start loading the pixmap as soon as possible if (lyxrc.show_banner) { @@ -147,20 +147,6 @@ void LyXScreen::checkAndGreyOut() void LyXScreen::showCursor(BufferView & bv) { - // This code is currently meaningful only for the Qt frontend. - // This is the place (like below in hideCursor) where - // processEvents is being called, and things like keystrokes and - // mouse clicks are being handed to the LyX core, once every - // cursor blink. - // THERE IS NOT SUPPOSED TO BE ANY OTHER CALL TO processEvents - // ANYWHERE ELSE. - // in BufferView::Pimpl::update() and here, the sync_allowed_ - // guard is set/cleared which is used here to prevent recursive - // calls to screen update. startUpdating() and doneUpdating() in - // coordcache again contain asserts to detect such recursion. - if (sync_allowed_) - lyx_gui::sync_events(); - if (cursor_visible_) return; @@ -206,9 +192,6 @@ void LyXScreen::showCursor(BufferView & bv) void LyXScreen::hideCursor() { - if (sync_allowed_) - lyx_gui::sync_events(); - if (!cursor_visible_) return; @@ -226,6 +209,12 @@ void LyXScreen::toggleCursor(BufferView & bv) } +void LyXScreen::prepareCursor() +{ + cursor_visible_ = false; +} + + void LyXScreen::redraw(BufferView & bv, ViewMetricsInfo const & vi) { greyed_out_ = false; @@ -235,7 +224,6 @@ void LyXScreen::redraw(BufferView & bv, ViewMetricsInfo const & vi) expose(0, 0, workarea().workWidth(), workarea().workHeight()); workarea().getPainter().end(); theCoords.doneUpdating(); - sync_allowed_ = true; } diff --git a/src/frontends/screen.h b/src/frontends/screen.h index fd3f6e78a3..c10c65d0e8 100644 --- a/src/frontends/screen.h +++ b/src/frontends/screen.h @@ -54,8 +54,9 @@ public: /// toggle the cursor's visibility void toggleCursor(BufferView & bv); - /// - void unAllowSync() { sync_allowed_ = false; }; + /// set cursor_visible_ to false in prep for re-display + void prepareCursor(); + protected: /// cause the display of the given area of the work area @@ -90,8 +91,6 @@ private: /// is the cursor currently displayed bool cursor_visible_; - /// - bool sync_allowed_; }; #endif // SCREEN_H diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 57bd08c788..36ec96f45b 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -1522,7 +1522,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // Redraw screen unless explicitly told otherwise. // This also initializes the position cache for all insets // in (at least partially) visible top-level paragraphs. - view()->update(true, update); + if (update) + view()->update(Update::FitCursor | Update::Force); + else + view()->update(Update::FitCursor); // if we executed a mutating lfun, mark the buffer as dirty // FIXME: Why not use flag.enabled() but call getStatus again? diff --git a/src/lyxtext.h b/src/lyxtext.h index 3e67c12b3a..a73826cb8a 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -95,7 +95,7 @@ public: void setFont(LCursor & cur, LyXFont const &, bool toggleall = false); /// rebreaks the given par - void redoParagraph(pit_type pit); + bool redoParagraph(pit_type pit); /// returns pos in given par at given x coord pos_type x2pos(pit_type pit, int row, int x) const; diff --git a/src/metricsinfo.h b/src/metricsinfo.h index d0cd5580f8..60a3a1745d 100644 --- a/src/metricsinfo.h +++ b/src/metricsinfo.h @@ -97,12 +97,14 @@ class TextMetricsInfo {}; class ViewMetricsInfo { public: - ViewMetricsInfo(lyx::pit_type p1, lyx::pit_type p2, - int y1, int y2) : p1(p1), p2(p2), y1(y1), y2(y2) {} + ViewMetricsInfo(lyx::pit_type p1, lyx::pit_type p2, int y1, int y2, + bool singlepar) : p1(p1), p2(p2), y1(y1), y2(y2), + singlepar(singlepar) {} lyx::pit_type p1; lyx::pit_type p2; int y1; int y2; + bool singlepar; }; diff --git a/src/rowpainter.C b/src/rowpainter.C index 68034fe0f3..5e730ef8e5 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -787,6 +787,8 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi) // paint one paragraph above and one below + // Note MV: this cannot be suppressed even for singlepar. + // Try viewing the User Guide Mobius figure if (vi.p1 > 0) { text->redoParagraph(vi.p1 - 1); paintPar(pi, *bv.text(), vi.p1 - 1, 0, diff --git a/src/text.C b/src/text.C index 18c6df2476..ca069b6635 100644 --- a/src/text.C +++ b/src/text.C @@ -1649,7 +1649,7 @@ Row const & LyXText::firstRow() const } -void LyXText::redoParagraph(pit_type const pit) +bool LyXText::redoParagraph(pit_type const pit) { // remove rows of paragraph, keep track of height changes Paragraph & par = pars_[pit]; @@ -1700,8 +1700,13 @@ void LyXText::redoParagraph(pit_type const pit) dim.asc += par.rows()[0].ascent(); dim.des -= par.rows()[0].ascent(); + + bool const same = dim == par.dim(); + par.dim() = dim; //lyxerr << "redoParagraph: " << par.rows().size() << " rows\n"; + + return !same; } diff --git a/src/text3.C b/src/text3.C index 5bb93fc65f..e4d9060598 100644 --- a/src/text3.C +++ b/src/text3.C @@ -263,7 +263,7 @@ void update(LCursor & cur) { //we don't call update(true, false) directly to save a metrics call if (cur.bv().fitCursor()) - cur.bv().update(false, true); + cur.bv().update(Update::Force); } @@ -1130,9 +1130,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.resetAnchor(); moveCursor(cur, false); - // real_current_font.number can change so we need to - // update the minibuffer - if (old_font != real_current_font) + needsUpdate = redoParagraph(cur.pit()); + if (!needsUpdate) { + // update only this paragraph + cur.bv().update(Update::SinglePar | Update::Force); + } + bv->updateScrollbar(); break; } -- 2.39.2