diff --git a/examples/itemviews/spreadsheet/main.cpp b/examples/itemviews/spreadsheet/main.cpp
index 19bb379..ba63aa9 100644
--- a/examples/itemviews/spreadsheet/main.cpp
+++ b/examples/itemviews/spreadsheet/main.cpp
@@ -42,13 +42,15 @@
 #include <QtWidgets/QApplication>
 #include "spreadsheet.h"
 
+#include <QtWidgets/QLayout>
+
 int main(int argc, char** argv) {
     Q_INIT_RESOURCE(spreadsheet);
     QApplication app(argc, argv);
     SpreadSheet sheet(10, 6);
     sheet.setWindowIcon(QPixmap(":/images/interview.png"));
-    sheet.resize(640, 420);
     sheet.show();
+    sheet.layout()->setSizeConstraint( QLayout::SetFixedSize );
     return app.exec();
 }
 
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index aa4f8f5..c0bf780 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1116,6 +1116,7 @@ void QAbstractItemView::reset()
     }
 #endif
 #endif
+    updateGeometry();
 }
 
 /*!
@@ -1132,6 +1133,7 @@ void QAbstractItemView::setRootIndex(const QModelIndex &index)
     }
     d->root = index;
     d->doDelayedItemsLayout();
+    updateGeometry();
 }
 
 /*!
@@ -1614,6 +1616,9 @@ bool QAbstractItemView::event(QEvent *event)
     case QEvent::FontChange:
         d->doDelayedItemsLayout(); // the size of the items will change
         break;
+    case QEvent::Resize:
+        updateGeometries();
+        break;
 #ifdef QT_SOFTKEYS_ENABLED
     case QEvent::LanguageChange:
         d->doneSoftKey->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::DoneSoftKey));
@@ -2697,6 +2702,7 @@ void QAbstractItemView::updateGeometries()
 {
     updateEditorGeometries();
     d_func()->fetchMoreTimer.start(0, this); //fetch more later
+    updateGeometry();
 }
 
 /*!
@@ -3244,6 +3250,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
     d->updateEditorData(topLeft, bottomRight);
     if (!isVisible() || d->delayedPendingLayout)
         return; // no need to update
+    updateGeometry();
     d->viewport->update();
 }
 
@@ -3346,6 +3353,7 @@ void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int star
     }
 #endif
 #endif
+    q->updateGeometry();
 }
 
 /*!
@@ -3426,6 +3434,7 @@ void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int s
     }
 #endif
 #endif
+    q->updateGeometry();
 }
 
 
@@ -3440,15 +3449,16 @@ void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int sta
     Q_UNUSED(start)
     Q_UNUSED(end)
 
+    Q_Q(QAbstractItemView);
 #ifndef QT_NO_ACCESSIBILITY
 #ifdef Q_WS_X11
-    Q_Q(QAbstractItemView);
     if (QAccessible::isActive()) {
         QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end);
         QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
     }
 #endif
 #endif
+    q->updateGeometry();
 }
 
 /*!
@@ -3473,6 +3483,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
     }
 #endif
 #endif
+    q->updateGeometry();
 }
 
 /*!
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index ec629ca..1d00f73 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1055,6 +1055,27 @@ QTableView::~QTableView()
 /*!
   \reimp
 */
