Hello community, here is the log from the commit of package libkscreen2 for openSUSE:Factory checked in at 2016-10-04 15:52:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libkscreen2 (Old) and /work/SRC/openSUSE:Factory/.libkscreen2.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libkscreen2" Changes: -------- --- /work/SRC/openSUSE:Factory/libkscreen2/libkscreen2.changes 2016-08-29 15:28:15.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libkscreen2.new/libkscreen2.changes 2016-10-04 15:52:31.000000000 +0200 @@ -1,0 +2,29 @@ +Thu Sep 29 16:36:28 UTC 2016 - [email protected] + +- Update to 5.8.0 + * New LTS feature release + * For more details please see: + https://www.kde.org/announcements/plasma-5.8.0.php + +------------------------------------------------------------------- +Wed Sep 21 09:15:09 UTC 2016 - [email protected] + +- Use %{_plasma5_version} again, define it if needed + +------------------------------------------------------------------- +Thu Sep 15 15:53:55 UTC 2016 - [email protected] + +- Update to 5.7.95 (Plasma 5.8 Beta) + * New LTS feature release + * For more details please see: + https://www.kde.org/announcements/plasma-5.7.95.php + +------------------------------------------------------------------- +Tue Sep 13 17:42:09 UTC 2016 - [email protected] + +- Update to 5.7.5 + * New bugfix release + * For more details please see: + https://www.kde.org/announcements/plasma-5.7.5.php + +------------------------------------------------------------------- Old: ---- libkscreen-5.7.4.tar.xz New: ---- libkscreen-5.8.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libkscreen2.spec ++++++ --- /var/tmp/diff_new_pack.ZzzShQ/_old 2016-10-04 15:52:32.000000000 +0200 +++ /var/tmp/diff_new_pack.ZzzShQ/_new 2016-10-04 15:52:32.000000000 +0200 @@ -15,17 +15,17 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - %define lname libKF5Screen7 %define plasma_version 5.0.0 Name: libkscreen2 -Version: 5.7.4 +Version: 5.8.0 Release: 0 +%{!?_plasma5_version: %global _plasma5_version %{version}} BuildRequires: cmake >= 2.8.12 BuildRequires: extra-cmake-modules >= 5.14.0 BuildRequires: fdupes BuildRequires: kf5-filesystem -BuildRequires: cmake(KF5Wayland) >= %{version} +BuildRequires: cmake(KF5Wayland) >= %{_plasma5_version} BuildRequires: cmake(Qt5Core) >= 5.4.0 BuildRequires: cmake(Qt5DBus) >= 5.4.0 BuildRequires: cmake(Qt5Gui) >= 5.4.0 ++++++ libkscreen-5.7.4.tar.xz -> libkscreen-5.8.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/CMakeLists.txt new/libkscreen-5.8.0/CMakeLists.txt --- old/libkscreen-5.7.4/CMakeLists.txt 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/CMakeLists.txt 2016-09-29 13:28:59.000000000 +0200 @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.12) project(libkscreen) -set(PROJECT_VERSION "5.7.4") +set(PROJECT_VERSION "5.8.0") find_package(ECM 5.14.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/CMakeLists.txt new/libkscreen-5.8.0/autotests/CMakeLists.txt --- old/libkscreen-5.7.4/autotests/CMakeLists.txt 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/CMakeLists.txt 2016-09-29 13:28:59.000000000 +0200 @@ -21,6 +21,7 @@ kscreen_add_test(testconfigmonitor) kscreen_add_test(testinprocess) kscreen_add_test(testbackendloader) +kscreen_add_test(testlog) set(KSCREEN_WAYLAND_LIBS KF5::WaylandServer KF5::WaylandClient diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testbackendloader.cpp new/libkscreen-5.8.0/autotests/testbackendloader.cpp --- old/libkscreen-5.7.4/autotests/testbackendloader.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testbackendloader.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -47,6 +47,7 @@ TestBackendLoader::TestBackendLoader(QObject *parent) : QObject(parent) { + qputenv("KSCREEN_LOGGING", "false"); qputenv("KSCREEN_BACKEND_INPROCESS", QByteArray()); qputenv("KSCREEN_BACKEND", QByteArray()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testconfigmonitor.cpp new/libkscreen-5.8.0/autotests/testconfigmonitor.cpp --- old/libkscreen-5.7.4/autotests/testconfigmonitor.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testconfigmonitor.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -55,6 +55,7 @@ private Q_SLOTS: void initTestCase() { + qputenv("KSCREEN_LOGGING", "false"); qputenv("KSCREEN_BACKEND", "Fake"); // This particular test is only useful for out of process operation, so enforce that qputenv("KSCREEN_BACKEND_INPROCESS", "0"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testinprocess.cpp new/libkscreen-5.8.0/autotests/testinprocess.cpp --- old/libkscreen-5.7.4/autotests/testinprocess.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testinprocess.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -68,6 +68,7 @@ void TestInProcess::init() { + qputenv("KSCREEN_LOGGING", "false"); // Make sure we do everything in-process qputenv("KSCREEN_BACKEND_INPROCESS", "1"); // Use Fake backend with one of the json configs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testkwaylandbackend.cpp new/libkscreen-5.8.0/autotests/testkwaylandbackend.cpp --- old/libkscreen-5.7.4/autotests/testkwaylandbackend.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testkwaylandbackend.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -74,6 +74,7 @@ : QObject(parent) , m_config(nullptr) { + qputenv("KSCREEN_LOGGING", "false"); m_server = new WaylandTestServer(this); m_server->setConfig(TEST_DATA + QStringLiteral("multipleoutput.json")); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testkwaylandconfig.cpp new/libkscreen-5.8.0/autotests/testkwaylandconfig.cpp --- old/libkscreen-5.7.4/autotests/testkwaylandconfig.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testkwaylandconfig.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -63,6 +63,7 @@ : QObject(parent) , m_server(nullptr) { + qputenv("KSCREEN_LOGGING", "false"); } void TestKWaylandConfig::initTestCase() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testlog.cpp new/libkscreen-5.8.0/autotests/testlog.cpp --- old/libkscreen-5.7.4/autotests/testlog.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-5.8.0/autotests/testlog.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -0,0 +1,131 @@ +/************************************************************************************* + * Copyright 2016 by Sebastian Kügler <[email protected]> * + * * + * 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 <QLoggingCategory> + +#include "../src/log.h" + +Q_DECLARE_LOGGING_CATEGORY(KSCREEN_TESTLOG) + +Q_LOGGING_CATEGORY(KSCREEN_TESTLOG, "kscreen.testlog") + +using namespace KScreen; + +auto KSCREEN_LOGGING = "KSCREEN_LOGGING"; + +class TestLog : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void init(); + void initTestCase(); + void cleanupTestCase(); + void testContext(); + void testEnabled(); + void testLog(); + +private: + QString m_defaultLogFile; +}; + +void TestLog::init() +{ + QStandardPaths::setTestModeEnabled(true); + m_defaultLogFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kscreen/kscreen.log"; +} + +void TestLog::initTestCase() +{ + +} + +void TestLog::cleanupTestCase() +{ + qunsetenv(KSCREEN_LOGGING); +} + +void TestLog::testContext() +{ + auto log = Log::instance(); + QString ctx("context text"); + QVERIFY(log != nullptr); + log->setContext(ctx); + QCOMPARE(log->context(), ctx); + + delete log; +} + +void TestLog::testEnabled() +{ + qputenv(KSCREEN_LOGGING, QByteArray("faLSe")); + + auto log = Log::instance(); + QCOMPARE(log->enabled(), false); + QCOMPARE(log->logFile(), QString()); + + delete log; + qunsetenv(KSCREEN_LOGGING); + + log = Log::instance(); + QCOMPARE(log->enabled(), true); + QCOMPARE(log->logFile(), m_defaultLogFile); + + delete log; +} + +void TestLog::testLog() +{ + auto log = Log::instance(); + + QFile lf(m_defaultLogFile); + lf.remove(); + QVERIFY(!lf.exists()); + + QString logmsg("This is a log message. ♥"); + Log::log(logmsg); + + QVERIFY(lf.exists()); + QVERIFY(lf.remove()); + + qCDebug(KSCREEN_TESTLOG) << "qCDebug message from testlog"; + QVERIFY(lf.exists()); + QVERIFY(lf.remove()); + + delete Log::instance(); + + // Make sure on log file gets written when disabled + qputenv(KSCREEN_LOGGING, "false"); + + qCDebug(KSCREEN_TESTLOG) << logmsg; + QCOMPARE(Log::instance()->enabled(), false); + QVERIFY(!lf.exists()); + + Log::log(logmsg); + QVERIFY(!lf.exists()); + + // Make sure we don't crash on cleanup + delete Log::instance(); + delete Log::instance(); +} + +QTEST_MAIN(TestLog) + +#include "testlog.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testqscreenbackend.cpp new/libkscreen-5.8.0/autotests/testqscreenbackend.cpp --- old/libkscreen-5.7.4/autotests/testqscreenbackend.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testqscreenbackend.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -54,6 +54,7 @@ void testQScreenBackend::initTestCase() { + qputenv("KSCREEN_LOGGING", "false"); qputenv("KSCREEN_BACKEND", "qscreen"); qputenv("KSCREEN_BACKEND_INPROCESS", "1"); KScreen::BackendManager::instance()->shutdownBackend(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/autotests/testscreenconfig.cpp new/libkscreen-5.8.0/autotests/testscreenconfig.cpp --- old/libkscreen-5.7.4/autotests/testscreenconfig.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/autotests/testscreenconfig.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -24,6 +24,7 @@ #include "../src/output.h" #include "../src/mode.h" #include "../src/getconfigoperation.h" +#include "../src/setconfigoperation.h" #include "../src/backendmanager_p.h" using namespace KScreen; @@ -43,7 +44,9 @@ void clonesOutput(); void configCanBeApplied(); void supportedFeatures(); + void testInvalidMode(); void cleanupTestCase(); + void testOutputPositionNormalization(); }; ConfigPtr testScreenConfig::getConfig() @@ -64,6 +67,7 @@ void testScreenConfig::initTestCase() { + qputenv("KSCREEN_LOGGING", "false"); qputenv("KSCREEN_BACKEND", "Fake"); } @@ -245,6 +249,60 @@ QVERIFY(config->supportedFeatures().testFlag(KScreen::Config::Feature::PrimaryDisplay)); } +void testScreenConfig::testInvalidMode() +{ + ModeList modes; + ModePtr invalidMode = modes.value("99"); + QVERIFY(invalidMode.isNull()); + + auto output = new KScreen::Output(); + auto currentMode = output->currentMode(); + QVERIFY(currentMode.isNull()); + QVERIFY(!currentMode); + delete output; +} + +void testScreenConfig::testOutputPositionNormalization() +{ + qputenv("KSCREEN_BACKEND_ARGS", "TEST_DATA=" TEST_DATA "multipleoutput.json"); + + const ConfigPtr config = getConfig(); + QVERIFY(!config.isNull()); + auto left = config->outputs().first(); + auto right = config->outputs().last(); + QVERIFY(!left.isNull()); + QVERIFY(!right.isNull()); + left->setPos(QPoint(-5000, 700)); + right->setPos(QPoint(-3720, 666)); + QCOMPARE(left->pos(), QPoint(-5000, 700)); + QCOMPARE(right->pos(), QPoint(-3720, 666)); + + // start a set operation to fix up the positions + { + auto setop = new SetConfigOperation(config); + setop->exec(); + } + QCOMPARE(left->pos(), QPoint(0, 34)); + QCOMPARE(right->pos(), QPoint(1280, 0)); + + // make sure it doesn't touch a valid config + { + auto setop = new SetConfigOperation(config); + setop->exec(); + } + QCOMPARE(left->pos(), QPoint(0, 34)); + QCOMPARE(right->pos(), QPoint(1280, 0)); + + // positions of single outputs should be at 0, 0 + left->setEnabled(false); + { + auto setop = new SetConfigOperation(config); + setop->exec(); + } + QCOMPARE(right->pos(), QPoint()); +} + + QTEST_MAIN(testScreenConfig) #include "testscreenconfig.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/backends/xrandr/xrandrconfig.cpp new/libkscreen-5.8.0/backends/xrandr/xrandrconfig.cpp --- old/libkscreen-5.7.4/backends/xrandr/xrandrconfig.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/backends/xrandr/xrandrconfig.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -515,17 +515,19 @@ return false; } + const int modeId = kscreenOutput->currentMode() ? kscreenOutput->currentModeId().toInt() : kscreenOutput->preferredModeId().toInt(); + qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (enable output)"; qCDebug(KSCREEN_XRANDR) << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() << ")"; qCDebug(KSCREEN_XRANDR) << "\tNew CRTC:" << freeCrtc->crtc(); qCDebug(KSCREEN_XRANDR) << "\tPos:" << kscreenOutput->pos(); - qCDebug(KSCREEN_XRANDR) << "\tMode:" << kscreenOutput->currentModeId() << "(" << kscreenOutput->currentMode()->size() << ")"; + qCDebug(KSCREEN_XRANDR) << "\tMode:" << kscreenOutput->currentMode() << "Preferred:" << kscreenOutput->preferredModeId(); qCDebug(KSCREEN_XRANDR) << "\tRotation:" << kscreenOutput->rotation(); auto cookie = xcb_randr_set_crtc_config(XCB::connection(), freeCrtc->crtc(), XCB_CURRENT_TIME, XCB_CURRENT_TIME, kscreenOutput->pos().rx(), kscreenOutput->pos().ry(), - kscreenOutput->currentModeId().toInt(), + modeId, kscreenOutput->rotation(), 1, outputs); XCB::ScopedPointer<xcb_randr_set_crtc_config_reply_t> reply(xcb_randr_set_crtc_config_reply(XCB::connection(), cookie, NULL)); @@ -537,7 +539,7 @@ if (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS) { XRandROutput *xOutput = output(kscreenOutput->id()); - xOutput->update(freeCrtc->crtc(), kscreenOutput->currentModeId().toInt(), + xOutput->update(freeCrtc->crtc(), modeId, XCB_RANDR_CONNECTION_CONNECTED, kscreenOutput->isPrimary()); } return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS); @@ -552,11 +554,13 @@ return enableOutput(kscreenOutput); } + int modeId = kscreenOutput->currentMode() ? kscreenOutput->currentModeId().toInt() : kscreenOutput->preferredModeId().toInt(); + qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (change output)"; qCDebug(KSCREEN_XRANDR) << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() << ")"; qCDebug(KSCREEN_XRANDR) << "\tCRTC:" << xOutput->crtc()->crtc(); qCDebug(KSCREEN_XRANDR) << "\tPos:" << kscreenOutput->pos(); - qCDebug(KSCREEN_XRANDR) << "\tMode:" << kscreenOutput->currentModeId() << "(" << kscreenOutput->currentMode()->size() << ")"; + qCDebug(KSCREEN_XRANDR) << "\tMode:" << modeId << kscreenOutput->currentMode(); qCDebug(KSCREEN_XRANDR) << "\tRotation:" << kscreenOutput->rotation(); xcb_randr_output_t outputs[1] { static_cast<xcb_randr_output_t>(kscreenOutput->id()) }; @@ -564,7 +568,7 @@ auto cookie = xcb_randr_set_crtc_config(XCB::connection(), xOutput->crtc()->crtc(), XCB_CURRENT_TIME, XCB_CURRENT_TIME, kscreenOutput->pos().rx(), kscreenOutput->pos().ry(), - kscreenOutput->currentModeId().toInt(), + modeId, kscreenOutput->rotation(), 1, outputs); XCB::ScopedPointer<xcb_randr_set_crtc_config_reply_t> reply(xcb_randr_set_crtc_config_reply(XCB::connection(), cookie, NULL)); @@ -575,7 +579,7 @@ qCDebug(KSCREEN_XRANDR) << "\tResult: " << reply->status; if (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS) { - xOutput->update(xOutput->crtc()->crtc(), kscreenOutput->currentModeId().toInt(), + xOutput->update(xOutput->crtc()->crtc(), modeId, XCB_RANDR_CONNECTION_CONNECTED, kscreenOutput->isPrimary()); } return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/CMakeLists.txt new/libkscreen-5.8.0/src/CMakeLists.txt --- old/libkscreen-5.7.4/src/CMakeLists.txt 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/CMakeLists.txt 2016-09-29 13:28:59.000000000 +0200 @@ -16,6 +16,7 @@ edid.cpp mode.cpp debug_p.cpp + log.cpp ) qt5_add_dbus_interface(libkscreen_SRCS ${CMAKE_SOURCE_DIR}/interfaces/org.kde.KScreen.Backend.xml backendinterface) @@ -43,6 +44,7 @@ ecm_generate_headers(KScreen_HEADERS HEADER_NAMES + Log Mode Output EDID diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/backendlauncher/main.cpp new/libkscreen-5.8.0/src/backendlauncher/main.cpp --- old/libkscreen-5.7.4/src/backendlauncher/main.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/backendlauncher/main.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -22,9 +22,11 @@ #include "debug_p.h" #include "backendloader.h" +#include "log.h" int main(int argc, char **argv) { + KScreen::Log::instance(); QGuiApplication::setDesktopSettingsAware(false); QGuiApplication app(argc, argv); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/backendmanager.cpp new/libkscreen-5.8.0/src/backendmanager.cpp --- old/libkscreen-5.7.4/src/backendmanager.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/backendmanager.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -28,6 +28,7 @@ #include "debug_p.h" #include "getconfigoperation.h" #include "configserializer_p.h" +#include "log.h" #include <QDBusConnection> #include <QDBusPendingCall> @@ -68,6 +69,7 @@ , mLoader(0) , mMethod(OutOfProcess) { + Log::instance(); // Decide wether to run in, or out-of-process // if KSCREEN_BACKEND_INPROCESS is set explicitely, we respect that @@ -288,7 +290,6 @@ void BackendManager::startBackend(const QString &backend, const QVariantMap &arguments) { - qCDebug(KSCREEN) << "starting external backend launcher for" << backend; // This will autostart the launcher if it's not running already, calling // requestBackend(backend) will: // a) if the launcher is started it will force it to load the correct backend, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/doctor/doctor.cpp new/libkscreen-5.8.0/src/doctor/doctor.cpp --- old/libkscreen-5.7.4/src/doctor/doctor.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/doctor/doctor.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -37,6 +37,7 @@ #include "../getconfigoperation.h" #include "../setconfigoperation.h" #include "../edid.h" +#include "../log.h" #include "../output.h" Q_LOGGING_CATEGORY(KSCREEN_DOCTOR, "kscreen.doctor") @@ -78,7 +79,7 @@ void Doctor::start(QCommandLineParser *parser) { m_parser = parser; - if (m_parser->isSet("backends")) { + if (m_parser->isSet("info")) { showBackends(); } if (parser->isSet("json") || parser->isSet("outputs") || !m_positionalArgs.isEmpty()) { @@ -109,6 +110,16 @@ } return; } + + if (m_parser->isSet("log")) { + + const QString logmsg = m_parser->value(QStringLiteral("log")); + if (!Log::instance()->enabled()) { + qCWarning(KSCREEN_DOCTOR) << "Logging is disabled, unset KSCREEN_LOGGING in your environment."; + } else { + Log::log(logmsg); + } + } // We need to kick the event loop, otherwise .quit() hangs QTimer::singleShot(0, qApp->quit); } @@ -146,9 +157,13 @@ { cout << "Environment: " << endl; auto env_kscreen_backend = (qgetenv("KSCREEN_BACKEND").isEmpty()) ? QStringLiteral("[not set]") : qgetenv("KSCREEN_BACKEND"); - cout << " * KSCREEN_BACKEND is : " << env_kscreen_backend << endl; + cout << " * KSCREEN_BACKEND : " << env_kscreen_backend << endl; auto env_kscreen_backend_inprocess = (qgetenv("KSCREEN_BACKEND_INPROCESS").isEmpty()) ? QStringLiteral("[not set]") : qgetenv("KSCREEN_BACKEND_INPROCESS"); cout << " * KSCREEN_BACKEND_INPROCESS : " << env_kscreen_backend_inprocess << endl; + auto env_kscreen_logging = (qgetenv("KSCREEN_LOGGING").isEmpty()) ? QStringLiteral("[not set]") : qgetenv("KSCREEN_LOGGING"); + cout << " * KSCREEN_LOGGING : " << env_kscreen_logging << endl; + + cout << "Logging to : " << (Log::instance()->enabled() ? Log::instance()->logFile() : "[logging disabled]") << endl; auto backends = BackendManager::instance()->listBackends(); auto preferred = BackendManager::instance()->preferredBackend(); cout << "Preferred KScreen backend : " << green << preferred.fileName() << cr << endl; @@ -175,12 +190,20 @@ auto ops = op.split('.'); if (ops.count() > 2) { bool ok; + int output_id = -1; if (ops[0] == QStringLiteral("output")) { - int output_id = parseInt(ops[1], ok); - if (!ok) { - cerr << "Unable to parse output id" << ops[1] << endl; - qApp->exit(3); - return; + Q_FOREACH (const auto &output, m_config->outputs()) { + if (output->name() == ops[1]) { + output_id = output->id(); + } + } + if (output_id == -1) { + output_id = parseInt(ops[1], ok); + if (!ok) { + cerr << "Unable to parse output id" << ops[1] << endl; + qApp->exit(3); + return; + } } if (ops.count() == 3 && ops[2] == QStringLiteral("enable")) { if (!setEnabled(output_id, true)) { @@ -300,12 +323,22 @@ Q_FOREACH (const auto &output, m_config->outputs()) { cout << green << "Output: " << cr << output->id() << " " << output->name(); cout << " " << (output->isEnabled() ? green + "enabled" : red + "disabled"); + cout << " " << (output->isConnected() ? green + "connected" : red + "disconnected"); cout << " " << (output->isPrimary() ? green + "primary" : QString()); auto _type = typeString[output->type()]; cout << " " << yellow << (_type.isEmpty() ? "UnmappedOutputType" : _type); cout << blue << " Modes: " << cr; Q_FOREACH (auto mode, output->modes()) { - cout << mode->id() << ":" << mode->name() << " "; + auto name = QString("%1x%2@%3").arg(QString::number(mode->size().width()), + QString::number(mode->size().height()), + QString::number(qRound(mode->refreshRate()))); + if (mode == output->currentMode()) { + name = green + name + "*" + cr; + } + if (mode == output->preferredMode()) { + name = name + "!"; + } + cout << mode->id() << ":" << name << " "; } const auto g = output->geometry(); cout << yellow << "Geometry: " << cr << g.x() << "," << g.y() << " " << g.width() << "x" << g.height(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/doctor/main.cpp new/libkscreen-5.8.0/src/doctor/main.cpp --- old/libkscreen-5.7.4/src/doctor/main.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/doctor/main.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -50,12 +50,12 @@ "Usage examples:\n\n" " Show output information:\n" " $ kscreen-doctor -o\n" - " Output: 1 Samsung SyncMaster enabled Modes: 1:800x600@60 [...] Geometry: 0,0 1280x800\n" - " Output: 2 DELL U2410 enabled Modes: 1:800x600@60 [...] Geometry: 1280,0 1920x1080\n" - "\n Disable the second output, enable the first and set it to a specific mode\n" - " $ kscreen-doctor output.2.disable output.1.mode.1 output.1.enable\n" - "\n Position the second output on the right of the smaller output\n" - " $ kscreen-doctor output.2.position.0,1280 output.1.position.0,0\n"; + " Output: 1 eDP-1 enabled connected Panel Modes: Modes: 1:800x600@60 [...] Geometry: 0,0 1280x800\n" + " Output: 70 HDMI-2 enabled connected HDMI Modes: 1:800x600@60 [...] Geometry: 1280,0 1920x1080\n" + "\n Disable the hdmi output, enable the laptop panel and set it to a specific mode\n" + " $ kscreen-doctor output.HDMI-2.disable output.eDP-1.mode.1 output.eDP-1.enable\n" + "\n Position the hdmi monitor on the right of the laptop panel\n" + " $ kscreen-doctor output.HDMI-2.position.0,1280 output.eDP-1.position.0,0\n"; /* "\nError codes:\n" " 2 : general parse error\n" @@ -67,34 +67,37 @@ " 9 : invalid mode id\n"; */ const QString syntax = "Specific output settings are separated by spaces, each setting is in the form of\n" - "output.<id>.<setting>[.<value>]\n" + "output.<name>.<setting>[.<value>]\n" "For example:\n" - "$ kscreen-doctor output.2.enable \\ \n" - " output.1.mode.4 \\ \n" - " output.1.position.1280,0\n" + "$ kscreen-doctor output.HDMI-2.enable \\ \n" + " output.eDP-1.mode.4 \\ \n" + " output.eDP-1.position.1280,0\n" "Multiple settings are passed in order to have kscreen-doctor apply these settings in one go.\n"; QGuiApplication app(argc, argv); KScreen::Doctor server; - QCommandLineOption backends = QCommandLineOption(QStringList() << QStringLiteral("b") << "backends", - QStringLiteral("Show backend information")); + QCommandLineOption info = QCommandLineOption(QStringList() << QStringLiteral("i") << "info", + QStringLiteral("Show runtime information: backends, logging, etc.")); QCommandLineOption outputs = QCommandLineOption(QStringList() << QStringLiteral("o") << "outputs", QStringLiteral("Show outputs")); QCommandLineOption json = QCommandLineOption(QStringList() << QStringLiteral("j") << "json", QStringLiteral("Show configuration in JSON format")); QCommandLineOption dpms = QCommandLineOption(QStringList() << QStringLiteral("d") << "dpms", - QStringLiteral("Display power management"), QStringLiteral("off")); + QStringLiteral("Display power management (wayland only)"), QStringLiteral("off")); + QCommandLineOption log = QCommandLineOption(QStringList() << QStringLiteral("l") << "log", + QStringLiteral("Write a comment to the log file"), QStringLiteral("comment")); QCommandLineParser parser; parser.setApplicationDescription(desc); - parser.addPositionalArgument("config", syntax, QStringLiteral("[output.<id>.<setting> output.<id>.setting [...]]")); + parser.addPositionalArgument("config", syntax, QStringLiteral("[output.<name>.<setting> output.<name>.setting [...]]")); parser.addHelpOption(); - parser.addOption(backends); + parser.addOption(info); parser.addOption(json); parser.addOption(outputs); parser.addOption(dpms); + parser.addOption(log); parser.process(app); if (!parser.positionalArguments().isEmpty()) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/getconfigoperation.cpp new/libkscreen-5.8.0/src/getconfigoperation.cpp --- old/libkscreen-5.7.4/src/getconfigoperation.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/getconfigoperation.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -21,6 +21,7 @@ #include "configoperation_p.h" #include "config.h" #include "output.h" +#include "log.h" #include "backendmanager_p.h" #include "configserializer_p.h" #include "backendinterface.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/log.cpp new/libkscreen-5.8.0/src/log.cpp --- old/libkscreen-5.7.4/src/log.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-5.8.0/src/log.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -0,0 +1,136 @@ +/************************************************************************************* + * Copyright 2016 by Sebastian Kügler <[email protected]> * + * * + * 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 "log.h" + +#include <QDateTime> +#include <QDir> +#include <QFile> +#include <QFileInfo> +#include <QStandardPaths> + +namespace KScreen { + +Log* Log::sInstance = nullptr; +QtMessageHandler sDefaultMessageHandler = nullptr; + +void kscreenLogOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + if (QString::fromLocal8Bit(context.category).startsWith(QLatin1String("kscreen"))) { + Log::log(localMsg.constData(), context.category); + } + sDefaultMessageHandler(type, context, msg); +} + +void log(const QString& msg) +{ + Log::log(msg); +} + +Log* Log::instance() +{ + if (!sInstance) { + sInstance = new Log(); + } + + return sInstance; +} + +using namespace KScreen; +class Log::Private +{ + public: + QString context; + bool enabled = true; + QString logFile; +}; + +Log::Log() : + d(new Private) +{ + const char* logging_env = "KSCREEN_LOGGING"; + + 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; + } + } + d->logFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kscreen/kscreen.log"; + + QLoggingCategory::setFilterRules("kscreen.*=true"); + QFileInfo fi(d->logFile); + if (!QDir().mkpath(fi.absolutePath())) { + qWarning() << "Failed to create logging dir" << fi.absolutePath(); + } + + if (!sDefaultMessageHandler) { + sDefaultMessageHandler = qInstallMessageHandler(kscreenLogOutput); + } +} + +Log::Log(Log::Private *dd) : + d(dd) +{ +} + +Log::~Log() +{ + delete d; + sInstance = nullptr; +} + +QString Log::context() const +{ + return d->context; +} + +void Log::setContext(const QString& context) +{ + d->context = context; +} + +bool Log::enabled() const +{ + return d->enabled; +} + +QString Log::logFile() const +{ + return d->logFile; +} + +void Log::log(const QString &msg, const QString &category) +{ + if (!instance()->enabled()) { + return; + } + auto _cat = category; + _cat.remove("kscreen."); + const QString timestamp = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss.zzz"); + QString logMessage = QString("\n%1 ; %2 ; %3 : %4").arg(timestamp, _cat, instance()->context(), msg); + QFile file(instance()->logFile()); + if (!file.open(QIODevice::Append | QIODevice::Text)) { + return; + } + file.write(logMessage.toUtf8()); +} + +} // ns diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/log.h new/libkscreen-5.8.0/src/log.h --- old/libkscreen-5.7.4/src/log.h 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-5.8.0/src/log.h 2016-09-29 13:28:59.000000000 +0200 @@ -0,0 +1,117 @@ +/************************************************************************************* + * Copyright 2016 by Sebastian Kügler <[email protected]> * + * * + * 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 * + *************************************************************************************/ + +#ifndef KSCREEN_LOG_H +#define KSCREEN_LOG_H + +#include "kscreen_export.h" +#include "types.h" + +#include <QObject> +#include <QLoggingCategory> + +namespace KScreen { + +void log(const QString& msg); + +/** KScreen-internal file logging. + * + * The purpose of this class is to allow better debugging of kscreen. QDebug falls short here, since + * we need to debug the concert of kscreen components from different processes. + * + * KScreen::Log manages access to kscreen's log file. + * + * The following environment variables are considered: + * - disable logging by setting + * KSCREEN_LOGGING=false + * - set the log file to a custom path, the default is in ~/.local/share/kscreen/kscreen.log + * + * Please do not translate messages written to the logs, it's developer information and should be + * english, independent from the user's locale preferences. + * + * @code + * + * Log::instance()->setContext("resume"); + * Log::log("Applying detected output configuration."); + * + * @endcode + * + * @since 5.8 + */ +class KSCREEN_EXPORT Log +{ + public: + virtual ~Log(); + + static Log* instance(); + + /** Log a message to a file + * + * Call this static method to add a new line to the log. + * + * @arg msg The log message to write. + */ + static void log(const QString &msg, const QString &category = QString()); + + /** Context for the logs. + * + * The context can be used to indicate what is going on overall, it is used to be able + * to group log entries into subsequential operations. For example the context can be + * "handling resume", which is then added to the log messages. + * + * @arg msg The log message to write to the file. + * + * @see ontext() + */ + QString context() const; + + /** Set the context for the logs. + * + * @see context() + */ + void setContext(const QString &context); + + /** Logging to file is enabled by environmental var, is it? + * + * @arg msg The log message to write to the file. + * @return Whether logging is enabled. + */ + bool enabled() const; + + /** Path to the log file + * + * This is usually ~/.local/share/kscreen/kscreen.log, but can be changed by setting + * KSCREEN_LOGFILE in the environment. + * + * @return The path to the log file. + */ + QString logFile() const; + + private: + explicit Log(); + class Private; + Private * const d; + + static Log* sInstance; + Log(Private *dd); +}; + +} //KSCreen namespace + + +#endif //KSCREEN_LOG_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/output.cpp new/libkscreen-5.8.0/src/output.cpp --- old/libkscreen-5.7.4/src/output.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/output.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -286,7 +286,7 @@ biggest = candidateMode; } - Q_ASSERT_X(biggest, "preferredModeId", "biggest mode must exists"); + Q_ASSERT_X(biggest, "preferredModeId", "biggest mode must exist"); d->preferredMode = biggest->id(); return d->preferredMode; @@ -520,7 +520,13 @@ QDebug operator<<(QDebug dbg, const KScreen::OutputPtr &output) { if(output) { - dbg << "KScreen::Output(Id:" << output->id() <<", Name:" << output->name() << ")"; + dbg << "KScreen::Output(" << output->id() << " " + << output->name() + << (output->isConnected() ? "connected" : "disconnected") + << (output->isEnabled() ? "enabled" : "disabled") + << output->pos() << output->size() + << output->currentModeId() + << ")"; } else { dbg << "KScreen::Output(NULL)"; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.7.4/src/setconfigoperation.cpp new/libkscreen-5.8.0/src/setconfigoperation.cpp --- old/libkscreen-5.7.4/src/setconfigoperation.cpp 2016-08-23 14:48:20.000000000 +0200 +++ new/libkscreen-5.8.0/src/setconfigoperation.cpp 2016-09-29 13:28:59.000000000 +0200 @@ -24,6 +24,8 @@ #include "configoperation_p.h" #include "config.h" #include "configserializer_p.h" +#include "debug_p.h" +#include "output.h" #include <QDBusPendingCallWatcher> #include <QDBusPendingCall> @@ -42,6 +44,7 @@ void backendReady(org::kde::kscreen::Backend* backend); void onConfigSet(QDBusPendingCallWatcher *watcher); + void normalizeOutputPositions(); KScreen::ConfigPtr config; @@ -120,6 +123,7 @@ void SetConfigOperation::start() { Q_D(SetConfigOperation); + d->normalizeOutputPositions(); if (BackendManager::instance()->method() == BackendManager::InProcess) { auto backend = d->loadBackend(); backend->setConfig(d->config); @@ -129,4 +133,33 @@ } } +void SetConfigOperationPrivate::normalizeOutputPositions() +{ + if (!config) { + return; + } + int offsetX = INT_MAX; + int offsetY = INT_MAX; + Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { + if (!output->isConnected() || !output->isEnabled()) { + continue; + } + offsetX = qMin(output->pos().x(), offsetX); + offsetY = qMin(output->pos().y(), offsetY); + } + + if (!offsetX && !offsetY) { + return; + } + qCDebug(KSCREEN) << "Correcting output positions by:" << QPoint(offsetX, offsetY); + Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { + if (!output->isConnected() || !output->isEnabled()) { + continue; + } + QPoint newPos = QPoint(output->pos().x() - offsetX, output->pos().y() - offsetY); + qCDebug(KSCREEN) << "Moved output from" << output->pos() << "to" << newPos; + output->setPos(newPos); + } +} + #include "setconfigoperation.moc"
