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

Reply via email to