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();
 

Reply via email to