Version: CVS (using KDE Devel) Using KATE. Set config so that you don't autowrap. Now shrink the window until you get a horizonal scrollbar. Jump to the end of file. Note last line of file is obscured behind the scrollbar.
This is more complicated that it appears. I can't consistently reproduce it, but I can sometimes get it back. It seems to be a function of how long the lines are above the last line and when they trigger the scrollbar to appear. KATE does the right thing most of the time. Not a high priority problem.
I think this always works: make all the lines on the first page short enough to not have a scrollbar make a long line near the end of the file but not the end Ctrl-home to the beginning. Ctrl-end to the end Last line will be behind the horiz scrollbar that appeared in the jump
The bug might be in the jump to end code. In this condition when I jump to the scroll position is 2 lines off from the bottom. There might be a +/- 1 that has the wrong sign. By doing down arrows I can make the last line appear.
Do you see this bug in Kate/KWrite as well?
I only have kdevelop built so I can't tell. I think I know what the bug is. Start at the top of the file with the scroll bar off. Jump to the bottom. The calculation for how many lines are visible has already been done. It controls where the top of the window is for the last pages. But now when the window paints the scrollbar is enabled. This messes up the top of window calculation. It only impact the last window full and text and when jumping from an area without a scrollbar to one with. I have made this same bug in code I have written. The problem is that the last page of the file needs to be special cased. The general code doesn't work right on the last page.
this bug is probably in Kate part
*** Bug 78135 has been marked as a duplicate of this bug. ***
*** Bug 100477 has been marked as a duplicate of this bug. ***
SVN commit 478300 by cullmann: BUG: 56301 BUG: 71577 don't hide the horizontal scrollbar, just disable it if not needed, will forward port to KDE 4 trunk soon, this should solve many problems at once, no artefacts while scrolling, no wrong positioning, no hiding of lines, no probs, world peace :) On kwrite-devel@kde.org, please review for any big faults ;) CCMAIL: kwrite-devel@kde.org M +37 -100 kateviewinternal.cpp M +4 -3 kateviewinternal.h --- branches/KDE/3.5/kdelibs/kate/part/kateviewinternal.cpp #478299:478300 @@ -64,7 +64,6 @@ , m_madeVisible(false) , m_shiftKeyPressed (false) , m_autoCenterLines (false) - , m_columnScrollDisplayed(false) , m_selChangedByUser (false) , selectAnchor (-1, -1) , m_selectionMode( Default ) @@ -106,15 +105,17 @@ m_colLayout->addWidget(m_lineScroll); m_lineLayout->addLayout(m_colLayout); - if (!m_view->dynWordWrap()) - { - // bottom corner box - m_dummy = new QWidget(m_view); - m_dummy->setFixedHeight(style().scrollBarExtent().width()); + // bottom corner box + m_dummy = new QWidget(m_view); + m_dummy->setFixedHeight(style().scrollBarExtent().width()); + + if (m_view->dynWordWrap()) + m_dummy->hide(); + else m_dummy->show(); - m_lineLayout->addWidget(m_dummy); - } + m_lineLayout->addWidget(m_dummy); + // Hijack the line scroller's controls, so we can scroll nicely for word-wrap connect(m_lineScroll, SIGNAL(prevPage()), SLOT(scrollPrevPage())); connect(m_lineScroll, SIGNAL(nextPage()), SLOT(scrollNextPage())); @@ -132,7 +133,13 @@ // scrollbar for columns // m_columnScroll = new QScrollBar(QScrollBar::Horizontal,m_view); - m_columnScroll->hide(); + + // hide the column scrollbar in the dynamic word wrap mode + if (m_view->dynWordWrap()) + m_columnScroll->hide(); + else + m_columnScroll->show(); + m_columnScroll->setTracking(true); m_startX = 0; m_oldStartX = 0; @@ -226,20 +233,13 @@ { if (m_view->dynWordWrap()) { - delete m_dummy; - m_dummy = 0; m_columnScroll->hide(); - m_columnScrollDisplayed = false; - + m_dummy->hide (); } else { - // bottom corner box - m_dummy = new QWidget(m_view); - m_dummy->setFixedSize( style().scrollBarExtent().width(), - style().scrollBarExtent().width() ); - m_dummy->show(); - m_lineLayout->addWidget(m_dummy); + m_columnScroll->show(); + m_dummy->show (); } tagAll(); @@ -251,20 +251,7 @@ // Determine where the cursor should be to get the cursor on the same view line if (m_wrapChangeViewLine != -1) { KateTextCursor newStart = viewLineOffset(displayCursor, -m_wrapChangeViewLine); - - // Account for the scrollbar in non-dyn-word-wrap mode - if (!m_view->dynWordWrap() && scrollbarVisible(newStart.line())) { - int lines = linesDisplayed() - 1; - - if (m_view->height() != height()) - lines++; - - if (newStart.line() + lines == displayCursor.line()) - newStart = viewLineOffset(displayCursor, 1 - m_wrapChangeViewLine); - } - makeVisible(newStart, newStart.col(), true); - } else { update(); } @@ -385,14 +372,6 @@ m_cachedMaxStartPos = viewLineOffset(end, -((int)linesDisplayed() - 1)); } - // If we're not dynamic word-wrapping, the horizontal scrollbar is hidden and will appear, increment the maxStart by 1 - if (!m_view->dynWordWrap() && m_columnScroll->isHidden() && scrollbarVisible(m_cachedMaxStartPos.line())) - { - KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1))); - - return viewLineOffset(end, -(int)linesDisplayed()); - } - m_usePlainLines = false; return m_cachedMaxStartPos; @@ -715,34 +694,23 @@ lineRanges[z].clear(); } - if (scrollbarVisible(startLine())) - { - m_columnScroll->blockSignals(true); + m_columnScroll->blockSignals(true); - int max = maxLen(startLine()) - width(); - if (max < 0) - max = 0; + int max = maxLen(startLine()) - width(); + if (max < 0) + max = 0; - m_columnScroll->setRange(0, max); + // disable scrollbar + m_columnScroll->setDisabled (max == 0); - m_columnScroll->setValue(m_startX); + m_columnScroll->setRange(0, max); - // Approximate linescroll - m_columnScroll->setSteps(m_view->renderer()->config()->fontMetrics()->width('a'), width()); + m_columnScroll->setValue(m_startX); - m_columnScroll->blockSignals(false); + // Approximate linescroll + m_columnScroll->setSteps(m_view->renderer()->config()->fontMetrics()->width('a'), width()); - if (!m_columnScroll->isVisible () && !m_suppressColumnScrollBar) - { - m_columnScroll->show(); - m_columnScrollDisplayed = true; - } - } - else if (!m_suppressColumnScrollBar && (startX() == 0)) - { - m_columnScroll->hide(); - m_columnScrollDisplayed = false; - } + m_columnScroll->blockSignals(false); } m_updatingView = false; @@ -820,11 +788,6 @@ else if ( c > viewLineOffset(endPos(), -m_minLinesVisible) ) { KateTextCursor scroll = viewLineOffset(c, -((int)linesDisplayed() - m_minLinesVisible - 1)); - - if (!m_view->dynWordWrap() && m_columnScroll->isHidden()) - if (scrollbarVisible(scroll.line())) - scroll.setLine(scroll.line() + 1); - scrollPos(scroll, false, calledExternally); } else if ( c < viewLineOffset(startPos(), m_minLinesVisible) ) @@ -1859,19 +1822,6 @@ int linesToScroll = -QMAX( ((int)linesDisplayed() - 1) - lineadj, 0 ); m_preserveMaxX = true; - // don't scroll the full view in case the scrollbar appears - if (!m_view->dynWordWrap()) { - if (scrollbarVisible(startLine() + linesToScroll + viewLine)) { - if (!m_columnScrollDisplayed) { - linesToScroll++; - } - } else { - if (m_columnScrollDisplayed) { - linesToScroll--; - } - } - } - if (!m_doc->pageUpDownMovesCursor () && !atTop) { int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX; @@ -1921,19 +1871,6 @@ int linesToScroll = QMAX( (linesDisplayed() - 1) - lineadj, 0 ); m_preserveMaxX = true; - // don't scroll the full view in case the scrollbar appears - if (!m_view->dynWordWrap()) { - if (scrollbarVisible(startLine() + linesToScroll + viewLine - (linesDisplayed() - 1))) { - if (!m_columnScrollDisplayed) { - linesToScroll--; - } - } else { - if (m_columnScrollDisplayed) { - linesToScroll--; - } - } - } - if (!m_doc->pageUpDownMovesCursor () && !atEnd) { int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX; @@ -1962,11 +1899,6 @@ } } -bool KateViewInternal::scrollbarVisible(uint startLine) -{ - return maxLen(startLine) > width() - 8; -} - int KateViewInternal::maxLen(uint startLine) { // Q_ASSERT(!m_view->dynWordWrap()); @@ -3108,7 +3040,7 @@ leftBorder->update(); } - } else if (!m_columnScroll->isHidden()) { + } else if (columnScrollingPossible()) { QWheelEvent copy = *e; QApplication::sendEvent(m_columnScroll, ©); @@ -3154,7 +3086,7 @@ if (dy) scrollLines(startPos().line() + dy); - if (!m_view->dynWordWrap() && m_columnScrollDisplayed && dx) + if (columnScrollingPossible () && dx) scrollColumns(kMin (m_startX + dx, m_columnScroll->maxValue())); if (!dy && !dx) @@ -3174,6 +3106,11 @@ m_textHintTimer.stop (); } +bool KateViewInternal::columnScrollingPossible () +{ + return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maxValue() > 0); +} + //BEGIN EDIT STUFF void KateViewInternal::editStart() { --- branches/KDE/3.5/kdelibs/kate/part/kateviewinternal.h #478299:478300 @@ -268,7 +268,6 @@ // column scrollbar + x position // QScrollBar *m_columnScroll; - bool m_columnScrollDisplayed; int m_startX; int m_oldStartX; @@ -289,9 +288,11 @@ // QMemArray<KateLineRange> lineRanges; - // Used to determine if the scrollbar will appear/disappear in non-wrapped mode - bool scrollbarVisible(uint startLine); + // maximal lenght of textlines visible from given startLine int maxLen(uint startLine); + + // are we allowed to scroll columns? + bool columnScrollingPossible (); // returns the maximum X value / col value a cursor can take for a specific line range int lineMaxCursorX(const KateLineRange& range);