Dov Feldstern wrote:
> (I hope I'm referring to the correct version of the patch:) As Helge
> already reported, on very slow systems (I tested this by running under
> valgrind), if you type quickly, some keystrokes get swallowed...

Nice idea to slow down with valgrind.

I've reproduced the error and fixed it.
The problem was, not only page up/down keys were dropped.
This code does not work (because of the implicit casts?)

static const int delayed_keys = Qt::Key_PageDown | Qt::Key_PageUp;
if (e->key() & delayed_keys) {

I have to replace it by

if (e->key() == Qt::Key_PageDown || e->key() == Qt::Key_PageUp) {


With running valgrind I could also reproduce the scroll bar
behavior reported by Helge, but here I could fix it with
the patch.

Attached the updated patch.

Peter
Index: src/frontends/qt4/GuiWorkArea.cpp
===================================================================
--- src/frontends/qt4/GuiWorkArea.cpp   (revision 18512)
+++ 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 int id;
+       static bool locked;
+};
+
+// Qt doc: user event type between 1000 and 65535
+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 int id;
+       static bool locked;
+};
+
+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,30 @@
 }
 
 
-void GuiWorkArea::adjustViewWithScrollBar(int)
+void GuiWorkArea::lyxScrollEvent()
 {
        scrollBufferView(verticalScrollBar()->sliderPosition());
 }
 
 
+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 +457,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();
 
@@ -414,7 +483,26 @@
 
 void GuiWorkArea::keyPressEvent(QKeyEvent * e)
 {
+       if (e->key() == Qt::Key_PageDown || e->key() == Qt::Key_PageUp) {
+               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())
@@ -427,6 +515,7 @@
        processKeySym(sym, q_key_state(e->modifiers()));
 }
 
+
 void GuiWorkArea::doubleClickTimeout() {
        dc_event_.active = false;
 }
Index: src/frontends/qt4/GuiWorkArea.h
===================================================================
--- src/frontends/qt4/GuiWorkArea.h     (revision 18512)
+++ 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();
 

Reply via email to