diff --git a/shell/desktopview.cpp b/shell/desktopview.cpp --- a/shell/desktopview.cpp +++ b/shell/desktopview.cpp @@ -85,12 +85,6 @@ return; } - /*connect(screen, &QObject::destroyed, this, [this]() { - if (DesktopView::screen()) { - m_screenToFollow = DesktopView::screen(); - adaptToScreen(); - } - });*/ m_screenToFollow = screen; setScreen(screen); adaptToScreen(); diff --git a/shell/shellcorona.h b/shell/shellcorona.h --- a/shell/shellcorona.h +++ b/shell/shellcorona.h @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -65,7 +66,7 @@ } } -class ShellCorona : public Plasma::Corona, QDBusContext +class ShellCorona : public Plasma::Corona, QDBusContext, public QAbstractNativeEventFilter { Q_OBJECT Q_PROPERTY(QString shell READ shell WRITE setShell) @@ -113,6 +114,9 @@ QString defaultContainmentPlugin() const; +protected: + bool nativeEventFilter(const QByteArray & eventType, void * message, long * result) Q_DECL_OVERRIDE; + public Q_SLOTS: /** * Request saving applicationConfig on disk, it's event compressed, not immediate diff --git a/shell/shellcorona.cpp b/shell/shellcorona.cpp --- a/shell/shellcorona.cpp +++ b/shell/shellcorona.cpp @@ -79,6 +79,9 @@ #if HAVE_X11 #include #include +#include +#include +#include #endif @@ -97,6 +100,8 @@ qmlRegisterUncreatableType("org.kde.plasma.shell", 2, 0, "Desktop", QStringLiteral("It is not possible to create objects of type Desktop")); qmlRegisterUncreatableType("org.kde.plasma.shell", 2, 0, "Panel", QStringLiteral("It is not possible to create objects of type Panel")); + qApp->installNativeEventFilter(this); + m_lookAndFeelPackage = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); KConfigGroup cg(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "KDE"); const QString packageName = cg.readEntry("LookAndFeelPackage", QString()); @@ -1991,6 +1996,35 @@ return plugin; } +bool ShellCorona::nativeEventFilter(const QByteArray& eventType, void* message, long int* result) +{ + Q_UNUSED(result); +#if HAVE_X11 + // a particular edge case: when we switch the only enabled screen + // we don't have any signal about it, the primary screen changes but we have the same old QScreen* getting recycled + // see https://bugs.kde.org/show_bug.cgi?id=373880 + // if this slot will be invoked many times, their//second time on will do nothing as name and primaryconnector will be the same by then + if (eventType != "xcb_generic_event_t") { + return false; + } + + xcb_generic_event_t *ev = static_cast(message); + + const auto responseType = XCB_EVENT_RESPONSE_TYPE(ev); + if (responseType == XCB_RANDR_NOTIFY) { + if (qGuiApp->primaryScreen()->name() != m_screenPool->primaryConnector()) { + //new screen? + if (m_screenPool->id(qGuiApp->primaryScreen()->name()) < 0) { + m_screenPool->insertScreenMapping(m_screenPool->firstAvailableId(), qGuiApp->primaryScreen()->name()); + } + //switch the primary screen in the pool + m_screenPool->setPrimaryConnector(qGuiApp->primaryScreen()->name()); + } + } +#endif + return false; +} + void ShellCorona::updateStruts() { foreach(PanelView* view, m_panelViews) {