Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Dear release team, KDE Plasma 5.8 is an LTS release that I consider fit to be updated in stretch. This particular request is for libkscreen 5.8.6. Compared to the 5.8.4 version currently in stretch the 5.8.6 release fixes are: + Allow changing an output's modelist at runtime (7367e55) [1] + Disable low level logging (04a6483) [2] (Closes: #846940) + Improve laptop panel detection (57cd4d1) On the Debian side, the symbols file adds the new symbols related to 7367e55, and notes the mentioned closes. I'm attaching the full debdiff and the upstream gitlog. The 4:5.8.6-1 version is currently in experimental, and I would like to upload the 4:5.8.6-2 version to unstable if this gets approved. Please unblock package libkscreen Happy hacking, [1]: https://bugs.kde.org/show_bug.cgi?id=356864 [2]: https://bugs.kde.org/show_bug.cgi?id=361688 unblock libkscreen/4:5.8.6-2 -- System Information: Debian Release: 9.0 APT prefers unstable-debug APT policy: (500, 'unstable-debug'), (500, 'testing-debug'), (500, 'testing'), (500, 'stable'), (50, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386, armhf Kernel: Linux 4.9.0-1-amd64 (SMP w/4 CPU cores) Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Init: systemd (via /run/systemd/system)
commit 652f0452059e41e529a8f6a7275b6e364ed6928b Author: Jonathan Riddell <j...@jriddell.org> Date: Tue Feb 21 11:44:09 2017 +0000 Update version number for 5.8.6 GIT_SILENT diff --git a/CMakeLists.txt b/CMakeLists.txt index a6fbf0a..b1a3bdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.12) project(libkscreen) -set(PROJECT_VERSION "5.8.5") +set(PROJECT_VERSION "5.8.6") find_package(ECM 5.14.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) commit 57cd4d12b3c70495935675cb7df6532b98695fb1 Author: Sebastian Kügler <se...@kde.org> Date: Tue Jan 24 16:15:26 2017 +0100 Fix type argument for get property call We were passing the wrong argument in there, it has to be the atom's type, not the atom property itself. This fixes detection of the laptop panel in some cases, where we can't fix it with our fallback mechanism. Patch-by: Gabriel Souza Franco <gabrielfrancoso...@gmail.com> Signed-off-by: Sebastian Kügler <se...@kde.org> diff --git a/backends/xrandr/xrandroutput.cpp b/backends/xrandr/xrandroutput.cpp index 94a0b65..cc49823 100644 --- a/backends/xrandr/xrandroutput.cpp +++ b/backends/xrandr/xrandroutput.cpp @@ -318,7 +318,7 @@ QByteArray XRandROutput::typeFromProperty(xcb_randr_output_t outputId) char *connectorType; - auto cookie = xcb_randr_get_output_property(XCB::connection(), outputId, atomType, + auto cookie = xcb_randr_get_output_property(XCB::connection(), outputId, atomType->atom, XCB_ATOM_ANY, 0, 100, false, false); XCB::ScopedPointer<xcb_randr_get_output_property_reply_t> reply(xcb_randr_get_output_property_reply(XCB::connection(), cookie, NULL)); if (!reply) { commit 04a6483a01caaa17e476ac9e4a47725f0e1ca06f Author: Sebastian Kügler <se...@kde.org> Date: Fri Jan 6 17:46:13 2017 +0100 disable logging to kscreen.log by default Summary: Most of the issues that this feature should uncover have been uncovered, it makes sense to disable the logging (and futzing around with QCategorizedLogging) by default, and only use it to debug specific setups. Test Plan: Adjusted autotests accordingly. Reviewers: #plasma, mart Reviewed By: mart Subscribers: graesslin, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D3993 BUG:361688 CHANGELOG:Disable logging to kscreen.log by default, re-enable with export KSCREEN_LOGGING=1 cherry-picked from cea4c63f84650efa4 diff --git a/autotests/testlog.cpp b/autotests/testlog.cpp index 47cd1df..76654d6 100644 --- a/autotests/testlog.cpp +++ b/autotests/testlog.cpp @@ -55,6 +55,7 @@ void TestLog::init() void TestLog::initTestCase() { + qputenv(KSCREEN_LOGGING, QByteArray("true")); } void TestLog::cleanupTestCase() @@ -85,6 +86,13 @@ void TestLog::testEnabled() qunsetenv(KSCREEN_LOGGING); log = Log::instance(); + QCOMPARE(log->enabled(), false); + QCOMPARE(log->logFile(), QString()); + + delete log; + qputenv(KSCREEN_LOGGING, QByteArray("truE")); + + log = Log::instance(); QCOMPARE(log->enabled(), true); QCOMPARE(log->logFile(), m_defaultLogFile); diff --git a/src/log.cpp b/src/log.cpp index dbb48a3..51b385e 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -57,7 +57,7 @@ class Log::Private { public: QString context; - bool enabled = true; + bool enabled = false; QString logFile; }; @@ -68,11 +68,13 @@ Log::Log() : if (qEnvironmentVariableIsSet(logging_env)) { const QString logging_env_value = qgetenv(logging_env).constData(); - if (logging_env_value == QStringLiteral("0") || logging_env_value.toLower() == QStringLiteral("false")) { - d->enabled = false; - return; + if (logging_env_value != QStringLiteral("0") && logging_env_value.toLower() != QStringLiteral("false")) { + d->enabled = true; } } + if (!d->enabled) { + return; + } d->logFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kscreen/kscreen.log"; QLoggingCategory::setFilterRules("kscreen.*=true"); commit 7f364342238af7b667ef64f4f63eb3077655b024 Author: Jonathan Riddell <j...@jriddell.org> Date: Tue Dec 27 09:27:30 2016 +0000 Update version number for 5.8.5 GIT_SILENT diff --git a/CMakeLists.txt b/CMakeLists.txt index 8515e95..a6fbf0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.12) project(libkscreen) -set(PROJECT_VERSION "5.8.4") +set(PROJECT_VERSION "5.8.5") find_package(ECM 5.14.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) commit 7367e55b7c172d54d068eb09f308e92368c294e9 Author: Sebastian Kügler <se...@kde.org> Date: Wed Oct 19 23:36:43 2016 +0200 allow changing an output's modelist at runtime This should fix running Plasma in a windowed virtual machine, when the window is resized, the mode list changes, and libksreen can't currently handle that. Summary: * make Output::modes() non CONSTANT, add modesChanged() signal * compare the mode lists and set the new one * queue an outputChanged signal when applied * autotest for modelist changes * update the mode list on RRNotify events BUG:356864 Test Plan: * for library part, autotests are added * for xrandr backends, we can't sensibly autotest this :( Reviewers: #plasma, mart Reviewed By: mart Subscribers: graesslin, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D3117 diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 9f8cea7..774685c 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -22,6 +22,7 @@ kscreen_add_test(testconfigmonitor) kscreen_add_test(testinprocess) kscreen_add_test(testbackendloader) kscreen_add_test(testlog) +kscreen_add_test(testmodelistchange) set(KSCREEN_WAYLAND_LIBS KF5::WaylandServer KF5::WaylandClient diff --git a/autotests/testmodelistchange.cpp b/autotests/testmodelistchange.cpp new file mode 100644 index 0000000..58080f8 --- /dev/null +++ b/autotests/testmodelistchange.cpp @@ -0,0 +1,179 @@ +/************************************************************************************* + * Copyright 2016 by Sebastian Kügler <se...@kde.org> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * + *************************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QObject> + +#include "../src/config.h" +#include "../src/configmonitor.h" +#include "../src/output.h" +#include "../src/mode.h" +#include "../src/getconfigoperation.h" +#include "../src/setconfigoperation.h" +#include "../src/backendmanager_p.h" + +using namespace KScreen; + + +class TestModeListChange : public QObject +{ + Q_OBJECT + +private: + KScreen::ConfigPtr getConfig(); + KScreen::ModeList createModeList(); + bool compareModeList(KScreen::ModeList before, KScreen::ModeList &after); + + QSize s0 = QSize(1920, 1080); + QSize s1 = QSize(1600, 1200); + QSize s2 = QSize(1280, 1024); + QSize s3 = QSize(800, 600); + QSize snew = QSize(777, 888); + QString idnew = QStringLiteral("666"); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + + void modeListChange(); +}; + +ConfigPtr TestModeListChange::getConfig() +{ + qputenv("KSCREEN_BACKEND_INPROCESS", "1"); + auto *op = new GetConfigOperation(); + if (!op->exec()) { + qWarning("ConfigOperation error: %s", qPrintable(op->errorString())); + BackendManager::instance()->shutdownBackend(); + return ConfigPtr(); + } + + BackendManager::instance()->shutdownBackend(); + + return op->config(); +} + +KScreen::ModeList TestModeListChange::createModeList() +{ + + KScreen::ModeList newmodes; + { + QString _id = QString::number(11); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s0); + kscreenMode->setRefreshRate(60); + newmodes.insert(_id, kscreenMode); + } + { + QString _id = QString::number(22); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s1); + kscreenMode->setRefreshRate(60); + newmodes.insert(_id, kscreenMode); + } + { + QString _id = QString::number(33); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s2); + kscreenMode->setRefreshRate(60); + newmodes.insert(_id, kscreenMode); + } + return newmodes; +} + + +void TestModeListChange::initTestCase() +{ + qputenv("KSCREEN_LOGGING", "false"); + qputenv("KSCREEN_BACKEND", "Fake"); +} + +void TestModeListChange::cleanupTestCase() +{ + BackendManager::instance()->shutdownBackend(); +} + +void TestModeListChange::modeListChange() +{ + //json file for the fake backend + qputenv("KSCREEN_BACKEND_ARGS", "TEST_DATA=" TEST_DATA "singleoutput.json"); + + const ConfigPtr config = getConfig(); + QVERIFY(!config.isNull()); + + auto output = config->outputs().first(); + QVERIFY(!output.isNull()); + auto modelist = output->modes(); + + auto mode = modelist.first(); + mode->setId(QStringLiteral("44")); + mode->setSize(QSize(880, 440)); + output->setModes(modelist); + + QCOMPARE(output->modes().first()->id(), QStringLiteral("44")); + QCOMPARE(output->modes().first()->size(), QSize(880, 440)); + QVERIFY(!modelist.isEmpty()); + + ConfigMonitor::instance()->addConfig(config); + QSignalSpy outputChangedSpy(output.data(), &Output::outputChanged); + QVERIFY(outputChangedSpy.isValid()); + QSignalSpy modesChangedSpy(output.data(), &Output::modesChanged); + QVERIFY(modesChangedSpy.isValid()); + + auto before = createModeList(); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 1); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 1); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 1); + QCOMPARE(output->modes().first()->size(), s0); + QCOMPARE(output->modes().first()->id(), QStringLiteral("11")); + + auto after = createModeList(); + auto firstmode = after.first(); + QVERIFY(!firstmode.isNull()); + QCOMPARE(firstmode->size(), s0); + QCOMPARE(firstmode->id(), QStringLiteral("11")); + firstmode->setSize(snew); + firstmode->setId(idnew); + output->setModes(after); + QCOMPARE(modesChangedSpy.count(), 2); + + QString _id = QString::number(11); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s0); + kscreenMode->setRefreshRate(60); + before.insert(_id, kscreenMode); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 3); + QCOMPARE(outputChangedSpy.count(), modesChangedSpy.count()); +} + + +QTEST_MAIN(TestModeListChange) + +#include "testmodelistchange.moc" diff --git a/backends/xrandr/xrandroutput.cpp b/backends/xrandr/xrandroutput.cpp index 9a5cabc..94a0b65 100644 --- a/backends/xrandr/xrandroutput.cpp +++ b/backends/xrandr/xrandroutput.cpp @@ -141,7 +141,7 @@ void XRandROutput::update(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, xcb_rand if (isConnected() != (conn == XCB_RANDR_CONNECTION_CONNECTED)) { if (conn == XCB_RANDR_CONNECTION_CONNECTED) { // New monitor has been connected, refresh everything - init(); + init(); } else { // Disconnected m_connected = conn; @@ -153,6 +153,14 @@ void XRandROutput::update(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, xcb_rand m_modes.clear(); m_preferredModes.clear(); } + } else if (conn == XCB_RANDR_CONNECTION_CONNECTED) { + // the output changed in some way, let's update the internal + // list of modes, as it may have changed + XCB::OutputInfo outputInfo(m_id, XCB_TIME_CURRENT_TIME); + if (outputInfo) { + updateModes(outputInfo); + } + } // A monitor has been enabled or disabled diff --git a/src/output.cpp b/src/output.cpp index a45150e..1fcf30b 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -69,6 +69,7 @@ class Output::Private } QString biggestMode(const ModeList& modes) const; + bool compareModeList(const ModeList& before, const ModeList& after); int id; QString name; @@ -90,6 +91,32 @@ class Output::Private mutable QPointer<Edid> edid; }; +bool Output::Private::compareModeList(const ModeList& before, const ModeList &after) +{ + if (before.keys() != after.keys()) { + return false; + } + for (const QString &key : before.keys()) { + const auto mb = before.value(key); + const auto ma = after.value(key); + if (mb->id() != ma->id()) { + return false; + } + if (mb->size() != ma->size()) { + return false; + } + if (mb->refreshRate() != ma->refreshRate()) { + return false; + } + if (mb->name() != ma->name()) { + return false; + } + } + // They're the same + return true; +} + + QString Output::Private::biggestMode(const ModeList& modes) const { int area, total = 0; @@ -221,7 +248,12 @@ ModeList Output::modes() const void Output::setModes(const ModeList &modes) { + bool changed = !d->compareModeList(d->modeList, modes); d->modeList = modes; + if (changed) { + emit modesChanged(); + emit outputChanged(); + } } QString Output::currentModeId() const @@ -494,8 +526,10 @@ void Output::apply(const OutputPtr& other) changes << &Output::clonesChanged; setClones(other->d->clones);; } + if (!d->compareModeList(d->modeList, other->d->modeList)) { + changes << &Output::outputChanged; + } - // Non-notifyable changes setPreferredModes(other->d->preferredModes); ModeList modes; Q_FOREACH (const ModePtr &otherMode, other->modes()) { @@ -503,6 +537,7 @@ void Output::apply(const OutputPtr& other) } setModes(modes); + // Non-notifyable changes if (other->d->edid) { delete d->edid; d->edid = other->d->edid->clone(); diff --git a/src/output.h b/src/output.h index bb109e2..13b4a72 100644 --- a/src/output.h +++ b/src/output.h @@ -46,7 +46,7 @@ class KSCREEN_EXPORT Output : public QObject Q_PROPERTY(QString name READ name WRITE setName NOTIFY outputChanged) Q_PROPERTY(Type type READ type WRITE setType NOTIFY outputChanged) Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY outputChanged) - Q_PROPERTY(ModeList modes READ modes CONSTANT) + Q_PROPERTY(ModeList modes READ modes NOTIFY modesChanged) Q_PROPERTY(QPoint pos READ pos WRITE setPos NOTIFY posChanged) Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged) Q_PROPERTY(Rotation rotation READ rotation WRITE setRotation NOTIFY rotationChanged) @@ -204,6 +204,14 @@ class KSCREEN_EXPORT Output : public QObject void isPrimaryChanged(); void clonesChanged(); + /** The mode list changed. + * + * This may happen when a mode is added or changed. + * + * @since 5.8.3 + */ + void modesChanged(); + private: Q_DISABLE_COPY(Output)
diff -Nru libkscreen-5.8.4/autotests/CMakeLists.txt libkscreen-5.8.6/autotests/CMakeLists.txt --- libkscreen-5.8.4/autotests/CMakeLists.txt 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/autotests/CMakeLists.txt 2017-02-21 13:06:30.000000000 +0100 @@ -22,6 +22,7 @@ kscreen_add_test(testinprocess) kscreen_add_test(testbackendloader) kscreen_add_test(testlog) +kscreen_add_test(testmodelistchange) set(KSCREEN_WAYLAND_LIBS KF5::WaylandServer KF5::WaylandClient diff -Nru libkscreen-5.8.4/autotests/testlog.cpp libkscreen-5.8.6/autotests/testlog.cpp --- libkscreen-5.8.4/autotests/testlog.cpp 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/autotests/testlog.cpp 2017-02-21 13:06:30.000000000 +0100 @@ -55,6 +55,7 @@ void TestLog::initTestCase() { + qputenv(KSCREEN_LOGGING, QByteArray("true")); } void TestLog::cleanupTestCase() @@ -85,6 +86,13 @@ qunsetenv(KSCREEN_LOGGING); log = Log::instance(); + QCOMPARE(log->enabled(), false); + QCOMPARE(log->logFile(), QString()); + + delete log; + qputenv(KSCREEN_LOGGING, QByteArray("truE")); + + log = Log::instance(); QCOMPARE(log->enabled(), true); QCOMPARE(log->logFile(), m_defaultLogFile); diff -Nru libkscreen-5.8.4/autotests/testmodelistchange.cpp libkscreen-5.8.6/autotests/testmodelistchange.cpp --- libkscreen-5.8.4/autotests/testmodelistchange.cpp 1970-01-01 01:00:00.000000000 +0100 +++ libkscreen-5.8.6/autotests/testmodelistchange.cpp 2017-02-21 13:06:30.000000000 +0100 @@ -0,0 +1,179 @@ +/************************************************************************************* + * Copyright 2016 by Sebastian Kügler <se...@kde.org> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * + *************************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QObject> + +#include "../src/config.h" +#include "../src/configmonitor.h" +#include "../src/output.h" +#include "../src/mode.h" +#include "../src/getconfigoperation.h" +#include "../src/setconfigoperation.h" +#include "../src/backendmanager_p.h" + +using namespace KScreen; + + +class TestModeListChange : public QObject +{ + Q_OBJECT + +private: + KScreen::ConfigPtr getConfig(); + KScreen::ModeList createModeList(); + bool compareModeList(KScreen::ModeList before, KScreen::ModeList &after); + + QSize s0 = QSize(1920, 1080); + QSize s1 = QSize(1600, 1200); + QSize s2 = QSize(1280, 1024); + QSize s3 = QSize(800, 600); + QSize snew = QSize(777, 888); + QString idnew = QStringLiteral("666"); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + + void modeListChange(); +}; + +ConfigPtr TestModeListChange::getConfig() +{ + qputenv("KSCREEN_BACKEND_INPROCESS", "1"); + auto *op = new GetConfigOperation(); + if (!op->exec()) { + qWarning("ConfigOperation error: %s", qPrintable(op->errorString())); + BackendManager::instance()->shutdownBackend(); + return ConfigPtr(); + } + + BackendManager::instance()->shutdownBackend(); + + return op->config(); +} + +KScreen::ModeList TestModeListChange::createModeList() +{ + + KScreen::ModeList newmodes; + { + QString _id = QString::number(11); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s0); + kscreenMode->setRefreshRate(60); + newmodes.insert(_id, kscreenMode); + } + { + QString _id = QString::number(22); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s1); + kscreenMode->setRefreshRate(60); + newmodes.insert(_id, kscreenMode); + } + { + QString _id = QString::number(33); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s2); + kscreenMode->setRefreshRate(60); + newmodes.insert(_id, kscreenMode); + } + return newmodes; +} + + +void TestModeListChange::initTestCase() +{ + qputenv("KSCREEN_LOGGING", "false"); + qputenv("KSCREEN_BACKEND", "Fake"); +} + +void TestModeListChange::cleanupTestCase() +{ + BackendManager::instance()->shutdownBackend(); +} + +void TestModeListChange::modeListChange() +{ + //json file for the fake backend + qputenv("KSCREEN_BACKEND_ARGS", "TEST_DATA=" TEST_DATA "singleoutput.json"); + + const ConfigPtr config = getConfig(); + QVERIFY(!config.isNull()); + + auto output = config->outputs().first(); + QVERIFY(!output.isNull()); + auto modelist = output->modes(); + + auto mode = modelist.first(); + mode->setId(QStringLiteral("44")); + mode->setSize(QSize(880, 440)); + output->setModes(modelist); + + QCOMPARE(output->modes().first()->id(), QStringLiteral("44")); + QCOMPARE(output->modes().first()->size(), QSize(880, 440)); + QVERIFY(!modelist.isEmpty()); + + ConfigMonitor::instance()->addConfig(config); + QSignalSpy outputChangedSpy(output.data(), &Output::outputChanged); + QVERIFY(outputChangedSpy.isValid()); + QSignalSpy modesChangedSpy(output.data(), &Output::modesChanged); + QVERIFY(modesChangedSpy.isValid()); + + auto before = createModeList(); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 1); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 1); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 1); + QCOMPARE(output->modes().first()->size(), s0); + QCOMPARE(output->modes().first()->id(), QStringLiteral("11")); + + auto after = createModeList(); + auto firstmode = after.first(); + QVERIFY(!firstmode.isNull()); + QCOMPARE(firstmode->size(), s0); + QCOMPARE(firstmode->id(), QStringLiteral("11")); + firstmode->setSize(snew); + firstmode->setId(idnew); + output->setModes(after); + QCOMPARE(modesChangedSpy.count(), 2); + + QString _id = QString::number(11); + KScreen::ModePtr kscreenMode(new KScreen::Mode); + kscreenMode->setId(_id); + kscreenMode->setName(_id); + kscreenMode->setSize(s0); + kscreenMode->setRefreshRate(60); + before.insert(_id, kscreenMode); + output->setModes(before); + QCOMPARE(modesChangedSpy.count(), 3); + QCOMPARE(outputChangedSpy.count(), modesChangedSpy.count()); +} + + +QTEST_MAIN(TestModeListChange) + +#include "testmodelistchange.moc" diff -Nru libkscreen-5.8.4/backends/xrandr/xrandroutput.cpp libkscreen-5.8.6/backends/xrandr/xrandroutput.cpp --- libkscreen-5.8.4/backends/xrandr/xrandroutput.cpp 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/backends/xrandr/xrandroutput.cpp 2017-02-21 13:06:30.000000000 +0100 @@ -141,7 +141,7 @@ if (isConnected() != (conn == XCB_RANDR_CONNECTION_CONNECTED)) { if (conn == XCB_RANDR_CONNECTION_CONNECTED) { // New monitor has been connected, refresh everything - init(); + init(); } else { // Disconnected m_connected = conn; @@ -153,6 +153,14 @@ m_modes.clear(); m_preferredModes.clear(); } + } else if (conn == XCB_RANDR_CONNECTION_CONNECTED) { + // the output changed in some way, let's update the internal + // list of modes, as it may have changed + XCB::OutputInfo outputInfo(m_id, XCB_TIME_CURRENT_TIME); + if (outputInfo) { + updateModes(outputInfo); + } + } // A monitor has been enabled or disabled @@ -310,7 +318,7 @@ char *connectorType; - auto cookie = xcb_randr_get_output_property(XCB::connection(), outputId, atomType, + auto cookie = xcb_randr_get_output_property(XCB::connection(), outputId, atomType->atom, XCB_ATOM_ANY, 0, 100, false, false); XCB::ScopedPointer<xcb_randr_get_output_property_reply_t> reply(xcb_randr_get_output_property_reply(XCB::connection(), cookie, NULL)); if (!reply) { diff -Nru libkscreen-5.8.4/CMakeLists.txt libkscreen-5.8.6/CMakeLists.txt --- libkscreen-5.8.4/CMakeLists.txt 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/CMakeLists.txt 2017-02-21 13:06:30.000000000 +0100 @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.12) project(libkscreen) -set(PROJECT_VERSION "5.8.4") +set(PROJECT_VERSION "5.8.6") find_package(ECM 5.14.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) diff -Nru libkscreen-5.8.4/debian/changelog libkscreen-5.8.6/debian/changelog --- libkscreen-5.8.4/debian/changelog 2016-11-23 18:37:14.000000000 +0100 +++ libkscreen-5.8.6/debian/changelog 2017-03-13 11:33:19.000000000 +0100 @@ -1,3 +1,17 @@ +libkscreen (4:5.8.6-1) experimental; urgency=medium + + * New upstream release (5.8.6) + + Disable kscreen.log logging by default (Closes: 846940) + + -- Maximiliano Curia <m...@debian.org> Mon, 13 Mar 2017 11:33:19 +0100 + +libkscreen (4:5.8.5-1) experimental; urgency=medium + + * New upstream release (5.8.5). + * Update symbols files. + + -- Maximiliano Curia <m...@debian.org> Fri, 30 Dec 2016 18:46:19 +0100 + libkscreen (4:5.8.4-1) unstable; urgency=medium [ Automatic packaging ] diff -Nru libkscreen-5.8.4/debian/libkf5screen7.symbols libkscreen-5.8.6/debian/libkf5screen7.symbols --- libkscreen-5.8.4/debian/libkf5screen7.symbols 2016-11-23 18:37:14.000000000 +0100 +++ libkscreen-5.8.6/debian/libkf5screen7.symbols 2017-03-13 11:33:19.000000000 +0100 @@ -1,4 +1,4 @@ -# SymbolsHelper-Confirmed: 4:5.8.0 amd64 armhf i386 +# SymbolsHelper-Confirmed: 4:5.8.5 amd64 libKF5Screen.so.7 libkf5screen7 #MINVER#, libkf5screen-bin (>= 4:5.6.2~) _ZN7KScreen13ConfigMonitor11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.1.1 _ZN7KScreen13ConfigMonitor11qt_metacastEPKc@Base 5.1.1 @@ -171,6 +171,7 @@ _ZN7KScreen6Output11qt_metacastEPKc@Base 5.1.1 _ZN7KScreen6Output11setRotationENS0_8RotationE@Base 5.1.1 _ZN7KScreen6Output11sizeChangedEv@Base 4:5.4.0 + _ZN7KScreen6Output12modesChangedEv@Base 4:5.8.5 _ZN7KScreen6Output12setConnectedEb@Base 5.1.1 _ZN7KScreen6Output13clonesChangedEv@Base 5.1.1 _ZN7KScreen6Output13outputChangedEv@Base 5.1.1 @@ -185,6 +186,7 @@ _ZN7KScreen6Output5applyERK14QSharedPointerIS0_E@Base 5.1.1 _ZN7KScreen6Output5setIdEi@Base 5.1.1 _ZN7KScreen6Output6setPosERK6QPoint@Base 5.1.1 + _ZN7KScreen6Output7Private15compareModeListERK4QMapI7QString14QSharedPointerINS_4ModeEEES9_@Base 4:5.8.5 _ZN7KScreen6Output7setEdidERK10QByteArray@Base 5.1.1 _ZN7KScreen6Output7setIconERK7QString@Base 5.1.1 _ZN7KScreen6Output7setNameERK7QString@Base 5.1.1 diff -Nru libkscreen-5.8.4/debian/patches/make_kwayland_optional.diff libkscreen-5.8.6/debian/patches/make_kwayland_optional.diff --- libkscreen-5.8.4/debian/patches/make_kwayland_optional.diff 2016-11-23 18:37:14.000000000 +0100 +++ libkscreen-5.8.6/debian/patches/make_kwayland_optional.diff 2017-03-13 11:33:19.000000000 +0100 @@ -9,11 +9,9 @@ tests/CMakeLists.txt | 4 +++- 4 files changed, 27 insertions(+), 19 deletions(-) -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 8515e95..a66cf5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -20,7 +20,7 @@ set(REQUIRED_QT_VERSION 5.4.0) +@@ -20,7 +20,7 @@ find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core DBus Gui Test X11Extras) # Wayland backend @@ -22,8 +20,6 @@ add_feature_info("KF5Wayland" KF5Wayland_FOUND "Required for building libkscreen's KWayland backend") # xrandr backend -diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt -index 9f8cea7..3a3bc20 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -1,6 +1,9 @@ @@ -37,9 +33,9 @@ macro(KSCREEN_ADD_TEST) foreach(_testname ${ARGN}) -@@ -23,24 +26,25 @@ kscreen_add_test(testinprocess) - kscreen_add_test(testbackendloader) +@@ -24,24 +27,25 @@ kscreen_add_test(testlog) + kscreen_add_test(testmodelistchange) -set(KSCREEN_WAYLAND_LIBS - KF5::WaylandServer KF5::WaylandClient @@ -51,35 +47,36 @@ - ${CMAKE_SOURCE_DIR}/tests/kwayland/waylandtestserver.cpp -) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../backends/kwayland) +- +-kscreen_add_test(testkwaylandbackend) +-kscreen_add_test(testkwaylandconfig) +-kscreen_add_test(testkwaylanddpms) +- +-set(KSCREEN_WAYLAND_LIBS "") +-set(KSCREEN_WAYLAND_SRCS "") +- +if(${KF5Wayland_FOUND}) + set(KSCREEN_WAYLAND_LIBS + KF5::WaylandServer KF5::WaylandClient + ) - --kscreen_add_test(testkwaylandbackend) --kscreen_add_test(testkwaylandconfig) --kscreen_add_test(testkwaylanddpms) ++ + # For WaylandConfigReader and TestServer + set(KSCREEN_WAYLAND_SRCS + ${CMAKE_SOURCE_DIR}/tests/kwayland/waylandconfigreader.cpp + ${CMAKE_SOURCE_DIR}/tests/kwayland/waylandtestserver.cpp + ) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../backends/kwayland) - --set(KSCREEN_WAYLAND_LIBS "") --set(KSCREEN_WAYLAND_SRCS "") ++ + kscreen_add_test(testkwaylandbackend) + kscreen_add_test(testkwaylandconfig) + kscreen_add_test(testkwaylanddpms) - ++ + set(KSCREEN_WAYLAND_LIBS "") + set(KSCREEN_WAYLAND_SRCS "") +endif() if (ENABLE_XRANDR_TESTS) kscreen_add_test(textxrandr) -diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt -index 3563e13..5f44182 100644 --- a/backends/CMakeLists.txt +++ b/backends/CMakeLists.txt @@ -1,6 +1,8 @@ @@ -92,8 +89,6 @@ if(${XCB_RANDR_FOUND}) message(STATUS "Will build xrandr backend.") -diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt -index 1489d21..e82f7f7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,6 @@ diff -Nru libkscreen-5.8.4/src/log.cpp libkscreen-5.8.6/src/log.cpp --- libkscreen-5.8.4/src/log.cpp 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/src/log.cpp 2017-02-21 13:06:30.000000000 +0100 @@ -57,7 +57,7 @@ { public: QString context; - bool enabled = true; + bool enabled = false; QString logFile; }; @@ -68,11 +68,13 @@ if (qEnvironmentVariableIsSet(logging_env)) { const QString logging_env_value = qgetenv(logging_env).constData(); - if (logging_env_value == QStringLiteral("0") || logging_env_value.toLower() == QStringLiteral("false")) { - d->enabled = false; - return; + if (logging_env_value != QStringLiteral("0") && logging_env_value.toLower() != QStringLiteral("false")) { + d->enabled = true; } } + if (!d->enabled) { + return; + } d->logFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kscreen/kscreen.log"; QLoggingCategory::setFilterRules("kscreen.*=true"); diff -Nru libkscreen-5.8.4/src/output.cpp libkscreen-5.8.6/src/output.cpp --- libkscreen-5.8.4/src/output.cpp 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/src/output.cpp 2017-02-21 13:06:30.000000000 +0100 @@ -69,6 +69,7 @@ } QString biggestMode(const ModeList& modes) const; + bool compareModeList(const ModeList& before, const ModeList& after); int id; QString name; @@ -90,6 +91,32 @@ mutable QPointer<Edid> edid; }; +bool Output::Private::compareModeList(const ModeList& before, const ModeList &after) +{ + if (before.keys() != after.keys()) { + return false; + } + for (const QString &key : before.keys()) { + const auto mb = before.value(key); + const auto ma = after.value(key); + if (mb->id() != ma->id()) { + return false; + } + if (mb->size() != ma->size()) { + return false; + } + if (mb->refreshRate() != ma->refreshRate()) { + return false; + } + if (mb->name() != ma->name()) { + return false; + } + } + // They're the same + return true; +} + + QString Output::Private::biggestMode(const ModeList& modes) const { int area, total = 0; @@ -221,7 +248,12 @@ void Output::setModes(const ModeList &modes) { + bool changed = !d->compareModeList(d->modeList, modes); d->modeList = modes; + if (changed) { + emit modesChanged(); + emit outputChanged(); + } } QString Output::currentModeId() const @@ -494,8 +526,10 @@ changes << &Output::clonesChanged; setClones(other->d->clones);; } + if (!d->compareModeList(d->modeList, other->d->modeList)) { + changes << &Output::outputChanged; + } - // Non-notifyable changes setPreferredModes(other->d->preferredModes); ModeList modes; Q_FOREACH (const ModePtr &otherMode, other->modes()) { @@ -503,6 +537,7 @@ } setModes(modes); + // Non-notifyable changes if (other->d->edid) { delete d->edid; d->edid = other->d->edid->clone(); diff -Nru libkscreen-5.8.4/src/output.h libkscreen-5.8.6/src/output.h --- libkscreen-5.8.4/src/output.h 2016-11-22 11:18:06.000000000 +0100 +++ libkscreen-5.8.6/src/output.h 2017-02-21 13:06:30.000000000 +0100 @@ -46,7 +46,7 @@ Q_PROPERTY(QString name READ name WRITE setName NOTIFY outputChanged) Q_PROPERTY(Type type READ type WRITE setType NOTIFY outputChanged) Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY outputChanged) - Q_PROPERTY(ModeList modes READ modes CONSTANT) + Q_PROPERTY(ModeList modes READ modes NOTIFY modesChanged) Q_PROPERTY(QPoint pos READ pos WRITE setPos NOTIFY posChanged) Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged) Q_PROPERTY(Rotation rotation READ rotation WRITE setRotation NOTIFY rotationChanged) @@ -204,6 +204,14 @@ void isPrimaryChanged(); void clonesChanged(); + /** The mode list changed. + * + * This may happen when a mode is added or changed. + * + * @since 5.8.3 + */ + void modesChanged(); + private: Q_DISABLE_COPY(Output)