Bug 181742

Summary: article list columns can resize themselves when new articles arrive
Product: [Applications] akregator Reporter: Jonathan Marten <jjm>
Component: generalAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED UPSTREAM    
Severity: normal CC: dominik.stadler, Stefan.Borggraefe
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Jonathan Marten 2009-01-24 13:23:26 UTC
Version:            (using Devel)
OS:                Linux
Installed from:    Compiled sources

Found this bug while investigating another list view problem in Akregator, bug 152702.  However, this is not the same problem - so opening a new bug to avoid cluttering that.

Even with the commits from 152702, there seems to be still a problem where the feed columns will sometimes automatically resize themselves even where there is no user interaction.  To reproduce, resize or hide article list columns as desired, then open an article in a new tab.  Leave that tab open (so that the article list view is hidden), then wait for new articles to arrive in that feed.  After some new articles have arrived, switch back to the article list tab - the columns will have resized themselves.

When this happens, the article list view is getting the signal QHeaderView::sectionResized(int,int,int) from its header().  Catching this with gdb results in the following backtrace (ArticleListView::hdrResized() is a function that I've added in order to catch the signal, higher frames snipped):

Breakpoint 2, Akregator::ArticleListView::hdrResized (this=0x81dc650, li=0, o=0, n=0)
    at /ws/trunk/kdepim-trunk/akregator/src/articlelistview.cpp:197
197         QObject *s = sender();
(gdb) where
#0  Akregator::ArticleListView::hdrResized (this=0x81dc650, li=0, o=0, n=0)
    at /ws/trunk/kdepim-trunk/akregator/src/articlelistview.cpp:197
#1  0xb32d9050 in Akregator::ArticleListView::qt_metacall (this=0x81ea5c8,
    _c=QMetaObject::InvokeMetaMethod, _id=10, _a=0xbfdb7ec8)
    at /ws/BUILD.keelhaul/kdepim-trunk-BUILD/akregator/src/articlelistview.moc:181
#2  0xb6cca575 in QMetaObject::activate (sender=0x81f8250, from_signal_index=<value optimized out>,
    to_signal_index=69, argv=0x81dc650) at kernel/qobject.cpp:3028
#3  0xb6ccacb5 in QMetaObject::activate (sender=0x81f8250, m=0xb699a0f8, local_signal_index=1,
    argv=0xbfdb7ec8) at kernel/qobject.cpp:3101
#4  0xb677cca5 in QHeaderView::sectionResized (this=0x81f8250, _t1=0, _t2=672, _t3=392)
    at .moc/debug-shared/moc_qheaderview.cpp:214
#5  0xb678944c in QHeaderView::resizeSection (this=0x81f8250, logical=0, size=392)
    at itemviews/qheaderview.cpp:887
#6  0xb67b95b1 in QTreeView::resizeColumnToContents (this=0x81ea5c8, column=0)
    at itemviews/qtreeview.cpp:2485
#7  0xb67b962c in QTreeViewPrivate::_q_forceColumnResizeToFitContents (this=0x827be30)
    at itemviews/qtreeview.cpp:2994
#8  0xb67c7f57 in QTreeView::qt_metacall (this=0x81ea5c8, _c=QMetaObject::InvokeMetaMethod, _id=23,
    _a=0xbfdb80f8) at .moc/debug-shared/moc_qtreeview.cpp:149
#9  0xb32d8fb2 in Akregator::ArticleListView::qt_metacall (this=0x81ea5c8,
    _c=QMetaObject::InvokeMetaMethod, _id=91, _a=0xbfdb80f8)
    at /ws/BUILD.keelhaul/kdepim-trunk-BUILD/akregator/src/articlelistview.moc:166
#10 0xb6cca575 in QMetaObject::activate (sender=0x82c9b78, from_signal_index=<value optimized out>,
    to_signal_index=9, argv=0x81dc650) at kernel/qobject.cpp:3028
#11 0xb6ccacb5 in QMetaObject::activate (sender=0x82c9b78, m=0xb6d665b8, local_signal_index=5,
    argv=0xbfdb80f8) at kernel/qobject.cpp:3101
#12 0xb6d0edf5 in QAbstractItemModel::rowsInserted (this=0x82c9b78, _t1=@0xbfdb8134, _t2=0, _t3=0)
    at .moc/debug-shared/moc_qabstractitemmodel.cpp:157
#13 0xb6cace0b in QAbstractItemModel::endInsertRows (this=0x82c9b78)
    at kernel/qabstractitemmodel.cpp:2092
#14 0xb681a2f9 in QSortFilterProxyModelPrivate::insert_source_items (this=0x85b2e38,
    source_to_proxy=@0x8514d60, proxy_to_source=@0x8514d58, source_items=@0xbfdb8288,
    source_parent=@0xbfdb83e4, orient=Qt::Vertical, emit_signal=true)
    at itemviews/qsortfilterproxymodel.cpp:585
#15 0xb681bd14 in QSortFilterProxyModelPrivate::source_items_inserted (this=0x85b2e38,
    source_parent=@0xbfdb83e4, start=3107, end=3107, orient=Qt::Vertical)
    at itemviews/qsortfilterproxymodel.cpp:680

Looking higher up the stack leads to the following code in QTreeView:

(gdb) up 7
#7  0xb67b962c in QTreeViewPrivate::_q_forceColumnResizeToFitContents (this=0x827be30)
    at itemviews/qtreeview.cpp:2994
2994            q->resizeColumnToContents(q->currentIndex().column());
(gdb) p header
$1 = (class QHeaderView *) 0x81f8250
(gdb) p header->count()
$2 = 4
(gdb) p header->hiddenSectionCount()
$3 = 2
(gdb) p header->isVisible()
$4 = false
(gdb) p header->isHidden()
$5 = false
(gdb)

This function says:

void QTreeViewPrivate::_q_forceColumnResizeToFitContents()
{
    Q_Q(QTreeView);

    /**
      * if:
      *
      * a) The tree view has no header (user cannot resize the column) OR
      * b) The tree view has a header, but hidden (user cannot resize the column) OR
      * c) The tree view has a visible header, but with _only_ one (or zero) column (that
      *    means: no other information will be affected).
      *
      * We can expand the column to make the contents properly visible.
      */
    if (!header || !header->isVisible() || ((header->count() - header->hiddenSectionCount()) <= 1)) {
        q->resizeColumnToContents(q->currentIndex().column());
    }
}

Possibly the logic here is wrong - the conditional for case (b) should use isHidden() instead of !isVisible().  The header can be 'not visible' as a result of a parent widget being hidden, in this case where another tab is displayed so hiding the treeview, but it will not be 'hidden'.  This has the effect in Akregator of automatically resizing the columns when new articles arrive.

The correct test to use ought to be 'hidden', which allows the case where the treeview has no header but will not cause a resize when the treeview is merely hidden by a parent.

Changing that line as follows:

    if (!header || header->isHidden() || ((header->count() - header->hiddenSectionCount()) <= 1)) {

and rebuilding Qt eliminates the automatic column resizing problem in Akregator.

This may be a bug in Qt - should it be reported upstream?
Comment 1 Jonathan Marten 2009-01-30 16:44:16 UTC
Reported upstream as http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=242901
Comment 2 Jonathan Marten 2009-06-26 13:42:03 UTC
Qt issue closed as a duplicate, although no indication of what it is a duplicate of...