]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiWorkArea.cpp
Fix reloading of local layout file (bug #11120)
[lyx.git] / src / frontends / qt4 / GuiWorkArea.cpp
index f4380da5e8c773c0aaa9791ac1808b21df225da5..129656444b73b5a6e9ef33d41cd48b52abae3774 100644 (file)
@@ -306,6 +306,7 @@ void GuiWorkArea::init()
                        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());
@@ -469,14 +470,12 @@ void GuiWorkArea::scheduleRedraw(bool update_metrics)
 
        // 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();
@@ -574,7 +573,7 @@ void GuiWorkArea::Private::resizeBufferView()
        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
@@ -592,11 +591,8 @@ void GuiWorkArea::Private::resizeBufferView()
 }
 
 
-void GuiWorkArea::Private::showCaret()
+void GuiWorkArea::Private::updateCaretGeometry()
 {
-       if (caret_visible_)
-               return;
-
        Point point;
        int h = 0;
        buffer_view_->caretPosAndHeight(point, h);
@@ -631,7 +627,15 @@ void GuiWorkArea::Private::showCaret()
        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());
 }
 
@@ -893,7 +897,23 @@ void GuiWorkArea::wheelEvent(QWheelEvent * ev)
 {
        // 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:
@@ -1240,20 +1260,32 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
 
 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->need_resize_ || pixelRatio() != d->last_pixel_ratio_) {
+               d->resetScreen();
                d->resizeBufferView();
-               if (d->caret_visible_) {
-                       d->hideCaret();
-                       d->showCaret();
-               }
        }
 
        d->last_pixel_ratio_ = pixelRatio();
 
-       GuiPainter pain(viewport(), pixelRatio());
+       GuiPainter pain(d->screenDevice(), pixelRatio());
+
        d->buffer_view_->draw(pain, d->caret_visible_);
 
        // The preedit text, if needed
@@ -1262,6 +1294,9 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
        // and the caret
        if (d->caret_visible_)
                d->caret_->draw(pain);
+
+       d->updateScreen(ev->rect());
+
        ev->accept();
 }
 
@@ -1273,11 +1308,13 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
 
        // 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.