Index: abstract_opengl_context_attribute_builder.h =================================================================== --- abstract_opengl_context_attribute_builder.h +++ abstract_opengl_context_attribute_builder.h @@ -94,6 +94,14 @@ return m_resetOnVideoMemoryPurge; } + void setHighPriority(bool highPriority) { + m_highPriority = highPriority; + } + + bool isHighPriority() const { + return m_highPriority; + } + virtual std::vector build() const = 0; QDebug operator<<(QDebug dbg) const; @@ -107,6 +115,7 @@ bool m_coreProfile = false; bool m_compatibilityProfile = false; bool m_resetOnVideoMemoryPurge = false; + bool m_highPriority = false; }; inline QDebug operator<<(QDebug dbg, const AbstractOpenGLContextAttributeBuilder *attribs) Index: abstract_opengl_context_attribute_builder.cpp =================================================================== --- abstract_opengl_context_attribute_builder.cpp +++ abstract_opengl_context_attribute_builder.cpp @@ -32,7 +32,8 @@ dbg.nospace() << "Robust:\t" << isRobust() << "\n"; dbg.nospace() << "Forward compatible:\t" << isForwardCompatible() << "\n"; dbg.nospace() << "Core profile:\t" << isCoreProfile() << "\n"; - dbg.nospace() << "Compatibility profile:\t" << isCompatibilityProfile(); + dbg.nospace() << "Compatibility profile:\t" << isCompatibilityProfile() << "\n"; + dbg.nospace() << "High priority:\t" << isHighPriority(); return dbg; } Index: autotests/integration/virtual_desktop_test.cpp =================================================================== --- autotests/integration/virtual_desktop_test.cpp +++ autotests/integration/virtual_desktop_test.cpp @@ -40,6 +40,7 @@ void init(); void cleanup(); + void testNetCurrentDesktop(); void testLastDesktopRemoved_data(); void testLastDesktopRemoved(); }; @@ -60,6 +61,16 @@ kwinApp()->start(); QVERIFY(workspaceCreatedSpy.wait()); waylandServer()->initWorkspace(); + + if (kwinApp()->x11Connection()) { + // verify the current desktop x11 property on startup, see BUG: 391034 + Xcb::Atom currentDesktopAtom("_NET_CURRENT_DESKTOP"); + QVERIFY(currentDesktopAtom.isValid()); + Xcb::Property currentDesktop(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1); + bool ok = true; + QCOMPARE(currentDesktop.value(0, &ok), 0); + QVERIFY(ok); + } } void VirtualDesktopTest::init() @@ -74,6 +85,47 @@ Test::destroyWaylandConnection(); } +void VirtualDesktopTest::testNetCurrentDesktop() +{ + if (!kwinApp()->x11Connection()) { + QSKIP("Skipped on Wayland only"); + } + QCOMPARE(VirtualDesktopManager::self()->count(), 1u); + VirtualDesktopManager::self()->setCount(4); + QCOMPARE(VirtualDesktopManager::self()->count(), 4u); + + Xcb::Atom currentDesktopAtom("_NET_CURRENT_DESKTOP"); + QVERIFY(currentDesktopAtom.isValid()); + Xcb::Property currentDesktop(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1); + bool ok = true; + QCOMPARE(currentDesktop.value(0, &ok), 0); + QVERIFY(ok); + + // go to desktop 2 + VirtualDesktopManager::self()->setCurrent(2); + currentDesktop = Xcb::Property(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1); + QCOMPARE(currentDesktop.value(0, &ok), 1); + QVERIFY(ok); + + // go to desktop 3 + VirtualDesktopManager::self()->setCurrent(3); + currentDesktop = Xcb::Property(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1); + QCOMPARE(currentDesktop.value(0, &ok), 2); + QVERIFY(ok); + + // go to desktop 4 + VirtualDesktopManager::self()->setCurrent(4); + currentDesktop = Xcb::Property(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1); + QCOMPARE(currentDesktop.value(0, &ok), 3); + QVERIFY(ok); + + // and back to first + VirtualDesktopManager::self()->setCurrent(1); + currentDesktop = Xcb::Property(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1); + QCOMPARE(currentDesktop.value(0, &ok), 0); + QVERIFY(ok); +} + void VirtualDesktopTest::testLastDesktopRemoved_data() { QTest::addColumn("type"); Index: autotests/opengl_context_attribute_builder_test.cpp =================================================================== --- autotests/opengl_context_attribute_builder_test.cpp +++ autotests/opengl_context_attribute_builder_test.cpp @@ -45,6 +45,7 @@ void testResetOnVideoMemoryPurge(); void testVersionMajor(); void testVersionMajorAndMinor(); + void testHighPriority(); void testEgl_data(); void testEgl(); void testGles_data(); @@ -75,6 +76,7 @@ QCOMPARE(builder.isCoreProfile(), false); QCOMPARE(builder.isCompatibilityProfile(), false); QCOMPARE(builder.isResetOnVideoMemoryPurge(), false); + QCOMPARE(builder.isHighPriority(), false); } void OpenGLContextAttributeBuilderTest::testRobust() @@ -123,6 +125,16 @@ QCOMPARE(builder.isResetOnVideoMemoryPurge(), false); } +void OpenGLContextAttributeBuilderTest::testHighPriority() +{ + MockOpenGLContextAttributeBuilder builder; + QCOMPARE(builder.isHighPriority(), false); + builder.setHighPriority(true); + QCOMPARE(builder.isHighPriority(), true); + builder.setHighPriority(false); + QCOMPARE(builder.isHighPriority(), false); +} + void OpenGLContextAttributeBuilderTest::testVersionMajor() { MockOpenGLContextAttributeBuilder builder; @@ -158,69 +170,139 @@ QTest::addColumn("forwardCompatible"); QTest::addColumn("coreProfile"); QTest::addColumn("compatibilityProfile"); + QTest::addColumn("highPriority"); QTest::addColumn>("expectedAttribs"); - QTest::newRow("fallback") << false << 0 << 0 << false << false << false << false << std::vector{EGL_NONE}; - QTest::newRow("legacy/robust") << false << 0 << 0 << true << false << false << false << + QTest::newRow("fallback") << false << 0 << 0 << false << false << false << false << false << std::vector{EGL_NONE}; + QTest::newRow("legacy/robust") << false << 0 << 0 << true << false << false << false << false << + std::vector{ + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, + EGL_NONE}; + QTest::newRow("legacy/robust/high priority") << false << 0 << 0 << true << false << false << false << true << std::vector{ EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, EGL_NONE}; - QTest::newRow("core") << true << 3 << 1 << false << false << false << false << + QTest::newRow("core") << true << 3 << 1 << false << false << false << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE}; - QTest::newRow("core/robust") << true << 3 << 1 << true << false << false << false << + QTest::newRow("core/high priority") << true << 3 << 1 << false << false << false << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core/robust") << true << 3 << 1 << true << false << false << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE}; - QTest::newRow("core/robust/forward compatible") << true << 3 << 1 << true << true << false << false << + QTest::newRow("core/robust/high priority") << true << 3 << 1 << true << false << false << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core/robust/forward compatible") << true << 3 << 1 << true << true << false << false << false << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_NONE}; + QTest::newRow("core/robust/forward compatible/high priority") << true << 3 << 1 << true << true << false << false << true << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, EGL_NONE}; - QTest::newRow("core/forward compatible") << true << 3 << 1 << false << true << false << false << + QTest::newRow("core/forward compatible") << true << 3 << 1 << false << true << false << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_NONE}; - QTest::newRow("core profile/forward compatible") << true << 3 << 2 << false << true << true << false << + QTest::newRow("core/forward compatible/high priority") << true << 3 << 1 << false << true << false << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core profile/forward compatible") << true << 3 << 2 << false << true << true << false << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, EGL_NONE}; - QTest::newRow("compatibility profile/forward compatible") << true << 3 << 2 << false << true << false << true << + QTest::newRow("core profile/forward compatible/high priority") << true << 3 << 2 << false << true << true << false << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("compatibility profile/forward compatible") << true << 3 << 2 << false << true << false << true << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, EGL_NONE}; - QTest::newRow("core profile/robust/forward compatible") << true << 3 << 2 << true << true << true << false << + QTest::newRow("compatibility profile/forward compatible/high priority") << true << 3 << 2 << false << true << false << true << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("core profile/robust/forward compatible") << true << 3 << 2 << true << true << true << false << false << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_NONE}; + QTest::newRow("core profile/robust/forward compatible/high priority") << true << 3 << 2 << true << true << true << false << true << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, EGL_NONE}; - QTest::newRow("compatibility profile/robust/forward compatible") << true << 3 << 2 << true << true << false << true << + QTest::newRow("compatibility profile/robust/forward compatible") << true << 3 << 2 << true << true << false << true << false << std::vector{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, EGL_NONE}; + QTest::newRow("compatibility profile/robust/forward compatible/high priority") << true << 3 << 2 << true << true << false << true << true << + std::vector{ + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 2, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; } void OpenGLContextAttributeBuilderTest::testEgl() @@ -232,6 +314,7 @@ QFETCH(bool, forwardCompatible); QFETCH(bool, coreProfile); QFETCH(bool, compatibilityProfile); + QFETCH(bool, highPriority); EglContextAttributeBuilder builder; if (requestVersion) { @@ -241,33 +324,47 @@ builder.setForwardCompatible(forwardCompatible); builder.setCoreProfile(coreProfile); builder.setCompatibilityProfile(compatibilityProfile); + builder.setHighPriority(highPriority); auto attribs = builder.build(); QTEST(attribs, "expectedAttribs"); } void OpenGLContextAttributeBuilderTest::testGles_data() { QTest::addColumn("robust"); + QTest::addColumn("highPriority"); QTest::addColumn>("expectedAttribs"); - QTest::newRow("robust") << true << std::vector{ + QTest::newRow("robust") << true << false << std::vector{ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT, EGL_NONE}; - QTest::newRow("normal") << false << std::vector{ + QTest::newRow("robust/high priority") << true << true << std::vector{ + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, + EGL_NONE}; + QTest::newRow("normal") << false << false << std::vector{ + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE}; + QTest::newRow("normal/high priority") << false << true << std::vector{ EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, EGL_NONE}; } void OpenGLContextAttributeBuilderTest::testGles() { QFETCH(bool, robust); + QFETCH(bool, highPriority); EglOpenGLESContextAttributeBuilder builder; builder.setVersion(2); builder.setRobust(robust); + builder.setHighPriority(highPriority); auto attribs = builder.build(); QTEST(attribs, "expectedAttribs"); Index: effects/blur/blur_config.desktop =================================================================== --- effects/blur/blur_config.desktop +++ effects/blur/blur_config.desktop @@ -39,7 +39,7 @@ Name[hsb]=Młowojty Name[hu]=Elmosódás Name[ia]=Obscura (Blur) -Name[id]=Samar +Name[id]=Buram Name[is]=Móða Name[it]=Sfocatura Name[ja]=ぼかし Index: egl_context_attribute_builder.cpp =================================================================== --- egl_context_attribute_builder.cpp +++ egl_context_attribute_builder.cpp @@ -52,6 +52,10 @@ attribs.emplace_back(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); } } + if (isHighPriority()) { + attribs.emplace_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + attribs.emplace_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); + } attribs.emplace_back(EGL_NONE); return attribs; } @@ -67,6 +71,10 @@ attribs.emplace_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); attribs.emplace_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); } + if (isHighPriority()) { + attribs.emplace_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + attribs.emplace_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); + } attribs.emplace_back(EGL_NONE); return attribs; } Index: keyboard_layout.cpp =================================================================== --- keyboard_layout.cpp +++ keyboard_layout.cpp @@ -272,7 +272,7 @@ p->setProgram(QStringLiteral("kcmshell5")); connect(p, static_cast(&QProcess::finished), p, &QProcess::deleteLater); connect(p, static_cast(&QProcess::error), this, - [p] (QProcess::ProcessError e) { + [] (QProcess::ProcessError e) { if (e == QProcess::FailedToStart) { qCDebug(KWIN_CORE) << "Failed to start kcmshell5"; } Index: libinput/connection.cpp =================================================================== --- libinput/connection.cpp +++ libinput/connection.cpp @@ -28,8 +28,6 @@ #include "../udev.h" #include "libinput_logging.h" -#include - #include #include #include @@ -603,23 +601,6 @@ // pass configuration to Device device->setConfig(m_config->group("Libinput").group(QString::number(device->vendor())).group(QString::number(device->product())).group(device->name())); device->loadConfiguration(); - - if (device->isPointer() && !device->isTouchpad()) { - const KConfigGroup group = m_config->group("Mouse"); - device->setLeftHanded(group.readEntry("MouseButtonMapping", "RightHanded") == QLatin1String("LeftHanded")); - qreal accel = group.readEntry("Acceleration", -1.0); - if (qFuzzyCompare(accel, -1.0) || qFuzzyCompare(accel, 1.0)) { - // default value - device->setPointerAcceleration(0.0); - } else { - // the X11-based config is mapped in [0.1,20.0] with 1.0 being the "normal" setting - we assume that's the default - if (accel < 1.0) { - device->setPointerAcceleration(-1.0 + ((accel * 10.0) - 1.0) / 9.0); - } else { - device->setPointerAcceleration((accel -1.0)/19.0); - } - } - } } void Connection::slotKGlobalSettingsNotifyChange(int type, int arg) Index: output.h =================================================================== --- output.h +++ output.h @@ -89,6 +89,39 @@ } protected: + QPointer getChangeset() const { + return m_changeset; + } + QPointer getWaylandOutput() const { + return m_waylandOutput; + } + void setWaylandOutput(KWayland::Server::OutputInterface *set); + QPointer getWaylandOutputDevice() const { + return m_waylandOutputDevice; + } + void setWaylandOutputDevice(KWayland::Server::OutputDeviceInterface *set); + QPoint globalPos() const { + return m_globalPos; + } + + QSize rawPhysicalSize() const { + return m_physicalSize; + } + void setRawPhysicalSize(const QSize &set) { + m_physicalSize = set; + } + + void setOrientation(Qt::ScreenOrientation set) { + m_orientation = set; + } + bool internal() const { + return m_internal; + } + void setInternal(bool set) { + m_internal = set; + } + +private: QPointer m_changeset; QPointer m_waylandOutput; QPointer m_waylandOutputDevice; Index: output.cpp =================================================================== --- output.cpp +++ output.cpp @@ -79,4 +79,14 @@ commitChanges(); } +void Output::setWaylandOutput(KWayland::Server::OutputInterface *set) +{ + m_waylandOutput = set; +} + +void Output::setWaylandOutputDevice(KWayland::Server::OutputDeviceInterface *set) +{ + m_waylandOutputDevice = set; +} + } Index: platform.h =================================================================== --- platform.h +++ platform.h @@ -460,7 +460,6 @@ void initFailed(); void cursorChanged(); void readyChanged(bool); - /** * Emitted by backends using a one screen (nested window) approach and when the size of that changes. **/ Index: platformsupport/scenes/opengl/abstract_egl_backend.cpp =================================================================== --- platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -217,30 +217,63 @@ { const bool haveRobustness = hasExtension(QByteArrayLiteral("EGL_EXT_create_context_robustness")); const bool haveCreateContext = hasExtension(QByteArrayLiteral("EGL_KHR_create_context")); + const bool haveContextPriority = hasExtension(QByteArrayLiteral("EGL_IMG_context_priority")); std::vector> candidates; if (isOpenGLES()) { + if (haveCreateContext && haveRobustness && haveContextPriority) { + auto glesRobustPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesRobustPriority->setVersion(2); + glesRobustPriority->setRobust(true); + glesRobustPriority->setHighPriority(true); + candidates.push_back(std::move(glesRobustPriority)); + } if (haveCreateContext && haveRobustness) { auto glesRobust = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); glesRobust->setVersion(2); glesRobust->setRobust(true); candidates.push_back(std::move(glesRobust)); } + if (haveContextPriority) { + auto glesPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesPriority->setVersion(2); + glesPriority->setHighPriority(true); + candidates.push_back(std::move(glesPriority)); + } auto gles = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); gles->setVersion(2); candidates.push_back(std::move(gles)); } else { if (options->glCoreProfile() && haveCreateContext) { + if (haveRobustness && haveContextPriority) { + auto robustCorePriority = std::unique_ptr(new EglContextAttributeBuilder); + robustCorePriority->setVersion(3, 1); + robustCorePriority->setRobust(true); + robustCorePriority->setHighPriority(true); + candidates.push_back(std::move(robustCorePriority)); + } if (haveRobustness) { auto robustCore = std::unique_ptr(new EglContextAttributeBuilder); robustCore->setVersion(3, 1); robustCore->setRobust(true); candidates.push_back(std::move(robustCore)); } + if (haveContextPriority) { + auto corePriority = std::unique_ptr(new EglContextAttributeBuilder); + corePriority->setVersion(3, 1); + corePriority->setHighPriority(true); + candidates.push_back(std::move(corePriority)); + } auto core = std::unique_ptr(new EglContextAttributeBuilder); core->setVersion(3, 1); candidates.push_back(std::move(core)); } + if (haveRobustness && haveCreateContext && haveContextPriority) { + auto robustPriority = std::unique_ptr(new EglContextAttributeBuilder); + robustPriority->setRobust(true); + robustPriority->setHighPriority(true); + candidates.push_back(std::move(robustPriority)); + } if (haveRobustness && haveCreateContext) { auto robust = std::unique_ptr(new EglContextAttributeBuilder); robust->setRobust(true); Index: plugins/platforms/drm/drm_output.cpp =================================================================== --- plugins/platforms/drm/drm_output.cpp +++ plugins/platforms/drm/drm_output.cpp @@ -79,8 +79,8 @@ m_crtc->setOutput(nullptr); m_conn->setOutput(nullptr); - delete m_waylandOutput.data(); - delete m_waylandOutputDevice.data(); + delete getWaylandOutput().data(); + delete getWaylandOutputDevice().data(); delete m_cursor[0]; delete m_cursor[1]; } @@ -126,7 +126,7 @@ c->fill(Qt::transparent); QPainter p; p.begin(c); - if (m_orientation == Qt::InvertedLandscapeOrientation) { + if (orientation() == Qt::InvertedLandscapeOrientation) { QMatrix4x4 matrix; matrix.translate(cursorImage.width() / 2.0, cursorImage.height() / 2.0); matrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); @@ -141,24 +141,26 @@ { QMatrix4x4 matrix; QMatrix4x4 hotspotMatrix; - if (m_orientation == Qt::InvertedLandscapeOrientation) { + if (orientation() == Qt::InvertedLandscapeOrientation) { matrix.translate(pixelSize().width() /2.0, pixelSize().height() / 2.0); matrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); matrix.translate(-pixelSize().width() /2.0, -pixelSize().height() / 2.0); const auto cursorSize = m_backend->softwareCursor().size(); hotspotMatrix.translate(cursorSize.width()/2.0, cursorSize.height()/2.0); hotspotMatrix.rotate(180.0f, 0.0f, 0.0f, 1.0f); hotspotMatrix.translate(-cursorSize.width()/2.0, -cursorSize.height()/2.0); } - matrix.scale(m_scale); - matrix.translate(-m_globalPos.x(), -m_globalPos.y()); + matrix.scale(scale()); + auto outputGlobalPos = Output::globalPos(); + matrix.translate(-outputGlobalPos.x(), -outputGlobalPos.y()); const QPoint p = matrix.map(globalPos) - hotspotMatrix.map(m_backend->softwareCursorHotspot()); drmModeMoveCursor(m_backend->fd(), m_crtc->id(), p.x(), p.y()); } QSize DrmOutput::pixelSize() const { - if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { + auto orient = orientation(); + if (orient == Qt::PortraitOrientation || orient == Qt::InvertedPortraitOrientation) { return QSize(m_mode.vdisplay, m_mode.hdisplay); } return QSize(m_mode.hdisplay, m_mode.vdisplay); @@ -174,9 +176,9 @@ initOutput(); } else { setDpms(DpmsMode::Off); - delete m_waylandOutput.data(); + delete getWaylandOutput().data(); } - m_waylandOutputDevice->setEnabled(enabled ? + getWaylandOutputDevice()->setEnabled(enabled ? KWayland::Server::OutputDeviceInterface::Enablement::Enabled : KWayland::Server::OutputDeviceInterface::Enablement::Disabled); } @@ -266,9 +268,10 @@ return false; } - m_internal = connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP; + setInternal(connector->connector_type == DRM_MODE_CONNECTOR_LVDS || + connector->connector_type == DRM_MODE_CONNECTOR_eDP); - if (m_internal) { + if (internal()) { connect(kwinApp(), &Application::screensCreated, this, [this] { connect(screens()->orientationSensor(), &OrientationSensor::orientationChanged, this, &DrmOutput::automaticRotation); @@ -288,7 +291,7 @@ qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid.eisaId << "/" << m_edid.monitorName << "/" << m_edid.serialNumber << " from " << physicalSize << "to " << overwriteSize; physicalSize = overwriteSize; } - m_physicalSize = physicalSize; + setRawPhysicalSize(physicalSize); initOutputDevice(connector); @@ -308,62 +311,69 @@ void DrmOutput::initOutput() { - Q_ASSERT(m_waylandOutputDevice); - if (!m_waylandOutput.isNull()) { - delete m_waylandOutput.data(); - m_waylandOutput.clear(); + auto waylandOutputDevice = getWaylandOutputDevice(); + Q_ASSERT(waylandOutputDevice); + + auto waylandOutput = getWaylandOutput(); + if (!waylandOutput.isNull()) { + delete waylandOutput.data(); + waylandOutput.clear(); } - m_waylandOutput = waylandServer()->display()->createOutput(); + waylandOutput = waylandServer()->display()->createOutput(); connect(this, &DrmOutput::modeChanged, this, [this] { - if (m_waylandOutput.isNull()) { + auto waylandOutput = getWaylandOutput(); + if (waylandOutput.isNull()) { return; } - m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode)); + waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), + refreshRateForMode(&m_mode)); } ); - m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer()); - m_waylandOutput->setModel(m_waylandOutputDevice->model()); - m_waylandOutput->setPhysicalSize(m_physicalSize); + waylandOutput->setManufacturer(waylandOutputDevice->manufacturer()); + waylandOutput->setModel(waylandOutputDevice->model()); + waylandOutput->setPhysicalSize(rawPhysicalSize()); // set dpms if (!m_dpms.isNull()) { - m_waylandOutput->setDpmsSupported(true); - m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsMode)); - connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this, + waylandOutput->setDpmsSupported(true); + waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsMode)); + connect(waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this, [this] (KWayland::Server::OutputInterface::DpmsMode mode) { setDpms(fromWaylandDpmsMode(mode)); }, Qt::QueuedConnection ); } - for(const auto &mode: m_waylandOutputDevice->modes()) { + for(const auto &mode: waylandOutputDevice->modes()) { KWayland::Server::OutputInterface::ModeFlags flags; if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Current) { flags |= KWayland::Server::OutputInterface::ModeFlag::Current; } if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred) { flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred; } - m_waylandOutput->addMode(mode.size, flags, mode.refreshRate); + waylandOutput->addMode(mode.size, flags, mode.refreshRate); } - m_waylandOutput->create(); + waylandOutput->create(); + setWaylandOutput(waylandOutput.data()); } void DrmOutput::initOutputDevice(drmModeConnector *connector) { - if (!m_waylandOutputDevice.isNull()) { - delete m_waylandOutputDevice.data(); - m_waylandOutputDevice.clear(); + auto waylandOutputDevice = getWaylandOutputDevice(); + if (!waylandOutputDevice.isNull()) { + delete waylandOutputDevice.data(); + waylandOutputDevice.clear(); } - m_waylandOutputDevice = waylandServer()->display()->createOutputDevice(); - m_waylandOutputDevice->setUuid(m_uuid); + waylandOutputDevice = waylandServer()->display()->createOutputDevice(); + waylandOutputDevice->setUuid(m_uuid); if (!m_edid.eisaId.isEmpty()) { - m_waylandOutputDevice->setManufacturer(QString::fromLatin1(m_edid.eisaId)); + waylandOutputDevice->setManufacturer(QString::fromLatin1(m_edid.eisaId)); } else { - m_waylandOutputDevice->setManufacturer(i18n("unknown")); + waylandOutputDevice->setManufacturer(i18n("unknown")); } QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown")); @@ -382,9 +392,9 @@ modelName = i18n("unknown"); } - m_waylandOutputDevice->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName); + waylandOutputDevice->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName); - m_waylandOutputDevice->setPhysicalSize(m_physicalSize); + waylandOutputDevice->setPhysicalSize(rawPhysicalSize()); // read in mode information for (int i = 0; i < connector->count_modes; ++i) { @@ -407,9 +417,10 @@ mode.flags = deviceflags; mode.refreshRate = refreshRate; qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size; - m_waylandOutputDevice->addMode(mode); + waylandOutputDevice->addMode(mode); } - m_waylandOutputDevice->create(); + waylandOutputDevice->create(); + setWaylandOutputDevice(waylandOutputDevice.data()); } bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const @@ -704,8 +715,9 @@ { qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to On."; - if (m_waylandOutput) { - m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); + auto waylandOutput = getWaylandOutput(); + if (waylandOutput) { + waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); } emit dpmsChanged(); @@ -722,117 +734,124 @@ { qCDebug(KWIN_DRM) << "DPMS mode set for output" << m_crtc->id() << "to Off."; - if (m_waylandOutput) { - m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); + auto waylandOutput = getWaylandOutput(); + if (waylandOutput) { + waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsModePending)); } emit dpmsChanged(); m_backend->outputWentOff(); } int DrmOutput::currentRefreshRate() const { - if (!m_waylandOutput) { + auto waylandOutput = getWaylandOutput(); + if (!waylandOutput) { return 60000; } - return m_waylandOutput->refreshRate(); + return waylandOutput->refreshRate(); } bool DrmOutput::commitChanges() { - Q_ASSERT(!m_waylandOutputDevice.isNull()); + auto waylandOutputDevice = getWaylandOutputDevice(); + Q_ASSERT(!waylandOutputDevice.isNull()); + + auto changeset = getChangeset(); - if (m_changeset.isNull()) { + if (changeset.isNull()) { qCDebug(KWIN_DRM) << "no changes"; // No changes to an output is an entirely valid thing return true; } //enabledChanged is handled by drmbackend - if (m_changeset->modeChanged()) { - qCDebug(KWIN_DRM) << "Setting new mode:" << m_changeset->mode(); - m_waylandOutputDevice->setCurrentMode(m_changeset->mode()); - updateMode(m_changeset->mode()); - } - if (m_changeset->transformChanged()) { - qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(m_changeset->transform()); - transform(m_changeset->transform()); - } - if (m_changeset->positionChanged()) { - qCDebug(KWIN_DRM) << "Server setting position: " << m_changeset->position(); - setGlobalPos(m_changeset->position()); + if (changeset->modeChanged()) { + qCDebug(KWIN_DRM) << "Setting new mode:" << changeset->mode(); + waylandOutputDevice->setCurrentMode(changeset->mode()); + updateMode(changeset->mode()); + } + if (changeset->transformChanged()) { + qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(changeset->transform()); + transform(changeset->transform()); + } + if (changeset->positionChanged()) { + qCDebug(KWIN_DRM) << "Server setting position: " << changeset->position(); + setGlobalPos(changeset->position()); // may just work already! } - if (m_changeset->scaleChanged()) { - qCDebug(KWIN_DRM) << "Setting scale:" << m_changeset->scale(); - setScale(m_changeset->scale()); + if (changeset->scaleChanged()) { + qCDebug(KWIN_DRM) << "Setting scale:" << changeset->scale(); + setScale(changeset->scale()); } return true; } void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) { - m_waylandOutputDevice->setTransform(transform); + getWaylandOutputDevice()->setTransform(transform); using KWayland::Server::OutputDeviceInterface; using KWayland::Server::OutputInterface; + auto waylandOutput = getWaylandOutput(); + switch (transform) { case OutputDeviceInterface::Transform::Normal: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0); } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Normal); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Normal); } - m_orientation = Qt::PrimaryOrientation; + setOrientation(Qt::PrimaryOrientation); break; case OutputDeviceInterface::Transform::Rotated90: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate90); } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Rotated90); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Rotated90); } - m_orientation = Qt::PortraitOrientation; + setOrientation(Qt::PortraitOrientation); break; case OutputDeviceInterface::Transform::Rotated180: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate180); } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Rotated180); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Rotated180); } - m_orientation = Qt::InvertedLandscapeOrientation; + setOrientation(Qt::InvertedLandscapeOrientation); break; case OutputDeviceInterface::Transform::Rotated270: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate270); } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Rotated270); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Rotated270); } - m_orientation = Qt::InvertedPortraitOrientation; + setOrientation(Qt::InvertedPortraitOrientation); break; case OutputDeviceInterface::Transform::Flipped: // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Flipped); } break; case OutputDeviceInterface::Transform::Flipped90: // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped90); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Flipped90); } break; case OutputDeviceInterface::Transform::Flipped180: // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped180); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Flipped180); } break; case OutputDeviceInterface::Transform::Flipped270: // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped270); + if (waylandOutput) { + waylandOutput->setTransform(OutputInterface::Transform::Flipped270); } break; } @@ -962,7 +981,7 @@ // go back to previous state if (m_lastWorkingState.valid) { m_mode = m_lastWorkingState.mode; - m_orientation = m_lastWorkingState.orientation; + setOrientation(m_lastWorkingState.orientation); setGlobalPos(m_lastWorkingState.globalPos); if (m_primaryPlane) { m_primaryPlane->setTransformation(m_lastWorkingState.planeTransformations); @@ -986,8 +1005,8 @@ if (wasModeset) { // store current mode set as new good state m_lastWorkingState.mode = m_mode; - m_lastWorkingState.orientation = m_orientation; - m_lastWorkingState.globalPos = m_globalPos; + m_lastWorkingState.orientation = orientation(); + m_lastWorkingState.globalPos = globalPos(); if (m_primaryPlane) { m_lastWorkingState.planeTransformations = m_primaryPlane->transformation(); } Index: plugins/platforms/drm/egl_gbm_backend.cpp =================================================================== --- plugins/platforms/drm/egl_gbm_backend.cpp +++ plugins/platforms/drm/egl_gbm_backend.cpp @@ -258,17 +258,41 @@ EGLint count; EGLConfig configs[1024]; - if (eglChooseConfig(eglDisplay(), config_attribs, configs, 1, &count) == EGL_FALSE) { + if (!eglChooseConfig(eglDisplay(), config_attribs, configs, sizeof(configs)/sizeof(EGLConfig), &count)) { qCCritical(KWIN_DRM) << "choose config failed"; return false; } - if (count != 1) { - qCCritical(KWIN_DRM) << "choose config did not return a config" << count; - return false; + + qCDebug(KWIN_DRM) << "EGL buffer configs count:" << count; + + // loop through all configs, chosing the first one that has suitable format + for (EGLint i = 0; i < count; i++) { + EGLint gbmFormat; + // query some configuration parameters, to show in debug log + eglGetConfigAttrib(eglDisplay(), configs[i], EGL_NATIVE_VISUAL_ID, &gbmFormat); + + if (KWIN_DRM().isDebugEnabled()) { + // GBM formats are declared as FOURCC code (integer from ASCII chars, so use this fact) + char gbmFormatStr[sizeof(EGLint) + 1] = {0}; + memcpy(gbmFormatStr, &gbmFormat, sizeof(EGLint)); + // query number of bits for color channel + EGLint blueSize, redSize, greenSize, alphaSize; + eglGetConfigAttrib(eglDisplay(), configs[i], EGL_RED_SIZE, &redSize); + eglGetConfigAttrib(eglDisplay(), configs[i], EGL_GREEN_SIZE, &greenSize); + eglGetConfigAttrib(eglDisplay(), configs[i], EGL_BLUE_SIZE, &blueSize); + eglGetConfigAttrib(eglDisplay(), configs[i], EGL_ALPHA_SIZE, &alphaSize); + qCDebug(KWIN_DRM) << " EGL config #" << i << " has GBM FOURCC format:" << gbmFormatStr + << "; color sizes (RGBA order):" << redSize << greenSize << blueSize << alphaSize; + } + + if ((gbmFormat == GBM_FORMAT_XRGB8888) || (gbmFormat == GBM_FORMAT_ARGB8888)) { + setConfig(configs[i]); + return true; + } } - setConfig(configs[0]); - return true; + qCCritical(KWIN_DRM) << "choose EGL config did not return a suitable config" << count; + return false; } void EglGbmBackend::present() Index: plugins/platforms/virtual/virtual_output.h =================================================================== --- plugins/platforms/virtual/virtual_output.h +++ plugins/platforms/virtual/virtual_output.h @@ -33,14 +33,14 @@ public: VirtualOutput(QObject *parent = nullptr); - VirtualOutput(const VirtualOutput &o); virtual ~VirtualOutput(); QRect geometry() const { return m_geo; } private: + Q_DISABLE_COPY(VirtualOutput); friend class VirtualBackend; QRect m_geo; Index: plugins/platforms/virtual/virtual_output.cpp =================================================================== --- plugins/platforms/virtual/virtual_output.cpp +++ plugins/platforms/virtual/virtual_output.cpp @@ -27,14 +27,6 @@ { } -VirtualOutput::VirtualOutput(const VirtualOutput &o) - : m_geo(o.m_geo), - m_outputScale(o.m_outputScale), - m_gammaSize(o.m_gammaSize), - m_gammaResult(o.m_gammaResult) -{ -} - VirtualOutput::~VirtualOutput() { } Index: plugins/qpa/abstractplatformcontext.cpp =================================================================== --- plugins/qpa/abstractplatformcontext.cpp +++ plugins/qpa/abstractplatformcontext.cpp @@ -146,21 +146,48 @@ const QList extensions = eglExtensions.split(' '); const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness")); const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context")); + const bool haveContextPriority = extensions.contains(QByteArrayLiteral("EGL_IMG_context_priority")); std::vector> candidates; if (isOpenGLES()) { + if (haveCreateContext && haveRobustness && haveContextPriority) { + auto glesRobustPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesRobustPriority->setVersion(2); + glesRobustPriority->setRobust(true); + glesRobustPriority->setHighPriority(true); + candidates.push_back(std::move(glesRobustPriority)); + } if (haveCreateContext && haveRobustness) { auto glesRobust = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); glesRobust->setVersion(2); glesRobust->setRobust(true); candidates.push_back(std::move(glesRobust)); } + if (haveContextPriority) { + auto glesPriority = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); + glesPriority->setVersion(2); + glesPriority->setHighPriority(true); + candidates.push_back(std::move(glesPriority)); + } auto gles = std::unique_ptr(new EglOpenGLESContextAttributeBuilder); gles->setVersion(2); candidates.push_back(std::move(gles)); } else { // Try to create a 3.1 core context if (m_format.majorVersion() >= 3 && haveCreateContext) { + if (haveRobustness && haveContextPriority) { + auto robustCorePriority = std::unique_ptr(new EglContextAttributeBuilder); + robustCorePriority->setVersion(m_format.majorVersion(), m_format.minorVersion()); + robustCorePriority->setRobust(true); + robustCorePriority->setForwardCompatible(true); + if (m_format.profile() == QSurfaceFormat::CoreProfile) { + robustCorePriority->setCoreProfile(true); + } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { + robustCorePriority->setCompatibilityProfile(true); + } + robustCorePriority->setHighPriority(true); + candidates.push_back(std::move(robustCorePriority)); + } if (haveRobustness) { auto robustCore = std::unique_ptr(new EglContextAttributeBuilder); robustCore->setVersion(m_format.majorVersion(), m_format.minorVersion()); @@ -173,6 +200,18 @@ } candidates.push_back(std::move(robustCore)); } + if (haveContextPriority) { + auto corePriority = std::unique_ptr(new EglContextAttributeBuilder); + corePriority->setVersion(m_format.majorVersion(), m_format.minorVersion()); + corePriority->setForwardCompatible(true); + if (m_format.profile() == QSurfaceFormat::CoreProfile) { + corePriority->setCoreProfile(true); + } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { + corePriority->setCompatibilityProfile(true); + } + corePriority->setHighPriority(true); + candidates.push_back(std::move(corePriority)); + } auto core = std::unique_ptr(new EglContextAttributeBuilder); core->setVersion(m_format.majorVersion(), m_format.minorVersion()); core->setForwardCompatible(true); @@ -183,7 +222,12 @@ } candidates.push_back(std::move(core)); } - + if (haveRobustness && haveCreateContext && haveContextPriority) { + auto robustPriority = std::unique_ptr(new EglContextAttributeBuilder); + robustPriority->setRobust(true); + robustPriority->setHighPriority(true); + candidates.push_back(std::move(robustPriority)); + } if (haveRobustness && haveCreateContext) { auto robust = std::unique_ptr(new EglContextAttributeBuilder); robust->setRobust(true); Index: scripts/minimizeall/metadata.desktop =================================================================== --- scripts/minimizeall/metadata.desktop +++ scripts/minimizeall/metadata.desktop @@ -42,6 +42,7 @@ Comment=Adds a shortcut to minimize and restore all windows Comment[ca]=Afegeix una drecera per a minimitzar i restaurar totes les finestres Comment[ca@valencia]=Afig una drecera per a minimitzar i restaurar totes les finestres +Comment[cs]=Přidá zkratku k minimalizaci a obnovení všech oken. Comment[da]=Tilføjer en genvej til at minimere og gendanne alle vinduer Comment[de]=Fügt einen Kurzbefehl hinzu, um alle Fenster zu minimieren oder wieder anzuzeigen Comment[en_GB]=Adds a shortcut to minimise and restore all windows Index: udev.h =================================================================== --- udev.h +++ udev.h @@ -82,6 +82,7 @@ return m_udev != nullptr; } UdevDevice::Ptr primaryGpu(); + UdevDevice::Ptr primaryFramebuffer(); UdevDevice::Ptr virtualGpu(); UdevDevice::Ptr renderNode(); UdevDevice::Ptr deviceFromSyspath(const char *syspath); Index: udev.cpp =================================================================== --- udev.cpp +++ udev.cpp @@ -18,6 +18,7 @@ along with this program. If not, see . *********************************************************************/ #include "udev.h" +#include "logind.h" // Qt #include #include @@ -106,6 +107,7 @@ if (m_enumerate.isNull()) { return UdevDevice::Ptr(); } + QString defaultSeat = QStringLiteral("seat0"); udev_list_entry *it = udev_enumerate_get_list_entry(m_enumerate.data()); UdevDevice::Ptr firstFound; while (it) { @@ -115,6 +117,13 @@ if (!device) { continue; } + QString deviceSeat = device->property("ID_SEAT"); + if (deviceSeat.isEmpty()) { + deviceSeat = defaultSeat; + } + if (deviceSeat != LogindIntegration::self()->seat()) { + continue; + } if (test(device)) { return device; } @@ -135,7 +144,6 @@ enumerate.addMatch(UdevEnumerate::Match::SysName, "card[0-9]*"); enumerate.scan(); return enumerate.find([](const UdevDevice::Ptr &device) { - // TODO: check seat auto pci = device->getParentWithSubsystemDevType("pci"); if (!pci) { return false; @@ -178,6 +186,28 @@ }); } +UdevDevice::Ptr Udev::primaryFramebuffer() +{ + if (!m_udev) { + return UdevDevice::Ptr(); + } + UdevEnumerate enumerate(this); + enumerate.addMatch(UdevEnumerate::Match::SubSystem, "graphics"); + enumerate.addMatch(UdevEnumerate::Match::SysName, "fb[0-9]*"); + enumerate.scan(); + return enumerate.find([](const UdevDevice::Ptr &device) { + auto pci = device->getParentWithSubsystemDevType("pci"); + if (!pci) { + return false; + } + const char *systAttrValue = udev_device_get_sysattr_value(pci, "boot_vga"); + if (systAttrValue && qstrcmp(systAttrValue, "1") == 0) { + return true; + } + return false; + }); +} + UdevDevice::Ptr Udev::deviceFromSyspath(const char *syspath) { return UdevDevice::Ptr(new UdevDevice(udev_device_new_from_syspath(m_udev, syspath))); Index: workspace.cpp =================================================================== --- workspace.cpp +++ workspace.cpp @@ -393,6 +393,7 @@ // load again to sync to RootInfo, see BUG 385260 vds->load(); vds->updateRootInfo(); + rootInfo->setCurrentDesktop(vds->currentDesktop()->x11DesktopNumber()); // TODO: only in X11 mode // Extra NETRootInfo instance in Client mode is needed to get the values of the properties