diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
index 96fe1fc..83868b2 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
@@ -3679,3 +3679,33 @@ void webkit_web_view_restore_session_state(WebKitWebView* webView, WebKitWebView
 
     getPage(webView)->restoreFromSessionState(webkitWebViewSessionStateGetSessionState(state), false);
 }
+
+/**
+ * webkit_web_view_set_size_request_mode:
+ * @web_view: a #WebKitWebView
+ * @mode: a #WebKitWebViewSizeRequestMode
+ *
+ * Sets the size request mode to @mode for the @web_view. The @WEBKIT_SIZE_REQUEST_DEFAULT mode
+ * provides native scrolling inside the @web_view, while the @WEBKIT_SIZE_REQUEST_CONTENTS mode
+ * requests @web_view<!-- -->'s size based on its content size, as computed for the allocated width.
+ * It's up the a parent widget(s) to provide scrolling functionality, if needed.
+ *
+ * Since: 2.14
+ */
+void webkit_web_view_set_size_request_mode(WebKitWebView* webView, WebKitWebViewSizeRequestMode mode)
+{
+    g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+
+    WebViewBaseSizeRequestMode baseMode = WebViewBaseSizeRequestMode::Default;
+    switch (mode) {
+    case WEBKIT_SIZE_REQUEST_DEFAULT:
+        baseMode = WebViewBaseSizeRequestMode::Default;
+        break;
+    case WEBKIT_SIZE_REQUEST_CONTENTS:
+        baseMode = WebViewBaseSizeRequestMode::Contents;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    webkitWebViewBaseSetSizeRequestMode(WEBKIT_WEB_VIEW_BASE(webView), baseMode);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
index 700968f..ad7eeb3 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
@@ -185,6 +185,21 @@ typedef enum {
   WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT,
 } WebKitSnapshotRegion;
 
+/**
+ * WebKitWebViewSizeRequestMode:
+ * @WEBKIT_SIZE_REQUEST_DEFAULT: Default size request, which means the web view will
+ * use its own scrollbars.
+ * @WEBKIT_SIZE_REQUEST_CONTENTS: Request height based on the content size,
+ * as computed for the allocated width. It's up the a parent widget(s) to provide
+ * scrolling functionality, if needed.
+ *
+ * Since: 2.14
+ */
+typedef enum {
+    WEBKIT_SIZE_REQUEST_DEFAULT,
+    WEBKIT_SIZE_REQUEST_CONTENTS,
+} WebKitWebViewSizeRequestMode;
+
 struct _WebKitWebView {
     WebKitWebViewBase parent;
 
@@ -513,6 +528,10 @@ WEBKIT_API void
 webkit_web_view_restore_session_state                (WebKitWebView             *web_view,
                                                       WebKitWebViewSessionState *state);
 
+WEBKIT_API void
+webkit_web_view_set_size_request_mode                (WebKitWebView             *web_view,
+                                                      WebKitWebViewSizeRequestMode mode);
+
 G_END_DECLS
 
 #endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
index cb0ae33..d6412be 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -192,6 +192,7 @@ struct _WebKitWebViewBasePrivate {
     KeyBindingTranslator keyBindingTranslator;
     TouchEventsMap touchEvents;
     IntSize contentsSize;
+    WebViewBaseSizeRequestMode sizeRequestMode;
 
     GtkWindow* toplevelOnScreenWindow;
     unsigned long toplevelFocusInEventID;
@@ -648,6 +649,10 @@ static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allo
 
     IntRect viewRect(allocation->x, allocation->y, allocation->width, allocation->height);
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (priv->sizeRequestMode == WebViewBaseSizeRequestMode::Default)
+        webViewBase->priv->pageProxy->setMinimumLayoutSize(IntSize(0, 0));
+    else
+        webViewBase->priv->pageProxy->setMinimumLayoutSize(IntSize(allocation->width, 1));
     if (priv->inspectorView) {
         GtkAllocation childAllocation = viewRect;
 
@@ -699,16 +704,35 @@ static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allo
 
 static void webkitWebViewBaseGetPreferredWidth(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
 {
+    GtkAllocation allocation;
     WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    *minimumSize = 0;
     *naturalSize = priv->contentsSize.width();
+    switch (priv->sizeRequestMode) {
+    case WebViewBaseSizeRequestMode::Contents:
+        gtk_widget_get_allocation(widget, &allocation);
+        if (allocation.width >= *naturalSize)
+            *minimumSize = 0;
+        else
+            *minimumSize = *naturalSize;
+        break;
+    case WebViewBaseSizeRequestMode::Default:
+        *minimumSize = 0;
+        break;
+    }
 }
 
 static void webkitWebViewBaseGetPreferredHeight(GtkWidget* widget, gint* minimumSize, gint* naturalSize)
 {
     WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    *minimumSize = 0;
     *naturalSize = priv->contentsSize.height();
+    switch (priv->sizeRequestMode) {
+    case WebViewBaseSizeRequestMode::Contents:
+        *minimumSize = *naturalSize;
+        break;
+    case WebViewBaseSizeRequestMode::Default:
+        *minimumSize = 0;
+        break;
+    }
 }
 
 static void webkitWebViewBaseMap(GtkWidget* widget)
@@ -1532,6 +1556,18 @@ void webkitWebViewBaseSetContentsSize(WebKitWebViewBase* webkitWebViewBase, cons
     if (priv->contentsSize == contentsSize)
         return;
     priv->contentsSize = contentsSize;
+    if (priv->sizeRequestMode != WebViewBaseSizeRequestMode::Default)
+        gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
+}
+
+void webkitWebViewBaseSetSizeRequestMode(WebKitWebViewBase* webkitWebViewBase, WebViewBaseSizeRequestMode mode)
+{
+    WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
+    if (priv->sizeRequestMode == mode)
+        return;
+    priv->sizeRequestMode = mode;
+    priv->pageProxy->setMainFrameIsScrollable(mode == WebViewBaseSizeRequestMode::Default);
+    gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
 }
 
 void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase)
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index 9842e00..0dc2fe4 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -57,6 +57,9 @@ void webkitWebViewBaseSetInputMethodState(WebKitWebViewBase*, bool enabled);
 void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase*);
 void webkitWebViewBaseSetContentsSize(WebKitWebViewBase*, const WebCore::IntSize&);
 
+enum class WebViewBaseSizeRequestMode { Default, Contents };
+void webkitWebViewBaseSetSizeRequestMode(WebKitWebViewBase*, WebViewBaseSizeRequestMode);
+
 void webkitWebViewBaseSetFocus(WebKitWebViewBase*, bool focused);
 bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase*);
 bool webkitWebViewBaseIsFocused(WebKitWebViewBase*);
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h
index 9cc2311..504f18c 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.h
+++ b/Source/WebKit2/UIProcess/WebPageProxy.h
@@ -550,9 +550,12 @@ public:
     void getCenterForZoomGesture(const WebCore::IntPoint& centerInViewCoordinates, WebCore::IntPoint& center);
 #endif
 
+#if PLATFORM(COCOA) || PLATFORM(GTK)
+    void setMainFrameIsScrollable(bool);
+#endif
+
 #if PLATFORM(COCOA)
     void windowAndViewFramesChanged(const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates);
-    void setMainFrameIsScrollable(bool);
 
     void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
     bool shouldDelayWindowOrderingForEvent(const WebMouseEvent&);
diff --git a/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp
index 2dbae05..c4e8144 100644
--- a/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp
+++ b/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp
@@ -148,4 +148,9 @@ void WebPageProxy::getCenterForZoomGesture(const WebCore::IntPoint& centerInView
 }
 #endif
 
+void WebPageProxy::setMainFrameIsScrollable(bool isScrollable)
+{
+    process().send(Messages::WebPage::SetMainFrameIsScrollable(isScrollable), m_pageID);
+}
+
 } // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
index 51953ed..8f73c61 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
@@ -520,7 +520,7 @@ void WebChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) con
     m_page->drawingArea()->mainFrameContentSizeChanged(size);
 
     FrameView* frameView = frame->view();
-    if (frameView && !frameView->delegatesScrolling())  {
+    if (frameView && !frameView->delegatesScrolling() && frameView->canHaveScrollbars())  {
         bool hasHorizontalScrollbar = frameView->horizontalScrollbar();
         bool hasVerticalScrollbar = frameView->verticalScrollbar();
 
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
index 75e0437..3005f3d 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
@@ -343,12 +343,15 @@ messages -> WebPage LegacyReceiver {
     GetCenterForZoomGesture(WebCore::IntPoint centerInViewCoordinates) -> (WebCore::IntPoint center)
 #endif
 
+#if PLATFORM(COCOA) || PLATFORM(GTK)
+    SetMainFrameIsScrollable(bool isScrollable)
+#endif
+
 #if PLATFORM(COCOA)
     # Complex text input support for plug-ins.
     SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput)
 
     WindowAndViewFramesChanged(WebCore::FloatRect windowFrameInScreenCoordinates, WebCore::FloatRect windowFrameInUnflippedScreenCoordinates, WebCore::FloatRect viewFrameInWindowCoordinates, WebCore::FloatPoint accessibilityViewCoordinates)
-    SetMainFrameIsScrollable(bool isScrollable)
     RegisterUIProcessAccessibilityTokens(IPC::DataReference elemenToken, IPC::DataReference windowToken)
     GetStringSelectionForPasteboard() -> (String stringValue)
     GetDataSelectionForPasteboard(String pasteboardType) -> (WebKit::SharedMemory::Handle handle, uint64_t size)
