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 <QTimer>
#include <QDBusConnection>
#include <QDateTime>
#include <KGlobalAccel>
#include <KLocalizedString>
@ -167,6 +168,14 @@ BreezyDesktopEffect::BreezyDesktopEffect()
// Initial setup
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);
connect(m_cursorUpdateTimer, &QTimer::timeout, this, &BreezyDesktopEffect::updateCursorPos);
m_cursorUpdateTimer->setInterval(16); // ~60Hz
@ -197,6 +206,11 @@ BreezyDesktopEffect::~BreezyDesktopEffect()
m_shmDirectoryWatcher->deleteLater();
m_shmDirectoryWatcher = nullptr;
}
if (m_imuWatchdogTimer) {
m_imuWatchdogTimer->stop();
m_imuWatchdogTimer->deleteLater();
m_imuWatchdogTimer = nullptr;
}
deactivate();
}
@ -581,6 +595,15 @@ bool BreezyDesktopEffect::checkParityByte(const char* data) {
static qint64 lastConfigUpdate = 0;
static qint64 activatedAt = 0;
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");
QFile shmFile(shmPath);
if (!shmFile.open(QIODevice::ReadOnly)) {
@ -850,9 +873,9 @@ void BreezyDesktopEffect::evaluateCursorOnScreenState(const QPointF &prevPos, co
const bool onScreen =
m_effectOnScreenExpandedGeometry.contains(newPos.toPoint()) ||
m_effectOnScreenExpandedGeometry.contains(predicted.toPoint());
if (!m_cursorHidden && onScreen) {
if (m_enabled && !m_imuResetState && !m_cursorHidden && onScreen) {
hideCursor();
} else if (m_enabled && !m_imuResetState && m_cursorHidden && !onScreen) {
} else if (m_cursorHidden && (!m_enabled || m_imuResetState || !onScreen)) {
showCursor();
}
}

View File

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