Helge Hafting wrote: > Peter Kümmel wrote: >> Abdelrazak Younes wrote: >> >>>> Is this your only comment? >>>> >>> Yes. Sorry, don't have the time to do much more. I thought I'd share my >>> opinion ;-) >>> >> >> Sorry, too - for my harsh reply. >> >> >>>> Anyway I don't think there is a simpler solution, at least I will >>>> not look for it, this bug has cost me already too much time. >>>> >> >> OK, I've found a better solution ;) >> I had to test if it was worth to upgrade to 1GB ram. >> >> >>> I can understand that. I was thinking of collecting the scroll events >>> and cancelling them if a scroll operation is still on-going but maybe >>> that's what your patch do. I only briefly looked at it and it _seems_ >>> very complicated. >>> >> >> Yes this is what it does. An it _is_ complicated. ;) >> >> But I've found a more Qt like and elegant solution. >> See attached patch, which should be much more readably. >> >> I've introduced two events which are only posted once >> to the event queue until the event is not processed. >> >> This also improves(?) the scrolling under Windows, >> see the comment in generateLyxScrollEvent. >> > I checked out todays SVN, applied this patch, and compiled. > Unfortunately, it doesn't help. At least not on linux. > Scrolling a maximized userguide may still overshoot by several pages. > > Helge Hafting >
I'm running out of ideas... Is this patch better (the flush call is new)? Or with processEvents instead of flush? -- Peter Kümmel
Index: src/frontends/qt4/GuiWorkArea.cpp =================================================================== --- src/frontends/qt4/GuiWorkArea.cpp (revision 18430) +++ src/frontends/qt4/GuiWorkArea.cpp (working copy) @@ -190,8 +190,11 @@ // Initialize the vertical Scroll Bar QObject::connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), - this, SLOT(adjustViewWithScrollBar(int))); + this, SLOT(generateLyxScrollEvent())); + QObject::connect(verticalScrollBar(), SIGNAL(sliderReleased()), + this, SLOT(lyxScrollEvent())); + // disable context menu for the scrollbar verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); @@ -211,6 +214,53 @@ } + +class LyxScrollEvent : public QEvent +{ +public: + LyxScrollEvent() : QEvent(QEvent::Type(id)) + {} + static const int id; + static bool locked; +}; + +// Qt doc: user event type between 1000 and 65535 +const int LyxScrollEvent::id = 31415; +bool LyxScrollEvent::locked = false; + + +class LyxKeyEvent : public QKeyEvent +{ +public: + LyxKeyEvent(QKeyEvent * e) : + QKeyEvent(QEvent::Type(id), e->key(), + e->modifiers(), e->text(), e->isAutoRepeat(), e->count()) + {} + static const int id; + static bool locked; +}; + +const int LyxKeyEvent::id = 27182; +bool LyxKeyEvent::locked = false; + + + +bool GuiWorkArea::event(QEvent * event) +{ + if (event->type() == LyxKeyEvent::id) { + lyxKeyEvent(dynamic_cast<LyxKeyEvent*>(event)); + LyxKeyEvent::locked = false; + return true; + } else if (event->type() == LyxScrollEvent::id) { + lyxScrollEvent(); + LyxScrollEvent::locked = false; + return true; + } else { + return QAbstractScrollArea::event(event); + } +} + + void GuiWorkArea::setScrollbarParams(int h, int scroll_pos, int scroll_line_step) { if (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOn) @@ -231,12 +281,31 @@ } -void GuiWorkArea::adjustViewWithScrollBar(int) +void GuiWorkArea::lyxScrollEvent() { scrollBufferView(verticalScrollBar()->sliderPosition()); + QCoreApplication::flush(); } +void GuiWorkArea::generateLyxScrollEvent() +{ + // This gives the old slow (the scroll bar couldn't follow the mouse) + // scrolling on Windows. Is it really better? + // Windows/Qt is here not as fast as X11 + //lyxScrollEvent();return; + + // multiple scroll events are merged into one + if (!LyxScrollEvent::locked) { + LyxScrollEvent::locked = true; + LyxScrollEvent* scrollEvent = new LyxScrollEvent; + QCoreApplication::postEvent(this, scrollEvent); + LYXERR(Debug::GUI) << "scrolling: one event posted" << endl; + } else { + LYXERR(Debug::GUI) << "scrolling: waiting for processing last scrolling event" << endl; + } +} + void GuiWorkArea::dragEnterEvent(QDragEnterEvent * event) { if (event->mimeData()->hasUrls()) @@ -389,13 +458,14 @@ int const lines = qApp->wheelScrollLines() * e->delta() / 120; verticalScrollBar()->setValue(verticalScrollBar()->value() - lines * verticalScrollBar()->singleStep()); - adjustViewWithScrollBar(); + + generateLyxScrollEvent(); } void GuiWorkArea::generateSyntheticMouseEvent() { -// Set things off to generate the _next_ 'pseudo' event. + // Set things off to generate the _next_ 'pseudo' event. if (synthetic_mouse_event_.restart_timeout) synthetic_mouse_event_.timeout.start(); @@ -412,18 +482,32 @@ } + void GuiWorkArea::keyPressEvent(QKeyEvent * e) { - // do nothing if there are other events - // (the auto repeated events come too fast) - if (e->isAutoRepeat() && QCoreApplication::hasPendingEvents()) { - LYXERR(Debug::KEY) - << BOOST_CURRENT_FUNCTION << endl - << "key ignored" << endl; - e->ignore(); - return; + // add here all keys which should be delayed + static const int delayed_keys = Qt::Key_PageDown | Qt::Key_PageUp; + + if (e->key() & delayed_keys) { + if (!LyxKeyEvent::locked) { + LyxKeyEvent::locked = true; + QCoreApplication::postEvent(this, new LyxKeyEvent(e)); + e->ignore(); + LYXERR(Debug::GUI) << "key processing : event queued" << endl; + } else { + e->ignore(); + LYXERR(Debug::GUI) << "key processing : waiting for event processing" << endl; + } + } else { + e->accept(); + LyxKeyEvent lyxEvent(e); + lyxKeyEvent(&lyxEvent); } +} + +void GuiWorkArea::lyxKeyEvent(LyxKeyEvent * e) +{ LYXERR(Debug::KEY) << BOOST_CURRENT_FUNCTION << " count=" << e->count() << " text=" << fromqstr(e->text()) @@ -434,8 +518,10 @@ boost::shared_ptr<QKeySymbol> sym(new QKeySymbol); sym->set(e); processKeySym(sym, q_key_state(e->modifiers())); + QCoreApplication::flush(); } + void GuiWorkArea::doubleClickTimeout() { dc_event_.active = false; } Index: src/frontends/qt4/GuiWorkArea.h =================================================================== --- src/frontends/qt4/GuiWorkArea.h (revision 18430) +++ src/frontends/qt4/GuiWorkArea.h (working copy) @@ -25,8 +25,6 @@ #include <QTimer> #include <QPixmap> -#include <queue> - class QWidget; class QDragEnterEvent; class QDropEvent; @@ -38,6 +36,8 @@ class GuiView; class QLPainter; +class CursorWidget; +class LyxKeyEvent; /// for emulating triple click class double_click { @@ -81,7 +81,6 @@ * Qt-specific implementation of the work area * (buffer view GUI) */ - class CursorWidget; class GuiWorkArea : public QAbstractScrollArea, public WorkArea { Q_OBJECT @@ -144,15 +143,16 @@ void inputMethodEvent(QInputMethodEvent * ev); /// IM query QVariant inputMethodQuery(Qt::InputMethodQuery query) const; + /// overwrite QObject function + bool event(QEvent * event); + /// + void lyxKeyEvent(LyxKeyEvent * event); -public Q_SLOTS: +private Q_SLOTS: /// Adjust the LyX buffer view with the position of the scrollbar. - /** - * The action argument is not used in the the code, it is there - * only for the connection to the vertical srollbar signal which - * emits an 'int' action. - */ - void adjustViewWithScrollBar(int action = 0); + void lyxScrollEvent(); + /// + void generateLyxScrollEvent(); /// timer to limit triple clicks void doubleClickTimeout();