Hello community, here is the log from the commit of package libkscreen2 for openSUSE:Leap:15.2 checked in at 2020-02-16 18:28:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/libkscreen2 (Old) and /work/SRC/openSUSE:Leap:15.2/.libkscreen2.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libkscreen2" Sun Feb 16 18:28:26 2020 rev:90 rq:774566 version:5.18.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/libkscreen2/libkscreen2.changes 2020-01-15 15:21:48.766455679 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.libkscreen2.new.26092/libkscreen2.changes 2020-02-16 18:29:22.446751098 +0100 @@ -1,0 +2,39 @@ +Thu Feb 6 15:10:05 UTC 2020 - Fabian Vogt <[email protected]> + +- Update to 5.18.0 + * New bugfix release + * For more details please see: + * https://www.kde.org/announcements/plasma-5.18.0.php +- No code changes since 5.17.90 + +------------------------------------------------------------------- +Thu Jan 23 11:20:30 UTC 2020 - Christophe Giboudeaux <[email protected]> + +- Replace %make_jobs with %cmake_build + +------------------------------------------------------------------- +Mon Jan 20 13:34:02 UTC 2020 - Fabian Vogt <[email protected]> + +- Fix version in source URL + +------------------------------------------------------------------- +Thu Jan 16 14:04:18 UTC 2020 - Fabian Vogt <[email protected]> + +- Update to 5.17.90.1 + * New feature release + * For more details please see: + * https://www.kde.org/announcements/plasma-5.17.90.php +- Changes since 5.17.5: + * fix(kwayland): move blocking tablet init before timer start + * KF5_MIN_VERSION for plasma 5.18 is KF5 5.66.0 + * fix(randr): make sure crtc exists + * feat: add auto rotate and tablet mode information + * feat: replace replication source with logical size API + * docs: add todos for KF6 + * docs: add contributing guide + * Add KDEClangFormat cmake support + * [wayland] Don't init m_internalConfig twice + * Now we depend against kf5.58 + * Make it compile against qt 5.14 + +------------------------------------------------------------------- Old: ---- libkscreen-5.17.5.tar.xz libkscreen-5.17.5.tar.xz.sig New: ---- libkscreen-5.18.0.tar.xz libkscreen-5.18.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libkscreen2.spec ++++++ --- /var/tmp/diff_new_pack.RTlRrE/_old 2020-02-16 18:29:23.018751397 +0100 +++ /var/tmp/diff_new_pack.RTlRrE/_new 2020-02-16 18:29:23.022751399 +0100 @@ -19,7 +19,7 @@ %bcond_without lang %define lname libKF5Screen7 Name: libkscreen2 -Version: 5.17.5 +Version: 5.18.0 Release: 0 # Full Plasma 5 version (e.g. 5.8.95) %{!?_plasma5_bugfix: %define _plasma5_bugfix %{version}} @@ -29,9 +29,9 @@ License: GPL-2.0-or-later Group: System/GUI/KDE Url: http://www.kde.org -Source: https://download.kde.org/stable/plasma/%{version}/libkscreen-%{version}.tar.xz +Source: libkscreen-%{version}.tar.xz %if %{with lang} -Source1: https://download.kde.org/stable/plasma/%{version}/libkscreen-%{version}.tar.xz.sig +Source1: libkscreen-%{version}.tar.xz.sig Source2: plasma.keyring %endif Source3: baselibs.conf @@ -81,7 +81,7 @@ %build %cmake_kf5 -d build - %make_jobs + %cmake_build %install %kf5_makeinstall -C build ++++++ libkscreen-5.17.5.tar.xz -> libkscreen-5.18.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/CMakeLists.txt new/libkscreen-5.18.0/CMakeLists.txt --- old/libkscreen-5.17.5/CMakeLists.txt 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/CMakeLists.txt 2020-02-06 14:16:22.000000000 +0100 @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.0) project(libkscreen) -set(PROJECT_VERSION "5.17.5") +set(PROJECT_VERSION "5.18.0") set(QT_MIN_VERSION "5.12.0") -set(KF5_MIN_VERSION "5.62.0") +set(KF5_MIN_VERSION "5.66.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) @@ -20,6 +20,7 @@ include(CheckCXXCompilerFlag) include(CMakePackageConfigHelpers) include(GenerateExportHeader) +include(KDEClangFormat) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Core DBus Gui Test X11Extras) @@ -64,6 +65,10 @@ set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5Screen") +# add clang-format target for all our real source files +file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) +kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) + if (BUILD_QCH) ecm_install_qch_export( TARGETS KF5Screen_QCH @@ -99,11 +104,7 @@ DESTINATION "${KF5_INCLUDE_INSTALL_DIR}" COMPONENT Devel ) -if (${ECM_VERSION} STRGREATER "5.58.0") - install(FILES libkscreen.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) -else() - install(FILES libkscreen.categories DESTINATION ${KDE_INSTALL_CONFDIR}) -endif() +install(FILES libkscreen.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/CONTRIBUTING.md new/libkscreen-5.18.0/CONTRIBUTING.md --- old/libkscreen-5.17.5/CONTRIBUTING.md 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-5.18.0/CONTRIBUTING.md 2020-02-06 14:16:22.000000000 +0100 @@ -0,0 +1,73 @@ +# Contributing to libkscreen + + - [Code of Conduct](#code-of-conduct) + - [Submission Guideline](#submission-guideline) + - [Commit Message Guideline](#commit-message-guideline) + - [Contact](#contact) + +## Code of Conduct +The [KDE Community Code of Conduct][kde-coc] is applied. + +You can reach out to the [Commmunity Working Group][community-working-group] if you have questions about the Code of Conduct or if you want to get help on solving an issue with another contributor or maintainer. + +## Submission Guideline +The project follows the [Frameworks Coding Style][frameworks-style]. + +All non-trivial patches need to go through [Phabricator reviews][phab-reviews]. + +Commits are applied directly on top of master or a bug-fix branch and without merge commits. Larger changes must be split up into smaller logical commits each with a separate review. These reviews must be marked with Phabricator's online tools as dependent on each other. + +libkscreen is released as part of Plasma. See the [Plasma schedule][plasma-schedule] for information on when the next new major version is released from master branch or a minor release with changes from one of the bug-fix branches. + +## Commit Message Guideline +Besides the [KDE Commit Policy][commit-policy] the [Conventional Commits 1.0.0-beta.4][conventional-commits] specification is applied with the following amendments: + +* Only the following types are allowed: + * build: changes to the CMake build system, dependencies or other build-related tooling + * docs: documentation only changes to overall project or code + * feat: new feature + * fix: bug fix + * perf: performance improvement + * refactor: rewrite of code logic that neither fixes a bug nor adds a feature + * style: improvements to code style without logic change + * test: addition of a new test or correction of an existing one +* Only the following optional scopes are allowed: + * api + * kwayland + * qscreen + * randr +* Angular's [Revert][angular-revert] and [Subject][angular-subject] policies are applied. +* Breaking changes are supposed to be pointed out only in prose in the commit body. +* When a commit closes a bug on [Bugzilla][bugzilla] or when the commit has an associated Phabricator review special keywords must be used in the commit body to link the respective bug or review. See [here][commit-policy-keywords] for more information on these and other possible keywords. [Arcanist][arcanist] should be used for automating usage of the review keyword. + +Commits deliberately ignoring this guideline will be reverted. + +### Example + + fix(api): provide correct return value + + For function exampleFunction the return value was incorrect. + Instead provide the correct value A by changing B to C. + + BUG: <bug-number> + + Differential Revision: https://phabricator.kde.org/<review-number> + +## Contact +Real-time communication about the project happens on the IRC channel `#plasma` on freenode and the bridged Matrix room `#plasma:kde.org`. + +Emails about the project can be sent to the [plasma-devel][plasma-devel] mailing list. + +[kde-coc]: https://kde.org/code-of-conduct +[community-working-group]: https://ev.kde.org/workinggroups/cwg.php +[frameworks-style]: https://community.kde.org/Policies/Frameworks_Coding_Style +[phab-reviews]: https://phabricator.kde.org/differential +[plasma-schedule]: https://community.kde.org/Schedules/Plasma_5 +[commit-policy]: https://community.kde.org/Policies/Commit_Policy +[conventional-commits]: https://www.conventionalcommits.org/en/v1.0.0-beta.4/#specification +[angular-revert]: https://github.com/angular/angular/blob/3cf2005a936bec2058610b0786dd0671dae3d358/CONTRIBUTING.md#revert +[angular-subject]: https://github.com/angular/angular/blob/3cf2005a936bec2058610b0786dd0671dae3d358/CONTRIBUTING.md#subject +[bugzilla]: https://bugs.kde.org/describecomponents.cgi?product=KScreen +[commit-policy-keywords]: https://community.kde.org/Policies/Commit_Policy#Special_keywords_in_GIT_and_SVN_log_messages +[arcanist]: https://secure.phabricator.com/book/phabricator/article/arcanist +[plasma-devel]: https://mail.kde.org/mailman/listinfo/plasma-devel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/README.md new/libkscreen-5.18.0/README.md --- old/libkscreen-5.17.5/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-5.18.0/README.md 2020-02-06 14:16:22.000000000 +0100 @@ -0,0 +1,14 @@ +# libkscreen + +libkscreen is the screen management library for KDE Plasma Workspaces. Its primary consumer is the KDE screen management application KScreen. + +libkscreen is part of [Plasma releases][plasma-releases]. + +## End user +Since this is a development library end users should instead look for support directly for the apps using this library. Please contact the support channels of your Linux distribution first. In case you find a bug in KScreen or if the bug is traced back to libkscreen, you can report it at the KDE [bug tracker][bug-tracker] (first look for duplicates). + +## Contributing +See the `CONTRIBUTING.md` file. + +[plasma-releases]: https://community.kde.org/Schedules/Plasma_5 +[bug-tracker]: https://bugs.kde.org/describecomponents.cgi?product=KScreen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/kwayland/CMakeLists.txt new/libkscreen-5.18.0/backends/kwayland/CMakeLists.txt --- old/libkscreen-5.17.5/backends/kwayland/CMakeLists.txt 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/kwayland/CMakeLists.txt 2020-02-06 14:16:22.000000000 +0100 @@ -6,12 +6,14 @@ waylandscreen.cpp ../utils.cpp ) +qt5_add_dbus_interface(wayland_SRCS org.kde.KWin.TabletModeManager.xml tabletmodemanager_interface) add_library(KSC_KWayland MODULE ${wayland_SRCS}) set_target_properties(KSC_KWayland PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kscreen") set_target_properties(KSC_KWayland PROPERTIES PREFIX "") target_link_libraries(KSC_KWayland Qt5::Core + Qt5::DBus Qt5::Gui KF5::Screen KF5::WaylandClient diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/kwayland/org.kde.KWin.TabletModeManager.xml new/libkscreen-5.18.0/backends/kwayland/org.kde.KWin.TabletModeManager.xml --- old/libkscreen-5.17.5/backends/kwayland/org.kde.KWin.TabletModeManager.xml 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-5.18.0/backends/kwayland/org.kde.KWin.TabletModeManager.xml 2020-02-06 14:16:22.000000000 +0100 @@ -0,0 +1,13 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.kde.KWin.TabletModeManager"> + <property name="tabletModeAvailable" type="b" access="read"/> + <property name="tabletMode" type="b" access="read"/> + <signal name="tabletModeAvailableChanged"> + <arg name="tabletModeAvailable" type="b" direction="out"/> + </signal> + <signal name="tabletModeChanged"> + <arg name="tabletMode" type="b" direction="out"/> + </signal> + </interface> +</node> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/kwayland/waylandbackend.cpp new/libkscreen-5.18.0/backends/kwayland/waylandbackend.cpp --- old/libkscreen-5.17.5/backends/kwayland/waylandbackend.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/kwayland/waylandbackend.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -40,8 +40,6 @@ { qCDebug(KSCREEN_WAYLAND) << "Loading Wayland backend."; - m_internalConfig = new WaylandConfig(this); - connect(m_internalConfig, &WaylandConfig::configChanged, this, [this]() { Q_EMIT configChanged(m_internalConfig->currentConfig()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/kwayland/waylandconfig.cpp new/libkscreen-5.18.0/backends/kwayland/waylandconfig.cpp --- old/libkscreen-5.17.5/backends/kwayland/waylandconfig.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/kwayland/waylandconfig.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -22,6 +22,8 @@ #include "waylandoutput.h" #include "waylandscreen.h" +#include "tabletmodemanager_interface.h" + #include <configmonitor.h> #include <mode.h> @@ -43,9 +45,12 @@ , m_kscreenConfig(new Config) , m_kscreenPendingConfig(nullptr) , m_screen(new WaylandScreen(this)) + , m_tabletModeAvailable(false) + , m_tabletModeEngaged(false) { - connect(this, &WaylandConfig::initialized, &m_syncLoop, &QEventLoop::quit); + initKWinTabletMode(); + connect(this, &WaylandConfig::initialized, &m_syncLoop, &QEventLoop::quit); QTimer::singleShot(1000, this, [this] { if (m_syncLoop.isRunning()) { qCWarning(KSCREEN_WAYLAND) << "Connection to Wayland server at socket:" @@ -67,6 +72,43 @@ m_syncLoop.quit(); } +void WaylandConfig::initKWinTabletMode() +{ + auto *interface = new OrgKdeKWinTabletModeManagerInterface(QStringLiteral("org.kde.KWin"), + QStringLiteral("/org/kde/KWin"), + QDBusConnection::sessionBus(), this); + if (!interface->isValid()) { + m_tabletModeAvailable = false; + m_tabletModeEngaged = false; + return; + } + + m_tabletModeAvailable = interface->tabletModeAvailable(); + m_tabletModeEngaged = interface->tabletMode(); + + connect(interface, &OrgKdeKWinTabletModeManagerInterface::tabletModeChanged, + this, [this](bool tabletMode) { + if (m_tabletModeEngaged == tabletMode) { + return; + } + m_tabletModeEngaged = tabletMode; + if (!m_blockSignals && m_initializingOutputs.empty()) { + Q_EMIT configChanged(); + } + } + ); + connect(interface, &OrgKdeKWinTabletModeManagerInterface::tabletModeAvailableChanged, + this, [this](bool available) { + if (m_tabletModeAvailable == available) { + return; + } + m_tabletModeAvailable = available; + if (!m_blockSignals && m_initializingOutputs.empty()) { + Q_EMIT configChanged(); + } + }); +} + void WaylandConfig::initConnection() { m_thread = new QThread(this); @@ -227,6 +269,9 @@ m_kscreenConfig->setScreen(m_screen->toKScreenScreen(m_kscreenConfig)); auto features = Config::Feature::Writable | Config::Feature::PerOutputScaling; + // TODO: enable new features when all patches have landed +// const auto features = Config::Feature::Writable | Config::Feature::PerOutputScaling +// | Config::Feature::AutoRotation | Config::Feature::TabletMode; m_kscreenConfig->setSupportedFeatures(features); m_kscreenConfig->setValid(m_connection->display()); @@ -258,6 +303,9 @@ } m_kscreenConfig->setOutputs(kscreenOutputs); + m_kscreenConfig->setTabletModeAvailable(m_tabletModeAvailable); + m_kscreenConfig->setTabletModeEngaged(m_tabletModeEngaged); + return m_kscreenConfig; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/kwayland/waylandconfig.h new/libkscreen-5.18.0/backends/kwayland/waylandconfig.h --- old/libkscreen-5.17.5/backends/kwayland/waylandconfig.h 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/kwayland/waylandconfig.h 2020-02-06 14:16:22.000000000 +0100 @@ -80,6 +80,7 @@ void checkInitialized(); void disconnected(); + void initKWinTabletMode(); void initConnection(); void addOutput(quint32 name, quint32 version); @@ -109,6 +110,9 @@ KScreen::ConfigPtr m_kscreenConfig; KScreen::ConfigPtr m_kscreenPendingConfig; WaylandScreen *m_screen; + + bool m_tabletModeAvailable; + bool m_tabletModeEngaged; }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/xrandr/xrandrconfig.cpp new/libkscreen-5.18.0/backends/xrandr/xrandrconfig.cpp --- old/libkscreen-5.17.5/backends/xrandr/xrandrconfig.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/xrandr/xrandrconfig.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -155,7 +155,7 @@ } } - KScreen::OutputList toDisable, toEnable, toChange, toReplicate; + KScreen::OutputList toDisable, toEnable, toChange; for (const KScreen::OutputPtr &kscreenOutput : kscreenOutputs) { xcb_randr_output_t outputId = kscreenOutput->id(); @@ -180,16 +180,6 @@ ++neededCrtcs; - // Update replication when it is supposed to be a replica or changes not to be anymore. - if (kscreenOutput->replicationSource() || currentOutput->replicationSource()) { - if (int sourceId = kscreenOutput->replicationSource()) { - kscreenOutput->setPos(config->output(sourceId)->pos()); - } - if (!toReplicate.contains(outputId)) { - toReplicate.insert(outputId, kscreenOutput); - } - } - if (kscreenOutput->currentModeId() != currentOutput->currentModeId()) { if (!toChange.contains(outputId)) { toChange.insert(outputId, kscreenOutput); @@ -208,6 +198,12 @@ } } + if (kscreenOutput->explicitLogicalSize() != currentOutput->logicalSize()) { + if (!toChange.contains(outputId)) { + toChange.insert(outputId, kscreenOutput); + } + } + XRandRMode *currentMode = currentOutput->modes().value( kscreenOutput->currentModeId().toInt()); // For some reason, in some environments currentMode is null @@ -291,7 +287,7 @@ //If there is nothing to do, not even bother if (oldPrimaryOutput == primaryOutput && toDisable.isEmpty() && - toEnable.isEmpty() && toChange.isEmpty() && toReplicate.isEmpty()) { + toEnable.isEmpty() && toChange.isEmpty()) { if (newScreenSize != currentScreenSize) { setScreenSize(newScreenSize); } @@ -327,12 +323,6 @@ } } - for (KScreen::OutputPtr &output : toReplicate) { - if (replicateOutput(output)) { - forceScreenSizeUpdate = true; - } - } - if (oldPrimaryOutput != primaryOutput) { setPrimaryOutput(primaryOutput); } @@ -566,8 +556,10 @@ return false; } + XRandROutput *xOutput = output(kscreenOutput->id()); const int modeId = kscreenOutput->currentMode() ? kscreenOutput->currentModeId().toInt() : kscreenOutput->preferredModeId().toInt(); + xOutput->updateLogicalSize(kscreenOutput, freeCrtc); qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (enable output)" << "\n" << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() @@ -582,8 +574,8 @@ return false; } - output(kscreenOutput->id())->update(freeCrtc->crtc(), modeId, XCB_RANDR_CONNECTION_CONNECTED, - kscreenOutput->isPrimary()); + xOutput->update(freeCrtc->crtc(), modeId, XCB_RANDR_CONNECTION_CONNECTED, + kscreenOutput->isPrimary()); return true; } @@ -600,6 +592,7 @@ int modeId = kscreenOutput->currentMode() ? kscreenOutput->currentModeId().toInt() : kscreenOutput->preferredModeId().toInt(); + xOutput->updateLogicalSize(kscreenOutput); qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (change output)" << "\n" << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() @@ -612,40 +605,6 @@ if (!sendConfig(kscreenOutput, xOutput->crtc())) { return false; } - - xOutput->update(xOutput->crtc()->crtc(), modeId, - XCB_RANDR_CONNECTION_CONNECTED, kscreenOutput->isPrimary()); - return true; -} - -bool XRandRConfig::replicateOutput(const KScreen::OutputPtr &kscreenOutput) const -{ - XRandROutput *xOutput = output(kscreenOutput->id()); - Q_ASSERT(xOutput); - - if (!xOutput->crtc()) { - qCDebug(KSCREEN_XRANDR) << "Output" << kscreenOutput->id() - << "has no CRTC, falling back to enableOutput()"; - enableOutput(kscreenOutput); - } - - int modeId = kscreenOutput->currentMode() ? kscreenOutput->currentModeId().toInt() : - kscreenOutput->preferredModeId().toInt(); - - qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (change output)" << "\n" - << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() - << ")" << "\n" - << "\tCRTC:" << xOutput->crtc()->crtc() << "\n" - << "\tPos:" << kscreenOutput->pos() << "\n" - << "\tMode:" << modeId << kscreenOutput->currentMode() << "\n" - << "\tRotation:" << kscreenOutput->rotation(); - - if (!xOutput->setReplicationSource(kscreenOutput->replicationSource())) { - return false; - } - if (!sendConfig(kscreenOutput, xOutput->crtc())) { - return false; - } xOutput->update(xOutput->crtc()->crtc(), modeId, XCB_RANDR_CONNECTION_CONNECTED, kscreenOutput->isPrimary()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/xrandr/xrandrconfig.h new/libkscreen-5.18.0/backends/xrandr/xrandrconfig.h --- old/libkscreen-5.17.5/backends/xrandr/xrandrconfig.h 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/xrandr/xrandrconfig.h 2020-02-06 14:16:22.000000000 +0100 @@ -60,7 +60,6 @@ bool disableOutput(const KScreen::OutputPtr &output) const; bool enableOutput(const KScreen::OutputPtr &output) const; bool changeOutput(const KScreen::OutputPtr &output) const; - bool replicateOutput(const KScreen::OutputPtr &output) const; bool sendConfig(const KScreen::OutputPtr &kscreenOutput, XRandRCrtc *crtc) const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/xrandr/xrandroutput.cpp new/libkscreen-5.18.0/backends/xrandr/xrandroutput.cpp --- old/libkscreen-5.17.5/backends/xrandr/xrandroutput.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/xrandr/xrandroutput.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -40,7 +40,6 @@ , m_id(id) , m_primary(false) , m_type(KScreen::Output::Unknown) - , m_replicationSource(XCB_NONE) , m_crtc(nullptr) { init(); @@ -129,11 +128,6 @@ return m_crtc; } -xcb_randr_output_t XRandROutput::replicationSource() const -{ - return m_replicationSource; -} - void XRandROutput::update() { init(); @@ -327,20 +321,27 @@ tr.matrix31 == fZero && tr.matrix32 == fZero && tr.matrix33 == fOne; } -xcb_render_transform_t zeroMatrix() +xcb_render_transform_t zeroTransform() { return { DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0) }; } +xcb_render_transform_t unityTransform() +{ + return { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), + DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), + DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; +} + xcb_render_transform_t XRandROutput::currentTransform() const { auto cookie = xcb_randr_get_crtc_transform(XCB::connection(), m_crtc->crtc()); xcb_generic_error_t *error = nullptr; auto *reply = xcb_randr_get_crtc_transform_reply(XCB::connection(), cookie, &error); if (error) { - return zeroMatrix(); + return zeroTransform(); } const xcb_render_transform_t transform = reply->pending_transform; @@ -348,128 +349,56 @@ return transform; } -QSizeF XRandROutput::scaledSize(xcb_render_transform_t transform) const +QSizeF XRandROutput::logicalSize() const { - const QSize ownSize = size(); - if (!ownSize.isValid()) { + const QSize modeSize = size(); + if (!modeSize.isValid()) { return QSize(); } - const qreal width = FIXED_TO_DOUBLE(transform.matrix11) * ownSize.width(); - const qreal height = FIXED_TO_DOUBLE(transform.matrix22) * ownSize.height(); + const xcb_render_transform_t transform = currentTransform(); + const qreal width = FIXED_TO_DOUBLE(transform.matrix11) * modeSize.width(); + const qreal height = FIXED_TO_DOUBLE(transform.matrix22) * modeSize.height(); return QSizeF(width, height); } -bool XRandROutput::isReplicaOf(XRandROutput *output, xcb_render_transform_t ownTransform) const +void XRandROutput::updateLogicalSize(const KScreen::OutputPtr &output, XRandRCrtc *crtc) { - if (output->id() == m_id) { - return false; + if (!crtc) { + // TODO: This is a workaround for now when updateLogicalSize is called on enabling the + // output. At this point m_crtc is not yet set. Change the order in the future so + // that the additional argument is not necessary anymore. + crtc = m_crtc; } - if (output->position() != position()) { - return false; - } - if (output->replicationSource() != XCB_NONE) { - return false; - } - - const QSizeF sSize = scaledSize(ownTransform); - if (!sSize.isValid()) { - return false; - } - - const auto outputTransform = output->currentTransform(); - if (!isScaling(outputTransform)) { - return false; - } - - if (sSize != output->scaledSize(outputTransform)) { - return false; - } - - return true; -} - -xcb_render_transform_t unityTransform() -{ - return { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), - DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), - DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; -} - -xcb_render_transform_t XRandROutput::getReplicationTransform(XRandROutput *source) -{ - if (!source) { - return unityTransform(); - } - - const auto *sourceMode = source->currentMode(); - const auto *ownMode = currentMode(); - if (!sourceMode || !ownMode) { - return unityTransform(); - } - - QSize sourceSize = sourceMode->size(); - QSize size = ownMode->size(); - - if (isHorizontal()) { - if (!source->isHorizontal()) { - sourceSize.transpose(); - } - } else if (source->isHorizontal()) { - size.transpose(); - } - - const qreal widthFactor = sourceSize.width() / (qreal)size.width(); - const qreal heightFactor = sourceSize.height() / (qreal)size.height(); - + const QSizeF logicalSize = output->explicitLogicalSize(); xcb_render_transform_t transform = unityTransform(); - transform.matrix11 = DOUBLE_TO_FIXED(widthFactor); - transform.matrix22 = DOUBLE_TO_FIXED(heightFactor); - return transform; -} + KScreen::ModePtr mode = output->currentMode() ? output->currentMode() : output->preferredMode(); + if(mode && logicalSize.isValid()) { + QSize modeSize = mode->size(); + if (!output->isHorizontal()) { + modeSize.transpose(); + } -bool XRandROutput::updateReplication() -{ - XRandROutput *source = m_config->output(m_replicationSource); - if (source && (!source->isEnabled() || !source->isConnected())) { - return false; + const qreal widthFactor = logicalSize.width() / (qreal)modeSize.width(); + const qreal heightFactor = logicalSize.height() / (qreal)modeSize.height(); + transform.matrix11 = DOUBLE_TO_FIXED(widthFactor); + transform.matrix22 = DOUBLE_TO_FIXED(heightFactor); } - xcb_render_transform_t transform = getReplicationTransform(source); QByteArray filterName(isScaling(transform) ? "bilinear" : "nearest"); auto cookie = xcb_randr_set_crtc_transform_checked(XCB::connection(), - m_crtc->crtc(), + crtc->crtc(), transform, filterName.size(), filterName.data(), 0, nullptr); xcb_generic_error_t *error = xcb_request_check(XCB::connection(), cookie); if (error) { - qCDebug(KSCREEN_XRANDR) << "Error on replication transformation!"; + qCDebug(KSCREEN_XRANDR) << "Error on logical size transformation!"; free(error); - return false; - } - free(error); - return true; -} - -bool XRandROutput::setReplicationSource(xcb_randr_output_t source) -{ - if (!m_crtc) { - return false; - } - if (m_replicationSource == source) { - return true; - } - xcb_randr_output_t oldSource = m_replicationSource; - m_replicationSource = source; - if (!updateReplication()) { - m_replicationSource = oldSource; - return false; } - return true; } KScreen::OutputPtr XRandROutput::toKScreenOutput() const @@ -513,7 +442,7 @@ kscreenOutput->setRotation(rotation()); kscreenOutput->setCurrentModeId(currentModeId()); } - kscreenOutput->setReplicationSource(m_replicationSource); + // TODO: set logical size? } kscreenOutput->blockSignals(signalsBlocked); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/backends/xrandr/xrandroutput.h new/libkscreen-5.18.0/backends/xrandr/xrandroutput.h --- old/libkscreen-5.17.5/backends/xrandr/xrandroutput.h 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/backends/xrandr/xrandroutput.h 2020-02-06 14:16:22.000000000 +0100 @@ -61,7 +61,7 @@ QPoint position() const; QSize size() const; - QSizeF scaledSize(xcb_render_transform_t transform) const; + QSizeF logicalSize() const; QString currentModeId() const; XRandRMode::Map modes() const; @@ -75,12 +75,7 @@ KScreen::OutputPtr toKScreenOutput() const; - bool updateReplication(); - bool setReplicationSource(xcb_randr_output_t source); - - xcb_randr_output_t replicationSource() const; - - xcb_render_transform_t currentTransform() const; + void updateLogicalSize(const KScreen::OutputPtr &output, XRandRCrtc *crtc = nullptr); private: void init(); @@ -89,15 +84,7 @@ static KScreen::Output::Type fetchOutputType(xcb_randr_output_t outputId, const QString &name); static QByteArray typeFromProperty(xcb_randr_output_t outputId); - xcb_render_transform_t getReplicationTransform(XRandROutput *source); - - /** - * This makes an educated guess based on position, size and scale if @param output is a - * replication source for this output. - * - * @return true if this output can be seen as a replica of @param output - */ - bool isReplicaOf(XRandROutput *output, xcb_render_transform_t ownTransform) const; + xcb_render_transform_t currentTransform() const; XRandRConfig *m_config; xcb_randr_output_t m_id; @@ -113,7 +100,6 @@ QStringList m_preferredModes; QList<xcb_randr_output_t> m_clones; - xcb_randr_output_t m_replicationSource; unsigned int m_widthMm; unsigned int m_heightMm; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/src/config.cpp new/libkscreen-5.18.0/src/config.cpp --- old/libkscreen-5.17.5/src/config.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/src/config.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -38,6 +38,8 @@ : QObject(parent) , valid(true) , supportedFeatures(Config::Feature::None) + , tabletModeAvailable(false) + , tabletModeEngaged(false) , q(parent) { } @@ -90,6 +92,8 @@ OutputPtr primaryOutput; OutputList outputs; Features supportedFeatures; + bool tabletModeAvailable; + bool tabletModeEngaged; private: Config *q; @@ -260,6 +264,26 @@ d->supportedFeatures = features; } +bool Config::tabletModeAvailable() const +{ + return d->tabletModeAvailable; +} + +void Config::setTabletModeAvailable(bool available) +{ + d->tabletModeAvailable = available; +} + +bool Config::tabletModeEngaged() const +{ + return d->tabletModeEngaged; +} + +void Config::setTabletModeEngaged(bool engaged) +{ + d->tabletModeEngaged = engaged; +} + OutputList Config::outputs() const { return d->outputs; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/src/config.h new/libkscreen-5.18.0/src/config.h --- old/libkscreen-5.17.5/src/config.h 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/src/config.h 2020-02-06 14:16:22.000000000 +0100 @@ -67,6 +67,8 @@ Writable = 1 << 1, ///< The backend supports setting the config, it's not read-only. PerOutputScaling = 1 << 2, ///< The backend supports scaling each output individually. OutputReplication = 1 << 3, ///< The backend supports replication of outputs. + AutoRotation = 1 << 4, ///< The backend supports automatic rotation of outputs. + TabletMode = 1 << 5, ///< The backend supports querying if a device is in tablet mode. }; Q_DECLARE_FLAGS(Features, Feature) @@ -165,6 +167,42 @@ */ void setSupportedFeatures(const Features &features); + /** + * Indicates that the device supports switching between a default and a tablet mode. This is + * common for convertibles. + * + * @return true when tablet mode is available, otherwise false + * @see setTabletModeAvailable + * @since 5.18 + */ + bool tabletModeAvailable() const; + + /** Sets if the device supports a tablet mode. This should not be called by the + * user, but by the backend. + * + * @see tabletModeAvailable + * @since 5.18 + */ + void setTabletModeAvailable(bool available); + + /** + * Indicates that the device is currently in tablet mode. + * + * @return true when in tablet mode, otherwise false + * @see setTabletModeEngaged + * @since 5.18 + */ + bool tabletModeEngaged() const; + + /** + * Sets if the device is currently in tablet mode. This should not be called by the + * user, but by the backend. + * + * @see tabletModeEngaged + * @since 5.18 + */ + void setTabletModeEngaged(bool engaged); + Q_SIGNALS: void outputAdded(const KScreen::OutputPtr &output); void outputRemoved(int outputId); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/src/configmonitor.cpp new/libkscreen-5.18.0/src/configmonitor.cpp --- old/libkscreen-5.17.5/src/configmonitor.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/src/configmonitor.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -185,7 +185,7 @@ void ConfigMonitor::Private::configDestroyed(QObject *removedConfig) { for (auto iter = watchedConfigs.begin(); iter != watchedConfigs.end(); ++iter) { - if (iter->data() == removedConfig) { + if (iter->toStrongRef() == removedConfig) { iter = watchedConfigs.erase(iter); // Iterate over the entire list in case there are duplicates } @@ -223,7 +223,7 @@ { const QWeakPointer<Config> weakConfig = config.toWeakRef(); if (!d->watchedConfigs.contains(weakConfig)) { - connect(weakConfig.data(), &QObject::destroyed, + connect(weakConfig.toStrongRef().data(), &QObject::destroyed, d, &Private::configDestroyed); d->watchedConfigs << weakConfig; } @@ -233,7 +233,7 @@ { const QWeakPointer<Config> weakConfig = config.toWeakRef(); if (d->watchedConfigs.contains(config)) { - disconnect(weakConfig.data(), &QObject::destroyed, + disconnect(weakConfig.toStrongRef().data(), &QObject::destroyed, d, &Private::configDestroyed); d->watchedConfigs.removeAll(config); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/src/output.cpp new/libkscreen-5.18.0/src/output.cpp --- old/libkscreen-5.17.5/src/output.cpp 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/src/output.cpp 2020-02-06 14:16:22.000000000 +0100 @@ -40,6 +40,7 @@ replicationSource(0), rotation(None), scale(1.0), + logicalSize(QSizeF()), connected(false), enabled(false), primary(false), @@ -92,6 +93,7 @@ QSize size; Rotation rotation; qreal scale; + QSizeF logicalSize; bool connected; bool enabled; bool primary; @@ -214,6 +216,7 @@ Q_EMIT outputChanged(); } +// TODO KF6: remove this deprecated method QString Output::hash() const { if (edid() && edid()->isValid()) { @@ -393,6 +396,7 @@ Q_EMIT sizeChanged(); } +// TODO KF6: make the Rotation enum an enum class and align values with Wayland transformation property Output::Rotation Output::rotation() const { return d->rotation; @@ -423,6 +427,43 @@ emit scaleChanged(); } +QSizeF Output::logicalSize() const +{ + if (d->logicalSize.isValid()) { + return d->logicalSize; + } + + QSizeF size = enforcedModeSize(); + if (!size.isValid()) { + return QSizeF(); + } + size = size / d->scale; + + // We can't use d->size, because d->size does not reflect the actual rotation() set by caller. + // It is only updated when we get update from KScreen, but not when user changes mode or + // rotation manually. + + if (!isHorizontal()) { + size = size.transposed(); + } + return size; +} + +QSizeF Output::explicitLogicalSize() const +{ + return d->logicalSize; +} + +void Output::setLogicalSize(const QSizeF &size) +{ + if (qFuzzyCompare(d->logicalSize.width(), size.width()) + && qFuzzyCompare(d->logicalSize.height(), size.height())) { + return; + } + d->logicalSize = size; + Q_EMIT logicalSizeChanged(); +} + bool Output::isConnected() const { return d->connected; @@ -556,19 +597,10 @@ QRect Output::geometry() const { - QSize size = enforcedModeSize(); + QSize size = logicalSize().toSize(); if (!size.isValid()) { return QRect(); } - size = size / d->scale; - - // We can't use QRect(d->pos, d->size), because d->size does not reflect the - // actual rotation() set by caller, it's only updated when we get update from - // KScreen, but not when user changes mode or rotation manually - - if (!isHorizontal()) { - size = size.transposed(); - } return QRect(d->pos, size); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-5.17.5/src/output.h new/libkscreen-5.18.0/src/output.h --- old/libkscreen-5.17.5/src/output.h 2020-01-07 16:34:44.000000000 +0100 +++ new/libkscreen-5.18.0/src/output.h 2020-02-06 14:16:22.000000000 +0100 @@ -62,6 +62,8 @@ Q_PROPERTY(QSize sizeMm READ sizeMm CONSTANT) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) Q_PROPERTY(bool followPreferredMode READ followPreferredMode WRITE setFollowPreferredMode NOTIFY followPreferredModeChanged) + Q_PROPERTY(QSizeF logicalSize READ logicalSize WRITE setLogicalSize + NOTIFY logicalSizeChanged) enum Type { @@ -296,6 +298,37 @@ void setScale(qreal factor); /** + * The logical size is the output's representation internal to the display server and its + * overall screen geometry. + * + * returns the logical size of this output + * + * @since 5.18 + */ + QSizeF logicalSize() const; + + /** + * The logical size is the output's representation internal to the display server and its + * overall screen geometry. + * + * returns the explicitly set logical size of this output, is an invalid size if not set + * + * @since 5.18 + */ + QSizeF explicitLogicalSize() const; + + /** + * Specifies explicitly the logical size of this output and by that overrides any other + * logical size calculation through mode and scale. To enable this instead again call this + * function with an invalid size as argument. + * + * @param size of this output in logical space + * + * @since 5.18 + */ + void setLogicalSize(const QSizeF &size); + + /** * @returns whether the mode should be changed to the new preferred mode * once it changes * @@ -323,6 +356,7 @@ void clonesChanged(); void replicationSourceChanged(); void scaleChanged(); + void logicalSizeChanged(); void followPreferredModeChanged(bool followPreferredMode); /** The mode list changed.
