From 31bded06b1b4a9d99e309254886433876b2a57d2 Mon Sep 17 00:00:00 2001 From: Martin Vermeer Date: Wed, 11 May 2005 07:44:20 +0000 Subject: [PATCH] The processEvents / screen update recursion bug fix. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9931 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView_pimpl.C | 13 +++++++++++-- src/ChangeLog | 5 +++++ src/frontends/ChangeLog | 5 +++++ src/frontends/qt2/ChangeLog | 8 ++++++++ src/frontends/qt2/QDialogView.h | 4 ---- src/frontends/qt2/QLPopupMenu.C | 1 - src/frontends/qt2/QMathDialog.C | 6 +----- src/frontends/qt2/lyx_gui.C | 4 ++++ src/frontends/screen.C | 30 ++++++++++++++++++------------ src/frontends/screen.h | 6 ++++++ 10 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index eb6582816f..ce12c3d10a 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -617,12 +617,20 @@ void BufferView::Pimpl::update(bool fitcursor, bool forceupdate) if (buffer_) { // Update macro store buffer_->buildMacros(); - // First drawing step 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. theCoords.startUpdating(); + // First drawing step ViewMetricsInfo vi = metrics(); if (fitcursor && fitCursor()) { @@ -633,7 +641,8 @@ void BufferView::Pimpl::update(bool fitcursor, bool forceupdate) // Second drawing step screen().redraw(*bv_, vi); } else { - // Abort updating of the coord cache - just restore the old one + // Abort updating of the coord + // cache - just restore the old one std::swap(theCoords, backup); } } else diff --git a/src/ChangeLog b/src/ChangeLog index c878219061..c7463cf819 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2005-05-11 Martin Vermeer + + * BufferView_pimpl.C (update): fix processEvents -caused update + recursion bug + 2005-05-09 Georg Baum * cursor.h (undispatched, noUpdate): add comments from André diff --git a/src/frontends/ChangeLog b/src/frontends/ChangeLog index e7aed9bff5..0ed23a44bf 100644 --- a/src/frontends/ChangeLog +++ b/src/frontends/ChangeLog @@ -1,3 +1,8 @@ +2005-05-11 Martin Vermeer + + * screen.[hC]: fix processEvents -caused screen update recursion + bug + 2005-04-25 Angus Leeming * LyXView.C: diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index ede22cdaa2..c5f851f7e8 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,11 @@ +2005-05-11 Martin Vermeer + + * lyx_gui.C (sync_events): + * QDialogView.h (update, build): + * QLPopupMenu.C (fire): + * QMathDialog.C (resizeEvent, showingPanel): fix processEvent + -caused update recursion bug + 2005-05-06 Michael Schmitt * ui/*.ui: remove captions: they are unused and pollute the po diff --git a/src/frontends/qt2/QDialogView.h b/src/frontends/qt2/QDialogView.h index 061c8537b3..41baaa5f22 100644 --- a/src/frontends/qt2/QDialogView.h +++ b/src/frontends/qt2/QDialogView.h @@ -126,10 +126,8 @@ void QView::update() // protect the BC from unwarranted state transitions - qApp->processEvents(); updating_ = true; update_contents(); - qApp->processEvents(); updating_ = false; form()->setUpdatesEnabled(true); @@ -142,10 +140,8 @@ void QView::build() { // protect the BC from unwarranted state transitions - qApp->processEvents(); updating_ = true; build_dialog(); - qApp->processEvents(); updating_ = false; } diff --git a/src/frontends/qt2/QLPopupMenu.C b/src/frontends/qt2/QLPopupMenu.C index 1f1ba57aa6..677a4fa6a3 100644 --- a/src/frontends/qt2/QLPopupMenu.C +++ b/src/frontends/qt2/QLPopupMenu.C @@ -88,7 +88,6 @@ QLPopupMenu::QLPopupMenu(QLMenubar * owner, void QLPopupMenu::fire(int index) { - qApp->processEvents(); #ifdef Q_WS_MACX if (index >= indexOffset) { MenuItem mi = owner_->backend().getMenu("LyX")[index - indexOffset]; diff --git a/src/frontends/qt2/QMathDialog.C b/src/frontends/qt2/QMathDialog.C index 0c43674acc..59ee731754 100644 --- a/src/frontends/qt2/QMathDialog.C +++ b/src/frontends/qt2/QMathDialog.C @@ -52,8 +52,7 @@ protected: return; w_->resize(viewport()->width(), w_->height()); - // force the resize to get accurate scrollbars - qApp->processEvents(); + // force the resize to get accurate scrollbar resizeContents(w_->width(), w_->height()); } private: @@ -156,9 +155,6 @@ void QMathDialog::showingPanel(int num) addPanel(num); - // Qt needs to catch up. Dunno why. - qApp->processEvents(); - panel_initialised[num] = true; } diff --git a/src/frontends/qt2/lyx_gui.C b/src/frontends/qt2/lyx_gui.C index f5230da557..7b47712385 100644 --- a/src/frontends/qt2/lyx_gui.C +++ b/src/frontends/qt2/lyx_gui.C @@ -252,6 +252,10 @@ void start(string const & batch, vector const & files) void sync_events() { + // This is the ONLY place where processEvents may be called. + // During screen update/ redraw, this method is disabled to + // prevent keyboard events being handed to the LyX core, where + // they could cause re-entrant calls to screen update. qApp->processEvents(); } diff --git a/src/frontends/screen.C b/src/frontends/screen.C index 6308730a20..537a13a8aa 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) + : greyed_out_(true), cursor_visible_(false), sync_allowed_(true) { // Start loading the pixmap as soon as possible if (lyxrc.show_banner) { @@ -147,15 +147,19 @@ void LyXScreen::checkAndGreyOut() void LyXScreen::showCursor(BufferView & bv) { - // You are not expected to understand this. This forces Qt - // (the problem case) to deal with its event queue. This is - // necessary when holding down a key such as 'page down' or - // just typing: without this processing of the event queue, - // the cursor gets ahead of itself without a selection or - // workarea redraw having a chance to keep up. If you think - // you can remove this, try selecting text with the mouse - // in Qt, or holding Page Down on the User's Guide. - lyx_gui::sync_events(); + // 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; @@ -202,6 +206,9 @@ void LyXScreen::showCursor(BufferView & bv) void LyXScreen::hideCursor() { + if (sync_allowed_) + lyx_gui::sync_events(); + if (!cursor_visible_) return; @@ -223,13 +230,12 @@ void LyXScreen::redraw(BufferView & bv, ViewMetricsInfo const & vi) { greyed_out_ = false; workarea().getPainter().start(); - hideCursor(); paintText(bv, vi); lyxerr[Debug::DEBUG] << "Redraw screen" << endl; expose(0, 0, workarea().workWidth(), workarea().workHeight()); workarea().getPainter().end(); theCoords.doneUpdating(); - showCursor(bv); + sync_allowed_ = true; } diff --git a/src/frontends/screen.h b/src/frontends/screen.h index e229864525..fd3f6e78a3 100644 --- a/src/frontends/screen.h +++ b/src/frontends/screen.h @@ -54,6 +54,9 @@ public: /// toggle the cursor's visibility void toggleCursor(BufferView & bv); + /// + void unAllowSync() { sync_allowed_ = false; }; + protected: /// cause the display of the given area of the work area virtual void expose(int x, int y, int w, int h) = 0; @@ -86,6 +89,9 @@ private: /// is the cursor currently displayed bool cursor_visible_; + + /// + bool sync_allowed_; }; #endif // SCREEN_H -- 2.39.5