diff --git a/build/qmake/mkspecs/features/functions.prf b/build/qmake/mkspecs/features/functions.prf
index 40a125f14fd94592c6a0ad1d5e22dcd4897e0a40..48c23a7f46a525bd559511f930228b4366e617a9 100644
--- a/build/qmake/mkspecs/features/functions.prf
+++ b/build/qmake/mkspecs/features/functions.prf
@@ -27,6 +27,13 @@ defineReplace(findMocables) {
   return($$mocables)
 }
 
+defineReplace(findIncludedMocFiles) {
+  input = $$1
+  for (file, input): \
+      infiles += $$absolute_path($$file, $$_PRO_FILE_PWD_)
+  return($$system("$$QTWEBENGINE_ROOT/build/scripts/find-included-moc-files $$infiles"))
+}
+
 defineReplace(mocOutput) {
   out = $$1
   # The order is important, since the output of the second replace would end up accidentaly transformed by the first one
diff --git a/build/qmake/mkspecs/features/gyp_generator.prf b/build/qmake/mkspecs/features/gyp_generator.prf
index 2cb6523319c0db82b7b3fc12681a7f080ad8bd5c..b01a9bb6cb1a7ad04bdf9cc6b0d53d7d99af7caf 100644
--- a/build/qmake/mkspecs/features/gyp_generator.prf
+++ b/build/qmake/mkspecs/features/gyp_generator.prf
@@ -34,7 +34,7 @@ GYPI_FILE = $$replace(_PRO_FILE_, .pro$, .gyp)
 
 TARGET_TYPE = $$toGypTargetType()
 MOCABLE_HEADERS = $$findMocables($$HEADERS)
-MOCABLE_SOURCES = $$findMocables($$SOURCES)
+INCLUDED_MOC_FILES = $$findIncludedMocFiles($$SOURCES)
 
 GYPI_CONTENTS =  "{" \
                  "  'targets': [" \
@@ -74,20 +74,29 @@ GYPI_CONTENTS += "    ],"
                    "      }," \
                    "    },"
 }
+
+# Source files to compile
 GYPI_CONTENTS += "    'sources': ["
 for (sourcefile, SOURCES): GYPI_CONTENTS += "      '$$sourcefile',"
 for (headerfile, HEADERS): GYPI_CONTENTS += "      '$$headerfile',"
+
+# Add moc output files to compile that aren't included at the end of any other source
 MOC_OUT_PATH = $$absolute_path($$MOC_DIR, $$OUT_PWD)$${QMAKE_DIR_SEP}
-for (mocable_header, MOCABLE_HEADERS): GYPI_CONTENTS += "       '$$MOC_OUT_PATH$$mocOutput($$mocable_header)',"
-for (mocable_source, MOCABLE_SOURCES): GYPI_CONTENTS += "       '$$MOC_OUT_PATH$$mocOutput($$mocable_source)',"
+for (mocable_header, MOCABLE_HEADERS) {
+    !contains(INCLUDED_MOC_FILES, $$mocOutput($$mocable_header)) {
+        GYPI_CONTENTS += "       '$$MOC_OUT_PATH$$mocOutput($$mocable_header)',"
+    }
+}
+
 GYPI_CONTENTS += "    ],"
 !isEmpty(INCLUDEPATH) {
   GYPI_CONTENTS += "    'include_dirs': ["
   for (path, INCLUDEPATH): GYPI_CONTENTS += "      '$$path',"
   GYPI_CONTENTS += "    ],"
 }
+
 # Generate the actions for moc
