Abdelrazak Younes wrote: > Peter Kümmel wrote: >> Next try. To see how it works change the event_delay_ms >> variable in the constructor to 3000 and use -dbg 12. > > This looks way too complicated Peter. There must be a simpler solution. > > Abdel. >
You could start with some like the attached patch (does not work on Linux) or with an event filter as mentioned in the Trolltech list thread. -- Peter Kümmel
Index: src/frontends/qt4/GuiWorkArea.cpp =================================================================== --- src/frontends/qt4/GuiWorkArea.cpp (revision 18416) +++ src/frontends/qt4/GuiWorkArea.cpp (working copy) @@ -161,7 +161,8 @@ GuiWorkArea::GuiWorkArea(int w, int h, int id, LyXView & lyx_view) : WorkArea(id, lyx_view), need_resize_(false), schedule_redraw_(false), - preedit_lines_(1) + preedit_lines_(1), waiting_for_key_processing(false), + waiting_for_scrolling(false) { screen_ = QPixmap(viewport()->width(), viewport()->height()); cursor_ = new frontend::CursorWidget(); @@ -190,8 +191,21 @@ // Initialize the vertical Scroll Bar QObject::connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), - this, SLOT(adjustViewWithScrollBar(int))); + this, SLOT(verticalScrollBarActionTriggered())); + QObject::connect(verticalScrollBar(), SIGNAL(sliderReleased()), + this, SLOT(verticalScrollBarSliderReleased())); + // We circumvent the event queue for scroll events. + // This avoids scrolling after the user has stopped + // scrolling, but scrolling proceeds because the + // event queue is full of scroll events. + QObject::connect(this, SIGNAL(updateScrollBar()), + this, SLOT(adjustViewWithScrollBar())); + QObject::connect(this, SIGNAL(processKeySignal(QKeyEvent*)), + this, SLOT(processKey(QKeyEvent*))); + + + // disable context menu for the scrollbar verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); @@ -234,9 +248,32 @@ void GuiWorkArea::adjustViewWithScrollBar(int) { scrollBufferView(verticalScrollBar()->sliderPosition()); + waiting_for_scrolling = false; + LYXERR(Debug::GUI) << BOOST_CURRENT_FUNCTION + << ": delayed scrolling done" << endl; } +void GuiWorkArea::verticalScrollBarActionTriggered() +{ + // multiple scroll events are merged into one + if (!waiting_for_scrolling) { + waiting_for_scrolling = true; + // emit signal + updateScrollBar(); + } else { + LYXERR(Debug::GUI) << BOOST_CURRENT_FUNCTION + << ": delay scrolling" << endl; + } +} + +void GuiWorkArea::verticalScrollBarSliderReleased() +{ + // finally adjust the scrollbar + adjustViewWithScrollBar(); +} + + void GuiWorkArea::dragEnterEvent(QDragEnterEvent * event) { if (event->mimeData()->hasUrls()) @@ -389,13 +426,13 @@ int const lines = qApp->wheelScrollLines() * e->delta() / 120; verticalScrollBar()->setValue(verticalScrollBar()->value() - lines * verticalScrollBar()->singleStep()); - adjustViewWithScrollBar(); + verticalScrollBarActionTriggered(); } 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,14 +449,32 @@ } +void GuiWorkArea::processKey(QKeyEvent * e) +{ + boost::shared_ptr<QKeySymbol> sym(new QKeySymbol); + sym->set(e); + processKeySym(sym, q_key_state(e->modifiers())); + waiting_for_key_processing = false; + LYXERR(Debug::GUI) << BOOST_CURRENT_FUNCTION + << ": delayed key processing done" << endl; +} + + 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; + // add here all keys which should be delayed + static const int delayed_keys = Qt::Key_PageDown | Qt::Key_PageUp; + + if (e->key() & delayed_keys) { + LYXERR(Debug::GUI) << BOOST_CURRENT_FUNCTION + << ": delay key processing" << endl; + if (!waiting_for_key_processing) { + waiting_for_key_processing = true; + // emit signal + e->accept(); + processKey(e); + return; + } e->ignore(); return; } Index: src/frontends/qt4/GuiWorkArea.h =================================================================== --- src/frontends/qt4/GuiWorkArea.h (revision 18416) +++ src/frontends/qt4/GuiWorkArea.h (working copy) @@ -26,6 +26,7 @@ #include <QPixmap> #include <queue> +#include <set> class QWidget; class QDragEnterEvent; @@ -33,11 +34,13 @@ class QWheelEvent; class QPaintEvent; + namespace lyx { namespace frontend { class GuiView; class QLPainter; +class CursorWidget; /// for emulating triple click class double_click { @@ -81,7 +84,6 @@ * Qt-specific implementation of the work area * (buffer view GUI) */ - class CursorWidget; class GuiWorkArea : public QAbstractScrollArea, public WorkArea { Q_OBJECT @@ -156,6 +158,18 @@ /// timer to limit triple clicks void doubleClickTimeout(); +private Q_SLOTS: + /// process vertical scroll bar event + void verticalScrollBarActionTriggered(); + /// + void verticalScrollBarSliderReleased(); + /// + void processKey(QKeyEvent * ev); + +Q_SIGNALS: + void updateScrollBar(); + void processKeySignal(QKeyEvent * ev); + private: /// The slot connected to SyntheticMouseEvent::timeout. void generateSyntheticMouseEvent(); @@ -177,6 +191,10 @@ bool schedule_redraw_; /// int preedit_lines_; + /// + bool waiting_for_key_processing; + /// + bool waiting_for_scrolling; }; } // namespace frontend