mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-11 00:47:22 +00:00
159 lines
4.6 KiB
C++
159 lines
4.6 KiB
C++
|
|
// 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;
|
||
|
|
}
|