+QSize QTableView::viewportSizeHint() const
+{
+    Q_D(const QTableView);
+    QSize result( d->verticalHeader->isVisible()   ? d->verticalHeader->width() : 0,
+                  d->horizontalHeader->isVisible() ? d->horizontalHeader->height() : 0 );
+    for (int i = 0; i < d->horizontalHeader->count(); ++i) {
+        if (!d->horizontalHeader->isSectionHidden(i)) {
+            result.rwidth() += d->horizontalHeader->sectionSize(i);
+        }
+    }
+    for (int i = 0; i < d->verticalHeader->count(); ++i) {
+        if (!d->verticalHeader->isSectionHidden(i)) {
+            result.rheight() += d->verticalHeader->sectionSize(i);
+        }
+    }
+    return result;
+}
+
+/*!
+  \reimp
+*/
 void QTableView::setModel(QAbstractItemModel *model)
 {
     Q_D(QTableView);
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
index 29f3793..32cb1b0 100644
--- a/src/widgets/itemviews/qtableview.h
+++ b/src/widgets/itemviews/qtableview.h
@@ -120,6 +120,8 @@ public:
     void clearSpans();
 
     void sortByColumn(int column, Qt::SortOrder order);
+    
+    QSize viewportSizeHint() const;
 
 public Q_SLOTS:
     void selectRow(int row);
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 801160d..e541304 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -886,6 +886,8 @@ QWidgetList QAbstractScrollArea::scrollBarWidgets(Qt::Alignment alignment)
 void QAbstractScrollArea::setViewportMargins(int left, int top, int right, int bottom)
 {
     Q_D(QAbstractScrollArea);
+    if (d->left == left && d->top == top && d->right == right && d->bottom == bottom) 
+        return;
     d->left = left;
     d->top = top;
     d->right = right;
@@ -1477,13 +1479,25 @@ QSize QAbstractScrollArea::minimumSizeHint() const
 */
 QSize QAbstractScrollArea::sizeHint() const
 {
-    return QSize(256, 192);
-#if 0
     Q_D(const QAbstractScrollArea);
-    int h = qMax(10, fontMetrics().height());
-    int f = 2 * d->frameWidth;
-    return QSize((6 * h) + f, (4 * h) + f);
-#endif
+    const int f = 2 * d->frameWidth;
+    const QSize frame( f, f );
+    const QSize scrollbars( d->vbarpolicy == Qt::ScrollBarAlwaysOn ? d->vbar->sizeHint().width() : 0,
+                            d->hbarpolicy == Qt::ScrollBarAlwaysOn ? d->hbar->sizeHint().height() : 0 );
+    return frame + scrollbars + viewportSizeHint();
+}
+
+QSize QAbstractScrollArea::viewportSizeHint() const
+{
+    Q_D(const QAbstractScrollArea);
+    if (d->viewport) {
+        const QSize sh = d->viewport->sizeHint();
+        if (sh.isValid()) {
+            return sh;
+        }
+    }
+    const int h = qMax(10, fontMetrics().height());
+    return QSize(6 * h, 4 * h);
 }
 
 /*!
diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h
index 3f2a273..4f25ce3 100644
--- a/src/widgets/widgets/qabstractscrollarea.h
+++ b/src/widgets/widgets/qabstractscrollarea.h
@@ -90,6 +90,8 @@ public:
 
     QSize sizeHint() const;
 
+    virtual QSize viewportSizeHint() const;
+
 protected Q_SLOTS:
     void setupViewport(QWidget *viewport);
 
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index 48c179a..c323edb 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -385,30 +385,20 @@ void QScrollArea::setWidgetResizable(bool resizable)
 }
 
 /*!
-    \reimp
+   \reimp
  */
-QSize QScrollArea::sizeHint() const
+QSize QScrollArea::viewportSizeHint() const
 {
     Q_D(const QScrollArea);
-    int f = 2 * d->frameWidth;
-    QSize sz(f, f);
-    int h = fontMetrics().height();
     if (d->widget) {
-        if (!d->widgetSize.isValid())
-            d->widgetSize = d->resizable ? d->widget->sizeHint() : d->widget->size();
-        sz += d->widgetSize;
+        return d->resizable ? d->widget->sizeHint() : d->widget->size();
     } else {
-        sz += QSize(12 * h, 8 * h);
+        const int h = fontMetrics().height();
+        return QSize(12 * h, 8 * h);
     }
-    if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
-        sz.setWidth(sz.width() + d->vbar->sizeHint().width());
-    if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
-        sz.setHeight(sz.height() + d->hbar->sizeHint().height());
-    return sz.boundedTo(QSize(36 * h, 24 * h));
 }
 
 
-
 /*!
     \reimp
  */
diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h
index 2d62cc1..b94d4e2 100644
--- a/src/widgets/widgets/qscrollarea.h
+++ b/src/widgets/widgets/qscrollarea.h
@@ -71,7 +71,8 @@ public:
     bool widgetResizable() const;
     void setWidgetResizable(bool resizable);
 
-    QSize sizeHint() const;
+    QSize viewportSizeHint() const;
+    
     bool focusNextPrevChild(bool next);
 
     Qt::Alignment alignment() const;
