diff --git a/kwin/src/breezydesktopeffect.cpp b/kwin/src/breezydesktopeffect.cpp index c356e3d..c20c14b 100644 --- a/kwin/src/breezydesktopeffect.cpp +++ b/kwin/src/breezydesktopeffect.cpp @@ -113,6 +113,13 @@ namespace KWin BreezyDesktopEffect::BreezyDesktopEffect() { + const QByteArray sessionClass = qgetenv("XDG_SESSION_CLASS").toLower(); + if (sessionClass != "user") { + m_sessionClassBlocked = true; + qCWarning(KWIN_XR) << "Breezy - effect disabled; expected XDG_SESSION_CLASS=user, got:" << sessionClass; + return; + } + qCCritical(KWIN_XR) << "\t\t\tBreezy - constructor"; // safe to request on each load, acts as a no-op if already present @@ -316,12 +323,17 @@ void BreezyDesktopEffect::toggle() void BreezyDesktopEffect::activate() { + if (m_sessionClassBlocked) { + return; + } qCCritical(KWIN_XR) << "\t\t\tBreezy - activate"; if (!isRunning()) setRunning(true); connect(effects, &EffectsHandler::cursorShapeChanged, this, &BreezyDesktopEffect::updateCursorImage); - m_cursorUpdateTimer->start(); + if (m_cursorUpdateTimer) { + m_cursorUpdateTimer->start(); + } // QuickSceneEffect grabs the keyboard and mouse input, which pulls focus away from the active window // and doesn't allow for interaction with anything on the desktop. These two calls fix that. @@ -331,13 +343,21 @@ void BreezyDesktopEffect::activate() void BreezyDesktopEffect::deactivate() { + if (m_sessionClassBlocked) { + if (isRunning()) { + setRunning(false); + } + return; + } qCCritical(KWIN_XR) << "\t\t\tBreezy - deactivate"; m_effectTargetScreenIndex = -1; invalidateEffectOnScreenGeometryCache(); disconnect(effects, &EffectsHandler::cursorShapeChanged, this, &BreezyDesktopEffect::updateCursorImage); - m_cursorUpdateTimer->stop(); + if (m_cursorUpdateTimer) { + m_cursorUpdateTimer->stop(); + } showCursor(); if (m_removeVirtualDisplaysOnDisable) { @@ -642,6 +662,9 @@ bool BreezyDesktopEffect::checkParityByte(const char* data) { static qint64 lastConfigUpdate = 0; static qint64 activatedAt = 0; void BreezyDesktopEffect::updatePose() { + if (m_sessionClassBlocked) { + return; + } // Reentrancy guard: if an update is already in progress, skip bool expected = false; if (!m_poseUpdateInProgress.compare_exchange_strong(expected, true)) { diff --git a/kwin/src/breezydesktopeffect.h b/kwin/src/breezydesktopeffect.h index 5e1ff4e..dc63f3f 100644 --- a/kwin/src/breezydesktopeffect.h +++ b/kwin/src/breezydesktopeffect.h @@ -189,21 +189,21 @@ namespace KWin bool m_zoomOnFocusEnabled = false; int m_lookingAtScreenIndex = -1; int m_effectTargetScreenIndex = -1; - bool m_poseResetState; + bool m_poseResetState = false; bool m_poseHasPosition = false; QList m_poseOrientations; QVector3D m_posePosition; - quint32 m_poseTimeElapsedMs; + quint32 m_poseTimeElapsedMs = 0; quint64 m_poseTimestamp = 0; QList m_lookAheadConfig; qreal m_lookAheadOverride = -1.0; // -1 = use device default QList m_displayResolution; - qreal m_diagonalFOV; - qreal m_lensDistanceRatio; - bool m_sbsEnabled; - bool m_smoothFollowEnabled; + qreal m_diagonalFOV = 0.0; + qreal m_lensDistanceRatio = 0.0; + bool m_sbsEnabled = false; + bool m_smoothFollowEnabled = false; QList m_smoothFollowOrigin; - bool m_customBannerEnabled; + bool m_customBannerEnabled = false; QFileSystemWatcher *m_shmFileWatcher = nullptr; QFileSystemWatcher *m_shmDirectoryWatcher = nullptr; bool m_cursorHidden = false; @@ -211,6 +211,7 @@ namespace KWin QTimer *m_cursorUpdateTimer = nullptr; QTimer *m_watchdogTimer = nullptr; std::atomic m_poseUpdateInProgress{false}; + bool m_sessionClassBlocked = false; qreal m_focusedDisplayDistance = 0.85; qreal m_allDisplaysDistance = 1.05; qreal m_displaySpacing = 0.0; diff --git a/kwin/src/kcm/breezydesktopeffectkcm.cpp b/kwin/src/kcm/breezydesktopeffectkcm.cpp index 080f15e..4124664 100644 --- a/kwin/src/kcm/breezydesktopeffectkcm.cpp +++ b/kwin/src/kcm/breezydesktopeffectkcm.cpp @@ -204,6 +204,15 @@ BreezyDesktopEffectConfig::BreezyDesktopEffectConfig(QObject *parent, const KPlu ui.setupUi(widget()); addConfig(BreezyDesktopConfig::self(), widget()); + // safe to request on each load, acts as a no-op if already present + { + QJsonObject flags; + QJsonArray requested; + requested.append(QStringLiteral("productivity_basic")); + flags.insert(QStringLiteral("request_features"), requested); + XRDriverIPC::instance().writeControlFlags(flags); + } + // Advanced tab: measurement units selector (stored as "cm" or "in") if (ui.comboMeasurementUnits) { ui.comboMeasurementUnits->clear();