From 168405b68c8ce2dd174c86ce3938fbabff93efd7 Mon Sep 17 00:00:00 2001 From: Kevin Smith <git@kismith.co.uk> Date: Mon, 4 Oct 2010 11:26:17 +0100 Subject: Fix chat logs scrolling to bottom. (bug introduced since beta6) Resolves: #591 diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp index 1ad274f..70bb0e8 100644 --- a/Swift/QtUI/QtChatView.cpp +++ b/Swift/QtUI/QtChatView.cpp @@ -44,15 +44,13 @@ QtChatView::QtChatView(QtChatTheme* theme, QWidget* parent) : QWidget(parent) { mainLayout->addWidget(webView_); #endif - - - webPage_ = new QWebPage(this); webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); webView_->setPage(webPage_); connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard())); viewReady_ = false; + isAtBottom_ = true; resetView(); } @@ -76,7 +74,7 @@ QWebElement QtChatView::snippetToDOM(boost::shared_ptr<ChatSnippet> snippet) { } void QtChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) { - bool bottom = isScrolledToBottom(); + rememberScrolledToBottom(); QWebElement newElement = snippetToDOM(snippet); QWebElement continuationElement = lastElement_.findFirst("#insert"); if (snippet->getAppendToPrevious()) { @@ -87,27 +85,21 @@ void QtChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) { newInsertPoint_.prependOutside(newElement); } lastElement_ = newElement; - if (bottom) { - /* Warning: I'm not confident about this, although it does work.*/ - QTimer::singleShot(0, this, SLOT(scrollToBottom())); - } } void QtChatView::replaceLastMessage(const QString& newMessage) { assert(viewReady_); /* FIXME: must be queued? */ - bool bottom = isScrolledToBottom(); + rememberScrolledToBottom(); assert(!lastElement_.isNull()); QWebElement replace = lastElement_.findFirst("span.swift_message"); assert(!replace.isNull()); QString old = lastElement_.toOuterXml(); replace.setInnerXml(ChatSnippet::escape(newMessage)); - if (bottom) { - QTimer::singleShot(0, this, SLOT(scrollToBottom())); - } } void QtChatView::replaceLastMessage(const QString& newMessage, const QString& note) { + rememberScrolledToBottom(); replaceLastMessage(newMessage); QWebElement replace = lastElement_.findFirst("span.swift_time"); assert(!replace.isNull()); @@ -129,14 +121,21 @@ void QtChatView::setAckXML(const QString& id, const QString& xml) { ackElement.setInnerXml(xml); } -bool QtChatView::isScrolledToBottom() const { - return webPage_->mainFrame()->scrollBarValue(Qt::Vertical) == webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical); +void QtChatView::rememberScrolledToBottom() { + isAtBottom_ = webPage_->mainFrame()->scrollBarValue(Qt::Vertical) == webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical); } void QtChatView::scrollToBottom() { + isAtBottom_ = true; webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical)); } +void QtChatView::handleFrameSizeChanged() { + if (isAtBottom_) { + scrollToBottom(); + } +} + void QtChatView::handleLinkClicked(const QUrl& url) { QDesktopServices::openUrl(url); } @@ -180,6 +179,8 @@ void QtChatView::resetView() { newInsertPoint_.setOuterXml("<div id='swift_insert'/>"); chatElement.appendInside(newInsertPoint_); Q_ASSERT(!newInsertPoint_.isNull()); + + connect(webPage_->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), this, SLOT(handleFrameSizeChanged()), Qt::UniqueConnection); } } diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h index 8c1a99a..84738d4 100644 --- a/Swift/QtUI/QtChatView.h +++ b/Swift/QtUI/QtChatView.h @@ -30,7 +30,7 @@ namespace Swift { void addMessage(boost::shared_ptr<ChatSnippet> snippet); void replaceLastMessage(const QString& newMessage); void replaceLastMessage(const QString& newMessage, const QString& note); - bool isScrolledToBottom() const; + void rememberScrolledToBottom(); void setAckXML(const QString& id, const QString& xml); signals: @@ -45,6 +45,7 @@ namespace Swift { private slots: void handleViewLoadFinished(bool); + void handleFrameSizeChanged(); private: void headerEncode(); @@ -54,6 +55,7 @@ namespace Swift { QWebElement snippetToDOM(boost::shared_ptr<ChatSnippet> snippet); bool viewReady_; + bool isAtBottom_; QtWebView* webView_; QWebPage* webPage_; QList<boost::shared_ptr<ChatSnippet> > queuedSnippets_; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 6913747..a71cd43 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -349,8 +349,8 @@ void QtChatWindow::returnPressed() { if (!inputEnabled_) { return; } - onSendMessageRequest(Q2PSTRING(input_->toPlainText())); messageLog_->scrollToBottom(); + onSendMessageRequest(Q2PSTRING(input_->toPlainText())); inputClearing_ = true; input_->clear(); inputClearing_ = false; -- cgit v0.10.2-6-g49f6