r = max(r, TabIndicatorWidth);
}
+ //FIXME: LyXRC::cursor_width should be caret_width
caret_width_ = lyxrc.cursor_width
? lyxrc.cursor_width
: 1 + int((lyxrc.currentZoom + 50) / 200.0);
QRect const & rect() { return rect_; }
private:
- /// cursor is in RTL or LTR text
+ /// caret is in RTL or LTR text
bool rtl_;
/// indication for RTL or LTR
bool l_shape_;
GuiWorkArea::Private::Private(GuiWorkArea * parent)
: p(parent), buffer_view_(0), lyx_view_(0),
caret_(0), caret_visible_(false),
- need_resize_(false), schedule_redraw_(false), preedit_lines_(1),
- pixel_ratio_(1.0),
+ need_resize_(false), preedit_lines_(1),
+ 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());
Point p;
int h = 0;
- d->buffer_view_->cursorPosAndHeight(p, h);
+ d->buffer_view_->caretPosAndHeight(p, h);
// Don't start blinking if the cursor isn't on screen.
if (!d->buffer_view_->cursorInView(p, h))
return;
}
-void GuiWorkArea::redraw(bool update_metrics)
+void GuiWorkArea::scheduleRedraw(bool update_metrics)
{
if (!isVisible())
// No need to redraw in this case.
d->buffer_view_->cursor().fixIfBroken();
}
- // update cursor position, because otherwise it has to wait until
+ // 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();
// In order to avoid bad surprise in the middle of an operation,
// we better stop the blinking caret...
- // the cursor gets restarted in GuiView::restartCaret()
+ // the caret gets restarted in GuiView::restartCaret()
stopBlinkingCaret();
guiApp->processKeySym(key, mod);
}
cmd.action() != LFUN_MOUSE_MOTION || cmd.button() != mouse_button::none;
// In order to avoid bad surprise in the middle of an operation, we better stop
- // the blinking cursor.
+ // the blinking caret.
if (notJustMovingTheMouse)
p->stopBlinkingCaret();
// FIXME: let GuiView take care of those.
lyx_view_->clearMessage();
- // Show the cursor immediately after any operation
+ // Show the caret immediately after any operation
p->startBlinkingCaret();
}
Point point;
int h = 0;
- buffer_view_->cursorPosAndHeight(point, h);
+ buffer_view_->caretPosAndHeight(point, h);
bool const caret_in_view = buffer_view_->cursorInView(point, h);
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
need_resize_ = false;
p->busy(false);
- // Eventually, restart the cursor after the resize event.
+ // Eventually, restart the caret after the resize event.
// We might be resizing even if the focus is on another widget so we only
- // restart the cursor if we have the focus.
+ // restart the caret if we have the focus.
if (p->hasFocus())
QTimer::singleShot(50, p, SLOT(startBlinkingCaret()));
}
-void GuiWorkArea::Private::showCaret()
+void GuiWorkArea::Private::updateCaretGeometry()
{
- if (caret_visible_)
- return;
-
Point point;
int h = 0;
- buffer_view_->cursorPosAndHeight(point, h);
+ buffer_view_->caretPosAndHeight(point, h);
if (!buffer_view_->cursorInView(point, h))
return;
if (realfont.language() == latex_language)
l_shape = false;
- // show cursor on screen
+ // show caret on screen
Cursor & cur = buffer_view_->cursor();
bool completable = cur.inset().showCompletionCursor()
&& completer_->completionAvailable()
caret_visible_ = true;
//int cur_x = buffer_view_->getPos(cur).x_;
- // We may have decided to slide the cursor row so that cursor
+ // We may have decided to slide the cursor row so that caret
// is visible.
point.x_ -= buffer_view_->horizScrollOffset();
caret_->update(point.x_, point.y_, h, l_shape, isrtl, completable);
+}
+
- if (schedule_redraw_) {
- // This happens when a graphic conversion is finished. As we don't know
- // the size of the new graphics, it's better the update everything.
- // We can't use redraw() here because this would trigger a infinite
- // recursive loop with showCaret().
- buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
- p->viewport()->update();
- updateScrollbar();
- schedule_redraw_ = false;
+void GuiWorkArea::Private::showCaret()
+{
+ if (caret_visible_)
return;
- }
+ updateCaretGeometry();
p->viewport()->update(caret_->rect());
}
// FIXME: let GuiView take care of those.
d->lyx_view_->updateLayoutList();
}
- // Show the cursor immediately after any operation.
+ // Show the caret immediately after any operation.
startBlinkingCaret();
// FIXME QT5
#ifdef Q_WS_X11
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());
+ 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();
}
d->buffer_view_->cursor().insert(qstring_to_ucs4(e->commitString()));
d->buffer_view_->updateMetrics();
d->buffer_view_->cursor().endUndoGroup();
+ d->updateCaretGeometry();
viewport()->update();
}
- // Hide the cursor during the test transformation.
+ // Hide the caret during the test transformation.
if (e->preeditString().isEmpty())
startBlinkingCaret();
else
cur_r.moveLeft(10);
cur_r.moveBottom(cur_r.bottom()
+ cur_r.height() * (d->preedit_lines_ - 1));
- // return lower right of cursor in LyX.
+ // return lower right of caret in LyX.
return cur_r;
default:
return QWidget::inputMethodQuery(query);
}
-void GuiWorkArea::scheduleRedraw()
-{
- d->schedule_redraw_ = true;
-}
-
-
bool GuiWorkArea::inDialogMode() const
{
return d->dialog_mode_;
GuiWorkArea * wa = workArea(i);
LASSERT(wa, return);
wa->setUpdatesEnabled(true);
- wa->redraw(true);
+ wa->scheduleRedraw(true);
wa->setFocus();
///
currentWorkAreaChanged(wa);