--- khtml/khtmlview.cpp.sav 2005-03-14 10:53:55.116596234 +0100 +++ khtml/khtmlview.cpp 2005-03-14 11:00:50.210653569 +0100 @@ -146,6 +146,9 @@ public: KHTMLViewPrivate() : underMouse( 0 ), underMouseNonShared( 0 ) +#ifndef NO_SMOOTH_SCROLL_HACK + , dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false) +#endif { #ifndef KHTML_NO_CARET m_caretViewContext = 0; @@ -381,6 +384,17 @@ public: int m_mouseScroll_byY : 4; QTimer *m_mouseScrollTimer; QWidget *m_mouseScrollIndicator; +#ifndef NO_SMOOTH_SCROLL_HACK + QTimer timer2; + int dx; + int dy; + // Step size * 16 and residual to avoid huge difference between 1px/step and 2px/step + int ddx; + int ddy; + int rdx; + int rdy; + bool scrolling; +#endif }; #ifndef QT_NO_TOOLTIP @@ -489,6 +503,11 @@ KHTMLView::KHTMLView( KHTMLPart *part, Q init(); viewport()->show(); +#ifndef NO_SMOOTH_SCROLL_HACK +#define timer timer2 + connect(&d->timer, SIGNAL(timeout()), this, SLOT(scrollTick())); +#undef timer +#endif } KHTMLView::~KHTMLView() @@ -1657,8 +1676,16 @@ void KHTMLView::keyReleaseEvent(QKeyEven d->scrollSuspendPreActivate = false; if( _ke->key() == Key_Shift && d->scrollSuspendPreActivate && _ke->state() == Qt::ShiftButton && !(KApplication::keyboardMouseState() & Qt::ShiftButton)) + { if (d->scrollTimerId) - d->scrollSuspended = !d->scrollSuspended; + { + d->scrollSuspended = !d->scrollSuspended; +#ifndef NO_SMOOTH_SCROLL_HACK + if( d->scrollSuspended ) + stopScrolling(); +#endif + } + } // Send keyup event if ( dispatchKeyEvent( _ke ) ) @@ -2797,7 +2824,11 @@ void KHTMLView::viewportWheelEvent(QWhee else { d->scrollBarMoved = true; +#ifndef NO_SMOOTH_SCROLL_HACK + scrollViewWheelEvent( e ); +#else QScrollView::viewportWheelEvent( e ); +#endif QMouseEvent *tempEvent = new QMouseEvent( QEvent::MouseMove, QPoint(-1,-1), QPoint(-1,-1), Qt::NoButton, e->state() ); emit viewportMouseMoveEvent ( tempEvent ); @@ -3986,4 +4017,109 @@ void KHTMLView::moveCaretToLineEnd() #endif // KHTML_NO_CARET +#ifndef NO_SMOOTH_SCROLL_HACK +#define timer timer2 + +// All scrolls must be completed within 240ms of last keypress +static const int SCROLL_TIME = 240; +// Each step is 20 ms == 50 frames/second +static const int SCROLL_TICK = 20; + +void KHTMLView::scrollBy(int dx, int dy) +{ + KConfigGroup cfg( KGlobal::config(), "KDE" ); + if( !cfg.readBoolEntry( "SmoothScrolling", true )) { + QScrollView::scrollBy( dx, dy ); + return; + } + // scrolling destination + int full_dx = d->dx + dx; + int full_dy = d->dy + dy; + + // scrolling speed + int ddx = 0; + int ddy = 0; + + int steps = SCROLL_TIME/SCROLL_TICK; + + ddx = (full_dx*16)/steps; + ddy = (full_dy*16)/steps; + + // don't go under 1px/step + if (ddx > 0 && ddx < 16) ddx = 16; + if (ddy > 0 && ddy < 16) ddy = 16; + if (ddx < 0 && ddx > -16) ddx = -16; + if (ddy < 0 && ddy > -16) ddy = -16; + + d->dx = full_dx; + d->dy = full_dy; + d->ddx = ddx; + d->ddy = ddy; + + if (!d->scrolling) { + scrollTick(); + startScrolling(); + } +} + +void KHTMLView::scrollTick() { + if (d->dx == 0 && d->dy == 0) { + stopScrolling(); + return; + } + + int tddx = d->ddx + d->rdx; + int tddy = d->ddy + d->rdy; + + int ddx = tddx / 16; + int ddy = tddy / 16; + d->rdx = tddx % 16; + d->rdy = tddy % 16; + + if (d->dx > 0 && ddx > d->dx) ddx = d->dx; + else + if (d->dx < 0 && ddx < d->dx) ddx = d->dx; + + if (d->dy > 0 && ddy > d->dy) ddy = d->dy; + else + if (d->dy < 0 && ddy < d->dy) ddy = d->dy; + + d->dx -= ddx; + d->dy -= ddy; + +// QScrollView::setContentsPos( contentsX() + ddx, contentsY() + ddy); + QScrollView::scrollBy(ddx, ddy); +} + +void KHTMLView::startScrolling() +{ + d->scrolling = true; + d->timer.start(SCROLL_TICK, false); +} + +void KHTMLView::stopScrolling() +{ + d->timer.stop(); + d->dx = d->dy = 0; + d->scrolling = false; +} + +// Overloaded from QScrollView and QScrollBar +void KHTMLView::scrollViewWheelEvent( QWheelEvent *e ) +{ + int pageStep = verticalScrollBar()->pageStep(); + int lineStep = verticalScrollBar()->lineStep(); + int step = QMIN( QApplication::wheelScrollLines()*lineStep, pageStep ); + if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) + step = pageStep; + + int dy = (e->delta()*step)/120; + scrollBy(0,-dy); + e->accept(); +} + +#undef timer + +#endif // NO_SMOOTH_SCROLL_HACK + #undef DEBUG_CARETMODE --- khtml/khtmlview.h.sav 2005-03-14 10:53:53.502840927 +0100 +++ khtml/khtmlview.h 2005-03-14 10:54:04.049241779 +0100 @@ -175,6 +175,11 @@ signals: void zoomView( int ); void hideAccessKeys(); void repaintAccessKeys(); +//#define NO_SMOOTH_SCROLL_HACK +#ifndef NO_SMOOTH_SCROLL_HACK +public slots: + void scrollBy(int dx, int dy); +#endif protected: void clear(); @@ -206,9 +211,22 @@ protected: void doAutoScroll(); void timerEvent ( QTimerEvent * ); +#ifndef NO_SMOOTH_SCROLL_HACK + void startScrolling(); + void stopScrolling(); +#ifndef QT_NO_WHEELEVENT + void scrollViewWheelEvent( QWheelEvent* e ); +#endif +#endif + protected slots: void slotPaletteChanged(); void slotScrollBarMoved(); +#ifndef NO_SMOOTH_SCROLL_HACK + void scrollTick(); +#else + void scrollTick() {}; // moc cannot handle #if +#endif private slots: void tripleClickTimeout();