The processEvents / screen update recursion bug fix.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9931 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Martin Vermeer 2005-05-11 07:44:20 +00:00
parent 7e41f0b392
commit 31bded06b1
10 changed files with 58 additions and 24 deletions

View File

@ -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

View File

@ -1,3 +1,8 @@
2005-05-11 Martin Vermeer <martin.vermeer@hut.fi>
* BufferView_pimpl.C (update): fix processEvents -caused update
recursion bug
2005-05-09 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* cursor.h (undispatched, noUpdate): add comments from André

View File

@ -1,3 +1,8 @@
2005-05-11 Martin Vermeer <martin.vermeer@hut.fi>
* screen.[hC]: fix processEvents -caused screen update recursion
bug
2005-04-25 Angus Leeming <leeming@lyx.org>
* LyXView.C:

View File

@ -1,3 +1,11 @@
2005-05-11 Martin Vermeer <martin.vermeer@hut.fi>
* 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 <michael.schmitt@teststep.org>
* ui/*.ui: remove captions: they are unused and pollute the po

View File

@ -126,10 +126,8 @@ void QView<GUIDialog>::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<GUIDialog>::build()
{
// protect the BC from unwarranted state transitions
qApp->processEvents();
updating_ = true;
build_dialog();
qApp->processEvents();
updating_ = false;
}

View File

@ -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];

View File

@ -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;
}

View File

@ -252,6 +252,10 @@ void start(string const & batch, vector<string> 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();
}

View File

@ -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;
}

View File

@ -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