File indexing completed on 2024-10-27 04:24:10
0001 #include "formfactormanager.h" 0002 0003 #include "settingsstore.h" 0004 #include "mauimanutils.h" 0005 0006 #include <QDebug> 0007 #include <QSize> 0008 #include <QScreen> 0009 #include <QGuiApplication> 0010 0011 #if !defined Q_OS_ANDROID 0012 #include <QDBusInterface> 0013 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0014 #define QT5_BASED 0015 #include <QtSystemInfo/qinputinfo.h> 0016 #else 0017 #define QT6_BASED 0018 #include <QInputDevice> 0019 #endif 0020 #endif 0021 0022 using namespace MauiMan; 0023 0024 #if !defined Q_OS_ANDROID 0025 #ifdef QT5_BASE 0026 static QString typeToString(QInputDevice::InputTypeFlags type) 0027 { 0028 qDebug() << type; 0029 QStringList typeString; 0030 if (type.testFlag(QInputDevice::Button)) 0031 typeString << QStringLiteral("Button"); 0032 if (type.testFlag(QInputDevice::Mouse)) 0033 typeString << QStringLiteral("Mouse"); 0034 if (type.testFlag(QInputDevice::TouchPad)) 0035 typeString << QStringLiteral("TouchPad"); 0036 if (type.testFlag(QInputDevice::TouchScreen)) 0037 typeString << QStringLiteral("TouchScreen"); 0038 if (type.testFlag(QInputDevice::Keyboard)) 0039 typeString << QStringLiteral("Keyboard"); 0040 if (type.testFlag(QInputDevice::Switch)) 0041 typeString << QStringLiteral("Switch"); 0042 0043 if (typeString.isEmpty()) 0044 typeString << QStringLiteral("Unknown"); 0045 return typeString.join((QStringLiteral(", "))); 0046 } 0047 #elif defined QT6_BASE 0048 static QString typeToString(QInputDevice::DeviceTypes type) 0049 { 0050 qDebug() << type; 0051 QStringList typeString; 0052 if (type.testFlag(QInputDevice::DeviceType::Mouse)) 0053 typeString << QStringLiteral("Mouse"); 0054 if (type.testFlag(QInputDevice::DeviceType::TouchPad)) 0055 typeString << QStringLiteral("TouchPad"); 0056 if (type.testFlag(QInputDevice::DeviceType::TouchScreen)) 0057 typeString << QStringLiteral("TouchScreen"); 0058 if (type.testFlag(QInputDevice::DeviceType::Keyboard)) 0059 typeString << QStringLiteral("Keyboard"); 0060 if (typeString.isEmpty()) 0061 typeString << QStringLiteral("Unknown"); 0062 return typeString.join((QStringLiteral(", "))); 0063 } 0064 #endif 0065 #endif 0066 0067 void FormFactorManager::sync(const QString &key, const QVariant &value) 0068 { 0069 #if !defined Q_OS_ANDROID 0070 if (m_interface && m_interface->isValid()) 0071 { 0072 m_interface->call(key, value); 0073 } 0074 #endif 0075 } 0076 0077 void FormFactorManager::setConnections() 0078 { 0079 #if !defined Q_OS_ANDROID 0080 if(m_interface) 0081 { 0082 m_interface->disconnect(); 0083 m_interface->deleteLater(); 0084 m_interface = nullptr; 0085 } 0086 0087 m_interface = new QDBusInterface(QStringLiteral("org.mauiman.Manager"), 0088 QStringLiteral("/FormFactor"), 0089 QStringLiteral("org.mauiman.FormFactor"), 0090 QDBusConnection::sessionBus(), this); 0091 0092 if (m_interface->isValid()) 0093 { 0094 connect(m_interface, SIGNAL(preferredModeChanged(uint)), this, SLOT(onPreferredModeChanged(uint))); 0095 } 0096 #endif 0097 } 0098 0099 void FormFactorManager::loadSettings() 0100 { 0101 m_settings->beginModule(QStringLiteral("FormFactor")); 0102 0103 #if !defined Q_OS_ANDROID 0104 if(m_interface && m_interface->isValid()) 0105 { 0106 m_preferredMode = m_interface->property("preferredMode").toUInt(); 0107 return; 0108 } 0109 #endif 0110 0111 m_preferredMode = m_settings->load(QStringLiteral("PreferredMode"), m_preferredMode).toUInt(); 0112 } 0113 0114 FormFactorManager::FormFactorManager(QObject *parent) : MauiMan::FormFactorInfo(parent) 0115 ,m_settings(new MauiMan::SettingsStore(this)) 0116 ,m_info(new MauiMan::FormFactorInfo(this)) 0117 { 0118 qDebug( " INIT FORMFACTOR MANAGER"); 0119 0120 #if !defined Q_OS_ANDROID 0121 auto server = new MauiManUtils(this); 0122 if(server->serverRunning()) 0123 { 0124 this->setConnections(); 0125 } 0126 0127 connect(server, &MauiManUtils::serverRunningChanged, [this](bool state) 0128 { 0129 if(state) 0130 { 0131 this->setConnections(); 0132 } 0133 }); 0134 #endif 0135 m_preferredMode = defaultMode(); 0136 0137 loadSettings(); 0138 } 0139 0140 uint FormFactorManager::preferredMode() const 0141 { 0142 return m_preferredMode; 0143 } 0144 0145 uint FormFactorInfo::bestMode() const 0146 { 0147 return m_bestMode; 0148 } 0149 0150 uint FormFactorInfo::defaultMode() const 0151 { 0152 return m_defaultMode; 0153 } 0154 0155 bool FormFactorInfo::hasKeyboard() const 0156 { 0157 return m_hasKeyboard; 0158 } 0159 0160 bool FormFactorInfo::hasTouchscreen() const 0161 { 0162 return m_hasTouchscreen; 0163 } 0164 0165 bool FormFactorInfo::hasMouse() const 0166 { 0167 return m_hasMouse; 0168 } 0169 0170 bool FormFactorInfo::hasTouchpad() const 0171 { 0172 return m_hasTouchpad; 0173 } 0174 0175 void FormFactorManager::setPreferredMode(uint preferredMode) 0176 { 0177 if (m_preferredMode == preferredMode) 0178 return; 0179 0180 m_preferredMode = preferredMode; 0181 0182 sync(QStringLiteral("setPreferredMode"), m_preferredMode); 0183 m_settings->save(QStringLiteral("PreferredMode"), m_preferredMode); 0184 0185 Q_EMIT preferredModeChanged(m_preferredMode); 0186 } 0187 0188 void FormFactorManager::onPreferredModeChanged(uint preferredMode) 0189 { 0190 if (m_preferredMode == preferredMode) 0191 return; 0192 0193 m_preferredMode = preferredMode; 0194 Q_EMIT preferredModeChanged(m_preferredMode); 0195 } 0196 0197 void FormFactorInfo::findBestMode() 0198 { 0199 uint bestMode = m_defaultMode; 0200 /* 0201 * 0- desktop 0202 * 1- tablet 0203 * 2- phone 0204 * */ 0205 0206 if(m_hasTouchscreen) 0207 { 0208 if(m_screenSize.width() > 1500) 0209 { 0210 if(m_hasKeyboard || m_hasMouse || m_hasTouchpad) 0211 { 0212 bestMode = 0; //A big touch screen and with keyboard/mouse/trackpad 0213 }else 0214 { 0215 bestMode = 1; //A big touch screen alone 0216 } 0217 } 0218 else if(m_screenSize.width() > 500) 0219 { 0220 bestMode = 1; //A tablet size touch screen 0221 } 0222 else 0223 { 0224 bestMode = 2; //A mobile size touch screen 0225 } 0226 0227 }else 0228 { 0229 0230 if(m_screenSize.width() > 1500) 0231 { 0232 bestMode = 0; // A big screen 0233 0234 } 0235 else if(m_screenSize.width() > 500) 0236 { 0237 if(m_hasTouchpad) 0238 { 0239 bestMode = 1; // A small screen with a trackpad 0240 }else 0241 { 0242 bestMode = 0; 0243 } 0244 } 0245 else 0246 { 0247 bestMode = 1; //A mobile size touch screen 0248 } 0249 } 0250 0251 m_bestMode = bestMode; 0252 Q_EMIT bestModeChanged(m_bestMode); 0253 } 0254 0255 QRect FormFactorInfo::screenSize() 0256 { 0257 QScreen *screen = qApp->primaryScreen(); 0258 return screen->geometry(); 0259 } 0260 0261 Qt::ScreenOrientation FormFactorInfo::screenOrientation() 0262 { 0263 QScreen *screen = qApp->primaryScreen(); 0264 return screen->orientation(); 0265 } 0266 0267 #ifdef QT5_BASE 0268 void FormFactorInfo::checkInputs(const QInputInfoManager *inputManager) 0269 { 0270 #if !defined Q_OS_ANDROID 0271 0272 // qDebug() <<"Found"<< inputDeviceManager->deviceMap().count() << "input devices"; 0273 // QMapIterator<QString, QInputDevice*> i(inputDeviceManager->deviceMap()); 0274 // while (i.hasNext()) 0275 // { 0276 // i.next(); 0277 // qDebug() << i.value()->name() << i.value()->identifier(); 0278 // qDebug() << "buttons count"<< i.value()->buttons().count(); 0279 // qDebug() << "switch count"<< i.value()->switches().count(); 0280 // qDebug() << "relativeAxes count"<< i.value()->relativeAxes().count(); 0281 // qDebug() << "absoluteAxes count"<< i.value()->absoluteAxes().count(); 0282 // qDebug() << "type" << typeToString(i.value()->types()); 0283 0284 // qDebug(); 0285 // // qDebug() << i.value()->name(); 0286 // } 0287 0288 const int keyboardsCount = inputManager->count(QInputDevice::Keyboard); 0289 const int mouseCount = inputManager->count(QInputDevice::Mouse); 0290 const int touchCount = inputManager->count(QInputDevice::TouchScreen); 0291 const int trackpadCount = inputManager->count(QInputDevice::TouchPad); 0292 0293 m_hasKeyboard = keyboardsCount > 0; 0294 m_hasMouse = mouseCount > 0; 0295 m_hasTouchscreen = touchCount > 0; 0296 m_hasTouchpad = trackpadCount > 0; 0297 0298 Q_EMIT hasKeyboardChanged(m_hasKeyboard); 0299 Q_EMIT hasMouseChanged(m_hasMouse); 0300 Q_EMIT hasTouchscreenChanged(m_hasTouchscreen); 0301 Q_EMIT hasTouchpadChanged(m_hasTouchpad); 0302 0303 qDebug() << "Number of keyboards:" << keyboardsCount; 0304 qDebug() << "Number of mice:" << mouseCount; 0305 qDebug() << "Number of touchscreens:" << touchCount; 0306 qDebug() << "Number of touchpads:" << trackpadCount; 0307 #endif 0308 } 0309 #elif defined QT6_BASE 0310 void FormFactorInfo::checkInputs(const QList<const QInputDevice *> &devices) 0311 { 0312 auto hasType = [devices](QInputDevice::DeviceType type) -> bool 0313 { 0314 auto res= std::find_if(devices.constBegin(), devices.constEnd(), [type](const QInputDevice *device) 0315 { 0316 return device->type() == type; 0317 }); 0318 0319 return res != std::end(devices); 0320 }; 0321 0322 m_hasKeyboard = hasType(QInputDevice::DeviceType::Keyboard); 0323 m_hasMouse = hasType(QInputDevice::DeviceType::Mouse); 0324 m_hasTouchscreen = hasType(QInputDevice::DeviceType::TouchScreen); 0325 m_hasTouchpad = hasType(QInputDevice::DeviceType::TouchPad); 0326 0327 Q_EMIT hasKeyboardChanged(m_hasKeyboard); 0328 Q_EMIT hasMouseChanged(m_hasMouse); 0329 Q_EMIT hasTouchscreenChanged(m_hasTouchscreen); 0330 Q_EMIT hasTouchpadChanged(m_hasTouchpad); 0331 } 0332 #endif 0333 0334 FormFactorInfo::FormFactorInfo(QObject *parent) : QObject(parent) 0335 { 0336 qDebug( " INIT FORMFACTOR INFO"); 0337 0338 #if !defined Q_OS_ANDROID 0339 0340 #ifdef QT5_BASED 0341 auto inputDeviceManager = new QInputInfoManager(this); 0342 connect(inputDeviceManager, &QInputInfoManager::ready,[ inputDeviceManager]() 0343 { 0344 inputDeviceManager->setFilter(QInputDevice::Mouse | QInputDevice::Keyboard | QInputDevice::TouchScreen | QInputDevice::TouchPad); 0345 }); 0346 0347 connect(inputDeviceManager, &QInputInfoManager::filterChanged,this,[this, inputDeviceManager](QInputDevice::InputTypeFlags ) 0348 { 0349 checkInputs(inputDeviceManager); 0350 findBestMode(); 0351 }); 0352 0353 connect(inputDeviceManager, &QInputInfoManager::deviceAdded,[this, inputDeviceManager](QInputDevice *) 0354 { 0355 checkInputs(inputDeviceManager); 0356 findBestMode(); 0357 }); 0358 0359 connect(inputDeviceManager, &QInputInfoManager::deviceRemoved,[this, inputDeviceManager](QString) 0360 { 0361 checkInputs(inputDeviceManager); 0362 findBestMode(); 0363 }); 0364 #elif defined QT6_BASE 0365 checkInputs(QInputDevice::devices()); 0366 #endif 0367 findBestMode(); 0368 #endif 0369 0370 }