summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Martin <[email protected]>2016-12-25 20:20:40 +0100
committerMarco Martin <[email protected]>2016-12-25 20:24:08 +0100
commit20b439a4f4a1aa652f7960f0e6dfa8201f89aa11 (patch)
tree141d7f2ae909ad8ad0f2f4ead717890e8ca99551
parentd8402baf46fe2ca9a1a9e41a708ebcb77c60a736 (diff)
notice when the only screen changes
Summary: in a corner case that is used a lot, the internal laptop screen gets automatically disabled when an external screen is connected. the only QScreen* available from the QGuiApp gets recycled for the new screen and there is no signal this switch occurred. To work around this, as all the view get an expose event when this happen, monitor the rename of the desktopview's qscreen and manage this separatedly in the shell. BUG:373880 Test Plan: connection and disconnecting an external screen to the laptop both in the case of internal screen enabled or disabled Reviewers: davidedmundson, #plasma Reviewed By: davidedmundson, #plasma Subscribers: davidedmundson, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D3777
-rw-r--r--shell/desktopview.cpp19
-rw-r--r--shell/desktopview.h2
-rw-r--r--shell/shellcorona.cpp14
3 files changed, 28 insertions, 7 deletions
diff --git a/shell/desktopview.cpp b/shell/desktopview.cpp
index c629932..55d0eec 100644
--- a/shell/desktopview.cpp
+++ b/shell/desktopview.cpp
@@ -85,12 +85,7 @@ void DesktopView::setScreenToFollow(QScreen *screen)
return;
}
- /*connect(screen, &QObject::destroyed, this, [this]() {
- if (DesktopView::screen()) {
- m_screenToFollow = DesktopView::screen();
- adaptToScreen();
- }
- });*/
+ m_screenName = screen->name();
m_screenToFollow = screen;
setScreen(screen);
adaptToScreen();
@@ -204,7 +199,17 @@ DesktopView::SessionType DesktopView::sessionType() const
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
+ //https://bugreports.qt.io/browse/QTBUG-57785
+ 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<QKeyEvent *>(e);
if (KWindowSystem::showingDesktop() && ke->key() == Qt::Key_Escape) {
ShellCorona *c = qobject_cast<ShellCorona *>(corona());
diff --git a/shell/desktopview.h b/shell/desktopview.h
index d0696df..98dd47c 100644
--- a/shell/desktopview.h
+++ b/shell/desktopview.h
@@ -88,12 +88,14 @@ private Q_SLOTS:
Q_SIGNALS:
void stayBehindChanged();
void windowTypeChanged();
+ void screenRenamed();
private:
void coronaPackageChanged(const KPackage::Package &package);
void ensureWindowType();
void setupWaylandIntegration();
+ QString m_screenName;
QPointer<PlasmaQuick::ConfigView> m_configView;
QPointer<QScreen> m_oldScreen;
QPointer<QScreen> m_screenToFollow;
diff --git a/shell/shellcorona.cpp b/shell/shellcorona.cpp
index 7ec2b88..133a750 100644
--- a/shell/shellcorona.cpp
+++ b/shell/shellcorona.cpp
@@ -1144,6 +1144,20 @@ void ShellCorona::addOutput(QScreen* screen)
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);