shift-shell/initialstart/devicecontext.cpp

159 lines
4.6 KiB
C++
Raw Normal View History

// SPDX-FileCopyrightText: 2026 Marco Allegretti
// SPDX-License-Identifier: EUPL-1.2
#include "devicecontext.h"
#include <KRuntimePlatform>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QGuiApplication>
#include <QInputDevice>
#include <QJSEngine>
#include <QQmlEngine>
#include <QScreen>
#include <algorithm>
namespace
{
bool pathExists(const QString &path)
{
return QFileInfo::exists(path);
}
bool systemHasBattery()
{
const QDir powerSupply(QStringLiteral("/sys/class/power_supply"));
const QStringList entries = powerSupply.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &entry : entries) {
if (entry.startsWith(QStringLiteral("BAT"), Qt::CaseInsensitive)) {
return true;
}
if (pathExists(powerSupply.filePath(entry + QStringLiteral("/type")))) {
QFile typeFile(powerSupply.filePath(entry + QStringLiteral("/type")));
if (typeFile.open(QIODevice::ReadOnly) && QString::fromUtf8(typeFile.readAll()).trimmed() == QLatin1String("Battery")) {
return true;
}
}
}
return false;
}
}
DeviceContext::DeviceContext(QObject *parent)
: QObject(parent)
, m_runtimePlatform(KRuntimePlatform::runtimePlatform().join(QLatin1Char(',')))
, m_hasBattery(systemHasBattery())
{
const QList<const QInputDevice *> devices = QInputDevice::devices();
for (const QInputDevice *device : devices) {
if (!device) {
continue;
}
const auto type = device->type();
m_hasTouch = m_hasTouch || type == QInputDevice::DeviceType::TouchScreen;
m_hasKeyboard = m_hasKeyboard || type == QInputDevice::DeviceType::Keyboard;
m_hasMouse = m_hasMouse || type == QInputDevice::DeviceType::Mouse;
}
const QList<QScreen *> screens = QGuiApplication::screens();
m_displayCount = std::max(1, static_cast<int>(screens.size()));
if (QScreen *screen = QGuiApplication::primaryScreen()) {
const QSize size = screen->geometry().size();
m_primaryDisplayLandscape = size.width() >= size.height();
}
const QString platform = m_runtimePlatform;
if (m_displayCount > 1) {
m_recommendedDeviceClass = QStringLiteral("dual-screen");
m_recommendedExperienceProfile = QStringLiteral("hybrid");
} else if (platform.contains(QStringLiteral("phone"))) {
m_recommendedDeviceClass = QStringLiteral("phone");
m_recommendedExperienceProfile = QStringLiteral("mobile");
} else if (platform.contains(QStringLiteral("handheld"))) {
m_recommendedDeviceClass = QStringLiteral("handheld");
m_recommendedExperienceProfile = QStringLiteral("gaming");
} else if (platform.contains(QStringLiteral("tablet"))) {
m_recommendedDeviceClass = QStringLiteral("tablet");
m_recommendedExperienceProfile = QStringLiteral("mobile");
} else if (m_hasBattery && m_hasTouch && (m_hasKeyboard || m_hasMouse)) {
m_recommendedDeviceClass = QStringLiteral("tablet");
m_recommendedExperienceProfile = QStringLiteral("hybrid");
} else if (m_hasBattery && (m_hasKeyboard || m_hasMouse)) {
m_recommendedDeviceClass = QStringLiteral("laptop");
m_recommendedExperienceProfile = QStringLiteral("desktop");
} else if (!m_hasBattery && !m_hasTouch) {
m_recommendedDeviceClass = QStringLiteral("desktop");
m_recommendedExperienceProfile = QStringLiteral("desktop");
} else {
m_recommendedDeviceClass = QStringLiteral("tablet");
m_recommendedExperienceProfile = QStringLiteral("mobile");
}
}
DeviceContext *DeviceContext::self()
{
static auto *instance = new DeviceContext(qApp);
return instance;
}
DeviceContext *DeviceContext::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
{
Q_UNUSED(qmlEngine)
Q_UNUSED(jsEngine)
return self();
}
QString DeviceContext::runtimePlatform() const
{
return m_runtimePlatform;
}
QString DeviceContext::recommendedDeviceClass() const
{
return m_recommendedDeviceClass;
}
QString DeviceContext::recommendedExperienceProfile() const
{
return m_recommendedExperienceProfile;
}
bool DeviceContext::hasTouch() const
{
return m_hasTouch;
}
bool DeviceContext::hasKeyboard() const
{
return m_hasKeyboard;
}
bool DeviceContext::hasMouse() const
{
return m_hasMouse;
}
bool DeviceContext::hasBattery() const
{
return m_hasBattery;
}
int DeviceContext::displayCount() const
{
return m_displayCount;
}
bool DeviceContext::hasExternalDisplay() const
{
return m_displayCount > 1;
}
bool DeviceContext::primaryDisplayLandscape() const
{
return m_primaryDisplayLandscape;
}