diff --git a/kded/daemon.cpp b/kded/daemon.cpp index d05d629..a815b82 100644 --- a/kded/daemon.cpp +++ b/kded/daemon.cpp @@ -1,254 +1,259 @@ /************************************************************************************* * Copyright (C) 2012 by Alejandro Fiestas Olivares * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "daemon.h" #include "serializer.h" #include "generator.h" #include "device.h" #include "kscreenadaptor.h" #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY(KScreenDaemonFactory, registerPlugin();) K_EXPORT_PLUGIN(KScreenDaemonFactory("kscreen", "kscreen")) KScreenDaemon::KScreenDaemon(QObject* parent, const QList< QVariant >& ) : KDEDModule(parent) , m_monitoredConfig(0) , m_iteration(0) , m_pendingSave(false) , m_monitoring(false) , m_timer(new QTimer()) { setenv("KSCREEN_BACKEND", "XRandR", 0); if (!KScreen::Config::loadBackend()) { kWarning() << "Couldn't load backend: " << getenv("KSCREEN_BACKEND"); return; } KActionCollection *coll = new KActionCollection(this); KAction* action = coll->addAction("display"); action->setText(i18n("Switch Display" )); action->setGlobalShortcut(KShortcut(Qt::Key_Display)); new KScreenAdaptor(this); connect(Device::self(), SIGNAL(lidIsClosedChanged(bool,bool)), SLOT(lidClosedChanged(bool))); m_timer->setInterval(300); m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), SLOT(applyGenericConfig())); connect(action, SIGNAL(triggered(bool)), SLOT(displayButton())); connect(Generator::self(), SIGNAL(ready()), SLOT(init())); monitorConnectedChange(); } KScreenDaemon::~KScreenDaemon() { Generator::destroy(); Device::destroy(); } void KScreenDaemon::init() { applyConfig(); } void KScreenDaemon::applyConfig() { kDebug() << "Applying config"; if (Serializer::configExists()) { applyKnownConfig(); return; } applyIdealConfig(); } void KScreenDaemon::applyKnownConfig() { kDebug() << "Applying known config"; setMonitorForChanges(false); - KScreen::Config::setConfig(Serializer::config(Serializer::currentId())); + KScreen::Config* config = Serializer::config(Serializer::currentId()); + if (!KScreen::Config::canBeApplied(config)) { + return applyIdealConfig(); + } + + KScreen::Config::setConfig(config); QMetaObject::invokeMethod(this, "scheduleMonitorChange", Qt::QueuedConnection); } void KScreenDaemon::applyIdealConfig() { kDebug() << "Applying ideal config"; setMonitorForChanges(true); KScreen::Config::setConfig(Generator::self()->idealConfig()); } void KScreenDaemon::configChanged() { kDebug() << "Change detected"; if (m_pendingSave) { return; } kDebug() << "Scheduling screen save"; m_pendingSave = true; QMetaObject::invokeMethod(this, "saveCurrentConfig", Qt::QueuedConnection); } void KScreenDaemon::saveCurrentConfig() { kDebug() << "Saving current config"; m_pendingSave = false; Serializer::saveConfig(KScreen::Config::current()); } void KScreenDaemon::displayButton() { kDebug() << "displayBtn triggered"; if (m_timer->isActive()) { kDebug() << "Too fast cowboy"; return; } m_timer->start(); } void KScreenDaemon::resetDisplaySwitch() { kDebug(); m_iteration = 0; } void KScreenDaemon::applyGenericConfig() { if (m_iteration == 5) { m_iteration = 0; } setMonitorForChanges(true); m_iteration++; kDebug() << "displayButton: " << m_iteration; KDebug::Block genericConfig("Applying display switch"); KScreen::Config::setConfig(Generator::self()->displaySwitch(m_iteration)); } void KScreenDaemon::lidClosedChanged(bool lidIsClosed) { KDebug::Block genericConfig(" Lid closed"); kDebug() << "Lid is closed:" << lidIsClosed; //If the laptop is closed, use ideal config WITHOUT saving it if (lidIsClosed) { setMonitorForChanges(false); KScreen::Config::setConfig(Generator::self()->idealConfig()); return; } //If the lid is open, restore config (or generate a new one if needed applyConfig(); } void KScreenDaemon::outputConnectedChanged() { KScreen::Output *output = qobject_cast(sender()); if (output->isConnected()) { Q_EMIT outputConnected(output->name()); if (!Serializer::configExists()) { Q_EMIT unknownOutputConnected(output->name()); } } } void KScreenDaemon::monitorConnectedChange() { if (!m_monitoredConfig) { m_monitoredConfig = KScreen::Config::current(); if (!m_monitoredConfig) { return; } KScreen::ConfigMonitor::instance()->addConfig(m_monitoredConfig); } KScreen::OutputList outputs = m_monitoredConfig->outputs(); Q_FOREACH(KScreen::Output* output, outputs) { connect(output, SIGNAL(isConnectedChanged()), SLOT(applyConfig())); connect(output, SIGNAL(isConnectedChanged()), SLOT(resetDisplaySwitch())); connect(output, SIGNAL(isConnectedChanged()), SLOT(outputConnectedChanged())); } } void KScreenDaemon::setMonitorForChanges(bool enabled) { if (m_monitoring == enabled) { return; } kDebug() << "Monitor for changes: " << enabled; if (!m_monitoredConfig) { m_monitoredConfig = KScreen::Config::current(); if (!m_monitoredConfig) { return; } KScreen::ConfigMonitor::instance()->addConfig(m_monitoredConfig); } m_monitoring = enabled; KScreen::OutputList outputs = m_monitoredConfig->outputs(); Q_FOREACH(KScreen::Output* output, outputs) { if (m_monitoring) { enableMonitor(output); } else { disableMonitor(output); } } } void KScreenDaemon::scheduleMonitorChange() { QMetaObject::invokeMethod(this, "setMonitorForChanges", Qt::QueuedConnection, Q_ARG(bool, true)); } void KScreenDaemon::enableMonitor(KScreen::Output* output) { connect(output, SIGNAL(currentModeIdChanged()), SLOT(configChanged())); connect(output, SIGNAL(isEnabledChanged()), SLOT(configChanged())); connect(output, SIGNAL(isPrimaryChanged()), SLOT(configChanged())); connect(output, SIGNAL(outputChanged()), SLOT(configChanged())); connect(output, SIGNAL(clonesChanged()), SLOT(configChanged())); connect(output, SIGNAL(posChanged()), SLOT(configChanged())); connect(output, SIGNAL(rotationChanged()), SLOT(configChanged())); } void KScreenDaemon::disableMonitor(KScreen::Output* output) { disconnect(output, SIGNAL(currentModeIdChanged()), this, SLOT(configChanged())); disconnect(output, SIGNAL(isEnabledChanged()), this, SLOT(configChanged())); disconnect(output, SIGNAL(isPrimaryChanged()), this, SLOT(configChanged())); disconnect(output, SIGNAL(outputChanged()), this, SLOT(configChanged())); disconnect(output, SIGNAL(clonesChanged()), this, SLOT(configChanged())); disconnect(output, SIGNAL(posChanged()), this, SLOT(configChanged())); disconnect(output, SIGNAL(rotationChanged()), this, SLOT(configChanged())); }