diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 926ec16..0218f5d 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -168,6 +168,7 @@ QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
 #endif
 
 QList<QScreen *> QGuiApplicationPrivate::screen_list;
+int QGuiApplicationPrivate::primary_screen = 0;
 
 QWindowList QGuiApplicationPrivate::window_list;
 QWindow *QGuiApplicationPrivate::focus_window = 0;
@@ -888,9 +889,9 @@ QWindowList QGuiApplication::topLevelWindows()
 */
 QScreen *QGuiApplication::primaryScreen()
 {
-    if (QGuiApplicationPrivate::screen_list.isEmpty())
+    if (QGuiApplicationPrivate::screen_list.size() <= QGuiApplicationPrivate::primary_screen)
         return 0;
-    return QGuiApplicationPrivate::screen_list.at(0);
+    return QGuiApplicationPrivate::screen_list.at(QGuiApplicationPrivate::primary_screen);
 }
 
 /*!
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index c89268d..977d14e 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -168,6 +168,7 @@ Q_SIGNALS:
     void saveStateRequest(QSessionManager &sessionManager);
 #endif
     void paletteChanged(const QPalette &pal);
+    void primaryScreenChanged();
 
 protected:
     bool event(QEvent *) Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 0559442..6fa9f13 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -216,6 +216,7 @@ public:
     QList<QCursor> cursor_list;
 #endif
     static QList<QScreen *> screen_list;
+    static int primary_screen;
 
     static QFont *app_font;
 
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 4d973d4..74adf70 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -453,10 +453,13 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
     ps->d_func()->screen = screen;
     if (isPrimary) {
         QGuiApplicationPrivate::screen_list.prepend(screen);
+        QGuiApplicationPrivate::primary_screen = 0;
     } else {
         QGuiApplicationPrivate::screen_list.append(screen);
     }
     emit qGuiApp->screenAdded(screen);
+    if (isPrimary)
+        emit qGuiApp->primaryScreenChanged();
 }
 
 /*!
@@ -474,6 +477,15 @@ void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
     delete screen;
 }
 
+void QPlatformIntegration::changePrimaryScreen(QPlatformScreen *screen)
+{
+    int i = QGuiApplicationPrivate::screen_list.indexOf(screen->d_func()->screen);
+    if (i >= 0) {
+        QGuiApplicationPrivate::primary_screen = i;
+        emit qGuiApp->primaryScreenChanged();
+    }
+}
+
 QStringList QPlatformIntegration::themeNames() const
 {
     return QStringList();
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 2aa502b..7a34f8f 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -175,6 +175,7 @@ public:
 protected:
     void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
     void destroyScreen(QPlatformScreen *screen);
+    void changePrimaryScreen(QPlatformScreen *screen);
 };
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 80c844e..f962895 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -270,15 +270,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
                 if (screen->mode() != output.mode)
                     screen->updateRefreshRate(output.mode);
 
-                // If the screen became primary, reshuffle the order in QGuiApplicationPrivate
-                // TODO: add a proper mechanism for updating primary screen
-                if (!wasPrimary && screen->isPrimary()) {
-                    QScreen *realScreen = static_cast<QPlatformScreen*>(screen)->screen();
-                    QGuiApplicationPrivate::screen_list.removeOne(realScreen);
-                    QGuiApplicationPrivate::screen_list.prepend(realScreen);
-                    m_screens.removeOne(screen);
-                    m_screens.prepend(screen);
-                }
+                if (!wasPrimary && screen->isPrimary())
+                    QXcbIntegration::instance()->changePrimaryScreen(screen);
                 qCDebug(lcQpaScreen) << "output has changed" << screen;
             }
         }
diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index 9471602..ee1b40b 100644
--- a/src/widgets/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
@@ -36,6 +36,7 @@
 #include "qdesktopwidget_p.h"
 #include "qscreen.h"
 #include "qwidget_p.h"
+#include <private/qguiapplication_p.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -134,6 +135,7 @@ QDesktopWidget::QDesktopWidget()
     setObjectName(QLatin1String("desktop"));
     d->_q_updateScreens();
     connect(qApp, SIGNAL(screenAdded(QScreen*)), this, SLOT(_q_updateScreens()));
+    connect(qApp, SIGNAL(primaryScreenChanged()), this, SIGNAL(primaryScreenChanged()));
 }
 
 QDesktopWidget::~QDesktopWidget()
@@ -147,7 +149,7 @@ bool QDesktopWidget::isVirtualDesktop() const
 
 int QDesktopWidget::primaryScreen() const
 {
-    return 0;
+    return QGuiApplicationPrivate::primary_screen;
 }
 
 int QDesktopWidget::numScreens() const
diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h
index 5412c5b..fdd095f 100644
--- a/src/widgets/kernel/qdesktopwidget.h
+++ b/src/widgets/kernel/qdesktopwidget.h
@@ -47,7 +47,7 @@ class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget
     Q_OBJECT
     Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop)
     Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged)
-    Q_PROPERTY(int primaryScreen READ primaryScreen)
+    Q_PROPERTY(int primaryScreen READ primaryScreen NOTIFY primaryScreenChanged)
 public:
     QDesktopWidget();
     ~QDesktopWidget();
@@ -77,6 +77,7 @@ Q_SIGNALS:
     void resized(int);
     void workAreaResized(int);
     void screenCountChanged(int);
+    void primaryScreenChanged();
 
 protected:
     void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;
