Add watchdog that will detect if the IMU keepalive goes stale in the case where the shared mem file hasn't been updated

This commit is contained in:
wheaney 2025-09-24 12:21:57 -07:00
parent fc6858d535
commit 90eb3aeb68
2 changed files with 29 additions and 2 deletions

View File

@ -23,6 +23,7 @@
#include <QQuickItem> #include <QQuickItem>
#include <QTimer> #include <QTimer>
#include <QDBusConnection> #include <QDBusConnection>
#include <QDateTime>
#include <KGlobalAccel> #include <KGlobalAccel>
#include <KLocalizedString> #include <KLocalizedString>
@ -167,6 +168,14 @@ BreezyDesktopEffect::BreezyDesktopEffect()
// Initial setup // Initial setup
setupFileWatcher(); setupFileWatcher();
m_imuWatchdogTimer = new QTimer(this);
m_imuWatchdogTimer->setInterval(1000);
connect(m_imuWatchdogTimer, &QTimer::timeout, this, [this]() {
if (!m_enabled) return;
this->updateImuRotation();
});
m_imuWatchdogTimer->start();
m_cursorUpdateTimer = new QTimer(this); m_cursorUpdateTimer = new QTimer(this);
connect(m_cursorUpdateTimer, &QTimer::timeout, this, &BreezyDesktopEffect::updateCursorPos); connect(m_cursorUpdateTimer, &QTimer::timeout, this, &BreezyDesktopEffect::updateCursorPos);
m_cursorUpdateTimer->setInterval(16); // ~60Hz m_cursorUpdateTimer->setInterval(16); // ~60Hz
@ -197,6 +206,11 @@ BreezyDesktopEffect::~BreezyDesktopEffect()
m_shmDirectoryWatcher->deleteLater(); m_shmDirectoryWatcher->deleteLater();
m_shmDirectoryWatcher = nullptr; m_shmDirectoryWatcher = nullptr;
} }
if (m_imuWatchdogTimer) {
m_imuWatchdogTimer->stop();
m_imuWatchdogTimer->deleteLater();
m_imuWatchdogTimer = nullptr;
}
deactivate(); deactivate();
} }
@ -581,6 +595,15 @@ bool BreezyDesktopEffect::checkParityByte(const char* data) {
static qint64 lastConfigUpdate = 0; static qint64 lastConfigUpdate = 0;
static qint64 activatedAt = 0; static qint64 activatedAt = 0;
void BreezyDesktopEffect::updateImuRotation() { void BreezyDesktopEffect::updateImuRotation() {
// Reentrancy guard: if an update is already in progress, skip
bool expected = false;
if (!m_imuUpdateInProgress.compare_exchange_strong(expected, true)) {
return;
}
// destructor called on function exit, triggers reset of the flag
struct ResetFlag { std::atomic<bool>* f; ~ResetFlag(){ f->store(false); } } reset{&m_imuUpdateInProgress};
const QString shmPath = QStringLiteral("/dev/shm/breezy_desktop_imu"); const QString shmPath = QStringLiteral("/dev/shm/breezy_desktop_imu");
QFile shmFile(shmPath); QFile shmFile(shmPath);
if (!shmFile.open(QIODevice::ReadOnly)) { if (!shmFile.open(QIODevice::ReadOnly)) {
@ -850,9 +873,9 @@ void BreezyDesktopEffect::evaluateCursorOnScreenState(const QPointF &prevPos, co
const bool onScreen = const bool onScreen =
m_effectOnScreenExpandedGeometry.contains(newPos.toPoint()) || m_effectOnScreenExpandedGeometry.contains(newPos.toPoint()) ||
m_effectOnScreenExpandedGeometry.contains(predicted.toPoint()); m_effectOnScreenExpandedGeometry.contains(predicted.toPoint());
if (!m_cursorHidden && onScreen) { if (m_enabled && !m_imuResetState && !m_cursorHidden && onScreen) {
hideCursor(); hideCursor();
} else if (m_enabled && !m_imuResetState && m_cursorHidden && !onScreen) { } else if (m_cursorHidden && (!m_enabled || m_imuResetState || !onScreen)) {
showCursor(); showCursor();
} }
} }

View File

@ -12,6 +12,8 @@
#include <QVariantList> #include <QVariantList>
#include <QHash> #include <QHash>
#include <QRect> #include <QRect>
#include <atomic>
class QTimer;
namespace KWin namespace KWin
{ {
@ -181,6 +183,8 @@ namespace KWin
bool m_cursorHidden = false; bool m_cursorHidden = false;
QPointF m_cursorPos; QPointF m_cursorPos;
QTimer *m_cursorUpdateTimer = nullptr; QTimer *m_cursorUpdateTimer = nullptr;
QTimer *m_imuWatchdogTimer = nullptr;
std::atomic<bool> m_imuUpdateInProgress{false};
qreal m_focusedDisplayDistance = 0.85; qreal m_focusedDisplayDistance = 0.85;
qreal m_allDisplaysDistance = 1.05; qreal m_allDisplaysDistance = 1.05;
qreal m_displaySpacing = 0.0; qreal m_displaySpacing = 0.0;