diff --git a/lib/quick/qquickwebengineview_p_p.h b/lib/quick/qquickwebengineview_p_p.h
index 947886c441f2450e1e6631d5c4dc713605d3adf0..54bc21628d9c6a1d7378a131429677ff433ad78f 100644
--- a/lib/quick/qquickwebengineview_p_p.h
+++ b/lib/quick/qquickwebengineview_p_p.h
@@ -68,6 +68,7 @@ public:
     virtual void loadFinished(bool success) Q_DECL_OVERRIDE;
     virtual void focusContainer() Q_DECL_OVERRIDE;
     virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition) Q_DECL_OVERRIDE;
+    virtual bool contextMenuRequested(const WebEngineContextMenuData &) Q_DECL_OVERRIDE { return false;}
 
     QExplicitlySharedDataPointer<WebContentsAdapter> adapter;
     QUrl icon;
diff --git a/lib/web_contents_adapter_client.h b/lib/web_contents_adapter_client.h
index 39968a8a503d9ffce9c5c85e8969395efa5b3f35..8e92ead7c1f97968777edf0a354596cd06daca20 100644
--- a/lib/web_contents_adapter_client.h
+++ b/lib/web_contents_adapter_client.h
@@ -47,12 +47,28 @@
 #include <QString>
 #include <QUrl>
 
-
 class RenderWidgetHostViewQt;
 class RenderWidgetHostViewQtDelegate;
 class WebContentsAdapter;
 class WebContentsDelegateQt;
 
+// FIXME: make this ref-counted and implicitely shared and expose as public API maybe ?
+class WebEngineContextMenuData {
+
+public:
+    QPoint pos;
+    QUrl linkUrl;
+    QString linkText;
+    QString selectedText;
+// Some likely candidates for future additions as we add support for the related actions:
+//    bool isImageBlocked;
+//    bool isEditable;
+//    bool isSpellCheckingEnabled;
+//    QStringList spellCheckingSuggestions;
+//    <enum tbd> mediaType;
+//    ...
+};
+
 class QWEBENGINE_EXPORT WebContentsAdapterClient {
 public:
     enum CompositingMode {
@@ -87,6 +103,7 @@ public:
     virtual void loadFinished(bool success) = 0;
     virtual void focusContainer() = 0;
     virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition) = 0;
+    virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0;
 };
 
 #endif // WEB_CONTENTS_ADAPTER_CLIENT_H
diff --git a/lib/web_contents_view_qt.cpp b/lib/web_contents_view_qt.cpp
index 340075c9a6d1c935f549feffd2538dba5ce80700..8fc7f5b12bed9c92e6fb41f742cc243e3db01ff3 100644
--- a/lib/web_contents_view_qt.cpp
+++ b/lib/web_contents_view_qt.cpp
@@ -48,6 +48,7 @@
 #include "base/command_line.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/context_menu_params.h"
 
 void WebContentsViewQt::initialize(WebContentsAdapterClient* client)
 {
@@ -111,3 +112,19 @@ void WebContentsViewQt::SetInitialFocus()
 {
     Focus();
 }
+
+static WebEngineContextMenuData fromParams(const content::ContextMenuParams &params)
+{
+    WebEngineContextMenuData ret;
+    ret.pos = QPoint(params.x, params.y);
+    ret.linkUrl = toQt(params.link_url);
+    ret.linkText = toQt(params.link_text.data());
+    ret.selectedText = toQt(params.selection_text.data());
+    return ret;
+}
+
+void WebContentsViewQt::ShowContextMenu(const content::ContextMenuParams &params)
+{
+    WebEngineContextMenuData contextMenuData(fromParams(params));
+    m_client->contextMenuRequested(contextMenuData);
+}
diff --git a/lib/web_contents_view_qt.h b/lib/web_contents_view_qt.h
index b76c725455ed54b70812568235304a459fbd378f..d71369762246cc8ae257605df2d539111648f3ce 100644
--- a/lib/web_contents_view_qt.h
+++ b/lib/web_contents_view_qt.h
@@ -107,6 +107,8 @@ public:
     virtual void ShowPopupMenu(const gfx::Rect& bounds, int item_height, double item_font_size, int selected_item,
                                 const std::vector<content::MenuItem>& items, bool right_aligned, bool allow_multiple_selection) { QT_NOT_YET_IMPLEMENTED }
 
+    virtual void ShowContextMenu(const content::ContextMenuParams &params);
+
 #if defined(OS_MACOSX)
     virtual void SetAllowOverlappingViews(bool overlapping) { QT_NOT_YET_IMPLEMENTED }
     virtual void CloseTabAfterEventTracking() { QT_NOT_YET_IMPLEMENTED }
diff --git a/lib/widgets/Api/qwebenginepage.cpp b/lib/widgets/Api/qwebenginepage.cpp
index 8fafb3c47434d7d52d8955bdafca9f587ae1bb75..b956a878584e62430538604e4746eae6f58f6b9e 100644
--- a/lib/widgets/Api/qwebenginepage.cpp
+++ b/lib/widgets/Api/qwebenginepage.cpp
@@ -31,7 +31,11 @@
 #include "web_contents_adapter.h"
 
 #include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QIcon>
 #include <QLayout>
+#include <QMenu>
 #include <QUrl>
 
 QT_BEGIN_NAMESPACE
@@ -269,6 +273,78 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
     }
 }
 
+bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data)
+{
+    if (!view)
+        return false;
+
+    QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos));
+    switch (view->contextMenuPolicy()) {
+    case Qt::PreventContextMenu:
+        return false;
+    case Qt::DefaultContextMenu:
+        m_menuData = data;
+        view->contextMenuEvent(&event);
+        break;
+    case Qt::CustomContextMenu:
+        Q_EMIT view->customContextMenuRequested(data.pos);
+        break;
+    case Qt::ActionsContextMenu:
+        if (view->actions().count()) {
+            QMenu::exec(view->actions(), event.globalPos(), 0, view);
+            break;
+        }
+        // fall through
+    default:
+        event.ignore();
+        return false;
+        break;
+    }
+    Q_ASSERT(view->d_func()->m_pendingContextMenuEvent);
+    view->d_func()->m_pendingContextMenuEvent = false;
+    m_menuData = WebEngineContextMenuData();
+    return true;
+}
+
+QMenu *QWebEnginePage::createStandardContextMenu()
+{
+    Q_D(QWebEnginePage);
+    QMenu *menu = new QMenu(d->view);
+    QAction *action = 0;
+    WebEngineContextMenuData contextMenuData(d->m_menuData);
+    if (contextMenuData.selectedText.isEmpty()) {
+        action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu);
+        connect(action, &QAction::triggered, d->view, &QWebEngineView::back);
+        action->setEnabled(d->adapter->canGoBack());
+        menu->addAction(action);
+
+        action = new QAction(QIcon::fromTheme(QStringLiteral("go-next")), tr("&Forward"), menu);
+        connect(action, &QAction::triggered, d->view, &QWebEngineView::forward);
+        action->setEnabled(d->adapter->canGoForward());
+        menu->addAction(action);
+
+        action = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), tr("&Reload"), menu);
+        connect(action, &QAction::triggered, d->view, &QWebEngineView::reload);
+        menu->addAction(action);
+    } else {
+        action = new QAction(tr("Copy..."), menu);
+        // FIXME: We probably can't keep "cheating" with lambdas, but for now it keeps this patch smaller ;)
+        connect(action, &QAction::triggered, [=]() { qApp->clipboard()->setText(contextMenuData.selectedText); });
+        menu->addAction(action);
+    }
+
+    if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
+        menu->addSeparator();
+        action = new QAction(tr("Navigate to..."), menu);
+        connect(action, &QAction::triggered, [=]() { load(contextMenuData.linkUrl); });
+        menu->addAction(action);
+        action = new QAction(tr("Copy link address"), menu);
+        connect(action, &QAction::triggered, [=]() { qApp->clipboard()->setText(contextMenuData.linkUrl.toString()); });
+        menu->addAction(action);
+    }
+    return menu;
+}
+
 void QWebEnginePage::load(const QUrl& url)
 {
     Q_D(QWebEnginePage);
diff --git a/lib/widgets/Api/qwebenginepage_p.h b/lib/widgets/Api/qwebenginepage_p.h
index e8f511d2d6668c7fe6b14ad68462aeba155c94ca..56080c97726d728903e80c5dcf723a63d2a3156b 100644
--- a/lib/widgets/Api/qwebenginepage_p.h
+++ b/lib/widgets/Api/qwebenginepage_p.h
@@ -74,6 +74,7 @@ public:
     virtual void loadFinished(bool success) Q_DECL_OVERRIDE;
     virtual void focusContainer() Q_DECL_OVERRIDE;
     virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition) Q_DECL_OVERRIDE;
