From b37948000e3844b85862a3b728447048d36d113f Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Tue, 13 May 2014 17:04:24 +0200 Subject: [PATCH] Improve predictability of plasma-shell screen id's So far we were just enforcing that 0 would be the primary screen. After this change we will make sure that the rest are layed out horizontally and then vertically if there's a 2 at the same position. If a new screen is connected, we'll try to put it in the correct position following the described situation. BUG: 334502 --- shell/shellcorona.cpp | 80 +++++++++++++++++++------------------------ shell/shellcorona.h | 1 + 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/shell/shellcorona.cpp b/shell/shellcorona.cpp index a40afea0c..7cc55f5f4 100644 --- a/shell/shellcorona.cpp +++ b/shell/shellcorona.cpp @@ -116,6 +116,16 @@ static QScreen *outputToScreen(KScreen::Output *output) return 0; } +static KScreen::Output *screenToOutput(QScreen* screen, KScreen::Config* config) +{ + foreach(KScreen::Output* output, config->connectedOutputs()) { + if (screen->name() == output->name()) { + return output; + } + } + return 0; +} + WorkspaceScripting::DesktopScriptEngine* ShellCorona::scriptEngine() const { return d->scriptEngine; @@ -247,15 +257,15 @@ QString ShellCorona::shell() const return d->shell; } +bool outputLess(KScreen::Output *a, KScreen::Output *b) +{ + return a->isPrimary() && !b->isPrimary() && (a->pos().x() < b->pos().x() || (a->pos().x() == b->pos().x() && a->pos().y() < b->pos().y())); +} + static QList sortOutputs(const QHash &outputs) { - QList ret; - foreach(KScreen::Output *output, outputs) { - if (output->isPrimary()) - ret.prepend(output); - else - ret.append(output); - } + QList ret = outputs.values(); + std::sort(ret.begin(), ret.end(), outputLess); return ret; } @@ -507,6 +517,14 @@ PanelView *ShellCorona::panelView(Plasma::Containment *containment) const ///// SLOTS +void ShellCorona::shiftViews(int idx, int delta, int until) +{ + for (int i = idx; iviews[i]->setScreen(d->views[i-delta]->screen()); + d->views[i]->adaptToScreen(); + } +} + void ShellCorona::addOutput(KScreen::Output *output) { connect(output, &KScreen::Output::isEnabledChanged, this, [this, output]() { this->addOutput(output); }, Qt::UniqueConnection); @@ -525,13 +543,13 @@ void ShellCorona::addOutput(KScreen::Output *output) } } - //let's make sure the output hasn't been added already, I think libkscreen is emitting some - //signals twice + int insertPosition = 0; foreach (DesktopView *view, d->views) { - if (screen == view->screen()) { - qWarning() << "trying to add output twice" << output; - return; - } + KScreen::Output *out = screenToOutput(view->screen(), d->screenConfiguration); + if(outputLess(output, out)) + break; + + insertPosition++; } DesktopView *view = new DesktopView(this, screen); @@ -539,33 +557,11 @@ void ShellCorona::addOutput(KScreen::Output *output) //We have to do it in a lambda, connect(screen, &QObject::destroyed, this, [=]() { removeDesktop(view); }); - const QString currentActivity = d->activityController->currentActivity(); - - qDebug() << "added screen" << output; - if (!d->views.isEmpty() && output->isPrimary()) { - DesktopView *oldPrimaryView = d->views.first(); - QScreen *oldPrimaryScreen = oldPrimaryView->screen(); - - //move any panels that were preivously on the old primary screen to the new primary screen - foreach (PanelView *panelView, d->panelViews) { - if (oldPrimaryScreen==panelView->screen()) - panelView->setScreen(screen); - if (view->containment()) { - view->containment()->reactToScreenChange(); - } - } - - Plasma::Containment *primaryContainment = oldPrimaryView->containment(); - oldPrimaryView->setContainment(0); - view->setContainment(primaryContainment); - - d->views.prepend(view); - view = oldPrimaryView; - } else { - Q_ASSERT(d->views.isEmpty() || !output->isPrimary()); - d->views.append(view); - } + d->views.append(0); + shiftViews(insertPosition, 1, d->views.count()-1); + d->views[insertPosition] = view; + const QString currentActivity = d->activityController->currentActivity(); int screenNum = d->views.count()-1; Plasma::Containment *containment = d->desktopContainments[currentActivity][screenNum]; if (!containment) { @@ -597,13 +593,9 @@ void ShellCorona::removeDesktop(DesktopView *view) { int idx = d->views.indexOf(view); DesktopView *lastView = d->views.takeAt(d->views.count()-1); - lastView->containment()->reactToScreenChange(); lastView->deleteLater(); - for (int i = idx; iviews.count()-1; ++i) { - d->views[i]->setScreen(d->views[i+1]->screen()); - d->views[i]->adaptToScreen(); - } + shiftViews(idx, -1, d->views.count()-1); screenInvariants(); } diff --git a/shell/shellcorona.h b/shell/shellcorona.h index aa14bcb23..6c0f83cd5 100644 --- a/shell/shellcorona.h +++ b/shell/shellcorona.h @@ -155,6 +155,7 @@ private Q_SLOTS: void desktopContainmentDestroyed(QObject*); private: + void shiftViews(int idx, int delta, int until); void screenInvariants() const; /**