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()) {
// 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
+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é
+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:
+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
// protect the BC from unwarranted state transitions
- qApp->processEvents();
updating_ = true;
update_contents();
- qApp->processEvents();
updating_ = false;
form()->setUpdatesEnabled(true);
{
// protect the BC from unwarranted state transitions
- qApp->processEvents();
updating_ = true;
build_dialog();
- qApp->processEvents();
updating_ = false;
}
void QLPopupMenu::fire(int index)
{
- qApp->processEvents();
#ifdef Q_WS_MACX
if (index >= indexOffset) {
MenuItem mi = owner_->backend().getMenu("LyX")[index - indexOffset];
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:
addPanel(num);
- // Qt needs to catch up. Dunno why.
- qApp->processEvents();
-
panel_initialised[num] = true;
}
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();
}
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) {
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;
void LyXScreen::hideCursor()
{
+ if (sync_allowed_)
+ lyx_gui::sync_events();
+
if (!cursor_visible_)
return;
{
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;
}
/// 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;
/// is the cursor currently displayed
bool cursor_visible_;
+
+ ///
+ bool sync_allowed_;
};
#endif // SCREEN_H