: p(parent), buffer_view_(0), lyx_view_(0),
caret_(0), caret_visible_(false),
need_resize_(false), preedit_lines_(1),
- pixel_ratio_(1.0),
+ last_pixel_ratio_(1.0),
completer_(new GuiCompleter(p, p)), dialog_mode_(false), shell_escape_(false),
read_only_(false), clean_(true), externally_modified_(false)
{
generateSyntheticMouseEvent();
});
+ d->resetScreen();
// With Qt4.5 a mouse event will happen before the first paint event
// so make sure that the buffer view has an up to date metrics.
d->buffer_view_->resize(viewport()->width(), viewport()->height());
// update caret position, because otherwise it has to wait until
// the blinking interval is over
- if (d->caret_visible_) {
- d->hideCaret();
- d->showCaret();
- }
+ d->updateCaretGeometry();
LYXERR(Debug::WORKAREA, "WorkArea::redraw screen");
viewport()->update();
+ /// FIXME: is this still true now that paintEvent does the actual painting?
/// \warning: scrollbar updating *must* be done after the BufferView is drawn
/// because \c BufferView::updateScrollbar() is called in \c BufferView::draw().
d->updateScrollbar();
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
if (caret_in_view)
buffer_view_->scrollToCursor();
- p->viewport()->update();
+ updateCaretGeometry();
// Update scrollbars which might have changed due different
// BufferView dimension. This is especially important when the
}
-void GuiWorkArea::Private::showCaret()
+void GuiWorkArea::Private::updateCaretGeometry()
{
- if (caret_visible_)
- return;
-
Point point;
int h = 0;
buffer_view_->caretPosAndHeight(point, h);
point.x_ -= buffer_view_->horizScrollOffset();
caret_->update(point.x_, point.y_, h, l_shape, isrtl, completable);
+}
+
+void GuiWorkArea::Private::showCaret()
+{
+ if (caret_visible_)
+ return;
+
+ updateCaretGeometry();
p->viewport()->update(caret_->rect());
}
{
// Wheel rotation by one notch results in a delta() of 120 (see
// documentation of QWheelEvent)
+ // But first we have to ignore horizontal scroll events.
+#if QT_VERSION < 0x050000
+ if (ev->orientation() == Qt::Horizontal) {
+ ev->accept();
+ return;
+ }
double const delta = ev->delta() / 120.0;
+#else
+ QPoint const aDelta = ev->angleDelta();
+ // skip horizontal wheel event
+ if (abs(aDelta.x()) > abs(aDelta.y())) {
+ ev->accept();
+ return;
+ }
+ double const delta = aDelta.y() / 120.0;
+#endif
+
bool zoom = false;
switch (lyxrc.scroll_wheel_zoom) {
case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
void GuiWorkArea::paintEvent(QPaintEvent * ev)
{
+ // Do not trigger the painting machinery if we are not ready (see
+ // bug #10989). The second test triggers when in the middle of a
+ // dispatch operation.
+ if (view().busy() || d->buffer_view_->buffer().undo().activeUndoGroup()) {
+ // 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());
+ // Ignore this paint event, but request a new one for later.
+ viewport()->update(ev->rect());
+ ev->accept();
+ return;
+ }
+
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
- if (d->needResize()) {
+ if (d->need_resize_ || pixelRatio() != d->last_pixel_ratio_) {
+ d->resetScreen();
d->resizeBufferView();
- if (d->caret_visible_) {
- d->hideCaret();
- d->showCaret();
- }
}
- GuiPainter pain(viewport(), pixelRatio());
+ d->last_pixel_ratio_ = pixelRatio();
+
+ GuiPainter pain(d->screenDevice(), pixelRatio());
+
d->buffer_view_->draw(pain, d->caret_visible_);
// The preedit text, if needed
// and the caret
if (d->caret_visible_)
d->caret_->draw(pain);
+
+ d->updateScreen(ev->rect());
+
ev->accept();
}
// insert the processed text in the document (handles undo)
if (!e->commitString().isEmpty()) {
- d->buffer_view_->cursor().beginUndoGroup();
- d->buffer_view_->cursor().insert(qstring_to_ucs4(e->commitString()));
+ FuncRequest cmd(LFUN_SELF_INSERT,
+ qstring_to_ucs4(e->commitString()),
+ FuncRequest::KEYBOARD);
+ dispatch(cmd);
+ // FIXME: this is supposed to remove traces from preedit
+ // string. Can we avoid calling it explicitely?
d->buffer_view_->updateMetrics();
- d->buffer_view_->cursor().endUndoGroup();
- viewport()->update();
}
// Hide the caret during the test transformation.