-!isEmpty(MOCABLE_HEADERS)|!isEmpty(MOCABLE_SOURCES) {
+!isEmpty(MOCABLE_HEADERS) {
     GYPI_CONTENTS += "    'actions': ["
     for(header, MOCABLE_HEADERS): GYPI_CONTENTS += $$mocAction($$header)
     GYPI_CONTENTS += "    ],"
diff --git a/build/scripts/find-included-moc-files b/build/scripts/find-included-moc-files
new file mode 100755
index 0000000000000000000000000000000000000000..e55f3824c0462adafb1d7a19d32154e3c457834b
--- /dev/null
+++ b/build/scripts/find-included-moc-files
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+import re, sys, os
+
+includedMocs = set()
+for f in filter(os.path.isfile, sys.argv[1:]):
+    inBlockComment = False
+    for line in open(f).readlines():
+        m = re.search('#include "(moc_\w+.cpp)"', line)
+        if m:
+            includedMocs.add(m.group(1))
+for moc in includedMocs:
+    print moc
diff --git a/lib/qwebcontentsview.cpp b/lib/qwebcontentsview.cpp
index c8f5535dd5d0b8c39ec43d77739248e5b4c93b7e..0920a5d7db5cfb50a7f03323361bae202751b139 100644
--- a/lib/qwebcontentsview.cpp
+++ b/lib/qwebcontentsview.cpp
@@ -68,7 +68,7 @@ QWebContentsView::QWebContentsView()
     WebContentsDelegateQt* delegate = d->webContentsDelegate.get();
     connect(delegate, SIGNAL(titleChanged(const QString&)), this, SIGNAL(titleChanged(const QString&)));
     connect(delegate, SIGNAL(urlChanged(const QUrl&)), this, SIGNAL(urlChanged(const QUrl&)));
-    connect(delegate, SIGNAL(loadingStateChanged()), d, SLOT(loadingStateChanged()));
+    connect(delegate, SIGNAL(loadingStateChanged()), this, SLOT(_q_onLoadingStateChanged()));
 }
 
 QWebContentsView::~QWebContentsView()
@@ -147,7 +147,7 @@ QWebContentsViewPrivate::QWebContentsViewPrivate()
     contents_view->SetClient(this);
 }
 
-void QWebContentsViewPrivate::loadingStateChanged()
+void QWebContentsViewPrivate::_q_onLoadingStateChanged()
 {
     Q_Q(QWebContentsView);
     bool isLoading = webContentsDelegate->web_contents()->IsLoading();
@@ -168,3 +168,5 @@ RenderWidgetHostViewQtDelegate *QWebContentsViewPrivate::CreateRenderWidgetHostV
     q->layout()->addWidget(viewDelegate);
     return viewDelegate;
 }
+
+#include "moc_qwebcontentsview.cpp"
diff --git a/lib/qwebcontentsview.h b/lib/qwebcontentsview.h
index 2bea89a1407591be367d124ca4f528fbee93c804..b9753c7199fb33952842e47e9768c9edb8752876 100644
--- a/lib/qwebcontentsview.h
+++ b/lib/qwebcontentsview.h
@@ -71,6 +71,8 @@ Q_SIGNALS:
 
 private:
     Q_DECLARE_PRIVATE(QWebContentsView)
+    Q_PRIVATE_SLOT(d_func(), void _q_onLoadingStateChanged());
+
     // Hides QObject::d_ptr allowing us to use the convenience macros.
     QScopedPointer<QWebContentsViewPrivate> d_ptr;
 };
diff --git a/lib/qwebcontentsview_p.h b/lib/qwebcontentsview_p.h
index c2009c7acb40f434c7da00be9abd96fc0de5335c..20049587d49e7dcf9390fe76f90ae22d896e6b14 100644
--- a/lib/qwebcontentsview_p.h
+++ b/lib/qwebcontentsview_p.h
@@ -47,22 +47,18 @@
 #include "web_contents_view_qt.h"
 #include "web_engine_context.h"
 
-
 #include <QScopedPointer>
-#include <QObject>
 
-class QWebContentsViewPrivate : public QObject, public WebContentsViewQtClient
+class QWebContentsViewPrivate : public WebContentsViewQtClient
 {
     QWebContentsView *q_ptr;
     Q_DECLARE_PUBLIC(QWebContentsView)
-    Q_OBJECT
 public:
     QWebContentsViewPrivate();
 
     RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(content::RenderWidgetHostViewQt *view) Q_DECL_OVERRIDE;
 
-public Q_SLOTS:
-    void loadingStateChanged();
+    void _q_onLoadingStateChanged();
 
 public:
     scoped_refptr<WebEngineContext> context;