diff --git a/shell/desktopview.h b/shell/desktopview.h --- a/shell/desktopview.h +++ b/shell/desktopview.h @@ -88,12 +88,14 @@ Q_SIGNALS: void stayBehindChanged(); void windowTypeChanged(); + void screenRenamed(); private: void coronaPackageChanged(const KPackage::Package &package); void ensureWindowType(); void setupWaylandIntegration(); + QString m_screenName; QPointer m_configView; QPointer m_oldScreen; QPointer m_screenToFollow; diff --git a/shell/desktopview.cpp b/shell/desktopview.cpp --- a/shell/desktopview.cpp +++ b/shell/desktopview.cpp @@ -204,7 +204,16 @@ bool DesktopView::event(QEvent *e) { - if (e->type() == QEvent::KeyRelease) { + //NOTE: we need this heuristic for the case when there is an + //internal laptop screen that gets disabled upon connection of an external one. the only QCreen * pointer gets recycled and there is no dedicated signal to discover this at all + //after being moved, the view will get an expose event, so we can check there if the screen has been renamed + //see https://bugs.kde.org/show_bug.cgi?id=373880 + if (e->type() == QEvent::Expose) { + if (m_screenToFollow && m_screenToFollow->name() != m_screenName) { + m_screenName = m_screenToFollow->name(); + emit screenRenamed(); + } + } else if (e->type() == QEvent::KeyRelease) { QKeyEvent *ke = static_cast(e); if (KWindowSystem::showingDesktop() && ke->key() == Qt::Key_Escape) { ShellCorona *c = qobject_cast(corona()); diff --git a/shell/shellcorona.cpp b/shell/shellcorona.cpp --- a/shell/shellcorona.cpp +++ b/shell/shellcorona.cpp @@ -1144,6 +1144,20 @@ DesktopView *view = new DesktopView(this, screen); connect(view, &QQuickWindow::sceneGraphError, this, &ShellCorona::showOpenGLNotCompatibleWarning); + // 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 + connect(view, &DesktopView::screenRenamed, this, [=](){ + 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()); + } + }); Plasma::Containment *containment = createContainmentForActivity(m_activityController->currentActivity(), insertPosition); Q_ASSERT(containment);