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