Skip paint event when in the middle of a buffer operation

This is detected when an undo group is open and contains at east one
element. This means indeed that changes are in progress. Note that the
group is in general opened in GuiApplication::dispatch. The code there
is changed to ensure that the group is closed before updating the
screen.

This patch is experimental. It is expected to be replaced in master by
a more complete solution. It could in the meantime be backported to 2.3.x.

Fixes bug #11159.
This commit is contained in:
Jean-Marc Lasgouttes 2018-05-31 23:15:40 +02:00
parent efc9720b0d
commit c7496a11b2
4 changed files with 21 additions and 9 deletions

View File

@ -610,6 +610,12 @@ void Undo::endUndoGroup(CursorData const & cur_after)
} }
bool Undo::activeUndoGroup() const
{
return d->group_level_ > 0 && d->undostack_.top().group_id == d->group_id_;
}
void Undo::recordUndo(CursorData const & cur, UndoKind kind) void Undo::recordUndo(CursorData const & cur, UndoKind kind)
{ {
d->recordUndo(kind, cur, cur.pit(), cur.pit(), cur); d->recordUndo(kind, cur, cur.pit(), cur.pit(), cur);

View File

@ -96,6 +96,8 @@ public:
void endUndoGroup(); void endUndoGroup();
/// end the current undo group and set UndoElement::cur_after if necessary. /// end the current undo group and set UndoElement::cur_after if necessary.
void endUndoGroup(CursorData const & cur_after); void endUndoGroup(CursorData const & cur_after);
/// return true if an undo group is open and contains at least one element
bool activeUndoGroup() const;
/// The general case: record undo information for an arbitrary range. /// The general case: record undo information for an arbitrary range.
/** /**

View File

@ -1401,15 +1401,17 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY(); current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
buffer = &current_view_->currentBufferView()->buffer(); buffer = &current_view_->currentBufferView()->buffer();
} }
// This handles undo groups automagically
UndoGroupHelper ugh(buffer); dr.screenUpdate(Update::FitCursor);
{
// This handles undo groups automagically
UndoGroupHelper ugh(buffer);
dispatch(cmd, dr);
}
// redraw the screen at the end (first of the two drawing steps). // redraw the screen at the end (first of the two drawing steps).
// This is done unless explicitly requested otherwise // This is done unless explicitly requested otherwise
dr.screenUpdate(Update::FitCursor);
dispatch(cmd, dr);
updateCurrentView(cmd, dr); updateCurrentView(cmd, dr);
d->dispatch_result_ = dr; d->dispatch_result_ = dr;
return d->dispatch_result_; return d->dispatch_result_;
} }

View File

@ -1248,10 +1248,12 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
void GuiWorkArea::paintEvent(QPaintEvent * ev) void GuiWorkArea::paintEvent(QPaintEvent * ev)
{ {
// Do not trigger the painting machinery if we are not ready (see // Do not trigger the painting machinery if we are not ready (see
// bug #10989). However, since macOS has turned the screen black at // bug #10989). The second test triggers when in the middle of a
// this point, our backing store has to be copied to screen. // dispatch operation.
if (view().busy()) { if (view().busy() || d->buffer_view_->buffer().undo().activeUndoGroup()) {
// this is a no-op except on macOS. // Since macOS has turned the screen black at this point, our
// backing store has to be copied to screen (this is a no-op
// except on macOS).
d->updateScreen(ev->rect()); d->updateScreen(ev->rect());
ev->accept(); ev->accept();
return; return;