+    virtual bool contextMenuRequested(const WebEngineContextMenuData &data) Q_DECL_OVERRIDE;
 
     void updateAction(QWebEnginePage::WebAction) const;
     void updateNavigationActions();
@@ -84,6 +85,7 @@ public:
     QWebEngineView *view;
     mutable QAction *actions[QWebEnginePage::WebActionCount];
     bool m_isLoading;
+    WebEngineContextMenuData m_menuData;
 };
 
 QT_END_NAMESPACE
diff --git a/lib/widgets/Api/qwebengineview.cpp b/lib/widgets/Api/qwebengineview.cpp
index d07e710abe2bd2c7790a42e0463c40986bc0de4e..536f075f3954cce2286153a8bd838b36f4f02a63 100644
--- a/lib/widgets/Api/qwebengineview.cpp
+++ b/lib/widgets/Api/qwebengineview.cpp
@@ -44,6 +44,9 @@
 
 #include "qwebenginepage_p.h"
 
+#include <QAction>
+#include <QMenu>
+#include <QContextMenuEvent>
 #include <QStackedLayout>
 
 QT_BEGIN_NAMESPACE
@@ -186,6 +189,24 @@ void QWebEngineView::setZoomFactor(qreal factor)
     page()->setZoomFactor(factor);
 }
 
+bool QWebEngineView::event(QEvent *ev)
+{
+    Q_D(QWebEngineView);
+    // We swallow spontaneous contextMenu events and synthethize those back later on when we get the
+    // HandleContextMenu callback from chromium
+    if (ev->type() == QEvent::ContextMenu) {
+        ev->accept();
+        return true;
+    }
+    return QWidget::event(ev);
+}
+
+void QWebEngineView::contextMenuEvent(QContextMenuEvent *event)
+{
+    QMenu *menu = page()->createStandardContextMenu();
+    menu->popup(event->globalPos());
+}
+
 QT_END_NAMESPACE
 
 #include "moc_qwebengineview.cpp"
diff --git a/lib/widgets/Api/qwebengineview.h b/lib/widgets/Api/qwebengineview.h
index c3b3067bce3c5f6645342357d1ea92699faad784..2c649d46f24d0e72c013b5bbfbbe07a5e4bf745e 100644
--- a/lib/widgets/Api/qwebengineview.h
+++ b/lib/widgets/Api/qwebengineview.h
@@ -30,6 +30,7 @@
 #include <QtWebEngineWidgets/qwebenginepage.h>
 
 QT_BEGIN_NAMESPACE
+class QContextMenuEvent;
 class QIcon;
 class QNetworkRequest;
 class QPrinter;
@@ -129,11 +130,14 @@ Q_SIGNALS:
 
 protected:
     virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type);
+    virtual void contextMenuEvent(QContextMenuEvent*) Q_DECL_OVERRIDE;
+    virtual bool event(QEvent*) Q_DECL_OVERRIDE;
 
 private:
     Q_DECLARE_PRIVATE(QWebEngineView);
 
     friend class QWebEnginePage;
+    friend class QWebEnginePagePrivate;
 };
 
 QT_END_NAMESPACE
diff --git a/lib/widgets/Api/qwebengineview_p.h b/lib/widgets/Api/qwebengineview_p.h
index 73e5d45d8f0bb2acc6a37679ace05be0d8f7731e..774386a213cea85ae79fd4cb1e6d2889e74d3862 100644
--- a/lib/widgets/Api/qwebengineview_p.h
+++ b/lib/widgets/Api/qwebengineview_p.h
@@ -59,6 +59,7 @@ public:
     QWebEngineViewPrivate();
 
     QWebEnginePage *page;
+    bool m_pendingContextMenuEvent;
 };
 
 QT_END_NAMESPACE
diff --git a/lib/widgets/widgets.pro b/lib/widgets/widgets.pro
index 272e3568edd6841d9735874c62e296f9553e5a40..60730f880ababd057685d2d70bea5d5842c768ea 100644
--- a/lib/widgets/widgets.pro
+++ b/lib/widgets/widgets.pro
@@ -9,6 +9,8 @@ MODULE = webenginewidgets
 # For our export macros
 DEFINES += QT_BUILD_WEBENGINEWIDGETS_LIB
 
+CONFIG += c++11
+
 QT += widgets
 QT_PRIVATE += widgets-private gui-private core-private