diff --git a/BiometricAuth/CMakeLists.txt b/BiometricAuth/CMakeLists.txt index 9ba7d2c..e1b52a5 100644 --- a/BiometricAuth/CMakeLists.txt +++ b/BiometricAuth/CMakeLists.txt @@ -1,28 +1,27 @@ qt5_wrap_cpp(BiometricAuth_SRC biometricdeviceinfo.h - biometricproxy.h - biometricauthwidget.h - biometricdeviceswidget.h + biometricproxy.h giodbus.h + uniauthservice.h ) set(BiometricAuth_SRC ${BiometricAuth_SRC} biometricdeviceinfo.cpp - biometricproxy.cpp - biometricauthwidget.cpp - biometricdeviceswidget.cpp + biometricproxy.cpp giodbus.cpp + uniauthservice.cpp ) include_directories( ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} - ${Qt5DBus_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} + ${GIOUNIX2_INCLUDE_DIRS} ) add_library(BiometricAuth STATIC ${BiometricAuth_SRC}) -target_link_libraries(BiometricAuth Qt5::Core Qt5::DBus Qt5::Widgets ${OpenCV_LIBS} ${GIOUNIX2_LIBRARIES}) +target_link_libraries(BiometricAuth Qt5::Core Qt5::DBus Qt5::Widgets + ${GIOUNIX2_LIBRARIES}) diff --git a/BiometricAuth/biometricauthwidget.cpp b/BiometricAuth/biometricauthwidget.cpp index a7b552d..4a03938 100644 --- a/BiometricAuth/biometricauthwidget.cpp +++ b/BiometricAuth/biometricauthwidget.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "biometricauthwidget.h" #include diff --git a/BiometricAuth/biometricauthwidget.h b/BiometricAuth/biometricauthwidget.h index e380abf..8390a02 100644 --- a/BiometricAuth/biometricauthwidget.h +++ b/BiometricAuth/biometricauthwidget.h @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef BIOMETRICAUTHWIDGET_H #define BIOMETRICAUTHWIDGET_H diff --git a/BiometricAuth/biometricdeviceinfo.cpp b/BiometricAuth/biometricdeviceinfo.cpp index 368b1d0..83f97f0 100644 --- a/BiometricAuth/biometricdeviceinfo.cpp +++ b/BiometricAuth/biometricdeviceinfo.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "biometricdeviceinfo.h" @@ -34,6 +33,25 @@ QString DeviceType::getDeviceType(int deviceType) return QString(typeString); } +int DeviceType::getBioType(int bioType) +{ + switch(bioType) + { + case Face: + return 0; + case FingerPrint: + return 1; + case FingerVein: + return 2; + case Iris: + return 3; + case VoicePrint: + return 4; + default: + return -1; + } +} + QString DeviceType::getDeviceType_tr(int deviceType) { switch(deviceType) @@ -48,6 +66,8 @@ QString DeviceType::getDeviceType_tr(int deviceType) return tr("Face"); case VoicePrint: return tr("VoicePrint"); + case LOGINOPT_TYPE_GENERAL_UKEY: + return tr("ukey"); case REMOTE_QRCODE_TYPE: return tr("QRCode"); default: @@ -107,10 +127,33 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, DeviceInfo &deviceInf return arg; } +/* For the type FeatureInfo */ +QDBusArgument &operator<<(QDBusArgument &argument, const FeatureInfo &featureInfo) +{ + argument.beginStructure(); + argument << featureInfo.uid << featureInfo.biotype + << featureInfo.device_shortname << featureInfo.index + << featureInfo.index_name; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, FeatureInfo &featureInfo) +{ + argument.beginStructure(); + argument >> featureInfo.uid >> featureInfo.biotype + >> featureInfo.device_shortname >> featureInfo.index + >> featureInfo.index_name; + argument.endStructure(); + return argument; +} + void registerMetaType() { qRegisterMetaType("DeviceInfo"); qDBusRegisterMetaType(); + qRegisterMetaType("FeatureInfo"); + qDBusRegisterMetaType(); } diff --git a/BiometricAuth/biometricdeviceinfo.h b/BiometricAuth/biometricdeviceinfo.h index c9604be..e5a4e64 100644 --- a/BiometricAuth/biometricdeviceinfo.h +++ b/BiometricAuth/biometricdeviceinfo.h @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef BIOMETRICDEVICEINFO_H #define BIOMETRICDEVICEINFO_H @@ -69,6 +68,8 @@ public: * @return */ static QString getDeviceType_tr(int deviceType); + //根据设备优先级获取设备类型 + static int getBioType(int bioType); }; /** @@ -210,20 +211,35 @@ struct DeviceInfo int OpsStatus; }; + +struct FeatureInfo { + int uid; + int biotype; + QString device_shortname; + int index; + QString index_name; +}; + class QDBusArgument; QDBusArgument &operator <<(QDBusArgument &arg, const DeviceInfo &deviceInfo); const QDBusArgument &operator >>(const QDBusArgument &arg, DeviceInfo &deviceInfo); +QDBusArgument &operator<<(QDBusArgument &argument, const FeatureInfo &featureInfo); +const QDBusArgument &operator>>(const QDBusArgument &argument, FeatureInfo &featureInfo); void registerMetaType(); typedef std::shared_ptr DeviceInfoPtr; typedef QList DeviceList; typedef QMap DeviceMap; +typedef std::shared_ptr FeatureInfoPtr; +typedef QList FeatureList; +typedef QMap FeatureMap; QDebug operator <<(QDebug stream, const DeviceInfo &deviceInfo); Q_DECLARE_METATYPE(DeviceInfo) +Q_DECLARE_METATYPE(FeatureInfo) /** * @brief 获取默认设备 @@ -264,6 +280,8 @@ enum LOGINOPT_TYPE { LOGINOPT_TYPE_IRIS, // 虹膜 LOGINOPT_TYPE_VOICEPRINT, // 声纹 LOGINOPT_TYPE_FINGERVEIN, // 指静脉 + LOGINOPT_TYPE_GENERAL_UKEY, // 普通的ukey + LOGINOPT_TYPE_ADVANCED_UKEY, // 高阶的ukey LOGINOPT_TYPE_QRCODE, // 二维码 LOGINOPT_TYPE_OTHERS, // 其他 LOGINOPT_TYPE_COUNT diff --git a/BiometricAuth/biometricdeviceswidget.cpp b/BiometricAuth/biometricdeviceswidget.cpp index 856b750..0766ae3 100644 --- a/BiometricAuth/biometricdeviceswidget.cpp +++ b/BiometricAuth/biometricdeviceswidget.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "biometricdeviceswidget.h" #include diff --git a/BiometricAuth/biometricdeviceswidget.h b/BiometricAuth/biometricdeviceswidget.h index d606aef..bdef3da 100644 --- a/BiometricAuth/biometricdeviceswidget.h +++ b/BiometricAuth/biometricdeviceswidget.h @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef BIOMETRICDEVICESWIDGET_H #define BIOMETRICDEVICESWIDGET_H diff --git a/BiometricAuth/biometricproxy.cpp b/BiometricAuth/biometricproxy.cpp index 85637a4..9f2513e 100644 --- a/BiometricAuth/biometricproxy.cpp +++ b/BiometricAuth/biometricproxy.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,12 +12,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "biometricproxy.h" #include +#include BiometricProxy::BiometricProxy(QObject *parent) : QDBusAbstractInterface(BIOMETRIC_DBUS_SERVICE, @@ -37,6 +37,41 @@ QDBusPendingCall BiometricProxy::Identify(int drvid, int uid, int indexStart, in return asyncCallWithArgumentList(QStringLiteral("Identify"), argList); } +QDBusPendingCall BiometricProxy::UkeyIdentify(int drvid, int type, int uid) +{ + QList argList; + argList << drvid << type << uid; + return asyncCallWithArgumentList(QStringLiteral("UkeyIdentify"), argList); +} + +bool BiometricProxy::GetHasUkeyFeature(int uid, int indexStart, int indexEnd) +{ + QList qlist; + FeatureInfo *featureInfo; + int listsize; + QDBusMessage result = call(QStringLiteral("GetAllFeatureList"),uid,indexStart,indexEnd); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return false; + } + QList variantList = result.arguments(); + listsize = variantList[0].value(); + variantList[1].value() >> qlist; + for (int i = 0; i < listsize; i++) { + featureInfo = new FeatureInfo; + qlist[i].variant().value() >> *featureInfo; + if(featureInfo->biotype == LOGINOPT_TYPE_GENERAL_UKEY){ + delete featureInfo; + return true; + } + delete featureInfo; + } + + return false; + +} + int BiometricProxy::GetFeatureCount(int uid, int indexStart, int indexEnd) { QDBusMessage result = call(QStringLiteral("GetDevList")); @@ -68,6 +103,17 @@ int BiometricProxy::GetFeatureCount(int uid, int indexStart, int indexEnd) return res; } +int BiometricProxy::SetExtraInfo(QString info_type,QString extra_info) +{ + QDBusReply reply = call(QStringLiteral("SetExtraInfo"), info_type, extra_info); + if(!reply.isValid()) + { + qWarning() << "SetExtraInfo error:" << reply.error(); + return -1; + } + return reply.value(); +} + int BiometricProxy::StopOps(int drvid, int waiting) { QDBusReply reply = call(QStringLiteral("StopOps"), drvid, waiting); @@ -145,6 +191,28 @@ DeviceList BiometricProxy::GetDevList() return deviceList; } +FeatureMap BiometricProxy::GetUserFeatures(int uid) +{ + FeatureMap featureMap; + QList qlist; + int listsize; + QDBusMessage result = call(QStringLiteral("GetAllFeatureList"), uid, 0, -1); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return featureMap; + } + QList variantList = result.arguments(); + listsize = variantList[0].value(); + variantList[1].value() >> qlist; + for (int i = 0; i < listsize; i++) { + FeatureInfoPtr pFeatureInfo = std::make_shared(); + qlist[i].variant().value() >> *pFeatureInfo; + featureMap[pFeatureInfo->device_shortname].append(pFeatureInfo); + } + return featureMap; +} + int BiometricProxy::GetDevCount() { QDBusMessage result = call(QStringLiteral("GetDevList")); diff --git a/BiometricAuth/biometricproxy.h b/BiometricAuth/biometricproxy.h index ac03881..5395ed7 100644 --- a/BiometricAuth/biometricproxy.h +++ b/BiometricAuth/biometricproxy.h @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef BIOMETRICPROXY_H #define BIOMETRICPROXY_H @@ -65,6 +64,21 @@ public Q_SLOTS: * @return 结果: (结果,用户id) */ QDBusPendingCall Identify(int drvid, int uid, int indexStart = 0, int indexEnd = -1); + /** + * @brief 使用指定id的设备进行用户认证 + * @param drvid 驱动(设备)id + * @param type ukey的认证类型,2表示pin认证(需通过setExtraInfo设置pin码,3表示指纹认证) + * @param uid 用户id + * @return 结果: (结果,用户id) + */ + QDBusPendingCall UkeyIdentify(int drvid, int type, int uid); + /** + * @brief 设置一些认证时所需的额外的信息 + * @param info_type 额外的信息类型,ukey pincode认证时传 "pincode" + * @param extra_info 额外的信息内容,ukey pincode认证时传PIN码内容 + * @return 结果: (设置额外信息的结果) + */ + int SetExtraInfo(QString info_type, QString extra_info); /** * @brief 终止设备上正在进行的操作 * @param drvid 设备id @@ -80,6 +94,14 @@ public Q_SLOTS: * @return */ int GetFeatureCount(int uid, int indexStart = 0, int indexEnd = -1); + /** + * @brief 获取当前用户已连接设备对应特征数目 + * @param uid 用户id + * @param indexStart 用于认证的特征索引范围 + * @param indexEnd + * @return 返回是否存在ukey特征 + */ + bool GetHasUkeyFeature(int uid, int indexStart = 0, int indexEnd = -1); /** * @brief 获取已连接的设备列表 * @return @@ -117,7 +139,12 @@ public Q_SLOTS: StatusReslut UpdateStatus(int drvid); int GetUserDevCount(int uid); int GetUserDevFeatureCount(int uid,int drvid); - + /** + * @brief GetUserFeatures 获取用户所有特征 + * @param uid 用户id + * @return 特征信息列表 + */ + FeatureMap GetUserFeatures(int uid); Q_SIGNALS: /** diff --git a/BiometricAuth/giodbus.cpp b/BiometricAuth/giodbus.cpp index 737c101..02a362b 100644 --- a/BiometricAuth/giodbus.cpp +++ b/BiometricAuth/giodbus.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "giodbus.h" #include #include diff --git a/BiometricAuth/giodbus.h b/BiometricAuth/giodbus.h index 13e0880..a75f989 100644 --- a/BiometricAuth/giodbus.h +++ b/BiometricAuth/giodbus.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef GIODBUS_H #define GIODBUS_H diff --git a/BiometricAuth/main.cpp b/BiometricAuth/main.cpp index 6215ae1..cd780b5 100644 --- a/BiometricAuth/main.cpp +++ b/BiometricAuth/main.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include #include diff --git a/BiometricAuth/uniauthservice.cpp b/BiometricAuth/uniauthservice.cpp new file mode 100644 index 0000000..4f327af --- /dev/null +++ b/BiometricAuth/uniauthservice.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "uniauthservice.h" +#include +#include + +#define UNIAUTH_DBUS_SERVICE "org.ukui.UniauthBackend" +#define UNIAUTH_DBUS_PATH "/org/ukui/UniauthBackend" +#define UNIAUTH_DBUS_INTERFACE "org.ukui.UniauthBackend" + +#define FD_DBUS_SERVICE "org.freedesktop.DBus" +#define FD_DBUS_PATH "/org/freedesktop/DBus" +#define FD_DBUS_INTERFACE "org.freedesktop.DBus" + +UniAuthService::UniAuthService(QObject *parent) + : QDBusAbstractInterface(UNIAUTH_DBUS_SERVICE, + UNIAUTH_DBUS_PATH, + UNIAUTH_DBUS_INTERFACE, + QDBusConnection::systemBus(), + parent) + , m_isActivatable(false) +{ + setTimeout(2147483647); + QDBusInterface *dbusService = new QDBusInterface(FD_DBUS_SERVICE, + FD_DBUS_PATH, + FD_DBUS_INTERFACE, + QDBusConnection::systemBus()); + if (dbusService) { + QDBusReply result = dbusService->call(QStringLiteral("ListActivatableNames")); + if(!result.isValid()) { + qWarning() << "ListActivatableNames error:" << result.error().message(); + } else { + QStringList listNames = result.value(); + if (listNames.contains(UNIAUTH_DBUS_INTERFACE)) { + m_isActivatable = true; + } + } + } +} + +// 设置默认设备 +void UniAuthService::setDefaultDevice(int bioDevType, QString deviceName) +{ + qDebug() << " bioType : " << bioDevType << "deviceName : " << deviceName; + QDBusMessage result = call(QStringLiteral("setDefaultDevice"), bioDevType, deviceName); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "setDefaultDevice error:" << result.errorMessage(); + return ; + } + return ; +} + +// 获取默认设备 +QString UniAuthService::getDefaultDevice(QString userName, int bioDevType) +{ + QDBusMessage result = call(QStringLiteral("getDefaultDevice"), userName, bioDevType); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getDefaultDevice error:" << result.errorMessage(); + return ""; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + QString strDefDevice = varResult.takeFirst().toString(); + return strDefDevice; + } else { + return ""; + } +} + +// 获取所有默认设备 +QStringList UniAuthService::getAllDefaultDevice(QString userName) +{ + QStringList listDefDevices; + QDBusReply result = call(QStringLiteral("getAllDefaultDevice"), userName); + if(!result.isValid()) { + qWarning() << "getAllDefaultDevice error:" << result.error().message(); + } else { + listDefDevices = result.value(); + } + return listDefDevices; +} + +//生物特征开关接口 +bool UniAuthService::getBioAuthStatus(QString userName, int bioAuthType) +{ + QDBusMessage bioResult = call(QStringLiteral("getBioAuthStatus"), userName, bioAuthType); + if(bioResult.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getBioStatus error:" << bioResult.errorMessage(); + return false; + } + QList varResult = bioResult.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +void UniAuthService::setBioAuthStatus(int bioAuthType, bool status) +{ + qDebug() << "setBioAuthStatus bioAuthType : " << bioAuthType << "status : " << status; + QDBusMessage result = call(QStringLiteral("setBioAuthStatus"), bioAuthType, status); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "setBioAuthStatus error:" << result.errorMessage(); + return ; + } + return ; +} + +// 获取最大失败次数 +int UniAuthService::getMaxFailedTimes() +{ + QDBusMessage result = call(QStringLiteral("getMaxFailedTimes")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getMaxFailedTimes error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toInt(); + } else { + return 3; + } +} + +// 获取是否使能微信扫码登录 +bool UniAuthService::getQRCodeEnable() +{ + QDBusMessage result = call(QStringLiteral("getQRCodeEnable")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getQRCodeEnable error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +// 获取是否双认证 +bool UniAuthService::getDoubleAuth() +{ + QDBusMessage result = call(QStringLiteral("getDoubleAuth")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getDoubleAuth error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +// 获取用户绑定 +bool UniAuthService::getUserBind() +{ + QDBusMessage result = call(QStringLiteral("getUserBind")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getUserBind error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +// 获取是否在控制面板显示 +bool UniAuthService::getIsShownInControlCenter() +{ + QDBusMessage result = call(QStringLiteral("getIsShownInControlCenter")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getIsShownInControlCenter error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +// 获取是否使用第一个设备 +bool UniAuthService::getUseFirstDevice() +{ + QDBusMessage result = call(QStringLiteral("getUseFirstDevice")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getUseFirstDevice error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +// 获取是否隐藏切换按钮 +bool UniAuthService::getHiddenSwitchButton() +{ + QDBusMessage result = call(QStringLiteral("getHiddenSwitchButton")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getHiddenSwitchButton error:" << result.errorMessage(); + return false; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toBool(); + } else { + return false; + } +} + +bool UniAuthService::isActivatable() +{ + return m_isActivatable; +} diff --git a/BiometricAuth/uniauthservice.h b/BiometricAuth/uniauthservice.h new file mode 100644 index 0000000..9bbe5b4 --- /dev/null +++ b/BiometricAuth/uniauthservice.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef UNIAUTH_SERVICE_H +#define UNIAUTH_SERVICE_H + +#include +#include + +enum authEnableType { + ENABLETYPE_BIO, // 全局总使能 + ENABLETYPE_SAVER, // 锁屏 + ENABLETYPE_GREETER, // 登录 + ENABLETYPE_POLKIT, // 授权 + ENABLETYPE_SU, // 暂保留 + ENABLETYPE_SUDO, // 暂保留 + ENABLETYPE_LOGIN, // 暂保留 +}; + +class UniAuthService : public QDBusAbstractInterface +{ + Q_OBJECT +public: + explicit UniAuthService(QObject *parent = nullptr); + +public Q_SLOTS: + // 设置默认设备 + void setDefaultDevice(int bioDevType, QString deviceName); + // 获取默认设备 + QString getDefaultDevice(QString userName, int bioDevType); + // 获取所有默认设备 + QStringList getAllDefaultDevice(QString userName); + //生物特征开关接口 + bool getBioAuthStatus(QString userName, int bioAuthType); + void setBioAuthStatus(int bioAuthType, bool status); + // 获取最大失败次数 + int getMaxFailedTimes(); + // 获取是否使能微信扫码登录 + bool getQRCodeEnable(); + // 获取是否双认证 + bool getDoubleAuth(); + // 获取用户绑定 + bool getUserBind(); + // 获取是否在控制面板显示 + bool getIsShownInControlCenter(); + // 获取是否使用第一个设备 + bool getUseFirstDevice(); + // 获取是否隐藏切换按钮 + bool getHiddenSwitchButton(); + +public: + bool isActivatable(); + +Q_SIGNALS: + //默认设备改变 + void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName); + //开关状态改变 + void bioAuthStatusChanged(QString userName, int type, bool status); + +private: + bool m_isActivatable; +}; + +#endif // UNIAUTH_SERVICE_H diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e63621..2a8cc61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,14 @@ find_package(Qt5 COMPONENTS Core Widgets DBus X11Extras Xml Network Svg) find_package(PkgConfig REQUIRED) find_package(OpenCV REQUIRED) find_package(PkgConfig) +find_package(KF5Screen REQUIRED) +find_package(KF5Wayland REQUIRED) +find_package(LayerShellQt REQUIRED) + pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) +pkg_check_modules(kylin-nm-base REQUIRED kylin-nm-base) +pkg_check_modules(KScreen REQUIRED kscreen2) # 是否是intel项目 option (USE_INTEL "intel项目" OFF) @@ -63,5 +69,5 @@ add_subdirectory(screensaver-focus-helper) add_subdirectory(Common) add_subdirectory(KylinNM) -add_dependencies(ukui-screensaver-dialog BiometricAuth VirtualKeyboard Common) +add_dependencies(ukui-screensaver-dialog BiometricAuth VirtualKeyboard Common Screensaver) add_dependencies(ukui-screensaver-default Common) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index 5390d95..1f4d3b7 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -1,7 +1,21 @@ +pkg_check_modules(GLIB REQUIRED glib-2.0) +find_package(X11 REQUIRED) +find_package(KF5WindowSystem) + +include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} + ${GLIB2_INCLUDE_DIRS} + ${KF5Wayland_LIBRARIES} + ) + qt5_wrap_cpp(Common_SRC autoresize.h checkbutton.h commonfunc.h + glibinterface.h + plasma-shell-manager.h ) set(Common_SRC @@ -9,14 +23,9 @@ set(Common_SRC autoresize.cpp checkbutton.cpp commonfunc.cpp + glibinterface.cpp + plasma-shell-manager.cpp ) -include_directories( - ${Qt5Core_INCLUDE_DIRS} - ${Qt5Widgets_INCLUDE_DIRS} - ${Qt5DBus_INCLUDE_DIRS} - ) - - add_library(Common STATIC ${Common_SRC}) -target_link_libraries(Common Qt5::Core Qt5::DBus Qt5::Widgets) +target_link_libraries(Common Qt5::Core Qt5::DBus Qt5::Widgets Qt5::X11Extras ${GIOUNIX2_LIBRARIES} ${KF5Wayland_LIBRARIES} -lKF5WaylandClient -lKF5WaylandServer KF5::WindowSystem) diff --git a/Common/checkbutton.cpp b/Common/checkbutton.cpp index 14ae327..9962a15 100644 --- a/Common/checkbutton.cpp +++ b/Common/checkbutton.cpp @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #include "checkbutton.h" diff --git a/Common/checkbutton.h b/Common/checkbutton.h index d6167c9..59f3463 100644 --- a/Common/checkbutton.h +++ b/Common/checkbutton.h @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #ifndef CHECKBUTTON_H #define CHECKBUTTON_H diff --git a/Common/commonfunc.cpp b/Common/commonfunc.cpp index 150bd5c..e9aacce 100644 --- a/Common/commonfunc.cpp +++ b/Common/commonfunc.cpp @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,14 +12,15 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #include #include #include +#include +#include #include #include #include "commonfunc.h" @@ -75,3 +75,36 @@ QString ElideText(QFont font,int width,QString strInfo) return strInfo; } +/*修改图片缩放机制,图片长宽不一致时,先取图片中央的部分*/ +QPixmap scaledPixmap(QPixmap src) +{ + QPixmap rectPixmap; + if (src.width() > src.height()) { + QPixmap iconPixmap = src.copy((src.width() - src.height())/2, 0, src.height(), src.height()); + // 根据label高度等比例缩放图片 + rectPixmap = iconPixmap.scaledToHeight(src.height()); + } else { + QPixmap iconPixmap = src.copy(0, (src.height() - src.width())/2, src.width(), src.width()); + // 根据label宽度等比例缩放图片 + rectPixmap = iconPixmap.scaledToWidth(src.width()); + } + return rectPixmap; +} + +QPixmap PixmapToRound(const QPixmap &src, int radius) +{ + if (src.isNull()) { + return QPixmap(); + } + + QPixmap pixmapa(src); + QPixmap pixmap(radius*2,radius*2); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + QPainterPath path; + path.addEllipse(0, 0, radius*2, radius*2); + painter.setClipPath(path); + painter.drawPixmap(0, 0, radius*2, radius*2, pixmapa); + return pixmap; +} diff --git a/Common/commonfunc.h b/Common/commonfunc.h index 3e23bb3..d028bdd 100644 --- a/Common/commonfunc.h +++ b/Common/commonfunc.h @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,22 +12,26 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #ifndef COMMONFUNC_H #define COMMONFUNC_H #include #include +#include + +#define G_FONT_SIZE (11.0) bool ispicture(QString filepath); QString getSystemVersion(); QString getSystemDistrib(); bool getUseFirstDevice(); QString ElideText(QFont font,int width,QString strInfo); +QPixmap scaledPixmap(QPixmap src); +QPixmap PixmapToRound(const QPixmap &src, int radius); class commonFunc { diff --git a/Common/glibinterface.cpp b/Common/glibinterface.cpp new file mode 100644 index 0000000..66c26bc --- /dev/null +++ b/Common/glibinterface.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "glibinterface.h" +#include +#include + +#define STYLE_TYPE_SCHEMA "org.ukui.style" +#define KEY_SYSTEM_FONT_SIZE "system-font-size" +#define DEFAULT_FONT_SIZE (10.0) + +double getDefaultFontSize() +{ + GSettingsSchemaSource *schema_source = NULL; + GSettingsSchema *schema = NULL; + + schema_source = g_settings_schema_source_get_default(); + if(schema_source){ + schema = g_settings_schema_source_lookup (schema_source,KEY_SYSTEM_FONT_SIZE,TRUE); + if(schema){ + GVariant *size; + unsigned long length; + GSettings *gs; + + gs = g_settings_new(STYLE_TYPE_SCHEMA); + size = g_settings_get_default_value(gs, KEY_SYSTEM_FONT_SIZE); + QString fontsize(g_variant_get_string(size,&length)); + g_object_unref(gs); + + return fontsize.toDouble(); + } + } + return DEFAULT_FONT_SIZE; +} diff --git a/Common/glibinterface.h b/Common/glibinterface.h new file mode 100644 index 0000000..3b3c018 --- /dev/null +++ b/Common/glibinterface.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef GLIBINTERFACE_H +#define GLIBINTERFACE_H + +double getDefaultFontSize(); + +#endif // LOCKWIDGET_H + diff --git a/Common/plasma-shell-manager.cpp b/Common/plasma-shell-manager.cpp new file mode 100644 index 0000000..e8336b4 --- /dev/null +++ b/Common/plasma-shell-manager.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "plasma-shell-manager.h" + +#include +#include + +#include +#include + +#include +#include +#include + +static PlasmaShellManager* global_instance = nullptr; + +PlasmaShellManager *PlasmaShellManager::getInstance() +{ + if(QString(qgetenv("XDG_SESSION_TYPE")) != "wayland" || QX11Info::isPlatformX11()){ + return nullptr; + } + if (!global_instance) + { + global_instance = new PlasmaShellManager; + qDebug() << "Here create instance..."; + } + qDebug() << "Return instance"; + return global_instance; +} + +bool PlasmaShellManager::setAppWindowActive() +{ + if (!supportPlasmaWindowManagement()) + return false; + + m_appWindow->requestActivate(); + return true; +} + +bool PlasmaShellManager::setAppWindowKeepAbove(bool keep) +{ + if (!supportPlasmaWindowManagement()) + { + qDebug() << "false"; + return false; + } + if(keep != m_appWindow->isKeepAbove()) { + qDebug() << "to keep above"; + m_appWindow->requestToggleKeepAbove(); + } + return true; +} + +bool PlasmaShellManager::setMaximized(QWindow *window) +{ + if (!supportShell()) + return false; + + auto surface = KWayland::Client::Surface::fromWindow(window); + if (!surface) + return false; + + auto shellSurface = m_shell->createSurface(surface, window); + if (!shellSurface) + return false; + + shellSurface->setMaximized(); + return true; +} + +bool PlasmaShellManager::setRole(QWindow *window, KWayland::Client::PlasmaShellSurface::Role role) +{ + if (!supportPlasmaShell()) + return false; + + auto surface = KWayland::Client::Surface::fromWindow(window); + if (!surface) + return false; + + auto plasmaShellSurface = m_plasmaShell->createSurface(surface, window); + if (!plasmaShellSurface) + return false; + + plasmaShellSurface->setRole(role); + return true; +} + +bool PlasmaShellManager::setPos(QWindow *window, const QPoint &pos) +{ + if (!supportPlasmaShell()) + return false; + + auto surface = KWayland::Client::Surface::fromWindow(window); + if (!surface) + return false; + + auto plasmaShellSurface = m_plasmaShell->createSurface(surface, window); + if (!plasmaShellSurface) + return false; + + plasmaShellSurface->setPosition(pos); + + return true; +} + +bool PlasmaShellManager::supportPlasmaShell() +{ + return m_plasmaShell; +} + +bool PlasmaShellManager::supportShell() +{ + return m_shell; +} + +bool PlasmaShellManager::supportPlasmaWindowManagement() +{ + return m_windowManager && m_appWindow; +} + +bool PlasmaShellManager::supportFakeInput() +{ + return m_fakeInput; +} + +bool PlasmaShellManager::supportKeyState() +{ + return m_keyState; +} + +KWayland::Client::Keystate::State PlasmaShellManager::getKeyState(KWayland::Client::Keystate::Key key) +{ + if(!supportKeyState()){ + return KWayland::Client::Keystate::Unlocked; + } + + return m_keyStateMap[key]; +} + +void PlasmaShellManager::setKeyPressed(quint32 key) +{ + if(!supportFakeInput()) + return ; + + m_fakeInput->requestKeyboardKeyPress(key); + m_fakeInput->requestKeyboardKeyRelease(key); +} + +PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) +{ + m_keyStateMap.insert(KWayland::Client::Keystate::Key::CapsLock,KWayland::Client::Keystate::Unlocked); + m_keyStateMap.insert(KWayland::Client::Keystate::Key::NumLock,KWayland::Client::Keystate::Unlocked); + m_keyStateMap.insert(KWayland::Client::Keystate::Key::ScrollLock,KWayland::Client::Keystate::Unlocked); + + auto connection = KWayland::Client::ConnectionThread::fromApplication(qApp); + auto registry = new KWayland::Client::Registry(this); + registry->create(connection->display()); + + connect(registry, &KWayland::Client::Registry::plasmaShellAnnounced, this, [=](){ + qDebug() << "plasmaShellAnnounced..."; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); + if (interface.name != 0) { + qDebug() << "createPlasmaShell..."; + m_plasmaShell = registry->createPlasmaShell(interface.name, interface.version, this); + } + }); + + connect(registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced, this, [=](){ + qDebug() << "plasmaWindowManagementAnnounced"; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaWindowManagement); + if (interface.name != 0) { + qDebug() << "createPlasmaWindowManagement"; + m_windowManager = registry->createPlasmaWindowManagement(interface.name, interface.version, this); + } + if(m_windowManager) { + connect(m_windowManager, &KWayland::Client::PlasmaWindowManagement::windowCreated, + [this](KWayland::Client::PlasmaWindow *window) { + qDebug()<< "PlasmaWindow..."; + if (window->pid() == getpid()) { + if(isFirstCreate) { + isFirstCreate = false; + m_appWindow = window; + + connect(m_appWindow, &KWayland::Client::PlasmaWindow::activeChanged, + [this]() { + this->setAppWindowKeepAbove(true); + this->setAppWindowActive(); + }); + connect(m_appWindow, &KWayland::Client::PlasmaWindow::keepAboveChanged, + [this]() { + this->setAppWindowKeepAbove(true); + this->setAppWindowActive(); + }); + } + } + }); + } + }); + + connect(registry, &KWayland::Client::Registry::shellAnnounced, this, [=](){ + const auto interface = registry->interface(KWayland::Client::Registry::Interface::Shell); + if (interface.name != 0) { + m_shell = registry->createShell(interface.name, interface.version, this); + } + }); + + connect(registry, &KWayland::Client::Registry::fakeInputAnnounced, this, [=](){ + qDebug()<<"fakeInputAnnounced"; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::FakeInput); + if (interface.name != 0) { + qDebug()<<"createFakeInput"; + m_fakeInput = registry->createFakeInput(interface.name, interface.version); + m_fakeInput->authenticate("ukui-screensaver-dialog","virual keyboard"); + } + }); + + connect(registry, &KWayland::Client::Registry::keystateAnnounced, this, [=](){ + qDebug()<<"keystateAnnounced"; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::Keystate); + if (interface.name != 0) { + qDebug()<<"createKeyState"; + m_keyState = registry->createKeystate(interface.name, interface.version); + if(m_keyState){ + connect(m_keyState, &KWayland::Client::Keystate::stateChanged, + [this](KWayland::Client::Keystate::Key key,KWayland::Client::Keystate::State state) { + qDebug()<<"key = "<fetchStates(); + } + } + }); + + registry->setup(); + connection->roundtrip(); +} diff --git a/Common/plasma-shell-manager.h b/Common/plasma-shell-manager.h new file mode 100644 index 0000000..e5e0230 --- /dev/null +++ b/Common/plasma-shell-manager.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#ifndef PLASMASHELLMANAGER_H +#define PLASMASHELLMANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class PlasmaShellManager : public QObject +{ + Q_OBJECT +public: + static PlasmaShellManager *getInstance(); + + bool setAppWindowActive(); + bool setAppWindowKeepAbove(bool keep); + bool setMaximized(QWindow *window); + bool setRole(QWindow *window, KWayland::Client::PlasmaShellSurface::Role role); + bool setPos(QWindow *window, const QPoint &pos); + void setKeyPressed(quint32 key); + + bool supportPlasmaShell(); + bool supportShell(); + bool supportPlasmaWindowManagement(); + bool supportFakeInput(); + bool supportKeyState(); + KWayland::Client::Keystate::State getKeyState(KWayland::Client::Keystate::Key key); +Q_SIGNALS: + void keyStateChanged(); + +private: + explicit PlasmaShellManager(QObject *parent = nullptr); + + KWayland::Client::PlasmaShell *m_plasmaShell = nullptr; + KWayland::Client::Shell *m_shell = nullptr; + KWayland::Client::PlasmaWindowManagement *m_windowManager = nullptr; + KWayland::Client::PlasmaWindow *m_appWindow = nullptr; + KWayland::Client::FakeInput *m_fakeInput = nullptr; + KWayland::Client::Keystate *m_keyState = nullptr; + + bool isFirstCreate = true; + + QMap m_keyStateMap; + +}; + + +#endif // PLASMASHELLMANAGER_H diff --git a/KylinNM/src/backthread.cpp b/KylinNM/src/backthread.cpp index 5747fc8..d115d26 100644 --- a/KylinNM/src/backthread.cpp +++ b/KylinNM/src/backthread.cpp @@ -33,16 +33,13 @@ BackThread::BackThread(QObject *parent) : QObject(parent) { - cmdConnWifi = new QProcess(this); - connect(cmdConnWifi , SIGNAL(readyReadStandardOutput()) , this , SLOT(on_readoutput())); - connect(cmdConnWifi , SIGNAL(readyReadStandardError()) , this , SLOT(on_readerror())); - cmdConnWifi->start("bash"); - cmdConnWifi->waitForStarted(); } BackThread::~BackThread() { - cmdConnWifi->close(); + if (cmdConnWifi) { + cmdConnWifi->close(); + } } //get the connection state of wired and wireles network @@ -278,7 +275,13 @@ void BackThread::execConnWifiPWD(QString connName, QString password) void BackThread::execConnWifi(QString connName) { //disConnLanOrWifi("wifi"); - + if (!cmdConnWifi) { + cmdConnWifi = new QProcess(this); + connect(cmdConnWifi , SIGNAL(readyReadStandardOutput()) , this , SLOT(on_readoutput())); + connect(cmdConnWifi , SIGNAL(readyReadStandardError()) , this , SLOT(on_readerror())); + cmdConnWifi->start("bash"); + cmdConnWifi->waitForStarted(); + } QString cmdStr = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection up \"" + connName.replace("\"","\\\"") + "\"\n"; cmdConnWifi->write(cmdStr.toUtf8().data()); } diff --git a/KylinNM/src/kylinnm.cpp b/KylinNM/src/kylinnm.cpp index 3446f2e..d17fd83 100644 --- a/KylinNM/src/kylinnm.cpp +++ b/KylinNM/src/kylinnm.cpp @@ -2470,6 +2470,7 @@ void KylinNM::enWifiDone() qDebug()<<"debug: already turn on the switch of wifi network"; syslog(LOG_DEBUG, "Already turn on the switch of wifi network"); + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); } void KylinNM::disWifiDone() { diff --git a/KylinNM/src/swipegesturerecognizer.cpp b/KylinNM/src/swipegesturerecognizer.cpp index 87b553c..dd888c3 100644 --- a/KylinNM/src/swipegesturerecognizer.cpp +++ b/KylinNM/src/swipegesturerecognizer.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include #include diff --git a/KylinNM/src/swipegesturerecognizer.h b/KylinNM/src/swipegesturerecognizer.h index 2e51665..4b6c7b8 100644 --- a/KylinNM/src/swipegesturerecognizer.h +++ b/KylinNM/src/swipegesturerecognizer.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef SWIPEGESTURERECOGNIZER_H #define SWIPEGESTURERECOGNIZER_H diff --git a/KylinNM/src/switchbutton.cpp b/KylinNM/src/switchbutton.cpp index 714e249..43ad098 100644 --- a/KylinNM/src/switchbutton.cpp +++ b/KylinNM/src/switchbutton.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "switchbutton.h" SwitchButton::SwitchButton(QWidget *parent) : QWidget(parent) diff --git a/KylinNM/src/switchbutton.h b/KylinNM/src/switchbutton.h index 7c0f1e5..8c86bc2 100644 --- a/KylinNM/src/switchbutton.h +++ b/KylinNM/src/switchbutton.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef SWITCHBUTTON_H #define SWITCHBUTTON_H diff --git a/VirtualKeyboard/CMakeLists.txt b/VirtualKeyboard/CMakeLists.txt index f9d52c7..aa1ddf2 100644 --- a/VirtualKeyboard/CMakeLists.txt +++ b/VirtualKeyboard/CMakeLists.txt @@ -4,21 +4,33 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) +include_directories(${PROJECT_SOURCE_DIR}/Common) + qt5_add_resources(VirtualKeyboard_SRC src/keyboard.qrc) +qt5_wrap_cpp(VirtualKeyboard_SRC + src/fakekeyboard.h + ) + set(VirtualKeyboard_SRC ${VirtualKeyboard_SRC} - src/cursormonitor.cpp - src/keyboardwidget.cpp - src/virtualkeyboard.cpp - src/x11keyboard.cpp - src/keyboard.qrc) + src/charsmorewidget.cpp + src/charswidget.cpp + src/dragwidget.cpp + src/kbbutton.cpp + src/kbtitle.cpp + src/letterswidget.cpp + src/numberswidget.cpp + src/virtualkeyboardwidget.cpp + src/x11keyboard.cpp + src/qtkeyboard.cpp + ) include_directories( ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} - ) + ) add_library(VirtualKeyboard STATIC ${VirtualKeyboard_SRC}) -target_link_libraries(VirtualKeyboard Qt5::Core Qt5::Widgets) +target_link_libraries(VirtualKeyboard Qt5::Core Qt5::Widgets Qt5::X11Extras Common) diff --git a/VirtualKeyboard/VirtualKeyboard.pri b/VirtualKeyboard/VirtualKeyboard.pri index e8029dc..79c43c4 100644 --- a/VirtualKeyboard/VirtualKeyboard.pri +++ b/VirtualKeyboard/VirtualKeyboard.pri @@ -1,18 +1,26 @@ SOURCES += \ - $$PWD/src/keyboardwidget.cpp \ - $$PWD/src/x11keyboard.cpp \ - $$PWD/src/cursormonitor.cpp \ - $$PWD/src/virtualkeyboard.cpp + $$PWD/src/charsmorewidget.cpp \ + $$PWD/src/charswidget.cpp \ + $$PWD/src/dragwidget.cpp \ + $$PWD/src/kbbutton.cpp \ + $$PWD/src/kbtitle.cpp \ + $$PWD/src/letterswidget.cpp \ + $$PWD/src/numberswidget.cpp \ + $$PWD/src/virtualkeyboardwidget.cpp \ + $$PWD/src/x11keyboard.cpp HEADERS += \ - $$PWD/src/keyboardwidget.h \ - $$PWD/src/x11keyboard.h \ - $$PWD/src/cursormonitor.h \ - $$PWD/src/virtualkeyboard.h - -FORMS += \ - $$PWD/src/keyboardwidget.ui + $$PWD/src/charsmorewidget.h \ + $$PWD/src/charswidget.h \ + $$PWD/src/commondef.h \ + $$PWD/src/dragwidget.h \ + $$PWD/src/kbbutton.h \ + $$PWD/src/kbtitle.h \ + $$PWD/src/letterswidget.h \ + $$PWD/src/numberswidget.h \ + $$PWD/src/virtualkeyboardwidget.h \ + $$PWD/src/x11keyboard.h RESOURCES += \ diff --git a/VirtualKeyboard/src/charsmorewidget.cpp b/VirtualKeyboard/src/charsmorewidget.cpp new file mode 100644 index 0000000..01cc10f --- /dev/null +++ b/VirtualKeyboard/src/charsmorewidget.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "charsmorewidget.h" +#include "commondef.h" + +#include +#include +#include +#include +#include +#include + +CharsMoreWidget::CharsMoreWidget(QWidget *parent/* = nullptr*/) + : QWidget(parent) +{ + this->setAttribute(Qt::WA_TranslucentBackground);//背景透明 + setWindowFlags(Qt::FramelessWindowHint | + Qt::WindowStaysOnTopHint | + Qt::WindowDoesNotAcceptFocus); + initUI(); +} + +CharsMoreWidget::~CharsMoreWidget() +{ + +} + +void CharsMoreWidget::adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical/* = false*/, bool floatStatus) +{ + QMap::iterator itGeometry = m_mapBtnGeometrys.begin(); + for (; itGeometry != m_mapBtnGeometrys.end(); itGeometry ++) { + QWidget *widget = itGeometry.key(); + if (widget) { + QRect oldGeometry = itGeometry.value(); + QRect newGeometry = oldGeometry; + if (floatStatus) { + newGeometry.setX(oldGeometry.x()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } else { + newGeometry.setX(oldGeometry.x()*lfWidthScale); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } + widget->setGeometry(newGeometry); + } + } + + QChar chChars[] = {',', '.', '?', '!', '\'', ':', '~', '@', ';', '"', + '/', '(', ')', '_', '+', '=', '`', '^', '#', '*', + '%', '&', '\\', '[', ']', '<', '>', '{', '}', '|', + '$', '-'}; + for (int n = 0; n < sizeof(chChars)/sizeof(QChar); n++) { //单独更新符号btn的高度 + QString objName = QString("btn_%1").arg(QString(chChars[n])); + KBButton *btn = findChild(objName); + btn->setFixedHeight(KEYBOARD_FIXED_DEFAULT_NORMAL_CHARSMORE_BTN_HEIGHT *lfHeightScale); + } + //更新listfarame的高度 + listFrame->setFixedHeight(KEYBOARD_FIXED_DEFAULT_NORMAL_CHARSMORE_BTN_HEIGHT *m_vlayoutBtnList->count() *lfHeightScale); +} + +void CharsMoreWidget::onBtnClicked(QChar charId) +{ + QObject *obj = sender(); + KBButton *btn = static_cast(obj); + QString objName = btn->objectName(); + int lastUnderline = objName.lastIndexOf('_'); + int start = strlen("btn_"); + int keyLength = lastUnderline - start; + QString keyName = objName.mid(start, keyLength); + if (keyName == BTN_RETURN) { + Q_EMIT specialBtnClicked(PAGE_CHAR); + } else if (charId != QChar::Null) { + Q_EMIT normalBtnClicked(charId); + } else { + Q_EMIT specialBtnClicked(keyName); + } +} + +void CharsMoreWidget::initUI() +{ + // all chars + m_vlayoutBtnList = new QVBoxLayout(); + m_vlayoutBtnList->setContentsMargins(8,0,0,0); + m_vlayoutBtnList->setSpacing(1); + listFrame = new QFrame(); + listFrame->setLayout(m_vlayoutBtnList); + listFrame->setStyleSheet("QFrame{border-radius: 8px}"); + m_scrollFrame = new QScrollArea(this); + m_scrollFrame->setContentsMargins(0, 0, 0, 0); + m_scrollFrame->setFocusPolicy(Qt::NoFocus); + m_scrollFrame->setStyleSheet("QScrollArea {background-color: #C0FFFFFF; border-radius:8px;}"); + m_scrollFrame->viewport()->setStyleSheet("background-color:transparent;"); + m_scrollFrame->verticalScrollBar()->setProperty("drawScrollBarGroove", false); + m_scrollFrame->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollFrame->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + m_scrollFrame->setWidgetResizable(true); + m_scrollFrame->setWidget(listFrame); + m_scrollFrame->setGeometry(KEYBOARD_FIXED_DEFAULT_CHARSMORE_L1, 0, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_WIDTH, KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_HEIGHT); + listFrame->setGeometry(KEYBOARD_FIXED_DEFAULT_CHARSMORE_L1, 0, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_WIDTH, KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_HEIGHT); + m_mapBtnGeometrys[m_scrollFrame] = m_scrollFrame->geometry(); + m_mapBtnGeometrys[listFrame] = listFrame->geometry(); + QChar chChars[] = {',', '.', '?', '!', '\'', ':', '~', '@', ';', '"', + '/', '(', ')', '_', '+', '=', '`', '^', '#', '*', + '%', '&', '\\', '[', ']', '<', '>', '{', '}', '|', + '$', '-', ' ', ' ', ' ', ' '}; + QHBoxLayout *lastLayout = nullptr; + for (int n = 0; n < sizeof(chChars)/sizeof(QChar); n++) { + KBButton *charBtn = new KBButton(listFrame); + charBtn->setCharId(chChars[n]); + charBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_NORMAL, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_FONT_COLOR_PRESS, + KBButton::BORDER_RADIUS_NONE); + if ((n%KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_COLS) == 0) { + lastLayout = new QHBoxLayout(); + lastLayout->setContentsMargins(0,0,0,0); + lastLayout->setSpacing(1); + m_vlayoutBtnList->addLayout(lastLayout); + } + if (chChars[n] == ' ') { + charBtn->setDisabled(true); + } else { + charBtn->setObjectName(QString("btn_%1").arg(QString(chChars[n]))); + } + charBtn->setFixedHeight(KEYBOARD_FIXED_DEFAULT_NORMAL_CHARSMORE_BTN_HEIGHT); + lastLayout->addWidget(charBtn); + m_mapSubWidgetListRects[charBtn] = charBtn->geometry(); + connect(charBtn, &KBButton::clicked, this, &CharsMoreWidget::onBtnClicked); + } + // backspace + KBButton *backspaceBtn = new KBButton(this); + backspaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_CHARSMORE_L1+(KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_WIDTH+KEYBOARD_FIXED_DEFAULT_CHARSMORE_HSPACING), + 0, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_HEIGHT); + backspaceBtn->setObjectName("btn_backspace"); + backspaceBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + backspaceBtn->setIcon(QIcon(":/images/images/delet.svg")); + m_mapBtnGeometrys[backspaceBtn] = backspaceBtn->geometry(); + connect(backspaceBtn, &KBButton::clicked, this, &CharsMoreWidget::onBtnClicked); + // enter + KBButton *enterBtn = new KBButton(this); + enterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_CHARSMORE_L1+(KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_WIDTH+KEYBOARD_FIXED_DEFAULT_CHARSMORE_HSPACING), + (KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_HEIGHT+KEYBOARD_FIXED_DEFAULT_CHARSMORE_VSPACING)*1, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_HEIGHT); + enterBtn->setObjectName("btn_enter"); + enterBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + enterBtn->setIcon(QIcon(":/images/images/enter.svg")); + connect(enterBtn, &KBButton::clicked, this, &CharsMoreWidget::onBtnClicked); + m_mapBtnGeometrys[enterBtn] = enterBtn->geometry(); + // return + KBButton *returnBtn = new KBButton(this); + returnBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_CHARSMORE_L1+(KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_WIDTH+KEYBOARD_FIXED_DEFAULT_CHARSMORE_HSPACING), + (KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_HEIGHT+KEYBOARD_FIXED_DEFAULT_CHARSMORE_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_HEIGHT); + returnBtn->setObjectName("btn_return"); + returnBtn->setText(tr("&&?!")); + returnBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(returnBtn, &KBButton::clicked, this, &CharsMoreWidget::onBtnClicked); + m_mapBtnGeometrys[returnBtn] = returnBtn->geometry(); +} diff --git a/VirtualKeyboard/src/charsmorewidget.h b/VirtualKeyboard/src/charsmorewidget.h new file mode 100644 index 0000000..9971ed3 --- /dev/null +++ b/VirtualKeyboard/src/charsmorewidget.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef CHARSMOREWIDGETS_H +#define CHARSMOREWIDGETS_H + +#include +#include "kbbutton.h" +#include + +class QVBoxLayout; +class QHBoxLayout; +class QScrollArea; +class QFrame; +class CharsMoreWidget : public QWidget +{ + Q_OBJECT +public: + explicit CharsMoreWidget(QWidget *parent = nullptr); + ~CharsMoreWidget(); + void adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical = false, bool floatStatus = false); + +public Q_SLOTS: + void onBtnClicked(QChar charId); + +Q_SIGNALS: + void clicked(int nKeyId); + void specialBtnClicked(QString keyName); + void normalBtnClicked(QChar charId); + +private: + void initUI(); + +private: + QMap m_mapBtnGeometrys; + QMap m_mapSubWidgetListRects; + QVBoxLayout *m_vlayoutBtnList = nullptr; + QScrollArea *m_scrollFrame = nullptr; + QFrame *listFrame = nullptr; +}; + +#endif // CHARSMOREWIDGETS_H diff --git a/VirtualKeyboard/src/charswidget.cpp b/VirtualKeyboard/src/charswidget.cpp new file mode 100644 index 0000000..c66597f --- /dev/null +++ b/VirtualKeyboard/src/charswidget.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "charswidget.h" + +#include "commondef.h" +#include + +CharsWidget::CharsWidget(QWidget *parent/* = nullptr*/) + : QWidget(parent) +{ + this->setAttribute(Qt::WA_TranslucentBackground);//背景透明 + initUI(); +} + +CharsWidget::~CharsWidget() +{ + +} + +void CharsWidget::initUI() +{ + // line 1 + QChar chLine1[] = {'1','2','3','4','5','6','7','8','9','0'}; + for (int n = 0; n < sizeof(chLine1)/sizeof(QChar); n++) { + KBButton *charBtn = new KBButton(this); + charBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L1+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*n, + KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + charBtn->setCharId(chLine1[n]); + charBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(charBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[charBtn] = charBtn->geometry(); + } + // backspace + KBButton *backspaceBtn = new KBButton(this); + backspaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L1+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*10, + KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + backspaceBtn->setObjectName("btn_backspace"); + backspaceBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(backspaceBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + backspaceBtn->setIcon(QIcon(":/images/images/delet.svg")); + m_mapBtnGeometrys[backspaceBtn] = backspaceBtn->geometry(); + + // line 2 + QChar chLine2[] = {'~','/',':',';','(',')','@','"','\''}; + for (int n = 0; n < sizeof(chLine2)/sizeof(QChar); n++) { + KBButton *charBtn = new KBButton(this); + charBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L2+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*n, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING), + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + charBtn->setCharId(chLine2[n]); + charBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(charBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[charBtn] = charBtn->geometry(); + } + // enter + KBButton *enterBtn = new KBButton(this); + enterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L2+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*9, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING), + KEYBOARD_FIXED_DEFAULT_ENTERBTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + enterBtn->setObjectName("btn_enter"); + enterBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(enterBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + enterBtn->setIcon(QIcon(":/images/images/enter.svg")); + m_mapBtnGeometrys[enterBtn] = enterBtn->geometry(); + + // line 3 + QChar chLine3[] = {'-','_','#','%','$','+','^',',','.','!'}; + for (int n = 0; n < sizeof(chLine3)/sizeof(QChar); n++) { + KBButton *charBtn = new KBButton(this); + charBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L3+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*(n+1), + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + charBtn->setCharId(chLine3[n]); + charBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(charBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[charBtn] = charBtn->geometry(); + } + // more + KBButton *moreBtn = new KBButton(this); + moreBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L3, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + moreBtn->setObjectName("btn_more"); + moreBtn->setText(tr("More")); + moreBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(moreBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[moreBtn] = moreBtn->geometry(); + + // line 4 + KBButton *returnBtn = new KBButton(this); + returnBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + returnBtn->setObjectName("btn_return"); + returnBtn->setText(tr("ABC")); + returnBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(returnBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[returnBtn] = returnBtn->geometry(); + + KBButton *numBtn = new KBButton(this); + numBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING), + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + numBtn->setObjectName("btn_number"); + numBtn->setText(tr("123")); + numBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(numBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[numBtn] = numBtn->geometry(); + + KBButton *threedBtn = new KBButton(this); + threedBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*2, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + threedBtn->setObjectName("btn_threed"); + threedBtn->setCharId(('&')); + threedBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(threedBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[threedBtn] = threedBtn->geometry(); + + KBButton *spaceBtn = new KBButton(this); + spaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*3, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_SPACEBTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + spaceBtn->setObjectName("btn_space"); + spaceBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_BORDER_NORMAL, + KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + spaceBtn->setIcon(QIcon(":/images/images/space.svg")); + connect(spaceBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[spaceBtn] = spaceBtn->geometry(); + + KBButton *whBtn = new KBButton(this); + whBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*8, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + whBtn->setCharId('?'); + whBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(whBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[whBtn] = whBtn->geometry(); + + KBButton *leftBtn = new KBButton(this); + leftBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*9, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + leftBtn->setObjectName("btn_left"); + leftBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + leftBtn->setIcon(QIcon(":/images/images/left.svg")); + connect(leftBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[leftBtn] = leftBtn->geometry(); + + KBButton *rightBtn = new KBButton(this); + rightBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*10, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + rightBtn->setObjectName("btn_right"); + rightBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + rightBtn->setIcon(QIcon(":/images/images/right.svg")); + connect(rightBtn, &KBButton::clicked, this, &CharsWidget::onBtnClicked); + m_mapBtnGeometrys[rightBtn] = rightBtn->geometry(); +} + +void CharsWidget::adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical/* = false*/, bool floatStatus) +{ + QMap::iterator itGeometry = m_mapBtnGeometrys.begin(); + for (; itGeometry != m_mapBtnGeometrys.end(); itGeometry ++) { + KBButton *button = itGeometry.key(); + if (button) { + QRect oldGeometry = itGeometry.value(); + QRect newGeometry = oldGeometry; + if (floatStatus) { + newGeometry.setX(oldGeometry.x()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } else { + newGeometry.setX(oldGeometry.x()*lfWidthScale); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } + button->setGeometry(newGeometry); + } + } +} + +void CharsWidget::onBtnClicked(QChar charId) +{ + QObject *obj = sender(); + KBButton *btn = static_cast(obj); + QString objName = btn->objectName(); + int lastUnderline = objName.lastIndexOf('_'); + int start = strlen("btn_"); + int keyLength = lastUnderline - start; + QString keyName = objName.mid(start, keyLength); + if (keyName == BTN_RETURN) { + Q_EMIT specialBtnClicked(PAGE_LETTER); + } else if (keyName == "more") { + Q_EMIT specialBtnClicked(PAGE_CHARSMORE); + } else if (keyName == "number") { + Q_EMIT specialBtnClicked(PAGE_NUMBER); + } else if (charId != QChar::Null) { + Q_EMIT normalBtnClicked(charId); + } else { + Q_EMIT specialBtnClicked(keyName); + } +} diff --git a/VirtualKeyboard/src/charswidget.h b/VirtualKeyboard/src/charswidget.h new file mode 100644 index 0000000..1076201 --- /dev/null +++ b/VirtualKeyboard/src/charswidget.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef CHARSWIDGET_H +#define CHARSWIDGET_H + +#include +#include "kbbutton.h" +#include + +class CharsWidget : public QWidget +{ + Q_OBJECT +public: + explicit CharsWidget(QWidget *parent = nullptr); + virtual ~CharsWidget(); + + void adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical = false, bool floatStatus = false); + +public Q_SLOTS: + void onBtnClicked(QChar charId); + +Q_SIGNALS: + void clicked(int nKeyId); + void specialBtnClicked(QString keyName); + void normalBtnClicked(QChar c); + +private: + void initUI(); + +private: + QMap m_mapBtnGeometrys; + +}; + +#endif // CHARSWIDGET_H diff --git a/VirtualKeyboard/src/commondef.h b/VirtualKeyboard/src/commondef.h new file mode 100644 index 0000000..629bd2d --- /dev/null +++ b/VirtualKeyboard/src/commondef.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef COMMONDEF_H +#define COMMONDEF_H + +#define KEYBOARD_PARENT_DEFAULT_WIDTH 1620 +#define KEYBOARD_PARENT_DEFAULT_HEIGHT 1080 + +#define KEYBOARD_FIXED_DEFAULT_WIDTH 1620 +#define KEYBOARD_DRAGSHOW_FIXED_DEFAULT_HEIGHT 428 + +#define KEYBOARD_DRAGSHOW_FIXED_DEFAULT_WIDTH 1458 +#define KEYBOARD_DRAGHIDE_FIXED_DEFAULT_HEIGHT 404 + +#define KEYBOARD_TITLEBTN_DEFAULT_WIDTH 56 +#define KEYBOARD_TITLEBTN_DEFAULT_HEIGHT 56 +#define KEYBOARD_TITLE_DEFAULT_HEIGHT 68 + +#define KEYBOARD_DRAGBTN_DEFAULT_WIDTH 56 +#define KEYBOARD_DRAGBTN_DEFAULT_HEIGHT 4 +#define KEYBOARD_DRAG_DEFAULT_HEIGHT 26 + +#define KEYBOARD_FLOAT_PERCENTAGE 0.9 + +#define KEYBOARD_FIXED_DEFAULT_LMARGIN 22 // 左边距 +#define KEYBOARD_FIXED_DEFAULT_RMARGIN 22 // 右边距 +#define KEYBOARD_FIXED_DEFAULT_TMARGIN 8 // 上边距 +#define KEYBOARD_FIXED_DEFAULT_BMARGIN 16 // 下边距 + +#define KEYBOAED_FIXED_DEFAULT_VSPACING 8 // 垂直间隔 +#define KEYBOAED_FIXED_DEFAULT_HSPACING 8 // 水平间隔 +// letters +#define KEYBOARD_FIXED_DEFAULT_LETTER_L1 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) // 字符页面左起点 +#define KEYBOARD_FIXED_DEFAULT_LETTER_L2 (KEYBOARD_FIXED_DEFAULT_LMARGIN+72) // 字符页面左起点 +#define KEYBOARD_FIXED_DEFAULT_LETTER_L3 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) // 字符页面左起点 +#define KEYBOARD_FIXED_DEFAULT_LETTER_L4 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) // 字符页面左起点 +#define KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH 136 // 字符按钮宽度 +#define KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT 72 // 字符按钮高度 +#define KEYBOARD_FIXED_DEFAULT_LETTER_ENTWIDTH 208 +#define KEYBOARD_FIXED_DEFAULT_LETTER_SPCWIDTH 712 +#define KEYBOARD_FIXED_DEFAULT_TITLEBTN_WIDTH 56 +#define KEYBOARD_FIXED_DEFAULT_TITLEBTN_HEIGHT 56 + +#define KEYBOARD_FIXED_DEFAULT_ENTERBTN_WIDTH 208 +#define KEYBOARD_FIXED_DEFAULT_SPACEBTN_WIDTH 712 + +#define KEYBOARD_LETTER_COLOR_NORMAL "#FFFFFF" +#define KEYBOARD_LETTER_COLOR_PRESSED "#DDE0E4" +#define KEYBOARD_LETTER_COLOR_BORDER_NORMAL "#95A0AD" +#define KEYBOARD_LETTER_COLOR_BORDER_PRESSED "#95A0AD" + +#define KEYBOARD_OTHER_COLOR_NORMAL "#CED3D9" +#define KEYBOARD_OTHER_COLOR_PRESSED "#3790FA" +#define KEYBOARD_OTHER_COLOR_BORDER_NORMAL "#95A0AD" +#define KEYBOARD_OTHER_COLOR_BORDER_PRESSED "#1174E5" + +#define KEYBOARD_FONT_COLOR_PRESS "#262626" +#define KEYBOARD_OTHER_FONT_COLOR_PRESS "#FFFFFF" + +//numbers +#define KEYBOARD_FIXED_DEFAULT_NUMBER_L1 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) +#define KEYBOARD_FIXED_DEFAULT_NUMBER_L2 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) +#define KEYBOARD_FIXED_DEFAULT_NUMBER_L3 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) +#define KEYBOARD_FIXED_DEFAULT_NUMBER_L4 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) + +#define KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH 306 // 数字按钮宽度 +#define KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT 72 // 数字按钮高度 +#define KEYBOARD_FIXED_DEFAULT_NUMBER_CHARS_HEIGHT 230 // 数字字符按钮高度 + +// chars more + +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_L1 (KEYBOARD_FIXED_DEFAULT_LMARGIN+0) +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_HSPACING 16 +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_VSPACING 16 + +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_COLS 6 +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_WIDTH 1350 // 字符列表宽度 +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_LIST_HEIGHT 315 // 字符列表高度 +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_WIDTH 214 // 按钮宽度 +#define KEYBOARD_FIXED_DEFAULT_CHARSMORE_BTN_HEIGHT 94 // 功能按钮高度 +#define KEYBOARD_FIXED_DEFAULT_NORMAL_CHARSMORE_BTN_HEIGHT 80 // 符号按钮高度 + +//iconsize +#define KEYBOARD_FIXED_DEFAULT_ICONSIZE QSize(25, 25) + +//keyName +#define PAGE_CHAR "page_char" +#define PAGE_NUMBER "page_number" +#define PAGE_CHARSMORE "page_charmore" +#define PAGE_LETTER "page_letter" +#define BTN_FLOAT "float" +#define BTN_CLOSE "close" +#define BTN_RETURN "return" +#define BTN_BACK "backspace" +#define BTN_ENTER "enter" +#define BTN_SHIFT "shift" +#define BTN_CTRL "ctrl" +#define BTN_ALT "alt" +#define BTN_SPACE "space" +#define BTN_RIGHT "right" +#define BTN_LEFT "left" +#define BTN_CAPSLOCK "capslock" + + + +#endif // COMMONDEF_H diff --git a/VirtualKeyboard/src/cursormonitor.cpp b/VirtualKeyboard/src/cursormonitor.cpp index 2c76123..9553a60 100644 --- a/VirtualKeyboard/src/cursormonitor.cpp +++ b/VirtualKeyboard/src/cursormonitor.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "cursormonitor.h" #include diff --git a/VirtualKeyboard/src/dragwidget.cpp b/VirtualKeyboard/src/dragwidget.cpp new file mode 100644 index 0000000..db8a332 --- /dev/null +++ b/VirtualKeyboard/src/dragwidget.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "dragwidget.h" +#include +#include +#include +#include "commondef.h" + +DragWidget::DragWidget(QWidget *parent/* = nullptr*/) + : QWidget(parent) +{ + setAttribute(Qt::WA_TranslucentBackground);//背景透明 + initUI(); +} + +DragWidget::~DragWidget() +{ + +} + +void DragWidget::initUI() +{ + setFixedHeight(KEYBOARD_DRAG_DEFAULT_HEIGHT); + + m_labelDrag = new QLabel(this); + m_labelDrag->setPixmap(QPixmap(":/images/images/drag.svg")); + m_labelDrag->setGeometry((KEYBOARD_PARENT_DEFAULT_WIDTH - KEYBOARD_TITLEBTN_DEFAULT_WIDTH)/2, + (this->height() - KEYBOARD_TITLEBTN_DEFAULT_HEIGHT)/2, + KEYBOARD_TITLEBTN_DEFAULT_WIDTH, KEYBOARD_TITLEBTN_DEFAULT_HEIGHT); + m_mapSubGeometrys[m_labelDrag] = m_labelDrag->geometry(); +} + +void DragWidget::adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical/* = false*/, bool floatStatus) +{ + setFixedHeight(KEYBOARD_DRAG_DEFAULT_HEIGHT*lfHeightScale); + QMap::iterator itGeometry = m_mapSubGeometrys.begin(); + for (; itGeometry != m_mapSubGeometrys.end(); itGeometry ++) { + QLabel *label = itGeometry.key(); + if (label) { + QRect oldGeometry = itGeometry.value(); + QRect newGeometry = oldGeometry; + if (floatStatus) { + newGeometry.setX(oldGeometry.x()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } else { + newGeometry.setX(oldGeometry.x()*lfWidthScale); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } + label->setGeometry(newGeometry); + } + } +} diff --git a/VirtualKeyboard/src/dragwidget.h b/VirtualKeyboard/src/dragwidget.h new file mode 100644 index 0000000..e8b1527 --- /dev/null +++ b/VirtualKeyboard/src/dragwidget.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef DRAGWIDGET_H +#define DRAGWIDGET_H + +#include +#include +#include + +class DragWidget : public QWidget +{ + Q_OBJECT +public: + DragWidget(QWidget *parent = nullptr); + virtual ~DragWidget(); + +public: + void adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical = false, bool floatStatus = false); + +private: + void initUI(); + +private: + QLabel *m_labelDrag = nullptr; + QMap m_mapSubGeometrys; +}; + +#endif // DRAGWIDGET_H diff --git a/VirtualKeyboard/src/fakekeyboard.h b/VirtualKeyboard/src/fakekeyboard.h new file mode 100644 index 0000000..65a22ce --- /dev/null +++ b/VirtualKeyboard/src/fakekeyboard.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef FAKEKEYBOARD_H +#define FAKEKEYBOARD_H + +#include +#include + +class Modifier : public QObject +{ + Q_OBJECT +public: + Modifier(){} + + enum MOD{ + UNKNOWN = -1, + CTRL, + SHIFT, + ALT, + SUPER + }; + Q_ENUM(MOD) + + static QString getModifierName(int mod) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + const char* modName = metaEnum.valueToKey(mod); + QString result = QString(modName).toLower(); + return result; + } + static MOD getModifier(const QString &modName) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + MOD mod = (MOD)metaEnum.keyToValue(modName.toUpper().toLocal8Bit().data()); + return mod; + } +}; + +class FuncKey : public QObject +{ + Q_OBJECT +public: + FuncKey(){} + + enum FUNCKEY { + UNKNOWN = -1, + SPACE = 0, + BACKSPACE, + ENTER, + HOME, + END, + PGUP, + PGDN, + INSERT, + DELETE, + UP, + DOWN, + LEFT, + RIGHT, + CAPSLOCK + }; + Q_ENUM(FUNCKEY) + static QString getKeyName(int key) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + const char* keyName = metaEnum.valueToKey(key); + QString result = QString(keyName).toLower(); + return result; + } + static FUNCKEY getKey(const QString &keyName) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + FUNCKEY key = (FUNCKEY)metaEnum.keyToValue(keyName.toUpper().toLocal8Bit().data()); + return key; + } +}; + +class FakeKeyboard : public QObject +{ + Q_OBJECT +public: + explicit FakeKeyboard(QObject *parent = nullptr) + : QObject(parent) + { + + } + + virtual void addModifier(Modifier::MOD mod) = 0; + virtual void removeModifier(Modifier::MOD mod) = 0; + virtual bool hasModifier(Modifier::MOD mod) = 0; + virtual QList getAllModifier() = 0; + virtual void clearModifier() = 0; + +public Q_SLOTS: + virtual void onKeyPressed(QChar c) = 0; + virtual void onKeyPressed(FuncKey::FUNCKEY key) = 0; +}; + +#endif // FAKEKEYBOARD_H diff --git a/VirtualKeyboard/src/images/backspace.svg b/VirtualKeyboard/src/images/backspace.svg deleted file mode 100644 index 092d72d..0000000 --- a/VirtualKeyboard/src/images/backspace.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/VirtualKeyboard/src/images/backspace_click.svg b/VirtualKeyboard/src/images/backspace_click.svg deleted file mode 100644 index 4a9d7fa..0000000 --- a/VirtualKeyboard/src/images/backspace_click.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/VirtualKeyboard/src/images/capslock.svg b/VirtualKeyboard/src/images/capslock.svg deleted file mode 100644 index a5a367c..0000000 --- a/VirtualKeyboard/src/images/capslock.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/VirtualKeyboard/src/images/capslock_click.svg b/VirtualKeyboard/src/images/capslock_click.svg deleted file mode 100644 index 36ae8f8..0000000 --- a/VirtualKeyboard/src/images/capslock_click.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/VirtualKeyboard/src/images/capslock_hl.svg b/VirtualKeyboard/src/images/capslock_hl.svg deleted file mode 100644 index 4f8870a..0000000 --- a/VirtualKeyboard/src/images/capslock_hl.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/VirtualKeyboard/src/images/capslock_hl_click.svg b/VirtualKeyboard/src/images/capslock_hl_click.svg deleted file mode 100644 index 65b0a21..0000000 --- a/VirtualKeyboard/src/images/capslock_hl_click.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/VirtualKeyboard/src/images/close.svg b/VirtualKeyboard/src/images/close.svg index c509415..ba56780 100644 --- a/VirtualKeyboard/src/images/close.svg +++ b/VirtualKeyboard/src/images/close.svg @@ -1,22 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/VirtualKeyboard/src/images/close_click.svg b/VirtualKeyboard/src/images/close_click.svg deleted file mode 100644 index d143065..0000000 --- a/VirtualKeyboard/src/images/close_click.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/VirtualKeyboard/src/images/delet.svg b/VirtualKeyboard/src/images/delet.svg new file mode 100644 index 0000000..b290563 --- /dev/null +++ b/VirtualKeyboard/src/images/delet.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/VirtualKeyboard/src/images/down.svg b/VirtualKeyboard/src/images/down.svg deleted file mode 100644 index 73361dd..0000000 --- a/VirtualKeyboard/src/images/down.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - -画板 15 - - - - diff --git a/VirtualKeyboard/src/images/down_click.svg b/VirtualKeyboard/src/images/down_click.svg deleted file mode 100644 index 9140b38..0000000 --- a/VirtualKeyboard/src/images/down_click.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/VirtualKeyboard/src/images/drag.svg b/VirtualKeyboard/src/images/drag.svg new file mode 100644 index 0000000..9bc4dac --- /dev/null +++ b/VirtualKeyboard/src/images/drag.svg @@ -0,0 +1,3 @@ + + + diff --git a/VirtualKeyboard/src/images/enter.svg b/VirtualKeyboard/src/images/enter.svg index 5cbc51d..9c09d11 100644 --- a/VirtualKeyboard/src/images/enter.svg +++ b/VirtualKeyboard/src/images/enter.svg @@ -1,11 +1,4 @@ - - - - - - - + + + + diff --git a/VirtualKeyboard/src/images/enter_click.svg b/VirtualKeyboard/src/images/enter_click.svg deleted file mode 100644 index 106cc7b..0000000 --- a/VirtualKeyboard/src/images/enter_click.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/VirtualKeyboard/src/images/float-restore.svg b/VirtualKeyboard/src/images/float-restore.svg new file mode 100644 index 0000000..3349d01 --- /dev/null +++ b/VirtualKeyboard/src/images/float-restore.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/VirtualKeyboard/src/images/float.svg b/VirtualKeyboard/src/images/float.svg new file mode 100644 index 0000000..a24e50f --- /dev/null +++ b/VirtualKeyboard/src/images/float.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/VirtualKeyboard/src/images/left.svg b/VirtualKeyboard/src/images/left.svg index 6ac0fa8..f614a70 100644 --- a/VirtualKeyboard/src/images/left.svg +++ b/VirtualKeyboard/src/images/left.svg @@ -1,7 +1,3 @@ - - - -画板 19 - - + + + diff --git a/VirtualKeyboard/src/images/left_click.svg b/VirtualKeyboard/src/images/left_click.svg deleted file mode 100644 index edfd291..0000000 --- a/VirtualKeyboard/src/images/left_click.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - -画板 20 - - diff --git a/VirtualKeyboard/src/images/rectangle.svg b/VirtualKeyboard/src/images/rectangle.svg new file mode 100644 index 0000000..7ffef85 --- /dev/null +++ b/VirtualKeyboard/src/images/rectangle.svg @@ -0,0 +1,3 @@ + + + diff --git a/VirtualKeyboard/src/images/right.svg b/VirtualKeyboard/src/images/right.svg index 62c301c..9922eb7 100644 --- a/VirtualKeyboard/src/images/right.svg +++ b/VirtualKeyboard/src/images/right.svg @@ -1,6 +1,3 @@ - - - - - + + + diff --git a/VirtualKeyboard/src/images/right_click.svg b/VirtualKeyboard/src/images/right_click.svg deleted file mode 100644 index 5ba0ec6..0000000 --- a/VirtualKeyboard/src/images/right_click.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/VirtualKeyboard/src/images/shift.svg b/VirtualKeyboard/src/images/shift.svg new file mode 100644 index 0000000..6a3b438 --- /dev/null +++ b/VirtualKeyboard/src/images/shift.svg @@ -0,0 +1,3 @@ + + + diff --git a/VirtualKeyboard/src/images/shift_lock.svg b/VirtualKeyboard/src/images/shift_lock.svg new file mode 100644 index 0000000..09d5c99 --- /dev/null +++ b/VirtualKeyboard/src/images/shift_lock.svg @@ -0,0 +1,4 @@ + + + + diff --git a/VirtualKeyboard/src/images/space.svg b/VirtualKeyboard/src/images/space.svg new file mode 100644 index 0000000..b5b9769 --- /dev/null +++ b/VirtualKeyboard/src/images/space.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/VirtualKeyboard/src/images/super.svg b/VirtualKeyboard/src/images/super.svg deleted file mode 100644 index c847e44..0000000 --- a/VirtualKeyboard/src/images/super.svg +++ /dev/null @@ -1 +0,0 @@ -画板 11 \ No newline at end of file diff --git a/VirtualKeyboard/src/images/super_click.svg b/VirtualKeyboard/src/images/super_click.svg deleted file mode 100644 index 7fcc495..0000000 --- a/VirtualKeyboard/src/images/super_click.svg +++ /dev/null @@ -1 +0,0 @@ -画板 12 \ No newline at end of file diff --git a/VirtualKeyboard/src/images/unlock.svg b/VirtualKeyboard/src/images/unlock.svg new file mode 100644 index 0000000..17271fd --- /dev/null +++ b/VirtualKeyboard/src/images/unlock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/VirtualKeyboard/src/images/up.svg b/VirtualKeyboard/src/images/up.svg deleted file mode 100644 index d5613b2..0000000 --- a/VirtualKeyboard/src/images/up.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - -画板 13 - - - - diff --git a/VirtualKeyboard/src/images/up_click.svg b/VirtualKeyboard/src/images/up_click.svg deleted file mode 100644 index 225e401..0000000 --- a/VirtualKeyboard/src/images/up_click.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/VirtualKeyboard/src/kbbutton.cpp b/VirtualKeyboard/src/kbbutton.cpp new file mode 100644 index 0000000..d593793 --- /dev/null +++ b/VirtualKeyboard/src/kbbutton.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "kbbutton.h" +#include "commondef.h" +#include +#include + +KBButton::KBButton(QWidget *parent/* = nullptr*/) + : QPushButton(parent) +{ + this->installEventFilter(this); + this->setIconSize(KEYBOARD_FIXED_DEFAULT_ICONSIZE); + this->setFocusPolicy(Qt::NoFocus); + connect(this, &QPushButton::clicked, this, [&,this]() { + if (m_charId.isLetter()) { + if (m_isShift) { + if (m_isCaps) { + m_charId = m_charId.toLower(); + } else { + m_charId = m_charId.toUpper(); + } + } else { + if (m_isCaps) { + m_charId = m_charId.toUpper(); + } else { + m_charId = m_charId.toLower(); + } + } + } + Q_EMIT clicked(m_charId); + }); +} + +KBButton::~KBButton() +{ + +} + +bool KBButton::eventFilter(QObject *watched, QEvent *event) +{ + if (m_clrNormal == KEYBOARD_LETTER_COLOR_NORMAL) + return QPushButton::eventFilter(watched, event); + if (event->type() == QEvent::MouseButtonPress) { + QPixmap pressIcon = this->icon().pixmap(QSize(24, 24)); + pressIcon = drawSymbolicColoredPixmap(pressIcon, "white"); + this->setIcon(pressIcon); + } else if (event->type() == QEvent::MouseButtonRelease) { + QPixmap releaseIcon = this->icon().pixmap(QSize(24, 24)); + releaseIcon = drawSymbolicColoredPixmap(releaseIcon, "black"); + this->setIcon(releaseIcon); + } + return QPushButton::eventFilter(watched, event); +} + +void KBButton::setCharId(QChar charId) +{ + m_charId = charId; + if (charId == '&') { + setText("&&"); + } else { + setText(m_charId); + } +} + +void KBButton::updateStyleSheet(QString clrNormal, QString clrHover, QString clrChecked, QString clrBoard, QString clrBoardPress, QString clrFontPress, int radius, bool is_lock) +{ + QString strBorderRadius = QString("border-top-left-radius: %1px; border-top-right-radius: %2px; border-bottom-right-radius: %3px;border-bottom-left-radius: %4px;") + .arg((radius&BORDER_RADIUS_LT)?8:0) + .arg((radius&BORDER_RADIUS_TR)?8:0) + .arg((radius&BORDER_RADIUS_RB)?8:0) + .arg((radius&BORDER_RADIUS_LB)?8:0); + if (!is_lock) { + setStyleSheet(QString("QPushButton{%1 border: 2px solid %2; border-width: 0px 0px 2px 0px; background: %3; color: #262626}" + // "QPushButton:hover{border: 2px solid %4; border-width: 2px 0px 0px 0px; background: %5;}" + "QPushButton:pressed{border: 2px solid %4; border-width: 2px 0px 0px 0px; background: %5; color: %6}" + "QPushButton:checked{border: 2px solid %7; border-width: 2px 0px 0px 0px; background: %8; color: %9}") + .arg(strBorderRadius).arg(clrBoard).arg(clrNormal).arg(clrBoardPress).arg(clrHover).arg(clrFontPress).arg(clrBoardPress).arg(clrChecked).arg(clrFontPress) + ); + } else { + setStyleSheet(QString("QPushButton{%1 border: 2px solid %2; border-width: 0px 0px 2px 0px; background: %3; color: #FFFFFF}" + // "QPushButton:hover{border: 2px solid %4; border-width: 2px 0px 0px 0px; background: %5;}" + "QPushButton:pressed{border: 2px solid %4; border-width: 2px 0px 0px 0px; background: %5; color: %6}" + "QPushButton:checked{border: 2px solid %7; border-width: 2px 0px 0px 0px; background: %8; color: %9}") + .arg(strBorderRadius).arg(clrBoard).arg(clrNormal).arg(clrBoardPress).arg(clrHover).arg(clrFontPress).arg(clrBoardPress).arg(clrChecked).arg(clrFontPress) + ); + } + m_clrBoard = clrBoard; + m_clrNormal = clrNormal; + m_clrBoardPress = clrBoardPress; + m_clrHover = clrHover; + m_clrChecked = clrChecked; + if (m_clrNormal == KEYBOARD_LETTER_COLOR_NORMAL) { + sysFont.setPixelSize(32); + this->setFont(sysFont); + this->setIconSize(QSize(32, 32)); + } else { + sysFont.setPixelSize(24); + this->setFont(sysFont); + this->setIconSize(QSize(24, 24)); + } +} + +QPixmap KBButton::drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor) +{ + QImage img = source.toImage(); + for (int x = 0; x < img.width(); x++) { + for (int y = 0; y < img.height(); y++) { + auto color = img.pixelColor(x, y); + if (color.alpha() > 0) { + if ( "white" == cgColor) { + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + } else if( "black" == cgColor) { + color.setRed(0); + color.setGreen(0); + color.setBlue(0); + img.setPixelColor(x, y, color); + } else if ("gray"== cgColor) { + color.setRed(152); + color.setGreen(163); + color.setBlue(164); + img.setPixelColor(x, y, color); + } else if ("blue" == cgColor){ + color.setRed(61); + color.setGreen(107); + color.setBlue(229); + img.setPixelColor(x, y, color); + } else { + return source; + } + } + } + } + return QPixmap::fromImage(img); +} + +void KBButton::setShiftState(bool isShift) +{ + if (m_isShift != isShift) { + if (m_charId.isLetter()) { + if (isShift) { + setText(m_charId.toUpper()); + } else { + setText(m_charId.toLower()); + } + } + m_isShift = isShift; + } +} + +void KBButton::setCapsStatus(bool isCaps) +{ + m_isCaps = isCaps; + setShiftState(m_isCaps); +} + +void KBButton::setCtrlState(bool isCtrl) +{ + +} + +void KBButton::setAltState(bool isAlt) +{ + +} diff --git a/VirtualKeyboard/src/kbbutton.h b/VirtualKeyboard/src/kbbutton.h new file mode 100644 index 0000000..923fa2e --- /dev/null +++ b/VirtualKeyboard/src/kbbutton.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef KBBUTTON_H +#define KBBUTTON_H + +#include + +class KBButton : public QPushButton +{ + Q_OBJECT +public: + enum BORDER_RADIUS{ + BORDER_RADIUS_NONE, + BORDER_RADIUS_LT = 1, + BORDER_RADIUS_TR = 2, + BORDER_RADIUS_RB = 4, + BORDER_RADIUS_LB = 8, + BORDER_RADIUS_ALL = 0xF, + }; + KBButton(QWidget *parent = nullptr); + virtual ~KBButton(); + + void setCharId(QChar charId); + void updateStyleSheet(QString clrNormal, QString clrHover, QString clrChecked, QString clrBoard, QString clrBoardPress, QString clrFontPress, int radius = BORDER_RADIUS_ALL, bool is_lock = false); + void setShiftState(bool isShift); + void setCapsStatus(bool isCaps); + void setCtrlState(bool isCtrl); + void setAltState(bool isAlt); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +Q_SIGNALS: + void clicked(QChar charId); + +private: + QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor); + +private: + int m_nKeyId = -1; + bool m_isShift = false; + bool m_isCtrl = false; + bool m_isAlt = false; + bool m_isCaps = false; + QChar m_charId = QChar::Null; + QString m_clrBoard; + QString m_clrNormal; + QString m_clrBoardPress; + QString m_clrHover; + QString m_clrChecked; + QFont sysFont; +}; + +#endif // KBBUTTON_H diff --git a/VirtualKeyboard/src/kbtitle.cpp b/VirtualKeyboard/src/kbtitle.cpp new file mode 100644 index 0000000..f5aa6b7 --- /dev/null +++ b/VirtualKeyboard/src/kbtitle.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "kbtitle.h" +#include +#include +#include "commondef.h" +#include + +KBTitle::KBTitle(QWidget *parent/* = nullptr*/) + : QWidget(parent) +{ + setAttribute(Qt::WA_TranslucentBackground);//背景透明 + initUI(); + initConnections(); +} + +KBTitle::~KBTitle() +{ + +} + +void KBTitle::initUI() +{ + setFixedHeight(KEYBOARD_TITLE_DEFAULT_HEIGHT); + QString strBtnStyle = "QPushButton{ text-align:center; color: rgba(255, 255, 255, 255); border: none; border-radius: 4px; outline: none;}" + "QPushButton:hover{ background-color: rgba(255,255,255,15%); }" + "QPushButton::pressed { background-color: rgba(255,255,255,40%); }" + "QPushButton::checked { background-color: rgba(255,255,255,40%); }"; + + m_btnFloat = new QPushButton(this); + m_btnFloat->setFlat(true); + m_btnFloat->setFocusPolicy(Qt::NoFocus); + m_btnFloat->setIcon(QIcon(":/images/images/float.svg")); + m_btnFloat->setObjectName("btn_float"); + m_btnFloat->setIconSize(KEYBOARD_FIXED_DEFAULT_ICONSIZE); + m_btnFloat->setGeometry(1484, 8, KEYBOARD_TITLEBTN_DEFAULT_WIDTH, KEYBOARD_TITLEBTN_DEFAULT_HEIGHT); + m_btnFloat->setStyleSheet(strBtnStyle); + m_mapSubGeometrys[m_btnFloat] = m_btnFloat->geometry(); + + m_btnClose = new QPushButton(this); + m_btnClose->setFlat(true); + m_btnClose->setFocusPolicy(Qt::NoFocus); + m_btnClose->setIcon(QIcon(":/images/images/close.svg")); + m_btnClose->setIconSize(KEYBOARD_FIXED_DEFAULT_ICONSIZE); + m_btnClose->setObjectName("btn_close"); + m_btnClose->setGeometry(1548, 8, KEYBOARD_TITLEBTN_DEFAULT_WIDTH, KEYBOARD_TITLEBTN_DEFAULT_HEIGHT); + m_btnClose->setStyleSheet(strBtnStyle); + m_mapSubGeometrys[m_btnClose] = m_btnClose->geometry(); +} + +void KBTitle::initConnections() +{ + connect(m_btnFloat, &QPushButton::clicked, this, &KBTitle::onBtnClicked); + connect(m_btnClose, &QPushButton::clicked, this, &KBTitle::onBtnClicked); +} + +void KBTitle::onBtnClicked() +{ + QObject *obj = sender(); + QPushButton *btn = static_cast(obj); + QString objName = btn->objectName(); + int lastUnderline = objName.lastIndexOf('_'); + int start = strlen("btn_"); + int keyLength = lastUnderline - start; + QString keyName = objName.mid(start, keyLength); + if (keyName == BTN_FLOAT) { + if (floatStatus) { + btn->setIcon(QIcon(":/images/images/float.svg")); + } else { + btn->setIcon(QIcon(":/images/images/float-restore.svg")); + } + floatStatus = !floatStatus; + } + + Q_EMIT btnClicked(keyName); +} + +void KBTitle::adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical/* = false*/, bool floatStatus) +{ + setFixedHeight(KEYBOARD_TITLE_DEFAULT_HEIGHT*lfHeightScale); + QMap::iterator itGeometry = m_mapSubGeometrys.begin(); + for (; itGeometry != m_mapSubGeometrys.end(); itGeometry ++) { + QPushButton *button = itGeometry.key(); + if (button) { + QRect oldGeometry = itGeometry.value(); + QRect newGeometry = oldGeometry; + if (floatStatus) { + newGeometry.setX(oldGeometry.x()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } else { + newGeometry.setX(oldGeometry.x()*lfWidthScale); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } + button->setGeometry(newGeometry); + } + } +} diff --git a/VirtualKeyboard/src/kbtitle.h b/VirtualKeyboard/src/kbtitle.h new file mode 100644 index 0000000..cda3263 --- /dev/null +++ b/VirtualKeyboard/src/kbtitle.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef KBTITLE_H +#define KBTITLE_H + +#include +#include +#include + +class KBTitle : public QWidget +{ + Q_OBJECT +public: + KBTitle(QWidget *parent = nullptr); + virtual ~KBTitle(); + +public: + void adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical = false, bool floatStatus = false); + +public Q_SLOTS: + void onBtnClicked(); + +Q_SIGNALS: + void btnClicked(QString keyName); + +private: + void initUI(); + void initConnections(); + +private: + QPushButton *m_btnFloat = nullptr; + QPushButton *m_btnClose = nullptr; + QMap m_mapSubGeometrys; + bool floatStatus = false; +}; + +#endif // KBTITLE_H diff --git a/VirtualKeyboard/src/keyboard.qrc b/VirtualKeyboard/src/keyboard.qrc index 4e38067..a5e482e 100644 --- a/VirtualKeyboard/src/keyboard.qrc +++ b/VirtualKeyboard/src/keyboard.qrc @@ -1,27 +1,17 @@ - - keyboard.qss - - images/backspace_click.svg - images/backspace.svg - images/capslock_click.svg - images/capslock_hl.svg - images/capslock.svg - images/down_click.svg - images/down.svg - images/enter_click.svg images/enter.svg - images/left_click.svg images/left.svg - images/right_click.svg images/right.svg - images/super_click.svg - images/super.svg - images/up.svg - images/close_click.svg images/close.svg - images/capslock_hl_click.svg - images/up_click.svg + images/unlock.svg + images/space.svg + images/shift.svg + images/float.svg + images/float-restore.svg + images/drag.svg + images/delet.svg + images/shift_lock.svg + images/rectangle.svg diff --git a/VirtualKeyboard/src/keyboard.qss b/VirtualKeyboard/src/keyboard.qss deleted file mode 100644 index e91e23c..0000000 --- a/VirtualKeyboard/src/keyboard.qss +++ /dev/null @@ -1,37 +0,0 @@ -QPushButton -{ - border: none; - font: 24px; - color: white; - background: #35322f; - border-radius: 5px; -} - -QPushButton::pressed -{ - color: gray; - background: #2a2826; -} - -#btn_backspace, #btn_enter, #btn_shift_l, -#btn_shift_r, #btn_ctrl_l, #btn_ctrl_r, -#btn_alt_l, #btn_alt_r, #btn_super -{ - font: 16px; - background: #1e1b18 -} - -#btn_backspace::pressed, #btn_enter::pressed, #btn_shift_l::pressed, -#btn_shift_r::pressed, #btn_ctrl_l::pressed, #btn_ctrl_r::pressed, -#btn_alt_l::pressed, #btn_alt_r::pressed, #btn_super::pressed -{ - background: #181613; - color: gray; -} - -#btn_letter, #btn_symbol, #btn_number, -#btn_insert, #btn_delete, #btn_home, -#btn_end, #btn_pgup, #btn_pgdn, #btn_close -{ - font: 16px; -} diff --git a/VirtualKeyboard/src/keyboardwidget.cpp b/VirtualKeyboard/src/keyboardwidget.cpp deleted file mode 100644 index e97a710..0000000 --- a/VirtualKeyboard/src/keyboardwidget.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/** - * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. -**/ -#include "keyboardwidget.h" -#include "ui_keyboardwidget.h" -#include -#include -#include - -#define SYMBOL_KEY_COUNT 29 -#define SYMBOL_PAGE_COUNT 2 - -#define BUTTON_BG "QPushButton{background:#1E1B18}" -#define BUTTON_BG_PRESSED "QPushButton{background: #181613;}" -#define BUTTON_BG_HL "QPushButton{background:#80c342}" -#define BUTTON_BG_HL_PRESSED "QPushButton{background:#486E25}" - - -QChar symbols[SYMBOL_PAGE_COUNT][SYMBOL_KEY_COUNT] = - { {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', - 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/'}, - {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', - '`', '-', '=', '[', ']', '\\', '|', '{', '}', - '~','<', '>', ':', ';', '\'', '"', '_', '+', '?'}}; - - -KeyboardWidget::KeyboardWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui::KeyboardWidget), - capsLock(false), - isShift(false), - page(0) -{ - vKeyboard = new X11Keyboard(this); - connect(this, SIGNAL(keyPressed(QChar)), - vKeyboard, SLOT(onKeyPressed(QChar))); - connect(this, SIGNAL(keyPressed(FuncKey::FUNCKEY)), - vKeyboard, SLOT(onKeyPressed(FuncKey::FUNCKEY))); - - ui->setupUi(this); - bindSingal(); - setDefaultIcon(); -} - -KeyboardWidget::~KeyboardWidget() -{ - delete ui; -} - -void KeyboardWidget::resizeEvent(QResizeEvent */*event*/) -{ - int w = width(); - int h = height(); - int mainLeftMargin = ui->hl_main->contentsMargins().left(); - int mainRightMargin = ui->hl_main->contentsMargins().right(); - int mainTopMargin = ui->hl_main->contentsMargins().left(); - int mainBottomMargin = ui->hl_main->contentsMargins().right(); - int mainSpacing = ui->hl_main->spacing(); - int itemSpacing = ui->hl_1->spacing(); - - int btnWidthCount = w - 11 * itemSpacing - mainSpacing- mainLeftMargin - mainRightMargin; - int btnHeightCount = h - 3 * itemSpacing - mainTopMargin - mainBottomMargin; - double btnWidth = btnWidthCount / 12; - double btnHeight = btnHeightCount / 4; - for(int i = 0; i <= 28; i++) { - QString btnObjName = "btn_" + QString::number(i); - QPushButton *btn = ui->page_letter->findChild(btnObjName); - btn->setFixedSize(btnWidth, btnHeight); - } - ui->btn_ctrl_l->setFixedSize(btnWidth * 1.3, btnHeight); - ui->btn_ctrl_r->setFixedSize(btnWidth * 1.3, btnHeight); - ui->btn_alt_l->setFixedSize(btnWidth, btnHeight); - ui->btn_alt_r->setFixedSize(btnWidth, btnHeight); - ui->btn_super->setFixedSize(btnWidth, btnHeight); - ui->btn_shift_l->setFixedSize(btnWidth, btnHeight); - ui->btn_shift_r->setFixedHeight(btnHeight); - ui->spacer_2->changeSize(btnWidth / 2, 20); - - - for(int i = 1; i <= 9; i++) { - QString btnObjName = "btn_num_" + QString::number(i); - QPushButton *btn = ui->page_number->findChild(btnObjName); - btn->setFixedWidth(btnWidth); - } - ui->btn_backspace_num->setFixedSize(btnWidth,btnHeight); - ui->btn_insert->setFixedWidth(btnWidth); - ui->btn_delete->setFixedWidth(btnWidth); - ui->btn_home->setFixedWidth(btnWidth); - ui->btn_end->setFixedWidth(btnWidth); - ui->btn_pgup->setFixedWidth(btnWidth); - ui->btn_pgdn->setFixedWidth(btnWidth); - ui->btn_up->setFixedSize(btnWidth,btnHeight); - ui->btn_down->setFixedSize(btnWidth,btnHeight); - ui->btn_left->setFixedSize(btnWidth,btnHeight); - ui->btn_right->setFixedSize(btnWidth,btnHeight); - - ui->btn_close->setFixedHeight(btnHeight); - ui->btn_letter->setFixedHeight(btnHeight); - ui->btn_symbol->setFixedHeight(btnHeight); - ui->btn_number->setFixedHeight(btnHeight); - - setIconSize(); -} - -float hScale = 0.6; -float wScale = hScale; -#define SET_ICON_SIZE_SCALE(btn) \ - ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->width() * hScale, ui->btn_##btn->height() * wScale)); - -#define SET_ICON_SIZE(btn) \ - ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->width(), ui->btn_##btn->height())); - -#define SET_SHIFT_ICON_SIZE_SCALE(btn) \ - ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->height() * 0.4, ui->btn_##btn->height() * 0.4)); - -#define SET_ENTER_ICON_SIZE_SCALE(btn) \ - ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->width() * 0.4, ui->btn_##btn->height() * 0.4)); - -void KeyboardWidget::setIconSize() -{ - SET_ICON_SIZE_SCALE(backspace); - SET_ICON_SIZE_SCALE(backspace_num); - SET_ENTER_ICON_SIZE_SCALE(enter); - SET_ICON_SIZE_SCALE(enter_num); - SET_ICON_SIZE_SCALE(close); - SET_ICON_SIZE_SCALE(super); - - SET_SHIFT_ICON_SIZE_SCALE(shift_l); - SET_SHIFT_ICON_SIZE_SCALE(shift_r); - SET_ICON_SIZE(up); - SET_ICON_SIZE(down); - SET_ICON_SIZE(left); - SET_ICON_SIZE(right); -} - -void KeyboardWidget::bindSingal() -{ - for(auto obj : ui->page_letter->children()) { - if(obj->metaObject()->className() == QString("QPushButton")) { - QPushButton *btn = static_cast(obj); - btn->setFocusPolicy(Qt::NoFocus); - connect(btn, &QPushButton::clicked, this, &KeyboardWidget::onButtonClicked); - connect(btn, &QPushButton::pressed, this, &KeyboardWidget::onButtonPressed); - connect(btn, &QPushButton::released, this, &KeyboardWidget::onButtonReleased); - } - } - for(auto obj : ui->page_number->children()) { - if(obj->metaObject()->className() == QString("QPushButton")) { - QPushButton *btn = static_cast(obj); - btn->setFocusPolicy(Qt::NoFocus); - connect(btn, &QPushButton::clicked, this, &KeyboardWidget::onButtonClicked); - connect(btn, &QPushButton::pressed, this, &KeyboardWidget::onButtonPressed); - connect(btn, &QPushButton::released, this, &KeyboardWidget::onButtonReleased); - } - } - ui->btn_close->setFocusPolicy(Qt::NoFocus); - ui->btn_letter->setFocusPolicy(Qt::NoFocus); - ui->btn_symbol->setFocusPolicy(Qt::NoFocus); - ui->btn_number->setFocusPolicy(Qt::NoFocus); - - connect(ui->btn_letter, &QPushButton::clicked, this, [&] { - ui->stackedWidget->setCurrentWidget(ui->page_letter); - page = 0; - switchPage(); - }); - connect(ui->btn_symbol, &QPushButton::clicked, this, [&] { - ui->stackedWidget->setCurrentWidget(ui->page_letter); - page = 1; - switchPage(); - }); - connect(ui->btn_number, &QPushButton::clicked, this, [&] { - ui->stackedWidget->setCurrentWidget(ui->page_number); - }); - connect(ui->btn_close, &QPushButton::clicked, - this, &KeyboardWidget::aboutToClose); - - connect(ui->btn_close, &QPushButton::pressed, - this, &KeyboardWidget::onButtonPressed); - connect(ui->btn_close, &QPushButton::released, - this, &KeyboardWidget::onButtonReleased); -} - -void KeyboardWidget::setDefaultIcon() -{ - ui->btn_backspace->setIcon(QIcon(":/images/images/backspace.svg")); - ui->btn_backspace_num->setIcon(QIcon(":/images/images/backspace.svg")); - ui->btn_enter->setIcon(QIcon(":/images/images/enter.svg")); - ui->btn_enter_num->setIcon(QIcon(":/images/images/enter.svg")); - ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_close->setIcon(QIcon(":/images/images/close.svg")); - //ui->btn_super->setIcon(QIcon(":/images/images/super.svg")); - ui->btn_super->setText("Super"); - ui->btn_up->setIcon(QIcon(":/images/images/up.svg")); - ui->btn_down->setIcon(QIcon(":/images/images/down.svg")); - ui->btn_left->setIcon(QIcon(":/images/images/left.svg")); - ui->btn_right->setIcon(QIcon(":/images/images/right.svg")); -} - -QString KeyboardWidget::getKeyName(QPushButton *btn) -{ - QString objName = btn->objectName(); - int lastUnderline = objName.lastIndexOf('_'); - int start = strlen("btn_"); - int keyLength = lastUnderline - start; - QString keyName = objName.mid(start, keyLength); - return keyName; -} - -void KeyboardWidget::changeFuncKeyStyle(QPushButton *btn, bool isPressed) -{ - QString modName = getKeyName(btn); - Modifier::MOD mod = Modifier::getModifier(modName); - - if(vKeyboard->hasModifier(mod)) { - if(isPressed) - btn->setStyleSheet(BUTTON_BG_HL_PRESSED); - else - btn->setStyleSheet(BUTTON_BG_HL); - } else { - if(isPressed) - btn->setStyleSheet(BUTTON_BG_PRESSED); - else - btn->setStyleSheet(BUTTON_BG); - } -} - -void KeyboardWidget::changeShitKeyStyle(QPushButton *btn, bool isPressed) -{ - if(page == 0){ - if(isShift) { - if(capsLock){ - if(isPressed) { - btn->setStyleSheet(BUTTON_BG_HL_PRESSED); - btn->setIcon(QIcon(":/images/images/capslock_click.svg")); - } else { - btn->setStyleSheet(BUTTON_BG_HL); - btn->setIcon(QIcon(":/images/images/capslock.svg")); - } - } - else { - if(isPressed) - btn->setIcon(QIcon(":/images/images/capslock_hl_click.svg")); - else - btn->setIcon(QIcon(":/images/images/capslock_hl.svg")); - } - } else { - if(isPressed) - btn->setIcon(QIcon(":/images/images/capslock_click.svg")); - else - btn->setIcon(QIcon(":/images/images/capslock.svg")); - } - } -} - - -void KeyboardWidget::changeDirectKeyStyle(QPushButton *btn, bool isPressed) -{ - QString keyName = getKeyName(btn); - FuncKey::FUNCKEY key = FuncKey::getKey(keyName); - if(key == FuncKey::UNKNOWN) - return; - - QString iconName = QString(":/images/images/%1.svg").arg(keyName); - QString iconNamePressed = QString(":/images/images/%1_click.svg").arg(keyName); - - if(isPressed) - btn->setIcon(QIcon(iconNamePressed)); - else - btn->setIcon(QIcon(iconName)); -} - -/** - * @brief 修改按键样式 - * @param obj 按键 - * @param isPressed 按下或者松开 - */ -void KeyboardWidget::changeKeyStyle(QPushButton *btn, bool isPressed) -{ - if(btn == ui->btn_ctrl_l || btn == ui->btn_ctrl_r || - btn == ui->btn_alt_l || btn == ui->btn_alt_r || - btn == ui->btn_super) { - changeFuncKeyStyle(btn, isPressed); - } - - if(btn == ui->btn_shift_l) - changeShitKeyStyle(ui->btn_shift_l, isPressed); - if(btn == ui->btn_shift_r) - changeShitKeyStyle(ui->btn_shift_r, isPressed); - - changeDirectKeyStyle(btn, isPressed); -} - -void KeyboardWidget::onButtonPressed() -{ - QPushButton *btn = static_cast(sender()); - changeKeyStyle(btn, true); -} - -void KeyboardWidget::onButtonReleased() -{ - QPushButton *btn = static_cast(sender()); - changeKeyStyle(btn, false); -} - -void KeyboardWidget::onButtonClicked() -{ - QObject *obj = sender(); - if(obj->metaObject()->className() != QString("QPushButton")) - return; - - QPushButton *btn = static_cast(obj); - QString keyName = getKeyName(btn); - qDebug() << "keyName: " << keyName; - - Modifier::MOD mod = Modifier::getModifier(keyName); - FuncKey::FUNCKEY funcKey = FuncKey::getKey(keyName); - - if(keyName == "shift") { - if(page == 0) { - isShift = !isShift; - if(isShift) { //第一次被按下 - capsLock = false; - shiftLastClicked = QTime::currentTime(); - ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock_hl.svg")); - ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock_hl.svg")); - } - else { - int doubleClickInterval = QApplication::doubleClickInterval(); - if(shiftLastClicked.msecsTo(QTime::currentTime()) <= doubleClickInterval) { - //shift键双击,锁定大写 - capsLock = true; - isShift = true; - ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_l->setStyleSheet("QPushButton{background:#80c342}"); - ui->btn_shift_r->setStyleSheet("QPushButton{background:#80c342}"); - } else { - ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_l->setStyleSheet("QPushButton{background:#1e1b18}"); - ui->btn_shift_r->setStyleSheet("QPushButton{background:#1e1b18}"); - } - } - toggleCase(); - } else { - page = page % (SYMBOL_PAGE_COUNT - 1) + 1; - switchPage(); - } - } else if(mod != Modifier::UNKNOWN) { - if(vKeyboard->hasModifier(mod)) { - vKeyboard->removeModifier(mod); - btn->setStyleSheet(BUTTON_BG); - btn->setStyleSheet(BUTTON_BG); - } else { - vKeyboard->addModifier(mod); - btn->setStyleSheet(BUTTON_BG_HL); - btn->setStyleSheet(BUTTON_BG_HL); - } - } else if(funcKey != FuncKey::UNKNOWN) { - Q_EMIT keyPressed(funcKey); - } else { //字符键 - QChar c; - QString text = btn->text(); - qDebug() << "clicked button text: " << text; - if(text == "&&") - c = '&'; - else if(text.length() == 1) - c = text.at(0); - - Q_EMIT keyPressed(c); - - //如果shift键被单击,按一个键后就恢复为小写 - if(isShift && !capsLock) { - isShift = false; - toggleCase(); - changeShitKeyStyle(ui->btn_shift_l, false); - changeShitKeyStyle(ui->btn_shift_r, false); - } - clearModifier(); - } -} - -void KeyboardWidget::clearModifier() -{ - for(auto mod : vKeyboard->getAllModifier()) { - QString modName = Modifier::getModifierName(mod); - if(mod == Modifier::SUPER) { - QString objName = QString("btn_%1").arg(modName); - QPushButton *btn = ui->page_letter->findChild(objName); - btn->setStyleSheet(BUTTON_BG); - } else { - QString objName = QString("btn_%1_l").arg(modName); - QPushButton *btn = ui->page_letter->findChild(objName); - btn->setStyleSheet(BUTTON_BG); - objName = QString("btn_%1_r").arg(modName); - btn = ui->page_letter->findChild(objName); - btn->setStyleSheet(BUTTON_BG); - } - } - vKeyboard->clearModifier(); -} - -void KeyboardWidget::toggleCase() -{ - for(int i = 0; i < 26; i++) { - QString objName = "btn_" + QString::number(i); - QPushButton *btn = findChild(objName); - QChar ch; - if(isShift) { //切换到大写 - ch = symbols[0][i].toUpper(); - } else { - ch = symbols[0][i]; - } - btn->setText(ch); - } -} - -void KeyboardWidget::switchPage() -{ - if(page == 0) { - ui->btn_shift_l->setText(""); - ui->btn_shift_r->setText(""); - ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); - } else { - ui->btn_shift_l->setText(""); - ui->btn_shift_r->setText(""); - ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); - ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); - } - - for(int i = 0; i < SYMBOL_KEY_COUNT; i++) { - QString btnObjName = "btn_" + QString::number(i); - QPushButton *btn = ui->page_letter->findChild(btnObjName); - QChar c = symbols[page][i]; - if(c == '&') - btn->setText("&&"); - else - btn->setText(c); - } -} - diff --git a/VirtualKeyboard/src/keyboardwidget.h b/VirtualKeyboard/src/keyboardwidget.h deleted file mode 100644 index 25591ae..0000000 --- a/VirtualKeyboard/src/keyboardwidget.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. -**/ -#ifndef KEYBOARDWIDGET_H -#define KEYBOARDWIDGET_H - -#include -#include -#include -#include "x11keyboard.h" - -namespace Ui { -class KeyboardWidget; -} - -class QPushButton; - -class KeyboardWidget : public QWidget -{ - Q_OBJECT - -public: - explicit KeyboardWidget(QWidget *parent = 0); - ~KeyboardWidget(); - -protected: - void resizeEvent(QResizeEvent *event); - -private: - void bindSingal(); - void toggleCase(); - void switchPage(); - void setDefaultIcon(); - void setIconSize(); - void changeKeyStyle(QPushButton *btn, bool isPressed); - void changeFuncKeyStyle(QPushButton *btn, bool isPressed); - void changeShitKeyStyle(QPushButton *btn, bool isPressed); - void changeDirectKeyStyle(QPushButton *btn, bool isPressed); - void clearModifier(); - QString getKeyName(QPushButton *btn); - - -private Q_SLOTS: - void onButtonClicked(); - void onButtonPressed(); - void onButtonReleased(); - -Q_SIGNALS: - void aboutToClose(); - void keyPressed(QChar c); - void keyPressed(FuncKey::FUNCKEY key); - -private: - Ui::KeyboardWidget *ui; - bool capsLock; //是否大写锁定 - bool isShift; - QTime shiftLastClicked; //shift键上次被点击的时间 - int page; //当前是第几页的键盘 - X11Keyboard *vKeyboard; -}; - -#endif // KEYBOARDWIDGET_H diff --git a/VirtualKeyboard/src/keyboardwidget.ui b/VirtualKeyboard/src/keyboardwidget.ui deleted file mode 100644 index ac55eff..0000000 --- a/VirtualKeyboard/src/keyboardwidget.ui +++ /dev/null @@ -1,1203 +0,0 @@ - - - KeyboardWidget - - - Qt::NonModal - - - - 0 - 0 - 1132 - 293 - - - - - 0 - 0 - - - - - 0 - 0 - - - - KeyboardWidget - - - - 0 - - - QLayout::SetMinAndMaxSize - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 20 - - - QLayout::SetNoConstraint - - - 10 - - - 10 - - - 10 - - - 10 - - - - - 1 - - - - - 0 - - - QLayout::SetNoConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 5 - - - QLayout::SetNoConstraint - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 10 - - - QLayout::SetNoConstraint - - - - - - 0 - 0 - - - - q - - - - - - - - 0 - 0 - - - - w - - - - - - - - 0 - 0 - - - - e - - - - - - - - 0 - 0 - - - - r - - - - - - - - 0 - 0 - - - - t - - - - - - - - 0 - 0 - - - - y - - - - - - - - 0 - 0 - - - - u - - - - - - - - 0 - 0 - - - - i - - - - - - - - 0 - 0 - - - - o - - - - - - - - 0 - 0 - - - - p - - - - - - - - 0 - 0 - - - - - - - - - - - - - 10 - - - QLayout::SetNoConstraint - - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - a - - - - - - - - 0 - 0 - - - - s - - - - - - - - 0 - 0 - - - - d - - - - - - - - 0 - 0 - - - - f - - - - - - - - 0 - 0 - - - - g - - - - - - - - 0 - 0 - - - - h - - - - - - - - 0 - 0 - - - - j - - - - - - - - 0 - 0 - - - - k - - - - - - - - 0 - 0 - - - - l - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - 10 - - - QLayout::SetNoConstraint - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 0 - - - - z - - - - - - - - 0 - 0 - - - - x - - - - - - - - 0 - 0 - - - - c - - - - - - - - 0 - 0 - - - - v - - - - - - - - 0 - 0 - - - - b - - - - - - - - 0 - 0 - - - - n - - - - - - - - 0 - 0 - - - - m - - - - - - - - 0 - 0 - - - - , - - - - - - - - 0 - 0 - - - - . - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - 10 - - - QLayout::SetNoConstraint - - - - - - 0 - 0 - - - - - - - Ctrl - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - Alt - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - Alt - - - - - - - - 0 - 0 - - - - / - - - - - - - - 0 - 0 - - - - Ctrl - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - QLayout::SetNoConstraint - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 10 - - - QLayout::SetNoConstraint - - - - - QLayout::SetNoConstraint - - - 10 - - - - - - 0 - 0 - - - - 9 - - - - - - - - 0 - 0 - - - - 5 - - - - - - - - 0 - 0 - - - - 8 - - - - - - - - 0 - 0 - - - - 4 - - - - - - - - 0 - 0 - - - - 2 - - - - - - - - 0 - 0 - - - - 7 - - - - - - - - 0 - 0 - - - - 1 - - - - - - - - 0 - 0 - - - - 6 - - - - - - - - 0 - 0 - - - - 3 - - - - - - - - 0 - 0 - - - - 0 - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QLayout::SetNoConstraint - - - 10 - - - - - - 0 - 0 - - - - Delete - - - - - - - - 0 - 0 - - - - End - - - - - - - - 0 - 0 - - - - Insert - - - - - - - - 0 - 0 - - - - PgUp - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - Home - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - PgDn - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 5 - - - QLayout::SetNoConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Abc - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - @ - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - 123 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - diff --git a/VirtualKeyboard/src/letterswidget.cpp b/VirtualKeyboard/src/letterswidget.cpp new file mode 100644 index 0000000..f93b522 --- /dev/null +++ b/VirtualKeyboard/src/letterswidget.cpp @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "letterswidget.h" +#include "commondef.h" +#include "plasma-shell-manager.h" +#include +#include +#include + +LettersWidget::LettersWidget(QWidget *parent/* = nullptr*/) + : QWidget(parent) +{ + this->setAttribute(Qt::WA_TranslucentBackground);//背景透明 + initUI(); + + if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland" && !QX11Info::isPlatformX11()) { + isWayland = true; + } + + if(isWayland){ + connect(PlasmaShellManager::getInstance(), &PlasmaShellManager::keyStateChanged, + this, &LettersWidget::onCapsChanged); + }else{ + settings = new QGSettings("org.ukui.peripherals-keyboard", "", this); + connect(settings, &QGSettings::changed, + this, &LettersWidget::onCapsChanged); + } + onCapsChanged(); +} + +LettersWidget::~LettersWidget() +{ + +} + +void LettersWidget::initUI() +{ + // line 1 + QChar chLine1[] = {'q','w','e','r','t','y','u','i','o','p'}; + for (int n = 0; n < sizeof(chLine1)/sizeof(QChar); n++) { + KBButton *letterBtn = new KBButton(this); + QString objName = "btn_" + QString::number(chLine1[n].toLatin1()); + letterBtn->setObjectName(objName); + letterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L1+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*n, + KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + letterBtn->setCharId(chLine1[n]); + letterBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(letterBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[letterBtn] = letterBtn->geometry(); + } + // backspace + KBButton *backspaceBtn = new KBButton(this); + backspaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L1+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*10, + KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + backspaceBtn->setObjectName("btn_backspace"); + backspaceBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + backspaceBtn->setIcon(QIcon(":/images/images/delet.svg")); + connect(backspaceBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[backspaceBtn] = backspaceBtn->geometry(); + qDebug()<<"backspaceBtn geometry:"<geometry(); + + // line 2 + QChar chLine2[] = {'a','s','d','f','g','h','j','k','l'}; + for (int n = 0; n < sizeof(chLine2)/sizeof(QChar); n++) { + KBButton *letterBtn = new KBButton(this); + QString objName = "btn_" + QString::number(chLine2[n].toLatin1()); + letterBtn->setObjectName(objName); + letterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L2+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*n, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING), + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + letterBtn->setCharId(chLine2[n]); + letterBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(letterBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[letterBtn] = letterBtn->geometry(); + } + // enter + KBButton *enterBtn = new KBButton(this); + enterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L2+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*9, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING), + KEYBOARD_FIXED_DEFAULT_ENTERBTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + enterBtn->setObjectName("btn_enter"); + enterBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + enterBtn->setIcon(QIcon(":/images/images/enter.svg")); + connect(enterBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[enterBtn] = enterBtn->geometry(); + + // line 3 + QChar chLine3[] = {'z','x','c','v','b','n','m',',','.'}; + for (int n = 0; n < sizeof(chLine3)/sizeof(QChar); n++) { + KBButton *letterBtn = new KBButton(this); + QString objName = "btn_" + QString::number(chLine3[n].toLatin1()); + letterBtn->setObjectName(objName); + letterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L3+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*(n+1), + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + letterBtn->setCharId(chLine3[n]); + letterBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED, + KEYBOARD_FONT_COLOR_PRESS); + connect(letterBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[letterBtn] = letterBtn->geometry(); + } + // shift l + KBButton *shiftLBtn = new KBButton(this); + shiftLBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L3, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + shiftLBtn->setObjectName("btn_shift_l"); + shiftLBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + shiftLBtn->setIcon(QIcon(":/images/images/shift.svg")); + connect(shiftLBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[shiftLBtn] = shiftLBtn->geometry(); + // shift r + KBButton *shiftRBtn = new KBButton(this); + shiftRBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L3+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*10, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + shiftRBtn->setObjectName("btn_shift_r"); + shiftRBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + shiftRBtn->setIcon(QIcon(":/images/images/shift.svg")); + connect(shiftRBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[shiftRBtn] = shiftRBtn->geometry(); + + // line 4 + KBButton *symbolBtn = new KBButton(this); + symbolBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + symbolBtn->setObjectName("btn_symbol"); + symbolBtn->setText(tr("&&?!")); + symbolBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(symbolBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[symbolBtn] = symbolBtn->geometry(); + + KBButton *numBtn = new KBButton(this); + numBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING), + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + numBtn->setObjectName("btn_num"); + numBtn->setText(tr("123")); + numBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(numBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[numBtn] = numBtn->geometry(); + + KBButton *ctrlBtn = new KBButton(this); + ctrlBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*2, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + ctrlBtn->setObjectName("btn_ctrl"); + ctrlBtn->setText(tr("Ctrl")); + ctrlBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(ctrlBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[ctrlBtn] = ctrlBtn->geometry(); + + KBButton *spaceBtn = new KBButton(this); + spaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*3, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_SPACEBTN_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + spaceBtn->setObjectName("btn_space"); + spaceBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_BORDER_NORMAL, + KEYBOARD_LETTER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + spaceBtn->setIcon(QIcon(":/images/images/space.svg")); + connect(spaceBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[spaceBtn] = spaceBtn->geometry(); + + KBButton *altBtn = new KBButton(this); + altBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*8, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + altBtn->setObjectName("btn_alt"); + altBtn->setText(tr("Alt")); + altBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(altBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[altBtn] = altBtn->geometry(); + + KBButton *leftBtn = new KBButton(this); + leftBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*9, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + leftBtn->setObjectName("btn_left"); + leftBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + leftBtn->setIcon(QIcon(":/images/images/left.svg")); + connect(leftBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[leftBtn] = leftBtn->geometry(); + + KBButton *rightBtn = new KBButton(this); + rightBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_LETTER_L4+(KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*10, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_LETTER_WIDTH, + KEYBOARD_FIXED_DEFAULT_LETTER_HEIGHT); + rightBtn->setObjectName("btn_right"); + rightBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED, + KEYBOARD_OTHER_FONT_COLOR_PRESS); + rightBtn->setIcon(QIcon(":/images/images/right.svg")); + connect(rightBtn, &KBButton::clicked, this, &LettersWidget::onBtnClicked); + m_mapBtnGeometrys[rightBtn] = rightBtn->geometry(); +} + +void LettersWidget::adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical/* = false*/, bool floatStatus) +{ + QMap::iterator itGeometry = m_mapBtnGeometrys.begin(); + for (; itGeometry != m_mapBtnGeometrys.end(); itGeometry ++) { + KBButton *button = itGeometry.key(); + if (button) { + QRect oldGeometry = itGeometry.value(); + QRect newGeometry = oldGeometry; + if (floatStatus) { + newGeometry.setX(oldGeometry.x()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } else { + newGeometry.setX(oldGeometry.x()*lfWidthScale); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } + button->setGeometry(newGeometry); + } + } +} + +void LettersWidget::onBtnClicked(QChar charId) +{ + QObject *obj = sender(); + KBButton *btn = static_cast(obj); + QString objName = btn->objectName(); + int lastUnderline = objName.lastIndexOf('_'); + int start = strlen("btn_"); + int keyLength = lastUnderline - start; + QString keyName = objName.mid(start, keyLength); + + if (charId != QChar::Null && isShift && !capsState) { //第一次按shift,按后取消shift状态 + isShift = false; + changeFuncKeyStyle("shift_l", false); + changeFuncKeyStyle("shift_r", false); + toggleCase(); + } + + if (keyName == "num") { //数字页面 + Q_EMIT specialBtnClicked(PAGE_NUMBER); + } else if (keyName == "symbol") { //符号页面 + Q_EMIT specialBtnClicked(PAGE_CHAR); + } else if (keyName == BTN_SHIFT) { //shift + if (capsState) { + capsState = false; + isShift = false; + changeFuncKeyStyle("shift_l", false); + changeFuncKeyStyle("shift_r", false); + Q_EMIT specialBtnClicked(BTN_CAPSLOCK); + } else if (isShift) { //shift键锁定 + capsState = true; + isShift = true; + changeFuncKeyStyle("shift_l", true); + changeFuncKeyStyle("shift_r", true); + Q_EMIT specialBtnClicked(BTN_CAPSLOCK); + } else { + isShift = true; + changeFuncKeyStyle("shift_l", true); + changeFuncKeyStyle("shift_r", true); + } + toggleCase(); + } else if (charId != QChar::Null) { //字符 + Q_EMIT normalBtnClicked(charId); + } else { //ctrl或者alt + Q_EMIT specialBtnClicked(keyName); + + } +} + +void LettersWidget::onCapsChanged() +{ + if(isWayland){ + capsState = PlasmaShellManager::getInstance()->getKeyState(KWayland::Client::Keystate::Key::CapsLock); + }else{ + capsState = settings->get("capslock-state").toBool(); + } + + isShift = capsState; + for (int i = 97; i < 123; i++) { //大小写切换 + QString objName = QString("btn_%1").arg(QString::number(i)); + KBButton *btn = findChild(objName); + btn->setCapsStatus(capsState); + changeFuncKeyStyle("shift_l", capsState); + changeFuncKeyStyle("shift_r", capsState); + } +} + +void LettersWidget::toggleCase() +{ + for (int i = 97; i < 123; i++) { //大小写切换 + QString objName = QString("btn_%1").arg(QString::number(i)); + KBButton *btn = findChild(objName); + btn->setShiftState(isShift); + } +} + +void LettersWidget::changeFuncKeyStyle(QString obj, bool isLock) +{ + if(obj == BTN_CAPSLOCK) + return; + QString objName = QString("btn_%1").arg(obj); + KBButton *btn = findChild(objName); + if (isLock) { + btn->updateStyleSheet(KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS, + KBButton::BORDER_RADIUS_ALL,true); + if (capsState && obj.contains(BTN_SHIFT)) { + btn->setIcon(QIcon(":/images/images/shift_lock.svg")); + } else if (obj.contains(BTN_SHIFT)) { + btn->setIcon(QIcon(":/images/images/rectangle.svg")); + } + } else { + btn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + if (obj.contains(BTN_SHIFT)) { + btn->setIcon(QIcon(":/images/images/shift.svg")); + } + } +} diff --git a/VirtualKeyboard/src/letterswidget.h b/VirtualKeyboard/src/letterswidget.h new file mode 100644 index 0000000..31ee168 --- /dev/null +++ b/VirtualKeyboard/src/letterswidget.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef LETTERSWIDGET_H +#define LETTERSWIDGET_H + +#include +#include +#include "kbbutton.h" +#include + +class LettersWidget : public QWidget +{ + Q_OBJECT +public: + explicit LettersWidget(QWidget *parent = nullptr); + virtual ~LettersWidget(); + + void adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical = false, bool floatStatus = false); + void changeFuncKeyStyle(QString obj, bool isLock); + +public Q_SLOTS: + void onBtnClicked(QChar charId); + void onCapsChanged(); + +Q_SIGNALS: + void clicked(int nKeyId); + void specialBtnClicked(QString keyName); + void normalBtnClicked(QChar c); + +private: + void initUI(); + void toggleCase(); + +private: + QMap m_mapBtnGeometrys; + + bool isShift = false; + + QGSettings *settings; + bool capsState = false; + bool isWayland = false; +}; + +#endif // LETTERSWIDGET_H diff --git a/VirtualKeyboard/src/main.cpp b/VirtualKeyboard/src/main.cpp index 99fc2f0..dbb84a0 100644 --- a/VirtualKeyboard/src/main.cpp +++ b/VirtualKeyboard/src/main.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "virtualkeyboard.h" #include diff --git a/VirtualKeyboard/src/numberswidget.cpp b/VirtualKeyboard/src/numberswidget.cpp new file mode 100644 index 0000000..a09de13 --- /dev/null +++ b/VirtualKeyboard/src/numberswidget.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "numberswidget.h" +#include "kbbutton.h" +#include "commondef.h" + +#include +#include +#include +#include +#include +#include + +NumbersWidget::NumbersWidget(QWidget *parent) + : QWidget(parent) +{ + this->setAttribute(Qt::WA_TranslucentBackground);//背景透明 + initUI(); +} + +NumbersWidget::~NumbersWidget() +{ + +} + +void NumbersWidget::initUI() +{ + // all chars + m_layoutBtnList = new QVBoxLayout(); + m_layoutBtnList->setContentsMargins(8,0,0,0); + m_layoutBtnList->setSpacing(1); + listFrame = new QFrame(); + listFrame->setObjectName("listFrame"); + listFrame->setLayout(m_layoutBtnList); + listFrame->setStyleSheet("QFrame{border-radius: 8px}"); + listFrame->setFrameStyle(QFrame::Plain); + m_scrollFrame = new QScrollArea(this); + m_scrollFrame->setObjectName("scrollFrame"); + m_scrollFrame->setFocusPolicy(Qt::NoFocus); + m_scrollFrame->setContentsMargins(0, 0, 0, 0); + m_scrollFrame->setStyleSheet("QScrollArea {background-color: #C0CED3D9; border-radius:8px;}"); + m_scrollFrame->viewport()->setStyleSheet("background-color:transparent;"); + m_scrollFrame->verticalScrollBar()->setProperty("drawScrollBarGroove", false); + m_scrollFrame->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollFrame->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + m_scrollFrame->setWidgetResizable(true); + m_scrollFrame->setWidget(listFrame); + m_scrollFrame->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L1, KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, KEYBOARD_FIXED_DEFAULT_NUMBER_CHARS_HEIGHT); + listFrame->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L1, KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, KEYBOARD_FIXED_DEFAULT_NUMBER_CHARS_HEIGHT); + m_mapBtnGeometrys[m_scrollFrame] = m_scrollFrame->geometry(); + //m_mapBtnGeometrys[listFrame] = listFrame->geometry(); + QChar chChars[] = {',', '.', '?', '!', '\'', ':', '~', '@', ';', '"', + '/', '(', ')', '_', '+', '=', '`', '^', '#', '*', + '%', '&', '\\', '[', ']', '<', '>', '{', '}', '|', + '$', '-'}; + for (int n = 0; n < sizeof(chChars)/sizeof(QChar); n++) { + KBButton *charBtn = new KBButton(listFrame); + charBtn->setCharId(chChars[n]); + charBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_NORMAL, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS, + KBButton::BORDER_RADIUS_NONE); + charBtn->setObjectName(QString("btn_%1").arg(QString(chChars[n]))); + connect(charBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + charBtn->setFixedHeight(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + m_layoutBtnList->addWidget(charBtn); + } + // line 1 + QChar chLine1[] = {'1','2','3'}; + for (int n = 0; n < sizeof(chLine1)/sizeof(QChar); n++) { + KBButton *numberBtn = new KBButton(this); + numberBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L1+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*(n+1), + KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + numberBtn->setCharId(chLine1[n]); + numberBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(numberBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[numberBtn] = numberBtn->geometry(); + } + // backspace + KBButton *backspaceBtn = new KBButton(this); + backspaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L1+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*4, + KEYBOARD_FIXED_DEFAULT_TMARGIN, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + backspaceBtn->setObjectName("btn_backspace"); + backspaceBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + backspaceBtn->setIcon(QIcon(":/images/images/delet.svg")); + connect(backspaceBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[backspaceBtn] = backspaceBtn->geometry(); + + // line 2 + QChar chLine2[] = {'4','5','6'}; + for (int n = 0; n < sizeof(chLine2)/sizeof(QChar); n++) { + KBButton *numberBtn = new KBButton(this); + numberBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L2+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*(n+1), + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*1, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + numberBtn->setCharId(chLine2[n]); + numberBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(numberBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[numberBtn] = numberBtn->geometry(); + } + // @ + KBButton *atBtn = new KBButton(this); + atBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L2+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*4, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*1, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + atBtn->setCharId('@'); + atBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(atBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[atBtn] = atBtn->geometry(); + // line 3 + QChar chLine3[] = {'7','8','9'}; + for (int n = 0; n < sizeof(chLine3)/sizeof(QChar); n++) { + KBButton *numberBtn = new KBButton(this); + numberBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L3+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*(n+1), + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + numberBtn->setCharId(chLine3[n]); + numberBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_BORDER_NORMAL,KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(numberBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[numberBtn] = numberBtn->geometry(); + } + // symbol + KBButton *symbolBtn = new KBButton(this); + symbolBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L3+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*4, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*2, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + symbolBtn->setObjectName("btn_symbol"); + symbolBtn->setText(tr("&&?!")); + symbolBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(symbolBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[symbolBtn] = symbolBtn->geometry(); + + // line 4 + KBButton *returnBtn = new KBButton(this); + returnBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L4, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + returnBtn->setObjectName("btn_return"); + returnBtn->setText(tr("Return")); + returnBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + connect(returnBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[returnBtn] = returnBtn->geometry(); + + // space + KBButton *spaceBtn = new KBButton(this); + spaceBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L4+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*1, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + spaceBtn->setObjectName("btn_space"); + spaceBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_BORDER_NORMAL, + KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + spaceBtn->setIcon(QIcon(":/images/images/space.svg")); + connect(spaceBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[spaceBtn] = spaceBtn->geometry(); + + // . + KBButton *dianBtn = new KBButton(this); + dianBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L4+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*3, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + dianBtn->setCharId('.'); + dianBtn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_BORDER_NORMAL, + KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(dianBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[dianBtn] = dianBtn->geometry(); + + // 9 + KBButton *num0Btn = new KBButton(this); + num0Btn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L4+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*2, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + num0Btn->setCharId('0'); + num0Btn->updateStyleSheet(KEYBOARD_LETTER_COLOR_NORMAL,KEYBOARD_LETTER_COLOR_PRESSED, + KEYBOARD_LETTER_COLOR_PRESSED,KEYBOARD_LETTER_COLOR_BORDER_NORMAL, + KEYBOARD_LETTER_COLOR_BORDER_PRESSED,KEYBOARD_FONT_COLOR_PRESS); + connect(num0Btn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[num0Btn] = num0Btn->geometry(); + + // enter + KBButton *enterBtn = new KBButton(this); + enterBtn->setGeometry(KEYBOARD_FIXED_DEFAULT_NUMBER_L3+(KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH+KEYBOAED_FIXED_DEFAULT_HSPACING)*4, + KEYBOARD_FIXED_DEFAULT_TMARGIN+(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT+KEYBOAED_FIXED_DEFAULT_VSPACING)*3, + KEYBOARD_FIXED_DEFAULT_NUMBER_WIDTH, + KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT); + enterBtn->setObjectName("btn_enter"); + enterBtn->updateStyleSheet(KEYBOARD_OTHER_COLOR_NORMAL,KEYBOARD_OTHER_COLOR_PRESSED, + KEYBOARD_OTHER_COLOR_PRESSED,KEYBOARD_OTHER_COLOR_BORDER_NORMAL, + KEYBOARD_OTHER_COLOR_BORDER_PRESSED,KEYBOARD_OTHER_FONT_COLOR_PRESS); + enterBtn->setIcon(QIcon(":/images/images/enter.svg")); + connect(enterBtn, &KBButton::clicked, this, &NumbersWidget::onBtnClicked); + m_mapBtnGeometrys[enterBtn] = enterBtn->geometry(); +} + +void NumbersWidget::adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical/* = false*/, bool floatStatus) +{ + QMap::iterator itGeometry = m_mapBtnGeometrys.begin(); + for (; itGeometry != m_mapBtnGeometrys.end(); itGeometry ++) { + QWidget *widget = itGeometry.key(); + if (widget) { + QRect oldGeometry = itGeometry.value(); + QRect newGeometry = oldGeometry; + if (floatStatus) { + newGeometry.setX(oldGeometry.x()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale*KEYBOARD_FLOAT_PERCENTAGE); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } else { + newGeometry.setX(oldGeometry.x()*lfWidthScale); + newGeometry.setY(oldGeometry.y()*lfHeightScale); + newGeometry.setWidth(oldGeometry.width()*lfWidthScale); + newGeometry.setHeight(oldGeometry.height()*lfHeightScale); + } + widget->setGeometry(newGeometry); + } + } + + QChar chChars[] = {',', '.', '?', '!', '\'', ':', '~', '@', ';', '"', + '/', '(', ')', '_', '+', '=', '`', '^', '#', '*', + '%', '&', '\\', '[', ']', '<', '>', '{', '}', '|', + '$', '-'}; + for (int n = 0; n < sizeof(chChars)/sizeof(QChar); n++) { //单独更新符号btn的高度 + QString objName = QString("btn_%1").arg(QString(chChars[n])); + KBButton *btn = findChild(objName); + btn->setFixedHeight(KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT *lfHeightScale); + } + //更新listfarame的高度 + listFrame->setFixedHeight((KEYBOARD_FIXED_DEFAULT_NUMBER_HEIGHT *lfHeightScale +1) * (m_layoutBtnList->count())); +} + +void NumbersWidget::onBtnClicked(QChar charId) +{ + QObject *obj = sender(); + KBButton *btn = static_cast(obj); + QString objName = btn->objectName(); + int lastUnderline = objName.lastIndexOf('_'); + int start = strlen("btn_"); + int keyLength = lastUnderline - start; + QString keyName = objName.mid(start, keyLength); + qDebug() << "keyName: " << keyName; + if (keyName == BTN_RETURN) { + Q_EMIT specialBtnClicked(PAGE_LETTER); + } else if (keyName == "symbol") { + Q_EMIT specialBtnClicked(PAGE_CHAR); + } else if (charId != QChar::Null) { + Q_EMIT narmalBtnClicked(charId); + } else if (keyName == BTN_BACK) { + Q_EMIT specialBtnClicked(BTN_BACK); + } else { + Q_EMIT specialBtnClicked(keyName); + } +} diff --git a/VirtualKeyboard/src/numberswidget.h b/VirtualKeyboard/src/numberswidget.h new file mode 100644 index 0000000..bea0f28 --- /dev/null +++ b/VirtualKeyboard/src/numberswidget.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef NUMBERSWIDGET_H +#define NUMBERSWIDGET_H + +#include +#include + +class KBButton; +class QVBoxLayout; +class QScrollArea; +class QFrame; +class NumbersWidget : public QWidget +{ + Q_OBJECT +public: + explicit NumbersWidget(QWidget *parent = nullptr); + virtual ~NumbersWidget(); + + void adjustGeometry(double lfWidthScale, double lfHeightScale, bool isVertical = false, bool floatStatus = false); + +public Q_SLOTS: + void onBtnClicked(QChar charId); + +Q_SIGNALS: + void clicked(int nKeyId); + void specialBtnClicked(QString keyName); + void narmalBtnClicked(QChar charId); + +private: + void initUI(); + +private: + QMap m_mapBtnGeometrys; + QVBoxLayout *m_layoutBtnList = nullptr; + QScrollArea *m_scrollFrame = nullptr; + QFrame *listFrame = nullptr; +}; + +#endif // NUMBERSWIDGET_H diff --git a/VirtualKeyboard/src/qtkeyboard.cpp b/VirtualKeyboard/src/qtkeyboard.cpp new file mode 100644 index 0000000..a87495b --- /dev/null +++ b/VirtualKeyboard/src/qtkeyboard.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "qtkeyboard.h" +#include +#include +#include +#include +#include +#include +#include "plasma-shell-manager.h" + +QMap m_specialSymbolMap = { + {' ', Qt::Key_Space}, + {',', Qt::Key_Comma}, + {'.', Qt::Key_Period}, + {'\'', Qt::Key_QuoteLeft}, + {'@', Qt::Key_At}, + {'#', Qt::Key_NumberSign}, + {'$', Qt::Key_Dollar}, + {'%', Qt::Key_Percent}, + {'&', Qt::Key_Ampersand}, + {'*', Qt::Key_Asterisk}, + {'(', Qt::Key_ParenLeft}, + {')', Qt::Key_ParenRight}, + {'-', Qt::Key_Minus}, + {'+', Qt::Key_Plus}, + {'!', Qt::Key_Exclam}, + {'"', Qt::Key_QuoteDbl}, + {'<', Qt::Key_Less}, + {'>', Qt::Key_Greater}, + {':', Qt::Key_Colon}, + {';', Qt::Key_Semicolon}, + {'/', Qt::Key_Slash}, + {'?', Qt::Key_Question}, + {'=', Qt::Key_Equal}, + {'.', Qt::Key_Period}, /*XK_kana_middledot*/ + {'~', Qt::Key_AsciiTilde}, + {'`', Qt::Key_QuoteLeft}, + {'|', Qt::Key_Bar}, + {'^', Qt::Key_AsciiCircum}, + {'{', Qt::Key_BraceLeft}, + {'}', Qt::Key_BraceRight}, + {'[', Qt::Key_BracketLeft}, + {']', Qt::Key_BracketRight}, + {'_', Qt::Key_Underscore}, + {'\\', Qt::Key_Backslash}, +}; + +QMap m_funckeyMap = { + {FuncKey::SPACE, Qt::Key_Space}, + {FuncKey::BACKSPACE, Qt::Key_Backspace}, + {FuncKey::ENTER, Qt::Key_Enter}, + {FuncKey::HOME, Qt::Key_Home}, + {FuncKey::END, Qt::Key_End}, + {FuncKey::PGUP, Qt::Key_PageUp}, + {FuncKey::PGDN, Qt::Key_PageDown}, + {FuncKey::INSERT, Qt::Key_Insert}, + {FuncKey::DELETE, Qt::Key_Delete}, + {FuncKey::UP, Qt::Key_Up}, + {FuncKey::DOWN, Qt::Key_Down}, + {FuncKey::LEFT, Qt::Key_Left}, + {FuncKey::RIGHT, Qt::Key_Right} +}; + +QMap m_modifierMap = { + {Modifier::CTRL, Qt::ControlModifier}, + {Modifier::ALT, Qt::AltModifier}, + {Modifier::SUPER, Qt::MetaModifier}, + {Modifier::SHIFT, Qt::ShiftModifier} +}; + +QVector m_shiftKeyVec = {'~', '!', '@', '#', '$', '%', '^', '&', '*', + '(', ')', '_', '+', '{', '}', '|', ':', '"', + '>', '?'}; + +#define DRM_DIR "/sys/class/leds/" +#define CAPSLOCK_STATUS "capslock_state" + +/** + * @brief 判断大写键状态 + * @return true: 大写锁定 + */ +bool QtKeyboard::checkCapsLockState() +{ + QDir ledDir(DRM_DIR); + QStringList leds = ledDir.entryList(QDir::Dirs); + QString capsFile; + + for(int i = 0;i QtKeyboard::getAllModifier() +{ + return modList; +} + +void QtKeyboard::clearModifier() +{ + modList.clear(); +} + + +void QtKeyboard::onKeyPressed(QChar c) +{ + /*判断大写锁定打开时,转换字母大小写状态,与x11keyboard类逻辑保持一致*/ + if(checkCapsLockState() && c.isLetter()){ + if(c.isUpper()){ + c = c.toLower(); + } + else if(c.isLower()){ + c = c.toUpper(); + } + } + + if(c>='A' && c<='Z'){ + sendKey(c.toLatin1(),c); + }else if(c>='a' && c<='z'){ + sendKey(c.toLatin1() - 32,c); + }else if(c >= '0' && c<='9'){ + sendKey(c.toLatin1(),c); + }else if(m_specialSymbolMap.contains(c)){ + sendKey(m_specialSymbolMap[c],c); + }else { + sendKey(c.toLatin1(),c); + } +} + +void QtKeyboard::onKeyPressed(FuncKey::FUNCKEY key) +{ + int keysym = m_funckeyMap[key]; + /*这里的text根据实际按键得到的QEvent中的text内容打印*/ + if(key == FuncKey::SPACE){ + sendKey(keysym," "); + }else if(key == FuncKey::BACKSPACE){ + sendKey(keysym,"\b"); + }else if(key == FuncKey::ENTER){ + sendKey(keysym,"\r"); + }else if(key == FuncKey::INSERT){ + sendKey(keysym,"\u007F"); + }else if(key == FuncKey::CAPSLOCK){ + PlasmaShellManager::getInstance()->setKeyPressed(58); + }else{ + sendKey(keysym,""); + } +} + +void QtKeyboard::sendKey(const unsigned int keysym,const QString text) +{ + Qt::KeyboardModifiers modifier = Qt::NoModifier; + for(auto mod : modList){ + modifier = modifier | m_modifierMap[mod]; + } + + QWidget *objfous = QApplication::focusWidget(); + + if(objfous){ + QKeyEvent event1(QEvent::KeyPress, keysym + , modifier, text + , true, 1); + QKeyEvent event2(QEvent::KeyRelease, keysym + , modifier, text + , true, 1); + + QCoreApplication::sendEvent(objfous, &event1); + QCoreApplication::sendEvent(objfous, &event2); + } + +} diff --git a/VirtualKeyboard/src/qtkeyboard.h b/VirtualKeyboard/src/qtkeyboard.h new file mode 100644 index 0000000..a9c9690 --- /dev/null +++ b/VirtualKeyboard/src/qtkeyboard.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef QTKEYBOARD_H +#define QTKEYBOARD_H + +#include +#include +#include "fakekeyboard.h" + +class QtKeyboard : public FakeKeyboard +{ + Q_OBJECT +public: + explicit QtKeyboard(QObject *parent = nullptr); + ~QtKeyboard(); + void addModifier(Modifier::MOD mod); + void removeModifier(Modifier::MOD mod); + bool hasModifier(Modifier::MOD mod); + QList getAllModifier(); + void clearModifier(); + +public Q_SLOTS: + void onKeyPressed(QChar c); + void onKeyPressed(FuncKey::FUNCKEY key); + +private: + void sendKey(const unsigned int keyCode,const QString text); + bool checkCapsLockState(); + +private: + QList modList; +}; + +#endif // QTKEYBOARD_H diff --git a/VirtualKeyboard/src/virtualkeyboard.cpp b/VirtualKeyboard/src/virtualkeyboard.cpp deleted file mode 100644 index ea46695..0000000 --- a/VirtualKeyboard/src/virtualkeyboard.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. -**/ -#include "virtualkeyboard.h" -#include -#include -#include -#include - -VirtualKeyboard::VirtualKeyboard(QWidget *parent) - : QWidget(parent) -{ - Q_INIT_RESOURCE(keyboard); - - setAutoFillBackground(true); - QPalette plt; - plt.setBrush(QPalette::Background, Qt::black); - setPalette(plt); - - setWindowFlags(Qt::FramelessWindowHint | - Qt::WindowStaysOnTopHint | - Qt::WindowDoesNotAcceptFocus); - - - keyboardWidget = new KeyboardWidget(this); - QHBoxLayout *hl_keyboard = new QHBoxLayout(this); - QSpacerItem *spacer = new QSpacerItem(40, 20); - hl_keyboard->addSpacerItem(spacer); - hl_keyboard->addWidget(keyboardWidget); - QSpacerItem *spacer2 = new QSpacerItem(40, 20); - hl_keyboard->addSpacerItem(spacer2); - - QFile qssFile(":/qss/keyboard.qss"); - qssFile.open(QIODevice::ReadOnly); - setStyleSheet(qssFile.readAll()); - qssFile.close(); - - QDesktopWidget *desktop = QApplication::desktop(); - cursorMonitor = new CursorMonitor(this); - - //在多显示器情况下,监视鼠标指针的位置和主显示器变化信号 - connect(cursorMonitor, &CursorMonitor::cursorPosChanged, - this, [&](const QPoint &pos){ - adjustGeometry(desktop->screenNumber(pos)); - }); - - connect(desktop, &QDesktopWidget::primaryScreenChanged, - this, [&]{ - adjustGeometry(desktop->primaryScreen()); - }); - - connect(keyboardWidget, &KeyboardWidget::aboutToClose, - this, &VirtualKeyboard::aboutToClose); - - adjustGeometry(desktop->primaryScreen()); -} - -void VirtualKeyboard::adjustGeometry(int screen) -{ - QDesktopWidget *desktop = QApplication::desktop(); - QWidget *activateScreen = desktop->screen(screen); - setGeometry(0, activateScreen->height() - activateScreen->height() / 3, - activateScreen->width(), activateScreen->height() / 3); -} diff --git a/VirtualKeyboard/src/virtualkeyboard.h b/VirtualKeyboard/src/virtualkeyboard.h deleted file mode 100644 index 44b628a..0000000 --- a/VirtualKeyboard/src/virtualkeyboard.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. -**/ -#ifndef VIRTUALKEYBOARD_H -#define VIRTUALKEYBOARD_H - -#include -#include - -#include "keyboardwidget.h" -#include "cursormonitor.h" - -class VirtualKeyboard : public QWidget -{ - Q_OBJECT -public: - explicit VirtualKeyboard(QWidget *parent = 0); - -private: - void adjustGeometry(int screen); - -Q_SIGNALS: - void aboutToClose(); - -private: - KeyboardWidget *keyboardWidget; - CursorMonitor *cursorMonitor; - bool isApplication; -}; - - -#endif // VIRTUALKEYBOARD_H diff --git a/VirtualKeyboard/src/virtualkeyboardwidget.cpp b/VirtualKeyboard/src/virtualkeyboardwidget.cpp new file mode 100644 index 0000000..4318702 --- /dev/null +++ b/VirtualKeyboard/src/virtualkeyboardwidget.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "virtualkeyboardwidget.h" + +#include +#include +#include +#include +#include "commondef.h" +#include +#include +#include "dragwidget.h" +#include "kbtitle.h" +#include "letterswidget.h" +#include "numberswidget.h" +#include "charswidget.h" +#include "charsmorewidget.h" +#include "x11keyboard.h" +#include "qtkeyboard.h" + +VirtualKeyboardWidget::VirtualKeyboardWidget(QWidget *parent) + : QWidget(parent) + , m_lfWidthScale(1.0) + , m_lfHeightScale(1.0) + , m_isVertical(false) +{ + Q_INIT_RESOURCE(keyboard); + setAttribute(Qt::WA_TranslucentBackground);//背景透明 + //setAutoFillBackground(true); + setWindowFlags(Qt::FramelessWindowHint | + Qt::WindowStaysOnTopHint | + Qt::WindowDoesNotAcceptFocus); + + if(QX11Info::isPlatformX11()){ + vKeyboard = new X11Keyboard(this); + }else{ + vKeyboard = new QtKeyboard(this); + } + + connect(this, SIGNAL(keyPressed(QChar)), + vKeyboard, SLOT(onKeyPressed(QChar))); + connect(this, SIGNAL(keyPressed(FuncKey::FUNCKEY)), + vKeyboard, SLOT(onKeyPressed(FuncKey::FUNCKEY))); + initUI(); + initConnections(); +} + +VirtualKeyboardWidget::~VirtualKeyboardWidget() +{ + +} + +void VirtualKeyboardWidget::initUI() +{ + QVBoxLayout *layoutMain = new QVBoxLayout(this); + layoutMain->setContentsMargins(0,0,0,0); + layoutMain->setSpacing(0); + + m_dragWidget = new DragWidget(); + layoutMain->addWidget(m_dragWidget); + m_dragWidget->installEventFilter(this); + + m_kbTitle = new KBTitle(); + layoutMain->addWidget(m_kbTitle); + + m_stackedWidget = new QStackedWidget(); + + m_lettersWidget = new LettersWidget(); + m_stackedWidget->addWidget(m_lettersWidget); + + m_numbersWidget = new NumbersWidget(this); + m_stackedWidget->addWidget(m_numbersWidget); + + m_charsWidget = new CharsWidget(); + m_stackedWidget->addWidget(m_charsWidget); + + m_charsMoreWidget = new CharsMoreWidget(); + m_stackedWidget->addWidget(m_charsMoreWidget); + + m_stackedWidget->setCurrentIndex(VKB_PAGE_LETTERS); + m_nCurPage = VKB_PAGE_CHARSMORE; + layoutMain->addWidget(m_stackedWidget); +} + +void VirtualKeyboardWidget::initConnections() +{ + connect(m_kbTitle, &KBTitle::btnClicked, this, &VirtualKeyboardWidget::onSpecialBtnClicked); + connect(m_lettersWidget, &LettersWidget::specialBtnClicked, this, &VirtualKeyboardWidget::onSpecialBtnClicked); + connect(m_lettersWidget, &LettersWidget::normalBtnClicked, this, &VirtualKeyboardWidget::onNormalBtnClicked); + connect(m_numbersWidget, &NumbersWidget::specialBtnClicked, this, &VirtualKeyboardWidget::onSpecialBtnClicked); + connect(m_numbersWidget, &NumbersWidget::narmalBtnClicked, this, &VirtualKeyboardWidget::onNormalBtnClicked); + connect(m_charsWidget, &CharsWidget::specialBtnClicked, this, &VirtualKeyboardWidget::onSpecialBtnClicked); + connect(m_charsWidget, &CharsWidget::normalBtnClicked, this, &VirtualKeyboardWidget::onNormalBtnClicked); + connect(m_charsMoreWidget, &CharsMoreWidget::specialBtnClicked, this, &VirtualKeyboardWidget::onSpecialBtnClicked); + connect(m_charsMoreWidget, &CharsMoreWidget::normalBtnClicked, this, &VirtualKeyboardWidget::onNormalBtnClicked); +} + +void VirtualKeyboardWidget::adjustGeometry() +{ + QWidget *parentWidget = qobject_cast(parent()); + if (parentWidget) { + //qDebug()<< "parent: " << parentWidget <<"Parent gemotry:"<geometry(); + double lfWidth = parentWidget->geometry().width(); + double lfHeight = parentWidget->geometry().height(); + m_isVertical = lfHeight > lfWidth; + m_lfWidthScale = lfWidth/KEYBOARD_PARENT_DEFAULT_WIDTH; + if (m_isVertical) + m_lfHeightScale = lfHeight / KEYBOARD_PARENT_DEFAULT_WIDTH; + else + m_lfHeightScale = lfHeight / KEYBOARD_PARENT_DEFAULT_HEIGHT; + if (m_isdragState) { + lfWidth = m_lfWidthScale * KEYBOARD_DRAGSHOW_FIXED_DEFAULT_WIDTH; + lfHeight = m_lfHeightScale * KEYBOARD_DRAGSHOW_FIXED_DEFAULT_HEIGHT; + setGeometry(QRect(m_lfWidthScale * (KEYBOARD_PARENT_DEFAULT_WIDTH - KEYBOARD_DRAGSHOW_FIXED_DEFAULT_WIDTH) / 2, + parentWidget->geometry().height() - lfHeight, + lfWidth, lfHeight)); + m_dragWidget->show(); + } else { + lfWidth = m_lfWidthScale * KEYBOARD_FIXED_DEFAULT_WIDTH; + lfHeight = m_lfHeightScale * KEYBOARD_DRAGHIDE_FIXED_DEFAULT_HEIGHT; + m_dragWidget->hide(); + setGeometry(QRect(0, parentWidget->geometry().height()-lfHeight, lfWidth, lfHeight)); + } + + //qDebug()<<"Widget geometry:"<show(); + } else { + setGeometry(QRect(0, 0, + KEYBOARD_FIXED_DEFAULT_WIDTH, KEYBOARD_DRAGHIDE_FIXED_DEFAULT_HEIGHT)); + m_dragWidget->hide(); + } + m_lfWidthScale = 1.0; + m_lfHeightScale = 1.0; + m_isVertical = false; + } + if (m_dragWidget) { + m_dragWidget->adjustGeometry(m_lfWidthScale, m_lfHeightScale, m_isVertical, m_isdragState); + } + if (m_kbTitle) { + m_kbTitle->adjustGeometry(m_lfWidthScale, m_lfHeightScale, m_isVertical, m_isdragState); + } + if (m_lettersWidget) { + m_lettersWidget->adjustGeometry(m_lfWidthScale, m_lfHeightScale, m_isVertical, m_isdragState); + } + if (m_numbersWidget) { + m_numbersWidget->adjustGeometry(m_lfWidthScale, m_lfHeightScale, m_isVertical, m_isdragState); + } + if (m_charsWidget) { + m_charsWidget->adjustGeometry(m_lfWidthScale, m_lfHeightScale, m_isVertical, m_isdragState); + } + if (m_charsMoreWidget) { + m_charsMoreWidget->adjustGeometry(m_lfWidthScale, m_lfHeightScale, m_isVertical, m_isdragState); + } +} + +bool VirtualKeyboardWidget::eventFilter(QObject *watched, QEvent *event) +{ + if(watched != m_dragWidget && !isMove) return QWidget::eventFilter(watched, event); + switch(event->type()) + { + case QEvent::MouseButtonPress: + onMouseEvents(1); + return true; + case QEvent::MouseMove: + onMouseEvents(2); + return true; + case QEvent::MouseButtonRelease: + onMouseEvents(3); + return true; + default: + break; + } + return QWidget::eventFilter(watched, event); +} + +void VirtualKeyboardWidget::resizeEvent(QResizeEvent *event) +{ + adjustGeometry(); +} + +void VirtualKeyboardWidget::paintEvent(QPaintEvent *event) +{ + QPainterPath path; + QPainter painter(this); + painter.setOpacity(1.0); + painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; + painter.setClipping(true); + painter.setPen(Qt::transparent); + if (m_isdragState) { + path.addRoundedRect(this->rect(), 16, 16); + } else { + path.addRoundedRect(this->rect(), 0, 0); + } + path.setFillRule(Qt::WindingFill); + painter.setBrush(QColor("#EBEDEF")); + painter.setPen(Qt::transparent); + painter.drawPath(path); + QWidget::paintEvent(event); +} + +void VirtualKeyboardWidget::onSpecialBtnClicked(QString keyName) +{ + Modifier::MOD mod = Modifier::getModifier(keyName); + FuncKey::FUNCKEY funcKey = FuncKey::getKey(keyName); + if (mod != Modifier::UNKNOWN) { + if(vKeyboard->hasModifier(mod)) { + vKeyboard->removeModifier(mod); + m_lettersWidget->changeFuncKeyStyle(keyName, false); + } else { + vKeyboard->addModifier(mod); + m_lettersWidget->changeFuncKeyStyle(keyName, true); + } + if (keyName == BTN_CAPSLOCK) { + Q_EMIT keyPressed(FuncKey::CAPSLOCK); + clearModifier(); + } + } else if(funcKey != FuncKey::UNKNOWN) { + Q_EMIT keyPressed(funcKey); + } else if (keyName == PAGE_CHARSMORE) { + m_stackedWidget->setCurrentIndex(VKB_PAGE_CHARSMORE); + update(); + } else if (keyName == PAGE_CHAR) { + m_stackedWidget->setCurrentIndex(VKB_PAGE_CHARS); + update(); + } else if (keyName == PAGE_NUMBER) { + m_stackedWidget->setCurrentIndex(VKB_PAGE_NUMBERS); + update(); + } else if (keyName == PAGE_LETTER) { + m_stackedWidget->setCurrentIndex(VKB_PAGE_LETTERS); + update(); + } else if (keyName == BTN_FLOAT) { + m_isdragState = !m_isdragState; + adjustGeometry(); + Q_EMIT aboutToFloat(); + } else if (keyName == BTN_CLOSE) { + Q_EMIT aboutToClose(); + } +} + +void VirtualKeyboardWidget::onNormalBtnClicked(QChar c) +{ + Q_EMIT keyPressed(c); + clearModifier(); +} + +void VirtualKeyboardWidget::clearModifier() +{ + for(auto mod : vKeyboard->getAllModifier()) { + QString modName = Modifier::getModifierName(mod); + m_lettersWidget->changeFuncKeyStyle(modName, false); + } + vKeyboard->clearModifier(); +} + +void VirtualKeyboardWidget::onMouseEvents(int type) +{ + switch (type) { + case 1: + { + isMove = true; + lastPoint = QCursor::pos(); + break; + } + case 2: + { + if(isMove) + { + QPoint cPoint = QCursor::pos(); + QPoint p = pos(); + p.setX(p.x() - lastPoint.x() + cPoint.x()); + p.setY(p.y() - lastPoint.y() + cPoint.y()); + lastPoint = cPoint; + move(p); + } + break; + } + case 3: + { + isMove = false; + break; + } + default: + break; + } +} + + +bool VirtualKeyboardWidget::getFloatStatus() +{ + return m_isdragState; +} diff --git a/VirtualKeyboard/src/virtualkeyboardwidget.h b/VirtualKeyboard/src/virtualkeyboardwidget.h new file mode 100644 index 0000000..b7abe87 --- /dev/null +++ b/VirtualKeyboard/src/virtualkeyboardwidget.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef VIRTUALKEYBOARDWIDGET_H +#define VIRTUALKEYBOARDWIDGET_H + +#include +#include +#include +#include +#include "fakekeyboard.h" +#include "plasma-shell-manager.h" + +class DragWidget; +class KBTitle; +class LettersWidget; +class NumbersWidget; +class CharsWidget; +class CharsMoreWidget; +class VirtualKeyboardWidget : public QWidget +{ + Q_OBJECT +public: + enum { + VKB_PAGE_LETTERS, + VKB_PAGE_NUMBERS, + VKB_PAGE_CHARS, + VKB_PAGE_CHARSMORE, + }; + VirtualKeyboardWidget(QWidget *parent = nullptr); + virtual ~VirtualKeyboardWidget(); + bool getFloatStatus(); + void adjustGeometry(); + +public Q_SLOTS: + void onNormalBtnClicked(QChar c); + void onSpecialBtnClicked(QString keyName); + +Q_SIGNALS: + void aboutToClose(); + void aboutToFloat(); + void keyPressed(QChar c); + void keyPressed(FuncKey::FUNCKEY key); + +protected: + void paintEvent(QPaintEvent *) override; + void resizeEvent(QResizeEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + void initUI(); + void initConnections(); +// void adjustGeometry(); + void onMouseEvents(int type); + void clearModifier(); + +private: + double m_lfWidthScale; + double m_lfHeightScale; + bool m_isVertical; + QStackedWidget *m_stackedWidget = nullptr; + LettersWidget *m_lettersWidget = nullptr; + NumbersWidget *m_numbersWidget = nullptr; + CharsWidget *m_charsWidget = nullptr; + CharsMoreWidget *m_charsMoreWidget = nullptr; + KBTitle *m_kbTitle = nullptr; + DragWidget *m_dragWidget = nullptr; + int m_nCurPage; + QList m_listPageHis; + bool m_isdragState = false;//是否为悬浮状态 + bool isMove;// 是否可移动 + QPoint lastPoint;// 拖拽控件时 记录当前控件的位置 + FakeKeyboard *vKeyboard; +}; + +#endif // VIRTUALKEYBOARDWIDGET_H diff --git a/VirtualKeyboard/src/x11keyboard.cpp b/VirtualKeyboard/src/x11keyboard.cpp index 5e160ed..c7cd2c8 100644 --- a/VirtualKeyboard/src/x11keyboard.cpp +++ b/VirtualKeyboard/src/x11keyboard.cpp @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "x11keyboard.h" #include @@ -22,8 +21,6 @@ #include #include - - struct CharMap { QChar name; KeySym code; @@ -79,14 +76,15 @@ QMap funckeyMap = { {FuncKey::UP, XK_Up}, {FuncKey::DOWN, XK_Down}, {FuncKey::LEFT, XK_Left}, - {FuncKey::RIGHT, XK_Right} + {FuncKey::RIGHT, XK_Right}, + {FuncKey::CAPSLOCK, XK_Caps_Lock} }; QMap modifierMap = { {Modifier::CTRL, XK_Control_L}, {Modifier::ALT, XK_Alt_L}, {Modifier::SUPER, XK_Super_L}, - {Modifier::SHIFT, XK_Shift_L} + {Modifier::SHIFT, XK_Shift_L}, }; QVector shiftKeyVec = {'~', '!', '@', '#', '$', '%', '^', '&', '*', @@ -123,7 +121,7 @@ unsigned int keyCodeOfChar(QChar c) } X11Keyboard::X11Keyboard(QObject *parent) - : QObject(parent) + : FakeKeyboard(parent) { } @@ -168,6 +166,7 @@ void X11Keyboard::onKeyPressed(QChar c) void X11Keyboard::onKeyPressed(FuncKey::FUNCKEY key) { KeyCode keyCode; + KeySym keysym = funckeyMap[key]; if(keysym != NoSymbol) @@ -203,6 +202,9 @@ void X11Keyboard::sendKey(unsigned int keyCode) KeyCode keyCode = XKeysymToKeycode(display, modifierMap[mod]); XTestFakeKeyEvent(display, keyCode, False, 2); } + + //输入结束清除shift状态 + isShift = false; XFlush(display); } diff --git a/VirtualKeyboard/src/x11keyboard.h b/VirtualKeyboard/src/x11keyboard.h index 42fd997..9914019 100644 --- a/VirtualKeyboard/src/x11keyboard.h +++ b/VirtualKeyboard/src/x11keyboard.h @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,85 +12,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef X11KEYBOARD_H #define X11KEYBOARD_H #include #include +#include "fakekeyboard.h" -class Modifier : public QObject -{ - Q_OBJECT -public: - Modifier(){} - - enum MOD{ - UNKNOWN = -1, - CTRL, - SHIFT, - ALT, - SUPER - }; - Q_ENUM(MOD) - - static QString getModifierName(int mod) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - const char* modName = metaEnum.valueToKey(mod); - QString result = QString(modName).toLower(); - return result; - } - static MOD getModifier(const QString &modName) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - MOD mod = (MOD)metaEnum.keyToValue(modName.toUpper().toLocal8Bit().data()); - return mod; - } -}; - -class FuncKey : public QObject -{ - Q_OBJECT -public: - FuncKey(){} - - enum FUNCKEY { - UNKNOWN = -1, - SPACE = 0, - BACKSPACE, - ENTER, - HOME, - END, - PGUP, - PGDN, - INSERT, - DELETE, - UP, - DOWN, - LEFT, - RIGHT - }; - Q_ENUM(FUNCKEY) - static QString getKeyName(int key) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - const char* keyName = metaEnum.valueToKey(key); - QString result = QString(keyName).toLower(); - return result; - } - static FUNCKEY getKey(const QString &keyName) - { - QMetaEnum metaEnum = QMetaEnum::fromType(); - FUNCKEY key = (FUNCKEY)metaEnum.keyToValue(keyName.toUpper().toLocal8Bit().data()); - return key; - } -}; - -class X11Keyboard : public QObject +class X11Keyboard : public FakeKeyboard { Q_OBJECT public: diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index ac9b470..6900182 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -4,3 +4,4 @@ install(FILES ukui-screensaver.directory DESTINATION /usr/share/desktop-director install(FILES ukui-screensavers.menu DESTINATION /etc/xdg/menus) install(FILES ukui-screensaver-qt DESTINATION /etc/pam.d) install(FILES screensaver-startup.sh DESTINATION /usr/bin) +install(FILES ukui-screensaver-dialog.desktop DESTINATION /usr/share/applications) diff --git a/data/org.ukui.screensaver.gschema.xml b/data/org.ukui.screensaver.gschema.xml index b9d8aeb..4aef623 100644 --- a/data/org.ukui.screensaver.gschema.xml +++ b/data/org.ukui.screensaver.gschema.xml @@ -17,6 +17,11 @@ Automatic switching background Set this to TRUE to activate the automatic switching background. + + true + show rest time on screensaver + Set this to TRUE to show rest time on screensaver. + true show rest time on custom screensaver @@ -71,15 +76,25 @@ Wait idle delay to lock - 5 + -1 idle lock to lock Display the lock screen + + 10 + screensaver with lock timeout + Display the screensaver with lock's timeout + true Lock when sleep Set this to TRUE to lock the screen when the system goes sleep. + + true + Lock when close screen + Set this to TRUE to lock the screen when the screen goes close. + 'default-ukui' Screensaver theme selection mode @@ -151,7 +166,7 @@ Allow the session status message to be displayed when the screen is locked. - '/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg' + '/usr/share/backgrounds/1-openkylin.jpg' the background iamge of lockscreen Allow the user to set the background iamge of lockscreen. diff --git a/data/screensaver-startup.sh b/data/screensaver-startup.sh index fa8710d..822388a 100755 --- a/data/screensaver-startup.sh +++ b/data/screensaver-startup.sh @@ -1,5 +1,6 @@ #!/bin/bash -/usr/lib/ukui-screensaver/set4kScale >/dev/null 2>&1 ukui-screensaver-dialog --lock-startup & >/dev/null 2>&1 /usr/lib/ukui-screensaver/screensaver-focus-helper & >/dev/null 2>&1 +#如果锁屏和桌面进程并行启动,会对锁屏启动时间有较大影响,因此先启动锁屏,1s后再往下执行 +sleep 1 diff --git a/data/ukui-screensaver-dialog.desktop b/data/ukui-screensaver-dialog.desktop new file mode 100644 index 0000000..95f33d1 --- /dev/null +++ b/data/ukui-screensaver-dialog.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Type=Application +Name=Lockscreen Dialog +Name[tr]=Ekran pencere +Name[zh_CN]=锁屏窗口程序 +Name[zh_HK]=鎖屏窗口程式 +Name[zh_TW]=鎖屏窗口程式 +Comment[tr]=Ekran kilidini ve kurtarıcı göster +Comment[zh_CN]=展示屏幕锁定和保护程序 +Comment[zh_TW]=展示屏幕鎖定和保護程式 +Exec=/usr/bin/ukui-screensaver-dialog +NoDisplay=true +OnlyShowIn=UKUI +X-KDE-Wayland-Interfaces=org_kde_plasma_window_management,org_kde_kwin_keystate + diff --git a/data/ukui-screensaver.desktop b/data/ukui-screensaver.desktop index ce57723..9db6658 100644 --- a/data/ukui-screensaver.desktop +++ b/data/ukui-screensaver.desktop @@ -17,3 +17,4 @@ X-UKUI-Bugzilla-Product=ukui-screensaver X-UKUI-Bugzilla-Component=general X-UKUI-Bugzilla-Version=1.0.0 OnlyShowIn=UKUI +X-UKUI-AutoRestart=true diff --git a/debian/changelog b/debian/changelog index 5c529b6..cbff8f5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,157 @@ -ukui-screensaver (3.1.1.34update1-1) unstable; urgency=medium +ukui-screensaver (4.0.0.0-ok7~0825) yangtze; urgency=medium - [ Adrian Bunk ] - * Fix FTBFS with new glib. (Closes: #1020068) + * BUG号:I72HS3【次要】【电源管理】设置合盖时锁屏或休眠,开盖时出现键盘界面 + * 需求号:无 + * 其他修改说明:无 - -- handsome_feng Mon, 17 Oct 2022 19:23:23 +0800 + -- Yang Min Fri, 25 Aug 2023 08:58:00 +0800 + +ukui-screensaver (4.0.0.0-ok6~0808) yangtze; urgency=medium + + * BUG号:I7JFT2 屏保时空格键无法唤醒登录密码输入框 + I729TV 【用户切换】用户切换进入已登录用用户时,存在闪过屏保锁屏界面 + I774FQ 【锁屏】进入锁屏切换用户到其他用户,再切换回来后登录进入桌面过程中右下角弹出切换用户窗口 + * 需求号:无 + * 其他修改说明:无 + * commit id:004330d + + -- Yang Min Tue, 08 Aug 2023 09:45:26 +0800 + +ukui-screensaver (4.0.0.0-ok5~0705) yangtze; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他修改说明:修改changlog + + -- liudun Wed, 05 Jul 2023 19:54:42 +0800 + +ukui-screensaver (4.0.0.0-ok4~0705) yangtze; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他修改说明:添加layer-shell-qt的运行依赖 + + -- liudun Wed, 05 Jul 2023 19:20:57 +0800 + +ukui-screensaver (4.0.0.0-ok4~0704) yangtze; urgency=medium + + * BUG号:bug##I72EYT【次要】【锁屏】锁屏界面平板模式切换横竖屏后软键盘下方显示不全(wayland中文) + * 需求号:无 + * 其他修改说明:更新changelog + + -- liuyuanpeng Tue, 04 Jul 2023 15:41:42 +0800 + +ukui-screensaver (4.0.0.0-ok3~0704) yangtze; urgency=medium + + * BUG号:bug##I72EYT【次要】【锁屏】锁屏界面平板模式切换横竖屏后软键盘下方显示不全(wayland中文) + * 需求号:无 + * 其他修改说明:处理编译依赖问题 + + -- liudun Tue, 04 Jul 2023 10:34:46 +0800 + +ukui-screensaver (4.0.0.0-ok3~0628) yangtze; urgency=medium + + * BUG号:bug#I69CSS【锁屏】合盖后重新打开进入锁屏,此时锁屏界面下方图标会被遮住 + * 需求号:无 + * 其他修改说明:无 + + -- liudun Wed, 28 Jun 2023 15:05:12 +0800 + +ukui-screensaver (4.0.0.0-ok3~0608) yangtze; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他修改说明:处理编译依赖问题 + + -- Yang Min Thu, 08 Jun 2023 17:03:13 +0800 + +ukui-screensaver (4.0.0.0-ok3~0602) yangtze; urgency=medium + + * BUG号:I73TLX 修复网络图标显示异常的问题 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Fri, 02 Jun 2023 16:23:59 +0800 + +ukui-screensaver (4.0.0.0-ok2~0518) yangtze; urgency=medium + + * BUG号:I72EWI锁屏界面点击切换用户回来后,输入框不输入文字时显示密码多了个冒号 + I728TE【控制面板】中文模式下,在个性化屏保界面悬浮屏保预览界面,提示语为英文,且进入屏保提示语也为英文 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Thu, 18 May 2023 10:24:00 +0800 + +ukui-screensaver (4.0.0.0-ok1~0426) yangtze; urgency=medium + + * BUG号: 137546 【RISC-V】【控制面板】无法更改屏幕缩放 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Wed, 26 Apr 2023 19:49:20 +0800 + +ukui-screensaver (3.22.1.3-ok11~0412) yangtze; urgency=medium + + * BUG号:I5XFFQ 锁屏登入界面无键盘图标,无实体键盘时无法输入 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Wed, 12 Apr 2023 14:48:36 +0800 + +ukui-screensaver (3.22.1.3-ok10~0412) yangtze; urgency=medium + + * BUG号:136797 【虚拟机】【virtualbox】【锁屏】锁屏后锁屏页面时间与头像显示未对齐,登录页面正常 + I5M3SK 内存泄露 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Wed, 12 Apr 2023 13:40:10 +0800 + +ukui-screensaver (3.22.1.3-ok9~0323) yangtze; urgency=medium + + * BUG号:I65B7Q 【次要】【系统登录】登录界面tab后,esc键位无法回复登录界面默认显示 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Thu, 23 Mar 2023 09:35:33 +0800 + +ukui-screensaver (3.22.1.3-ok8~0314) yangtze; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他修改说明:更新屏保语录 + + -- Yang Min Tue, 14 Mar 2023 15:25:34 +0800 + +ukui-screensaver (3.22.1.3-ok7~0109) yangtze; urgency=medium + + * BUG号: 161081 【设计】ukui屏保格言替换文本 + * 需求号:无 + * 其他修改说明:无 + + -- Yang Min Mon, 09 Jan 2023 20:58:42 +0800 + +ukui-screensaver (3.22.1.3-ok6~1230) yangtze; urgency=medium + + * BUG号:131228 【wayland】【控制面板】【显示器】【锁屏】扩展模式下锁屏,仅一个屏幕有锁屏壁纸 + * 需求号:无 + * 其他修改说明:修复锁屏界面插拔电源均直接进入系统桌面问题 + + -- Yang Min Fri, 30 Dec 2022 15:27:42 +0800 + +ukui-screensaver (3.22.1.3-ok5~1208) yangtze; urgency=medium + + * BUG号:无 + * 需求号:Task#123734 子 openkylin网络插件化适配 / openkylin网络插件化适配-登录锁屏 + + -- Yang Min Thu, 08 Dec 2022 14:39:04 +0800 + +ukui-screensaver (3.22.1.3-ok3~1101) yangtze; urgency=medium + + * BUG号:无 + * 需求号:Task#114869 【登录锁屏】增加登录、锁屏状态显示 + + -- Yang Min Mon, 24 Oct 2022 11:13:26 +0800 ukui-screensaver (3.1.1.34update1-ok8) yangtze; urgency=medium diff --git a/debian/control b/debian/control index 6606284..231a94b 100644 --- a/debian/control +++ b/debian/control @@ -16,12 +16,22 @@ Build-Depends: debhelper-compat (= 12), libx11-dev, libxtst-dev, libqt5svg5-dev, + libkylin-nm-base (>=3.20.0.9-0k1), + libnm-dev, + libkf5networkmanagerqt-dev, + kylin-nm-plugin, libkf5wayland-dev, libkf5screen-dev, libgsettings-qt-dev, libkf5windowsystem-dev, libmatemixer-dev, - libukui-log4qt-dev + libimlib2-dev, + libukui-log4qt-dev, + libkysdk-sysinfo-dev (>> 1.1.0kylin1), + ukui-input-gather (>=1.0.0.2), + libinput-dev, + libukuiinputgatherclient-dev, + liblayershellqtinterface-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://www.github.com/ukui/ukui-screensaver @@ -33,6 +43,9 @@ Architecture: any Depends: ethtool, mate-desktop-common, ukui-session-manager, + libpam-biometric(>=3.20.0.10), + ukui-input-gather(>=1.0.0.2), + layer-shell-qt, ${misc:Depends}, ${shlibs:Depends} Replaces: ukui-screensaver-common (<< 2.0.0) diff --git a/debian/copyright b/debian/copyright index 1d740f2..34d2316 100644 --- a/debian/copyright +++ b/debian/copyright @@ -13,7 +13,13 @@ Files: CMakeLists.txt .gitattributes KylinNM/* .config.h.in + screensaver-focus-helper/* + set4kScale/* Copyright: 2018, Tianjin KYLIN Information Technology Co., Ltd. + 2019, Tianjin KYLIN Information Technology Co., Ltd. + 2020, Tianjin KYLIN Information Technology Co., Ltd. + 2021, Tianjin KYLIN Information Technology Co., Ltd. + 2022, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3+ Files: src/xeventmonitor.h @@ -26,7 +32,9 @@ License: GPL-3+ Files: BiometricAuth/* VirtualKeyboard/* Copyright: 2018, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-2+ + 2021, Tianjin KYLIN Information Technology Co., Ltd. + 2022, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ License: GPL-3+ This package is free software; you can redistribute it and/or modify diff --git a/examples/LoadCustomPlugin/LoadCustomPlugin.pro b/examples/LoadCustomPlugin/LoadCustomPlugin.pro new file mode 100644 index 0000000..ff6574b --- /dev/null +++ b/examples/LoadCustomPlugin/LoadCustomPlugin.pro @@ -0,0 +1,23 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2022-07-01T18:13:09 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = LoadCustomPlugin +TEMPLATE = app + +SOURCES += \ + main.cpp \ + widget.cpp + +HEADERS += \ + widget.h + +FORMS += \ + widget.ui + diff --git a/examples/LoadCustomPlugin/main.cpp b/examples/LoadCustomPlugin/main.cpp new file mode 100644 index 0000000..1ba44a8 --- /dev/null +++ b/examples/LoadCustomPlugin/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "widget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + + return a.exec(); +} diff --git a/examples/LoadCustomPlugin/widget.cpp b/examples/LoadCustomPlugin/widget.cpp new file mode 100644 index 0000000..fe30bca --- /dev/null +++ b/examples/LoadCustomPlugin/widget.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#pragma execution_character_set("utf-8") + +#include "widget.h" +#include "ui_widget.h" +#include +#include +#include +#include +#include + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); + connect(ui->load_plugin_btn,SIGNAL(clicked(bool)),this, SLOT(slot_load_plugin())); +} + +Widget::~Widget() +{ + delete ui; +} + +void Widget::slot_load_plugin() +{ + /* + QString file_path = QFileDialog::getOpenFileName(NULL,"加载插件",".","dll (*.dll *.so)"); + if(file_path.isEmpty()) + { + return; + } + */ + QPluginLoader pluginLoader("/usr/lib/ukui-screensaver/libscreensaver-default.so"); + pluginLoader.load(); + QObject* plugin = pluginLoader.instance(); + if (plugin) { + std::unique_ptr interface_ptr = std::unique_ptr(qobject_cast(plugin)); + QWidget* widget = interface_ptr->createWidget(false,this); + widget->setFixedHeight(180); + widget->setFixedWidth(300); + QHBoxLayout* mainLayout = new QHBoxLayout(this); + + mainLayout->addWidget(widget); + ui->widget->setLayout(mainLayout); + } +} diff --git a/examples/LoadCustomPlugin/widget.h b/examples/LoadCustomPlugin/widget.h new file mode 100644 index 0000000..02e7658 --- /dev/null +++ b/examples/LoadCustomPlugin/widget.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef WIDGET_H +#define WIDGET_H + +#include + +namespace Ui { +class Widget; +} + +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(QWidget *parent = 0); + ~Widget(); + +public slots: + void slot_load_plugin(); + +private: + Ui::Widget *ui; +}; + +#endif // WIDGET_H diff --git a/examples/LoadCustomPlugin/widget.ui b/examples/LoadCustomPlugin/widget.ui new file mode 100644 index 0000000..22adeca --- /dev/null +++ b/examples/LoadCustomPlugin/widget.ui @@ -0,0 +1,43 @@ + + + Widget + + + + 0 + 0 + 400 + 300 + + + + Widget + + + + + 140 + 30 + 111 + 31 + + + + LoadPlugin + + + + + + 30 + 90 + 331 + 141 + + + + + + + + diff --git a/i18n_ts/bo.ts b/i18n_ts/bo.ts index 1f66585..c84437e 100644 --- a/i18n_ts/bo.ts +++ b/i18n_ts/bo.ts @@ -4,120 +4,155 @@ AuthDialog - + Authentication failure, Please try again - - - - + + + + Please try again in %1 minutes. - - - - + + Enter the ukey password + + + + + Insert the ukey into the USB port + + + + + + + Please try again in %1 seconds. - - - - + + + + Account locked permanently. - + Verify face recognition or enter password to unlock - + Press fingerprint or enter password to unlock - + Verify voiceprint or enter password to unlock - + Verify finger vein or enter password to unlock - + Verify iris or enter password to unlock - + Use the bound wechat scanning code or enter the password to unlock - - + + Password cannot be empty - - Password + + Password: - + Input Password - + Login - + Retry - + Failed to verify %1, please enter password to unlock - + + Unable to verify %1, please enter password to unlock - + + Failed to verify %1, you still have %2 verification opportunities - - NET Exception + + Abnormal network + + + + + BatteryWidget + + + Charging... + + + + + fully charged + + + + + PowerMode + + + + + BatteryMode BiometricAuthWidget - + Current device: - + Identify failed, Please retry. @@ -125,26 +160,52 @@ BiometricDevicesWidget - + Please select the biometric device - + Device type: - + Device name: - + OK + + CharsMoreWidget + + + &&?! + + + + + CharsWidget + + + More + + + + + ABC + + + + + 123 + + + ConfForm @@ -253,32 +314,37 @@ DeviceType - + FingerPrint - + FingerVein - + Iris - + Face - + VoicePrint - + + ukey + + + + QRCode @@ -327,6 +393,7 @@ DlgConnHidWifi + Connect to Hidden Wi-Fi Network @@ -381,6 +448,7 @@ DlgConnHidWifiLeap + Connect to Hidden Wi-Fi Network @@ -465,6 +533,7 @@ DlgConnHidWifiSecFast + Connect to Hidden Wi-Fi Network @@ -600,6 +669,7 @@ DlgConnHidWifiSecLeap + Connect to Hidden Wi-Fi Network @@ -699,6 +769,7 @@ DlgConnHidWifiSecPeap + Connect to Hidden Wi-Fi Network @@ -849,6 +920,7 @@ DlgConnHidWifiSecPwd + Connect to Hidden Wi-Fi Network @@ -948,6 +1020,7 @@ DlgConnHidWifiSecTls + Connect to Hidden Wi-Fi Network @@ -1092,6 +1165,7 @@ DlgConnHidWifiSecTunnelTLS + Connect to Hidden Wi-Fi Network @@ -1227,6 +1301,7 @@ DlgConnHidWifiWep + Connect to Hidden Wi-Fi Network @@ -1331,6 +1406,7 @@ DlgConnHidWifiWpa + Connect to Hidden Wi-Fi Network @@ -1390,6 +1466,7 @@ DlgHotspotCreate + Dialog @@ -1436,45 +1513,154 @@ - InputInfos + EngineDevice - - - Get code + + yes - - Recapture(60s) + + no - - Recapture(%1s) + + Yes - - Service exception... + + No - - Invaild parameters... + + %1% available, charged - - Unknown fault:%1 + + Left %1h %2m (%3%) + + + + + %1% available + + + + + Left %1h %2m to full + + + + + charging (%1%) + + + + + %1 waiting to discharge (%2%) + + + + + %1 waiting to charge (%2%) + + + + + AC adapter + + + + + Laptop battery + + + + + UPS + + + + + Monitor + + + + + Mouse + + + + + Keyboard + + + + + PDA + + + + + Cell phone + + + + + Media player + + + + + Tablet + + + + + Computer + + + + + unrecognised - KeyboardWidget + InputInfos - - - KeyboardWidget + + + Get code + + + + + Recapture(60s) + + + + + Recapture(%1s) + + + + + Service exception... + + + + + Invaild parameters... + + + + + Unknown fault:%1 @@ -1482,6 +1668,7 @@ KylinNM + kylin-nm @@ -1554,7 +1741,7 @@ - + Not connected @@ -1567,7 +1754,7 @@ - + Disconnected @@ -1593,56 +1780,102 @@ - + Conn Ethernet Success - + Conn Ethernet Fail - + Conn Wifi Success - + Confirm your Wi-Fi password or usable of wireless card + + LettersWidget + + + &&?! + + + + + 123 + + + + + Ctrl + + + + + Alt + + + LockWidget - + + Form - - + + + Date - - + + + Time + + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + + LAN + + + + + WLAN + + LoginOptionsWidget - + Login Options - + + Password + + + + Identify device removed! @@ -1650,17 +1883,31 @@ MyLineEdit - - + + Verification code + + NumbersWidget + + + &&?! + + + + + Return + + + OneConnForm + Form @@ -1723,6 +1970,7 @@ OneLancForm + Form @@ -1769,7 +2017,7 @@ PhoneAuthWidget - + Verification by phoneNum @@ -1780,43 +2028,43 @@ - + commit - + 「 Use SMS to verification 」 - - + + Network not connected~ - + Verification Code invalid! - + Verification Code incorrect.Please retry! - + Failed time over limit!Retry after 1 hour! - + verifaction failed! - + Network unavailable~ @@ -1824,65 +2072,78 @@ PowerManager - + Log Out - + lock - - + + Restart - - + Power Off - - Suspend + + Shut Down - - Sleep + + Hibernate + + + + + Suspend QObject - + The screensaver is active. - + The screensaver is inactive. + + S: + + + + tablet device + + + Screensaver - + Picture does not exist - + View - + You have new notification @@ -1890,8 +2151,59 @@ SleepTime - - You have rested: + + You have rested + + + + + SureWindow + + + + + Form + + + + + + + TextLabel + + + + + + + Cancel + + + + + + + Confirm + + + + + The following program is running to prevent the system from reboot! + + + + + The following program is running to prevent the system from shutting down! + + + + + The following program is running to prevent the system from suspend! + + + + + The following program is running to prevent the system from hibernate! @@ -1911,38 +2223,38 @@ TabletLockWidget - - - - - - + + + + + + Cancel - - + + Back - + Skip - + New password is the same as old - + Reset password error:%1 - + Please scan by correct WeChat @@ -1958,7 +2270,7 @@ VerificationWidget - + Please scan by bound WeChat @@ -1966,7 +2278,7 @@ VerticalVerificationWidget - + Please scan by bound WeChat @@ -2014,6 +2326,35 @@ + + Widget + + + Widget + + + + + LoadPlugin + + + + + delay + + + how long to show lock + + + + + has-lock + + + if show lock + + + main @@ -2037,52 +2378,67 @@ - + Start command for the ukui ScreenSaver. - - - + + + lock the screen immediately - + query the status of the screen saver - + unlock the screen saver - + show the screensaver - + + show blank and delay to lock,param:idle/lid/lowpower + + + + Dialog for the ukui ScreenSaver. - + activated by session idle signal - - + + lock the screen and show screensaver immediately - + show screensaver immediately + + + show blank screensaver immediately and delay time to show lock + + + + + show blank screensaver immediately and if lock + + diff --git a/i18n_ts/bo_CN.ts b/i18n_ts/bo_CN.ts index 4135111..94e4d0d 100644 --- a/i18n_ts/bo_CN.ts +++ b/i18n_ts/bo_CN.ts @@ -21,7 +21,7 @@ Password: - གསང་ཨང་། + གསང་ཨང་། Biometric Authentication @@ -75,18 +75,10 @@ Password cannot be empty - - Password - - Login - - NET Exception - - Failed to verify %1, you still have %2 verification opportunities @@ -107,6 +99,37 @@ Input Password + + Abnormal network + + + + Enter the ukey password + གསང་བའི་ཨང་གྲངས་ནང་འཇུག་བྱེད་པ། + + + Insert the ukey into the USB port + བདེ་འཇགས་ཀྱི་གསང་བའི་ལྡེ་མིག་དེ་USBཡི་སྣེ་འདྲེན་དུ་འཇུག་རོགས། + + + + BatteryWidget + + Charging... + + + + fully charged + + + + PowerMode + + + + BatteryMode + + BiometricAuthWidget @@ -138,6 +161,28 @@ སྒྲིག་ཆས་ཀྱི་མིང་། + + CharsMoreWidget + + &&?! + + + + + CharsWidget + + More + + + + ABC + + + + 123 + + + ConfForm @@ -247,6 +292,10 @@ QRCode + + ukey + + DigitalAuthDialog @@ -1160,6 +1209,101 @@ + + EngineDevice + + yes + + + + no + + + + Yes + + + + No + + + + %1% available, charged + + + + Left %1h %2m (%3%) + + + + %1% available + + + + Left %1h %2m to full + + + + charging (%1%) + + + + %1 waiting to discharge (%2%) + + + + %1 waiting to charge (%2%) + + + + AC adapter + + + + Laptop battery + + + + UPS + + + + Monitor + + + + Mouse + + + + Keyboard + + + + PDA + + + + Cell phone + + + + Media player + + + + Tablet + + + + Computer + + + + unrecognised + + + InputInfos @@ -1187,13 +1331,6 @@ - - KeyboardWidget - - KeyboardWidget - - - KylinNM @@ -1289,6 +1426,25 @@ + + LettersWidget + + &&?! + + + + 123 + + + + Ctrl + + + + Alt + + + LockWidget @@ -1311,6 +1467,18 @@ SwitchUser བཀོལ་མི་བརྗེ་བ། + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + LAN + + + + WLAN + + LoginOptionsWidget @@ -1322,6 +1490,10 @@ Identify device removed! + + Password + + MyLineEdit @@ -1330,6 +1502,17 @@ + + NumbersWidget + + &&?! + + + + Return + + + OneConnForm @@ -1459,7 +1642,7 @@ PowerManager Sleep - མལ་གསོ། + མལ་གསོ། Log Out @@ -1489,6 +1672,14 @@ lock + + Shut Down + + + + Hibernate + + QObject @@ -1501,6 +1692,14 @@ འཆར་ངོས་སྲུང་སྐྱོབ་བྱ་རིམ་སད་འདུག + + S: + + + tablet device + + + Screensaver @@ -1528,7 +1727,46 @@ SleepTime You have rested: - ཁྱེད་ཀྱིས་ ལ་ངལ་གསོས་ཟིན། + ཁྱེད་ཀྱིས་ ལ་ངལ་གསོས་ཟིན། + + + You have rested + + + + + SureWindow + + Form + ནས་འོང་བ། + + + TextLabel + + + + Cancel + + + + Confirm + + + + The following program is running to prevent the system from reboot! + + + + The following program is running to prevent the system from shutting down! + + + + The following program is running to prevent the system from suspend! + + + + The following program is running to prevent the system from hibernate! + @@ -1621,6 +1859,31 @@ + + Widget + + Widget + + + + LoadPlugin + + + + + delay + + how long to show lock + + + + + has-lock + + if show lock + + + main @@ -1675,5 +1938,17 @@ show screensaver immediately + + show blank and delay to lock,param:idle/lid/lowpower + + + + show blank screensaver immediately and delay time to show lock + + + + show blank screensaver immediately and if lock + + diff --git a/i18n_ts/es.ts b/i18n_ts/es.ts index 21c1487..be5732c 100644 --- a/i18n_ts/es.ts +++ b/i18n_ts/es.ts @@ -59,10 +59,6 @@ Login - - Password - - Verify face recognition or enter password to unlock @@ -83,10 +79,6 @@ Verify iris or enter password to unlock - - NET Exception - - Failed to verify %1, you still have %2 verification opportunities @@ -107,6 +99,41 @@ Input Password + + Abnormal network + + + + Enter the ukey password + + + + Insert the ukey into the USB port + + + + Password: + + + + + BatteryWidget + + Charging... + + + + fully charged + + + + PowerMode + + + + BatteryMode + + BioAuthWidget @@ -203,6 +230,28 @@ + + CharsMoreWidget + + &&?! + + + + + CharsWidget + + More + Más + + + ABC + + + + 123 + + + ConfForm @@ -312,6 +361,10 @@ QRCode + + ukey + + DigitalAuthDialog @@ -1225,6 +1278,101 @@ + + EngineDevice + + yes + + + + no + + + + Yes + + + + No + + + + %1% available, charged + + + + Left %1h %2m (%3%) + + + + %1% available + + + + Left %1h %2m to full + + + + charging (%1%) + + + + %1 waiting to discharge (%2%) + + + + %1 waiting to charge (%2%) + + + + AC adapter + + + + Laptop battery + + + + UPS + + + + Monitor + + + + Mouse + + + + Keyboard + + + + PDA + + + + Cell phone + + + + Media player + + + + Tablet + + + + Computer + + + + unrecognised + + + InputInfos @@ -1256,7 +1404,7 @@ KeyboardWidget KeyboardWidget - TecladoWidget + TecladoWidget @@ -1354,6 +1502,25 @@ + + LettersWidget + + &&?! + + + + 123 + + + + Ctrl + + + + Alt + + + LockWidget @@ -1376,6 +1543,18 @@ SwitchUser Cambiar de usuario + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + LAN + + + + WLAN + + LoginOptionsWidget @@ -1385,7 +1564,7 @@ Password - Contraseña + Contraseña Identify device removed! @@ -1399,6 +1578,17 @@ + + NumbersWidget + + &&?! + + + + Return + + + OneConnForm @@ -1534,10 +1724,6 @@ Log Out - - Restart - - Power Off @@ -1547,11 +1733,19 @@ - Sleep + lock - lock + Shut Down + + + + Hibernate + + + + Restart @@ -1566,6 +1760,14 @@ + + S: + + + tablet device + + + Screensaver @@ -1584,7 +1786,42 @@ SleepTime - You have rested: + You have rested + + + + + SureWindow + + Form + Formar + + + TextLabel + TextLabel + + + Cancel + + + + Confirm + + + + The following program is running to prevent the system from reboot! + + + + The following program is running to prevent the system from shutting down! + + + + The following program is running to prevent the system from suspend! + + + + The following program is running to prevent the system from hibernate! @@ -1678,6 +1915,31 @@ + + Widget + + Widget + + + + LoadPlugin + + + + + delay + + how long to show lock + + + + + has-lock + + if show lock + + + main @@ -1732,5 +1994,17 @@ show screensaver immediately + + show blank and delay to lock,param:idle/lid/lowpower + + + + show blank screensaver immediately and delay time to show lock + + + + show blank screensaver immediately and if lock + + diff --git a/i18n_ts/fr.ts b/i18n_ts/fr.ts index c4588df..a7bc14f 100644 --- a/i18n_ts/fr.ts +++ b/i18n_ts/fr.ts @@ -59,10 +59,6 @@ Login - - Password - - Verify face recognition or enter password to unlock @@ -83,10 +79,6 @@ Verify iris or enter password to unlock - - NET Exception - - Failed to verify %1, you still have %2 verification opportunities @@ -107,6 +99,41 @@ Input Password + + Abnormal network + + + + Enter the ukey password + + + + Insert the ukey into the USB port + + + + Password: + + + + + BatteryWidget + + Charging... + + + + fully charged + + + + PowerMode + + + + BatteryMode + + BioAuthWidget @@ -203,6 +230,28 @@ + + CharsMoreWidget + + &&?! + + + + + CharsWidget + + More + Plus + + + ABC + + + + 123 + + + ConfForm @@ -312,6 +361,10 @@ QRCode + + ukey + + DigitalAuthDialog @@ -1225,6 +1278,101 @@ + + EngineDevice + + yes + + + + no + + + + Yes + + + + No + + + + %1% available, charged + + + + Left %1h %2m (%3%) + + + + %1% available + + + + Left %1h %2m to full + + + + charging (%1%) + + + + %1 waiting to discharge (%2%) + + + + %1 waiting to charge (%2%) + + + + AC adapter + + + + Laptop battery + + + + UPS + + + + Monitor + + + + Mouse + + + + Keyboard + + + + PDA + + + + Cell phone + + + + Media player + + + + Tablet + + + + Computer + + + + unrecognised + + + InputInfos @@ -1256,7 +1404,7 @@ KeyboardWidget KeyboardWidget - KeyboardWidget + KeyboardWidget @@ -1354,6 +1502,25 @@ + + LettersWidget + + &&?! + + + + 123 + + + + Ctrl + + + + Alt + + + LockWidget @@ -1376,6 +1543,18 @@ SwitchUser Changer d'utilisateur + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + LAN + + + + WLAN + + LoginOptionsWidget @@ -1385,7 +1564,7 @@ Password - Mot de passe + Mot de passe Identify device removed! @@ -1399,6 +1578,17 @@ + + NumbersWidget + + &&?! + + + + Return + + + OneConnForm @@ -1534,10 +1724,6 @@ Log Out - - Restart - - Power Off @@ -1547,11 +1733,19 @@ - Sleep + lock - lock + Shut Down + + + + Hibernate + + + + Restart @@ -1566,6 +1760,14 @@ + + S: + + + tablet device + + + Screensaver @@ -1584,7 +1786,42 @@ SleepTime - You have rested: + You have rested + + + + + SureWindow + + Form + Forme + + + TextLabel + TextLabel + + + Cancel + + + + Confirm + + + + The following program is running to prevent the system from reboot! + + + + The following program is running to prevent the system from shutting down! + + + + The following program is running to prevent the system from suspend! + + + + The following program is running to prevent the system from hibernate! @@ -1678,6 +1915,31 @@ + + Widget + + Widget + + + + LoadPlugin + + + + + delay + + how long to show lock + + + + + has-lock + + if show lock + + + main @@ -1732,5 +1994,17 @@ show screensaver immediately + + show blank and delay to lock,param:idle/lid/lowpower + + + + show blank screensaver immediately and delay time to show lock + + + + show blank screensaver immediately and if lock + + diff --git a/i18n_ts/pt.ts b/i18n_ts/pt.ts index 2de6ea7..7cd5872 100644 --- a/i18n_ts/pt.ts +++ b/i18n_ts/pt.ts @@ -59,10 +59,6 @@ Login - - Password - - Verify face recognition or enter password to unlock @@ -83,10 +79,6 @@ Verify iris or enter password to unlock - - NET Exception - - Failed to verify %1, you still have %2 verification opportunities @@ -107,6 +99,41 @@ Input Password + + Abnormal network + + + + Enter the ukey password + + + + Insert the ukey into the USB port + + + + Password: + + + + + BatteryWidget + + Charging... + + + + fully charged + + + + PowerMode + + + + BatteryMode + + BioAuthWidget @@ -203,6 +230,28 @@ + + CharsMoreWidget + + &&?! + + + + + CharsWidget + + More + Mais + + + ABC + + + + 123 + + + ConfForm @@ -312,6 +361,10 @@ QRCode + + ukey + + DigitalAuthDialog @@ -1225,6 +1278,101 @@ + + EngineDevice + + yes + + + + no + + + + Yes + + + + No + + + + %1% available, charged + + + + Left %1h %2m (%3%) + + + + %1% available + + + + Left %1h %2m to full + + + + charging (%1%) + + + + %1 waiting to discharge (%2%) + + + + %1 waiting to charge (%2%) + + + + AC adapter + + + + Laptop battery + + + + UPS + + + + Monitor + + + + Mouse + + + + Keyboard + + + + PDA + + + + Cell phone + + + + Media player + + + + Tablet + + + + Computer + + + + unrecognised + + + InputInfos @@ -1256,7 +1404,7 @@ KeyboardWidget KeyboardWidget - KeyboardWidget + KeyboardWidget @@ -1354,6 +1502,25 @@ + + LettersWidget + + &&?! + + + + 123 + + + + Ctrl + + + + Alt + + + LockWidget @@ -1376,6 +1543,18 @@ SwitchUser Mudar de utilizador + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + LAN + + + + WLAN + + LoginOptionsWidget @@ -1385,7 +1564,7 @@ Password - Senha + Senha Identify device removed! @@ -1399,6 +1578,17 @@ + + NumbersWidget + + &&?! + + + + Return + + + OneConnForm @@ -1534,10 +1724,6 @@ Log Out - - Restart - - Power Off @@ -1547,11 +1733,19 @@ - Sleep + lock - lock + Shut Down + + + + Hibernate + + + + Restart @@ -1566,6 +1760,14 @@ + + S: + + + tablet device + + + Screensaver @@ -1584,7 +1786,42 @@ SleepTime - You have rested: + You have rested + + + + + SureWindow + + Form + Formato + + + TextLabel + TextLabel + + + Cancel + + + + Confirm + + + + The following program is running to prevent the system from reboot! + + + + The following program is running to prevent the system from shutting down! + + + + The following program is running to prevent the system from suspend! + + + + The following program is running to prevent the system from hibernate! @@ -1678,6 +1915,31 @@ + + Widget + + Widget + + + + LoadPlugin + + + + + delay + + how long to show lock + + + + + has-lock + + if show lock + + + main @@ -1732,5 +1994,17 @@ show screensaver immediately + + show blank and delay to lock,param:idle/lid/lowpower + + + + show blank screensaver immediately and delay time to show lock + + + + show blank screensaver immediately and if lock + + diff --git a/i18n_ts/ru.ts b/i18n_ts/ru.ts index f3ab806..c96dcd4 100644 --- a/i18n_ts/ru.ts +++ b/i18n_ts/ru.ts @@ -59,10 +59,6 @@ Login - - Password - - Verify face recognition or enter password to unlock @@ -83,10 +79,6 @@ Verify iris or enter password to unlock - - NET Exception - - Failed to verify %1, you still have %2 verification opportunities @@ -107,6 +99,41 @@ Input Password + + Abnormal network + + + + Enter the ukey password + + + + Insert the ukey into the USB port + + + + Password: + + + + + BatteryWidget + + Charging... + + + + fully charged + + + + PowerMode + + + + BatteryMode + + BioAuthWidget @@ -203,6 +230,28 @@ + + CharsMoreWidget + + &&?! + + + + + CharsWidget + + More + Больше + + + ABC + + + + 123 + + + ConfForm @@ -312,6 +361,10 @@ QRCode + + ukey + + DigitalAuthDialog @@ -1225,6 +1278,101 @@ + + EngineDevice + + yes + + + + no + + + + Yes + + + + No + + + + %1% available, charged + + + + Left %1h %2m (%3%) + + + + %1% available + + + + Left %1h %2m to full + + + + charging (%1%) + + + + %1 waiting to discharge (%2%) + + + + %1 waiting to charge (%2%) + + + + AC adapter + + + + Laptop battery + + + + UPS + + + + Monitor + + + + Mouse + + + + Keyboard + + + + PDA + + + + Cell phone + + + + Media player + + + + Tablet + + + + Computer + + + + unrecognised + + + InputInfos @@ -1256,7 +1404,7 @@ KeyboardWidget KeyboardWidget - KeyboardWidget + KeyboardWidget @@ -1354,6 +1502,25 @@ + + LettersWidget + + &&?! + + + + 123 + + + + Ctrl + + + + Alt + + + LockWidget @@ -1376,6 +1543,18 @@ SwitchUser Сменить пользователя + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + LAN + + + + WLAN + + LoginOptionsWidget @@ -1385,7 +1564,7 @@ Password - пароль + пароль Identify device removed! @@ -1399,6 +1578,17 @@ + + NumbersWidget + + &&?! + + + + Return + + + OneConnForm @@ -1534,10 +1724,6 @@ Log Out - - Restart - - Power Off @@ -1547,11 +1733,19 @@ - Sleep + lock - lock + Shut Down + + + + Hibernate + + + + Restart @@ -1566,6 +1760,14 @@ + + S: + + + tablet device + + + Screensaver @@ -1584,7 +1786,42 @@ SleepTime - You have rested: + You have rested + + + + + SureWindow + + Form + форма + + + TextLabel + TextLabel + + + Cancel + + + + Confirm + + + + The following program is running to prevent the system from reboot! + + + + The following program is running to prevent the system from shutting down! + + + + The following program is running to prevent the system from suspend! + + + + The following program is running to prevent the system from hibernate! @@ -1678,6 +1915,31 @@ + + Widget + + Widget + + + + LoadPlugin + + + + + delay + + how long to show lock + + + + + has-lock + + if show lock + + + main @@ -1732,5 +1994,17 @@ show screensaver immediately + + show blank and delay to lock,param:idle/lid/lowpower + + + + show blank screensaver immediately and delay time to show lock + + + + show blank screensaver immediately and if lock + + diff --git a/i18n_ts/tr.ts b/i18n_ts/tr.ts index 1d46147..0c3682e 100644 --- a/i18n_ts/tr.ts +++ b/i18n_ts/tr.ts @@ -16,7 +16,7 @@ Parola - + Retry Yeniden Dene @@ -25,8 +25,9 @@ Kilidi Aç + Password: - Parola + Parola Account locked %1 minutes due to %2 fail attempts @@ -41,103 +42,110 @@ Kimlik doğrulama hatası, hala %1 kalan denemen var - + Authentication failure, Please try again - - - - + + + + Please try again in %1 minutes. - - - - + + Enter the ukey password + + + + + Insert the ukey into the USB port + + + + + + + Please try again in %1 seconds. - - - - + + + + Account locked permanently. - + Verify face recognition or enter password to unlock - + Press fingerprint or enter password to unlock - + Verify voiceprint or enter password to unlock - + Verify finger vein or enter password to unlock - + Verify iris or enter password to unlock - + Use the bound wechat scanning code or enter the password to unlock - - + + Password cannot be empty - - Password - - - - + Input Password - + Login - + Failed to verify %1, please enter password to unlock - + + Unable to verify %1, please enter password to unlock - + + Failed to verify %1, you still have %2 verification opportunities - - NET Exception + + Abnormal network @@ -153,6 +161,29 @@ Diğer Ayıtlar + + BatteryWidget + + + Charging... + + + + + fully charged + + + + + PowerMode + + + + + BatteryMode + + + BioDevices @@ -194,12 +225,12 @@ BiometricAuthWidget - + Current device: Şuanki aygıt: - + Identify failed, Please retry. Tanımlama başarısız, Lütfen tekrar deneyin. @@ -207,26 +238,52 @@ BiometricDevicesWidget - + Please select the biometric device Lütfen biyometrik aygıtı seçin - + Device type: Aygıt türü: - + Device name: Aygıt adı: - + OK Tamam + + CharsMoreWidget + + + &&?! + + + + + CharsWidget + + + More + + + + + ABC + + + + + 123 + + + ConfForm @@ -335,32 +392,37 @@ DeviceType - + FingerPrint Parmak İzi - + FingerVein Parmak Damarı - + Iris Göz - + Face Yüz - + VoicePrint Ses İzi - + + ukey + + + + QRCode @@ -409,6 +471,7 @@ DlgConnHidWifi + Connect to Hidden Wi-Fi Network @@ -463,6 +526,7 @@ DlgConnHidWifiLeap + Connect to Hidden Wi-Fi Network @@ -547,6 +611,7 @@ DlgConnHidWifiSecFast + Connect to Hidden Wi-Fi Network @@ -682,6 +747,7 @@ DlgConnHidWifiSecLeap + Connect to Hidden Wi-Fi Network @@ -781,6 +847,7 @@ DlgConnHidWifiSecPeap + Connect to Hidden Wi-Fi Network @@ -931,6 +998,7 @@ DlgConnHidWifiSecPwd + Connect to Hidden Wi-Fi Network @@ -1030,6 +1098,7 @@ DlgConnHidWifiSecTls + Connect to Hidden Wi-Fi Network @@ -1174,6 +1243,7 @@ DlgConnHidWifiSecTunnelTLS + Connect to Hidden Wi-Fi Network @@ -1309,6 +1379,7 @@ DlgConnHidWifiWep + Connect to Hidden Wi-Fi Network @@ -1413,6 +1484,7 @@ DlgConnHidWifiWpa + Connect to Hidden Wi-Fi Network @@ -1472,6 +1544,7 @@ DlgHotspotCreate + Dialog @@ -1518,45 +1591,154 @@ - InputInfos + EngineDevice - - - Get code + + yes - - Recapture(60s) + + no - - Recapture(%1s) + + Yes - - Service exception... + + No - - Invaild parameters... + + %1% available, charged - - Unknown fault:%1 + + Left %1h %2m (%3%) + + + + + %1% available + + + + + Left %1h %2m to full + + + + + charging (%1%) + + + + + %1 waiting to discharge (%2%) + + + + + %1 waiting to charge (%2%) + + + + + AC adapter + + + + + Laptop battery + + + + + UPS + + + + + Monitor + + + + + Mouse + + + + + Keyboard + + + + + PDA + + + + + Cell phone + + + + + Media player + + + + + Tablet + + + + + Computer + + + + + unrecognised - KeyboardWidget + InputInfos - - - KeyboardWidget + + + Get code + + + + + Recapture(60s) + + + + + Recapture(%1s) + + + + + Service exception... + + + + + Invaild parameters... + + + + + Unknown fault:%1 @@ -1564,6 +1746,7 @@ KylinNM + kylin-nm @@ -1636,7 +1819,7 @@ - + Not connected @@ -1649,7 +1832,7 @@ - + Disconnected @@ -1675,43 +1858,69 @@ - + Conn Ethernet Success - + Conn Ethernet Fail - + Conn Wifi Success - + Confirm your Wi-Fi password or usable of wireless card + + LettersWidget + + + &&?! + + + + + 123 + + + + + Ctrl + + + + + Alt + + + LockWidget - + + Form - - + + + Date Tarih - - + + + Time Zaman @@ -1723,20 +1932,36 @@ SwitchUser Kullanıcı Değiştir + + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + + + + + LAN + + + + + WLAN + + LoginOptionsWidget - + Login Options + Password - Parola + Parola - + Identify device removed! @@ -1744,17 +1969,31 @@ MyLineEdit - - + + Verification code + + NumbersWidget + + + &&?! + + + + + Return + + + OneConnForm + Form @@ -1817,6 +2056,7 @@ OneLancForm + Form @@ -1863,7 +2103,7 @@ PhoneAuthWidget - + Verification by phoneNum @@ -1874,43 +2114,43 @@ - + commit - + 「 Use SMS to verification 」 - - + + Network not connected~ - + Verification Code invalid! - + Verification Code incorrect.Please retry! - + Failed time over limit!Retry after 1 hour! - + verifaction failed! - + Network unavailable~ @@ -1918,7 +2158,7 @@ PowerManager - + lock kilit @@ -1947,46 +2187,59 @@ Kullanıcı Değiştir - + Log Out Çıkış - - + + Restart Yeniden Başlat - - + Power Off Bilgisayarı Kapat - - Suspend + + Shut Down - - Sleep + + Hibernate + + + + + Suspend QObject - + The screensaver is active. - + The screensaver is inactive. + + S: + + + + tablet device + + + Screensaver @@ -1998,17 +2251,17 @@ çıkış - + Picture does not exist - + View - + You have new notification @@ -2024,8 +2277,59 @@ SleepTime - - You have rested: + + You have rested + + + + + SureWindow + + + + + Form + + + + + + + TextLabel + + + + + + + Cancel + + + + + + + Confirm + + + + + The following program is running to prevent the system from reboot! + + + + + The following program is running to prevent the system from shutting down! + + + + + The following program is running to prevent the system from suspend! + + + + + The following program is running to prevent the system from hibernate! @@ -2045,38 +2349,38 @@ TabletLockWidget - - - - - - + + + + + + Cancel - - + + Back - + Skip - + New password is the same as old - + Reset password error:%1 - + Please scan by correct WeChat @@ -2092,7 +2396,7 @@ VerificationWidget - + Please scan by bound WeChat @@ -2100,7 +2404,7 @@ VerticalVerificationWidget - + Please scan by bound WeChat @@ -2148,56 +2452,100 @@ + + Widget + + + Widget + + + + + LoadPlugin + + + + + delay + + + how long to show lock + + + + + has-lock + + + if show lock + + + main - + Start command for the ukui ScreenSaver. Ukui Ekran Koruyucu için başlatma komutu. - - - + + + lock the screen immediately Ekranı hemen kilitle - + query the status of the screen saver - + unlock the screen saver - + show the screensaver - + + show blank and delay to lock,param:idle/lid/lowpower + + + + Dialog for the ukui ScreenSaver. - + activated by session idle signal - - + + lock the screen and show screensaver immediately - + show screensaver immediately + + + show blank screensaver immediately and delay time to show lock + + + + + show blank screensaver immediately and if lock + + Screensaver for ukui-screensaver diff --git a/i18n_ts/zh_CN.ts b/i18n_ts/zh_CN.ts index c76dc77..4cb393b 100644 --- a/i18n_ts/zh_CN.ts +++ b/i18n_ts/zh_CN.ts @@ -16,7 +16,7 @@ 使用密码认证 - + Retry 重试 @@ -37,84 +37,91 @@ 已登录 + Password: - 密码: + 密码: Account locked %1 minutes due to %2 fail attempts 账户锁定%1分钟由于%2次错误尝试 - - - - + + + + Please try again in %1 minutes. 请%1分钟后再试 - - - - + + + + Please try again in %1 seconds. 请%1秒后再试 - - - - + + + + Account locked permanently. 账号已被永久锁定 - + Verify face recognition or enter password to unlock 验证人脸识别或输入密码解锁 - + Press fingerprint or enter password to unlock 按压指纹或输入密码解锁 - + Verify voiceprint or enter password to unlock 验证声纹或输入密码解锁 - + Verify finger vein or enter password to unlock 验证指静脉或输入密码解锁 - + Verify iris or enter password to unlock 验证虹膜或输入密码解锁 - + Input Password 输入密码 - + Failed to verify %1, please enter password to unlock 验证%1失败,请输入密码解锁 - + + Unable to verify %1, please enter password to unlock 无法验证%1,请输入密码解锁 + + + Abnormal network + 网络异常 + Use the bound wechat scanning code or enter the password to log in 使用绑定的微信扫码或输入密码登录 - - + + Password cannot be empty 密码不能为空 @@ -127,7 +134,8 @@ 无法验证%1,请输入密码. - + + Failed to verify %1, you still have %2 verification opportunities 验证%1失败,您还有%2次尝试机会 @@ -140,9 +148,8 @@ 生物/扫码验证失败,您还有%1次尝试机会 - NET Exception - 网络异常 + 网络异常 Password Incorrect, Please try again @@ -157,22 +164,31 @@ 请输入密码或者录入指纹 - + Authentication failure, Please try again 认证失败,请重试 - + Use the bound wechat scanning code or enter the password to unlock 使用绑定的微信扫码或输入密码解锁 - - Password - 密码 + + Enter the ukey password + 输入安全密钥密码 - + + Insert the ukey into the USB port + 请将安全密钥插入USB端口 + + + Password + 密码 + + + Login 登录 @@ -197,6 +213,29 @@ 指纹验证失败,您还有%1次尝试机会 + + BatteryWidget + + + BatteryMode + 电池模式 + + + + PowerMode + 电源模式 + + + + Charging... + 正在充电... + + + + fully charged + 已充满电 + + BioDevices @@ -238,12 +277,12 @@ BiometricAuthWidget - + Current device: 当前设备: - + Identify failed, Please retry. 识别失败,请重试 @@ -251,26 +290,64 @@ BiometricDevicesWidget - + Please select the biometric device 请选择生物设备 - + Device type: 设备类型: - + Device name: 设备型号: - + OK 确定 + + CharsMoreWidget + + Return + 返回 + + + + &&?! + + + + + CharsWidget + + + More + 更多 + + + + ABC + + + + + 123 + + + + Return + 返回 + + + Number + 数字 + + ConfForm @@ -391,32 +468,37 @@ DeviceType - + FingerPrint 指纹 - + FingerVein 指静脉 - + Iris 虹膜 - + Face 人脸识别 - + VoicePrint 声纹 - + + ukey + + + + QRCode 二维码 @@ -534,6 +616,8 @@ + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -542,6 +626,8 @@ DlgConnHidWifiLeap + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -625,6 +711,8 @@ DlgConnHidWifiSecFast + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -759,6 +847,8 @@ DlgConnHidWifiSecLeap + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -857,6 +947,8 @@ DlgConnHidWifiSecPeap + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -1006,6 +1098,8 @@ DlgConnHidWifiSecPwd + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -1104,6 +1198,8 @@ DlgConnHidWifiSecTls + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -1247,6 +1343,8 @@ DlgConnHidWifiSecTunnelTLS + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -1381,6 +1479,8 @@ DlgConnHidWifiWep + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -1484,6 +1584,8 @@ DlgConnHidWifiWpa + + Connect to Hidden Wi-Fi Network 连接到隐藏 Wi-Fi 网络 @@ -1558,6 +1660,8 @@ DlgHotspotCreate + + Dialog @@ -1602,48 +1706,158 @@ WPA 及 WPA2 个人 + + EngineDevice + + + yes + + + + + no + + + + + Yes + + + + + No + + + + + %1% available, charged + + + + + Left %1h %2m (%3%) + + + + + %1% available + + + + + Left %1h %2m to full + + + + + charging (%1%) + + + + + %1 waiting to discharge (%2%) + + + + + %1 waiting to charge (%2%) + + + + + AC adapter + + + + + Laptop battery + + + + + UPS + + + + + Monitor + + + + + Mouse + + + + + Keyboard + + + + + PDA + + + + + Cell phone + + + + + Media player + + + + + Tablet + + + + + Computer + + + + + unrecognised + + + InputInfos - + Service exception... 服务异常,重试中... - + Invaild parameters... 参数异常,重试中... - + Unknown fault:%1 未知错误:%1 - + Recapture(60s) 重新获取(60s) - + Recapture(%1s) 重新获取(%1s) - - + + Get code 获取验证码 - - KeyboardWidget - - - KeyboardWidget - - - KylinDBus @@ -1655,6 +1869,8 @@ KylinNM + + kylin-nm 网络工具 @@ -1769,7 +1985,7 @@ - + Not connected 未连接任何网络 @@ -1782,7 +1998,7 @@ - + Disconnected 未连接 @@ -1818,7 +2034,7 @@ 断开无线网络 - + Confirm your Wi-Fi password or usable of wireless card 请确认Wi-Fi密码或无线设备 @@ -1874,35 +2090,72 @@ 正在更新 Wi-Fi列表 - + Conn Ethernet Success 连接有线网络成功 - + Conn Ethernet Fail 连接有线网络失败 - + Conn Wifi Success 连接无线网络成功 + + LettersWidget + + Symbol + 符号 + + + Num + 数字 + + + + &&?! + + + + + 123 + + + + + Ctrl + + + + + Alt + + + LockWidget + + Form - + + + Date 日期 - + + + Time 时间 @@ -1914,24 +2167,40 @@ SwitchUser 切换用户 + + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + 同时有多个用户登录系统,您确定要退出系统吗? + + + + LAN + 有线网络 + + + + WLAN + 无线局域网 + LoginOptionsWidget - + Login Options 登录选项 + Password - 密码 + 密码 Wechat 微信 - + Identify device removed! 校验设备已移除! @@ -1939,17 +2208,36 @@ MyLineEdit - - + + Verification code 短信验证码 + + NumbersWidget + + Symbol + 符号 + + + + &&?! + + + + + Return + 返回 + + OneConnForm + + Form -- @@ -2031,6 +2319,8 @@ OneLancForm + + Form -- @@ -2084,7 +2374,7 @@ PhoneAuthWidget - + Verification by phoneNum 手机号验证 @@ -2094,44 +2384,44 @@ - + 「 Use SMS to verification 」 「 请使用绑定该账户手机号验证 」 - + commit 提交 - - + + Network not connected~ 系统未联网,请检查网络连接~ - + Network unavailable~ 网络状态差,请检查网络连接~ - + Verification Code invalid! 验证码失效 - + Verification Code incorrect.Please retry! 验证码错误!请填写正确的验证码! - + Failed time over limit!Retry after 1 hour! 验证码错误次数超过10次,1小时后再试 - + verifaction failed! 手机验证失败 @@ -2139,7 +2429,7 @@ PowerManager - + lock 锁定 @@ -2168,33 +2458,37 @@ 切换用户 - + Log Out 注销 - - + + Restart 重启 - + Reboot + 重启 + + + Power Off 关机 - + Shut Down 关机 - + Hibernate 休眠 - + Suspend 睡眠 @@ -2206,16 +2500,25 @@ QObject - + The screensaver is active. 屏幕保护程序已激活 - + The screensaver is inactive. 屏幕保护程序未激活 + + S: + + + + tablet device + + + Screensaver @@ -2227,7 +2530,7 @@ 退出 - + Picture does not exist 图片不存在 @@ -2244,12 +2547,12 @@ 您有%1条未读消息 - + You have new notification 您有新的消息 - + View 预览 @@ -2257,37 +2560,68 @@ SleepTime - You have rested: - 您已休息: + 您已休息: + + + + You have rested + 您已休息 SureWindow + + Form -- + + TextLabel - + + + Cancel 取消 - + + + Confirm 确认 - Multiple users are logged in at the same time.Are you sure you want to reboot this system? - 同时有多个用户登录系统,您确定要退出系统吗? + 同时有多个用户登录系统,您确定要退出系统吗? + + + + The following program is running to prevent the system from suspend! + 以下程序正在运行,阻止系统进入睡眠! + + + + The following program is running to prevent the system from hibernate! + 以下程序正在运行,阻止系统进入休眠! + + + + The following program is running to prevent the system from shutting down! + 以下程序正在运行,阻止系统关机! + + + + The following program is running to prevent the system from reboot! + 以下程序正在运行,阻止系统重启! @@ -2325,38 +2659,38 @@ 向上滑动解锁 - + New password is the same as old 新密码与原密码相同 - + Reset password error:%1 重置密码失败:%1 - + Please scan by correct WeChat 请使用正确的微信扫码 - - - - - - + + + + + + Cancel 取消 - - + + Back 返回 - + Skip 跳过 @@ -2372,7 +2706,7 @@ VerificationWidget - + Please scan by bound WeChat 请使用已绑定的微信扫码 @@ -2380,7 +2714,7 @@ VerticalVerificationWidget - + Please scan by bound WeChat 请使用已绑定的微信扫码 @@ -2432,56 +2766,100 @@ 登录失败 + + Widget + + + Widget + + + + + LoadPlugin + + + + + delay + + + how long to show lock + + + + + has-lock + + + if show lock + + + main - + Start command for the ukui ScreenSaver. 启动锁屏到命令 - - - + + + lock the screen immediately 马上锁定屏幕 - + query the status of the screen saver 获取锁屏状态 - + unlock the screen saver 解锁屏幕 - + show the screensaver - + + show blank and delay to lock,param:idle/lid/lowpower + + + + Dialog for the ukui ScreenSaver. - + activated by session idle signal - - + + lock the screen and show screensaver immediately - + show screensaver immediately + + + show blank screensaver immediately and delay time to show lock + + + + + show blank screensaver immediately and if lock + + Screensaver for ukui-screensaver diff --git a/screensaver-focus-helper/blackwindow.cpp b/screensaver-focus-helper/blackwindow.cpp index 52f270e..0830595 100644 --- a/screensaver-focus-helper/blackwindow.cpp +++ b/screensaver-focus-helper/blackwindow.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "blackwindow.h" #include #include diff --git a/screensaver-focus-helper/blackwindow.h b/screensaver-focus-helper/blackwindow.h index 9f30d24..6d1f071 100644 --- a/screensaver-focus-helper/blackwindow.h +++ b/screensaver-focus-helper/blackwindow.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef BLACKWINDOW_H #define BLACKWINDOW_H diff --git a/screensaver-focus-helper/main.cpp b/screensaver-focus-helper/main.cpp index 35a93f6..70b9982 100644 --- a/screensaver-focus-helper/main.cpp +++ b/screensaver-focus-helper/main.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include #include #include diff --git a/screensaver/CMakeLists.txt b/screensaver/CMakeLists.txt index 7bce0d7..ce810ff 100644 --- a/screensaver/CMakeLists.txt +++ b/screensaver/CMakeLists.txt @@ -1,6 +1,7 @@ pkg_check_modules(X11 REQUIRED x11) pkg_check_modules(XTST REQUIRED xtst) pkg_check_modules(QGS REQUIRED gsettings-qt) +pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_SOURCE_DIR}/Common) @@ -9,14 +10,20 @@ include_directories( ${X11_INCLUDE_DIRS} ${XTST_INCLUDE_DIRS} ${QGS_INCLUDE_DIRS} + ${KDKINFO_INCLUDE_DIRS} ) +link_directories( + ${KDKINFO_LIBRARY_DIRS} + ) + set(EXTRA_LIBS ${EXTRA_LIBS} ${X11_LIBRARIES} ${XTST_LIBRARIES} - ${QGS_LIBRARIES} - Common + ${QGS_LIBRARIES} + ${KDKINFO_LIBRARIES} + Common ) qt5_add_resources(screensaver_SRC default.qrc @@ -29,7 +36,7 @@ qt5_wrap_cpp(screensaver_SRC cyclelabel.h scconfiguration.h sleeptime.h - weathermanager.h + ../src/weathermanager.h ../src/networkwatcher.h ) set(screensaver_SRC @@ -41,18 +48,85 @@ set(screensaver_SRC cyclelabel.cpp scconfiguration.cpp sleeptime.cpp - weathermanager.cpp + ../src/weathermanager.cpp ../src/networkwatcher.cpp ) add_executable(ukui-screensaver-default ${screensaver_SRC}) target_link_libraries(ukui-screensaver-default Qt5::Core Qt5::Widgets Qt5::X11Extras Qt5::Xml Qt5::Network ${EXTRA_LIBS}) +qt5_add_resources(screensaver_Plugin_SRC + default.qrc + ) + +qt5_wrap_cpp(screensaver_Plugin_SRC + chinesedate.h + screensaver.h + mbackground.h + cyclelabel.h + scconfiguration.h + sleeptime.h + ../src/weathermanager.h + ../src/networkwatcher.h + customplugin.h + screensaverplugin.h + ) +set(screensaver_Plugin_SRC + ${screensaver_Plugin_SRC} + chinesedate.cpp + mbackground.cpp + screensaver.cpp + cyclelabel.cpp + scconfiguration.cpp + sleeptime.cpp + ../src/weathermanager.cpp + ../src/networkwatcher.cpp + customplugin.cpp + ) + +add_library(screensaver-default SHARED ${screensaver_Plugin_SRC}) +target_link_libraries(screensaver-default Qt5::Core Qt5::Widgets Qt5::X11Extras Qt5::Xml Qt5::Network ${EXTRA_LIBS}) + +qt5_add_resources(Screensaver_SRC + default.qrc + ) + +qt5_wrap_cpp(Screensaver_SRC + chinesedate.h + screensaver.h + mbackground.h + cyclelabel.h + scconfiguration.h + sleeptime.h + ../src/weathermanager.h + ../src/networkwatcher.h + ) +set(Screensaver_SRC + ${screensaver_Plugin_SRC} + chinesedate.cpp + mbackground.cpp + screensaver.cpp + cyclelabel.cpp + scconfiguration.cpp + sleeptime.cpp + ../src/weathermanager.cpp + ../src/networkwatcher.cpp + ) + +add_library(Screensaver STATIC ${Screensaver_SRC}) +target_link_libraries(Screensaver Qt5::Core Qt5::Widgets Qt5::X11Extras Qt5::Xml Qt5::Network ${EXTRA_LIBS}) + install(TARGETS ukui-screensaver-default + screensaver-default DESTINATION lib/ukui-screensaver) install(FILES language/screensaver-zh_CN.ini language/screensaver-en_US.ini + language/screensaver-bo_CN.ini language/screensaver-jd.ini DESTINATION share/ukui-screensaver/language) + +install(FILES + screensaverplugin.h + DESTINATION include/ukui-screensaver/) diff --git a/screensaver/assets/default.qss b/screensaver/assets/default.qss index 2abe225..7985c01 100644 --- a/screensaver/assets/default.qss +++ b/screensaver/assets/default.qss @@ -1,13 +1,10 @@ QLabel#dateOfWeek { - font-size:16px; color: #ffffff; } QLabel#dateOfLocaltime { - font-size:50px; color: #ffffff; } QLabel#dateOfDay { - font-size:16px; color: #ffffff; } QLabel#dateOfLunar { @@ -17,31 +14,25 @@ QLabel#dateOfLunar { QLabel#clockTime { background:rgba(255,255,255,0.15); border-radius: 6px; - font-size:20px; color: #ffffff; } QLabel#colon { - font-size:20px; color: #ffffff; } QLabel#restTime { - font-size:20px; color: #ffffff; opacity:0.6; } QLabel#centerLabel { - font-size:36px; color: #ffffff; } QLabel#authorLabel { - font-size:28px; color: #ffffff; } QLabel#myText{ - font-size:18px; border-radius: 6px; background: rgba(255, 255, 255, 82%); - padding: 24px 48px 24px 48px; + padding: 24px 24px 24px 24px; color: #000000; } QPushButton{ diff --git a/screensaver/customplugin.cpp b/screensaver/customplugin.cpp new file mode 100644 index 0000000..7f31d23 --- /dev/null +++ b/screensaver/customplugin.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "customplugin.h" +#include "screensaver.h" +#include +#include +#include + +#define WORKING_DIRECTORY "/usr/share/ukui-screensaver" + +CustomPlugin::CustomPlugin(QObject *parent):QObject(parent) +{ + +} + +QString CustomPlugin::name() const +{ + return "screensaver-default"; +} + +QWidget* CustomPlugin::createWidget(bool isScreensaver,QWidget* parent) +{ + //加载翻译文件 + QString locale = QLocale::system().name(); + QTranslator translator; + QString qmFile = QString(WORKING_DIRECTORY"/i18n_qm/%1.qm").arg(locale); + translator.load(qmFile); + qApp->installTranslator(&translator); + qDebug() << "load translation file " << qmFile; + return new Screensaver(isScreensaver,parent); +} + +QString CustomPlugin::displayName() const +{ + return "screensaver-default"; +} diff --git a/screensaver/customplugin.h b/screensaver/customplugin.h new file mode 100644 index 0000000..49f3b07 --- /dev/null +++ b/screensaver/customplugin.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef CUSTOMPLUGIN_H +#define CUSTOMPLUGIN_H + +#include "screensaverplugin.h" +#include + +class CustomPlugin : public QObject, ScreensaverPlugin +{ + Q_OBJECT + //声明QT识别的唯一标识符 + Q_PLUGIN_METADATA(IID "org.ukui.screensaver.screensaver-default1.0.0") + //声明实现的插件接口 + Q_INTERFACES(ScreensaverPlugin) +public: + CustomPlugin(QObject* parent = 0); + QString name() const override; + QWidget* createWidget(bool isScreensaver,QWidget* parent) override; + QString displayName() const override; +}; + +#endif // CUSTOMPLUGIN_H diff --git a/screensaver/cyclelabel.cpp b/screensaver/cyclelabel.cpp index a97f42f..f6c847a 100644 --- a/screensaver/cyclelabel.cpp +++ b/screensaver/cyclelabel.cpp @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #include "cyclelabel.h" diff --git a/screensaver/cyclelabel.h b/screensaver/cyclelabel.h index 9967836..b8b2af6 100644 --- a/screensaver/cyclelabel.h +++ b/screensaver/cyclelabel.h @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #ifndef CYCLELABEL_H #define CYCLELABEL_H diff --git a/screensaver/language/screensaver-bo_CN.ini b/screensaver/language/screensaver-bo_CN.ini new file mode 100644 index 0000000..2405521 --- /dev/null +++ b/screensaver/language/screensaver-bo_CN.ini @@ -0,0 +1,84 @@ +[1] +FL=སྐྱེ་བོ་ཡོན་ཏན་ཡོད་མེད་པའི།། བླང་དོར་བློ་གྲོས་ལྡན་པ་མཁས།། +SL=རྡུལ་དང་འདྲེས་པའི་ལྕགས་ཕྱེ་རྣམས།། ཁབ་ལེན་རྡོ་ཡིས་ལེན་པར་ཤེས།། +[2] +FL=ལེགས་བཤད་མཁས་པའི་བློ་གྲོས་ཀྱིས།། གོ་ཡི་བླུན་པོས་དེ་ལྟ་མིན།། +SL=ཉི་མའི་འོད་ཟེར་ཤར་བ་ན།། འབྱུང་པོའི་བྱ་རྣམས་ལོང་བར་འགྱུར།། +[3] +FL=བློ་ཆུང་གྲོས་གཉིས་འཁྲུགས་པའི་ཚེ།། བློ་ལྡན་ཐབས་ཀྱིས་བདེ་བར་གསོ།། +SL=ཆུ་ཀླུང་རྙོག་པས་ཆུད་གཟན་པ།། ཆུ་དྭངས་ནོར་བུས་དྭངས་པར་བྱེད།། +[4] +FL=ཤེས་རབ་ལྡན་པ་མགོ་བསྐོར་ཡང་།། བྱ་བའི་ཆ་ལ་རྨོངས་མི་འགྱུར།། +SL=སྲོག་ཆགས་གྲོག་མ་མིག་མེད་ཀྱང་།། མིག་ལྡན་གཞན་ལས་ལྷག་པར་མགྱོགས།། +[5] +FL=བླུན་པོས་ཡོན་ཏན་ཁར་འབྱིན་ཏེ།། མཁས་པས་ཡོན་ཏན་ཁོང་དུ་སྦེད།། +SL=སོག་མ་ཆུ་ཡི་སྟེང་དུ་འཕྱོ།། ནོར་བུ་སྟེང་དུ་བཞག་ཀྱང་འབྱིང་།། +[6] +FL=མཁས་པ་ཡོན་ཏན་དཔག་མེད་ཀྱང་།། གཞན་གྱི་ཡོན་ཏན་ཆུང་ངུའང་ལེན།། +SL=དེ་ལྟར་རྒྱུན་དུ་སྤྱད་པ་ཡིས།། མྱུར་དུ་ཐམས་ཅད་མཁྱེན་པར་འགྲོ།། +[7] +FL=མཁས་པ་སློབ་པའི་དུས་ན་སྡུག། བདེ་བར་སྡོད་ལ་མཁས་མི་སྲིད།། +SL=བདེ་བ་ཆུང་ལ་ཆགས་པ་དེས།། ཆེན་པོའི་བདེ་བ་ཐོབ་མི་སྲིད།། +[8] +FL=དམ་པའི་ཡོན་ཏན་སྦས་གྱུར་ཀྱང་།། འཇིག་རྟེན་ཀུན་ལ་ཁྱབ་པར་གསལ།། +SL=སྣ་མའི་མེ་ཏོག་ལེགས་བཀབ་ཀྱང་།། དྲི་ཞིམ་ཀུན་ཏུ་ཁྱབ་པར་འགྱུར།། +[9] +FL=བློ་དང་ལྡན་ན་ཉམ་ཆུང་ཡང་།། སྟོབས་ལྡན་དགྲ་བོས་ཅི་བྱར་ཡོད།། +SL=རི་དྭགས་རྒྱལ་པོ་སྟོབས་ལྡན་ཡང་།། རི་བོང་བློ་དང་ལྡན་པས་བསད།། +[10] +FL=བླུན་པོ་བྱ་བ་ལ་སྦྱར་ན།། དོན་ཉམས་དེ་ཡང་ཉམས་པར་འགྱུར།། +SL=ཝ་སྐྱེས་རྒྱལ་པོར་བསྐོས་པ་ཡིས།། འཁོར་སྡིག་རང་ཡང་བསད་ཅེས་གྲགས།། +[11] +FL=ཕན་དང་མི་ཕན་མི་དཔྱོད་ཅིང་།། བློ་དང་ཐོས་པ་མི་སྒྲུབ་པར།། +SL=ལྟོ་འགྲངས་འབའ་ཞིག་དོན་གཉེར་བ།། སྤུ་མེད་པ་ཡི་ཕག་པ་ཡིན།། +[12] +FL=ཡོན་ཏན་ཆུང་རྣམས་ང་རྒྱལ་ཆེ།། མཁས་པར་གྱུར་ན་དུལ་བར་གནས།། +SL=ཆུ་ཕྲན་རྟག་ཏུ་ཀུ་ཅོ་ཆེ།། རྒྱ་མཚོས་ཅ་ཅོ་ག་ལ་སྒྲོག། +[13] +FL=དམ་པ་དུལ་བས་རང་གཞན་སྐྱོང་།།ངན་པ་རེངས་པས་རང་གཞན་སྡུག། +SL=འབྲས་ལྡན་ཤིང་གིས་རང་གཞན་སྲུང་།། ཤིང་སྐམ་རེངས་པས་རང་གཞན་སྲེག། +[14] +FL=ཧ་ཅང་གཡོ་སྒྱུ་མང་དྲགས་ན།། རེ་ཞིག་གྲུབ་ཀྱང་མཐའ་མར་བརླགས།། +SL=གཟིག་ལྤགས་བཀབ་པའི་བོང་བུ་ཡིས།། ལོ་ཏོག་ཟོས་མཐར་གཞན་གྱི་བསད།། +[15] +FL=གཡོ་ཅན་བཟང་བོའི་ཚུལ་བཟུང་ནས།། ཕྱི་ནས་དོན་ལ་བསླུ་བ་ཡོད།།རི་དྭགས་རྔ་མ་བསྟན་ནས་ནི།། ཁྲེལ་འདས་བོང་བུའི་ཤ་དག་འཚོང་།། +SL=མང་བོ་གཅིག་ཏུ་བློ་མཐུན་ན།། ཉམ་ཆུང་གིས་ཀྱང་དོན་ཆེན་འགྲུབ།།སྲོག་ཆགས་གྲོག་མའི་ཚོགས་འདུས་པས།།སེང་གེའི་ཕྲུ་གུ་བསད་ཅེས་གྲགས།། +[16] +FL=བདག་ཉིད་དཔོན་དུ་བསྐོས་གྱུར་ན།། དེ་ཡི་བྱ་བ་ཤེས་པ་དཀོན།། +SL=གཞན་ལ་ལྟ་བའི་མིག་ཡོད་ཀྱང་།། རང་ཉིད་བལྟ་ན་མེ་ལོང་དགོས།། +[17] +FL=རང་གིས་ངན་སྤྱོད་མ་བྱས་ན།། བརྒྱ་བྱིན་གྱིས་ཀྱང་སྨན་མི་ནུས།། +SL=ཆུ་མིག་རང་ཉིད་མ་བསྐམས་ན།། ས་ཡིས་མནན་པས་ག་ལ་ཐུབ།། +[18] +FL=བློ་ལྡན་བྱ་བ་ཅུང་ཟད་ཀྱང་།། རྒྱུན་དུ་གྲོས་ཀྱིས་བསྒྲུབ་པར་བྱ།། +SL=གྲུབ་པར་གྱུར་ན་ལྟ་ཅི་སྨྲོས།། མ་གྲུབ་ན་ཡང་མཛེས་པའི་རྒྱུ།། +[19] +FL=རང་ལ་དགོས་པའི་བསྟན་བཅོས་རྣམས།། ཉི་མ་རེ་ལ་ཚིག་རེ་ཟུངས།། +SL=གྲོག་མཁར་དང་ནི་སྦྲང་རྩི་ལྟར།། རིང་བོར་མི་ཐོགས་མཁས་པར་འགྱུར།། +[20] +FL=མཁས་པ་ཡོན་ཏན་མཛོད་འཛིན་པ།། དེ་དག་ལེགས་བཤད་རིན་ཆེན་སྡུད།། +SL=རྒྱ་མཚོ་ཆེན་པོ་ཆུ་བོའི་གཏེར།། ཡིན་ཕྱིར་ཆུ་ཕྲན་ཐམས་ཅད་འབབ།། +[21] +FL=ཡོན་ཏན་ལྡན་ན་སྐྱེ་བོ་ཀུན།། མ་བསྡུས་པར་ཡང་རང་ཉིད་འདུ།། +SL=དྲི་ལྡན་མེ་ཏོག་རྒྱང་རིང་ཡང་།། བུང་བ་སྤྲིན་གྱི་ཚོགས་བཞིན་འཁོར།། +[22] +FL=བློ་གྲོས་ལྡན་པ་གཉིས་བགྲོས་ན།། བློ་གྲོས་ལེགས་པ་གཞན་འབྱུང་སྲིད།། +SL=ཡུང་བ་དང་ནི་ཚ་ལེ་ལས།། ཁ་དོག་གཞན་ཞིག་སྐྱེ་བར་འགྱུར།། +[23] +FL=ཐབས་ལ་མཁས་ན་ཆེན་པོ་ཡང་།། བྲན་དུ་བཀོལ་བར་ག་ལ་དཀའ།། +SL=མཁའ་ལྡིང་མཐུ་རྩལ་ཆེ་ན་ཡང་།། གོས་སེར་ཅན་གྱི་བཞོན་པར་གྱུར།། +[24] +FL=བློ་དང་ལྡན་ན་མ་སྨྲས་ཀྱང་།། རྣམ་འགྱུར་ཉིད་ལས་བསམ་པ་གོ། +SL=བལ་བོའི་སེའུ་མ་ཟོས་ཀྱང་།། ཁ་དོག་ཉིད་ལས་བྲོ་བ་ཤེས།། +[25] +FL=དམ་པ་རྒྱང་ན་གནས་ན་ཡང་།། འཁོར་འདབས་ཕན་པས་རིང་ནས་སྐྱོང་།། +SL=མཁའ་ལ་སྤྲིན་ཆེན་འཁྲིགས་པ་ཡིས།། ས་ཡི་ལོ་ཏོག་ཁྱད་པར་འཕེལ།། +[26] +FL=དམ་པ་སྡིག་པ་ཆུང་ཡང་སྤོང་།། དམན་རྣམས་ཆེན་པོའང་དེ་ལྟ་མིན།། +SL=ཞོ་ལ་རྡུལ་ཕྲན་འབྱར་བ་སེལ།།ཆང་ལ་ཕབ་ཀྱང་ལྷག་པར་འདེབས།། +[27] +FL=རྒྱལ་པོ་རང་ཡུལ་ཆེ་བ་ཙམ།། དམ་པ་གང་དུ་ཕྱིན་པར་བཀུར།། +SL=མེ་ཏོག་ཕལ་ཆེར་ཉིན་རེའི་རྒྱན།། གཙུག་གི་ནོར་བུ་གང་དུའང་མཆོད།། +[28] +FL=རིག་པ་ནངས་པར་འཆི་ཡང་བསླབ།། ཚེ་འདིར་མཁས་པར་མ་གྱུར་ཀྱང་།། +SL=སྐྱེ་བ་ཕྱི་མར་བཅོལ་བ་ཡི།། ནོར་ལ་རང་ཉིད་ལེན་དང་མཚུངས།། diff --git a/screensaver/language/screensaver-zh_CN.ini b/screensaver/language/screensaver-zh_CN.ini index f8befd1..51b93e7 100644 --- a/screensaver/language/screensaver-zh_CN.ini +++ b/screensaver/language/screensaver-zh_CN.ini @@ -1,161 +1,121 @@ [1] -FL=因为有悔,所以披星戴月 -SL=因为有梦,所以奋不顾身 -author= +FL=世上的事,只要肯用心去学, +SL=没有一件是太晚的。 +author=三毛《送你一匹马》 [2] -OL=大直若屈,大巧若拙,大辩若讷。 -author=《老子》 +OL=如果你是大河,何必在乎别人把你当成小溪。 +author=汪国真 《如果》 [3] -OL=博学之,审问之,慎思之,明辨之,笃行之。 -author=《礼记》 +OL=世界上有不绝的风景,我有不老的心情。 +author=汪国真《我喜欢出发》 [4] -OL=兼听则明,偏听则暗。 -author=《资治通鉴》 +OL=人生如逆旅,我亦是行人。 +author=苏轼《临江仙·送钱穆父》 [5] -FL=一花一世界,一叶一追寻。 -SL=一曲一场叹,一生为一人。 -author=威廉·布莱克《天真的预言》 +OL=行乐直须年少,尊前看取衰翁。 +author=欧阳修《朝中措·送刘仲原甫出守维扬》 [6] -FL=月光下,你带着笑地向我步来, -SL=月色与雪色之间,你是第三种绝色。 -author=余光中 -[7] -OL=不要问我心里有没有你,我余光中都是你。 -author=余光中 -[8] -FL=你要是愿意,我就永远爱你, -SL=你要是不愿意,我就永远相思。 -author=王小波 -[9] -FL=草在结它的种子,风在摇它的叶子。 -SL=我们站着,不说话,就十分美好。 -author=顾城 -[10] -OL=见到你,我觉得多少适应了这个世界。 -author=村上春树 -[11] -OL=不须耳鬓常厮伴,一笑低头意已倾。 -author=朱生豪 -[12] -FL=君臣一梦,今古空名。 -SL=但远山长,云山乱,晓山青。 -author=苏轼 -[13] -FL=心如规矩,志如尺衡, -SL=平静如水,正直如绳。 -author=严遵 -[14] -OL=近水知鱼性,近山识鸟音。 -author=周希陶 -[15] -OL=此处果有可乐,我即别无所思。 -author=林语堂 -[16] -FL=心之所向,素履以往, -SL=生如逆旅,一苇以航。 -author=七堇年《尘曲》 -[17] -FL=你说,我们就山居于此吧, -SL=胭脂用尽时,桃花就开了。 -author=与谢野晶子 -[18] -OL=世间所有的相遇,都是久别重逢。 -author=白落梅 -[19] -OL=浮云一别后,流水十年间。 -author=韦应物《淮上喜会梁川故人》 -[20] -OL=最是人间留不住,朱颜辞镜花辞树。 -author=王国维《蝶恋花》 -[21] OL=行到水穷处,坐看云起时。 -author=王维 +author=王维《终南别业》 +[7] +OL=仰天大笑出门去,我辈岂是蓬蒿人。 +author=李白《南陵别儿童入京》 +[8] +OL=天生我材必有用,千金散尽还复来。 +author=李白《将进酒》 +[9] +OL=希君生羽翼,一化北溟鱼。 +author=李白《江夏使君叔席上赠史郎中》 +[10] +OL=惟沉默是最高的轻蔑。 +author=鲁迅《且介亭杂文附集》 +[11] +OL=虽偶有轻风细雨,但总归晴天朗照。 +author=史铁生《记忆与印象》 +[12] +OL=不能走远路却有辽阔的心。 +author=史铁生《我与地坛》 +[13] +OL=从卖气球的人那里,每个孩子牵走一个心愿。 +author=北岛《代课》 +[14] +OL=要有最朴素的生活和最遥远的梦想 +author=海子《枫》 +[15] +OL=雾打湿了我的双翼,可风却不容我再迟疑。 +author=舒婷《双桅船》 +[16] +OL=拯救地球好累,虽然有些疲惫但我还是会。 +author=《超人不会飞》 +[17] +OL=宁可一思进,莫在一思停。 +author=电影《一代宗师》 +[18] +OL=让人类永远保持理智,确实是一件奢侈的事。 +author=电影《流浪地球》 +[19] +FL=无论结果如何,人类的勇气和坚毅, +SL=都被镌刻在星空下。 +author=电影《流浪地球》 +[20] +OL=生活就像一盒巧克力,你不知道你的下一块口味是什么。 +author=电影《阿甘正传》 +[21] +FL=也许我们这些聪明人,脑袋里能装的目标太多, +SL=所以忘了执着。 +author=电影《阿甘正传》 [22] -OL=我有一瓢酒,可以慰风尘。 -author=韦应物 +FL=我并不是每次吃完饭就看电视,有时我边吃边看电视, +SL=生活中有些改变会增加乐趣。 +author=电影《加菲猫》 [23] -OL=墙头马上遥相顾,一见知君即断肠。 -author=白居易 +OL=做人如果没梦想,那跟咸鱼有什么分别? +author=电影《少林足球》 [24] -OL=人生到处知何似,应似飞鸿踏雪泥。 -author=《和子由渑池怀旧》 +FL=世界上有一种鸟是关不住的,因为它们的每一片羽毛都沾满了太阳的光辉。 +SL=当它们飞走的时候,你会觉得把它关起来是一种罪恶。 +author=电影《肖申克的救赎》 [25] -OL=粗缯大布裹生涯,腹有诗书气自华。 -author=《和董传留别》 +FL=你每天都在做很多看起来毫无意义的决定, +SL=但某天你的某个决定就能改变你一生。 +author=电影《西雅图未眠夜》 [26] -OL=清风徐来,水波不兴。 -author=《前赤壁赋》 +FL=把人类看做虫子的三体人似乎忘记了一个事实: +SL=虫子从来没有被战胜过。 +author=刘慈欣《三体》 [27] -OL=我有斗酒,藏之久矣,以待子不时之须。 -author=《后赤壁赋》 +FL=在宇宙中,你再快都有比你更快的, +SL=你再慢也有比你更慢的。 +author=刘慈欣《三体》 [28] -FL=若是有缘,千山暮雪,万里层云,终会重逢。 -SL=若是无缘,自此一去,天涯海角,再难相会。 -author=白落梅《你若安好便是晴天》 +OL=人间风雨各处有,何处不是浪浪山? +author=国漫《小妖怪的夏天》 [29] -FL=愿你一生努力,一生被爱。 -SL=想要的都拥有,得不到的都释怀。 -author=八月长安 -[30] -OL=凌晨四点醒来,发现海棠花未眠。 -author=川端康成 -[31] -OL=无路可走的时候,就不断回到原点。 -author=东野圭吾 -[32] -OL=你要批评指点四周的风景,你首先要爬上屋顶。 -author=歌德 -[33] -OL=只有流过血的手指,才能弹出世间的绝唱。 -author=泰戈尔 -[34] -FL=幸亏时光不会倒流, -SL=否则万物一定会朝旧岁月里疾步奔跑。 -author=《迷楼》 -[35] FL=我看到那些岁月如何奔驰, SL=挨过了冬季,便迎来了春天。 author=《瓦尔登湖》 -[36] -FL=整个世界展现在我们面前, -SL=期待着我们去创造,而不是去重复。 -author=毕加索 -[37] -FL=不必太纠结于当下,也不必太忧虑未来, -SL=当你经历过一些事情的时候,眼前的风景已经和从前不一样了。 -author=村上春树 -[38] -OL=三更梦醒,你是檐上落下的星。 +[30] +OL=保持热爱,奔赴山海。 author=佚名 -[39] -OL=我将永远忠于自己,披星戴月的奔向理想与自由。 +[31] +OL=别慌,月亮也正在大海某处迷茫。 author=佚名 -[40] -OL=有一天,我看了43次日落! -author=《小王子》 -[41] +[32] OL=当太阳升到最高点的时候,影子就不见了。 author=佚名 -[42] -OL=拯救地球好累,虽然有些疲惫但我还是会。 -author=《超人不会飞》 -[43] -OL=陌上花开,可缓缓归矣 +[33] +OL=大直若屈,大巧若拙,大辩若讷。 +author=《老子》 +[34] +OL=博学之,审问之,慎思之,明辨之,笃行之。 +author=《礼记》 +[35] +OL=你要批评指点四周的风景,你首先要爬上屋顶。 +author=歌德 +[36] +OL=只有流过血的手指,才能弹出世间的绝唱。 +author=泰戈尔 +[37] +OL=他强任他强,清风拂山岗。 author=佚名 -[44] -OL=别慌,月亮也正在大海某处迷茫 -author=佚名 -[45] -OL=夏天到了,春天的不甘该统统放下了 -author=佚名 -[46] -OL=保持热爱,奔赴山海 -author=佚名 -[47] -FL=你好,是故事的开始, -SL=你要好好的,是故事的结局。 -author=佚名 -[48] -OL=工欲善其事,必先利其器。 -author=《孔子》 diff --git a/screensaver/main.cpp b/screensaver/main.cpp index eb40b19..28f3dd3 100644 --- a/screensaver/main.cpp +++ b/screensaver/main.cpp @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) QCommandLineParser parser; QString windowId; - Screensaver s; + Screensaver s(false); XWindowAttributes xwa; parser.setApplicationDescription("Test helper"); @@ -81,14 +81,24 @@ int main(int argc, char *argv[]) scale = screen->devicePixelRatio(); if(onWindow){ - windowId = parser.value("window-id"); + windowId = parser.value("window-id"); WId wid = windowId.toULong(); - QWindow* window = QWindow::fromWinId(wid); - window->setProperty("_q_embedded_native_parent_handle",QVariant(wid)); - s.winId(); - s.windowHandle()->setParent(window); - XGetWindowAttributes (QX11Info::display(), wid, &xwa); + /*获取窗口属性失败时程序退出,这是为了避免应用调用屏保的一瞬间崩溃,导致 + 屏保获取到一个不存在的winid,从而产生一个屏保窗口*/ + + if(!XGetWindowAttributes (QX11Info::display(), wid, &xwa)) + { + qDebug()<<"XGetWindowAttributes failed"; + exit(0); + } + + QWindow* window = QWindow::fromWinId(wid); + s.setProperty("_q_embedded_native_parent_handle",QVariant(wid)); + /*设置焦点穿透*/ + s.setWindowFlag(Qt::WindowTransparentForInput, true); + s.winId(); + s.windowHandle()->setParent(window); #ifndef USE_INTEL XClassHint ch; ch.res_name = NULL; diff --git a/screensaver/scconfiguration.cpp b/screensaver/scconfiguration.cpp index a348df4..7342b76 100644 --- a/screensaver/scconfiguration.cpp +++ b/screensaver/scconfiguration.cpp @@ -21,6 +21,10 @@ #include #include #include +#include +#include +#include +#include "glibinterface.h" #define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" #define GSETTINGS_SCHEMA_MATE_BACKGROUND "org.mate.background" @@ -119,9 +123,13 @@ void SCConfiguration::onConfigurationChanged(QString key) }else if(key == "menuTransparency"){ int blur_Num = stygsettings->get("menuTransparency").toInt(); Q_EMIT blurChanged(blur_Num); - }else if(key == "styleName"){ + }else if(key == "styleName"){ QString m_curStyle = stygsettings->get("styleName").toString(); Q_EMIT styleChanged(m_curStyle); + } else if (key == "systemFontSize") { + double m_curFontSize = stygsettings->get("systemFontSize").toDouble(); + qDebug() << "curFontSize = " << m_curFontSize ; + Q_EMIT fontSizeChanged(m_curFontSize); } } @@ -132,10 +140,19 @@ QString SCConfiguration::getDefaultBackground() backgroundFile = ukgsettings->get("background").toString(); } - if(ispicture(backgroundFile)) + if(ispicture(backgroundFile)) { return backgroundFile; - else + } else { + char *systemName = kdk_system_get_systemName(); + if (systemName) { + if (QString(systemName) == "openKylin") { + free(systemName); + return "/usr/share/backgrounds/1-openkylin.jpg"; + } + free(systemName); + } return "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; + } } int SCConfiguration::getTimeType() @@ -162,6 +179,30 @@ QString SCConfiguration::getDateType() return dateType; } +int SCConfiguration::getFontSize() +{ + double fontSize = 0; + if(stygsettings){ + QStringList keys = stygsettings->keys(); + if (keys.contains("systemFontSize")) { + fontSize = stygsettings->get("systemFontSize").toDouble(); + } + } + + double defaultFontSize = getDefaultFontSize(); + qDebug()<<"defaultFontSize = "<logicalDotsPerInch() > 0) + m_ptTopx = 72/(QApplication::primaryScreen()->logicalDotsPerInch()); + return m_ptTopx; +} + bool SCConfiguration::getAutoSwitch() { bool ret = false; diff --git a/screensaver/scconfiguration.h b/screensaver/scconfiguration.h index e41ba78..83322fe 100644 --- a/screensaver/scconfiguration.h +++ b/screensaver/scconfiguration.h @@ -38,6 +38,8 @@ public: QString getDefaultBackground(); //获取屏保默认背景 int getTimeType(); //获取显示时间格式 QString getDateType(); //获取日期格式 + int getFontSize(); //获取当前字体大小 + double getPtToPx(); bool getAutoSwitch(); //获取是否自动切换 bool getCShowRestTime(); //自定义是否显示休息时间 bool getUShowRestTime(); //UKUI是否显示休息时间 @@ -69,6 +71,7 @@ Q_SIGNALS: QString dateTypeChanged(QString type); int blurChanged(int num); QString styleChanged(QString type); + int fontSizeChanged(int fontSize); private: void initGsettings(); diff --git a/screensaver/screensaver.cpp b/screensaver/screensaver.cpp index e481abe..c556d56 100644 --- a/screensaver/screensaver.cpp +++ b/screensaver/screensaver.cpp @@ -48,14 +48,16 @@ #include #include #include +#include #include +#include "../src/weathermanager.h" +#include "commonfunc.h" #include "screensaver.h" #include #include #include #include -#include "commonfunc.h" #include "config.h" #define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" @@ -66,11 +68,13 @@ #define KEY_MESSAGE_SHOW_ENABLED "show-message-enabled" #define KEY_HOURSYSTEM "hoursystem" #define KEY_DATE_FORMAT "date" +#define WORKING_DIRECTORY "/usr/share/ukui-screensaver" QTime Screensaver::m_currentTime = QTime::currentTime(); extern bool bControlFlg; -Screensaver::Screensaver(QWidget *parent): +Screensaver::Screensaver(bool isscreensaver,QWidget *parent): + isScreensaver(isscreensaver), QWidget(parent), switchTimer(nullptr), backgroundPath(""), @@ -93,8 +97,7 @@ Screensaver::Screensaver(QWidget *parent): hasChanged(false), process(nullptr), screenLabel(nullptr), - respondClick(false), - m_weatherManager(new WeatherManager(this)) + respondClick(false) { installEventFilter(this); // setWindowFlags(Qt::X11BypassWindowManagerHint); @@ -112,12 +115,13 @@ Screensaver::Screensaver(QWidget *parent): myText = configuration->getMyText(); }else isUShowRestTime = configuration->getUShowRestTime(); - + curFontSize = configuration->getFontSize(); + m_ptToPx = configuration->getPtToPx(); initUI(); m_background = new MBackground(); QString backgroundFile = configuration->getDefaultBackground(); - background = QPixmap(backgroundFile); + background = loadFromFile(backgroundFile); QList labelList = this->findChildren(); for(int i = 0;isetText(tr("Picture does not exist")); screenLabel->adjustSize(); screenLabel->hide(); - + m_strPreViewTrans = tr("View"); } Screensaver::~Screensaver() @@ -173,7 +177,7 @@ void Screensaver::themeChanged() myTextLabel->setStyleSheet(QString("font-size:5px;border-radius: 2px;background: %1;color: %2;padding: 4px 8px 4px 8px;border-width: 1px;border-style: solid;border-color:%3;") \ .arg(stringColor).arg(textString).arg(borderString)); else - myTextLabel->setStyleSheet(QString("font-size:18px;border-radius: 6px;background: %1;color: %2;padding: 24px 48px 24px 48px;border-width: 1px;border-style: solid;border-color:%3;") \ + myTextLabel->setStyleSheet(QString("font-size:24px;border-radius: 6px;background: %1;color: %2;padding: 24px 24px 24px 24px;border-width: 1px;border-style: solid;border-color:%3;") \ .arg(stringColor).arg(textString).arg(borderString)); } } @@ -240,6 +244,11 @@ void Screensaver::onDateFormatChanged(QString type){ dateType = type; } +void Screensaver::onFontSizeChanged(int fontSize) +{ + curFontSize = fontSize; +} + void Screensaver::onMessageNumberChanged(int num) { int number = configuration->getMessageNumber(); @@ -367,7 +376,7 @@ bool Screensaver::eventFilter(QObject *obj, QEvent *event) #ifndef USE_INTEL if(obj == this){ if(event->type()==QEvent::MouseButtonPress){ - if(respondClick){ + if(!isScreensaver){ if(!process){ process = new QProcess(this); } @@ -495,19 +504,30 @@ void Screensaver::resizeEvent(QResizeEvent */*event*/) { float scale = 1.0; scale = (float)width()/1920; - if(width() < 600 || height()<400){//当显示在控制面板上时,字体缩小三倍。 + if((width() < 600 || height()<400) && !isScreensaver){//当显示在控制面板上时,字体缩小三倍。 if(flag == 0) { QList labelList = this->findChildren(); for(int i = 0;ifont().pixelSize(); + int fontpt = labelList.at(i)->font().pointSize(); + if (fontsize > 0) { #ifdef USE_INTEL - const QString SheetStyle = QString("font-size:%1px;").arg(fontsize/3); + const QString SheetStyle = QString("font-size:%1px;").arg(fontsize/3); #else - const QString SheetStyle = QString("font-size:%1px;").arg(fontsize/4); + const QString SheetStyle = QString("font-size:%1px;").arg(fontsize/4); #endif - labelList.at(i)->setStyleSheet(SheetStyle); + labelList.at(i)->setStyleSheet(SheetStyle); + } else { + QFont font = labelList.at(i)->font(); +#ifdef USE_INTEL + font.setPointSize(fontpt/3); +#else + font.setPointSize(fontpt/4); +#endif + labelList.at(i)->setFont(font); + } } QList childList = timeLayout->findChildren(); for (int i = 0; i < childList.count(); ++i) { @@ -520,25 +540,6 @@ void Screensaver::resizeEvent(QResizeEvent */*event*/) flag = 1; #ifndef USE_INTEL if(myTextWidget){ - -// QColor highLightColor = palette().color(QPalette::Base); -// QString stringColor = QString("rgba(%1,%2,%3,82%)") -// .arg(highLightColor.red()) -// .arg(highLightColor.green()) -// .arg(highLightColor.blue()); -// QColor textColor = palette().color(QPalette::Text); -// QString textString = QString("rgb(%1,%2,%3)") -// .arg(textColor.red()) -// .arg(textColor.green()) -// .arg(textColor.blue()); -// QColor borderColor = palette().color(QPalette::BrightText); -// QString borderString = QString("rgba(%1,%2,%3,85%)") -// .arg(borderColor.red()) -// .arg(borderColor.green()) -// .arg(borderColor.blue()); - -// myTextLabel->setStyleSheet(QString("font-size:5px;border-radius: 2px;background: %1;color: %2;padding: 4px 8px 4px 8px;border-width: 1px;border-style: solid;border-color:%3;") \ -// .arg(stringColor).arg(textString).arg(borderString)); if(curStyle == "ukui-dark" || curStyle == "ukui-black"){ myTextLabel->setStyleSheet(QString("QLabel{font-size:5px;border-radius: 2px;padding: 4px 8px 4px 8px;border-width: 1px;\ background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:16px}").arg(blur_Num * 0.01)); @@ -651,7 +652,10 @@ void Screensaver::setUpdateCenterWidget() lang=lang.split('.')[0]; qDebug()<<"langStr = "<beginGroup(QString::number(index)); if(qsettings->contains("OL")){ - centerlabel1->setText(qsettings->value("OL").toString()); + if(qsettings->value("OL").typeName() == "QString") + centerlabel1->setText(qsettings->value("OL").toString()); + else + centerlabel1->setText(qsettings->value("OL").toStringList().join(' ')); centerlabel2->hide(); #ifndef USE_INTEL authorlabel->setText(qsettings->value("author").toString()); @@ -798,8 +805,14 @@ void Screensaver::updateCenterWidget(int index) } else if(qsettings->contains("FL")) { - centerlabel1->setText(qsettings->value("FL").toString()); - centerlabel2->setText(qsettings->value("SL").toString()); + if(qsettings->value("FL").typeName() == "QString") + centerlabel2->setText(qsettings->value("FL").toString()); + else + centerlabel2->setText(qsettings->value("FL").toStringList().join(' ')); + if(qsettings->value("SL").typeName() == "QString") + centerlabel2->setText(qsettings->value("SL").toString()); + else + centerlabel2->setText(qsettings->value("SL").toStringList().join(' ')); centerlabel2->show(); #ifndef USE_INTEL authorlabel->setText(qsettings->value("author").toString()); @@ -958,6 +971,9 @@ void Screensaver::setDatelayout() QVBoxLayout *vtimeLayout = new QVBoxLayout(timeLayout); this->dateOfLocaltime = new QLabel(this); + sysFont= qApp->font(); + sysFont.setPointSize((58 + curFontSize) *m_ptToPx); + this->dateOfLocaltime->setFont(sysFont); if(timeType == 12) this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("A hh:mm")); else @@ -969,10 +985,12 @@ void Screensaver::setDatelayout() vtimeLayout->addWidget(dateOfLocaltime); this->dateOfDay = new QLabel(this); + sysFont.setPointSize((16 + curFontSize) *m_ptToPx); + this->dateOfDay->setFont(sysFont); if(dateType == "cn") - this->dateOfDay->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + this->dateOfDay->setText(QDate::currentDate().toString("yyyy/MM/dd ddd").replace("周","星期")); else - this->dateOfDay->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + this->dateOfDay->setText(QDate::currentDate().toString("yyyy-MM-dd ddd").replace("周","星期")); this->dateOfDay->setObjectName("dateOfDay"); this->dateOfDay->setAlignment(Qt::AlignCenter); this->dateOfDay->adjustSize(); @@ -1038,7 +1056,7 @@ void Screensaver::updateDate() timer->setTimerType(Qt::PreciseTimer); connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); } - timer->start(800); + timer->start(500); updateTime(); } @@ -1078,15 +1096,19 @@ void Screensaver::updateTime() m_currentTime = QTime::currentTime(); #else - if(timeType == 12) - this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("A hh:mm")); - else - this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("hh:mm")); + QDateTime curDateTime = QDateTime::currentDateTime(); + if (m_lastDateTime.isNull() || qAbs(curDateTime.secsTo(m_lastDateTime)) >=1) { + if(timeType == 12) + this->dateOfLocaltime->setText(curDateTime.toString("A hh:mm")); + else + this->dateOfLocaltime->setText(curDateTime.toString("hh:mm")); - if(dateType == "cn") - this->dateOfDay->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); - else - this->dateOfDay->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + if(dateType == "cn") + this->dateOfDay->setText(curDateTime.date().toString("yyyy/MM/dd ddd").replace("周","星期")); + else + this->dateOfDay->setText(curDateTime.date().toString("yyyy-MM-dd ddd").replace("周","星期")); + m_lastDateTime = curDateTime; + } if(sleepTime){ if(!sleepTime->setTime(QDateTime::currentDateTime())){ @@ -1107,7 +1129,7 @@ void Screensaver::updateBackground() { QString path = m_background->getRand(); if(!path.isEmpty() && ispicture(path)){ - background = QPixmap(path); + background = loadFromFile(path); hasChanged=true; isMovie(); } @@ -1122,7 +1144,7 @@ void Screensaver::setRandomText() cycleLabel = new QLabel(this); cycleLabel->setFixedSize(16,16); layout->addWidget(cycleLabel); - layout->setSpacing(16); + layout->setSpacing(8); myTextLabel = new QLabel(myTextWidget); myTextLabel->setObjectName("myText"); // myTextLabel->setBackgroundRole(QPalette::Base); @@ -1147,7 +1169,7 @@ void Screensaver::setRandomText() // .arg(stringColor).arg(textString).arg(borderString)); blur_Num = configuration->getBlurNumber(); curStyle = configuration->getcurStyle(); - qDebug()<<"cu人Style= "<setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:16px}").arg(blur_Num * 0.01)); cycleLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:8px}").arg(blur_Num * 0.01)); @@ -1157,7 +1179,8 @@ void Screensaver::setRandomText() } layout->addWidget(myTextLabel); } - + sysFont.setPointSize((18 + curFontSize) *m_ptToPx); + myTextLabel->setFont(sysFont); myTextLabel->setText(myText); myTextWidget->adjustSize(); if(myText != "") @@ -1180,7 +1203,7 @@ void Screensaver::setPreviewText(bool bVisible) myPreviewLabel->setAlignment(Qt::AlignCenter); } - myPreviewLabel->setText(tr("View")); + myPreviewLabel->setText(m_strPreViewTrans); myPreviewLabel->adjustSize(); myPreviewLabel->setVisible(bVisible); @@ -1214,7 +1237,10 @@ void Screensaver::setCenterWidget() authorlabel = new QLabel(""); } else if(qsettings->contains("OL")){ - centerlabel1 = new QLabel(qsettings->value("OL").toString()); + if(qsettings->value("OL").typeName() == "QString") + centerlabel1 = new QLabel(qsettings->value("OL").toString()); + else + centerlabel1 = new QLabel(qsettings->value("OL").toStringList().join(' ')); centerlabel2 = new QLabel(""); centerlabel2->hide(); #ifndef USE_INTEL @@ -1223,8 +1249,14 @@ void Screensaver::setCenterWidget() } else if(qsettings->contains("FL")) { - centerlabel1 = new QLabel(qsettings->value("FL").toString()); - centerlabel2 = new QLabel(qsettings->value("SL").toString()); + if(qsettings->value("FL").typeName() == "QString") + centerlabel1 = new QLabel(qsettings->value("FL").toString()); + else + centerlabel1 = new QLabel(qsettings->value("FL").toStringList().join(' ')); + if(qsettings->value("SL").typeName() == "QString") + centerlabel2 = new QLabel(qsettings->value("SL").toString()); + else + centerlabel2 = new QLabel(qsettings->value("SL").toStringList().join(' ')); centerlabel2->show(); #ifndef USE_INTEL authorlabel = new QLabel(qsettings->value("author").toString()); @@ -1243,10 +1275,14 @@ void Screensaver::setCenterWidget() authorlabel->hide(); } #endif - centerlabel1->setObjectName("centerLabel"); centerlabel2->setObjectName("centerLabel"); authorlabel->setObjectName("authorLabel"); + sysFont.setPointSize((36 + curFontSize) *m_ptToPx); + centerlabel1->setFont(sysFont); + centerlabel2->setFont(sysFont); + sysFont.setPointSize((28 + curFontSize) *m_ptToPx); + authorlabel->setFont(sysFont); qsettings->endGroup(); @@ -1356,6 +1392,15 @@ void Screensaver::hideNotice() { m_widgetNotice->hide(); } + +QPixmap Screensaver::loadFromFile(QString strPath) +{ + QImageReader reader; + reader.setFileName(strPath); + reader.setAutoTransform(true); + reader.setDecideFormatFromContent(true); + return QPixmap::fromImageReader(&reader); +} /* void Screensaver::setDesktopBackground() { diff --git a/screensaver/screensaver.h b/screensaver/screensaver.h index cca782b..bbdb2b6 100644 --- a/screensaver/screensaver.h +++ b/screensaver/screensaver.h @@ -37,14 +37,15 @@ #include "checkbutton.h" #include "scconfiguration.h" #include "cyclelabel.h" -#include "weathermanager.h" + +class WeatherManager; class Screensaver : public QWidget { Q_OBJECT public: - explicit Screensaver(QWidget *parent = 0); + explicit Screensaver(bool isScreensaver,QWidget *parent = 0); ~Screensaver(); void addClickedEvent(); @@ -69,6 +70,7 @@ private: void enterEvent(QEvent*); void leaveEvent(QEvent*); void isMovie(); + QPixmap loadFromFile(QString strPath); QTimer *switchTimer; QTimer *fadeTimer; @@ -134,8 +136,11 @@ private: static QTime m_currentTime; int blur_Num; QString curStyle; + double curFontSize; + double m_ptToPx = 1.0; + QFont sysFont; - WeatherManager *m_weatherManager; + WeatherManager *m_weatherManager=nullptr; QWidget *m_weatherLaout; QLabel *m_weatherIcon; QLabel *m_weatherArea; @@ -153,7 +158,9 @@ private: int delayTime; QTimer *movieTimer = nullptr; int currentCount = 0; - + QDateTime m_lastDateTime; + bool isScreensaver = false; \ + QString m_strPreViewTrans; protected: void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); @@ -178,6 +185,7 @@ private Q_SLOTS: void onDateFormatChanged(QString type); void onBlurNumChanged(int num); void onStyleChanged(QString style); + void onFontSizeChanged(int fontSize); QPixmap getPaddingPixmap(); }; diff --git a/screensaver/screensaverplugin.h b/screensaver/screensaverplugin.h new file mode 100644 index 0000000..4fcd9ff --- /dev/null +++ b/screensaver/screensaverplugin.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef SCREENSAVER_PLUGIN_H +#define SCREENSAVER_PLUGIN_H + +#include + +class ScreensaverPlugin +{ +public: + virtual ~ScreensaverPlugin() {} + //插件实例的名称 + virtual QString name() const = 0; + + //创建UI的实例 + virtual QWidget* createWidget(bool isScreensaver,QWidget* parent) = 0; + + //获得插件的展示名称 + virtual QString displayName() const = 0; +}; + +//定义了在QT系统中该接口的全局唯一的ID +//实现该SDK的插件也要定义相同的ID +//接口的ID中包含了版本信息,通过该ID我们可以区别不同版本的SDK和插件 +//Q_DECLARE_INTERFACE宏将类型和ID关联起来,这样QT就可以验证加载的插件是否可以转换成MyPluginInterface类型 +#define interface_iid "org.ukui.screensaver.screensaver-default1.0.0" +Q_DECLARE_INTERFACE(ScreensaverPlugin, interface_iid) + +#endif // FILTER_H diff --git a/screensaver/sleeptime.cpp b/screensaver/sleeptime.cpp index 9fd6650..bd06b4d 100644 --- a/screensaver/sleeptime.cpp +++ b/screensaver/sleeptime.cpp @@ -20,9 +20,13 @@ #include #include #include +#include SleepTime::SleepTime(QWidget *parent) : QWidget(parent), - sleepTime(0) + sleepTime(0), + m_nLastSleepLeave(0), + m_nLastSleepTimeSecs(0), + configuration(SCConfiguration::instance()) { init(); } @@ -36,29 +40,25 @@ void SleepTime::init() { layout = new QHBoxLayout(this); layout->setDirection(QBoxLayout::RightToLeft); - layout->setSpacing(4); - - for(int i=0;i<2;i++) - { - QLabel *label = new QLabel(this); - label->setText("0"); - label->setFixedSize(40,40); - label->setObjectName("clockTime"); - list.append(label); - } - - QLabel *colon = new QLabel(this); - colon->setText(":"); - colon->setObjectName("colon"); - list.append(colon); - - for(int i=0;i<2;i++) + layout->setSpacing(8); + curFontSize = configuration->getFontSize(); + sysFont = qApp->font(); + sysFont.setPointSize((20 + curFontSize) *m_ptToPx); + for(int i=0;i<3;i++) { QLabel *label = new QLabel(this); label->setText("0"); label->setFixedSize(40,40); label->setObjectName("clockTime"); + label->setFont(sysFont); list.append(label); + if (i < 2) { + QLabel *colon = new QLabel(this); + colon->setText(":"); + colon->setObjectName("colon"); + colon->setFont(sysFont); + list.append(colon); + } } for(int i=0;isetText(tr("You have rested:")); + sysFont.setPointSize((20 + curFontSize) *m_ptToPx); + restTime->setFont(sysFont); + restTime->setText(tr("You have rested")); restTime->setObjectName("restTime"); restTime->setAlignment(Qt::AlignBottom); restTime->adjustSize(); + layout->addSpacing(8); layout->addWidget(restTime); initTime = QDateTime::currentDateTime(); + m_lastTime = initTime; } int SleepTime::setTime(QDateTime time) { - sleepTime = initTime.secsTo(time); - if(sleepTime>5999 || sleepTime<0){ - hide(); - return false; + // 与上一次取时间的时间差 + long nNewSleepTime = qAbs(m_lastTime.msecsTo(time)); + sleepTime = qAbs(initTime.msecsTo(time)); + // 时间差大于1s,则认为时间异常变化,保存已过去的时间 + if (nNewSleepTime > 1000) { + m_nLastSleepLeave += qAbs(m_lastTime.msecsTo(initTime)); + sleepTime = 0; + initTime = time; } + m_lastTime = time; + //当前时间差+异常情况过去的时间 + sleepTime += m_nLastSleepLeave; + sleepTime = sleepTime/1000; - int sec = sleepTime % 60; - int min = sleepTime/60; - setSeconds(sec); - setMinute(min); + if (m_nLastSleepTimeSecs == 0 || qAbs(sleepTime - m_nLastSleepTimeSecs) >= 1) { + int hour = sleepTime / 3600; + int sec = sleepTime % 3600 % 60; + int min = sleepTime % 3600 / 60; + setHour(hour); + setSeconds(sec); + setMinute(min); + m_nLastSleepTimeSecs = sleepTime; + } return true; } +void SleepTime::setHour(int hour) +{ + QString time; + if (hour >= 100) { + QLabelSetText(list.at(4), QString::number(hour)); + } else if (hour < 10) { + time = "0" + QString::number(hour); + list.at(4)->setText(time); + } else { + time = QString::number(hour); + list.at(4)->setText(time); + } + +} + void SleepTime::setSeconds(int seconds) { - int sec1 = seconds%10; - int sec2 = seconds/10; - - list.at(0)->setText(QString::number(sec1)); - list.at(1)->setText(QString::number(sec2)); + QString time; + if (seconds < 10) { + time = "0" + QString::number(seconds); + } else { + time = QString::number(seconds); + } + list.at(0)->setText(time); } void SleepTime::setMinute(int minutes) { - - int min1 = minutes%10; - int min2 = minutes/10; - list.at(3)->setText(QString::number(min1)); - list.at(4)->setText(QString::number(min2)); + QString time; + if (minutes < 10) { + time = "0" + QString::number(minutes); + } else { + time = QString::number(minutes); + } + list.at(2)->setText(time); } void SleepTime::setSmallMode() @@ -117,3 +153,18 @@ void SleepTime::setSmallMode() list.at(i)->setFixedSize(8,8); adjustSize(); } + +bool SleepTime::QLabelSetText(QLabel *label, QString string) +{ + bool is_over_length = false; + QFontMetrics fontMetrics(label->font()); + int fontSize = fontMetrics.width(string); + QString str = string; + if (fontSize > (label->width()-5)) { + str = fontMetrics.elidedText(string, Qt::ElideRight, label->width()); + is_over_length = true; + } + label->setText(str); + return is_over_length; +} + diff --git a/screensaver/sleeptime.h b/screensaver/sleeptime.h index bef0e32..2174ac5 100644 --- a/screensaver/sleeptime.h +++ b/screensaver/sleeptime.h @@ -19,6 +19,7 @@ #ifndef SLEEPTIME_H #define SLEEPTIME_H +#include "scconfiguration.h" #include #include #include @@ -36,15 +37,24 @@ public: void setSmallMode(); private: + SCConfiguration *configuration; QLabel *restTime; QList list; QHBoxLayout *layout; - int sleepTime; + long long sleepTime; + long long m_nLastSleepLeave; + long long m_nLastSleepTimeSecs; QDateTime initTime; + QDateTime m_lastTime; + double curFontSize; + double m_ptToPx = 1.0; + QFont sysFont; void init(); + void setHour(int hour); void setSeconds(int seconds); void setMinute(int minutes); + bool QLabelSetText(QLabel *label, QString string); }; #endif // SLEEPTIME_H diff --git a/screensaver/weathermanager.h b/screensaver/weathermanager.h deleted file mode 100644 index 3f29c40..0000000 --- a/screensaver/weathermanager.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Authors: ZHAI Kang-ning -**/ -#ifndef WEATHERMANAGER_H -#define WEATHERMANAGER_H - -#include -#include -#include -#include - -#include "../src/networkwatcher.h" - -class QNetworkAccessManager; -class QNetworkReply; -class LocalWeatherInfo; - -class WeatherManager : public QObject -{ - Q_OBJECT -public: - explicit WeatherManager(QObject *parent = nullptr); - -Q_SIGNALS: - void onWeatherUpdate(QString city, QString cond, QString temperature); - -private Q_SLOTS: - void replyFinished(QNetworkReply *); - void onNetworkStateChanged(uint state); - -public: - void getWeather(); - QPixmap getWeatherIcon(); - QPixmap getWeatherIcon(QString cond); - - QString getCityName(); - QString getCond(); - QString getTemperature(); - -private: - bool updateLocation();//更新位置,从用户设置获取城市信息,如有多个,只取第一个,未对接 - void weatherRequest(); - - bool getLogcalWeather(); - QString getLogcalCityId(); - -private: - QString m_city_id; // "101030100" 默认天津 - QString m_city_name; - QString m_cond_txt; //天气条件 晴、阴等 - QString m_temperature;//温度 10、20等 - - QNetworkAccessManager *m_net_manager; - QTimer *m_timer; - QGSettings *m_settings; - - LocalWeatherInfo *m_local_weather_info; - NetWorkWatcher *m_networkWatcher; - - int m_networkTryNum = 0; -}; - -class LocalWeatherInfo : QObject -{ - //"1920-08-27 10:17:42,101310204,澄迈,小雨,95%,25℃,北风,1级," 时间,城市编码,城市名称,天气,湿度,温度,风向,风力 - Q_OBJECT -public: - explicit LocalWeatherInfo(QObject *parent = nullptr); - -private: - QString m_update_time; - QString m_city_id; - QString m_city_name; - QString m_cond_text; - QString m_air_humidity; - QString m_temperature; - QString m_wind_direction; - QString m_wind_force; -public: - bool isTimeValid(); - - void setTime(QString time); - QString getTime(); - - void setCityId(QString cityId); - QString getCityId(); - - void setCityName(QString cityName); - QString getCityName(); - - void setCondText(QString condText); - QString getCondText(); - - void setAirHumidity(QString airHumidity); - QString getAirHumidity(); - - void setTemperature(QString temperature); - QString getTemperature(); - - void setWindDirection(QString windDirection); - QString getWindDirection(); - - void setWindForce(QString windForce); - QString getWindForce(); -}; - -#endif // WEATHERMANAGER_H diff --git a/set4kScale/CMakeLists.txt b/set4kScale/CMakeLists.txt index 09b8eef..9429dfa 100644 --- a/set4kScale/CMakeLists.txt +++ b/set4kScale/CMakeLists.txt @@ -3,13 +3,18 @@ project(set4kScale) pkg_check_modules(X11 REQUIRED x11) pkg_check_modules(XCB REQUIRED xcb) pkg_check_modules(QGS REQUIRED gsettings-qt) +pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) include_directories( ${X11_INCLUDE_DIRS} ${XCB_INCLUDE_DIRS} ${QGS_INCLUDE_DIRS} + ${KDKINFO_INCLUDE_DIRS} ) +link_directories( + ${KDKINFO_LIBRARY_DIRS}) + set(CMAKE_AUTOMOC ON) set(bin_SRCS @@ -18,7 +23,7 @@ set(bin_SRCS ) add_executable(set4kScale ${bin_SRCS}) -target_link_libraries(set4kScale Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_LIBRARIES} ${XCB_LIBRARIES} ${QGS_LIBRARIES}) +target_link_libraries(set4kScale Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_LIBRARIES} ${XCB_LIBRARIES} ${QGS_LIBRARIES} ${KDKINFO_LIBRARIES}) install(TARGETS set4kScale diff --git a/set4kScale/main.cpp b/set4kScale/main.cpp index 5ec6932..80b6c1e 100644 --- a/set4kScale/main.cpp +++ b/set4kScale/main.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include #include #include @@ -11,6 +28,8 @@ #include #include #include +#include + extern "C" { #include #include @@ -24,6 +43,26 @@ extern "C" { #define CURSOR_THEME "cursor-theme" +/* 设置DPI环境变量 */ +void setXresources(double scale) +{ + Display *dpy; + QGSettings *mouse_settings = new QGSettings(MOUSE_SCHEMA); + QString str = QString("Xft.dpi:\t%1\nXcursor.size:\t%2\nXcursor.theme:\t%3\n") + .arg(scale * 96) + .arg(mouse_settings->get(CURSOR_SIZE).toInt() * scale) + .arg(mouse_settings->get(CURSOR_THEME).toString()); + + dpy = XOpenDisplay(NULL); + XChangeProperty(dpy, RootWindow(dpy, 0), XA_RESOURCE_MANAGER, XA_STRING, 8, + PropModeReplace, (unsigned char *) str.toLatin1().data(), str.length()); + XCloseDisplay(dpy); + + qDebug() << "setXresources:" << str; + + delete mouse_settings; +} + /* 过滤低分辨率高缩放比情况 */ void screenScaleJudgement(QGSettings *settings) { @@ -40,40 +79,24 @@ void screenScaleJudgement(QGSettings *settings) if (width < 1920 && height < 1080) { state = true; - } else if (width == 1920 && height == 1080 && scale > 1.5) { + } + else if (width == 1920 && height == 1080 && scale > 1.5) { state = true; - } else if (width > 2560 && height > 1440) { + } + /* + else if (width > 2560 && height > 1440) { mScale = true; } + */ } - if (state && !mScale) { - QGSettings *mGsettings = new QGSettings(MOUSE_SCHEMA); - mGsettings->set(CURSOR_SIZE, 24); +// if (state && !mScale) { + if (state) { settings->set(SCALING_KEY, 1.0); - delete mGsettings; + scale = 1.0; } } -} - -/* 设置DPI环境变量 */ -void setXresources(int dpi) -{ - Display *dpy; - QGSettings *mouse_settings = new QGSettings(MOUSE_SCHEMA); - QString str = QString("Xft.dpi:\t%1\nXcursor.size:\t%2\nXcursor.theme:\t%3\n") - .arg(dpi) - .arg(mouse_settings->get(CURSOR_SIZE).toInt()) - .arg(mouse_settings->get(CURSOR_THEME).toString()); - - dpy = XOpenDisplay(NULL); - XChangeProperty(dpy, RootWindow(dpy, 0), XA_RESOURCE_MANAGER, XA_STRING, 8, - PropModeReplace, (unsigned char *) str.toLatin1().data(), str.length()); - XCloseDisplay(dpy); - - qDebug() << "setXresources:" << str; - - delete mouse_settings; + setXresources(scale); } /* 判断文件是否存在 */ @@ -102,21 +125,16 @@ void writeXresourcesFile(QString XresourcesFile, QGSettings *settings, double sc file.close(); QGSettings *Font = new QGSettings("org.ukui.font-rendering"); - QGSettings *mouse_settings = new QGSettings(MOUSE_SCHEMA); Font->set("dpi", 96.0); settings->set(SCALING_KEY, scaling); - mouse_settings->set(CURSOR_SIZE, scaling * 24.0); qDebug() << " writeXresourcesFile: content = " << content - << " scalings = " << settings->get(SCALING_KEY).toDouble() - << "cursor size = " << mouse_settings->get(CURSOR_SIZE).toInt(); + << " scalings = " << settings->get(SCALING_KEY).toDouble(); delete Font; - delete mouse_settings; } /* 判断是否为首次登陆 */ - bool isTheFirstLogin(QGSettings *settings) { QString homePath = getenv("HOME"); @@ -156,22 +174,23 @@ bool isTheFirstLogin(QGSettings *settings) if (zoom1) { mScaling = 1.0; } else if (!zoom1 && zoom2) { - mScaling = 1.5; + mScaling = 1.5; //考虑新版缩放,设置默认150%暂时停止设置; } else if (!zoom1 && !zoom2 && zoom3) { mScaling = 2.0; } writeXresourcesFile(XresourcesFile, settings, mScaling); + setXresources(mScaling); + return true; } - /* 配置新装系统、新建用户第一次登陆时,4K缩放功能*/ -void setHightResolutionScreenZoom() +void setHightResolutionScreenZoom(bool platForm) { QGSettings *settings; - double dpi; + double scale; int ScreenNum = QApplication::screens().length(); if (!QGSettings::isSchemaInstalled(XSETTINGS_SCHEMA) || !QGSettings::isSchemaInstalled("org.ukui.font-rendering") || !QGSettings::isSchemaInstalled(MOUSE_SCHEMA)) { @@ -181,28 +200,41 @@ void setHightResolutionScreenZoom() } settings = new QGSettings(XSETTINGS_SCHEMA); + scale = settings->get(SCALING_KEY).toDouble(); + + if (platForm) { + setXresources(scale); + goto end; + } + if (isTheFirstLogin(settings)) { qDebug() << "Set the default zoom value when logging in for the first time."; goto end; } /* 过滤单双屏下小分辨率大缩放值 */ + if (ScreenNum > 1) { + setXresources(scale); goto end; } screenScaleJudgement(settings); end: - dpi = 0.0; - dpi = settings->get(SCALING_KEY).toDouble() * 96.0; - setXresources(dpi); delete settings; } int main(int argc, char *argv[]) { QApplication a(argc, argv); - setHightResolutionScreenZoom(); + QString platForm = kdk_system_get_hostCloudPlatform(); + if (platForm == "none") { + qDebug() << "platForm=" << platForm << ", 系统环境为实体机"; + setHightResolutionScreenZoom(false); + } else { + qDebug() << "platForm=" << platForm << ", 系统环境为云环境"; + setHightResolutionScreenZoom(true); + } return 0; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4b7f93..c30a4e9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,9 @@ pkg_check_modules(QGS REQUIRED gsettings-qt) pkg_check_modules(GLIB REQUIRED glib-2.0) pkg_check_modules(MMIX REQUIRED libmatemixer) +pkg_check_modules(kylin-nm-base REQUIRED kylin-nm-base) +pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) +pkg_check_modules(IMLIB2 REQUIRED imlib2) find_library(PAM_LIBRARIES pam) @@ -13,6 +16,7 @@ include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_SOURCE_DIR}/VirtualKeyboard/src) include_directories(${PROJECT_SOURCE_DIR}/BiometricAuth) include_directories(${PROJECT_SOURCE_DIR}/Common) +include_directories(${PROJECT_SOURCE_DIR}/screensaver) include_directories(${PROJECT_SOURCE_DIR}/KylinNM) include_directories(${PROJECT_SOURCE_DIR}/KylinNM/src) include_directories(${PROJECT_SOURCE_DIR}/KylinNM/hot-spot) @@ -25,6 +29,15 @@ include_directories( ${QGS_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS} ${MMIX_INCLUDE_DIRS} + ${kylin-nm-base_INCLUDE_DIRS} + ${KF5Wayland_LIBRARIES} + ${KDKINFO_INCLUDE_DIRS} + ${IMLIB2_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ) + +link_directories( + ${KDKINFO_LIBRARY_DIRS} ) set(EXTRA_LIBS @@ -36,8 +49,15 @@ set(EXTRA_LIBS ${QGS_LIBRARIES} ${GLIB_LIBRARIES} ${MMIX_LIBRARIES} + ${KF5Wayland_LIBRARIES} + ${KDKINFO_LIBRARIES} + ${IMLIB2_LIBRARIES} -lrt -lpthread + -lKF5WaylandServer + -lKF5WaylandClient + -llibnm-icon-kylin + -lukuiinputgatherclient ) qt5_wrap_ui(dialog_SRC @@ -48,6 +68,7 @@ qt5_wrap_ui(dialog_SRC qt5_add_resources(dialog_SRC assets.qrc ../KylinNM/nmqrc.qrc #暂时将麒麟网络的资源文件放到这里,否则显示不出来,暂时不知道原因 + ../screensaver/default.qrc ) # 头文件中包含了Xlib.h,需要单独拿出来处理,不知道原因 @@ -60,7 +81,8 @@ qt5_wrap_cpp(dialog_SRC screensaverwidget.h auth.h auth-pam.h - screensaver.h + screensavermode.h + screensaverwndadaptor.h xeventmonitor.h monitorwatcher.h configuration.h @@ -86,10 +108,21 @@ qt5_wrap_cpp(dialog_SRC networkwatcher.h digitalkeyboard.h surewindow.h + loginedusers.h + lockchecker.h + servicemanager.h + mytabwidget.h + modebutton.h + klabel.h PhysicalDeviceSet/brightnessdeviceset.h PhysicalDeviceSet/flightmodeset.h PhysicalDeviceSet/sounddeviceset.h PhysicalDeviceSet/touchscreenset.h + device.h + enginedevice.h + batterywidget.h + libinputswitchevent.h + machinemodel.h ) set(dialog_SRC @@ -106,7 +139,8 @@ set(dialog_SRC monitorwatcher.cpp grab-x11.cpp configuration.cpp - screensaver.cpp + screensavermode.cpp + screensaverwndadaptor.cpp powermanager.cpp utils.cpp users.cpp @@ -128,12 +162,25 @@ set(dialog_SRC networkwatcher.cpp digitalkeyboard.cpp surewindow.cpp + loginedusers.cpp + lockchecker.cpp + servicemanager.cpp + mytabwidget.cpp + modebutton.cpp + klabel.cpp + rootWindowBackground.cpp PhysicalDeviceSet/brightnessdeviceset.cpp PhysicalDeviceSet/flightmodeset.cpp PhysicalDeviceSet/sounddeviceset.cpp PhysicalDeviceSet/touchscreenset.cpp + device.cpp + enginedevice.cpp + batterywidget.cpp + libinputswitchevent.cpp + machinemodel.cpp ) add_executable(ukui-screensaver-dialog ${dialog_SRC}) +add_definitions(-DAPP_API_MAJOR=0 -DAPP_API_MINOR=11 -DAPP_API_FUNC=0) target_link_libraries(ukui-screensaver-dialog Qt5::Core @@ -143,11 +190,16 @@ target_link_libraries(ukui-screensaver-dialog Qt5::X11Extras Qt5::Network ${EXTRA_LIBS} - BiometricAuth + BiometricAuth VirtualKeyboard Common Kylin-nm ukui-log4qt + Screensaver + opencv_imgcodecs + opencv_imgproc + opencv_core + LayerShellQt::Interface ) link_libraries(libmatemixer.so glib-2.0.so) @@ -170,7 +222,7 @@ set(backend_SRC logind.cpp ) add_executable(ukui-screensaver-backend ${backend_SRC}) -target_link_libraries(ukui-screensaver-backend Qt5::Core Qt5::DBus ${QGS_LIBRARIES} ukui-log4qt) +target_link_libraries(ukui-screensaver-backend Qt5::Core Qt5::DBus ${QGS_LIBRARIES} ukui-log4qt Common) set(command_SRC ukui-screensaver-command.cpp @@ -184,6 +236,14 @@ set(checkpass_SRC add_executable(ukui-screensaver-checkpass ${checkpass_SRC}) target_link_libraries(ukui-screensaver-checkpass ${PAM_LIBRARIES}) +set(ukss_SRCS + ukss_interface.cpp + ) + +add_definitions(-DUKSSSO_LIBRARY) +add_library(ukss SHARED ${ukss_SRCS}) +target_link_libraries(ukss Qt5::Core Qt5::DBus ${QGS_LIBRARIES}) + install(TARGETS ukui-screensaver-dialog ukui-screensaver-backend @@ -191,6 +251,8 @@ install(TARGETS ukui-screensaver-checkpass DESTINATION bin) +install(TARGETS ukss DESTINATION ${QT_INSTALL_LIBS}) + #set(test-act_SRC # users.cpp # test-accounts.cpp diff --git a/src/PhysicalDeviceSet/brightnessdeviceset.cpp b/src/PhysicalDeviceSet/brightnessdeviceset.cpp index 455c5d0..5e25b9f 100644 --- a/src/PhysicalDeviceSet/brightnessdeviceset.cpp +++ b/src/PhysicalDeviceSet/brightnessdeviceset.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "brightnessdeviceset.h" int BrightnessDeviceSet::m_value = -1; diff --git a/src/PhysicalDeviceSet/brightnessdeviceset.h b/src/PhysicalDeviceSet/brightnessdeviceset.h index 77cd162..c361c9d 100644 --- a/src/PhysicalDeviceSet/brightnessdeviceset.h +++ b/src/PhysicalDeviceSet/brightnessdeviceset.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef BRIGHTNESSDEVICESET_H #define BRIGHTNESSDEVICESET_H diff --git a/src/PhysicalDeviceSet/flightmodeset.cpp b/src/PhysicalDeviceSet/flightmodeset.cpp index adcbf67..33e4616 100644 --- a/src/PhysicalDeviceSet/flightmodeset.cpp +++ b/src/PhysicalDeviceSet/flightmodeset.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "flightmodeset.h" bool FlightModeSet::m_isFlightModeOpen = false; diff --git a/src/PhysicalDeviceSet/flightmodeset.h b/src/PhysicalDeviceSet/flightmodeset.h index 57842a4..3efcd0a 100644 --- a/src/PhysicalDeviceSet/flightmodeset.h +++ b/src/PhysicalDeviceSet/flightmodeset.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef FLIGHTMODESET_H #define FLIGHTMODESET_H /*! diff --git a/src/PhysicalDeviceSet/sounddeviceset.cpp b/src/PhysicalDeviceSet/sounddeviceset.cpp index f16ba8c..876708f 100644 --- a/src/PhysicalDeviceSet/sounddeviceset.cpp +++ b/src/PhysicalDeviceSet/sounddeviceset.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "sounddeviceset.h" int SoundDeviceSet::m_value = -1; diff --git a/src/PhysicalDeviceSet/sounddeviceset.h b/src/PhysicalDeviceSet/sounddeviceset.h index 2b98aaa..12701bd 100644 --- a/src/PhysicalDeviceSet/sounddeviceset.h +++ b/src/PhysicalDeviceSet/sounddeviceset.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef SOUNDDEVICESET_H #define SOUNDDEVICESET_H diff --git a/src/PhysicalDeviceSet/touchscreenset.cpp b/src/PhysicalDeviceSet/touchscreenset.cpp index 0ba4449..9884078 100644 --- a/src/PhysicalDeviceSet/touchscreenset.cpp +++ b/src/PhysicalDeviceSet/touchscreenset.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "touchscreenset.h" #include diff --git a/src/PhysicalDeviceSet/touchscreenset.h b/src/PhysicalDeviceSet/touchscreenset.h index fd6c5ef..096ce9e 100644 --- a/src/PhysicalDeviceSet/touchscreenset.h +++ b/src/PhysicalDeviceSet/touchscreenset.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef TOUCHSCREENSET_H #define TOUCHSCREENSET_H diff --git a/src/accountsinterface.cpp b/src/accountsinterface.cpp index 4b6abb5..7bc8cbb 100644 --- a/src/accountsinterface.cpp +++ b/src/accountsinterface.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "accountsinterface.h" const QString STR_EDU_SERVICE = "cn.kylinos.SSOBackend"; diff --git a/src/accountsinterface.h b/src/accountsinterface.h index cc97edd..2e1a0d5 100644 --- a/src/accountsinterface.h +++ b/src/accountsinterface.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef ACCOUNTSINTERFACE_H #define ACCOUNTSINTERFACE_H diff --git a/src/assets.qrc b/src/assets.qrc index 6059541..cb0a657 100644 --- a/src/assets.qrc +++ b/src/assets.qrc @@ -5,9 +5,7 @@ assets/show-password.png assets/hide-password.png - assets/keyboard.png assets/switchGreeter.png - assets/switchUser.png assets/waiting.png assets/capslock.png assets/combobox_down.png @@ -25,13 +23,8 @@ assets/unlock-button-pressed.png assets/iconFace.png assets/iconFace.svg - assets/powerManager.png assets/lock.png assets/logout.png - assets/shutdown.png - assets/suspend.png - assets/hibernate.png - assets/reboot.png assets/bio-login.png assets/password-login.png assets/weather/68.png @@ -119,11 +112,20 @@ assets/ukui-loginopt-finger.svg assets/ukui-loginopt-face.svg assets/ukui-loginopt-password.svg + assets/ukui-loginopt-ukey.svg assets/selected.svg assets/keyboard.svg assets/ukui-loginopt-smile.svg assets/ukui-loginopt-lose.svg assets/01-default-commercial.png assets/01-default-community.png + assets/suspend.svg + assets/shutdown.svg + assets/reboot.svg + assets/hibernate.svg + assets/switchuser.svg + + + assets/data/conf.ini diff --git a/src/assets/authdialog.qss b/src/assets/authdialog.qss index cdf0026..a45e1c3 100644 --- a/src/assets/authdialog.qss +++ b/src/assets/authdialog.qss @@ -11,6 +11,9 @@ QPushButton::hover{ QPushButton::pressed { background-color: rgba(255,255,255,40%); } +QPushButton::checked { + background-color: rgba(255, 255, 255, 40%); +} QToolButton{ text-align:center; @@ -31,14 +34,12 @@ QToolButton::checked { QLabel { color: white; - font-size: 16px; } QToolTip{ border-radius:4px; background-color:#FFFFFF; color:black; - font-size:16px } #userWidget{ @@ -54,24 +55,22 @@ QToolTip{ /* 用户名 */ #login_nameLabel{ - font-size: 24px; } /* 密码输入框 */ QLineEdit { background: #FFFFFF; - border: 1px solid #FFFFFF; + border: 2px solid #FFFFFF; border-radius: 6px; color:black; - font-size: 14px; lineedit-password-character:9679; } QLineEdit::hover { - border: 1px solid #FFFFFF; + border: 2px solid #FFFFFF; } QLineEdit::focus{ - + border: 2px solid #2C73C8; } /* 大写提示 */ @@ -95,26 +94,25 @@ QLineEdit::focus{ } #echoModeButton::checked { } + /* 登录按钮 */ #loginButton{ - min-width: 24px; - max-width: 24px; - min-height: 24px; - max-height: 24px; - icon-size: 24px; background:#3D6BE5; border-radius:12px; } +#loginButton::hover, +#loginButton::pressed{ + background:#9B3D6BE5; +} + /* PAM message提示*/ #messageLabel { - font-size: 16px; color: white; } #messageButton{ text-align:center; - font-size: 16px; color: white; } @@ -124,8 +122,7 @@ QMenu{ background-color: rgb(255,255,255,15%); color: white; border-radius: 4px; - width:260px; - font-size: 16px; + width:250px; padding: 5px 5px 5px 5px; } @@ -137,7 +134,6 @@ QMenu::item width:225px; border-radius: 4px; height:36px; - font-size:16px; padding: 2px 10px 2px 10px; } diff --git a/src/assets/data/conf.ini b/src/assets/data/conf.ini new file mode 100644 index 0000000..41ae2bd --- /dev/null +++ b/src/assets/data/conf.ini @@ -0,0 +1,15 @@ +[MachineType] +PANDING LTDtablet = SLATE +#Phytium12345 = SLATE + + +#key 值机器的sys_vendor + product_family +#cat /sys/class/dmi/id/product_family +#cat /sys/class/dmi/id/product_name +#cat /sys/class/dmi/id/sys_vendor + +#value 有以下四类 +#[SLATE]平板 +#[LAPTOP]计算机(有永久附加键盘) +#[CONVERTIBLE]平板/计算机(键盘可以分离、翻转或旋转) +#[ALLINONE]台式机 diff --git a/src/assets/hibernate.png b/src/assets/hibernate.png deleted file mode 100644 index a6338b1..0000000 Binary files a/src/assets/hibernate.png and /dev/null differ diff --git a/src/assets/hibernate.svg b/src/assets/hibernate.svg new file mode 100644 index 0000000..6cfad35 --- /dev/null +++ b/src/assets/hibernate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/keyboard.png b/src/assets/keyboard.png deleted file mode 100644 index 4d93f1e..0000000 Binary files a/src/assets/keyboard.png and /dev/null differ diff --git a/src/assets/powerManager.png b/src/assets/powerManager.png deleted file mode 100644 index 73089ad..0000000 Binary files a/src/assets/powerManager.png and /dev/null differ diff --git a/src/assets/reboot.png b/src/assets/reboot.png deleted file mode 100644 index 5365f79..0000000 Binary files a/src/assets/reboot.png and /dev/null differ diff --git a/src/assets/reboot.svg b/src/assets/reboot.svg new file mode 100644 index 0000000..4f55d46 --- /dev/null +++ b/src/assets/reboot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/shutdown.png b/src/assets/shutdown.png deleted file mode 100644 index a7c9c62..0000000 Binary files a/src/assets/shutdown.png and /dev/null differ diff --git a/src/assets/shutdown.svg b/src/assets/shutdown.svg new file mode 100644 index 0000000..d46725a --- /dev/null +++ b/src/assets/shutdown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/suspend.png b/src/assets/suspend.png deleted file mode 100644 index 63f2a32..0000000 Binary files a/src/assets/suspend.png and /dev/null differ diff --git a/src/assets/suspend.svg b/src/assets/suspend.svg new file mode 100644 index 0000000..a83bdfa --- /dev/null +++ b/src/assets/suspend.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/switchUser.png b/src/assets/switchUser.png deleted file mode 100644 index 65b98ea..0000000 Binary files a/src/assets/switchUser.png and /dev/null differ diff --git a/src/assets/switchuser.svg b/src/assets/switchuser.svg new file mode 100644 index 0000000..2d6bfae --- /dev/null +++ b/src/assets/switchuser.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-ukey.svg b/src/assets/ukui-loginopt-ukey.svg new file mode 100644 index 0000000..0239a86 --- /dev/null +++ b/src/assets/ukui-loginopt-ukey.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/authdialog.cpp b/src/authdialog.cpp index 4852dcc..e68e6ed 100644 --- a/src/authdialog.cpp +++ b/src/authdialog.cpp @@ -30,19 +30,22 @@ #include "users.h" #include "iconedit.h" +#include "configuration.h" #include "biometricproxy.h" -#include "biometricauthwidget.h" -#include "biometricdeviceswidget.h" #include "pam-tally.h" #include "commonfunc.h" #include "loginoptionswidget.h" +#include "servicemanager.h" +#include "uniauthservice.h" +#include "imageutil.h" +#include "klabel.h" AuthDialog::AuthDialog(const UserItem &user, QWidget *parent) : QWidget(parent), user(user), auth(new AuthPAM(this)), + configuration(Configuration::instance()), authMode(UNKNOWN), - m_deviceCount(-1), m_biometricProxy(nullptr), m_widgetLoginOpts(nullptr), m_buttonsWidget(nullptr), @@ -52,17 +55,32 @@ AuthDialog::AuthDialog(const UserItem &user, QWidget *parent) : m_timer(nullptr), isLockingFlg(false), m_nCurLockMin(0), - useFirstDevice(false) + w_timer(nullptr), + m_uniauthService(new UniAuthService(this)) { + setObjectName("AuthDialog"); + + QFile qssFile(":/qss/assets/authdialog.qss"); + if(qssFile.open(QIODevice::ReadOnly)) { + this->setStyleSheet(qssFile.readAll()); + } + curFontSize = configuration->getFontSize(); + m_ptToPx = configuration->getPtToPx(); initUI(); pam_tally_init(); //这里写函数声明 connect(auth, &Auth::showMessage, this, &AuthDialog::onShowMessage); connect(auth, &Auth::showPrompt, this, &AuthDialog::onShowPrompt); connect(auth, &Auth::authenticateComplete, this, &AuthDialog::onAuthComplete); + ServiceManager *sm = ServiceManager::instance(); + connect(sm, &ServiceManager::serviceStatusChanged, + this, &AuthDialog::onBiometricDbusChanged); - useFirstDevice = getUseFirstDevice(); m_failedTimes.clear(); + + connect(m_messageButton, &QPushButton::clicked, + this, &AuthDialog::onMessageButtonClicked); + } void AuthDialog::startAuth() @@ -88,29 +106,11 @@ void AuthDialog::stopAuth() clearMessage(); // auth->stopAuth(); - m_passwordEdit->readOnly(true); + // m_passwordEdit->readOnly(true); // if(m_passwdWidget) // m_passwdWidget->hide(); } -QPixmap AuthDialog::PixmapToRound(const QPixmap &src, int radius) -{ - if (src.isNull()) { - return QPixmap(); - } - - QPixmap pixmapa(src); - QPixmap pixmap(radius*2,radius*2); - pixmap.fill(Qt::transparent); - QPainter painter(&pixmap); - painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - QPainterPath path; - path.addEllipse(0, 0, radius*2, radius*2); - painter.setClipPath(path); - painter.drawPixmap(0, 0, radius*2, radius*2, pixmapa); - return pixmap; -} - void AuthDialog::initUI() { if (scale < 0.5) { @@ -123,7 +123,7 @@ void AuthDialog::initUI() m_userWidget->setObjectName(QStringLiteral("userWidget")); /* 头像 */ - const QString SheetStyle = QString("border-radius: %1px; border:0px solid white;").arg(77*scale); + const QString SheetStyle = QString("border-radius: %1px; border:0px solid white;").arg((int)(77*scale)); m_labelHeadImg = new QLabel(m_userWidget); m_labelHeadImg->setObjectName(QStringLiteral("faceLabel")); m_labelHeadImg->setFocusPolicy(Qt::NoFocus); @@ -131,9 +131,7 @@ void AuthDialog::initUI() m_labelHeadImg->setAlignment(Qt::AlignCenter); m_labelHeadImg->hide(); - QPixmap facePixmap(user.icon); - facePixmap = facePixmap.scaled(154*scale,154*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - facePixmap = PixmapToRound(facePixmap, 77*scale); + QPixmap facePixmap = makeRoundLogo(user.icon, 154*scale, 154*scale, 77*scale); m_labelHeadImg->setAlignment(Qt::AlignCenter); m_labelHeadImg->setPixmap(facePixmap); @@ -144,13 +142,10 @@ void AuthDialog::initUI() m_labelFace->hide(); // 二维码窗口 - m_labelLoginTypeTip = new QLabel(m_userWidget); - //m_labelLoginTypeTip->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + m_labelLoginTypeTip = new KLabel(m_userWidget); + m_labelLoginTypeTip->setFontSize(14); m_labelLoginTypeTip->setObjectName("loginTypeTipLabel"); m_labelLoginTypeTip->setAlignment(Qt::AlignCenter); - QFont font = m_labelLoginTypeTip->font(); - font.setPixelSize(14); - m_labelLoginTypeTip->setFont(font); m_labelQRCode = new QLabel(m_userWidget); m_labelQRCode->setObjectName("qrCodeLabel"); m_labelQRCode->setAlignment(Qt::AlignCenter); @@ -161,33 +156,22 @@ void AuthDialog::initUI() m_labelQRCode->setLayout(layoutQRCode); m_labelQRCodeTip = new QLabel(); m_labelQRCodeTip->setFixedSize(22,22); - m_labelQRCodeTip->setPixmap(QIcon::fromTheme("ukui-dialog-warning").pixmap(QSize(22,22))); layoutQRCode->addWidget(m_labelQRCodeTip, 0, Qt::AlignHCenter); - m_labelQRCodeMsg = new QLabel(); - m_labelQRCodeMsg->setFixedHeight(24); - font = m_labelQRCodeMsg->font(); - font.setPixelSize(16); + m_labelQRCodeMsg = new KLabel(); + m_labelQRCodeMsg->setFixedHeight(30); + m_labelQRCodeMsg->setFontSize(14); m_labelQRCodeMsg->setStyleSheet("QLabel{background-color:rgba(255,255,255,0);color:rgb(255,0,0)}"); - m_labelQRCodeMsg->setFont(font); layoutQRCode->addWidget(m_labelQRCodeMsg, 0, Qt::AlignHCenter); /* 用户名 */ - m_nameLabel = new QLabel(m_userWidget); + m_nameLabel = new KLabel(m_userWidget); m_nameLabel->setObjectName(QStringLiteral("login_nameLabel")); m_nameLabel->setFocusPolicy(Qt::NoFocus); m_nameLabel->setAlignment(Qt::AlignCenter); - m_nameLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + m_nameLabel->setFontSize(24); //m_nameLabel->setText(user.realName.isEmpty() ? user.name : user.realName); QString text = user.realName.isEmpty() ? user.name : user.realName; - font = m_nameLabel->font(); - font.setPixelSize(24); - QString str = ElideText(font,500,text); - if(text != str) - m_nameLabel->setToolTip(text); - if(text == str) - m_nameLabel->setToolTip(""); - m_nameLabel->setText(str); - + m_nameLabel->setElideText(text, 380); /* 密码框所在窗口 */ m_passwdWidget = new QWidget(this); @@ -200,31 +184,122 @@ void AuthDialog::initUI() m_passwdWidget->setInputMethodHints(Qt::ImhNone); m_passwordEdit->setObjectName(QStringLiteral("passwordEdit")); - m_passwordEdit->setIcon(QIcon(":/image/assets/login-button.svg")); - m_passwordEdit->setFocusPolicy(Qt::StrongFocus); + QPixmap iconLogin = QIcon::fromTheme("system-lock-screen-symbolic").pixmap(16,16); + iconLogin = ImageUtil::drawSymbolicColoredPixmap(iconLogin, "white"); + m_passwordEdit->setIcon(iconLogin); + //m_passwordEdit->setFocusPolicy(Qt::StrongFocus); m_passwordEdit->installEventFilter(this); m_passwordEdit->readOnly(true); + /*免密登录时,会出现闪一下密码框的问题,因此初始化时隐藏,收到pam发来的prompt类型的消息后再显示*/ + m_passwordEdit->hide(); m_passwordEdit->setType(QLineEdit::Password); - setFocusProxy(m_passwordEdit); + //setFocusProxy(m_passwordEdit); connect(m_passwordEdit, SIGNAL(clicked(const QString&)), this, SLOT(onRespond(const QString&))); //m_passwdWidget->hide(); /* 密码认证信息显示列表 */ - m_messageLabel = new QLabel(m_passwdWidget); + m_messageLabel = new KLabel(m_passwdWidget); m_messageLabel->setObjectName(QStringLiteral("messageLabel")); m_messageLabel->setAlignment(Qt::AlignLeft); - font = m_messageLabel->font(); - font.setPixelSize(14); - m_messageLabel->setFont(font); - m_messageLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + m_messageLabel->setFontSize(14); + + /* ukey密码框所在窗口 */ + m_ukeyPasswdWidget = new QWidget(this); + m_ukeyPasswdWidget->setObjectName(QStringLiteral("passwordWidget")); + + /* 密码框 */ + m_ukeyPasswordEdit = new IconEdit(m_ukeyPasswdWidget); + connect(m_ukeyPasswordEdit,&IconEdit::clickedPassword, + this,&AuthDialog::onM_passwordEditClicked); + + m_ukeyPasswdWidget->setInputMethodHints(Qt::ImhNone); + m_ukeyPasswordEdit->setObjectName(QStringLiteral("passwordEdit")); + m_ukeyPasswordEdit->setIcon(QIcon::fromTheme("system-lock-screen-symbolic")); + //m_ukeyPasswordEdit->setFocusPolicy(Qt::StrongFocus); + m_ukeyPasswordEdit->installEventFilter(this); + m_ukeyPasswordEdit->setType(QLineEdit::Password); + m_ukeyPasswordEdit->setPrompt(tr("Enter the ukey password")); + m_ukeyPasswordEdit->setModeBtnVisible(false); + connect(m_ukeyPasswordEdit, SIGNAL(clicked(const QString&)), + this, SLOT(onRespondUkey(const QString&))); + + /* 密码认证信息显示列表 */ + m_ukeyMessageLabel = new KLabel(m_ukeyPasswdWidget); + m_ukeyMessageLabel->setObjectName(QStringLiteral("messageLabel")); + m_ukeyMessageLabel->setAlignment(Qt::AlignLeft); + m_ukeyMessageLabel->setFontSize(14); + m_ukeyMessageLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + + m_ukeyPasswdWidget->hide(); + + m_loadingWidget = new QWidget(m_ukeyPasswdWidget); + m_loadingText = new KLabel(m_loadingWidget); + m_loadingText->setFontSize(18); + m_loadingText->setText(tr("Insert the ukey into the USB port")); + m_loadingButton = new QPushButton(m_loadingWidget); + m_loadingButton->setAttribute(Qt::WA_TransparentForMouseEvents, true); + m_loadingButton->setFlat(true); + m_loadingButton->installEventFilter(this); + m_loadingButton->setStyleSheet("QPushButton{text-align:center;color: rgb(255, 255, 255, 255);border: none;border-radius: 4px;outline: none;}"); + + m_loadingWidget->adjustSize(); + + QVBoxLayout *loadingLayout= new QVBoxLayout(m_loadingWidget); + loadingLayout->addWidget(m_loadingButton); + loadingLayout->addWidget(m_loadingText); + startLoadingUkey(); m_messageButton = new QPushButton(m_passwdWidget); m_messageButton->setObjectName(QStringLiteral("messageButton")); + QFont font; + font = m_messageButton->font(); + font.setPointSize((14 + curFontSize) *m_ptToPx); + m_messageButton->setFont(font); m_messageButton->hide(); } + +void AuthDialog::startLoadingUkey() +{ + //isLoadingUkey = true; + m_loadingWidget->show(); + m_ukeyPasswordEdit->hide(); + m_ukeyMessageLabel->hide(); + if(!m_loadingTimer) + { + m_loadingTimer = new QTimer(this); + m_loadingTimer->setInterval(150); + connect(m_loadingTimer, &QTimer::timeout, this, &AuthDialog::updateLoadingPixmap); + } + + QPixmap icon = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(27,27); + m_loadingPixmap = ImageUtil::drawSymbolicColoredPixmap(icon, "white"); + m_loadingButton->setIcon(m_loadingPixmap); + m_loadingButton->setIconSize(QSize(27, 27)); + m_loadingTimer->start(); +} + +void AuthDialog::stopLoadingUkey() +{ + isLoadingUkey = false; + m_loadingWidget->hide(); + m_ukeyPasswordEdit->show(); + m_ukeyMessageLabel->show(); + if(m_loadingTimer){ + m_loadingTimer->stop(); + } +} + +void AuthDialog::updateLoadingPixmap() +{ + QMatrix matrix; + matrix.rotate(90.0); + m_loadingPixmap = m_loadingPixmap.transformed(matrix, Qt::FastTransformation); + m_loadingButton->setIcon(QIcon(m_loadingPixmap)); +} + void AuthDialog::unlock_countdown() { int failed_count = 0; @@ -280,7 +355,9 @@ void AuthDialog::unlock_countdown() { if(m_passwordEdit){ m_passwordEdit->readOnly(false); - m_passwordEdit->setFocus(); + if (m_passwordEdit->isVisible()) { + m_passwordEdit->setFocus(); + } } if (isLockingFlg) { @@ -345,7 +422,9 @@ void AuthDialog::root_unlock_countdown() { if(m_passwordEdit){ m_passwordEdit->readOnly(false); - m_passwordEdit->setFocus(); + if (m_passwordEdit->isVisible()) { + m_passwordEdit->setFocus(); + } } if (isLockingFlg) { @@ -370,46 +449,62 @@ void AuthDialog::setChildrenGeometry() // 用户信息显示位置 m_userWidget->setGeometry(0, 0, width(), 376*scale); - m_labelLoginTypeTip->setGeometry(0,0,m_userWidget->width(), 24); + m_labelLoginTypeTip->setGeometry(0,0,m_userWidget->width(), 30); m_labelLoginTypeTip->setAlignment(Qt::AlignCenter); - m_labelHeadImg->setStyleSheet(QString("border-radius: %1px; border:0px solid white;").arg(77*scale)); + m_labelHeadImg->setStyleSheet(QString("border-radius: %1px; border:0px solid white;").arg((int)(77*scale))); m_labelHeadImg->setGeometry((width() - 154*scale) / 2 , m_labelLoginTypeTip->geometry().bottom()+24*scale, 154*scale, 154*scale); - QPixmap facePixmap(user.icon); - facePixmap = facePixmap.scaled(154*scale,154*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - facePixmap = PixmapToRound(facePixmap, 77*scale); + + QPixmap facePixmap = makeRoundLogo(user.icon, 154*scale, 154*scale, 77*scale); m_labelHeadImg->setPixmap(facePixmap); - m_labelQRCode->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,100%);").arg(6*scale)); + m_labelQRCode->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,100%);").arg((int)(6*scale))); m_labelQRCode->setGeometry((width() - 154*scale) / 2 , m_labelLoginTypeTip->geometry().bottom()+24*scale, 154*scale, 154*scale); setQRCode(m_imgQRCode); - m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,10%);").arg(77*scale)); + m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,10%);").arg((int)(77*scale))); m_labelFace->setGeometry((width() - 154*scale) / 2 , m_labelLoginTypeTip->geometry().bottom()+24*scale, 154*scale, 154*scale); QImage faceImg; setFaceImg(faceImg); m_nameLabel->setGeometry(0, m_labelHeadImg->geometry().bottom() + 16*scale, - width(), 34); + width(), 40); m_passwdWidget->setGeometry(0, m_nameLabel->geometry().bottom() + 24*scale, width(), 100); m_passwordEdit->setGeometry((m_passwdWidget->width() - 240)/2, 0, 240, 40); m_messageLabel->setGeometry((m_passwdWidget->width() - 240)/2, m_passwordEdit->geometry().bottom() + 4, - width()-(m_passwdWidget->width() - 240)/2, 20); + width()-(m_passwdWidget->width() - 240)/2, 36); + m_messageLabel->setMinimumHeight(36); + + m_ukeyPasswdWidget->setGeometry(0, m_nameLabel->geometry().bottom() + 24*scale, width(), 100); + m_ukeyPasswordEdit->setGeometry((m_ukeyPasswdWidget->width() - 240)/2, 0, 240, 40); + m_ukeyMessageLabel->setGeometry((m_ukeyPasswdWidget->width() - 240)/2, + m_ukeyPasswordEdit->geometry().bottom() + 4, + width()-(m_ukeyPasswdWidget->width() - 240)/2, 36); + m_loadingWidget->adjustSize(); + m_loadingWidget->setGeometry((m_ukeyPasswdWidget->width() - m_loadingWidget->width())/2, 0, m_loadingWidget->width(), m_loadingWidget->height()); + m_messageLabel->setMinimumHeight(36); m_messageButton->setGeometry((m_passwdWidget->width() - 200)/2, 0, 200, 40); +// m_messageButton->setStyleSheet("QPushButton:!checked:!pressed:!hover{background-color: rgba(255,255,255,40)}" +// "QPushButton:!checked:!pressed:hover{background-color: rgba(255,255,255,100)}" +// "QPushButton:pressed{background-color: rgba(255,255,255,40)}"); + setBiometricWidgetGeometry(); } void AuthDialog::switchLoginOptType(unsigned uLoginOptType) { + qDebug()<<"switchLoginOptType"<show(); m_labelQRCode->hide(); m_labelFace->hide(); + m_passwdWidget->show(); + m_ukeyPasswdWidget->hide(); } break; case LOGINOPT_TYPE_FACE: @@ -417,6 +512,8 @@ void AuthDialog::switchLoginOptType(unsigned uLoginOptType) m_labelHeadImg->hide(); m_labelQRCode->hide(); m_labelFace->show(); + m_passwdWidget->show(); + m_ukeyPasswdWidget->hide(); } break; case LOGINOPT_TYPE_FINGERPRINT: @@ -427,6 +524,8 @@ void AuthDialog::switchLoginOptType(unsigned uLoginOptType) m_labelHeadImg->show(); m_labelQRCode->hide(); m_labelFace->hide(); + m_passwdWidget->show(); + m_ukeyPasswdWidget->hide(); } break; case LOGINOPT_TYPE_QRCODE: @@ -435,6 +534,20 @@ void AuthDialog::switchLoginOptType(unsigned uLoginOptType) setQRCodeMsg(""); m_labelQRCode->show(); m_labelFace->hide(); + m_passwdWidget->show(); + m_ukeyPasswdWidget->hide(); + } + break; + case LOGINOPT_TYPE_GENERAL_UKEY: + { + m_labelHeadImg->show(); + m_labelQRCode->hide(); + m_labelFace->hide(); + m_passwdWidget->hide(); + m_ukeyPasswdWidget->show(); +// setFocusProxy(m_ukeyPasswordEdit); +// m_ukeyPasswordEdit->setFocusPolicy(Qt::StrongFocus); +// m_ukeyPasswordEdit->setFocus(); } break; default: @@ -478,6 +591,11 @@ void AuthDialog::switchLoginOptType(unsigned uLoginOptType) setLoginTypeTip(tr("Use the bound wechat scanning code or enter the password to unlock")); } break; + case LOGINOPT_TYPE_GENERAL_UKEY: + { + setLoginTypeTip(""); + } + break; default: return; } @@ -553,7 +671,13 @@ void AuthDialog::pamBioSuccess() switchLoginOptType(LOGINOPT_TYPE_PASSWORD); return ; } - m_widgetLoginOpts->startAuth(m_deviceInfo, user.uid); + + if(m_deviceInfo && m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + //ukey时不调用ukey认证 + }else{ + m_widgetLoginOpts->startAuth(m_deviceInfo, user.uid); + } + if (m_deviceInfo) { switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); } else { @@ -565,6 +689,13 @@ void AuthDialog::startBioAuth(unsigned uTimeout) { if (m_widgetLoginOpts) m_widgetLoginOpts->stopAuth(); + + if(m_deviceInfo && m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + //ukey时不调用ukey认证 + switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); + return; + } + if(!m_bioTimer){ m_bioTimer = new QTimer(this); connect(m_bioTimer, SIGNAL(timeout()), this, SLOT(pamBioSuccess())); @@ -580,9 +711,133 @@ void AuthDialog::setX11Focus() } } +void AuthDialog::setFocusin(int target) +{ + if(m_passwordEdit && m_passwordEdit->isVisible()) { + if (m_ukeyPasswordEdit) { + m_ukeyPasswordEdit->setFocusin(2); + } + switch (target) { + case REMOVE: //焦点清除 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_passwordEdit->setFocusin(2); + if(is_showMessageBtn) { + m_messageButton->clearFocus(); + m_messageButton->setStyleSheet("QPushButton:!checked:!pressed:!hover{background-color: rgba(255,255,255,40)}" + "QPushButton:!checked:!pressed:hover{background-color: rgba(255,255,255,100)}" + "QPushButton:pressed{background-color: rgba(255,255,255,40)}"); + } + m_nameLabel->setFocus(); + break; + case IN_LIGIN: //焦点在登录按钮 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_passwordEdit->setFocusin(1); + break; + case BIO_RIGHT: //登录选项焦点右移 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(0); + m_passwordEdit->setFocusin(2); + m_nameLabel->setFocus(); + break; + case BIO_LEFT: //登录选项焦点左移 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(1); + m_passwordEdit->setFocusin(target); + m_nameLabel->setFocus(); + break; + case IN_LINEEDIT: //焦点在密码输入框 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_passwordEdit->setFocusin(0); + break; + case ON_MESSAGEBTN: //免密登录按钮 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_passwordEdit->setFocusin(2); + m_messageButton->setFocus(); + m_messageButton->setStyleSheet("QPushButton{background-color: rgba(255,255,255,15%); border-radius: 4px; border: 2px solid #2C73C8;}"); + break; + default: + if(m_passwordEdit) + m_passwordEdit->setFocusin(target); + m_widgetLoginOpts->tabOptionSelected(2); + break; + } + } else { + if (m_passwordEdit) { + m_passwordEdit->setFocusin(2); + } + switch (target) { + case REMOVE: //焦点清除 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_ukeyPasswordEdit->setFocusin(2); + if(is_showMessageBtn) { + m_messageButton->clearFocus(); + m_messageButton->setStyleSheet("QPushButton:!checked:!pressed:!hover{background-color: rgba(255,255,255,40)}" + "QPushButton:!checked:!pressed:hover{background-color: rgba(255,255,255,100)}" + "QPushButton:pressed{background-color: rgba(255,255,255,40)}"); + } + m_nameLabel->setFocus(); + break; + case IN_LIGIN: //焦点在登录按钮 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_ukeyPasswordEdit->setFocusin(1); + break; + case BIO_RIGHT: //登录选项焦点右移 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(0); + m_ukeyPasswordEdit->setFocusin(2); + m_nameLabel->setFocus(); + break; + case BIO_LEFT: //登录选项焦点左移 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(1); + m_ukeyPasswordEdit->setFocusin(target); + m_nameLabel->setFocus(); + break; + case IN_LINEEDIT: //焦点在密码输入框 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_ukeyPasswordEdit->setFocusin(0); + break; + case ON_MESSAGEBTN: //免密登录按钮 + if(m_widgetLoginOpts) + m_widgetLoginOpts->tabOptionSelected(2); + m_ukeyPasswordEdit->setFocusin(2); + m_messageButton->setFocus(); + m_messageButton->setStyleSheet("QPushButton{background-color: rgba(255,255,255,15%); border-radius: 4px; border: 2px solid #2C73C8;}"); + break; + default: + if(m_ukeyPasswordEdit) + m_ukeyPasswordEdit->setFocusin(target); + m_widgetLoginOpts->tabOptionSelected(2); + break; + } + } +} + +void AuthDialog::setClick() +{ + m_widgetLoginOpts->tabOptionSelected(3); +} + +void AuthDialog::checkPassword() +{ + if (m_passwordEdit && m_passwordEdit->isVisible()) { + m_passwordEdit->clicked_cb(); + } else if (m_ukeyPasswordEdit && m_ukeyPasswordEdit->isVisible()) { + m_ukeyPasswordEdit->clicked_cb(); + } + setFocusin(REMOVE); +} + void AuthDialog::onShowPrompt(const QString &prompt, Auth::PromptType type) { - qDebug() << "-------prompt: " << prompt; + qDebug() << "-------prompt: " << prompt<show(); } - m_passwordEdit->setFocus(); + if (m_passwordEdit->isVisible()) + m_passwordEdit->setFocus(); prompted = true; unacknowledged_messages = false; @@ -612,7 +868,7 @@ void AuthDialog::onShowPrompt(const QString &prompt, Auth::PromptType type) } if(text == "Password: " || text == "密码:"){ - text = tr("Password "); + text = tr("Password: "); } else if (text == "Input password" || text == "Input Password" || text == "输入密码") { text = tr("Input Password"); } @@ -620,6 +876,8 @@ void AuthDialog::onShowPrompt(const QString &prompt, Auth::PromptType type) m_passwordEdit->clear(); m_passwordEdit->setPrompt(text); m_passwordEdit->show(); + if (m_passwordEdit->isVisible()) + m_passwordEdit->setFocus(); if(!m_timer){ m_timer = new QTimer(this); m_timer->setInterval(200); @@ -667,17 +925,31 @@ void AuthDialog::show_authenticated(bool successful) { m_passwdWidget->show(); m_passwordEdit->hide(); + m_passwordEdit->setFocusPolicy(Qt::NoFocus); +// m_messageButton->setFocusPolicy(Qt::StrongFocus); +// setFocusProxy(m_messageButton); m_messageButton->show(); + is_showMessageBtn = true; + Q_EMIT showMessageBtn(is_showMessageBtn); m_messageButton->setFocus(); m_messageButton->setDefault(true); - connect(m_messageButton, &QPushButton::clicked, - this, &AuthDialog::onMessageButtonClicked); if(successful) { isretry = false; m_messageButton->setText(tr("Login")); + QString strMsgTip = m_messageLabel->text(); switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + if (!strMsgTip.isEmpty()) { + m_messageLabel->setText(strMsgTip); + m_messageLabel->move(m_messageButton->x(), m_messageLabel->y()); + } +// QTimer::singleShot(100, this, [=](){ +// qDebug()<<"Delay to focus msgBtn!!"; +// m_messageButton->show(); +// m_messageButton->setFocus(); +// m_messageButton->setDefault(true); +// }); } else { @@ -697,6 +969,7 @@ void AuthDialog::onMessageButtonClicked() else { m_messageButton->hide(); + is_showMessageBtn = false; authMode = PASSWORD; m_messageLabel->setText(""); @@ -704,8 +977,25 @@ void AuthDialog::onMessageButtonClicked() } } +void AuthDialog::onRespondUkey(const QString &text) +{ + if (m_widgetLoginOpts){ + m_widgetLoginOpts->SetExtraInfo(text,"pincode"); + m_widgetLoginOpts->startAuth(m_deviceInfo, user.uid); + } +} + +bool AuthDialog::getLineeditStatus() +{ + return is_showMessageBtn; +} + void AuthDialog::onRespond(const QString &text) { + if (!prompted && text != BIOMETRIC_SUCCESS) { + qInfo()<<"Wait for input passwd!"; + return; + } unacknowledged_messages=false; clearMessage(); startWaiting(); @@ -749,11 +1039,17 @@ void AuthDialog::clearMessage() void AuthDialog::performBiometricAuth() { + qDebug()<<"performBiometricAuth"; if(!m_biometricProxy) { m_biometricProxy = new BiometricProxy(this); - isHiddenSwitchButton = GetHiddenSwitchButton(); - maxFailedTimes = GetFailedTimes(); + if (m_uniauthService && m_uniauthService->isActivatable()) { + isHiddenSwitchButton = m_uniauthService->getHiddenSwitchButton(); + maxFailedTimes = m_uniauthService->getMaxFailedTimes(); + } else { + isHiddenSwitchButton = GetHiddenSwitchButton(); + maxFailedTimes = GetFailedTimes(); + } } //服务没启动,或者打开DBus连接出错 @@ -773,24 +1069,23 @@ void AuthDialog::performBiometricAuth() //初始化生物识别认证UI initBiometricWidget(); - //初始化enableBiometriAuth - if(m_deviceCount <= 0) - { - m_deviceCount = m_widgetLoginOpts->getLoginOptCount(); - } - //没有可用设备,不启用生物识别认证 - if(m_deviceCount < 1) + if(m_widgetLoginOpts->getLoginOptCount() < 1) { qWarning() << "No available devices"; skipBiometricAuth(); + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } return; } //获取默认设备 - if(m_deviceName.isEmpty()) - { - m_deviceName = GetDefaultDevice(user.name); + if (m_widgetLoginOpts) { + m_deviceName = m_widgetLoginOpts->getDefaultDevice(user.name); } qDebug() << m_deviceName; if (m_deviceInfo) { @@ -800,15 +1095,11 @@ void AuthDialog::performBiometricAuth() } } - //如果默认设备为空的话,第一次不启动生物识别认证 + //如果默认设备为空的话,不进行生物认证 if(m_deviceName.isEmpty() && !m_deviceInfo) { - if(useFirstDevice == true) { - m_deviceInfo = m_widgetLoginOpts->getFirstDevInfo(); - } else { - skipBiometricAuth(); - return; - } + skipBiometricAuth(); + return; } //clearMessage(); @@ -816,16 +1107,27 @@ void AuthDialog::performBiometricAuth() if(!m_deviceInfo) { m_deviceInfo = m_widgetLoginOpts->findDeviceByName(m_deviceName); - if (!m_deviceInfo) - m_deviceInfo = m_widgetLoginOpts->getFirstDevInfo(); + if(!m_deviceInfo) + { + skipBiometricAuth(); + return; + } } - if(!m_deviceInfo) - { + + if(m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + m_widgetLoginOpts->setSelectedPassword(); skipBiometricAuth(); - return; + return ; } + switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); - startBioAuth(); + if(!m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) + startBioAuth(); + else { + QImage imgFailed; + setFaceImg(imgFailed, 1); + } skipBiometricAuth(); } @@ -839,13 +1141,15 @@ void AuthDialog::initBiometricWidget() if(m_widgetLoginOpts) { m_widgetLoginOpts->setUser(user.uid); } else { - m_widgetLoginOpts = new LoginOptionsWidget(m_biometricProxy, user.uid, this); + m_widgetLoginOpts = new LoginOptionsWidget(m_biometricProxy, user.uid, m_uniauthService, this); connect(m_widgetLoginOpts, &LoginOptionsWidget::authComplete, this, &AuthDialog::onBiometricAuthComplete); connect(m_widgetLoginOpts, &LoginOptionsWidget::optionSelected, this, &AuthDialog::onDeviceChanged); connect(m_widgetLoginOpts, &LoginOptionsWidget::updateImage, this, &AuthDialog::onLoginOptImage); + connect(m_widgetLoginOpts, &LoginOptionsWidget::setLoadingImage, + this, &AuthDialog::onLoadingImage); connect(m_widgetLoginOpts, &LoginOptionsWidget::notifyOptionsChange, this, &AuthDialog::onLoginOptsCount); connect(m_widgetLoginOpts, &LoginOptionsWidget::updateAuthMsg, @@ -857,6 +1161,12 @@ void AuthDialog::initBiometricWidget() m_widgetLoginOpts->hide(); else m_widgetLoginOpts->show(); + + if(m_widgetLoginOpts->getHasUkeyOptions() && m_widgetLoginOpts->getLoginOptCount() < 1){ + m_widgetLoginOpts->show(); + m_widgetLoginOpts->setSelectedPassword(); + } + m_widgetLoginOpts->setEnabled(true); setBiometricWidgetGeometry(); @@ -868,35 +1178,78 @@ void AuthDialog::setBiometricWidgetGeometry() if(m_widgetLoginOpts) { m_widgetLoginOpts->setGeometry(0, m_passwdWidget->geometry().bottom(), - width(), 84*scale); + width(), 92*scale); qDebug()<<"LoginOptGeometry:"<geometry()<<","<geometry() <<","<isHidden(); } } -void AuthDialog::onDeviceChanged(unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo) +int AuthDialog::getBioNum() { - if (!deviceInfo) + return m_widgetLoginOpts->getVisibleLoginOptCount(); +} + +void AuthDialog::onDeviceChanged(unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo, bool keyNavigation) +{ + if(!keyNavigation) + Q_EMIT loginOptionClicked(); + isLoadingUkey = false; + if(uCurLoginOptType == LOGINOPT_TYPE_PASSWORD){ + switchLoginOptType(uCurLoginOptType); + if(m_widgetLoginOpts){ + m_widgetLoginOpts->stopAuth(); + } + m_deviceInfo = nullptr; + authMode = PASSWORD; + startAuth(); return; - qDebug() << "device changed: " << *deviceInfo; - if(m_failedTimes.contains(deviceInfo->id) && + } + if (uCurLoginOptType != LOGINOPT_TYPE_GENERAL_UKEY && !deviceInfo) + return; + if(deviceInfo) + qDebug() << "device changed: " << *deviceInfo; + if(deviceInfo && m_failedTimes.contains(deviceInfo->id) && m_failedTimes[deviceInfo->id] >= maxFailedTimes){ qDebug() << "Failed MAX:"<id; return ; } - if (deviceInfo == m_deviceInfo) { + + if (uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY && !deviceInfo){ + isLoadingUkey = true; + startLoadingUkey(); + }else if(uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY && deviceInfo){ + stopLoadingUkey(); + } + + if (uCurLoginOptType != LOGINOPT_TYPE_GENERAL_UKEY && deviceInfo == m_deviceInfo) { return ; } + + if(m_bioTimer && m_bioTimer->isActive()) + m_bioTimer->stop(); + m_deviceInfo = deviceInfo; switchLoginOptType(uCurLoginOptType); - if(!isBioPassed) + if(!isBioPassed && deviceInfo) startBioAuth(); } void AuthDialog::onBiometricAuthComplete(bool result, int nStatus) { if(!result) { - if (nStatus >= 2) { + + if(m_deviceInfo && m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY && m_ukeyPasswdWidget->isVisible()){ + m_ukeyPasswordEdit->stopWaiting(); + m_ukeyPasswordEdit->clearText(); + } + + if (nStatus == 5 && m_deviceInfo) { + if(w_timer && w_timer->isActive()) + w_timer->stop(); + QImage imgFailed; + setFaceImg(imgFailed, 2); + return; + } else if (nStatus >= 2 && nStatus != 5) { if (m_deviceInfo) { if (m_failedTimes.contains(m_deviceInfo->id)) { m_failedTimes[m_deviceInfo->id] = m_failedTimes[m_deviceInfo->id] + 1; @@ -913,16 +1266,31 @@ void AuthDialog::onBiometricAuthComplete(bool result, int nStatus) setLoginTypeTip(tr("Failed to verify %1, please enter password to unlock").arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType))); QImage nullImage; setQRCode(nullImage); + }else if(m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + setUkeyTypeTip(tr("Unable to verify %1, please enter password to unlock").arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType))); } else { setLoginTypeTip(tr("Unable to verify %1, please enter password to unlock").arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType))); } if (m_widgetLoginOpts) m_widgetLoginOpts->setDeviceDisable(m_deviceInfo->id, true); + + if(m_ukeyPasswdWidget && m_ukeyPasswdWidget->isVisible()){ + m_ukeyPasswordEdit->readOnly(true); + } return ; } - setLoginTypeTip(tr("Failed to verify %1, you still have %2 verification opportunities") - .arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType)) - .arg(maxFailedTimes-m_failedTimes[m_deviceInfo->id])); + + qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + if(m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + setUkeyTypeTip(tr("Failed to verify %1, you still have %2 verification opportunities") + .arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType)) + .arg(maxFailedTimes-m_failedTimes[m_deviceInfo->id])); + }else { + setLoginTypeTip(tr("Failed to verify %1, you still have %2 verification opportunities") + .arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType)) + .arg(maxFailedTimes-m_failedTimes[m_deviceInfo->id])); + } + qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; } } @@ -931,12 +1299,12 @@ void AuthDialog::onBiometricAuthComplete(bool result, int nStatus) qDebug()<<"Biometric dbus error:"<= 2 && m_deviceInfo) { + if (nStatus >= 2 && nStatus != 5 && m_deviceInfo) { if (m_deviceInfo->deviceType == DeviceType::Face) { QImage imgFailed; setFaceImg(imgFailed, 1); @@ -985,6 +1353,7 @@ void AuthDialog::setQRCode(QImage& imgQRCode) m_imgQRCode.load(":/image/assets/ukui-qrcode-null.svg"); } else { m_imgQRCode = imgQRCode; + m_labelQRCodeTip->hide(); } m_imgQRCode = m_imgQRCode.scaled(QSize(150*scale, 150*scale)); m_labelQRCode->setAlignment(Qt::AlignCenter); @@ -995,10 +1364,16 @@ void AuthDialog::setQRCodeMsg(QString strMsg) { if (strMsg.isEmpty()) { m_labelQRCodeMsg->hide(); - m_labelQRCodeTip->hide(); + //m_labelQRCodeTip->hide(); } else { - m_labelQRCodeMsg->setText(strMsg); + //一开始认证时就没有网,直接停止加载状态 + if(w_timer && w_timer->isActive()) + { + w_timer->stop(); + } + m_labelQRCodeMsg->setElideText(strMsg, m_labelQRCode->width() - 20* scale, 14); m_labelQRCodeMsg->show(); + m_labelQRCodeTip->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(QSize(22,22))); m_labelQRCodeTip->show(); } } @@ -1015,6 +1390,10 @@ void AuthDialog::setFaceImg(QImage& imgFace, int nStatus) case 1: faceImage = QPixmap(":/image/assets/ukui-loginopt-lose.svg"); break; + case 2: + faceImage = m_widgetLoginOpts->loadSvg(":/image/assets/ukui-loginopt-smile.svg", "gray", 48); + m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,10%);").arg((int)(77*scale))); + break; default: faceImage = QPixmap(":/image/assets/ukui-loginopt-smile.svg"); break; @@ -1025,6 +1404,32 @@ void AuthDialog::setFaceImg(QImage& imgFace, int nStatus) m_labelFace->setPixmap(faceImage); } +void AuthDialog::updatePixmap() +{ + QMatrix matrix; + matrix.rotate(90.0); + m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation); + if(m_uCurLoginOptType == LOGINOPT_TYPE_QRCODE) + m_labelQRCodeTip->setPixmap(m_waitingPixmap); + else if(m_uCurLoginOptType == LOGINOPT_TYPE_FACE) { + m_labelFace->setPixmap(m_waitingPixmap); + } +} + +void AuthDialog::setUkeyTypeTip(QString text) +{ + QString textTip = text; + if (!textTip.isEmpty()) { +// QFontMetrics font(m_ukeyMessageLabel->font()); +// QString textTip = font.elidedText(textTip, Qt::ElideRight, m_messageLabel->width()-8); + m_ukeyMessageLabel->setText(textTip); + m_ukeyMessageLabel->setToolTip(text); + m_ukeyMessageLabel->show(); + } else { + m_ukeyMessageLabel->hide(); + } +} + void AuthDialog::setLoginTypeTip(QString strLoginTypeTip) { m_strLoginTypeTip = strLoginTypeTip; @@ -1044,7 +1449,7 @@ void AuthDialog::setLoginMsg(QString strLoginMsg) setLoginTypeTip(strLoginMsg); } -void AuthDialog::onLoginOptsCount(unsigned uCount) +void AuthDialog::onLoginOptsCount(unsigned uCount, bool is_bioBtn) { qDebug()<<"----------------------onLoginOptsCount Count:"<isDeviceDisable(m_deviceInfo->id)) { m_widgetLoginOpts->stopAuth(); authMode = BIOMETRIC; - startAuth(); + //初始化生物识别认证UI + initBiometricWidget(); + + //没有可用设备,不启用生物识别认证 + if(m_widgetLoginOpts->getLoginOptCount() < 1) + { + qWarning() << "No available devices"; + if (m_deviceInfo) { + m_deviceInfo = DeviceInfoPtr(); + } + return; + } + + //获取默认设备 + if (m_widgetLoginOpts) { + qDebug()<<"isLoadingUkey:"<getDefaultDevice(user.name,UniT_General_Ukey); + } else { + m_deviceName = m_widgetLoginOpts->getDefaultDevice(user.name); + } + } + qDebug() << m_deviceName; + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } + + //如果默认设备为空的话,不进行生物认证 + if(m_deviceName.isEmpty() && !m_deviceInfo) + { + return; + } + + if(!m_deviceInfo) + { + m_deviceInfo = m_widgetLoginOpts->findDeviceByName(m_deviceName); + if(!m_deviceInfo) + { + return; + } + } + + if (m_deviceInfo->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + stopLoadingUkey(); + } + + if(m_deviceInfo){ + m_widgetLoginOpts->setCurrentDevice(m_deviceInfo); + m_widgetLoginOpts->updateUIStatus(); + } + + switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); + startBioAuth(); } + if(is_bioBtn && uCount <= 1) + Q_EMIT loginOptionClicked(); } void AuthDialog::onLoginOptImage(QImage img) @@ -1075,4 +1537,144 @@ void AuthDialog::onLoginOptImage(QImage img) } else if (m_uCurLoginOptType == LOGINOPT_TYPE_QRCODE) { setQRCode(img); } + if(w_timer && w_timer->isActive()) + { + w_timer->stop(); + } +} + +void AuthDialog::onLoadingImage() +{ + if(!w_timer) + { + w_timer = new QTimer(this); + w_timer->setInterval(150); + connect(w_timer, &QTimer::timeout, this, &AuthDialog::updatePixmap); + } + m_waitingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(24, 24); + m_labelFace->setAlignment(Qt::AlignCenter); + if (m_uCurLoginOptType == LOGINOPT_TYPE_FACE) { + m_labelFace->setPixmap(m_waitingPixmap); + m_labelFace->show(); + } else if (m_uCurLoginOptType == LOGINOPT_TYPE_QRCODE) { + m_labelQRCodeTip->setPixmap(m_waitingPixmap); + m_labelQRCodeTip->show(); + } + w_timer->start(); +} + +void AuthDialog::onBiometricDbusChanged(bool bActive) +{ + qDebug()<<"BiometricDbus:"<isActivatable()) { + isHiddenSwitchButton = m_uniauthService->getHiddenSwitchButton(); + maxFailedTimes = m_uniauthService->getMaxFailedTimes(); + } else { + isHiddenSwitchButton = GetHiddenSwitchButton(); + maxFailedTimes = GetFailedTimes(); + } + } + + //服务没启动,或者打开DBus连接出错 + if(!m_biometricProxy->isValid()) + { + qWarning() << "An error occurs when connect to the biometric DBus"; + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } + return; + } + + //初始化生物识别认证UI + initBiometricWidget(); + + //没有可用设备,不启用生物识别认证 + if(m_widgetLoginOpts->getLoginOptCount() < 1) + { + qWarning() << "No available devices"; + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } + return; + } + + //获取默认设备 + if (m_widgetLoginOpts) { + m_deviceName = m_widgetLoginOpts->getDefaultDevice(user.name); + } + qDebug() << m_deviceName; + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } + + //如果默认设备为空的话,不再使用生物认证 + if(m_deviceName.isEmpty() && !m_deviceInfo) { + return; + } + + if (!m_deviceInfo) { + m_deviceInfo = m_widgetLoginOpts->findDeviceByName(m_deviceName); + if(!m_deviceInfo) { + return; + } + } + switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); + startBioAuth(); + }); + } +} + +QString AuthDialog::getCurAuthUserName() +{ + return user.name; +} + +QPixmap AuthDialog::makeRoundLogo(QString logo, int wsize, int hsize, int radius) +{ + QPixmap rectPixmap; + QPixmap iconcop = QPixmap(logo); + qreal dpi = m_labelHeadImg->devicePixelRatioF(); + if (dpi > 1.0) { + wsize = wsize * dpi; + hsize = hsize * dpi; + } + if (iconcop.width() > iconcop.height()) { + QPixmap iconPixmap = iconcop.copy((iconcop.width() - iconcop.height())/2, 0, iconcop.height(), iconcop.height()); + // 根据label高度等比例缩放图片 + rectPixmap = iconPixmap.scaledToHeight(hsize, Qt::SmoothTransformation); + } else { + QPixmap iconPixmap = iconcop.copy(0, (iconcop.height() - iconcop.width())/2, iconcop.width(), iconcop.width()); + // 根据label宽度等比例缩放图片 + rectPixmap = iconPixmap.scaledToWidth(wsize, Qt::SmoothTransformation); + } + + if (rectPixmap.isNull()) { + return QPixmap(); + } + QPixmap pixmapa(rectPixmap); + QPixmap pixmap(radius * 2 * dpi, radius * 2 * dpi); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + QPainterPath path; + path.addEllipse(0, 0, radius * 2 * dpi, radius * 2 * dpi); + painter.setClipPath(path); + painter.drawPixmap(0, 0, radius * 2 * dpi, radius * 2 * dpi, pixmapa); + pixmap.setDevicePixelRatio(dpi); + return pixmap; } diff --git a/src/authdialog.h b/src/authdialog.h index 73ecd16..9288545 100644 --- a/src/authdialog.h +++ b/src/authdialog.h @@ -30,21 +30,31 @@ #include "users.h" #include "biometricdeviceinfo.h" #include "pam-tally.h" +#include "uniauthservice.h" namespace Ui { class AuthDialog; } class QLabel; +class KLabel; class QPushButton; +class Configuration; class IconEdit; class Auth; class BiometricProxy; -class BiometricAuthWidget; -class BiometricDevicesWidget; class PamTally; class LoginOptionsWidget; +enum FOCUS { + REMOVE = 0, + IN_LIGIN, + BIO_RIGHT, + BIO_LEFT, + IN_LINEEDIT, + ON_MESSAGEBTN, +}; + extern float scale; class AuthDialog : public QWidget { @@ -56,6 +66,12 @@ public: void closeEvent(QCloseEvent *event); void setUserOfAuth(); void setX11Focus(); + void setFocusin(int target); + void setClick(); + void checkPassword(); + int getBioNum(); + bool getLineeditStatus(); + QString getCurAuthUserName(); private: void initUI(); void startWaiting(); @@ -66,21 +82,27 @@ private: void initBiometricWidget(); void setChildrenGeometry(); void setBiometricWidgetGeometry(); - QPixmap PixmapToRound(const QPixmap &src, int radius); void startBioAuth(unsigned uTimeout = 1000); void show_authenticated (bool successful = true); void setLoginTypeTip(QString strLoginTypeTip); + void setUkeyTypeTip(QString text); + void updatePixmap(); + void startLoadingUkey(); + void stopLoadingUkey(); + void updateLoadingPixmap(); + QPixmap makeRoundLogo(QString logo, int wsize, int hsize, int radius); private Q_SLOTS: void onShowMessage(const QString &message, Auth::MessageType type); void onShowPrompt(const QString &prompt, Auth::PromptType type); void onAuthComplete(); void onRespond(const QString &text); + void onRespondUkey(const QString &text); // void onBioAuthStart(); // void onBioAuthStop(); // void setBioMovieImage(); // void updateIcon(); - void onDeviceChanged(unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo); + void onDeviceChanged(unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo, bool keyNavigation); void onBiometricAuthComplete(bool result, int nStatus); void onBiometricButtonClicked(); void onPasswordButtonClicked(); @@ -89,13 +111,15 @@ private Q_SLOTS: void pamBioSuccess(); void onMessageButtonClicked(); void switchLoginOptType(unsigned uLoginOptType); - void onLoginOptsCount(unsigned uCount); + void onLoginOptsCount(unsigned uCount, bool is_bioBtn); void onLoginOptImage(QImage img); void setLoginMsg(QString strLoginMsg); void setQRCode(QImage& imgQRCode); void setFaceImg(QImage& imgFace, int nStatus = 0); void onM_passwordEditClicked(); void setQRCodeMsg(QString strMsg); + void onBiometricDbusChanged(bool bActive); + void onLoadingImage(); public Q_SLOTS: // void switchToBiometric(); @@ -108,6 +132,8 @@ public Q_SLOTS: Q_SIGNALS: void authenticateCompete(bool result); void clickPassword(bool clicked); + void loginOptionClicked(); + void showMessageBtn(bool is_show); private: UserItem user; Auth *auth; @@ -115,13 +141,12 @@ private: enum AuthMode { PASSWORD, BIOMETRIC, UNKNOWN }; AuthMode authMode; + Configuration *configuration; // biometric auth - int m_deviceCount; QString m_deviceName; DeviceInfoPtr m_deviceInfo = nullptr; BiometricProxy *m_biometricProxy; - BiometricAuthWidget *m_biometricAuthWidget; QWidget *m_buttonsWidget; QPushButton *m_biometricButton; QPushButton *m_passwordButton; @@ -134,18 +159,29 @@ private: // QPushButton *m_backButton; //返回用户列表 QWidget *m_userWidget; //放置用户信息Label QLabel *m_labelHeadImg = nullptr; //头像 - QLabel *m_nameLabel; //用户名 + KLabel *m_nameLabel; //用户名 // QLabel *m_isLoginLabel; //提示是否已登录 QWidget *m_passwdWidget; //放置密码输入框和信息列表 IconEdit *m_passwordEdit; //密码输入框 - QLabel *m_messageLabel; //PAM消息显示 + KLabel *m_messageLabel; //PAM消息显示 QPushButton *m_messageButton; + bool is_showMessageBtn = false; + + QWidget *m_ukeyPasswdWidget = nullptr; //放置密码输入框和信息列表 + IconEdit *m_ukeyPasswordEdit = nullptr; //密码输入框 + KLabel *m_ukeyMessageLabel = nullptr; //PAM消息显示 + + QWidget *m_loadingWidget = nullptr; + QPushButton *m_loadingButton = nullptr; + KLabel *m_loadingText = nullptr; + QTimer *m_loadingTimer = nullptr; + QPixmap m_loadingPixmap; QLabel *m_labelFace = nullptr; - QLabel *m_labelLoginTypeTip = nullptr; // 登录类型提示 + KLabel *m_labelLoginTypeTip = nullptr; // 登录类型提示 QLabel *m_labelQRCode = nullptr; // 二维码图标 - QLabel *m_labelQRCodeMsg = nullptr; // 二维码状态消息提示 + KLabel *m_labelQRCodeMsg = nullptr; // 二维码状态消息提示 QLabel *m_labelQRCodeTip = nullptr; bool isBioPassed; // 生物认证是否成功 @@ -153,7 +189,6 @@ private: bool isHiddenSwitchButton; QMap m_failedTimes; QTimer *m_bioTimer; - bool useFirstDevice; bool isLockingFlg; //判断当前是否正在锁定倒计时 int m_nCurLockMin; //当前锁定的分钟数 bool prompted = false; @@ -171,6 +206,13 @@ private: unsigned m_uCurLoginOptType = LOGINOPT_TYPE_PASSWORD; // 当前登录验证方式 QString m_strLoginTypeTip = ""; int m_nLastDeviceId = -1; + + QPixmap m_waitingPixmap; + QTimer *w_timer; + UniAuthService *m_uniauthService = nullptr; + double curFontSize = 0; + double m_ptToPx = 1.0; + bool isLoadingUkey = false; }; #endif // AUTHDIALOG_H diff --git a/src/batterywidget.cpp b/src/batterywidget.cpp new file mode 100644 index 0000000..d0a1c72 --- /dev/null +++ b/src/batterywidget.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "batterywidget.h" +#include +#include +#include +#include +#include + +BatteryWidget::BatteryWidget(QPoint point, QWidget *parent) : + QWidget(parent), + mPoint(point) +{ +// setWindowOpacity(0); + setAttribute(Qt::WA_TranslucentBackground); + initUi(); + setupComponent(); +} + +void BatteryWidget::initUi() +{ + QVBoxLayout *Lyt = new QVBoxLayout(this); + Lyt->setContentsMargins(16, 16, 16, 16); + Lyt->setSpacing(8); + mModeLabel = new QLabel(this); + mModeLabel->setFixedHeight(24); + mModeLabel->setStyleSheet("QLabel{font-size: 16px;font-family: NotoSansCJKsc-Bold, NotoSansCJKsc;" + "font-weight: bold;}"); + + QHBoxLayout *Lyt_1 = new QHBoxLayout(); + Lyt_1->setSpacing(4); + + mIconBtn = new QPushButton(this); + mIconBtn->setFixedSize(48, 32); + mIconBtn->setStyleSheet("QPushButton{\ + color: rgb(255, 255, 255, 255);\ + border: none;\ + border-radius: 4px;\ + outline: none;\ + }"); + + mValueLabel = new QLabel(this); + mValueLabel->setFixedHeight(48); + mValueLabel->setMidLineWidth(48); + + mStatusLabel = new QLabel(this); + mStatusLabel->setFixedHeight(36); + mStatusLabel->setAlignment(Qt::AlignRight); + + Lyt_1->addWidget(mIconBtn); + Lyt_1->addWidget(mValueLabel); + Lyt_1->addStretch(); + Lyt_1->addWidget(mStatusLabel); + + Lyt->addWidget(mModeLabel); + Lyt->addLayout(Lyt_1); + Lyt->addStretch(); +} + +void BatteryWidget::setupComponent() +{ + QString batteryPath = ""; + dface = new QDBusInterface(UPOWER_SERVICE, UPOWER_PATH, UPOWER_INTERFACE, QDBusConnection::systemBus(), this); + QDBusReply> reply = dface->call("EnumerateDevices"); + if (dface->isValid()) { + for (QDBusObjectPath op : reply.value()) { + if (op.path().contains("battery_")) { + batteryPath = op.path(); + qDebug() << "battery path is :" << batteryPath; + break; + } + } + } else { + qDebug() << "Enumerate devices failed"; + } + batInterface = new QDBusInterface(UPOWER_SERVICE, batteryPath, FREEDESKTOP_UPOWER, QDBusConnection::systemBus(), this); + + QDBusConnection::systemBus().connect( + UPOWER_SERVICE, batteryPath, FREEDESKTOP_UPOWER, "PropertiesChanged", this, SLOT(dealMessage(QDBusMessage))); + iface = new QDBusInterface(UPOWER_SERVICE, UPOWER_PATH, FREEDESKTOP_UPOWER, QDBusConnection::systemBus()); + if (dface->isValid()) { + mIconBtn->setIconSize(QSize(48, 32)); + mIconBtn->setFocusPolicy(Qt::NoFocus); + mIconBtn->setIcon(QIcon::fromTheme(getBatteryIconName())); + } + ed = EngineDevice::getInstance(); + onBatteryChanged(ed->engine_get_state()); + + int size; + size = ed->devices.size(); + for (int i = 0; i < size; i++) { + DEVICE *dv; + dv = ed->devices.at(i); + + if (dv->m_dev.kind == UP_DEVICE_KIND_LINE_POWER) { + continue; + } + + connect(ed, &EngineDevice::engine_signal_Battery_State, this, &BatteryWidget::onBatteryChanged); + continue; + } +} + +void BatteryWidget::setPoint(QPoint point) +{ + mPoint = point; +} + +QString BatteryWidget::getBatteryIconName() +{ + if (dface->isValid() && iface->isValid()) { + bool batteryState = false; + QDBusReply reply = iface->call("Get", UPOWER_SERVICE, "OnBattery"); + if (reply.isValid()) { + batteryState = reply.value().toBool(); + } + double percentage = -1.0; + QDBusReply percentage_reply = batInterface->call("Get", UPOWER_DIVICES_SERVICE, "Percentage"); + if (percentage_reply.isValid()) { + percentage = percentage_reply.value().toDouble(); + } + + if (batteryState) { + return QString("battery-level-%1-symbolic").arg((int)percentage / 10 * 10); + } else { + return QString("battery-level-%1-charging-symbolic").arg((int)percentage / 10 * 10); + } + } + return QString(); +} + +void BatteryWidget::showEvent(QShowEvent *event) +{ + QPoint pos = QPoint(mPoint.x(), + mPoint.y() - 112); + this->move(pos); + QWidget::showEvent(event); +} + +void BatteryWidget::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing, true); + p.save(); + p.setBrush(opt.palette.color(QPalette::Base)); + p.setPen(Qt::transparent); + p.setOpacity(0.75); + p.drawRoundedRect(this->rect(), 16, 16); + p.restore(); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void BatteryWidget::setBatteryIcon(QString icon) +{ + mIconBtn->setIcon(QIcon::fromTheme(icon)); +} + +void BatteryWidget::onBatteryChanged(QStringList args) +{ + int battery = args.at(0).toInt(); + int batteryState = args.at(1).toInt(); + if (batteryState == 1 || batteryState == 5) { + mStatusLabel->setText(tr("Charging...")); + } else if (batteryState == 4) { + mStatusLabel->setText(tr("fully charged")); + } + if (batteryState == 4 || batteryState == 1 || batteryState == 5) { + mStatusLabel->setVisible(true); + mModeLabel->setText(tr("PowerMode")); + } else { + mStatusLabel->setVisible(false); + mModeLabel->setText(tr("BatteryMode")); + } + + mValueLabel->setText(QString("%1%").arg(battery)); +} + +void BatteryWidget::dealMessage(QDBusMessage) +{ + mIconBtn->setIcon(QIcon::fromTheme(getBatteryIconName())); +} diff --git a/src/batterywidget.h b/src/batterywidget.h new file mode 100644 index 0000000..acf9ac5 --- /dev/null +++ b/src/batterywidget.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef BATTERYWIDGET_H +#define BATTERYWIDGET_H + +#include +#include +#include +#include +#include +#include +#include "enginedevice.h" + +#define FREEDESKTOP_UPOWER "org.freedesktop.DBus.Properties" +#define UPOWER_INTERFACE "org.freedesktop.UPower" +#define UPOWER_PATH "/org/freedesktop/UPower" +#define UPOWER_SERVICE "org.freedesktop.UPower" +#define UPOWER_DISPLAY_PATH "/org/freedesktop/UPower/devices/DisplayDevice" +#define UPOWER_DIVICES_SERVICE "org.freedesktop.UPower.Device" + +class BatteryWidget : public QWidget +{ + Q_OBJECT +public: + BatteryWidget(QPoint point, QWidget *parent = nullptr); + + void initUi(); + void setupComponent(); + void setPoint(QPoint point); + QString getBatteryIconName(); + +protected: + void showEvent(QShowEvent *event); + void paintEvent(QPaintEvent *event); + +private: + QLabel *mModeLabel; + QPushButton *mIconBtn; + QLabel *mValueLabel; + QLabel *mStatusLabel; + QPoint mPoint; + + QDBusInterface *batInterface; + QDBusInterface *iface; + QDBusInterface *dface; + + EngineDevice* ed; + +private Q_SLOTS: + void setBatteryIcon(QString icon); + void onBatteryChanged(QStringList args); + void dealMessage(QDBusMessage); + +}; + +#endif // BATTERYWIDGET_H diff --git a/src/common.h b/src/common.h index b7ed8c8..95489cb 100644 --- a/src/common.h +++ b/src/common.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef LOCKCOMMON_H #define LOCKCOMMON_H diff --git a/src/configuration.cpp b/src/configuration.cpp index ac964a0..0e9198c 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -20,16 +20,23 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#include +#include "glibinterface.h" #include "commonfunc.h" #define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define GSETTINGS_SCHEMA_STYLE "org.ukui.style" #define KEY_MODE "mode" #define KEY_THEMES "themes" +#define KEY_FONT_SIZE "systemFontSize" #define KEY_IDLE_ACTIVATION_ENABLED "idle-activation-enabled" #define KEY_LOCK_ENABLED "lock-enabled" #define KEY_IMAGE_TRANSITION_EFFECT "image-transition-effect" @@ -38,6 +45,7 @@ #define XSCREENSAVER_DIRNAME "/usr/lib/xscreensaver" #define KEY_IDLE_DELAY "idleDelay" #define KEY_IDLE_LOCK "idleLock" +#define KEY_LOCK_TIMEOUT "lockTimeout" Configuration* Configuration::instance_ = nullptr; @@ -51,13 +59,16 @@ Configuration::Configuration(QObject *parent) : QObject(parent) /* Initiailization */ mode = gsettings->get(KEY_MODE).toString(); themes = gsettings->get(KEY_THEMES).toStringList(); - idleDelay = gsettings->get( - KEY_IDLE_DELAY).toInt(); + idleDelay = gsettings->get(KEY_IDLE_DELAY).toInt(); lockEnabled = gsettings->get(KEY_LOCK_ENABLED).toBool(); idleLock = gsettings->get(KEY_IDLE_LOCK).toInt(); imageSwitchInterval = gsettings->get(KEY_IMAGE_SWITCH_INTERVAL).toInt(); imageTSEffect = gsettings->get(KEY_IMAGE_TRANSITION_EFFECT).toInt(); background = gsettings->get(KEY_BACKGROUND).toString(); + QStringList keysScreenSaver = gsettings->keys(); + if (keysScreenSaver.contains(KEY_LOCK_TIMEOUT)) { + m_nLockTimeout = gsettings->get(KEY_LOCK_TIMEOUT).toInt(); + } qDebug() << mode << themes; qDebug() << imageSwitchInterval << imageTSEffect; @@ -93,6 +104,13 @@ Configuration::Configuration(QObject *parent) : QObject(parent) if(themes.count() == 1 && themes[0] == "kyccss-personal-slideshow") mode ="image"; + + fsGsettings = new QGSettings(GSETTINGS_SCHEMA_STYLE); + + double defaultFontSize = getDefaultFontSize(); + + qDebug()<<"defaultFontSize = "<get(KEY_FONT_SIZE).toDouble() - defaultFontSize; } Configuration* Configuration::instance(QObject *parent) @@ -118,6 +136,8 @@ void Configuration::onConfigurationChanged(QString key) imageTSEffect = gsettings->get(KEY_IMAGE_TRANSITION_EFFECT).toInt(); else if(key == KEY_IMAGE_SWITCH_INTERVAL) imageSwitchInterval = gsettings->get(KEY_IMAGE_SWITCH_INTERVAL).toInt(); + else if (key == KEY_LOCK_TIMEOUT) + m_nLockTimeout = gsettings->get(KEY_LOCK_TIMEOUT).toInt(); } /* @@ -202,15 +222,50 @@ QString Configuration::getBackground() if(ispicture(background)) return background; + char *systemName = kdk_system_get_systemName(); + if (systemName) { + if (QString(systemName) == "openKylin") { + free(systemName); + return "/usr/share/backgrounds/1-openkylin.jpg"; + } + free(systemName); + } return "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; } -int Configuration::xscreensaverActivatedWhenIdle() +QString Configuration::getDefaultBackgroundName() { - return idleDelay; + return "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; } bool Configuration::lockWhenXScreensaverActivated() { return lockEnabled; } + +int Configuration::idlelock() +{ + return idleLock; +} + +int Configuration::idledelay() +{ + return idleDelay; +} + +int Configuration::locktimeout() +{ + return m_nLockTimeout; +} + +double Configuration::getFontSize() +{ + return curFontSize; +} + +double Configuration::getPtToPx() +{ + if (QApplication::primaryScreen()->logicalDotsPerInch() > 0) + m_pxToPt = 72/(QApplication::primaryScreen()->logicalDotsPerInch()); + return m_pxToPt; +} diff --git a/src/configuration.h b/src/configuration.h index a138775..8bd81e8 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -25,22 +25,27 @@ //#include "gsettings.h" #include -#include "screensaver.h" +#include "screensavermode.h" class QGSettings; class Configuration : public QObject { Q_OBJECT -public: +private: explicit Configuration(QObject *parent = nullptr); public: ScreenSaver *getScreensaver(); static Configuration *instance(QObject *parent = nullptr); - QString getBackground(); - int xscreensaverActivatedWhenIdle(); + QString getBackground(); + QString getDefaultBackgroundName(); bool lockWhenXScreensaverActivated(); + int idlelock(); + int idledelay(); + int locktimeout(); + double getFontSize(); + double getPtToPx(); public Q_SLOTS: void onConfigurationChanged(QString key); @@ -51,16 +56,20 @@ private: private: QGSettings *gsettings; QGSettings *bgGsettings; + QGSettings *fsGsettings; QString mode; + double curFontSize; + double m_pxToPt = 1.0; QList themes; QString background; bool idleActivationEnabled; bool lockEnabled; - int idleDelay; - int idleLock; + int idleDelay = -1; + int idleLock = -1; int imageTSEffect; int imageSwitchInterval; static Configuration *instance_; + int m_nLockTimeout = -1; }; #endif // CONFIGURATION_H diff --git a/src/device.cpp b/src/device.cpp new file mode 100644 index 0000000..007d30a --- /dev/null +++ b/src/device.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "device.h" +#include + +DEVICE::DEVICE(QObject *parent) : QObject(parent) {} + +void DEVICE::handleChanged(QDBusMessage msg) +{ + Q_EMIT device_property_changed(msg, m_dev.path); +} + +DEVICE::~DEVICE() {} diff --git a/src/device.h b/src/device.h new file mode 100644 index 0000000..73c8615 --- /dev/null +++ b/src/device.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#ifndef DEVICE_H +#define DEVICE_H + +#include + +#define GPM_DBUS_SERVICE "org.ukui.PowerManager" +#define GPM_DBUS_INTERFACE "org.ukui.PowerManager" +#define GPM_DBUS_INTERFACE_BACKLIGHT "org.ukui.PowerManager.Backlight" +#define GPM_DBUS_INTERFACE_KBD_BACKLIGHT "org.ukui.PowerManager.KbdBacklight" +#define GPM_DBUS_PATH "/org/ukui/PowerManager" +#define GPM_DBUS_PATH_BACKLIGHT "/org/ukui/PowerManager/Backlight" +#define GPM_DBUS_PATH_KBD_BACKLIGHT "/org/ukui/PowerManager/KbdBacklight" + +/* common descriptions of this program */ +#define GPM_NAME _("Power Manager") +#define GPM_DESCRIPTION _("Power Manager for the MATE desktop") + +/* schema location */ +#define GPM_SETTINGS_SCHEMA "org.ukui.power-manager" +#define GPM_SETTINGS_KEY_POLICY "icon-policy" + +/* actions */ +#define GPM_SETTINGS_ACTION_CRITICAL_UPS "action-critical-ups" +#define GPM_SETTINGS_ACTION_CRITICAL_BATT "action-critical-battery" +#define GPM_SETTINGS_ACTION_LOW_UPS "action-low-ups" +#define GPM_SETTINGS_ACTION_SLEEP_TYPE_AC "action-sleep-type-ac" +#define GPM_SETTINGS_ACTION_SLEEP_TYPE_BATT "action-sleep-type-battery" +#define GPM_SETTINGS_SLEEP_WHEN_CLOSED "event-when-closed-battery" + +/* backlight stuff */ +#define GPM_SETTINGS_BACKLIGHT_ENABLE "backlight-enable" +#define GPM_SETTINGS_BACKLIGHT_BATTERY_REDUCE "backlight-battery-reduce" +#define GPM_SETTINGS_DPMS_METHOD_AC "dpms-method-ac" +#define GPM_SETTINGS_DPMS_METHOD_BATT "dpms-method-battery" +#define GPM_SETTINGS_IDLE_BRIGHTNESS "idle-brightness" +#define GPM_SETTINGS_IDLE_DIM_AC "idle-dim-ac" +#define GPM_SETTINGS_IDLE_DIM_BATT "idle-dim-battery" +#define GPM_SETTINGS_IDLE_DIM_TIME "idle-dim-time" +#define GPM_SETTINGS_BRIGHTNESS_AC "brightness-ac" +#define GPM_SETTINGS_BRIGHTNESS_BAT "brightness-bat" +#define GPM_SETTINGS_BRIGHTNESS_DIM_BATT "brightness-dim-battery" + +/* keyboard backlight */ +#define GPM_SETTINGS_KBD_BACKLIGHT_BATT_REDUCE "kbd-backlight-battery-reduce" +#define GPM_SETTINGS_KBD_BRIGHTNESS_ON_AC "kbd-brightness-on-ac" +#define GPM_SETTINGS_KBD_BRIGHTNESS_DIM_BY_ON_BATT "kbd-brightness-dim-by-on-battery" +#define GPM_SETTINGS_KBD_BRIGHTNESS_DIM_BY_ON_IDLE "kbd-brightness-dim-by-on-idle" + +/* buttons */ +#define GPM_SETTINGS_BUTTON_LID_AC "button-lid-ac" +#define GPM_SETTINGS_BUTTON_LID_BATT "button-lid-battery" +#define GPM_SETTINGS_BUTTON_SUSPEND "button-suspend" +#define GPM_SETTINGS_BUTTON_HIBERNATE "button-hibernate" +#define GPM_SETTINGS_BUTTON_POWER "button-power" + +/* general */ +#define GPM_SETTINGS_USE_TIME_POLICY "use-time-for-policy" +#define GPM_SETTINGS_NETWORKMANAGER_SLEEP "network-sleep" +#define GPM_SETTINGS_IDLE_CHECK_CPU "check-type-cpu" + + +/* notify */ +#define GPM_SETTINGS_NOTIFY_LOW_CAPACITY "notify-low-capacity" +#define GPM_SETTINGS_NOTIFY_DISCHARGING "notify-discharging" +#define GPM_SETTINGS_NOTIFY_FULLY_CHARGED "notify-fully-charged" +#define GPM_SETTINGS_NOTIFY_SLEEP_FAILED "notify-sleep-failed" +#define GPM_SETTINGS_NOTIFY_SLEEP_FAILED_URI "notify-sleep-failed-uri" +#define GPM_SETTINGS_NOTIFY_LOW_POWER "notify-low-power" +#define GPM_SETTINGS_BAT_POLICY "power-policy-battery" +#define GPM_SETTINGS_ON_BAT_AUTO_SAVE "on-battery-auto-save" +#define GPM_SETTINGS_LOW_BAT_AUTO_SAVE "low-battery-auto-save" +#define GPM_SETTINGS_DISPLAY_LEFT_TIME "dispaly-left-time-of-charge-and-discharge" + + +/* thresholds */ +#define GPM_SETTINGS_PERCENTAGE_LOW "percentage-low" +#define GPM_SETTINGS_PERCENTAGE_CRITICAL "percentage-critical" +#define GPM_SETTINGS_PERCENTAGE_ACTION "percentage-action" +#define GPM_SETTINGS_TIME_LOW "time-low" +#define GPM_SETTINGS_TIME_CRITICAL "time-critical" +#define GPM_SETTINGS_TIME_ACTION "time-action" + +/* timeout */ +#define GPM_SETTINGS_SLEEP_COMPUTER_AC "sleep-computer-ac" +#define GPM_SETTINGS_SLEEP_COMPUTER_BATT "sleep-computer-battery" +#define GPM_SETTINGS_SLEEP_COMPUTER_UPS "sleep-computer-ups" +#define GPM_SETTINGS_SLEEP_DISPLAY_AC "sleep-display-ac" +#define GPM_SETTINGS_SLEEP_DISPLAY_BATT "sleep-display-battery" +#define GPM_SETTINGS_SLEEP_DISPLAY_UPS "sleep-display-ups" + +/* ui */ +#define GPM_SETTINGS_ICON_POLICY "icon-policy" +#define GPM_SETTINGS_ENABLE_SOUND "enable-sound" +#define GPM_SETTINGS_SHOW_ACTIONS "show-actions" + +/* statistics */ +#define GPM_SETTINGS_INFO_HISTORY_TIME "info-history-time" +#define GPM_SETTINGS_INFO_HISTORY_TYPE "info-history-type" +#define GPM_SETTINGS_INFO_HISTORY_GRAPH_SMOOTH "info-history-graph-smooth" +#define GPM_SETTINGS_INFO_HISTORY_GRAPH_POINTS "info-history-graph-points" +#define GPM_SETTINGS_INFO_STATS_TYPE "info-stats-type" +#define GPM_SETTINGS_INFO_STATS_GRAPH_SMOOTH "info-stats-graph-smooth" +#define GPM_SETTINGS_INFO_STATS_GRAPH_POINTS "info-stats-graph-points" +#define GPM_SETTINGS_INFO_PAGE_NUMBER "info-page-number" +#define GPM_SETTINGS_INFO_LAST_DEVICE "info-last-device" + +#if __aarch64__ +#define ARCH64 TRUE +#else +#define ARCH64 FALSE +#endif + +typedef enum { + GPM_ICON_POLICY_ALWAYS, + GPM_ICON_POLICY_PRESENT, + GPM_ICON_POLICY_CHARGE, + GPM_ICON_POLICY_LOW, + GPM_ICON_POLICY_CRITICAL, + GPM_ICON_POLICY_NEVER +} GpmIconPolicy; + +typedef enum { + GPM_ACTION_POLICY_BLANK, + GPM_ACTION_POLICY_SUSPEND, + GPM_ACTION_POLICY_SHUTDOWN, + GPM_ACTION_POLICY_HIBERNATE, + GPM_ACTION_POLICY_INTERACTIVE, + GPM_ACTION_POLICY_NOTHING +} GpmActionPolicy; + + + +typedef enum { + UP_DEVICE_KIND_UNKNOWN, + UP_DEVICE_KIND_LINE_POWER, + UP_DEVICE_KIND_BATTERY, + UP_DEVICE_KIND_UPS, + UP_DEVICE_KIND_MONITOR, + UP_DEVICE_KIND_MOUSE, + UP_DEVICE_KIND_KEYBOARD, + UP_DEVICE_KIND_PDA, + UP_DEVICE_KIND_PHONE, + UP_DEVICE_KIND_MEDIA_PLAYER, + UP_DEVICE_KIND_TABLET, + UP_DEVICE_KIND_COMPUTER, + UP_DEVICE_KIND_LAST +} UpDeviceKind; + +/** + * UpDeviceState: + * + * The device state. + **/ +typedef enum { + UP_DEVICE_STATE_UNKNOWN, + UP_DEVICE_STATE_CHARGING, + UP_DEVICE_STATE_DISCHARGING, + UP_DEVICE_STATE_EMPTY, + UP_DEVICE_STATE_FULLY_CHARGED, + UP_DEVICE_STATE_PENDING_CHARGE, + UP_DEVICE_STATE_PENDING_DISCHARGE, + UP_DEVICE_STATE_LAST +} UpDeviceState; + +/** + * UpDeviceTechnology: + * + * The device technology. + **/ +typedef enum { + UP_DEVICE_TECHNOLOGY_UNKNOWN, + UP_DEVICE_TECHNOLOGY_LITHIUM_ION, + UP_DEVICE_TECHNOLOGY_LITHIUM_POLYMER, + UP_DEVICE_TECHNOLOGY_LITHIUM_IRON_PHOSPHATE, + UP_DEVICE_TECHNOLOGY_LEAD_ACID, + UP_DEVICE_TECHNOLOGY_NICKEL_CADMIUM, + UP_DEVICE_TECHNOLOGY_NICKEL_METAL_HYDRIDE, + UP_DEVICE_TECHNOLOGY_LAST +} UpDeviceTechnology; + +/** + * UpDeviceLevel: + * + * The warning level of a battery. + **/ +typedef enum { + UP_DEVICE_LEVEL_UNKNOWN, + UP_DEVICE_LEVEL_NONE, + UP_DEVICE_LEVEL_DISCHARGING, + UP_DEVICE_LEVEL_LOW, + UP_DEVICE_LEVEL_CRITICAL, + UP_DEVICE_LEVEL_ACTION, + UP_DEVICE_LEVEL_LAST +} UpDeviceLevel; + +struct DEV +{ + UpDeviceKind kind; + UpDeviceLevel warnlevel; + QString Device; + QString Type; + QString PowerSupply; + QString Online; + QString Model; + QString Energy; + QString EnergyEmpty; + QString EnergyFull; + QString EnergyRate; + bool IsPresent; + QString IsRechargeable; + double Percentage; + UpDeviceState State; + qlonglong TimeToEmpty; + qlonglong TimeToFull; + QString Voltage; + double Capacity; + QString Technology; + QString path; + +}; + +class DEVICE : public QObject +{ + Q_OBJECT +public: + explicit DEVICE(QObject *parent = nullptr); + ~DEVICE(); +Q_SIGNALS: + void device_property_changed(QDBusMessage msg,QString path); + + +public Q_SLOTS: + void handleChanged(QDBusMessage msg); +public: + DEV m_dev; +}; + +#endif // DEVICE_H diff --git a/src/digitalkeyboard.cpp b/src/digitalkeyboard.cpp index 77239ba..4597ad4 100644 --- a/src/digitalkeyboard.cpp +++ b/src/digitalkeyboard.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "digitalkeyboard.h" #include diff --git a/src/digitalkeyboard.h b/src/digitalkeyboard.h index 107a115..4a386fe 100644 --- a/src/digitalkeyboard.h +++ b/src/digitalkeyboard.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef DIGITALKEYBOARD_H #define DIGITALKEYBOARD_H diff --git a/src/displaymanager.cpp b/src/displaymanager.cpp index abc9e0b..65e9346 100644 --- a/src/displaymanager.cpp +++ b/src/displaymanager.cpp @@ -73,7 +73,6 @@ QString DisplayManager::getDisplayType() void DisplayManager::switchToGreeter() { - qDebug()<<"111111111111111111111111111111111111111111111111111111"; if(_displayType == "lightdm"){ QDBusMessage ret = dmSeatService->call("SwitchToGreeter"); handleDBusError(ret); diff --git a/src/eduplatforminterface.cpp b/src/eduplatforminterface.cpp index 47084ef..6f3384c 100644 --- a/src/eduplatforminterface.cpp +++ b/src/eduplatforminterface.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "eduplatforminterface.h" const QString STR_EDU_SERVICE = "cn.kylinos.SSOBackend"; diff --git a/src/eduplatforminterface.h b/src/eduplatforminterface.h index 60e72dc..0a93506 100644 --- a/src/eduplatforminterface.h +++ b/src/eduplatforminterface.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef EDUPLATFORMINTERFACE_H #define EDUPLATFORMINTERFACE_H #include diff --git a/src/enginedevice.cpp b/src/enginedevice.cpp new file mode 100644 index 0000000..f69c95e --- /dev/null +++ b/src/enginedevice.cpp @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "enginedevice.h" +#include "device.h" +#include +#include +#include +#include +#include + +EngineDevice *EngineDevice::instance = NULL; + +void EngineDevice::power_device_get_devices() +{ + QList deviceNames; + + /* call enum dbus*/ + QDBusMessage msg = QDBusMessage::createMethodCall(DBUS_SERVICE, DBUS_OBJECT, DBUS_INTERFACE, "EnumerateDevices"); + QDBusMessage res = QDBusConnection::systemBus().call(msg); + + if (res.type() == QDBusMessage::ReplyMessage) { + const QDBusArgument &dbusArg = res.arguments().at(0).value(); + dbusArg >> deviceNames; + } else { + } + int len = deviceNames.size(); + // qDebug()<m_dev.path = deviceNames.at(i).path(); + getProperty(device->m_dev.path, device->m_dev); + /* connect the nofity signal to changecallback */ + QDBusConnection::systemBus().connect( + DBUS_SERVICE, + device->m_dev.path, + DBUS_INTERFACE_PRO, + QString("PropertiesChanged"), + device, + SLOT(handleChanged(QDBusMessage))); + connect( + device, + SIGNAL(device_property_changed(QDBusMessage, QString)), + this, + SLOT(power_device_change_callback(QDBusMessage, QString))); + + /* add to device list*/ + devices.append(device); + } +} + +EngineDevice::EngineDevice(QObject *parent) : QObject(parent) +{ + settings = new QGSettings(GPM_SETTINGS_SCHEMA); + power_device_get_devices(); +} + +void EngineDevice::getProperty(QString path, DEV &dev) +{ + QDBusMessage msg = QDBusMessage::createMethodCall(DBUS_SERVICE, path, DBUS_INTERFACE_PRO, "GetAll"); + msg << DBUS_INTERFACE_DEV; + QDBusMessage res = QDBusConnection::systemBus().call(msg); + + if (res.type() == QDBusMessage::ReplyMessage) { + const QDBusArgument &dbusArg = res.arguments().at(0).value(); + QMap map; + dbusArg >> map; + + dev.kind = (UpDeviceKind)map.value(QString("Type")).toInt(); + dev.Type = engine_kind_to_localised_text((UpDeviceKind)map.value(QString("Type")).toInt(), 1); + dev.Model = map.value(QString("Model")).toString(); + dev.Device = map.value(QString("NativePath")).toString(); + dev.IsPresent = (map.value(QString("IsPresent")).toBool()); + dev.PowerSupply = boolToString(map.value(QString("PowerSupply")).toBool()); + dev.Percentage = map.value(QString("Percentage")).toDouble(); + dev.Percentage = ((float)((int)((dev.Percentage + 0.05) * 10))) / 10; + + dev.Online = boolToString(map.value(QString("Online")).toBool()); + dev.State = (UpDeviceState)map.value(QString("State")).toInt(); + dev.TimeToEmpty = map.value(QString("TimeToEmpty")).toLongLong(); + dev.TimeToFull = map.value(QString("TimeToFull")).toLongLong(); + } +} + +QString EngineDevice::boolToString(bool ret) +{ + return ret ? tr("yes") : tr("no"); +} + +void EngineDevice::putAttributes(QMap &map, DEV &btrDetailData) +{ + if (map.contains("TimeToFull")) { + btrDetailData.TimeToFull = map.value(QString("TimeToFull")).toLongLong(); + } + if (map.contains("TimeToEmpty")) { + btrDetailData.TimeToEmpty = map.value(QString("TimeToEmpty")).toLongLong(); + } + if (map.contains("State")) { + btrDetailData.State = (UpDeviceState)map.value(QString("State")).toInt(); + } + if (map.contains("Percentage")) { + btrDetailData.Percentage = map.value(QString("Percentage")).toDouble(); + btrDetailData.Percentage = ((float)((int)((btrDetailData.Percentage + 0.05) * 10))) / 10; + } + if (map.contains("PowerSupply")) { + btrDetailData.PowerSupply = (map.value(QString("PowerSupply")).toBool()) ? tr("Yes") : tr("No"); + } + if (map.contains("IsPresent")) { + btrDetailData.IsPresent = (map.value(QString("IsPresent")).toBool()); + } +} + +void EngineDevice::power_device_change_callback(QDBusMessage msg, QString path) +{ + /* if battery change to display devices */ + /* judge state */ + DEVICE *item = nullptr; + Q_FOREACH (auto item_tmp, devices) { + if (item_tmp->m_dev.path == path) { + item = item_tmp; + break; + } + } + + if (item == nullptr) + return; + const QDBusArgument &arg = msg.arguments().at(1).value(); + QMap map; + arg >> map; + putAttributes(map, item->m_dev); + + /*recaculate state*/ + power_device_recalculate_state(); +} + +void EngineDevice::power_device_recalculate_state() +{ + engine_recalculate_summary(); +} + +/** + * engine_recalculate_summary: + */ +bool EngineDevice::engine_recalculate_summary() +{ + QString summary; + QStringList Battery_State; + + Battery_State = engine_get_state(); + summary = engine_get_summary(); + if (Battery_State.isEmpty()) { + return false; + } + if (previous_summary.isNull()) { + previous_summary = summary; + Q_EMIT engine_signal_summary_change(summary); + Q_EMIT engine_signal_Battery_State(Battery_State); + return true; + } + + if (previous_summary != summary) { + previous_summary = summary; + Q_EMIT engine_signal_summary_change(summary); + Q_EMIT engine_signal_Battery_State(Battery_State); + return true; + } + return false; +} + +QStringList EngineDevice::engine_get_state() +{ + DEVICE *device; + UpDeviceState state; + QStringList tooltip; + QStringList part; + bool is_present; + UpDeviceKind kind; + + Q_FOREACH (device, devices) { + is_present = device->m_dev.IsPresent; + state = device->m_dev.State; + kind = device->m_dev.kind; + if ((!is_present) || (kind != UP_DEVICE_KIND_BATTERY)) + continue; + if (state == UP_DEVICE_STATE_EMPTY) + continue; + part = engine_get_Battery_State(device); + if (!part.isEmpty()) + tooltip.append(part); + } + return tooltip; +} + +QStringList EngineDevice::engine_get_Battery_State(DEVICE *dv) +{ + UpDeviceState state; + double percentage; + QStringList result; + state = dv->m_dev.State; + int EMPTY = dv->m_dev.TimeToEmpty; + percentage = dv->m_dev.Percentage; + bool is_present; + is_present = dv->m_dev.IsPresent; + if (!is_present) + return result; + result.append(QString("%1").arg(percentage)); + result.append(QString("%1").arg(state)); + result.append(QString("%1").arg(EMPTY)); + return result; +} + +/** + * engine_get_summary: + * + * Returns the complete tooltip ready for display + **/ +QString EngineDevice::engine_get_summary() +{ + DEVICE *device; + UpDeviceState state; + QString tooltip; + QString part; + bool is_present; + UpDeviceKind kind; + + Q_FOREACH (device, devices) { + is_present = device->m_dev.IsPresent; + state = device->m_dev.State; + kind = device->m_dev.kind; + if ((!is_present) || (kind != UP_DEVICE_KIND_BATTERY)) + continue; + if (state == UP_DEVICE_STATE_EMPTY) + continue; + part = engine_get_device_summary(device); + if (!part.isNull()) + tooltip = QString("%1").arg(part); + } + return tooltip; +} + +/** + * engine_get_device_summary: + **/ + +QString EngineDevice::engine_get_device_summary(DEVICE *dv) +{ + QString kind_desc; + UpDeviceKind kind; + UpDeviceState state; + double percentage; + bool is_present; + uint time_to_full; + uint time_to_empty; + + QString result; + + kind = dv->m_dev.kind; + is_present = dv->m_dev.IsPresent; + state = dv->m_dev.State; + percentage = dv->m_dev.Percentage; + time_to_empty = dv->m_dev.TimeToEmpty; + time_to_full = dv->m_dev.TimeToFull; + if (!is_present) + return NULL; + + kind_desc = engine_kind_to_localised_text(kind, 1); + + if (state == UP_DEVICE_STATE_FULLY_CHARGED) { + + result = tr("%1% available, charged").arg(percentage); + + } else if (state == UP_DEVICE_STATE_DISCHARGING) { + + int is_show = settings->get(GPM_SETTINGS_DISPLAY_LEFT_TIME).toInt(); + if (is_show) { + result = tr("Left %1h %2m (%3%)") + .arg((time_to_empty) / 3600) + .arg(((time_to_empty) % 3600) / 60) + .arg(percentage); + } else { + result = tr("%1% available").arg(percentage); + } + + } else if (state == UP_DEVICE_STATE_CHARGING) { + int is_show = settings->get(GPM_SETTINGS_DISPLAY_LEFT_TIME).toInt(); + if (is_show) { + result = tr("Left %1h %2m to full").arg((time_to_full) / 3600).arg(((time_to_full) % 3600) / 60); + } else { + result = tr("charging (%1%)").arg(percentage); + } + + } else if (state == UP_DEVICE_STATE_PENDING_DISCHARGE) { + + /* TRANSLATORS: this is only shown for laptops with multiple batteries */ + result = tr("%1 waiting to discharge (%2%)").arg(kind_desc).arg(percentage); + + } else if (state == UP_DEVICE_STATE_PENDING_CHARGE) { + + /* TRANSLATORS: this is only shown for laptops with multiple batteries */ + result = tr("%1 waiting to charge (%2%)").arg(kind_desc).arg(percentage); + + } else { + printf("in an undefined state we are not charging or " + "discharging and the batteries are also not charged"); + result = QString("%1 (%2%)").arg(kind_desc).arg(percentage); + } + return result; +} + +/** + * engine_kind_to_localised_text: + **/ +QString EngineDevice::engine_kind_to_localised_text(UpDeviceKind kind, uint number) +{ + Q_UNUSED(number); + QString text; + switch (kind) { + case UP_DEVICE_KIND_LINE_POWER: + + text = tr("AC adapter"); + break; + case UP_DEVICE_KIND_BATTERY: + /* TRANSLATORS: laptop primary battery */ + text = tr("Laptop battery"); + break; + case UP_DEVICE_KIND_UPS: + /* TRANSLATORS: battery-backed AC power source */ + text = tr("UPS"); + break; + case UP_DEVICE_KIND_MONITOR: + /* TRANSLATORS: a monitor is a device to measure voltage and current */ + text = tr("Monitor"); + break; + case UP_DEVICE_KIND_MOUSE: + /* TRANSLATORS: wireless mice with internal batteries */ + text = tr("Mouse"); + break; + case UP_DEVICE_KIND_KEYBOARD: + /* TRANSLATORS: wireless keyboard with internal battery */ + text = tr("Keyboard"); + break; + case UP_DEVICE_KIND_PDA: + /* TRANSLATORS: portable device */ + text = tr("PDA"); + break; + case UP_DEVICE_KIND_PHONE: + /* TRANSLATORS: cell phone (mobile...) */ + text = tr("Cell phone"); + break; + case UP_DEVICE_KIND_MEDIA_PLAYER: + /* TRANSLATORS: media player, mp3 etc */ + text = tr("Media player"); + break; + case UP_DEVICE_KIND_TABLET: + /* TRANSLATORS: tablet device */ + text = tr("Tablet"); + break; + case UP_DEVICE_KIND_COMPUTER: + /* TRANSLATORS: tablet device */ + text = tr("Computer"); + break; + default: + printf("enum unrecognised: %i", kind); + text = tr("unrecognised"); + } + return text; +} diff --git a/src/enginedevice.h b/src/enginedevice.h new file mode 100644 index 0000000..c87bacc --- /dev/null +++ b/src/enginedevice.h @@ -0,0 +1,100 @@ +/* + * Copyright 2021 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ENGINEDEVICE_H +#define ENGINEDEVICE_H + +#include +#include "device.h" +#include +#include +#include +#include + + +#define DBUS_SERVICE "org.freedesktop.UPower" +#define DBUS_OBJECT "/org/freedesktop/UPower" +#define DBUS_INTERFACE "org.freedesktop.UPower" + +#define DBUS_INTERFACE_PRO "org.freedesktop.DBus.Properties" +#define DBUS_INTERFACE_DEV "org.freedesktop.UPower.Device" + +class EngineDevice : public QObject +{ + Q_OBJECT +private: + static EngineDevice* instance; + explicit EngineDevice(QObject *parent = nullptr); + class Deconstructor + { + public: + ~Deconstructor() { + if(instance) + { + delete instance; + instance = nullptr; + } + } + }; + static Deconstructor deconstructor; + +public: + static EngineDevice* getInstance() + { + if(instance==nullptr) + { + instance = new EngineDevice; + + } + return instance; + } + +Q_SIGNALS: + void engine_signal_discharge(DEV dv); + void engine_signal_charge(DEV dv); + void engine_signal_fullycharge(DEV dv); + void engine_signal_charge_low(DEV dv); + void engine_signal_charge_critical(DEV dv); + void engine_signal_charge_action(DEV dv); + void engine_signal_summary_change(QString summary); + void engine_signal_Battery_State(QStringList Battery_State); +public Q_SLOTS: + void power_device_change_callback(QDBusMessage msg, QString path); + +public: + QGSettings *settings; + QList devices; + QString previous_icon; + QString previous_summary; + + DEVICE *composite_device; + void power_device_recalculate_state(); + bool engine_recalculate_summary(); + void getProperty(QString path, DEV &dev); + QString engine_get_summary(); + QStringList engine_get_state (); + QString engine_kind_to_localised_text(UpDeviceKind kind, uint number); + void power_device_get_devices(); + + QStringList engine_get_Battery_State(DEVICE* dv); + + QString boolToString(bool ret); + QString engine_get_device_summary(DEVICE *dv); + void putAttributes(QMap &map, DEV &btrDetailData); +}; + +#endif // ENGINEDEVICE_H diff --git a/src/fullbackgroundwidget.cpp b/src/fullbackgroundwidget.cpp index c199287..f4124b0 100644 --- a/src/fullbackgroundwidget.cpp +++ b/src/fullbackgroundwidget.cpp @@ -30,8 +30,11 @@ #include #include #include +#include #include +#include "plasma-shell-manager.h" #include +#include "lockwidget.h" #include #include #include @@ -48,11 +51,10 @@ #include #include -#include "lockwidget.h" #include "xeventmonitor.h" #include "monitorwatcher.h" #include "configuration.h" -#include "screensaver.h" +#include "screensavermode.h" #include "screensaverwidget.h" #include "grab-x11.h" #include "tabletlockwidget.h" @@ -75,10 +77,8 @@ extern void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool qual QT_END_NAMESPACE #define BLUR_RADIUS 300 -#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" -#define KEY_IDLE_DELAY "idleDelay" -#define KEY_IDLE_LOCK "idleLock" -#define KEY_IDLE_LOCK_ENABLED "idleLockEnabled" + +#define SUBWND_COUNT_MAX 1024 QPixmap scaledPixmap(int width, int height, QString url) { @@ -198,7 +198,7 @@ QPixmap blurPixmap(QPixmap pixmap) FullBackgroundWidget::FullBackgroundWidget(QWidget *parent) : QWidget(parent), lockWidget(nullptr), - xEventMonitor(new XEventMonitor(this)), + //xEventMonitor(new XEventMonitor(this)), //monitorWatcher(new MonitorWatcher(this)), configuration(Configuration::instance()), isLocked(false), @@ -209,20 +209,24 @@ FullBackgroundWidget::FullBackgroundWidget(QWidget *parent) m_delay(false) { qDebug() << "init - screenStatus: " << screenStatus; + m_listWndIds.clear(); setMouseTracking(true); - // connect(monitorWatcher, &MonitorWatcher::monitorCountChanged, - // this, &FullBackgroundWidget::onScreenCountChanged); +// connect(monitorWatcher, &MonitorWatcher::monitorCountChanged, +// this, &FullBackgroundWidget::onScreenCountChanged); QDesktopWidget *desktop = QApplication::desktop(); connect(desktop, &QDesktopWidget::resized, this, &FullBackgroundWidget::onDesktopResized); - connect(desktop, &QDesktopWidget::workAreaResized, - this, &FullBackgroundWidget::onDesktopResized); +// connect(desktop, &QDesktopWidget::workAreaResized, +// this, &FullBackgroundWidget::onDesktopResized); connect(desktop, &QDesktopWidget::primaryScreenChanged, this, &FullBackgroundWidget::onDesktopResized); connect(desktop, &QDesktopWidget::screenCountChanged, this, &FullBackgroundWidget::onDesktopResized); +// connect(QApplication::primaryScreen(),&QScreen::geometryChanged, this, &FullBackgroundWidget::onDesktopResized); +// connect(QApplication::screens().at(0), &QScreen::virtualGeometryChanged, this,&FullBackgroundWidget::onDesktopResized); + QDBusInterface *iface = new QDBusInterface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", @@ -236,33 +240,17 @@ FullBackgroundWidget::FullBackgroundWidget(QWidget *parent) SS_DBUS_INTERFACE, QDBusConnection::sessionBus()); - connect(interfaceScreensaver, SIGNAL(SessionIdle()), - this, SLOT(showScreensaver())); + connect(interfaceScreensaver, SIGNAL(SecondRunParam(QString)), + this, SLOT(onSecondRunParam(QString))); +// 闲置不会主动锁住 +// QDBusInterface *interfaceLock = new QDBusInterface( +// SS_DBUS_SERVICE, +// SS_DBUS_PATH, +// SS_DBUS_INTERFACE, +// QDBusConnection::sessionBus()); - settings_delay = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); - connect(settings_delay, &QGSettings::changed, - this, &FullBackgroundWidget::onConfigurationDelayChanged); - idleDelay = settings_delay->get("idle-delay").toInt(); - qDebug()<<"idleDelay="<get("idle-lock").toInt(); - -// lockEnabled_Key = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); -// connect(lockEnabled_Key, &QGSettings::changed, -// this, &FullBackgroundWidget::lockEnabledChanged); -// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); -// qDebug()<, QStringList))); @@ -272,15 +260,6 @@ FullBackgroundWidget::FullBackgroundWidget(QWidget *parent) qApp->installNativeEventFilter(this); installEventFilter(this); QTimer::singleShot(500,this,SLOT(switchToLinux())); - - LogindIntegration *m_logind = new LogindIntegration(this); - - - connect(m_logind, &LogindIntegration::requestUnlock, this, - [this]() { - closeScreensaver(); - }); - } #ifdef USE_INTEL @@ -314,55 +293,73 @@ void FullBackgroundWidget::switchToLinux() void FullBackgroundWidget::laterActivate() { + if (QX11Info::isPlatformX11()) { + /*在不调用XSetInputFocus接口的情况下,在窗口失去焦点后,activateWindow概率性无法 + * 激活窗口,导致锁屏输入不了密码。 + * 复现方法:锁屏,然后切换到tty,启动终端,文管等窗口抢占锁屏窗口焦点,数次以后必现*/ + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } activateWindow(); raise(); + raiseOtherWnd(); setFocus(); - if(lockWidget && lockWidget->isVisible()) + if(lockWidget && lockWidget->isVisible()) { lockWidget->setFocus(); + lockWidget->onActiveLineedit();//将焦点设置到密码框 + } + update(); } -void FullBackgroundWidget::onConfigurationDelayChanged(QString key) +void FullBackgroundWidget::laterOtherActivate() { - if(key == KEY_IDLE_DELAY){ - idleDelay = settings_delay->get("idle-delay").toInt(); + activateWindow(); + raiseOtherWnd(); + //setFocus(); + if(lockWidget && lockWidget->isVisible()) { + lockWidget->setFocus(); + lockWidget->onActiveLineedit();//将焦点设置到密码框 } } -void FullBackgroundWidget::onConfigurationLockChanged(QString key) -{ - if(key == KEY_IDLE_LOCK){ - idleLock = settings_lock->get("idle-lock").toInt(); - } -} - -//void FullBackgroundWidget::lockEnabledChanged(QString key) -//{ -// if(key == KEY_IDLE_LOCK_ENABLED){ -// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); -// } -//} - void FullBackgroundWidget::setLockState() { if(lockState == true) return ; lockState = true; - - QDBusInterface *interface = new QDBusInterface(SS_DBUS_SERVICE, + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); + QString sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum); + QDBusInterface *interface = new QDBusInterface(sessionDbus, SS_DBUS_PATH, SS_DBUS_INTERFACE); + if (!interface->isValid()) { + delete interface; + interface = new QDBusInterface(SS_DBUS_SERVICE, + SS_DBUS_PATH, + SS_DBUS_INTERFACE); + } QDBusMessage msg = interface->call("SetLockState"); if(msg.type() == QDBusMessage::ErrorMessage) qDebug() << msg.errorMessage(); - + HideMultiview(); } bool FullBackgroundWidget::eventFilter(QObject *obj, QEvent *event) { + if (!QX11Info::isPlatformX11()) { + if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseMove || event->type() == 7){ + if(screenStatus & SCREEN_SAVER && !isBlank){ + clearScreensavers(); + } + } + } if(event->type() == QEvent::WindowDeactivate){ QTimer::singleShot(50,this,SLOT(laterActivate())); }else if(event->type() == QEvent::WindowActivate){ +// if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland" && !QX11Info::isPlatformX11()) { +// PlasmaShellManager::getInstance()->setAppWindowKeepAbove(true); +// } + QTimer::singleShot(500,this,SLOT(setLockState())); QTimer::singleShot(200,this,SLOT(killWindow())); } @@ -380,6 +377,15 @@ void FullBackgroundWidget::killWindow() void FullBackgroundWidget::setIsStartup(bool val) { isStartup = val; + if (lockWidget) { + lockWidget->setStartupMode(isStartup); + } + Q_EMIT StartupModeChanged(isStartup); +} + +bool FullBackgroundWidget::IsStartupMode() +{ + return isStartup; } void FullBackgroundWidget::paintEvent(QPaintEvent *event) @@ -423,7 +429,22 @@ void FullBackgroundWidget::paintEvent(QPaintEvent *event) void FullBackgroundWidget::closeEvent(QCloseEvent *event) { qDebug() << "FullBackgroundWidget::closeEvent"; - + // 处理认证完成后收到屏幕变化信号,调用lockWidget指针崩溃问题 + QDesktopWidget *desktop = QApplication::desktop(); + disconnect(desktop, &QDesktopWidget::resized, + this, &FullBackgroundWidget::onDesktopResized); + disconnect(desktop, &QDesktopWidget::workAreaResized, + this, &FullBackgroundWidget::onDesktopResized); + disconnect(desktop, &QDesktopWidget::primaryScreenChanged, + this, &FullBackgroundWidget::onDesktopResized); + disconnect(desktop, &QDesktopWidget::screenCountChanged, + this, &FullBackgroundWidget::onDesktopResized); + if (isStartup) + setIsStartup(false); + if(future.isRunning()){ + future.cancel(); + future.waitForFinished(); + } #ifdef USE_INTEL //蓝牙连接后 唤醒信号会有延迟 以防退出时未收到信号导致kwin compositor未resume QDBusInterface *interface = new QDBusInterface("org.ukui.KWin", @@ -446,7 +467,9 @@ void FullBackgroundWidget::closeEvent(QCloseEvent *event) if(widget) widget->close(); } - closeGrab(); + if(QX11Info::isPlatformX11()){ + closeGrab(); + } return QWidget::closeEvent(event); } @@ -465,46 +488,122 @@ void FullBackgroundWidget::showEvent(QShowEvent *event) bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { - if (qstrcmp(eventType, "xcb_generic_event_t") != 0) { + if (qstrcmp(eventType, "xcb_generic_event_t") != 0) { + return false; + } + xcb_generic_event_t *event = reinterpret_cast(message); + const uint8_t responseType = event->response_type & ~0x80; + if (responseType == XCB_CONFIGURE_NOTIFY) { + xcb_configure_notify_event_t *xc = reinterpret_cast(event); + if(xc->window == winId()) { + laterOtherActivate(); return false; } - xcb_generic_event_t *event = reinterpret_cast(message); - const uint8_t responseType = event->response_type & ~0x80; - if (responseType == XCB_CONFIGURE_NOTIFY) { - xcb_configure_notify_event_t *xc = reinterpret_cast(event); - if(xc->window == winId()) - return false; - XWindowAttributes window_attributes; - XGetWindowAttributes (QX11Info::display(), xc->window,&window_attributes); - XClassHint ch; - ch.res_name = NULL; - ch.res_class = NULL; - XGetClassHint (QX11Info::display(), xc->window, &ch); - if(QString(ch.res_name) == "ukui-screensaver-dialog") - return false; - - laterActivate(); - }else if(responseType == XCB_MAP_NOTIFY){ - xcb_map_notify_event_t *xm = reinterpret_cast(event); - if(xm->window == winId()) - return false; - XWindowAttributes window_attributes; - XGetWindowAttributes (QX11Info::display(), xm->window,&window_attributes); - XClassHint ch; - ch.res_name = NULL; - ch.res_class = NULL; - XGetClassHint (QX11Info::display(), xm->window, &ch); - if(QString(ch.res_name) == "ukui-screensaver-dialog") - return false; - laterActivate(); - } - return false; + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), xc->window, &ch); + if(QString(ch.res_name) == "ukui-screensaver-dialog") { + if (ch.res_name) + XFree(ch.res_name); + if (ch.res_class) + XFree(ch.res_class); + laterOtherActivate(); + return false; + } else if (isOtherWnd(xc->window)) { + if (ch.res_name) + XFree(ch.res_name); + if (ch.res_class) + XFree(ch.res_class); + return false; + } + if (ch.res_name) + XFree(ch.res_name); + if (ch.res_class) + XFree(ch.res_class); + laterActivate(); + } else if(responseType == XCB_MAP_NOTIFY){ + xcb_map_notify_event_t *xm = reinterpret_cast(event); + if(xm->window == winId()) { + laterOtherActivate(); + return false; + } + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), xm->window, &ch); + if(QString(ch.res_name) == "ukui-screensaver-dialog") { + if (ch.res_name) + XFree(ch.res_name); + if (ch.res_class) + XFree(ch.res_class); + laterOtherActivate(); + return false; + } else if (isOtherWnd(xm->window)) { + if (ch.res_name) + XFree(ch.res_name); + if (ch.res_class) + XFree(ch.res_class); + return false; + } + if (ch.res_name) + XFree(ch.res_name); + if (ch.res_class) + XFree(ch.res_class); + laterActivate(); + } else if (responseType == XCB_DESTROY_NOTIFY) { + xcb_destroy_notify_event_t *xd = reinterpret_cast(event); + if(isOtherWnd(xd->window)) { + UnRegisteSubWnd(xd->window); + return false; + } + } else if (responseType == XCB_UNMAP_NOTIFY) { + xcb_unmap_notify_event_t *xum = reinterpret_cast(event); + if(isOtherWnd(xum->window)) { + UnRegisteSubWnd(xum->window); + return false; + } + } else if (responseType == XCB_KEY_PRESS) { +// xcb_key_press_event_t *xc = reinterpret_cast(event); +// qDebug()<<"---------------------XCB_KEY_PRESS:"<detail; + //onGlobalKeyPress(xc->detail); + } else if (responseType == XCB_KEY_RELEASE) { + xcb_key_release_event_t *xc = reinterpret_cast(event); + onGlobalKeyRelease(xc->detail); + } else if(responseType == XCB_GE_GENERIC){ + xcb_ge_generic_event_t *xc = reinterpret_cast(event); + if(xc->event_type == XCB_BUTTON_PRESS){ //此处获取的是窗口内的点击事件,光标坐标不需要使用,就直接使用QCursor接口获取了 + onGlobalButtonPressed(QCursor::pos().x(), QCursor::pos().y()); + }else if(xc->event_type == XCB_MOTION_NOTIFY){ //此处获取的是窗口内的点击事件,光标坐标不需要使用,就直接使用QCursor接口获取了 + onGlobalButtonDrag(QCursor::pos().x(),QCursor::pos().y()); + } + }else if (responseType == XCB_BUTTON_PRESS) { //此处获取的是窗口外的鼠标点击 + xcb_button_press_event_t *xc = reinterpret_cast(event); + int x = xc->root_x; + int y = xc->root_y; + onGlobalButtonPressed(x, y); + qDebug()<<"---------------------XCB_BUTTON_PRESS:"<(event); + int x = xc->root_x; + int y = xc->root_y; + onGlobalButtonDrag(x, y); + qDebug()<<"---------------------XCB_MOTION_NOTIFY:"<getBackground()); reader.setAutoTransform(true); - reader.setScaledSize(QApplication::primaryScreen()->size()); + reader.setDecideFormatFromContent(true); + //reader.setScaledSize(QApplication::primaryScreen()->size()); background = QPixmap::fromImageReader(&reader); if(!background.isNull()){ @@ -550,14 +668,15 @@ void FullBackgroundWidget::init() } }); - setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint + if(QX11Info::isPlatformX11()){ + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); - setAttribute(Qt::WA_TranslucentBackground); + }else{ + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); + } - XWindowAttributes rootAttr; - XGetWindowAttributes(QX11Info::display(), QX11Info::appRootWindow(), &rootAttr); - XSelectInput( QX11Info::display(), QX11Info::appRootWindow(), - SubstructureNotifyMask|rootAttr.your_event_mask ); + /*x100下会出现黑色小方块问题,设置此属性时正常*/ + setAttribute(Qt::WA_TranslucentBackground); // 监听session信号 // smInterface = new QDBusInterface(SM_DBUS_SERVICE, @@ -567,16 +686,6 @@ void FullBackgroundWidget::init() // connect(smInterface, SIGNAL(StatusChanged(uint)), // this, SLOT(onSessionStatusChanged(uint))); - connect(xEventMonitor, SIGNAL(keyPress(const QString &)), - this, SLOT(onGlobalKeyPress(const QString &))); - connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), - this, SLOT(onGlobalKeyRelease(const QString &))); - connect(xEventMonitor, SIGNAL(buttonDrag(int, int)), - this, SLOT(onGlobalButtonDrag(int, int))); - connect(xEventMonitor, SIGNAL(buttonPress(int, int)), - this, SLOT(onGlobalButtonPressed(int, int))); - - // int totalWidth = 0; // int totalHeight = 0; // for(auto screen : QGuiApplication::screens()) @@ -588,8 +697,6 @@ void FullBackgroundWidget::init() QDesktopWidget *desktop = QApplication::desktop(); setGeometry(desktop->geometry()); - xEventMonitor->start(); - #ifdef USE_INTEL SoundDeviceSet::instance(); #endif @@ -601,26 +708,30 @@ void FullBackgroundWidget::onCursorMoved(const QPoint &pos) { return; } + bool chkInOneScreen = false; for(auto screen : QGuiApplication::screens()) { -#ifdef USE_INTEL if(screen == qApp->primaryScreen()){ - lockWidget->setGeometry(screen->geometry()); - break; - } -#else - if(screen->geometry().contains(pos)) - { - if(lockWidget->geometry() == screen->geometry()) - return ; - /*避免切换时闪烁*/ - qDebug()<geometry()<geometry(); + qInfo()<<"LockWidget:"<geometry()<geometry(); lockWidget->hide(); lockWidget->setGeometry(screen->geometry()); lockWidget->show(); + chkInOneScreen = true; break; } -#endif + } + if (!chkInOneScreen) { + for(auto screen : QGuiApplication::screens()) { + if(!screen){ + /*避免切换时闪烁*/ + qInfo()<<"LockWidget:"<geometry()<geometry()<<","<hide(); + lockWidget->setGeometry(screen->geometry()); + lockWidget->show(); + chkInOneScreen = true; + break; + } + } } } @@ -667,20 +778,41 @@ void FullBackgroundWidget::showLockWidget() }); #else lockWidget = new LockWidget(this); + lockWidget->setStartupMode(isStartup); connect(lockWidget, &LockWidget::closed, this, &FullBackgroundWidget::close); + connect(lockWidget, &LockWidget::keyGlobalRelease, + this, &FullBackgroundWidget::onGlobalKeyRelease); #endif } onCursorMoved(QCursor::pos()); lockWidget->setFocus(); - XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + if(QX11Info::isPlatformX11() ){ + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } activateWindow(); repaint(); } -void FullBackgroundWidget::showScreensaver() +void FullBackgroundWidget::onSecondRunParam(QString strParam) +{ + qDebug()<<"onSecondRunParam:"<getScreensaver(); + /*锁屏设置的Qt::WA_TranslucentBackground属性会导致第三方屏保变得透明,因此在使用第三方屏保时 + * 取消该属性,清除屏保时再设置回来*/ + if(saver->path != "/usr/lib/ukui-screensaver/ukui-screensaver-default") + { + setAttribute(Qt::WA_TranslucentBackground,false); + } + ScreenSaverWidget *saverWidget = new ScreenSaverWidget(saver, this); qDebug() << " new ScreenSaverWidget"; widgetXScreensaverList.push_back(saverWidget); @@ -711,12 +851,17 @@ void FullBackgroundWidget::showScreensaver() if(lockWidget) { lockWidget->stopAuth(); - lockWidget->hide(); + lockWidget->hide(); + } + if (!isPreview && !(screenStatus & SCREEN_LOCK)) { + // 延迟启动锁屏 + delayLockScreen(); } } void FullBackgroundWidget::clearScreensavers() { + stopDelayLockScreen(); #ifdef USE_INTEL screenStatus = /*(ScreenStatus)(screenStatus & ~SCREEN_SAVER)*/SCREEN_LOCK; #else @@ -727,7 +872,7 @@ void FullBackgroundWidget::clearScreensavers() widget->close(); } widgetXScreensaverList.clear(); - + setAttribute(Qt::WA_TranslucentBackground,true); qDebug() << "clearScreensavers - screenStatus: " << screenStatus; unsetCursor(); @@ -751,7 +896,7 @@ int FullBackgroundWidget::onSessionStatusChanged(uint status) } qDebug() << "onSessionStatusChanged - screenStatus: " << screenStatus; - if(!configuration->xscreensaverActivatedWhenIdle()) + if(configuration->idledelay() == -1) { return -1; } @@ -778,44 +923,103 @@ int FullBackgroundWidget::onSessionStatusChanged(uint status) showLockWidget(); showScreensaver(); #else - if(configuration->xscreensaverActivatedWhenIdle() != -1 && configuration->lockWhenXScreensaverActivated()) - { - //显示锁屏和屏保 - showLockWidget(); - showScreensaver(); - } - else if(configuration->xscreensaverActivatedWhenIdle() != -1) - { - if( idleDelay == idleLock && idleLock != -1){ - //显示锁屏和屏保 - showLockWidget(); - showScreensaver(); - }else{ - //只显示屏保 - showScreensaver(); - } - } + //显示屏保 + showScreensaver(); #endif } return 0; } -void FullBackgroundWidget::onBlankScreensaver() +void FullBackgroundWidget::onSessionActiveChanged(bool isActive) { - showLockWidget(); - screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER | SCREEN_LOCK); - qDebug() << "showScreensaver - screenStatus: " << screenStatus; + if (lockWidget) { + lockWidget->onSessionActiveChanged(isActive); + } +} - for(auto screen : QGuiApplication::screens()) - { - ScreenSaver *saver = configuration->getScreensaver(); - saver->mode = SaverMode(SAVER_BLANK_ONLY); - ScreenSaverWidget *saverWidget = new ScreenSaverWidget(saver, this); - widgetXScreensaverList.push_back(saverWidget); - saverWidget->setGeometry(screen->geometry()); - } - setCursor(Qt::BlankCursor); - isBlank = true; +void FullBackgroundWidget::delayLockScreen() +{ + if (!m_timerLock) { + m_timerLock = new QTimer(this); + connect(m_timerLock, &QTimer::timeout, this, &FullBackgroundWidget::onLockScreenTimeout); + } + qDebug()<<"LockTimeout:"<locktimeout(); + if (configuration->locktimeout() != -1) { + stopDelayLockScreen(); + m_timerLock->start(configuration->locktimeout()*1000); + } +} + +void FullBackgroundWidget::stopDelayLockScreen() +{ + if (m_timerLock && m_timerLock->isActive()) { + m_timerLock->stop(); + } +} + +void FullBackgroundWidget::onLockScreenTimeout() +{ + qDebug()<<"onLockScreenTimeout:"<lockWhenXScreensaverActivated(); + if (configuration->lockWhenXScreensaverActivated()) { + showLock(); + } + m_timerLock->stop(); +} + +void FullBackgroundWidget::onBlankScreensaver(int nDelay/* = 0*/, bool hasLock/* = true*/) +{ + if (hasLock) { + showLockWidget(); + screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER | SCREEN_LOCK); + } else { + screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER); + } + qDebug() << "showScreensaver - screenStatus: " << screenStatus << nDelay; + + for(auto screen : QGuiApplication::screens()) + { + ScreenSaver *saver = configuration->getScreensaver(); + saver->mode = SaverMode(SAVER_BLANK_ONLY); + ScreenSaverWidget *saverWidget = new ScreenSaverWidget(saver, this); + widgetXScreensaverList.push_back(saverWidget); + saverWidget->setGeometry(screen->geometry()); + } + setCursor(Qt::BlankCursor); + isBlank = true; + + if (0 == nDelay) { + /*在进行压力测试时,可能会出现锁屏界面启动极慢,导致在睡眠之前调用了锁屏,但 + * 锁屏没来得及绑定睡眠唤醒信号,导致唤醒后,锁屏界面没有收到信号从而一直显示黑屏的问题。 + * 因此这里在进入黑色屏保时,通过后台接口,获取一次当前是否应该显示黑色屏保状态*/ + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); + QString sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum); + QDBusInterface *interface = new QDBusInterface(sessionDbus, + SS_DBUS_PATH, + SS_DBUS_INTERFACE); + if (!interface->isValid()) { + delete interface; + interface = new QDBusInterface(SS_DBUS_SERVICE, + SS_DBUS_PATH, + SS_DBUS_INTERFACE); + } + + QDBusReply stateReply = interface->call("GetBlankState"); + if(!stateReply.isValid()){ + return ; + } + + if(!stateReply){ + isBlank = false; + clearScreensavers(); + } + } else { + QTimer::singleShot(nDelay, this, [=](){ + if (isBlank) { + isBlank = false; + clearScreensavers(); + } + }); + } } void FullBackgroundWidget::onScreensaver() @@ -824,7 +1028,7 @@ void FullBackgroundWidget::onScreensaver() showScreensaver(); } -void FullBackgroundWidget::onGlobalKeyPress(const QString &key) +void FullBackgroundWidget::onGlobalKeyPress(const quint8 &key) { #ifdef USE_INTEL qDebug() << "onGlobalKeyPress " << key << "screenStatus " << screenStatus; @@ -851,10 +1055,12 @@ void FullBackgroundWidget::onGlobalKeyPress(const QString &key) // lockWidget->RecieveKey(keyValue); // } // } +#else + #endif } -void FullBackgroundWidget::onGlobalKeyRelease(const QString &key) +void FullBackgroundWidget::onGlobalKeyRelease(int key) { // if(key == "Caps_Lock") // { @@ -899,17 +1105,40 @@ void FullBackgroundWidget::onGlobalKeyRelease(const QString &key) // 键盘上的num_lock生效、不需要登录界面进行管理 } #else - if(key == "Escape" && screenStatus == SCREEN_LOCK) - { - bool canShow = true; - if (lockWidget && !lockWidget->exitSubWidget()) - canShow = false; - if (canShow) - showScreensaver(); - } - else if(screenStatus & SCREEN_SAVER && !isBlank) - { - clearScreensavers(); + if (QX11Info::isPlatformX11()) { + if (key == 65) { // "Space" + if (lockWidget && lockWidget->isVisible()) {/*keyReleaseEvent有时候监听不到Space的按键事件 原因未知 + 把Space按键放到nativeEventFilter里面*/ + lockWidget->key_enter_release(Qt::Key_Space); + } + } + if (key == 9 && screenStatus == SCREEN_LOCK) { // "escape" + bool canShow = true; + if (lockWidget && !lockWidget->exitSubWidget()) + canShow = false; + if (configuration && configuration->idledelay() == -1) + canShow = false; + if (!m_isAlreadyShowSaver) + canShow = false; + if (canShow) + showScreensaver(); + } else if (screenStatus & SCREEN_SAVER && !isBlank) { + clearScreensavers(); + } + } else { + if (key == Qt::Key_Escape && screenStatus == SCREEN_LOCK) { // "escape" + bool canShow = true; + if (lockWidget && !lockWidget->exitSubWidget()) + canShow = false; + if (configuration && configuration->idledelay() == -1) + canShow = false; + if (!m_isAlreadyShowSaver) + canShow = false; + if (canShow) + showScreensaver(); + } else if (screenStatus & SCREEN_SAVER && !isBlank) { + clearScreensavers(); + } } #endif } @@ -1008,7 +1237,7 @@ void FullBackgroundWidget::onDesktopResized() QDesktopWidget *desktop = QApplication::desktop(); setGeometry(desktop->geometry()); if(lockWidget) - onCursorMoved(QCursor::pos()); + onCursorMoved(QCursor::pos()); if(screenStatus & SCREEN_SAVER) { clearScreensavers(); @@ -1016,6 +1245,10 @@ void FullBackgroundWidget::onDesktopResized() //repaint(); update(); #endif + +// if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland" && !QX11Info::isPlatformX11() ) { +// PlasmaShellManager::getInstance()->setPos(this->windowHandle(),QPoint(0,0)); +// } } void FullBackgroundWidget::laterInhibit(bool val) @@ -1038,6 +1271,7 @@ void FullBackgroundWidget::onPrepareForSleep(bool sleep) { ///系统休眠时,会关闭总线,导致设备不可用,发生错误 ///在系统休眠之前停止认证,在系统唤醒后重新开始认证 + qDebug()<<"onPrepareForSleep:"< FullBackgroundWidget::GetSubWndIds() +{ + return m_listWndIds; +} + +void FullBackgroundWidget::raiseOtherWnd() +{ + //qDebug()<<"raiseOtherWnd----:"<isValid()){ + qWarning()<<"org.ukui.KWin.MultitaskView interface error!"; + return false; + } + return true; +} + +bool FullBackgroundWidget::isMultiviewHidden() +{ + if (initMultiviewDbus()) { + QDBusReply reply = m_dbusIfMultiview->call("isHidden"); + if(!reply.isValid()) { + qWarning() << "isHidden error:" << reply.error(); + return true; + } + return reply.value(); + } + return true; +} + +void FullBackgroundWidget::HideMultiview() +{ + if (initMultiviewDbus()) { + QDBusMessage result = m_dbusIfMultiview->call("hide"); + if(result.type() == QDBusMessage::ErrorMessage) { + qWarning() << "HideMultiview error:" << result.errorMessage(); + } + } +} + +void FullBackgroundWidget::ShowMultiview() +{ + if (initMultiviewDbus()) { + QDBusMessage result = m_dbusIfMultiview->call("show"); + if(result.type() == QDBusMessage::ErrorMessage) { + qWarning() << "HideMultiview error:" << result.errorMessage(); + } + } +} diff --git a/src/fullbackgroundwidget.h b/src/fullbackgroundwidget.h index 991e2be..e960415 100644 --- a/src/fullbackgroundwidget.h +++ b/src/fullbackgroundwidget.h @@ -52,16 +52,22 @@ public: void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); void onScreensaver(); - void onBlankScreensaver(); + void onBlankScreensaver(int nDelay = 0, bool hasLock = true); void closeScreensaver(); void setIsStartup(bool val); + int RegisteSubWnd(quint64 uWndId); + int UnRegisteSubWnd(quint64 uWndId); + QList GetSubWndIds(); + bool IsStartupMode(); + public Q_SLOTS: void onCursorMoved(const QPoint &pos); void lock(); void showLockWidget(); void showLock(); - void showScreensaver(); + void showScreensaver(bool isPreview = false); + void onSecondRunParam(QString strParam); int onSessionStatusChanged(uint status); void inhibit(); void uninhibit(); @@ -69,6 +75,11 @@ public Q_SLOTS: void propertiesChangedSlot(QString, QMap, QStringList); void onShowBlackBackGround(); #endif + void onSessionActiveChanged(bool isActive); + +Q_SIGNALS: + void StartupModeChanged(bool isStartup); + private: void init(); void clearScreensavers(); @@ -77,24 +88,31 @@ private: QPixmap getPaddingPixmap(QPixmap pixmap, int width, int height); // void checkNumLock(); // int numberMatch(const QString &key); + void raiseOtherWnd(); + bool isOtherWnd(int wndId); + void delayLockScreen(); + void stopDelayLockScreen(); + bool initMultiviewDbus(); + bool isMultiviewHidden(); + void HideMultiview(); + void ShowMultiview(); private Q_SLOTS: void onScreenCountChanged(int); void onDesktopResized(); - void onGlobalKeyPress(const QString &key); - void onGlobalKeyRelease(const QString &key); + void onGlobalKeyPress(const quint8 &key); + void onGlobalKeyRelease(int key); void onGlobalButtonDrag(int xPos, int yPos); void onGlobalButtonPressed(int xPos, int yPos); void onPrepareForSleep(bool sleep); void switchToLinux(); void laterActivate(); + void laterOtherActivate(); void setLockState(); void killWindow(); void laterInhibit(bool val); void laterStartAuth(); - void onConfigurationDelayChanged(QString key); - void onConfigurationLockChanged(QString key); -// void lockEnabledChanged(QString key); + void onLockScreenTimeout(); private: QDBusInterface *smInterface; @@ -117,15 +135,18 @@ private: bool isPassed; bool m_delay; int isBlank; - QGSettings *settings_delay; - QGSettings *settings_lock; - QGSettings *lockEnabled_Key; QProcess *process = nullptr; - int idleDelay; - int idleLock; bool lockEnabled; bool isStartup = false; QFuture future; + + // 上层窗口管理 + QList m_listWndIds; + QTimer *m_timerLock = nullptr; + bool m_isAlreadyShowSaver = false; + + // 多任务视图接口 + QDBusInterface *m_dbusIfMultiview = nullptr; }; #endif // FULLBACKGROUNDWIDGET_H diff --git a/src/grab-x11.cpp b/src/grab-x11.cpp index a03d14d..9182cab 100644 --- a/src/grab-x11.cpp +++ b/src/grab-x11.cpp @@ -17,8 +17,19 @@ **/ #include "grab-x11.h" #include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include + +#define MAX_PROPERTY_VALUE_LEN 4096 class XServerGraber{ public: @@ -41,7 +52,7 @@ static bool grabKeyboard() static bool grabMouse() { #define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ - EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask + EnterWindowMask | LeaveWindowMask int rv = XGrabPointer(QX11Info::display(), QX11Info::appRootWindow(), True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); @@ -59,25 +70,179 @@ bool establishGrab() if(!grabKeyboard()) return false; - + +/*抓取鼠标会导致触摸无效,这里暂时取消掉*/ +/* if(!grabMouse()) { XUngrabKeyboard(QX11Info::display(), CurrentTime); XFlush(QX11Info::display()); return false; } - +*/ return true; } bool closeGrab() { - XSync(QX11Info::display(), False); + //XSync(QX11Info::display(), False); XServerGraber xserverGraber; Q_UNUSED(xserverGraber); XUngrabKeyboard(QX11Info::display(), CurrentTime); - XUngrabPointer(QX11Info::display(), CurrentTime); +// XUngrabPointer(QX11Info::display(), CurrentTime); XFlush(QX11Info::display()); return true; } + +static Bool +Window_Has_Property(Display * dpy, Window win, Atom atom) +{ + Atom type_ret; + int format_ret; + unsigned char *prop_ret; + unsigned long bytes_after, num_ret; + + type_ret = None; + prop_ret = NULL; + XGetWindowProperty(dpy, win, atom, 0, 0, False, AnyPropertyType, + &type_ret, &format_ret, &num_ret, + &bytes_after, &prop_ret); + if (prop_ret) + XFree(prop_ret); + + return (type_ret != None) ? True : False; +} + +int getWindowByPid(Window win){ + int ret = -1; + + Atom xa_ret_type; + int ret_format; + unsigned long ret_nitems; + unsigned long ret_bytes_after; + unsigned long tmp_size; + unsigned char *ret_prop; + int id = 0; + + + Atom xa_prop_name = XInternAtom(QX11Info::display(), "_NET_WM_PID", False); // 取对应字串的AtomID + + if (XGetWindowProperty(QX11Info::display(), win, xa_prop_name, 0, // 获取窗口属性 + MAX_PROPERTY_VALUE_LEN / 4, + False, XA_CARDINAL, &xa_ret_type, // XA_CARDINAL为数值类型 + &ret_format, &ret_nitems, &ret_bytes_after, + &ret_prop) != Success) // 后五个参数是返回值 + { + printf("Cannot get %s property.\n", "_NET_WM_PID"); + return -1; + } + else + { + if(ret_prop) + memcpy(&id, ret_prop, 4);// 类型传换 + qDebug()<<"window pid: "< diff --git a/src/hoverwidget.h b/src/hoverwidget.h index bcb811e..1fcf667 100644 --- a/src/hoverwidget.h +++ b/src/hoverwidget.h @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #ifndef HOVERWIDGET_H #define HOVERWIDGET_H diff --git a/src/iconedit.cpp b/src/iconedit.cpp index a620826..3e573fd 100644 --- a/src/iconedit.cpp +++ b/src/iconedit.cpp @@ -1,9 +1,9 @@ -/* iconedit.cpp +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,12 +12,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #include "iconedit.h" #include "imageutil.h" +#include "configuration.h" #include #include #include @@ -26,10 +26,12 @@ #include #include #include +#include #include #include #include +#define DRM_DIR "/sys/class/leds/" #define GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD "org.ukui.peripherals-keyboard" #define CAPSLOCK_STATUS "capslock_state" @@ -37,56 +39,97 @@ * @brief 判断大写键状态 * @return true: 大写锁定 */ -//bool checkCapsLockState() -//{ -// bool capsState = false; -// unsigned int n; -// XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &n); -// capsState = (n & 0x01) == 1; +bool checkCapsLockState() +{ + QDir ledDir(DRM_DIR); + QStringList leds = ledDir.entryList(QDir::Dirs); + QString capsFile; -// return capsState; -//} + for(int i = 0;igetFontSize(); + m_ptToPx = configuration->getPtToPx(); m_edit = new QLineEdit(this); m_edit->setObjectName(QStringLiteral("passwdEdit")); m_edit->setAttribute(Qt::WA_InputMethodEnabled, false); //禁用输入法 m_edit->setContextMenuPolicy(Qt::NoContextMenu); //禁用右键菜单 m_edit->installEventFilter(this); + QFont sysFont; + sysFont.setPointSize((16 + curFontSize) *m_ptToPx); + m_edit->setFont(sysFont); m_capsIcon = new QSvgWidget(this); m_capsIcon->setObjectName(QStringLiteral("capsIconLabel")); - settings = new QGSettings(GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD, "", this); - connect(settings, &QGSettings::changed, + + if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland"){ + capsState = checkCapsLockState(); + }else{ + settings = new QGSettings(GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD, "", this); + connect(settings, &QGSettings::changed, this, &IconEdit::onCapsChanged); - capsState = settings->get("capslock-state").toBool(); + capsState = settings->get("capslock-state").toBool(); + } + m_capsIcon->setVisible(capsState); m_capsIcon->load(QString(":/image/assets/capslock.svg")); m_iconButton = new QPushButton(this); + m_iconButton->setFixedSize(24, 24); + m_iconButton->setIconSize(QSize(24, 24)); m_iconButton->setObjectName(QStringLiteral("loginButton")); - m_iconButton->setFocusPolicy(Qt::NoFocus); m_iconButton->setCursor(QCursor(Qt::PointingHandCursor)); m_iconButton->installEventFilter(this); + m_iconButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); + m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #3D6BE5;"); - m_modeButton = new QPushButton(this); + m_modeButton = new ModeButton(this); m_modeButton->setObjectName(QStringLiteral("echoModeButton")); - m_modeButton->setCheckable(true); m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic")); - m_modeButton->setFocusPolicy(Qt::NoFocus); + m_modeButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); m_modeButton->setCursor(Qt::PointingHandCursor); m_modeButton->installEventFilter(this); - connect(m_modeButton, &QPushButton::clicked, this, [&](bool checked){ - setType(checked ? QLineEdit::Normal : QLineEdit::Password); + m_modeButton->setFixedSize(24, 14); + m_modeButton->setIconSize(QSize(16, 16)); + m_modeButton->setFlat(true); + connect(m_modeButton, &QPushButton::clicked, this, [=](){ + if (m_edit->echoMode() == QLineEdit::Password) { + setType(QLineEdit::Normal); + } else { + setType(QLineEdit::Password); + } }); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(1, 1, 8, 1); - layout->setSpacing(0); + layout->setSpacing(2); layout->addStretch(); layout->addWidget(m_capsIcon); layout->addWidget(m_modeButton); @@ -114,15 +157,26 @@ bool IconEdit::eventFilter(QObject *obj, QEvent *event) } if(event->type() == 2) { + setFocusin(0); Q_EMIT clickedPassword(true); } if(event->type() == 23) { - XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + if(QX11Info::isPlatformX11()){ + //XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } update(); }else if(event->type() == QEvent::MouseButtonPress){ - XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + if(QX11Info::isPlatformX11()){ + //XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } update(); + } else if(event->type() == QEvent::MouseButtonRelease) { //禁用鼠标中键 + QMouseEvent *mouseevent = static_cast(event); + if(mouseevent->button() == Qt::MidButton){ + event->ignore(); + return true; + } } } if(obj == m_iconButton){ @@ -132,18 +186,14 @@ bool IconEdit::eventFilter(QObject *obj, QEvent *event) } if(event->type() == 2) { + setFocusin(0); Q_EMIT clickedPassword(true); } - if(event->type() == QEvent::HoverEnter){ - setIcon(QIcon(":/image/assets/login-button-hover.svg")); - } - else if(event->type() == QEvent::HoverLeave){ - setIcon(QIcon(":/image/assets/login-button.svg")); - } } if(obj == m_modeButton){ if(event->type() == 2) { + setFocusin(0); Q_EMIT clickedPassword(true); } } @@ -153,31 +203,54 @@ bool IconEdit::eventFilter(QObject *obj, QEvent *event) void IconEdit::setType(QLineEdit::EchoMode type) { m_edit->setEchoMode(type); - if(type == 0){ - m_modeButton->setChecked(true); + if (type == 0) { m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic")); - } - else{ - m_modeButton->setChecked(false); + } else { m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic")); } } +void IconEdit::setModeBtnVisible(bool visible) +{ + m_modeButton->setVisible(visible); +} + void IconEdit::resizeEvent(QResizeEvent *) { // 设置输入框中文件输入区,不让输入的文字在被隐藏在按钮下 int w = m_iconButton->width() + m_modeButton->width(); - m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 8 : w, 1); + m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 10 : w + 6, 1); m_edit->setFixedSize(size()); } void IconEdit::setX11Focus() { - XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + if(QX11Info::isPlatformX11()){ + //XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } update(); } +void IconEdit::setFocusin(int target) +{ + switch (target) { + case 0: + m_edit->setFocus(); + m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #3D6BE5;"); + break; + case 1: + m_edit->clearFocus(); + m_iconButton->setFocus(); + m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #000000;"); + break; + default: + m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #3D6BE5;"); + m_edit->clearFocus(); + break; + } +} + void IconEdit::clicked_cb() { startWaiting(); @@ -186,17 +259,23 @@ void IconEdit::clicked_cb() void IconEdit::onCapsChanged() { - capsState = settings->get("capslock-state").toBool(); + if(settings){ + capsState = settings->get("capslock-state").toBool(); + }else{ + capsState = checkCapsLockState(); + } m_capsIcon->setVisible(capsState); int w = m_iconButton->width() + m_modeButton->width(); - m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 8 : w, 1); + m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 10 : w + 6, 1); } -//void IconEdit::onCapsStateChanged() -//{ -// bool capsState = m_capsIcon->isHidden(); - -//} +void IconEdit::onCapsStateChanged() +{ + capsState = checkCapsLockState(); + m_capsIcon->setVisible(capsState); + int w = m_iconButton->width() + m_modeButton->width(); + m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 10 : w + 6, 1); +} void IconEdit::setIcon(const QString &text) { @@ -209,6 +288,7 @@ void IconEdit::setIcon(const QString &text) void IconEdit::setIcon(const QIcon &icon) { m_iconButton->setIcon(icon); + m_iconButton->setIconSize(QSize(12,12)); m_iconButton->setText(""); m_icon = icon; m_iconText = ""; @@ -268,9 +348,10 @@ void IconEdit::startWaiting() // m_waitingPixmap = ImageUtil::loadSvg(":/image/assets/ukui-loginopt-face.svg", "white", 24); // m_iconButton->setIcon(QIcon(m_waitingPixmap)); - QPixmap icon = QIcon::fromTheme("ukui-loading-symbolic-0").pixmap(16,16); + QPixmap icon = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(16,16); m_waitingPixmap = ImageUtil::drawSymbolicColoredPixmap(icon, "white"); m_iconButton->setIcon(m_waitingPixmap); + m_iconButton->setIconSize(QSize(16,16)); m_timer->start(); } @@ -284,8 +365,10 @@ void IconEdit::stopWaiting() m_iconButton->setAttribute(Qt::WA_TransparentForMouseEvents, false); m_edit->setReadOnly(false); //m_iconButton->setEnabled(true); - if(!m_icon.isNull()) + if(!m_icon.isNull()) { m_iconButton->setIcon(m_icon); + m_iconButton->setIconSize(QSize(12,12)); + } else m_iconButton->setText(m_iconText); } @@ -298,6 +381,7 @@ void IconEdit::updatePixmap() matrix.rotate(90.0); m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation); m_iconButton->setIcon(QIcon(m_waitingPixmap)); + m_iconButton->setIconSize(QSize(16, 16)); } /* void IconEdit::setCapsState(bool capsState) diff --git a/src/iconedit.h b/src/iconedit.h index 7a66db7..f067a3e 100644 --- a/src/iconedit.h +++ b/src/iconedit.h @@ -1,9 +1,9 @@ -/* iconedit.h +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef ICONEDIT_H @@ -27,6 +26,9 @@ #include #include #include +#include "modebutton.h" + +class Configuration; class IconEdit : public QWidget { @@ -44,8 +46,10 @@ public: void startWaiting(); void stopWaiting(); void setX11Focus(); + void setFocusin(int target); void readOnly(bool enabled); void setLocked(bool lock); + void setModeBtnVisible(bool visible); //void setEnabled(bool enabled); protected: @@ -62,19 +66,22 @@ Q_SIGNALS: public Q_SLOTS: void clicked_cb(); void onCapsChanged(); -// void onCapsStateChanged(); + void onCapsStateChanged(); private: QLineEdit *m_edit; QSvgWidget *m_capsIcon; QPushButton *m_iconButton; - QPushButton *m_modeButton; + ModeButton *m_modeButton; QTimer *m_timer; QPixmap m_waitingPixmap; QString m_iconText; //文字作为图标 QIcon m_icon; - QGSettings *settings; - bool capsState = false; + QGSettings *settings; + bool capsState = false; + Configuration *configuration; + double curFontSize = 0; + double m_ptToPx = 1.0; }; #endif // ICONEDIT_H diff --git a/src/imageutil.cpp b/src/imageutil.cpp index 928d63f..11fe92f 100644 --- a/src/imageutil.cpp +++ b/src/imageutil.cpp @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #include "imageutil.h" diff --git a/src/imageutil.h b/src/imageutil.h index 92c09d8..ae40c46 100644 --- a/src/imageutil.h +++ b/src/imageutil.h @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 3, or (at your option) + * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,10 +12,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see . * - */ +**/ #ifndef IMAGEUTIL_H #define IMAGEUTIL_H diff --git a/src/interface.cpp b/src/interface.cpp index 12d5b60..d188ebf 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -24,12 +24,15 @@ #include #include #include +#include #include +#include +#include +#include Interface::Interface(QObject *parent) : QObject(parent), m_timerCount(0), - settings(nullptr), m_timer(nullptr) { lockState = false; @@ -51,10 +54,12 @@ Interface::Interface(QObject *parent) connect(&process, static_cast(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus){ + qInfo()<<"ukui-screensaver-dialog is exited,exitCode is "<get("sleep-activation-enabled").toBool()){ + if (!checkStatus(SESSION_STATUS_SLEEPED)) { + uninhibit(); + return; + } + + if (checkScreenDialogRunning()) { uninhibit(); return; } @@ -204,9 +315,10 @@ void Interface::onPrepareForSleep(bool sleep) return; } + blankState = true; this->onShowBlankScreensaver(); - if(!m_timer){ + if(!m_timer){ m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, this, [&]{ m_timerCount+=1; @@ -222,10 +334,55 @@ void Interface::onPrepareForSleep(bool sleep) } else { + m_nStatus &= ~SESSION_STATUS_SLEEPED; + blankState = false; inhibit(); } } +void Interface::onSessionIdleExit() +{ + qDebug()<<"onSessionIdleExit--------"; + m_nStatus &= ~SESSION_STATUS_SCREENSAVER; + m_nStatus &= ~SESSION_STATUS_SCREENCLOSE; + stopDelayLockScreen(); +} + +void Interface::onScreenClosed(bool state) +{ + qDebug()<<"onScreenClosed:"<isLidCloseWithBlank()) { + m_nStatus &= ~SESSION_STATUS_SCREENCLOSE; + } + stopDelayLockScreen(); + } +} + void Interface::ShowScreensaver() { if(process.state() != QProcess::NotRunning) @@ -269,3 +426,135 @@ void Interface::uninhibit() m_inhibitFileDescriptor = QDBusUnixFileDescriptor(); } + +bool Interface::checkStatus(int nStatus) +{ + if (!m_sessionWatcher) { + return false; + } + switch (nStatus) { + case SESSION_STATUS_SLEEPED: + { + m_nStatus |= nStatus; + if (!m_sessionWatcher->isSleepActivationEnable()) { + return false; + } + } + break; + case SESSION_STATUS_SCREENCLOSE: + { + m_nStatus |= nStatus; + if ((m_nStatus&SESSION_STATUS_SLEEPED) || !m_sessionWatcher->isCloseActivationEnable()) { + return false; + } + if (((m_sessionWatcher->closeActivationDelay() == m_sessionWatcher->sleepActivationDelay()) + && m_sessionWatcher->sleepActivationDelay() != -1) && !m_sessionWatcher->isSleepActivationEnable()) { + qDebug()<<"Sleep same with Close and Sleep disable!"; + return false; + } + } + break; + case SESSION_STATUS_SCREENSAVER: + { + m_nStatus |= nStatus; + if ((m_nStatus&SESSION_STATUS_SLEEPED) || (m_nStatus&SESSION_STATUS_SCREENCLOSE)) { + return false; + } + if (((m_sessionWatcher->idledelay()*60 == m_sessionWatcher->sleepActivationDelay()) + && m_sessionWatcher->sleepActivationDelay() != -1) && !m_sessionWatcher->isSleepActivationEnable()) { + qDebug()<<"Sleep same with idle and Sleep disable!"; + return false; + } + if (((m_sessionWatcher->idledelay()*60 == m_sessionWatcher->closeActivationDelay()) + && m_sessionWatcher->closeActivationDelay() != -1)/* && !m_sessionWatcher->isCloseActivationEnable()*/) { + qDebug()<<"Close same with idle do nothing!"; + return false; + } + } + break; + default: + return false; + } + return true; +} + +bool Interface::LockByBlank(int nType) // 0:idle delay close;1:lid close;2:lowpower close +{ + qDebug()<<"LockByBlank:"<closeActivationDelay(); + int nIdleDelay = m_sessionWatcher->idledelay(); + bool isCloseActive = m_sessionWatcher->isCloseActivationEnable(); + qDebug()<<"DelayState:"<isLockEnable()) { // 仅启动屏保 + isNeedLock = false; + } + } else { + return false; + } + } else { + qDebug()<<"Don't need blank lock:"<locktimeout() != -1 && isNeedLock) { + delayLockScreen(); + return false; + } else { + QString cmd = QString("/usr/bin/ukui-screensaver-dialog --blank --delay %1 --has-lock %2").arg(2000).arg(isNeedLock?1:0); + qDebug() << cmd; + process.start(cmd); + emitLockState(true); + } + return true; + } +} + +void Interface::delayLockScreen() +{ + if (!m_timerLock) { + m_timerLock = new QTimer(this); + connect(m_timerLock, &QTimer::timeout, this, &Interface::onLockScreenTimeout); + } + qDebug()<<"LockTimeout:"<locktimeout(); + if (m_sessionWatcher->locktimeout() != -1) { + stopDelayLockScreen(); + m_timerLock->start(m_sessionWatcher->locktimeout()*1000); + } +} + +void Interface::stopDelayLockScreen() +{ + if (m_timerLock && m_timerLock->isActive()) { + m_timerLock->stop(); + } +} + +void Interface::onLockScreenTimeout() +{ + Lock(); + m_timerLock->stop(); +} diff --git a/src/interface.h b/src/interface.h index 411ce5c..8b228ae 100644 --- a/src/interface.h +++ b/src/interface.h @@ -25,6 +25,7 @@ #include #include "types.h" #include "logind.h" +#include "sessionwatcher.h" class QGSettings; class Interface : public QObject, protected QDBusContext @@ -34,10 +35,13 @@ class Interface : public QObject, protected QDBusContext Q_CLASSINFO("D-Bus Interface", SS_DBUS_SERVICE) public: + enum { + SESSION_STATUS_SCREENSAVER = 1, // 屏保 + SESSION_STATUS_SCREENCLOSE = 2, // 关屏 + SESSION_STATUS_SLEEPED = 4, // 休眠/睡眠 + }; explicit Interface(QObject *parent = nullptr); LogindIntegration *m_logind; -Q_SIGNALS: - void SessionIdle(); public Q_SLOTS: /** @@ -54,19 +58,43 @@ public Q_SLOTS: void onShowBlankScreensaver(); void onNameLost(const QString&); void onPrepareForSleep(bool sleep); - + bool checkScreenDialogRunning(); + void onSessionIdleExit(); + void onScreenClosed(bool state); + void onLidStateChaned(bool isClosed); + bool GetBlankState(); + bool LockByBlank(int nType); + private: bool checkExistChild(); void inhibit(); void uninhibit(); + void emitLockState(bool); + bool checkStatus(int nStatus); + /** + * @brief delayLockScreen 延迟锁屏 + */ + void delayLockScreen(); + /** + * @brief stopDelayLockScreen 停止延迟锁屏 + */ + void stopDelayLockScreen(); + /** + * @brief onLockScreenTimeout 延迟锁屏处理过程 + */ + void onLockScreenTimeout(); + +private: bool lockState; bool slpState; - void emitLockState(bool); int m_timerCount; - QGSettings *settings; + SessionWatcher *m_sessionWatcher = nullptr; QTimer *m_timer; QDBusUnixFileDescriptor m_inhibitFileDescriptor; - + int m_nStatus = 0; // 当前状态 + bool blankState = false; + bool m_isNewBlankInterface = false; + QTimer *m_timerLock = nullptr; private: QProcess process; }; diff --git a/src/klabel.cpp b/src/klabel.cpp new file mode 100644 index 0000000..ad19dd3 --- /dev/null +++ b/src/klabel.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "klabel.h" +#include "configuration.h" +#include "commonfunc.h" +#include +#include +#include + +KLabel::KLabel(QWidget *parent) + : QLabel(parent), + configuration(Configuration::instance()) +{ + curFontSize = configuration->getFontSize(); + m_ptToPx = configuration->getPtToPx(); + this->setStyleSheet("QLabel{color: white;}" + "QToolTip{border-radius:4px; background-color:#FFFFFF; color:black;}"); +} + +void KLabel::setFontSize(int fontSize) +{ + sysFont.setPointSize((fontSize +curFontSize) *m_ptToPx); + this->setFont(sysFont); + QToolTip::setFont(sysFont); +} + +void KLabel::setElideText(const QString text, int width, int size) +{ + sysFont.setPointSize((size + curFontSize) *m_ptToPx); + QString str = ElideText(sysFont,width,text); + if(text != str) + this->setToolTip(text); + if(text == str) + this->setToolTip(""); + this->setText(str); +} diff --git a/src/klabel.h b/src/klabel.h new file mode 100644 index 0000000..c96b00b --- /dev/null +++ b/src/klabel.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef KLABEL_H +#define KLABEL_H + +#include + +class Configuration; + +class KLabel : public QLabel +{ + Q_OBJECT +public: + KLabel(QWidget *parent = nullptr); + void setFontSize(int fontSize); + void setElideText(const QString text, int width, int size = 16); + +private: + Configuration *configuration; + double curFontSize; + double m_ptToPx = 1.0; + QFont sysFont; +}; + +#endif // KLABEL_H diff --git a/src/libinputswitchevent.cpp b/src/libinputswitchevent.cpp new file mode 100644 index 0000000..de3886f --- /dev/null +++ b/src/libinputswitchevent.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "libinputswitchevent.h" + +typedef std::function sendEvent; +LibinputSwitchEvent::LibinputSwitchEvent(QObject *parent) + : QObject(parent) + , m_machineModel(MachineModel::getMachineModelInstance()) +{ + m_machineType = m_machineModel->getTheMachineType(); + sendEvent se = std::bind(&LibinputSwitchEvent::dealEvent, this, std::placeholders::_1); + m_inputGatherClient = new UKUIInputGatherClient; + m_inputGatherClient->setEventCallBack(se); + m_inputGatherClient->startToReceiveEvent(); +} + +LibinputSwitchEvent::~LibinputSwitchEvent() +{ + delete m_inputGatherClient; +} + +bool LibinputSwitchEvent::geInitDevicesStatus() +{ + //其他处理 + if (m_machineType == QStringLiteral("SLATE")) { + return true; + }else if (m_machineType == "LAPTOP" ) {//永久附加键盘笔记本 + //return true; + }else if (m_machineType == "ALLINONE") {//台式 + return false; + }else { + //0 非平板 + //1 平板 + //-1 不支持 + int status = m_inputGatherClient->libinputTabletSwitchState(); + qInfo() << __FILE__ << __LINE__<< "当前设备的状态:" << status; + if(status == 1) + return true; + else + return false; + } +} + +void LibinputSwitchEvent::dealEvent(Event* e) +{ + switch (e->type) { + case LIBINPUT_EVENT_SWITCH_TOGGLE: + qInfo() << __FILE__ << __LINE__ << "=LIBINPUT_EVENT_SWITCH_TOGGLE="; + if(e->event.switchEventDate.switchType == LIBINPUT_SWITCH_TABLET_MODE) { + qInfo() << __FILE__ << __LINE__ << "switch type" << e->event.switchEventDate.switchType; + qInfo() << __FILE__ << __LINE__ << "switch status" << e->event.switchEventDate.switchState; + if(e->event.switchEventDate.switchState == 1) { + Q_EMIT tabletModeStatusChanged(1); + }else { + Q_EMIT tabletModeStatusChanged(0); + } + } + break; + default: + break; + } +} diff --git a/src/libinputswitchevent.h b/src/libinputswitchevent.h new file mode 100644 index 0000000..95ecbe3 --- /dev/null +++ b/src/libinputswitchevent.h @@ -0,0 +1,45 @@ +/* + * Copyright 2022 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef LIBINPUTSWITCHEVENT_H +#define LIBINPUTSWITCHEVENT_H + +#include +#include +#include +#include +#include "machinemodel.h" +//头文件以及顺序不可改,不可删 +class LibinputSwitchEvent : public QObject +{ + Q_OBJECT +public: + explicit LibinputSwitchEvent(QObject *parent = nullptr); + + ~LibinputSwitchEvent(); + UKUIInputGatherClient * m_inputGatherClient = nullptr; + bool geInitDevicesStatus(); +signals: + void tabletModeStatusChanged(int tabletmode); +private: + void dealEvent(Event* e); + +private: + QString m_machineType; + std::shared_ptr m_machineModel = nullptr; +}; + +#endif // LIBINPUTSWITCHEVENT_H diff --git a/src/lockchecker.cpp b/src/lockchecker.cpp new file mode 100644 index 0000000..c0533cf --- /dev/null +++ b/src/lockchecker.cpp @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "lockchecker.h" +#include "loginedusers.h" +#include +#include +#include +#include +#include +#include +#include + +#define SYSTEMD_SERVICE "org.freedesktop.login1" +#define SYSTEMD_PATH "/org/freedesktop/login1" +#define SYSTEMD_INTERFACE "org.freedesktop.login1.Manager" + +QDBusArgument &InhibitInfo::operator<<(QDBusArgument &argument, const InhibitInfo::InhibitorInfo &mystruct) +{ + argument.beginStructure(); + argument << mystruct.name << mystruct.icon; + argument.endStructure(); + return argument; +} + +const QDBusArgument &InhibitInfo::operator>>(const QDBusArgument &argument, InhibitInfo::InhibitorInfo &mystruct) +{ + argument.beginStructure(); + argument >> mystruct.name >> mystruct.icon ; + argument.endStructure(); + return argument; +} + +LockChecker::LockChecker() +{ +} + +LockChecker::~LockChecker() +{ +} + +int LockChecker::checkLock() +{ + bool lockfile = false; + bool lockuser = false; + + QFile file_backup("/tmp/lock/kylin-backup.lock"); + QFile file_update("/tmp/lock/kylin-update.lock"); + if (file_backup.exists()) { + int fd_backup = open(QString("/tmp/lock/kylin-backup.lock").toUtf8().data(), O_RDONLY); + int b = flock(fd_backup, LOCK_EX|LOCK_NB); + qDebug() << "b" << b; + if (b < 0) { + lockfile = true; + QString file_user = getName(&file_backup); + if (file_user == qgetenv("USER")) { + lockuser = true; + } + } + file_backup.close(); + if (flock(fd_backup, LOCK_UN) == 0) { + qDebug() << "unlock sucess."; + } else { + qDebug() << "unlock fail."; + } + } + if (file_update.exists()) { + int fd_update = open(QString("/tmp/lock/kylin-update.lock").toUtf8().data(), O_RDONLY); + int c = flock(fd_update, LOCK_EX|LOCK_NB); + qDebug() << "c" << c; + if (c < 0) { + lockfile = true; + QString file_user = getName(&file_update); + if (file_user == qgetenv("USER")) { + lockuser = true; + } + } + file_backup.close(); + if (flock(fd_update, LOCK_UN) == 0) { + qDebug() << "unlock sucess."; + } else { + qDebug() << "unlock fail."; + } + } + if (lockfile) { + if(lockuser) + return 2; + return 1; + } + return 0; +} + +QStringList LockChecker::getLoginedUsers() +{ + QStringList loginedUser; + qRegisterMetaType("LoginedUsers"); + qDBusRegisterMetaType(); + QDBusInterface loginInterface(SYSTEMD_SERVICE, + SYSTEMD_PATH, + SYSTEMD_INTERFACE, + QDBusConnection::systemBus()); + + if (loginInterface.isValid()) { + qDebug() << "create interface success"; + } + + QDBusMessage result = loginInterface.call("ListUsers"); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + const QDBusArgument &dbusArgs = first.value(); + + QVector loginedUsers; + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + LoginedUsers user; + dbusArgs >> user; + loginedUsers.push_back(user); + } + dbusArgs.endArray(); + + for (LoginedUsers user : loginedUsers) { + + QDBusInterface userPertyInterface("org.freedesktop.login1", + user.objpath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + + QDBusReply reply = userPertyInterface.call("Get", "org.freedesktop.login1.User", "State"); + if (reply.isValid()) { + QString status = reply.value().toString(); + if ("closing" != status) { + loginedUser.append(user.userName); + } + } + } + return loginedUser; +} + +QVector LockChecker::listInhibitor(QString type) +{ + qDBusRegisterMetaType(); + + QVector resVec; + + QDBusInterface loginInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", + "org.gnome.SessionManager", QDBusConnection::sessionBus()); + + if (loginInterface.isValid()) { + qDebug() << "create interface success"; + } + + QDBusMessage result = loginInterface.call("ListInhibitor", QVariant(type)); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + const QDBusArgument &dbusArgs = first.value(); + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + InhibitInfo::InhibitorInfo inhibtor; + dbusArgs >> inhibtor; + resVec.push_back(inhibtor); + } + + dbusArgs.endArray(); + + return resVec; +} + +QString LockChecker::getName(QFile *a) +{ + QString user = getenv("USER"); + if (a->exists()) { + a->open(QIODevice::ReadOnly|QIODevice::Text); + QTextStream fileStream(a); + int k = 0; + while (!fileStream.atEnd()) { + QString line = fileStream.readLine(); + if (k == 0) { + QString a = line; + qDebug() << "uid="< outArgs = ret.arguments(); + QVariant first = outArgs.at(0); + const QDBusArgument &dbusArgs = first.value(); + QDBusObjectPath path; + dbusArgs.beginArray(); + int userNum = 0; + while (!dbusArgs.atEnd()) { + dbusArgs >> path; + userNum++; + } + dbusArgs.endArray(); + qDebug() << userNum; + + return userNum; +} diff --git a/src/lockchecker.h b/src/lockchecker.h new file mode 100644 index 0000000..6653850 --- /dev/null +++ b/src/lockchecker.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) Copyright 2021 KylinSoft Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#ifndef LOCKCHECKER_H +#define LOCKCHECKER_H + +#include +#include + +namespace InhibitInfo { + struct InhibitorInfo { + QString name; + QString icon; + }; + + QDBusArgument &operator<<(QDBusArgument &argument, const InhibitInfo::InhibitorInfo &mystruct); + + const QDBusArgument &operator>>(const QDBusArgument &argument, InhibitInfo::InhibitorInfo &mystruct); +} + +//struct userInfo { +// int userId; +// QString userName; +// QDBusObjectPath userPath; +//}; + +//QDBusArgument &operator <<(QDBusArgument &arg, const userInfo &usersInfo); +//const QDBusArgument &operator >>(const QDBusArgument &arg, userInfo &usersInfo); + +Q_DECLARE_METATYPE(InhibitInfo::InhibitorInfo) + +class LockChecker +{ +public: + LockChecker(); + ~LockChecker(); + +public: + static int checkLock(); + + static QStringList getLoginedUsers(); + +// static QVector getInhibitors(); + static QVector listInhibitor(QString type); + +// static bool isSleepBlocked(); + +// static bool isShutdownBlocked(); + +// static void getSleepInhibitors(QStringList &sleepInhibitors, QStringList &sleepInhibitorsReason); + +// static void getShutdownInhibitors(QStringList &shutdownInhibitors, QStringList &shutdownInhibitorsReason); + + static int getCachedUsers(); + +private: + static QString getName(QFile *a); +}; + +#endif // LOCKCHECKER_H diff --git a/src/lockwidget.cpp b/src/lockwidget.cpp index 19678ae..9949706 100644 --- a/src/lockwidget.cpp +++ b/src/lockwidget.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -32,30 +34,46 @@ #include #include #include -#include -#include +#include #include #include "authdialog.h" -#include "virtualkeyboard.h" +#include "virtualkeyboardwidget.h" +#include "configuration.h" #include "users.h" #include "displaymanager.h" #include "config.h" #include "commonfunc.h" #include "hoverwidget.h" #include "kylinnm.h" +#include "mytabwidget.h" +#include "klabel.h" +#include "rootWindowBackground.h" +#include "configuration.h" #include #include #include +#define GSETTINGS_SCHEMA_MATE_BG "org.mate.background" +#define KEY_PICTURE_FILENAME "pictureFilename" +#define KEY_PICTURE_OPTIONS "pictureOptions" +#define KEY_PRIMARY_COLOR "primaryColor" #define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" #define CONFIG_FILE "/etc/lightdm/ukui-greeter.conf" +#define ON_TAB_SHEET_WIDGET "#widgetNetworkManager{background-color: rgba(255,255,255,15%); border-radius: 4px; border: 2px solid #2C73C8;}" +#define ON_NORMAL_SHEET_WIDGET "#widgetNetworkManager{text-align:center;color: rgba(255, 255, 255, 255);border: none;border-radius: 4px;outline: none;}" +#define ON_TAB_SHEET "QPushButton{background-color: rgba(255,255,255,15%); border-radius: 4px; border: 2px solid #2C73C8;}" +#define ON_NORMAL_SHEET "QPushButton{text-align:center;color: rgba(255, 255, 255, 255);border: none;border-radius: 4px;outline: none;} \ + QPushButton::hover{background-color: rgba(255,255,255,15%);} \ + QPushButton::pressed {background-color: rgba(255,255,255,40%);}\ + QPushButton::checked {background-color: rgba(255, 255, 255, 40%);}" float scale; LockWidget::LockWidget(QWidget *parent) : QWidget(parent), ui(new Ui::LockWidget), usersMenu(nullptr), scrollArea(nullptr), + configuration(Configuration::instance()), users(new Users(this)), displayManager(new DisplayManager(this)), timeType(24), @@ -65,33 +83,40 @@ LockWidget::LockWidget(QWidget *parent) ui->setupUi(this); // m_kylinNM->installEventFilter(this); + if(users->getUsers().count() < 2){ + ui->btnSwitchUser->hide(); + } UserItem user = users->getUserByName(getenv("USER")); authDialog = new AuthDialog(user, this); authDialog->installEventFilter(this); connect(authDialog, &AuthDialog::authenticateCompete, - this, &LockWidget::closed); + this, &LockWidget::onAuthenticateCompete); connect(authDialog,&AuthDialog::clickPassword, - this,&LockWidget::hideNetManager); + this,&LockWidget::onClickPassword); + connect(authDialog,&AuthDialog::loginOptionClicked, + this,&LockWidget::resetNavigation); + connect(authDialog,&AuthDialog::showMessageBtn, + this,&LockWidget::onShowMessageBtn); // connect(this, &LockWidget::capsLockChanged, // authDialog, &AuthDialog::onCapsLockChanged); -// connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){ -// updateNetIcon(m_kylinNM->getConnectStatus()); -// }); - - xEventMonitor = new XEventMonitor(this); - connect(xEventMonitor, SIGNAL(keyPress(const QString &)), this, - SLOT(onGlobalKeyPress(const QString &))); - connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), this, - SLOT(onGlobalkeyRelease(const QString &))); - xEventMonitor->start(); - + curFontSize = configuration->getFontSize(); this->installEventFilter(this); initUI(); if(users->getUsers().count() < 2){ + is_switchBtn = false; ui->btnSwitchUser->hide(); } + + if(horAT != KEYBOARDBTN) { + if(is_batteryBtn) + horAT = BATTERYBTN; + else if(!is_batteryBtn && is_switchBtn) + horAT = SWITCHBTN; + else + horAT = NETWORKBTN; + } } LockWidget::~LockWidget() @@ -103,28 +128,59 @@ void LockWidget::closeEvent(QCloseEvent *event) { qDebug() << "LockWidget::closeEvent"; authDialog->close(); + return QWidget::closeEvent(event); } bool LockWidget::eventFilter(QObject *obj, QEvent *event) { - if (obj == m_kylinNM) - return true; - if(event->type() == 2){ - if(obj == ui->btnPowerManager || obj == ui->btnSwitchUser || obj == ui->btnNetworkManager) - return false; + if(obj == mkylinNM) + return true; - if(scrollArea && scrollArea->isVisible()){ - scrollArea->hide(); - } - if(powermanager && powermanager->isVisible()){ - authDialog->setFocus(); - authDialog->show(); - powermanager->hide(); + if(vKeyboard && obj == vKeyboard) + return true; + + if (vKeyboard && obj != vKeyboard && obj != ui->btnKeyboard && obj != btnNetworkManager && obj != ui->btnPowerManager && vKeyboard->isVisible()) { + hideBottomPlugins(); } - if(m_kylinNM && m_kylinNM->isVisible()){ - m_kylinNM->hide(); + + if(obj == ui->btnPowerManager || obj == ui->btnSwitchUser || obj == btnNetworkManager || obj == ui->btnBatteryStatus || obj == ui->btnKeyboard) { + authDialog->setFocusin(REMOVE); + return false; + } + + if(tabAt != LINEEDIT) { + authDialog->setFocusin(REMOVE); + if(tabAt == BOTTMBTN) { + tabAt = LINEEDIT; + setBottomBtnSheet(); + tabAt = BOTTMBTN; + } + } + + if(mBatteryWidget && mBatteryWidget->isVisible()) { + setCheckedSheet(BATTERYBTN, false); + at_plugins = false; + } + + if(scrollArea && scrollArea->isVisible()) { + setCheckedSheet(SWITCHBTN,false); + at_plugins = false; + } + + if(vKeyboard && vKeyboard->isVisible()) { + vKeyboard->hide(); + at_plugins = false; + } + + if(m_kylinNM && m_kylinNM->isVisible()) { + setCheckedSheet(NETWORKBTN, false); + at_plugins = false; + } + + if(powermanager && powermanager->isVisible()){ + showPowerManager(); } } @@ -134,52 +190,392 @@ bool LockWidget::eventFilter(QObject *obj, QEvent *event) //qDebug()<<"````````````````````````````````````````````"<type(); } } - - if(event->type() == QEvent::WindowActivate){ - if(!isNetFinished){ - isNetFinished = true; - QTimer::singleShot(2000, this, [=](){ - m_kylinNM = new KylinNM(this); - m_kylinNM->installEventFilter(this); - connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){ - updateNetIcon(m_kylinNM->getConnectStatus()); - }); - m_kylinNM->hide(); - QtConcurrent::run([=](){ - updateNetIcon(getNetStatus()); - }); - }); - } - } - return false; } -void LockWidget::onGlobalKeyPress(const QString &key) +void LockWidget::setStartupMode(bool mode) { -} - -void LockWidget::onGlobalkeyRelease(const QString &key) -{ - if (key == "Escape") { - - } else if (key == "Up" || key == "Down" || key == "Return" || key == "KP_Enter") { - qDebug()<<" key = "<isVisible()) - keyBdRelease(key); + m_isStartupMode = mode; + if (powermanager) { + powermanager->setStartupMode(m_isStartupMode); + } + if (m_isStartupMode) { + m_futureLoadDeskBg = QtConcurrent::run([=](){ + setRootWindow(); + }); } } -void LockWidget::keyBdRelease(QString key) +void LockWidget::key_enter_release(int key) +{ + if (tabAt == BOTTMBTN) { + switch (horAT) { + case BATTERYBTN: + showBattery(); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + break; + case SWITCHBTN: + if(scrollArea && scrollArea->isVisible()) { + SwitchToUser(list.at(nowAt)->objectName()); + } else { + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + showUserMenu(); + } + break; + case NETWORKBTN: + if(!m_kylinNM || !(m_kylinNM && m_kylinNM->isVisible())) + showNetManager(true); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + authDialog->setFocusin(REMOVE); + break; + case KEYBOARDBTN: + if(!vKeyboard || !(vKeyboard && vKeyboard->isVisible())) + showVirtualKeyboard(); + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + break; + case POWERBTN: + showPowerManager(true); + break; + default: + break; + } + } else if (tabAt == BIOBTN) { + authDialog->setClick(); + } else if (tabAt == ENTERBTN) { + authDialog->checkPassword(); + tabAt = LINEEDIT; + } else if (tabAt == POWERMANAGER) { + powermanager->keyBdRelease(key); + } +} + +void LockWidget::key_tab_release(int key) +{ + if(key == Qt::Key_Tab) { + if (at_plugins) { + authDialog->setFocusin(REMOVE); + return; + } + switch (tabAt) { + case LINEEDIT: + authDialog->setFocusin(IN_LIGIN); + tabAt = ENTERBTN; + break; + case MESSAGEBTN : + tabAt = BOTTMBTN; + authDialog->setFocusin(REMOVE); + if(is_batteryBtn) { + horAT = BATTERYBTN; + setBottomBtnSheet(); + } else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + setBottomBtnSheet(); + } else { + horAT =NETWORKBTN; + setBottomBtnSheet(); + } + break; + case ENTERBTN: + if(authDialog->getBioNum() >1) { + authDialog->setFocusin(BIO_RIGHT); + tabAt = BIOBTN; + } else { + tabAt = BOTTMBTN; + authDialog->setFocusin(REMOVE); + if(is_batteryBtn){ + horAT = BATTERYBTN; + } else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + } else { + horAT =NETWORKBTN; + } + setBottomBtnSheet(); + } + break; + case BIOBTN: + tabAt = BOTTMBTN; + authDialog->setFocusin(REMOVE); + if(is_batteryBtn) { + horAT = BATTERYBTN; + setBottomBtnSheet(); + } else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + setBottomBtnSheet(); + } else { + horAT =NETWORKBTN; + setBottomBtnSheet(); + } + break; + case BOTTMBTN: + if(!at_power) { + if(!authDialog->getLineeditStatus()) { + authDialog->setFocusin(IN_LINEEDIT); + tabAt = LINEEDIT; + } else { + authDialog->setFocusin(ON_MESSAGEBTN); + tabAt = MESSAGEBTN; + } + setBottomBtnSheet(); + } else if (at_power) { + powermanager->keyBdRelease(Qt::Key_Right); + tabAt = POWERMANAGER; + setBottomBtnSheet(); + } + break; + case POWERMANAGER: + powermanager->clearStatus(); + tabAt = BOTTMBTN; + if(is_batteryBtn) { + horAT = BATTERYBTN; + setBottomBtnSheet(); + } else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + setBottomBtnSheet(); + } else { + horAT =NETWORKBTN; + setBottomBtnSheet(); + } + break; + case EMPTY: + authDialog->setFocusin(IN_LINEEDIT); + tabAt = LINEEDIT; + setBottomBtnSheet(); + } + } +} + +void LockWidget::key_shiftTab_release() +{ + if (at_plugins) { + authDialog->setFocusin(REMOVE); + return; + } + switch (tabAt) { + case LINEEDIT: + tabAt = BOTTMBTN; + authDialog->setFocusin(REMOVE); + if(is_batteryBtn) + horAT = BATTERYBTN; + else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + } else { + horAT =NETWORKBTN; + } + setBottomBtnSheet(); + break; + case MESSAGEBTN : + tabAt = BOTTMBTN; + authDialog->setFocusin(REMOVE); + if(is_batteryBtn) { + horAT = BATTERYBTN; + setBottomBtnSheet(); + } else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + setBottomBtnSheet(); + } else { + horAT =NETWORKBTN; + setBottomBtnSheet(); + } + break; + case ENTERBTN: + authDialog->setFocusin(IN_LINEEDIT); + tabAt = LINEEDIT; + setBottomBtnSheet(); + break; + case BIOBTN: + authDialog->setFocusin(IN_LIGIN); + tabAt = ENTERBTN; + break; + case BOTTMBTN: + if(!at_power) { + if(!authDialog->getLineeditStatus()) { + if(authDialog->getBioNum() >1) { + authDialog->setFocusin(BIO_RIGHT); + tabAt = BIOBTN; + } else { + authDialog->setFocusin(IN_LIGIN); + tabAt = ENTERBTN; + } + } else { + authDialog->setFocusin(ON_MESSAGEBTN); + tabAt = MESSAGEBTN; + } + setBottomBtnSheet(); + } else { + powermanager->keyBdRelease(Qt::Key_Right); + tabAt = POWERMANAGER; + } + setBottomBtnSheet(); + break; + case POWERMANAGER: + powermanager->clearStatus(); + tabAt = BOTTMBTN; + if(is_batteryBtn) { + horAT = BATTERYBTN; + setBottomBtnSheet(); + } else if(users->getUsers().count() > 1){ + horAT = SWITCHBTN; + setBottomBtnSheet(); + } else { + horAT =NETWORKBTN; + setBottomBtnSheet(); + } + break; + case EMPTY: + authDialog->setFocusin(IN_LINEEDIT); + tabAt = LINEEDIT; + setBottomBtnSheet(); + } +} + +void LockWidget::key_LR_release(int key) +{ + if(key == Qt::Key_Right) { + if(tabAt == BOTTMBTN) { + if (at_plugins) + return; + switch (horAT) { + case BATTERYBTN: + if(is_switchBtn) + horAT = SWITCHBTN; + else + horAT = NETWORKBTN; + break; + case SWITCHBTN: + horAT = NETWORKBTN; + break; + case NETWORKBTN: + if (ui->btnKeyboard->isHidden()) { + horAT = POWERBTN; + } else { + horAT = KEYBOARDBTN; + } + break; + case KEYBOARDBTN: + horAT = POWERBTN; + break; + case POWERBTN: + if(is_batteryBtn) + horAT = BATTERYBTN; + else if(is_switchBtn) + horAT = SWITCHBTN; + else + horAT = NETWORKBTN; + break; + default: + break; + } + setBottomBtnSheet(); + } else if (tabAt == BIOBTN) { + authDialog->setFocusin(BIO_RIGHT); + } else if (tabAt == POWERMANAGER) { + powermanager->keyBdRelease(Qt::Key_Right); + } + } else if (key == Qt::Key_Left) { + if(tabAt == BOTTMBTN) { + if (at_plugins) + return; + switch (horAT) { + case BATTERYBTN: + horAT = POWERBTN; + break; + case SWITCHBTN: + if(is_batteryBtn) + horAT = BATTERYBTN; + else + horAT = POWERBTN; + break; + case NETWORKBTN: + if(is_switchBtn) + horAT = SWITCHBTN; + else if(is_batteryBtn) + horAT = BATTERYBTN; + else + horAT = POWERBTN;; + break; + case KEYBOARDBTN: + horAT = NETWORKBTN; + break; + case POWERBTN: + if (ui->btnKeyboard->isHidden()) { + horAT = NETWORKBTN; + } else { + horAT = KEYBOARDBTN; + } + break; + default: + break; + } + setBottomBtnSheet(); + } else if (tabAt == BIOBTN) { + authDialog->setFocusin(BIO_LEFT); + } else if (tabAt == POWERMANAGER) { + powermanager->keyBdRelease(Qt::Key_Left); + } + } +} + +void LockWidget::setBottomBtnSheet() +{ + if (tabAt == BOTTMBTN) { + switch (horAT) { + case BATTERYBTN: + ui->btnBatteryStatus->setStyleSheet(ON_TAB_SHEET); + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + ui->btnKeyboard->setStyleSheet(ON_NORMAL_SHEET); + ui->btnPowerManager->setStyleSheet(ON_NORMAL_SHEET); + break; + case SWITCHBTN: + ui->btnSwitchUser->setStyleSheet(ON_TAB_SHEET); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + ui->btnKeyboard->setStyleSheet(ON_NORMAL_SHEET); + ui->btnPowerManager->setStyleSheet(ON_NORMAL_SHEET); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + break; + case NETWORKBTN: + widgetNetworkManager->setStyleSheet(ON_TAB_SHEET_WIDGET); + ui->btnKeyboard->setStyleSheet(ON_NORMAL_SHEET); + ui->btnPowerManager->setStyleSheet(ON_NORMAL_SHEET); + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + break; + case KEYBOARDBTN: + ui->btnKeyboard->setStyleSheet(ON_TAB_SHEET); + ui->btnPowerManager->setStyleSheet(ON_NORMAL_SHEET); + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + break; + case POWERBTN: + ui->btnPowerManager->setStyleSheet(ON_TAB_SHEET); + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + ui->btnKeyboard->setStyleSheet(ON_NORMAL_SHEET); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + break; + default: + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + ui->btnKeyboard->setStyleSheet(ON_NORMAL_SHEET); + ui->btnPowerManager->setStyleSheet(ON_NORMAL_SHEET); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + break; + } + } else { + ui->btnSwitchUser->setStyleSheet(ON_NORMAL_SHEET); + widgetNetworkManager->setStyleSheet(ON_NORMAL_SHEET_WIDGET); + ui->btnKeyboard->setStyleSheet(ON_NORMAL_SHEET); + ui->btnPowerManager->setStyleSheet(ON_NORMAL_SHEET); + ui->btnBatteryStatus->setStyleSheet(ON_NORMAL_SHEET); + } +} + +void LockWidget::key_OB_release(int key) { - //usersMenu->setFocus(); QString focus = "focus"; QString normal = "normal"; - if(key == "Up"){ -// if(nowAt == -1){ -// nowAt = 0; -// setButtonStyle(focus); -// } + if(key == Qt::Key_Up){ // "Up" for(int i = 0; i < list.count(); i++){ if(nowAt == i){ if(i == 0) @@ -191,14 +587,13 @@ void LockWidget::keyBdRelease(QString key) nowAt = i-1; /*else if(i == 0){ - qDebug()<<"enheng???111"<setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); nowAt = list.count() -1; }*/ } } - } else if(key == "Down") { + } else if(key == Qt::Key_Down) { // "Down" for(int i = list.count(); i >= 0; i--){ if(nowAt == i){ if(i == list.count() - 1) @@ -209,38 +604,30 @@ void LockWidget::keyBdRelease(QString key) "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); nowAt = i+1; /*else if(i == list.count() - 1){ - qDebug()<<"enheng???111"<setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); nowAt = 0; }*/ } } - } else if(key == "Return" || key == "KP_Enter"){ - if(authDialog) - { - authDialog->stopAuth(); - } - if(list.at(nowAt)->objectName() == "Guest") - { - displayManager->switchToGuest(); - } - else if(list.at(nowAt)->objectName() == "SwitchUser") - { - displayManager->switchToGreeter(); - } - else - { - displayManager->switchToUser(list.at(nowAt)->objectName()); - } } } +void LockWidget::resetNavigation() +{ + tabAt = LINEEDIT; + setBottomBtnSheet(); + authDialog->setFocusin(IN_LINEEDIT); +} + void LockWidget::startAuth() { if(authDialog) { authDialog->startAuth(); +// if (isTableMode && !(vKeyboard && vKeyboard->isVisible())) { +// showVirtualKeyboard(); +// } } } @@ -255,7 +642,7 @@ void LockWidget::stopAuth() void LockWidget::setX11Focus() { if(authDialog){ - authDialog->setX11Focus(); + //authDialog->setX11Focus(); } } @@ -283,9 +670,9 @@ void LockWidget::initUI() ui->lblTime->setText(QDateTime::currentDateTime().toString("hh:mm")); if(dateType == "cn") - ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd").replace("周","星期")); else - ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd").replace("周","星期")); }); if(timeType == 12) @@ -293,7 +680,7 @@ void LockWidget::initUI() else ui->lblTime->setText(QDateTime::currentDateTime().toString("hh:mm")); - ui->lblTime->setStyleSheet("QLabel{color:white; font-size: 36px;}"); + ui->lblTime->setFontSize(36); ui->lblTime->setAlignment(Qt::AlignCenter); ui->lblTime->adjustSize(); timer->start(1000); @@ -302,17 +689,67 @@ void LockWidget::initUI() // qDebug() << "current date: " << date; // ui->lblDate->setText(date); if(dateType == "cn") - ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd").replace("周","星期")); else - ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd").replace("周","星期")); - ui->lblDate->setStyleSheet("QLabel{color:white; font-size: 18px;}"); + ui->lblDate->setFontSize(18); ui->lblDate->setAlignment(Qt::AlignCenter); ui->lblDate->adjustSize(); ui->widgetTime->adjustSize(); + //电池电量显示icon + batInterface = new QDBusInterface( + "org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus(), this); + + QString batteryPath = ""; + dface = new QDBusInterface(UPOWER_SERVICE, UPOWER_PATH, UPOWER_INTERFACE, QDBusConnection::systemBus(), this); + QDBusReply> reply = dface->call("EnumerateDevices"); + if (dface->isValid()) { + for (QDBusObjectPath op : reply.value()) { + if (op.path().contains("battery_")) { + batteryPath = op.path(); + qDebug() << "battery path is :" << batteryPath; + break; + } + } + } else { + qDebug() << "Enumerate devices failed"; + } + + iface = new QDBusInterface(UPOWER_SERVICE, batteryPath, FREEDESKTOP_UPOWER, QDBusConnection::systemBus()); + if (dface->isValid()) { + QDBusReply reply = batInterface->call("Get", "org.freedesktop.UPower", "LidIsPresent"); + if (reply.isValid()) { + if (true == reply.value().toBool()) { + setBatteryIcon(getBatteryIconName()); + QDBusConnection::systemBus().connect( + UPOWER_SERVICE, batteryPath, FREEDESKTOP_UPOWER, "PropertiesChanged", this, SLOT(dealMessage(QDBusMessage))); + ui->btnBatteryStatus->setFixedSize(48,48); + ui->btnBatteryStatus->setIconSize(QSize(24,24)); + ui->btnBatteryStatus->setFocusPolicy(Qt::NoFocus); + ui->btnBatteryStatus->installEventFilter(this); + ui->btnBatteryStatus->setCheckable(true); + ui->btnBatteryStatus->raise(); + mBatteryWidget = new BatteryWidget(QPoint(ui->btnBatteryStatus->x(), ui->btnBatteryStatus->y()), this); + mBatteryWidget->hide(); + connect(ui->btnBatteryStatus,&QPushButton::clicked + ,this,&LockWidget::showBattery); + } else { + ui->btnBatteryStatus->hide(); + is_batteryBtn = false; + } + } else { + ui->btnBatteryStatus->hide(); + is_batteryBtn = false; + } + } else { + ui->btnBatteryStatus->hide(); + is_batteryBtn = false; + } + //电源管理 - ui->btnPowerManager->setIcon(QIcon(":/image/assets/powerManager.png")); + ui->btnPowerManager->setIcon(QIcon(":/image/assets/shutdown.svg")); ui->btnPowerManager->setFixedSize(48,48); ui->btnPowerManager->setIconSize(QSize(24,24)); ui->btnPowerManager->setFocusPolicy(Qt::NoFocus); @@ -322,32 +759,30 @@ void LockWidget::initUI() ,this,&LockWidget::showPowerManager); - QtConcurrent::run([=](){ - updateNetIcon(getNetStatus()); + + widgetNetworkManager = new QWidget(this); + widgetNetworkManager->setObjectName("widgetNetworkManager"); + widgetNetworkManager->setFixedSize(48,48); + btnNetworkManager = new KyNetworkIcon(widgetNetworkManager); + btnNetworkManager->setCheckable(true); + btnNetworkManager->setFixedSize(48,48); + btnNetworkManager->setIconSize(QSize(24,24)); + btnNetworkManager->setFocusPolicy(Qt::NoFocus); + btnNetworkManager->installEventFilter(this); + btnNetworkManager->setCursor(Qt::PointingHandCursor); + + connect(btnNetworkManager,&QPushButton::clicked + ,this, [&,this](){ + this->showNetManager(); + this->setCursor(Qt::ArrowCursor); }); - ui->btnNetworkManager->setFixedSize(48,48); - ui->btnNetworkManager->setIconSize(QSize(24,24)); - ui->btnNetworkManager->setFocusPolicy(Qt::NoFocus); -// ui->btnNetworkManager->setStyleSheet("QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" -// "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); - ui->btnNetworkManager->installEventFilter(this); - - connect(ui->btnNetworkManager,&QPushButton::clicked - ,this,&LockWidget::showNetManager); - - //虚拟键盘 ui->btnKeyboard->setIcon(QIcon(":/image/assets/keyboard.svg")); ui->btnKeyboard->setFixedSize(48, 48); ui->btnKeyboard->setIconSize(QSize(24, 24)); ui->btnKeyboard->setFocusPolicy(Qt::NoFocus); ui->btnKeyboard->installEventFilter(this); -/* connect(ui->btnKeyboard, &QPushButton::clicked, - this, [&]{ - qDebug() << vKeyboard->isHidden(); - vKeyboard->setVisible(vKeyboard->isHidden()); - }); -*/ + connect(ui->btnKeyboard, &QPushButton::clicked, this, &LockWidget::showVirtualKeyboard); @@ -355,61 +790,148 @@ void LockWidget::initUI() if(displayManager->canSwitch()) { //initUserMenu(); - ui->btnSwitchUser->setIcon(QIcon(":/image/assets/switchUser.png")); + ui->btnSwitchUser->setIcon(QIcon(":/image/assets/switchuser.svg")); ui->btnSwitchUser->setIconSize(QSize(24, 24)); ui->btnSwitchUser->setFixedSize(48, 48); ui->btnSwitchUser->setFocusPolicy(Qt::NoFocus); + ui->btnSwitchUser->setCheckable(true); ui->btnSwitchUser->raise(); connect(ui->btnSwitchUser, &QPushButton::clicked, - this, [&]{ - if(!usersMenu){ - initUserMenu(); - } - - if(scrollArea && scrollArea->isVisible()){ - scrollArea->hide(); - } - else{ - scrollArea->show(); - if(m_kylinNM && m_kylinNM->isVisible()) - m_kylinNM->hide(); - scrollArea->setFocus(); - } - }); + this, &LockWidget::showUserMenu); } + //监听物理键盘插拔 + libswitch = new LibinputSwitchEvent; + isTableMode = libswitch->geInitDevicesStatus(); +// if(isTableMode && !(vKeyboard && vKeyboard->isVisible())) { +// showVirtualKeyboard(); +// } + connect(libswitch , &LibinputSwitchEvent::tabletModeStatusChanged, this, [ = ](int tablet_mode) { + isTableMode = tablet_mode; + qInfo()<<"TableMode:"<isVisible())) { +// QTimer::singleShot(1000, this, [=]{ +// if (this->isTableMode) { +// showVirtualKeyboard(); +// QTimer::singleShot(500, this, [&, this](){ +// authDialog->setFocusin(IN_LINEEDIT); +// }); +// } +// }); + } else if (!isTableMode && (tabAt == BOTTMBTN && horAT == KEYBOARDBTN) && (vKeyboard && vKeyboard->isVisible())) { + QTimer::singleShot(100, this, [=]{ + if (!this->isTableMode) { + hideBottomPlugins(); + } + }); + } + }); +} +void LockWidget::netInPutStatus() +{ + if(isTableMode && !(vKeyboard && vKeyboard->isVisible())) + showVirtualKeyboard(); } void LockWidget::showVirtualKeyboard() { + tabAt = LINEEDIT; + setBottomBtnSheet(); + tabAt = BOTTMBTN; + horAT = KEYBOARDBTN; if(!vKeyboard){ - vKeyboard = new VirtualKeyboard(this); + vKeyboard = new VirtualKeyboardWidget(this); + vKeyboard->installEventFilter(this); vKeyboard->hide(); - connect(vKeyboard, &VirtualKeyboard::aboutToClose, - vKeyboard, &VirtualKeyboard::hide); + connect(vKeyboard, &VirtualKeyboardWidget::aboutToClose, + this, &LockWidget::hideBottomPlugins); + connect(vKeyboard, &VirtualKeyboardWidget::aboutToFloat, + this, &LockWidget::netResetLocation); } vKeyboard->setVisible(vKeyboard->isHidden()); + if(!vKeyboard->isHidden()){ vKeyboard->raise(); + //authDialog->setFocusin(IN_LINEEDIT); + at_plugins = true; + if(m_kylinNM && m_kylinNM->isVisible() && !vKeyboard->getFloatStatus()) { + m_kylinNM->move(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - vKeyboard->height()); + m_kylinNM->raise(); + } else + authDialog->setFocusin(IN_LINEEDIT); + if(scrollArea && scrollArea->isVisible()) + setCheckedSheet(SWITCHBTN, false); + if(mBatteryWidget && mBatteryWidget->isVisible()) + setCheckedSheet(BATTERYBTN, false); } - setVirkeyboardPos(); + vKeyboard->raise(); + //setVirkeyboardPos(); } -void LockWidget::showPowerManager() +void LockWidget::netResetLocation() +{ + if (m_kylinNM && m_kylinNM->isVisible()) { + if (vKeyboard->getFloatStatus()) { + m_kylinNM->move(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 72 - 8) ; + } else { + m_kylinNM->move(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - vKeyboard->height()); + } + m_kylinNM->raise(); + } + if (vKeyboard && vKeyboard->isVisible()) { + vKeyboard->raise(); + } +} + +void LockWidget::showUserMenu() +{ + if(!usersMenu){ + initUserMenu(); + } + tabAt = LINEEDIT; + setBottomBtnSheet(); + tabAt = BOTTMBTN; + horAT = SWITCHBTN; + + if(scrollArea && scrollArea->isVisible()){ + setCheckedSheet(SWITCHBTN,false); + at_plugins = false; + authDialog->setFocusin(REMOVE); + } else { + setCheckedSheet(SWITCHBTN, true); + at_plugins = true; + authDialog->setFocusin(REMOVE); + if(m_kylinNM && m_kylinNM->isVisible()) + setCheckedSheet(NETWORKBTN, false); + if(mBatteryWidget && mBatteryWidget->isVisible()) + setCheckedSheet(BATTERYBTN, false); + scrollArea->setFocus(); + } +} + +void LockWidget::showPowerManager(bool keynavigation) { if(!powermanager){ - powermanager = new PowerManager(this); + powermanager = new PowerManager(getLoginedNum(), this); + powermanager->setStartupMode(m_isStartupMode); sureWidget = new SureWindow(this); powermanager->hide(); connect(powermanager,SIGNAL(lock()) ,this,SLOT(showPowerManager())); connect(powermanager,SIGNAL(switchToUser()) ,this,SLOT(switchToGreeter())); + connect(powermanager, SIGNAL(showInhibitWarning(QVector&,int)), + this,SLOT(showWarning(QVector&,int))); connect(powermanager, SIGNAL(mulUsersLogined(int)), this,SLOT(switchToSureDialog(int))); + connect(powermanager, SIGNAL(clickedSuspend()) + , this, SLOT(resetNavigation())); sureWidget->adjustSize(); sureWidget->move((width()-sureWidget->geometry().width())/2, (height()-sureWidget->geometry().height())/2); sureWidget->hide(); @@ -420,20 +942,50 @@ void LockWidget::showPowerManager() } if(m_kylinNM && m_kylinNM->isVisible()) - m_kylinNM->hide(); + setCheckedSheet(NETWORKBTN, false); if(scrollArea && scrollArea->isVisible()) - scrollArea->hide(); + setCheckedSheet(SWITCHBTN,false); + if(mBatteryWidget && mBatteryWidget->isVisible()) + setCheckedSheet(BATTERYBTN, false); if(sureWidget && sureWidget->isVisible()) sureWidget->hide(); + if (!at_power && (vKeyboard && vKeyboard->isVisible())) { + m_isShowKeyboard = true; + hideBottomPlugins(); + } else if (!at_power && (vKeyboard && !vKeyboard->isVisible())) { + m_isShowKeyboard = false; + } if(powermanager->isVisible()){ - authDialog->setFocus(); authDialog->show(); powermanager->hide(); + if(!authDialog->getLineeditStatus()) { + tabAt = LINEEDIT; + authDialog->setFocusin(IN_LINEEDIT); +// if (m_isShowKeyboard && isTableMode && !(vKeyboard && vKeyboard->isVisible())) { +// showVirtualKeyboard(); +// } + } else { + tabAt = MESSAGEBTN; + authDialog->setFocusin(ON_MESSAGEBTN); + } + //setBottomBtnSheet(); + powermanager->clearStatus(); + at_power = false; } - else{ + else{ authDialog->hide(); powermanager->show(); - powermanager->setFocus(); + if(keynavigation){ + powermanager->keyBdRelease(Qt::Key_Right); + tabAt = POWERMANAGER; + setBottomBtnSheet(); + } else { + tabAt = LINEEDIT; + setBottomBtnSheet(); + tabAt = BOTTMBTN; + horAT = POWERBTN; + } + at_power = true; #ifndef USE_INTEL powermanager->showNormalSize(); #endif @@ -443,13 +995,48 @@ void LockWidget::showPowerManager() } } -void LockWidget::switchToSureDialog(int type) +void LockWidget::setCheckedSheet(int type, bool show) +{ + switch (type) { + case BATTERYBTN: + if(show) { + mBatteryWidget->show(); + ui->btnBatteryStatus->setChecked(true); + } else { + mBatteryWidget->hide(); + ui->btnBatteryStatus->setChecked(false); + } + break; + case SWITCHBTN: + if(show) { + scrollArea->show(); + ui->btnSwitchUser->setChecked(true); + } else { + scrollArea->hide(); + ui->btnSwitchUser->setChecked(false); + } + break; + case NETWORKBTN: + if(show) { + m_kylinNM->show(); + btnNetworkManager->setChecked(true); + } else { + m_kylinNM->hide(); + btnNetworkManager->setChecked(false); + } + break; + default: + break; + } +} + +void LockWidget::showWarning(QVector &wlist, int type) { powermanagerType = type; if(m_kylinNM && m_kylinNM->isVisible()) - m_kylinNM->hide(); + setCheckedSheet(NETWORKBTN, false); if(scrollArea && scrollArea->isVisible()) - scrollArea->hide(); + setCheckedSheet(SWITCHBTN, false); authDialog->hide(); powermanager->hide(); @@ -457,9 +1044,36 @@ void LockWidget::switchToSureDialog(int type) sureWidget->setFocus(); ui->widgetTime->hide(); ui->btnPowerManager->hide(); - ui->btnNetworkManager->hide(); + //btnNetworkManager->hide(); + widgetNetworkManager->hide(); ui->btnSwitchUser->hide(); ui->btnKeyboard->hide(); + ui->btnBatteryStatus->hide(); + + sureWidget->setWarning(wlist, type); +} + +void LockWidget::switchToSureDialog(int type) +{ + powermanagerType = type; + if(m_kylinNM && m_kylinNM->isVisible()) + setCheckedSheet(NETWORKBTN, false); + if(scrollArea && scrollArea->isVisible()) + setCheckedSheet(SWITCHBTN, false); + + authDialog->hide(); + powermanager->hide(); + sureWidget->show(); + sureWidget->setFocus(); + ui->widgetTime->hide(); + ui->btnPowerManager->hide(); + widgetNetworkManager->hide(); + //btnNetworkManager->hide(); + ui->btnSwitchUser->hide(); + ui->btnKeyboard->hide(); + ui->btnBatteryStatus->hide(); + + sureWidget->setTips(tr("Multiple users are logged in at the same time.Are you sure you want to reboot this system?")); } void LockWidget::hideSureDialog() @@ -468,59 +1082,187 @@ void LockWidget::hideSureDialog() powermanager->show(); ui->widgetTime->show(); ui->btnPowerManager->show(); - ui->btnNetworkManager->show(); + widgetNetworkManager->show(); + //btnNetworkManager->show(); ui->btnSwitchUser->show(); ui->btnKeyboard->show(); + ui->btnBatteryStatus->show(); } void LockWidget::confirmClicked() { if(m_kylinNM && m_kylinNM->isVisible()) - m_kylinNM->hide(); + setCheckedSheet(NETWORKBTN, false); if(scrollArea && scrollArea->isVisible()) - scrollArea->hide(); + setCheckedSheet(SWITCHBTN, false); + if(mBatteryWidget && mBatteryWidget->isVisible()) + setCheckedSheet(BATTERYBTN, false); sureWidget->hide(); powermanager->hide(); authDialog->show(); ui->widgetTime->show(); ui->btnPowerManager->show(); - ui->btnNetworkManager->show(); + widgetNetworkManager->show(); + //btnNetworkManager->show(); ui->btnSwitchUser->show(); ui->btnKeyboard->show(); + ui->btnBatteryStatus->show(); powermanager->doEvent(powermanagerType); } -void LockWidget::showNetManager() +void LockWidget::showNetManager(bool keynavigation) { + if(!keynavigation) { + tabAt = LINEEDIT; + setBottomBtnSheet(); + tabAt = BOTTMBTN; + horAT = NETWORKBTN; + } if(!m_kylinNM){ - return; + /*这里放在点击按钮后加载,一个原因是启动优化,另一个原因是如果放在构造函数中加载,则必须 + * 先让网络窗口显示出来一次,否则会在锁屏程序退出时,锁屏窗口在closeEvent中崩溃,原因未知 + * 同时,可以尽量降低在未操作网络时,网络程序对锁屏窗口的影响*/ + loadNetPlugin(); + m_kylinNM->hide(); } if(m_kylinNM->isVisible()) { - m_kylinNM->hide(); + setCheckedSheet(NETWORKBTN, false); } else { - m_kylinNM->show(); + setCheckedSheet(NETWORKBTN, true); if(scrollArea && scrollArea->isVisible()) - scrollArea->hide(); + setCheckedSheet(SWITCHBTN, false); + if(mBatteryWidget && mBatteryWidget->isVisible()) + setCheckedSheet(BATTERYBTN, false); m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, - this->height() - m_kylinNM->height() - 100, + this->height() - m_kylinNM->height() - 72 - 8, m_kylinNM->width(), m_kylinNM->height()); - m_kylinNM->updateWifiList(); + m_kylinNM->raise(); + if (vKeyboard && vKeyboard->isVisible()) { + vKeyboard->raise(); + } + m_kylinNM->setFocus(); + /*在150%缩放下,点击网络弹窗左上角有线连接部分,authDialog会收到点击事件导致网络弹窗隐藏, + * 这里只调用m_kylinNM->raise()仍会有问题,需要再调用一次authDialog->lower()才行,原因未知*/ + if(authDialog && authDialog->isVisible()){ + authDialog->lower(); + authDialog->clearFocus(); + } + + if(mBatteryWidget && mBatteryWidget->isVisible()) { + mBatteryWidget->lower(); + mBatteryWidget->clearFocus(); + } + at_plugins = true; + + //m_kylinNM->updateWifiList(); } } -void LockWidget::hideNetManager() +void LockWidget::onClickPassword() { - if(!m_kylinNM){ - return; + tabAt = LINEEDIT; + if(is_switchBtn) + horAT = SWITCHBTN; + else + horAT = NETWORKBTN; + setBottomBtnSheet(); + authDialog->setFocusin(IN_LINEEDIT); + + if(m_kylinNM && m_kylinNM->isVisible()) { + setCheckedSheet(NETWORKBTN, false); + at_plugins = false; } - if(m_kylinNM && m_kylinNM->isVisible()) - m_kylinNM->hide(); + if(scrollArea && scrollArea->isVisible()) { + setCheckedSheet(SWITCHBTN, false); + at_plugins = false; + } + if(isTableMode) { + if(!(vKeyboard && vKeyboard->isVisible())) + showVirtualKeyboard(); + } +// if(vKeyboard && vKeyboard->isVisible()) { +// vKeyboard->hide(); +// at_plugins = false; +// } +} + +void LockWidget::onShowMessageBtn(bool is_show) +{ + if(is_show) { + tabAt = MESSAGEBTN; + authDialog->setFocusin(ON_MESSAGEBTN); + } +} + +void LockWidget::showBattery() +{ + if(mBatteryWidget->isVisible()) { + setCheckedSheet(BATTERYBTN, false); + at_plugins = false; + } else { + setCheckedSheet(BATTERYBTN, true); + at_plugins = true; + } + + tabAt = LINEEDIT; + setBottomBtnSheet(); + tabAt = BOTTMBTN; + horAT = BATTERYBTN; + if(scrollArea && scrollArea->isVisible()){ + setCheckedSheet(SWITCHBTN, false); + } else if (m_kylinNM && m_kylinNM->isVisible()){ + setCheckedSheet(NETWORKBTN, false); + } +} + +void LockWidget::hideBottomPlugins() +{ if(scrollArea && scrollArea->isVisible()) - scrollArea->hide(); + setCheckedSheet(SWITCHBTN, false); + + if(vKeyboard && vKeyboard->isVisible()) { + vKeyboard->hide(); + at_plugins = false; + } + if(m_kylinNM && m_kylinNM->isVisible()) { + m_kylinNM->move(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 72 - 8); + tabAt = BOTTMBTN; + horAT = NETWORKBTN; + setCheckedSheet(NETWORKBTN, true); + at_plugins = true; + authDialog->setFocusin(REMOVE); + return ; + } + //tabAt = EMPTY; + if(!authDialog->getLineeditStatus()) + tabAt = LINEEDIT; + setBottomBtnSheet(); +} + +void LockWidget::setBatteryIcon(QString str) +{ + QPixmap pixmap = QIcon::fromTheme(str).pixmap(QSize(24, 24)); + QImage img = pixmap.toImage(); + for (int x = 0; x < img.width(); x++) { + for (int y = 0; y < img.height(); y++) { + QColor color = img.pixelColor(x, y); + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + } + } + ui->btnBatteryStatus->setIcon(QPixmap::fromImage(img)); +} + +void LockWidget::dealMessage(QDBusMessage) +{ + setBatteryIcon(getBatteryIconName()); } int LockWidget::getNetStatus() @@ -554,25 +1296,93 @@ int LockWidget::getNetStatus() return ret; } -void LockWidget::updateNetIcon(int status) +void LockWidget::loadNetPlugin() { - switch(status) { - case 0: - //有线 - ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png")); - break; - case 1: - //无线 - ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wifi.png")); - break; - case 2: - //有线+无线 - ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png")); - break; - default: - //无连接 - ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-no-signal.png")); + m_kylinNM = new QWidget(this); + m_kylinNM->setFixedSize(420,480); + m_kylinNM->setObjectName("m_kylinNM"); + m_kylinNM->setStyleSheet("#m_kylinNM{background-color: white; border-radius:12px;}"); + + mkylinNM = new MyTabWidget(m_kylinNM); + mkylinNM->setFixedSize(420,480); + mkylinNM->tabBar()->setFixedHeight(40); + mkylinNM->installEventFilter(this); + + QPluginLoader netloader("/usr/lib/kylin-nm/libnetconnect.so");//有线 + QPluginLoader wlanloader("/usr/lib/kylin-nm/libwlanconnect.so");//无线 + + if (netloader.load()) { + QObject * plugin = netloader.instance(); + + if (plugin) { + Interface * pluginInstance = qobject_cast(plugin); + // 插件是否启用 + if (!pluginInstance) { + return; + } + + pluginInstance->setPluginType(SIMPLE); + QWidget *widget = pluginInstance->pluginUi(); + mkylinNM->addTab(widget,""); + + } else { + qDebug() << "Load Failed: " << netloader.errorString() << "\n"; + return; + } + } else { + qDebug() << "Load Failed: " << netloader.errorString() << "\n"; + return; } + + if (wlanloader.load()) { + QObject * plugin = wlanloader.instance(); + + if (plugin) { + Interface * pluginInstance = qobject_cast(plugin); + // 插件是否启用 + if (!pluginInstance) { + return; + } + + pluginInstance->setPluginType(SIMPLE); + /*这里需要先调用setParentWidget,否则会出现网络连接弹窗无法弹出来的问题*/ + pluginInstance->setParentWidget(this); + QWidget *widget = pluginInstance->pluginUi(); + mkylinNM->addTab(widget,""); + + // 平板模式输入状态下自动调出虚拟键盘 + connect(pluginInstance, SIGNAL(needShowVirtualKeyboard()), this, SLOT(netInPutStatus())); + } else { + qDebug() << "Load Failed: " << wlanloader.errorString() << "\n"; + return; + } + } else { + qDebug() << "Load Failed: " << wlanloader.errorString() << "\n"; + return; + } + + + QHBoxLayout *m_tabBarLayout = new QHBoxLayout(mkylinNM); + m_tabBarLayout->setContentsMargins(0,0,0,0); + QLabel *m_lanLabel = new QLabel(tr("LAN")); + m_lanLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + QLabel *m_wlanLabel = new QLabel(tr("WLAN")); + m_wlanLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + m_tabBarLayout->addWidget(m_lanLabel); + m_tabBarLayout->addWidget(m_wlanLabel); + mkylinNM->tabBar()->setLayout(m_tabBarLayout); + mkylinNM->tabBar()->setFixedWidth(420); + QPalette pal = qApp->palette(); + pal.setBrush(QPalette::Background, Qt::white); +// m_kylinNM->setPalette(pal); + mkylinNM->widget(0)->setPalette(pal); + mkylinNM->widget(1)->setPalette(pal); + + m_kylinNM->setGeometry(this->width() - mkylinNM->width() - 20, + this->height() - mkylinNM->height() - 72 - 8, + mkylinNM->width(), + mkylinNM->height()); + } void LockWidget::switchToGreeter() @@ -588,13 +1398,74 @@ void LockWidget::setVirkeyboardPos() { if(vKeyboard) { - vKeyboard->setGeometry(0, - height() - height()/3, - width(), height()/3); - +// vKeyboard->setGeometry(0, +// height() - height()/3, +// width(), height()/3); + vKeyboard->adjustGeometry(); } } +void LockWidget::SwitchToUser(QString strUserName) +{ + bool isSwitchSelf = false; + if(authDialog) { + if (strUserName == authDialog->getCurAuthUserName()) { + isSwitchSelf = true; + } else { + authDialog->stopAuth(); + } + } + if (!isSwitchSelf) { + this->hide(); + if (!m_timerChkActive) { + m_timerChkActive = new QTimer(this); + m_timerChkActive->setInterval(10*1000); + connect(m_timerChkActive, &QTimer::timeout, this, [&,this](){ + if (this->isHidden()) { + this->show(); + } + m_timerChkActive->stop(); + }); + } else { + if (m_timerChkActive->isActive()) { + m_timerChkActive->stop(); + } + } + m_timerChkActive->start(); + } + QTimer::singleShot(10,this, [&,this, isSwitchSelf, strUserName](){ + if(strUserName == "*Guest") + { + this->displayManager->switchToGuest(); + } + else if(strUserName == "*SwitchUser") + { + this->displayManager->switchToGreeter(); + } + else + { + if (!isSwitchSelf) { + this->displayManager->switchToUser(strUserName); + } + } + }); +} + +void LockWidget::onSessionActiveChanged(bool isActive) +{ + if (isActive) { + if (m_timerChkActive && m_timerChkActive->isActive()) { + m_timerChkActive->stop(); + } + if (this->isHidden()) { + this->show(); + } + } else { + if (m_timerChkActive && m_timerChkActive->isActive()) { + m_timerChkActive->stop(); + } + } +} void LockWidget::initUserMenu() { @@ -617,6 +1488,12 @@ void LockWidget::initUserMenu() usersMenu = new QMenu(scrollContents); usersMenu->setObjectName("usersMenu"); usersMenu->setToolTipsVisible(true); + usersMenu->setStyleSheet("QMenu{background-color: rgb(255,255,255,15%);color: white;border-radius: 8px;width:250px;padding: 5px 5px 5px 5px;} \ + QMenu::icon{padding: 2px 5px 2px 5px;}\ + QMenu::item{width:225px;border-radius: 4px;height:36px;padding: 2px 10px 2px 10px;} \ + QMenu::item:selected {border-radius: 4px;background-color:rgb(255,255,255,40%);} \ + QMenu::item:pressed {border-radius: 4px;background-color: rgb(255,255,255,40%);}"); + // usersMenu->setStyleSheet("QMenu{background-color:transparent;color:white;padding:5px 5px 5px 8px}"); //QToolTip{border-radius:4px;background-color:rgb(255,255,255,40%);color:white;} //如果没有设置x11属性,则由于弹出菜单受窗口管理器管理,而主窗口不受,在点击菜单又点回主窗口会闪屏。 @@ -637,13 +1514,14 @@ void LockWidget::initUserMenu() widget->setFixedSize(240, 40); QLabel *iconlabel =new QLabel(widget); QPixmap p(users->getDefaultIcon()); + p = scaledPixmap(p); p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); p = PixmapToRound(p, 16*scale); iconlabel->setPixmap(p); iconlabel->setGeometry(8,4,32,32); - QLabel *textlabel =new QLabel(widget); - textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); - textlabel->setGeometry(48,8,190,24); + KLabel *textlabel =new KLabel(widget); + textlabel->setFontSize(16); + textlabel->setGeometry(48,4,190,30); action->setToolTip("SwitchUser"); action->setData("SwitchUser"); usersMenu->addAction(action); @@ -671,13 +1549,14 @@ void LockWidget::initUserMenu() widget->setFixedSize(240, 40); QLabel *iconlabel =new QLabel(widget); QPixmap p(users->getDefaultIcon()); + p = scaledPixmap(p); p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); p = PixmapToRound(p, 16*scale); iconlabel->setPixmap(p); iconlabel->setGeometry(8,4,32,32); - QLabel *textlabel =new QLabel(widget); - textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); - textlabel->setGeometry(48,8,190,24); + KLabel *textlabel =new KLabel(widget); + textlabel->setFontSize(16); + textlabel->setGeometry(48,4,190,30); action->setData("Guest"); action->setToolTip("Guest"); usersMenu->addAction(action); @@ -695,25 +1574,56 @@ void LockWidget::initUserMenu() "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); } } - scrollContents->setFixedSize(usersMenu->width() - 14, usersMenu->height()); + scrollContents->setFixedSize(usersMenu->width(), usersMenu->height()); //设置弹出菜单,设置弹出菜单的坐标为切换用户按钮的上方,中间保持一定间隔。 if(scrollArea){ if(scrollContents->height() < height()/2){ - scrollArea->setFixedSize(usersMenu->width(),scrollContents->height()+1); - }else{ - scrollArea->setFixedSize(usersMenu->width() + 4, height()/2); + scrollArea->setFixedSize(usersMenu->width(), scrollContents->height()+1); + + scrollArea->clearMask(); + }else{ + scrollArea->setFixedSize(usersMenu->width() + 16, height()/2); + + /*当scrollArea区域小于scrollContent大小时,使用样式表绘制的圆角外部透明部分,会显示出scrollContent的内容 + * 导致圆角外部有阴影,因此使用另一种方式再次绘制圆角,该方式绘制出来的圆角存在一定锯齿,所以只在会有阴影 + * 的情况下执行。*/ + QBitmap bitMap(scrollArea->width(),scrollArea->height()); // 定义一个窗口大小的位图 + bitMap.fill(); // 填充整个位图 + QPainter painter(&bitMap); // 定义绘图设备 + painter.setBrush(Qt::black); // 必须定义为黑色 + painter.setPen(Qt::NoPen); // 只能为黑色或者不设置画笔 + painter.setRenderHint(QPainter::Antialiasing);// 反走样 + painter.drawRoundedRect(bitMap.rect(),8,8); // 绘制圆角矩形 + scrollArea->setMask(bitMap); } scrollArea->move(ui->btnSwitchUser->geometry().x()- scrollArea->width()/2 + 24, \ - height() - 72 - scrollArea->height() - 5); + height() - 72 - scrollArea->height() - 8); } } void LockWidget::keyReleaseEvent(QKeyEvent *e) { - if(e->key() == Qt::Key_K){ + if (!QX11Info::isPlatformX11()) + Q_EMIT keyGlobalRelease(e->key()); + +/* if (e->key() == 9) { // "Escape" + + } else */if(e->key() == Qt::Key_K){ if(e->modifiers() & Qt::ControlModifier) showVirtualKeyboard(); + } else if (e->key() == Qt::Key_Tab) { + key_tab_release(e->key()); + } else if(e->key() == Qt::Key_Backtab){ + if(e->modifiers() & Qt::ShiftModifier) + key_shiftTab_release(); + } else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down) { // "Up" "Down" + if(scrollArea && scrollArea->isVisible()) + key_OB_release(e->key()); + } else if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right ) { // "Left" "Right" + key_LR_release(e->key()); + } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { // "Return" "KP_Enter" + key_enter_release(e->key()); } } @@ -726,16 +1636,22 @@ void LockWidget::resizeEvent(QResizeEvent *event) //系统时间 ui->widgetTime->move((width()-ui->widgetTime->geometry().width())/2, 59*scale); - if(sureWidget) + + if(sureWidget){ + sureWidget->adjustSize(); sureWidget->move((width()-sureWidget->geometry().width())/2, (height()-sureWidget->geometry().height())/2); + } //认证窗口 //设置认证窗口左右居中 - if(scale >= 1) - authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4-0.65*scale), \ + if(scale >= 1.3) + authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4-0.7*scale), \ authDialog->width(), (height()*3/4)); + else if(scale <= 0.9) + authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4-0.9*scale), \ + authDialog->width(), (height()*3/4)); else - authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4+0.65*scale), \ + authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4-0.65*scale), \ authDialog->width(), (height()*3/4)); if(scale > 1) @@ -746,32 +1662,56 @@ void LockWidget::resizeEvent(QResizeEvent *event) x = x + ui->btnPowerManager->width(); ui->btnPowerManager->move(width() - x,height() - y); - x = x+ui->btnKeyboard->width()+16; - ui->btnKeyboard->move(width() - x, height() - y); + if(!ui->btnKeyboard->isHidden()){ + x = x+ui->btnKeyboard->width()+16; + ui->btnKeyboard->move(width() - x, height() - y); + } - x = x + ui->btnNetworkManager->width()+16; - ui->btnNetworkManager->move(width() - x, height() - y); + x = x + widgetNetworkManager->width()+16; + widgetNetworkManager->move(width() - x, height() - y); - x = x + ui->btnSwitchUser->width()+16; - ui->btnSwitchUser->move(width() - x, height() - y); + if(!ui->btnSwitchUser->isHidden()) { + x = x + ui->btnSwitchUser->width()+16; + ui->btnSwitchUser->move(width() - x, height() - y); + } + + x = x + ui->btnBatteryStatus->width()+16; + ui->btnBatteryStatus->move(width() - x, height() - y); setVirkeyboardPos(); + if (mBatteryWidget) { + mBatteryWidget->setFixedSize(314, 112); + mBatteryWidget->setPoint(QPoint(width() - 334, ui->btnBatteryStatus->y() - 16)); + } + + if(scrollContents && usersMenu) - scrollContents->setFixedSize(usersMenu->width() - 14, usersMenu->height()); + scrollContents->setFixedSize(usersMenu->width(), usersMenu->height()); //设置弹出菜单,设置弹出菜单的坐标为切换用户按钮的上方,中间保持一定间隔。 if(scrollArea){ if(scrollContents->height() < height()/2){ scrollArea->setFixedSize(usersMenu->width(),scrollContents->height()+1); - }else{ - scrollArea->setFixedSize(usersMenu->width() + 4, height()/2); - } + + scrollArea->clearMask(); + }else{ + scrollArea->setFixedSize(usersMenu->width() + 16, height()/2); + + QBitmap bitMap(scrollArea->width(),scrollArea->height()); // 定义一个窗口大小的位图 + bitMap.fill(); // 填充整个位图 + QPainter painter(&bitMap); // 定义绘图设备 + painter.setBrush(Qt::black); // 必须定义为黑色 + painter.setPen(Qt::NoPen); // 只能为黑色或者不设置画笔 + painter.setRenderHint(QPainter::Antialiasing);// 反走样 + painter.drawRoundedRect(bitMap.rect(),8,8); // 绘制圆角矩形 + scrollArea->setMask(bitMap); + } scrollArea->move(ui->btnSwitchUser->geometry().x()- scrollArea->width()/2 + 24, \ - height() - y - scrollArea->height() - 5); + height() - y - scrollArea->height() - 8); } if(m_kylinNM){ m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, - this->height() - m_kylinNM->height() - 100, + this->height() - m_kylinNM->height() - y - 8, m_kylinNM->width(), m_kylinNM->height()); } @@ -788,7 +1728,9 @@ void LockWidget::resizeEvent(QResizeEvent *event) powermanager->width(),powermanager->height()); } - XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + if(QX11Info::isPlatformX11()){ + // XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } } @@ -805,17 +1747,19 @@ void LockWidget::onUserAdded(const UserItem &user) widget->setFixedSize(240, 40); QLabel *iconlabel =new QLabel(widget); QPixmap p(user.icon); + p = scaledPixmap(p); p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); p = PixmapToRound(p, 16*scale); iconlabel->setPixmap(p); //iconlabel->setStyleSheet("background-color:transparent;"); iconlabel->setGeometry(8,4,32,32); - QLabel *textlabel =new QLabel(widget); - textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); - textlabel->setGeometry(48,8,190,24); + KLabel *textlabel =new KLabel(widget); + textlabel->setFontSize(16); + textlabel->setGeometry(48,4,190,30); if(getLoadStatus(user.name)){ QLabel *statusIcon = new QLabel(widget); QPixmap status(":/image/assets/selected.svg"); + status = scaledPixmap(status); status = status.scaled(14*scale,14*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); p = PixmapToRound(status, 7*scale); statusIcon->setPixmap(status); @@ -823,38 +1767,12 @@ void LockWidget::onUserAdded(const UserItem &user) } action->setDefaultWidget(widget); - QFont font; - font.setPixelSize(16); - QString str = ElideText(font,189,user.realName); - if(user.realName != str){ - textlabel->setToolTip(user.realName); - textlabel->setText(str); - } else { - textlabel->setText(user.realName); - } + textlabel->setElideText(user.realName, textlabel->width()); action->setData(user.name); usersMenu->addAction(action); usersMenu->adjustSize(); } -QPixmap LockWidget::PixmapToRound(const QPixmap &src, int radius) -{ - if (src.isNull()) { - return QPixmap(); - } - - QPixmap pixmapa(src); - QPixmap pixmap(radius*2,radius*2); - pixmap.fill(Qt::transparent); - QPainter painter(&pixmap); - painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - QPainterPath path; - path.addEllipse(0, 0, radius*2, radius*2); - painter.setClipPath(path); - painter.drawPixmap(0, 0, radius*2, radius*2, pixmapa); - return pixmap; -} - void LockWidget::onUserDeleted(const UserItem &user) { for(auto action : usersMenu->actions()) @@ -914,11 +1832,6 @@ void LockWidget::onUserMenuTrigged(QAction *action) { qDebug() << action->data().toString() << "selected"; - if(authDialog) - { - authDialog->stopAuth(); - } - QString userName = action->data().toString(); for (int i =0; i < list.count(); i++) { @@ -930,40 +1843,114 @@ void LockWidget::onUserMenuTrigged(QAction *action) "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); } } - if(userName == "Guest") - { - displayManager->switchToGuest(); - } - else if(userName == "SwitchUser") - { - displayManager->switchToGreeter(); - } - else - { - displayManager->switchToUser(userName); - } + SwitchToUser(userName); } bool LockWidget::exitSubWidget() { bool allExited = true; - if(scrollArea && scrollArea->isVisible()){ - scrollArea->hide(); + if(mBatteryWidget && mBatteryWidget->isVisible()) { + setCheckedSheet(BATTERYBTN, false); + at_plugins = false; + if(tabAt == BOTTMBTN && horAT == BATTERYBTN) + ui->btnBatteryStatus->setStyleSheet(ON_TAB_SHEET); + } else if(scrollArea && scrollArea->isVisible()){ + setCheckedSheet(SWITCHBTN, false); + at_plugins = false; + if(tabAt == BOTTMBTN && horAT == SWITCHBTN) + ui->btnSwitchUser->setStyleSheet(ON_TAB_SHEET); allExited = false; - } - if(powermanager && powermanager->isVisible()){ - authDialog->setFocus(); + } else if(m_kylinNM && m_kylinNM->isVisible()){ + setCheckedSheet(NETWORKBTN, false); + at_plugins = false; + if(tabAt == BOTTMBTN && horAT == NETWORKBTN) + widgetNetworkManager->setStyleSheet(ON_TAB_SHEET_WIDGET); + allExited = false; + } else if(vKeyboard && vKeyboard->isVisible()) { + vKeyboard->hide(); + at_plugins = false; + if(tabAt == BOTTMBTN && horAT == KEYBOARDBTN) + ui->btnKeyboard->setStyleSheet(ON_TAB_SHEET); + allExited = false; + } else if(powermanager && powermanager->isVisible()){ authDialog->show(); powermanager->hide(); + if(!authDialog->getLineeditStatus()) { + tabAt = LINEEDIT; + authDialog->setFocusin(IN_LINEEDIT); + if(isTableMode && !(vKeyboard && vKeyboard->isVisible())) { + showVirtualKeyboard(); + } + } else { + tabAt = MESSAGEBTN; + authDialog->setFocusin(ON_MESSAGEBTN); + } + setBottomBtnSheet(); + powermanager->clearStatus(); + at_power = false; allExited = false; + return allExited; } - if(m_kylinNM && m_kylinNM->isVisible()){ - m_kylinNM->hide(); - allExited = false; - } + if(tabAt != LINEEDIT && tabAt != MESSAGEBTN && tabAt != ENTERBTN && tabAt != BIOBTN) + authDialog->setFocusin(REMOVE); return allExited; } +void LockWidget::onActiveLineedit() +{ + if(tabAt == LINEEDIT || (tabAt == BOTTMBTN && horAT == KEYBOARDBTN)) { /* + 重启时session拉其他组件时会多次设置焦点 + 这个时候如果是平板模式,因为已经弹出了虚拟键盘 tabAt就会是BOTTOM + */ + if(authDialog && authDialog->isVisible()) { + if(!authDialog->getLineeditStatus()) { + authDialog->setFocusin(IN_LINEEDIT); +// if(isTableMode && !(vKeyboard && vKeyboard->isVisible())) +// showVirtualKeyboard(); + } else { + tabAt = MESSAGEBTN; + authDialog->setFocusin(ON_MESSAGEBTN); + } + } + } +} + +QString LockWidget::getBatteryIconName() +{ + if (iface->isValid() && dface->isValid()) { + bool batteryState = false; + QDBusReply reply = batInterface->call("Get", UPOWER_SERVICE, "OnBattery"); + if (reply.isValid()) { + batteryState = reply.value().toBool(); + } + double percentage = -1.0; + QDBusReply percentage_reply = iface->call("Get", UPOWER_DIVICES_SERVICE, "Percentage"); + if (percentage_reply.isValid()) { + percentage = percentage_reply.value().toDouble(); + } + + if (true == batteryState) { + return QString("battery-level-%1-symbolic").arg((int)percentage / 10 * 10); + } else { + return QString("battery-level-%1-charging-symbolic").arg((int)percentage / 10 * 10); + } + } + return QString(); +} + +int LockWidget::getLoginedNum() +{ + if(loginedNum != 0) + return loginedNum; + for(auto user : users->getUsers()) + { + if(getLoadStatus(user.name)){ + loginedNum++; + } + } + return loginedNum; +} + QDBusArgument &operator <<(QDBusArgument &arg, const userInfo &usersInfo) { arg.beginStructure(); @@ -983,5 +1970,98 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, userInfo &usersInfo) return arg; } +bool LockWidget::IsDesktopStarted() +{ + QDBusInterface *iface = new QDBusInterface(DESKTOP_DBUS_SERVICE, + DESKTOP_DBUS_PATH, + DESKTOP_DBUS_INTERFACE, + QDBusConnection::sessionBus(), + this); + if (iface) { + if (iface->isValid()) { + delete iface; + return true; + } + delete iface; + } + return false; +} +void LockWidget::setRootWindow() +{ + QStringList keysMateBg; + QString strUserBgFile = ""; + QString strUserBgColor = ""; + QString strUserBgOptions = ""; + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_MATE_BG)){ + QGSettings *mateBgSettings = new QGSettings(GSETTINGS_SCHEMA_MATE_BG, "", this); + keysMateBg = mateBgSettings->keys(); + if (keysMateBg.contains(KEY_PICTURE_FILENAME)) { + strUserBgFile = mateBgSettings->get(KEY_PICTURE_FILENAME).toString(); + } + if (keysMateBg.contains(KEY_PRIMARY_COLOR)) { + strUserBgColor = mateBgSettings->get(KEY_PRIMARY_COLOR).toString(); + } + if (keysMateBg.contains(KEY_PICTURE_OPTIONS)) { + strUserBgOptions = mateBgSettings->get(KEY_PICTURE_OPTIONS).toString(); + } + qDebug()<<"User bg info:"<getDefaultBackgroundName(); + } + if(nDrawBgType == 0) { + qDebug()<<"DrawBgFile:"< #include #include +#include +#include +#include +#include +#include "kylin-nm/kylin-nm-interface.h" #include "surewindow.h" +#include "lockchecker.h" #include "xeventmonitor.h" +#include "batterywidget.h" +#include "libinputswitchevent.h" namespace Ui { class LockWidget; @@ -42,9 +50,10 @@ struct userInfo { QDBusArgument &operator <<(QDBusArgument &arg, const userInfo &usersInfo); const QDBusArgument &operator >>(const QDBusArgument &arg, userInfo &usersInfo); -class VirtualKeyboard; +class VirtualKeyboardWidget; class PowerManager; class AuthDialog; +class Configuration; class Users; class UserItem; class DisplayManager; @@ -52,6 +61,24 @@ class QMenu; class QScrollArea; class KylinNM; +enum TABAT { + EMPTY = -1, + LINEEDIT = 0, + ENTERBTN, + BIOBTN, + BOTTMBTN, + POWERMANAGER, + MESSAGEBTN, +}; + +enum HORIZONBTN { + BATTERYBTN = 0, + SWITCHBTN, + NETWORKBTN, + KEYBOARDBTN, + POWERBTN, +}; + class LockWidget : public QWidget { Q_OBJECT @@ -64,33 +91,72 @@ public: void stopAuth(); void setX11Focus(); bool exitSubWidget(); + void setStartupMode(bool mode); + void onActiveLineedit(); + QString getBatteryIconName(); + void key_enter_release(int key); + void onSessionActiveChanged(bool isActive); + Q_SIGNALS: void closed(); + void keyGlobalRelease(int key); // void capsLockChanged(); private: void initUI(); void initUserMenu(); void setVirkeyboardPos(); - void updateNetIcon(int status); bool getLoadStatus(const QString &name); int getNetStatus(); - QPixmap PixmapToRound(const QPixmap &src, int radius); - void keyBdRelease(QString key); + void key_OB_release(int key); + void key_tab_release(int key); + void key_shiftTab_release(); + void key_LR_release(int key); + int getLoginedNum(); + void loadNetPlugin(); + void setBottomBtnSheet(); + void setCheckedSheet(int type, bool show); + void netResetLocation(); + + /** + * @brief IsDesktopStarted 桌面是否已启动 + * @return + */ + bool IsDesktopStarted(); + + /** + * @brief setRootWindow 设置X背景 + */ + void setRootWindow(); + + void SwitchToUser(QString strUserName); + private Q_SLOTS: void onUserAdded(const UserItem &user); void onUserDeleted(const UserItem &user); void onUserMenuTrigged(QAction *action); void showVirtualKeyboard(); - void showPowerManager(); - void showNetManager(); + void netInPutStatus(); + void showPowerManager(bool keynavigation = false); + void showUserMenu(); + void showNetManager(bool keynavigation = false); + void showBattery(); void switchToGreeter(); void switchToSureDialog(int type); + void showWarning(QVector &list, int type); void hideSureDialog(); void confirmClicked(); - void hideNetManager(); - void onGlobalKeyPress(const QString &key); - void onGlobalkeyRelease(const QString &key); + void onClickPassword(); + void hideBottomPlugins(); + void resetNavigation(); + void setBatteryIcon(QString str); + void dealMessage(QDBusMessage); + void onShowMessageBtn(bool is_show); + /** + * @brief onAuthenticateCompete 认证完成 + */ + void onAuthenticateCompete(); + protected: bool eventFilter(QObject *obj, QEvent *event); void resizeEvent(QResizeEvent *event); @@ -99,7 +165,8 @@ protected: private: Ui::LockWidget *ui; AuthDialog *authDialog; - VirtualKeyboard *vKeyboard = nullptr; + Configuration *configuration; + VirtualKeyboardWidget *vKeyboard = nullptr; PowerManager *powermanager = nullptr; SureWindow *sureWidget = nullptr; QTimer *timer; @@ -112,13 +179,40 @@ private: QScrollArea *scrollArea; QWidget *scrollContents; - KylinNM *m_kylinNM = nullptr; + QWidget *m_kylinNM = nullptr; + BatteryWidget *mBatteryWidget = nullptr; + QTabWidget *mkylinNM = nullptr; QWidget *m_NetManagerWidget; QStringList m_loginedUser; bool isNetFinished = false; int powermanagerType; - XEventMonitor *xEventMonitor; int nowAt = -1; + int loginedNum = 0; + QWidget *widgetNetworkManager = nullptr; + QPushButton *btnNetworkManager = nullptr; + bool m_isStartupMode = false; + bool is_switchBtn = true; + bool is_batteryBtn = true; + bool is_keynavigation =false; + int tabAt = LINEEDIT; + int horAT = BATTERYBTN; + bool at_power = false; + bool at_plugins = false; + + QDBusInterface *batInterface = nullptr; + QDBusInterface *iface = nullptr; + QDBusInterface *dface = nullptr; + + + // 监听键盘插拔 + LibinputSwitchEvent *libswitch = nullptr; + bool isTableMode = false; + bool m_isShowKeyboard = false; // 打开电源管理界面前虚拟键盘是否已打开 + + double curFontSize = 0; + QFuture m_futureLoadDeskBg; + + QTimer *m_timerChkActive = nullptr; }; #endif // LOCKWIDGET_H diff --git a/src/lockwidget.ui b/src/lockwidget.ui index 22caea6..9ca0558 100644 --- a/src/lockwidget.ui +++ b/src/lockwidget.ui @@ -28,6 +28,23 @@ Qt::NoFocus + + QPushButton{ + text-align:center; + color: rgb(255, 255, 255, 255); + border: none; + border-radius: 4px; + outline: none; +} +QPushButton::hover{ + background-color: rgb(255,255,255,15%); +} +QPushButton::pressed { + background-color: rgba(255,255,255,40%); +} + + + @@ -43,14 +60,14 @@ - + Time - + Date @@ -73,6 +90,23 @@ Qt::NoFocus + + QPushButton{ + text-align:center; + color: rgb(255, 255, 255, 255); + border: none; + border-radius: 4px; + outline: none; +} +QPushButton::hover{ + background-color: rgb(255,255,255,15%); +} +QPushButton::pressed { + background-color: rgba(255,255,255,40%); +} + + + @@ -89,30 +123,69 @@ PointingHandCursor + + QPushButton{ + text-align:center; + color: rgb(255, 255, 255, 255); + border: none; + border-radius: 4px; + outline: none; +} +QPushButton::hover{ + background-color: rgb(255,255,255,15%); +} +QPushButton::pressed { + background-color: rgba(255,255,255,40%); +} + + + - + - 370 + 330 10 - 80 - 26 + 97 + 32 PointingHandCursor - - Qt::NoFocus + + QPushButton::menu-indicator{ + image:none; +} +QPushButton{ + text-align:center; + color: rgb(255, 255, 255, 255); + border: none; + border-radius: 4px; + outline: none; +} +QPushButton::hover{ + background-color: rgb(255,255,255,15%); +} +QPushButton::pressed { + background-color: rgba(255,255,255,40%); +} + + + KLabel + QLabel +
klabel.h
+
+
diff --git a/src/logind.cpp b/src/logind.cpp index 34c00ed..e8817ac 100644 --- a/src/logind.cpp +++ b/src/logind.cpp @@ -24,6 +24,7 @@ const static QString login1Service = QStringLiteral("org.freedesktop.login1"); const static QString login1Path = QStringLiteral("/org/freedesktop/login1"); +const static QString propertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties"); const static QString login1ManagerInterface = QStringLiteral("org.freedesktop.login1.Manager"); const static QString login1SessionInterface = QStringLiteral("org.freedesktop.login1.Session"); @@ -34,12 +35,11 @@ LogindIntegration::LogindIntegration(QObject *parent) login1Path, login1ManagerInterface, QDBusConnection::systemBus()); - QDBusReply sessionPath = loginInterface.call("GetSessionByPID",(quint32) QCoreApplication::applicationPid()); + QDBusReply sessionPath = loginInterface.call("GetSession", "auto"); if(!sessionPath.isValid()){ qWarning()<< "Get session error:" << sessionPath.error(); } else{ - QString session = sessionPath.value().path(); QDBusConnection::systemBus().connect(login1Service, session, @@ -53,9 +53,56 @@ LogindIntegration::LogindIntegration(QObject *parent) QStringLiteral("Unlock"), this, SIGNAL(requestUnlock())); + + // 获取会话激活状态 + QDBusInterface iface(login1Service, + session, + propertiesInterface, + QDBusConnection::systemBus()); + QDBusReply reply = iface.call("Get", login1SessionInterface, "Active"); + if (reply.isValid()) { + m_isSessionActive = reply.value().toBool(); + qDebug()<<"Session is active:"< +#include #include class QDBusServiceWatcher; @@ -28,15 +29,20 @@ class LogindIntegration : public QObject Q_OBJECT public: explicit LogindIntegration(QObject *parent = nullptr); - ~LogindIntegration() override; + virtual ~LogindIntegration(); + + bool isSessionActive(); + +public Q_SLOTS: + void onSessionPropChanged(QString, QVariantMap, QStringList); Q_SIGNALS: void requestLock(); void requestUnlock(); - void connectedChanged(); + void sessionActiveChanged(bool isActive); private: - + bool m_isSessionActive = false; }; #endif diff --git a/src/loginedusers.cpp b/src/loginedusers.cpp new file mode 100644 index 0000000..bd4d247 --- /dev/null +++ b/src/loginedusers.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "loginedusers.h" + +QDBusArgument &operator<<(QDBusArgument &argument, const LoginedUsers &mystruct) +{ + argument.beginStructure(); + argument << mystruct.uid << mystruct.userName << mystruct.objpath;//< mystruct.usergroup; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, LoginedUsers &mystruct) +{ + argument.beginStructure(); + argument >> mystruct.uid >> mystruct.userName >> mystruct.objpath;// >> mystruct.usergroup; + argument.endStructure(); + return argument; +} diff --git a/src/loginedusers.h b/src/loginedusers.h new file mode 100644 index 0000000..de1b175 --- /dev/null +++ b/src/loginedusers.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#ifndef LOGINEDUSER_H +#define LOGINEDUSER_H + +#include + +struct LoginedUsers +{ + int uid; + QString userName; + QDBusObjectPath objpath; +}; + +QDBusArgument &operator<<(QDBusArgument &argument, const LoginedUsers &mystruct); + +const QDBusArgument &operator>>(const QDBusArgument &argument, LoginedUsers &mystruct); + + + +Q_DECLARE_METATYPE(LoginedUsers) + +#endif // LOGINEDUSER_H diff --git a/src/loginoptionswidget.cpp b/src/loginoptionswidget.cpp index c35e09d..f2f1b95 100644 --- a/src/loginoptionswidget.cpp +++ b/src/loginoptionswidget.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "loginoptionswidget.h" #include @@ -6,23 +23,46 @@ #include #include "giodbus.h" #include "biometricdeviceinfo.h" +#include "configuration.h" +#include "klabel.h" +#include #include #include #include #include #include +#include #include #include #include #include #include +#include -LoginOptionsWidget::LoginOptionsWidget(BiometricProxy* proxy, int uid, QWidget *parent) +#define ON_TAB_SHEET "QPushButton{background-color: rgba(255,255,255,15%); border-radius: 4px; border: 2px solid #2C73C8;}" +#define ON_NORMAL_SHEET "QPushButton{background-color: rgba(255,255,255,15%); border-radius: 4px; border: none;}\ + QPushButton::hover{ background-color: rgba(255,255,255,40%);}\ + QPushButton::pressed {background-color: rgba(255,255,255,40%);}\ + QPushButton::checked {background-color: rgba(255, 255, 255, 40%);}" + +LoginOptionsWidget::LoginOptionsWidget(BiometricProxy* proxy, int uid, UniAuthService* uniauthService, QWidget *parent) : QWidget(parent) , m_biomericProxy(proxy) , m_uid(uid) + , m_uniauthService(uniauthService) + , configuration(Configuration::instance()) { + m_listPriority.clear(); + m_listPriority.push_back(BioT_Face); + m_listPriority.push_back(BioT_FingerPrint); + m_listPriority.push_back(BioT_Iris); + m_listPriority.push_back(BioT_VoicePrint); + m_listPriority.push_back(BioT_FingerVein); + m_listPriority.push_back(REMOTE_QRCODE_TYPE); + m_listPriority.push_back(UniT_General_Ukey); + curFontSize = configuration->getFontSize(); + m_ptToPx = configuration->getPtToPx(); initUI(); initConnections(); m_mapDisableDev.clear(); @@ -35,7 +75,7 @@ LoginOptionsWidget::~LoginOptionsWidget() void LoginOptionsWidget::initUI() { - this->setFixedHeight(86); + this->setFixedHeight(94); // 初始化UI m_layoutMain = new QVBoxLayout(); m_layoutMain->setContentsMargins(0,0,0,0); @@ -44,10 +84,11 @@ void LoginOptionsWidget::initUI() m_layoutOptBtns->setContentsMargins(0,0,0,0); m_layoutOptBtns->setSpacing(16); - m_labelOptTitle = new QLabel(); + m_labelOptTitle = new KLabel(); m_labelOptTitle->setAlignment(Qt::AlignCenter); + m_labelOptTitle->setFontSize(16); m_labelOptTitle->setText(tr("Login Options")); - m_labelOptTitle->setFixedHeight(22); + m_labelOptTitle->setFixedHeight(30); m_layoutMain->addWidget(m_labelOptTitle); m_btnGroup = new QButtonGroup(this); @@ -91,6 +132,18 @@ unsigned LoginOptionsWidget::getLoginOptCount() return m_mapDevices.size(); } +int LoginOptionsWidget::getVisibleLoginOptCount() +{ + int nCount = 0; + QMap::iterator itMapBtn = m_mapOptBtns.begin(); + for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { + if (itMapBtn.value() && itMapBtn.value()->isVisible()) { + nCount ++; + } + } + return nCount; +} + DeviceInfoPtr LoginOptionsWidget::getFirstDevInfo() { DeviceInfoPtr devInfo = nullptr; @@ -129,35 +182,58 @@ DeviceInfoPtr LoginOptionsWidget::getFirstDevInfo() return devInfo; } +DeviceInfoPtr LoginOptionsWidget::getWechatDevice() +{ + DeviceInfoPtr devInfo = nullptr; + DeviceMap::iterator itDevInfo = m_mapDevices.begin(); + for (; itDevInfo != m_mapDevices.end(); itDevInfo++) { + for (auto devinfo : itDevInfo.value()) { + if (devinfo && devinfo->deviceType == REMOTE_QRCODE_TYPE) { + if (!isDeviceDisable(devinfo->id)) { + devInfo = devinfo; + break; + } + } + } + if (devInfo) { + break; + } + } + return devInfo; +} + void LoginOptionsWidget::addOptionButton(unsigned uLoginOptType, int nDrvId, QString strDrvName) { if (m_mapOptBtns.contains(nDrvId)) { return ; } - QToolButton *newButton = new QToolButton(); - QVBoxLayout *layoutBtn = new QVBoxLayout(); - newButton->setLayout(layoutBtn); - QLabel *newLabel = new QLabel(); - layoutBtn->setAlignment(Qt::AlignCenter); - layoutBtn->addWidget(newLabel); + QPushButton *newButton = new QPushButton(); +// QVBoxLayout *layoutBtn = new QVBoxLayout(); +// newButton->setLayout(layoutBtn); +// QLabel *newLabel = new QLabel(); +// layoutBtn->setAlignment(Qt::AlignCenter); +// layoutBtn->addWidget(newLabel); newButton->setCheckable(true); newButton->setChecked(false); newButton->setFocusPolicy(Qt::NoFocus); - if (nDrvId == -1) { - //newButton->setEnabled(false); - newButton->setChecked(true); - //屏蔽鼠标事件 - newButton->setAttribute(Qt::WA_TransparentForMouseEvents, true); - } else { +// if (nDrvId == -1) { +// //newButton->setEnabled(false); +// newButton->setChecked(true); +// //屏蔽鼠标事件 +// newButton->setAttribute(Qt::WA_TransparentForMouseEvents, true); +// } else { int nLength = m_btnGroup->buttons().length(); m_btnGroup->addButton(newButton, nLength); m_listDriveId.append(nDrvId); - } + // } QPixmap iconPixmap; switch (uLoginOptType) { case LOGINOPT_TYPE_PASSWORD: iconPixmap = loadSvg(":/image/assets/ukui-loginopt-password.svg", "white", 16); break; + case LOGINOPT_TYPE_GENERAL_UKEY: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-ukey.svg", "white", 16); + break; case LOGINOPT_TYPE_FACE: iconPixmap = loadSvg(":/image/assets/ukui-loginopt-face.svg", "white", 16); break; @@ -177,9 +253,15 @@ void LoginOptionsWidget::addOptionButton(unsigned uLoginOptType, int nDrvId, QSt iconPixmap = loadSvg(":/image/assets/ukui-loginopt-qrcode.svg", "white", 16); break; } - newLabel->setPixmap(iconPixmap); + newButton->setIcon(iconPixmap); + //newLabel->setPixmap(iconPixmap); newButton->setToolTip(strDrvName); - newButton->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + sysFont.setPointSize((14 + curFontSize) *m_ptToPx); + QToolTip::setFont(sysFont); + newButton->setStyleSheet("QPushButton{text-align:center;background-color: rgb(255,255,255,15%);border: none;border-radius: 4px;outline: none;}" + "QPushButton::hover{background-color: rgb(255,255,255,40%);}" + "QPushButton::pressed {background-color: rgba(255,255,255,40%);}" + "QPushButton::checked {background-color: rgba(255,255,255,40%);}"); newButton->setFixedSize(48, 48); if (isDeviceDisable(nDrvId)) { newButton->setDisabled(true); @@ -193,7 +275,7 @@ void LoginOptionsWidget::addOptionButton(unsigned uLoginOptType, int nDrvId, QSt void LoginOptionsWidget::clearOptionButtons() { - QMap::iterator itMapBtn = m_mapOptBtns.begin(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { if (itMapBtn.value()) { m_btnGroup->removeButton(itMapBtn.value()); @@ -205,36 +287,71 @@ void LoginOptionsWidget::clearOptionButtons() m_mapOptBtns.clear(); } +bool LoginOptionsWidget::getHasUkeyOptions() +{ + return isShowUkey; +} + void LoginOptionsWidget::updateOptionButtons() { + isShowUkey = false; clearOptionButtons(); - //addOptionButton(LOGINOPT_TYPE_PASSWORD, -1, tr("Password")); + addOptionButton(LOGINOPT_TYPE_PASSWORD, -1, tr("Password")); DeviceMap::iterator itMapDev = m_mapDevices.begin(); for ( ; itMapDev != m_mapDevices.end(); itMapDev++) { for (DeviceInfoPtr devPtr : itMapDev.value()) { if (devPtr) { + if(devPtr->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + //ukey 设备类型排在二维码前,但实际上应该显示在二维码之后,因此暂时不添加 + isShowUkey = true; + continue; + } addOptionButton(itMapDev.key(), devPtr->id, DeviceType::getDeviceType_tr(devPtr->deviceType)); } } } + + itMapDev = m_mapDevices.begin(); + if(isShowUkey){ + for ( ; itMapDev != m_mapDevices.end(); itMapDev++) { + for (DeviceInfoPtr devPtr : itMapDev.value()) { + if(devPtr && devPtr->deviceType == LOGINOPT_TYPE_GENERAL_UKEY){ + //此处才添加ukey + addOptionButton(itMapDev.key(), devPtr->id, DeviceType::getDeviceType_tr(devPtr->deviceType)); + } + } + } + } + + //存在特征但没有插入ukey + if(!isShowUkey && m_biomericProxy->GetHasUkeyFeature(m_uid) ){ + addOptionButton(LOGINOPT_TYPE_GENERAL_UKEY,-2,DeviceType::getDeviceType_tr(LOGINOPT_TYPE_GENERAL_UKEY)); + isShowUkey = true; + } + qDebug()<<"m_mapOptBtns.size():"<hide(); - QMap::iterator itMapBtn = m_mapOptBtns.begin(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { if (itMapBtn.value()) { itMapBtn.value()->hide(); } } - } else { + }else { m_labelOptTitle->show(); - QMap::iterator itMapBtn = m_mapOptBtns.begin(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { if (itMapBtn.value()) { itMapBtn.value()->show(); } } } + m_mapOptBtns[-1]->hide(); + if(m_mapOptBtns.size() == 2 && isShowUkey) { + m_mapOptBtns[-1]->show(); + } } void LoginOptionsWidget::setUser(int uid) @@ -246,27 +363,47 @@ void LoginOptionsWidget::setUser(int uid) void LoginOptionsWidget::readDevicesInfo() { m_mapDevices.clear(); - bool isAuthEnable = GetAuthEnable(); - bool isQRCodeEnable = GetQRCodeEnable(); + bool isAuthEnable = getBioAuthEnable(ENABLETYPE_SAVER); + bool isQRCodeEnable = getQRCodeEnable(); DeviceList deviceList = m_biomericProxy->GetDevList(); - for(auto pDeviceInfo : deviceList) - { - qDebug()<<"BeginGetFeature------!"; - int nDevFeatureCount = m_biomericProxy->GetUserDevFeatureCount(m_uid,pDeviceInfo->id); - qDebug() << *pDeviceInfo << ",feautres:"< 0) { - if (!isAuthEnable && pDeviceInfo->deviceType <= DeviceType::VoicePrint) - continue; - if (!isQRCodeEnable && pDeviceInfo->deviceType == REMOTE_QRCODE_TYPE) - continue; + QStringList listDefDevices = getAllDefDevices(); + qDebug()<<"BeginGetFeature------!"; + FeatureMap mapFeatures = m_biomericProxy->GetUserFeatures(m_uid); + qDebug() << m_uid <<",count:"<deviceType <= DeviceType::VoicePrint) + continue; + if (!isQRCodeEnable && pDeviceInfo->deviceType == REMOTE_QRCODE_TYPE) + continue; + int nFeatureCount = 0; + if (mapFeatures.contains(pDeviceInfo->shortName)) { + nFeatureCount = mapFeatures[pDeviceInfo->shortName].size(); + } + qDebug() << *pDeviceInfo <<",count:"< 0) { int nDevType = LOGINOPT_TYPE_OTHERS; nDevType = convertDeviceType(pDeviceInfo->deviceType); - m_mapDevices[nDevType].push_back(pDeviceInfo); + if (listDefDevices.contains(pDeviceInfo->shortName) && + !m_mapDevices.contains(nDevType)) { + m_mapDevices[nDevType].push_back(pDeviceInfo); + } } } + updateOptionButtons(); } +void LoginOptionsWidget::SetExtraInfo(QString extra_info, QString info_type) +{ + if(!m_biomericProxy) + { + qWarning() << "BiometricProxy doesn't exist."; + return; + } + m_biomericProxy->SetExtraInfo(info_type,extra_info); +} + void LoginOptionsWidget::startAuth(DeviceInfoPtr device, int uid) { if(!m_biomericProxy) @@ -292,7 +429,27 @@ void LoginOptionsWidget::startAuth(DeviceInfoPtr device, int uid) this->m_curLoginOptType = convertDeviceType(this->m_curDevInfo->deviceType); updateUIStatus(); SetLastDevice(this->m_strUserName, this->m_curDevInfo->id); - startAuth_(); + if(this->m_curLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY) + startUkeyAuth(); + else + startAuth_(); +} + +void LoginOptionsWidget::startUkeyAuth() +{ + if (!m_curDevInfo) + return ; + qDebug().noquote() << QString("Identify:[drvid: %1, uid: %2]").arg(m_curDevInfo->id).arg(m_uid); + + m_isInAuth = true; + m_dupFD = -1; + + Q_EMIT setLoadingImage(); + m_biomericProxy->StopOps(m_curDevInfo->id); + QDBusPendingCall call = m_biomericProxy->UkeyIdentify(m_curDevInfo->id, 2,m_uid); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, &LoginOptionsWidget::onIdentifyComplete); } void LoginOptionsWidget::startAuth_() @@ -304,6 +461,8 @@ void LoginOptionsWidget::startAuth_() m_isInAuth = true; m_dupFD = -1; + Q_EMIT setLoadingImage(); + m_biomericProxy->StopOps(m_curDevInfo->id); QDBusPendingCall call = m_biomericProxy->Identify(m_curDevInfo->id, m_uid); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, &QDBusPendingCallWatcher::finished, @@ -327,7 +486,7 @@ void LoginOptionsWidget::stopAuth() Q_EMIT updateImage(QImage()); } -void LoginOptionsWidget::onIdentifyComplete(QDBusPendingCallWatcher *watcher) +void LoginOptionsWidget::onUkeyIdentifyComplete(QDBusPendingCallWatcher *watcher) { if(m_isStopped == true) return ; @@ -339,12 +498,37 @@ void LoginOptionsWidget::onIdentifyComplete(QDBusPendingCallWatcher *watcher) Q_EMIT authComplete(false, -1); return; } + int result = reply.argumentAt(0).toInt(); + int authUid = reply.argumentAt(1).toInt(); + qDebug() << result << authUid << m_uid; + if(result == DBUS_RESULT_SUCCESS) { + qDebug() << "Identify success"; + Q_EMIT authComplete(true, 0); + } else { + qDebug() << "Identify failed"; + Q_EMIT authComplete(false, 2); + } +} + +void LoginOptionsWidget::onIdentifyComplete(QDBusPendingCallWatcher *watcher) +{ + if(m_isStopped == true) + return ; + + QDBusPendingReply reply = *watcher; + if(reply.isError()) + { + qWarning() << "Identify error: " << reply.error().message(); + Q_EMIT authComplete(false, -1); + return; + } + int result = reply.argumentAt(0).toInt(); int authUid = reply.argumentAt(1).toInt(); qDebug() << result << authUid << m_uid; // 特征识别成功,而且用户id匹配 - if(result == DBUS_RESULT_SUCCESS && authUid == m_uid) { + if(result == DBUS_RESULT_SUCCESS && authUid == m_uid) { qDebug() << "Identify success"; Q_EMIT authComplete(true, 0); } else if(result == DBUS_RESULT_NOTMATCH) { // 特征识别不匹配 @@ -362,6 +546,10 @@ void LoginOptionsWidget::onIdentifyComplete(QDBusPendingCallWatcher *watcher) Q_EMIT authComplete(false, 1); } else if (ret.opsStatus == OPS_IDENTIFY_STOP_BY_USER || ret.opsStatus == OPS_VERIFY_STOP_BY_USER) { Q_EMIT authComplete(false, -2); // 主动停止,直接重试 + } else if (ret.opsStatus == OPS_OPEN_FAIL || ret.opsStatus == OPS_OPEN_ERROR) { // 无法打开设备(设备是坏的/被占用),直接禁用 + Q_EMIT authComplete(false, 5); + } else if (ret.opsStatus >= OPS_GET_FLIST_SUCCESS && ret.opsStatus <= OPS_GET_FLIST_MAX) { + Q_EMIT authComplete(false, -3); // 主动停止,直接重试 } else { Q_EMIT authComplete(false, 2); } @@ -520,7 +708,10 @@ void LoginOptionsWidget::onUSBDeviceHotPlug(int drvid, int action, int /*devNum* //设备数量发生了变化 if(count != savedCount) { updateOptionButtons(); - Q_EMIT notifyOptionsChange(count); + Q_EMIT notifyOptionsChange(count, at_bioBtn); + if(at_bioBtn && count >= 1) + tabOptionSelected(FirstDevice); + updateUIStatus(); } } @@ -531,17 +722,29 @@ bool LoginOptionsWidget::getAuthDouble() return distribId; } -void LoginOptionsWidget::updateUIStatus() +void LoginOptionsWidget::setSelectedPassword() { if (m_mapOptBtns.contains(-1)) { - QToolButton* btn = m_mapOptBtns[-1]; - if (btn) { + QPushButton* btn = m_mapOptBtns[-1]; + if (btn && btn->isVisible()) { + btn->setChecked(true); + } + m_curDevInfo = nullptr; + } +} + +void LoginOptionsWidget::updateUIStatus() +{ + if (!m_curDevInfo && m_mapOptBtns.contains(-1)) { + QPushButton* btn = m_mapOptBtns[-1]; + if (btn && btn->isVisible()) { btn->setChecked(true); } } + if (m_curDevInfo) { if (m_mapOptBtns.contains(m_curDevInfo->id)) { - QToolButton* btn = m_mapOptBtns[m_curDevInfo->id]; + QPushButton* btn = m_mapOptBtns[m_curDevInfo->id]; if (btn) { btn->setChecked(true); } @@ -549,18 +752,140 @@ void LoginOptionsWidget::updateUIStatus() } } -void LoginOptionsWidget::onOptionSelected(int nIndex) +void LoginOptionsWidget::onOptionSelected(int nIndex, bool keyNavigation) { if (nIndex < 0) return; + if(!keyNavigation) + tabOptionSelected(CLEAR); if (nIndex < m_listDriveId.size()) { DeviceInfoPtr info = findDeviceById(m_listDriveId[nIndex]); if (info && !isDeviceDisable(info->id)) { - Q_EMIT optionSelected(convertDeviceType(info->deviceType), info); + Q_EMIT optionSelected(convertDeviceType(info->deviceType), info, keyNavigation); + }else if(nIndex == 0 && m_listDriveId[nIndex] == -1){ + stopAuth(); + m_curDevInfo = nullptr; + Q_EMIT optionSelected(LOGINOPT_TYPE_PASSWORD, nullptr, keyNavigation); + }else if(m_listDriveId[nIndex] == -2){ + //存在ukey特征,但未插入ukey + stopAuth(); + m_curDevInfo = nullptr; + Q_EMIT optionSelected(LOGINOPT_TYPE_GENERAL_UKEY, nullptr, keyNavigation); } } } +void LoginOptionsWidget::tabOptionSelected(int option) +{ + switch(option) { + case RIGHT: + { + at_bioBtn = true; + int nCur = nowAt; + if(nCur >= 0 && nCur < m_listDriveId.count()) { + if (m_mapOptBtns.contains(m_listDriveId[nCur])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[nCur]]; + if (btn) { + btn->setStyleSheet(ON_NORMAL_SHEET); + } + } + } + for (int n = 0; n < m_listDriveId.count(); n ++) { + nCur = nCur + 1; + if (nCur >= m_listDriveId.count()) + nCur = 0; + if (m_mapOptBtns.contains(m_listDriveId[nCur])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[nCur]]; + if (btn && btn->isVisible()) { + btn->setStyleSheet(ON_TAB_SHEET); + nowAt = nCur; + break; + } + } + } + } + break; + case LEFT: + { + at_bioBtn = true; + int nCur = nowAt; + if(nCur >= 0 && nCur < m_listDriveId.count()) { + if (m_mapOptBtns.contains(m_listDriveId[nCur])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[nCur]]; + if (btn) { + btn->setStyleSheet(ON_NORMAL_SHEET); + } + } + } + for (int n = 0; n < m_listDriveId.count(); n ++) { + nCur = nCur - 1; + if (nCur < 0) + nCur = m_listDriveId.count() - 1; + if (m_mapOptBtns.contains(m_listDriveId[nCur])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[nCur]]; + if (btn && btn->isVisible()) { + btn->setStyleSheet(ON_TAB_SHEET); + nowAt = nCur; + break; + } + } + } + } + break; + case CLEAR: + at_bioBtn = false; + if(nowAt >= 0) { + for (int n = 0; n < m_listDriveId.count(); n ++) { + if (m_mapOptBtns.contains(m_listDriveId[n])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[n]]; + if (btn) { + btn->setStyleSheet(ON_NORMAL_SHEET); + } + } + } + nowAt = -1; + } + break; + case FirstDevice: + at_bioBtn = true; + if(nowAt >= 0) { + for (int n = 0; n < m_listDriveId.count(); n ++) { + if (m_mapOptBtns.contains(m_listDriveId[n])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[n]]; + if (btn) { + btn->setStyleSheet(ON_NORMAL_SHEET); + } + } + } + int nCur = 0; + for (int n = 0; n < m_listDriveId.count(); n ++) { + nCur = nCur + 1; + if (nCur >= m_listDriveId.count()) + nCur = 0; + if (m_mapOptBtns.contains(m_listDriveId[nCur])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[nCur]]; + if (btn && btn->isVisible()) { + btn->setStyleSheet(ON_TAB_SHEET); + nowAt = nCur; + break; + } + } + } + nowAt = 0; + } + break; + case CLICK: + at_bioBtn = false; + if (nowAt >= 0 && nowAt < m_listDriveId.count() && m_mapOptBtns.contains(m_listDriveId[nowAt])) { + QPushButton* btn = m_mapOptBtns[m_listDriveId[nowAt]]; + if (btn) { + onOptionSelected(nowAt, true); + } + } + break; + } +} + int LoginOptionsWidget::convertDeviceType(int nDevType) { int nLoginOptType = LOGINOPT_TYPE_OTHERS; @@ -580,6 +905,12 @@ int LoginOptionsWidget::convertDeviceType(int nDevType) case BioT_VoicePrint: nLoginOptType = LOGINOPT_TYPE_VOICEPRINT; break; + case UniT_General_Ukey: + nLoginOptType = LOGINOPT_TYPE_GENERAL_UKEY; + break; + case UniT_Advanced_Ukey: + nLoginOptType = LOGINOPT_TYPE_ADVANCED_UKEY; + break; case UniT_Remote: nLoginOptType = LOGINOPT_TYPE_QRCODE; break; @@ -594,7 +925,7 @@ void LoginOptionsWidget::setDeviceDisable(int nDevId, bool bDisable) { if (bDisable) { m_mapDisableDev[m_uid][nDevId] = true; - QMap::iterator itMapBtn = m_mapOptBtns.begin(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { if (itMapBtn.key() == nDevId && itMapBtn.value()) { itMapBtn.value()->setDisabled(true); @@ -603,7 +934,7 @@ void LoginOptionsWidget::setDeviceDisable(int nDevId, bool bDisable) } } else { m_mapDisableDev[m_uid][nDevId] = false; - QMap::iterator itMapBtn = m_mapOptBtns.begin(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { if (itMapBtn.key() == nDevId && itMapBtn.value()) { itMapBtn.value()->setDisabled(false); @@ -678,3 +1009,99 @@ QPixmap LoginOptionsWidget::drawSymbolicColoredPixmap(QPixmap &source, QString c } return QPixmap::fromImage(img); } + +bool LoginOptionsWidget::getBioAuthEnable(int nType) +{ + bool isEnable = false; + if (m_uniauthService && m_uniauthService->isActivatable()) { + struct passwd *pwInfo = getpwuid(m_uid); + if (pwInfo) { + isEnable = m_uniauthService->getBioAuthStatus(pwInfo->pw_name, ENABLETYPE_BIO); + if (isEnable) { + isEnable = m_uniauthService->getBioAuthStatus(pwInfo->pw_name, nType); + } + return isEnable; + } else { + return false; + } + } else { + return GetAuthEnable(); + } +} + +bool LoginOptionsWidget::getQRCodeEnable() +{ + if (m_uniauthService && m_uniauthService->isActivatable()) { + return m_uniauthService->getQRCodeEnable(); + } else { + return GetQRCodeEnable(); + } +} + +QString LoginOptionsWidget::getDefaultDevice(QString strUserName,int bioType) +{ + if (m_uniauthService && m_uniauthService->isActivatable()) { + QString defaultDeviceName = ""; + QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType); + if(!strDeviceName.isEmpty()) { + DeviceInfoPtr pDeviceInfo = findDeviceByName(strDeviceName); + if (pDeviceInfo) { + defaultDeviceName = strDeviceName; + } + } + return defaultDeviceName; + } else { + return GetDefaultDevice(strUserName); + } +} + +QString LoginOptionsWidget::getDefaultDevice(QString strUserName) +{ + if (m_uniauthService && m_uniauthService->isActivatable()) { + QString defaultDeviceName = ""; + for (auto bioType : m_listPriority) { + QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType); + if(!strDeviceName.isEmpty()) { + DeviceInfoPtr pDeviceInfo = findDeviceByName(strDeviceName); + if (pDeviceInfo) { + defaultDeviceName = strDeviceName; + break; + } + } + } + return defaultDeviceName; + } else { + return GetDefaultDevice(strUserName); + } +} + +QStringList LoginOptionsWidget::getAllDefDevices() +{ + QStringList listDefDevices; + if (m_uniauthService && m_uniauthService->isActivatable()) { + struct passwd *pwdInfo = getpwuid(m_uid); + if (pwdInfo) { + listDefDevices = m_uniauthService->getAllDefaultDevice(pwdInfo->pw_name); + } + } else { + QString defaultDeviceName; + + struct passwd *pwd = getpwuid(m_uid); + QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf"; + QSettings userConfig(userConfigFile, QSettings::IniFormat); + qDebug() << userConfig.fileName(); + defaultDeviceName = userConfig.value("DefaultDevice").toString(); + qDebug() << defaultDeviceName; + + if(defaultDeviceName.isEmpty()) { + QSettings sysConfig("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); + defaultDeviceName = sysConfig.value("DefaultDevice").toString(); + } + qDebug() << "default device: " << defaultDeviceName; + if(!defaultDeviceName.isEmpty()){ + listDefDevices.push_back(defaultDeviceName); + } + } + return listDefDevices; +} + diff --git a/src/loginoptionswidget.h b/src/loginoptionswidget.h index c53a0bc..8c197fa 100644 --- a/src/loginoptionswidget.h +++ b/src/loginoptionswidget.h @@ -1,17 +1,37 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef LOGINOPTIONSWIDGET_H #define LOGINOPTIONSWIDGET_H #include #include "biometricproxy.h" #include "biometricdeviceinfo.h" +#include "uniauthservice.h" class QLabel; +class KLabel; class QButtonGroup; class QHBoxLayout; class QVBoxLayout; -class QToolButton; +class QPushButton; class QTimer; class QPixmap; +class Configuration; typedef enum { BioT_FingerPrint, /** 指纹 **/ @@ -26,16 +46,25 @@ typedef enum { UniT_Remote, /** 远程账户 **/ }BioType; +enum OPTION{ + RIGHT = 0, + LEFT, + CLEAR, + CLICK, + FirstDevice, +}; + class LoginOptionsWidget : public QWidget { Q_OBJECT public: - explicit LoginOptionsWidget(BiometricProxy* proxy, int uid, QWidget *parent = nullptr); + explicit LoginOptionsWidget(BiometricProxy* proxy, int uid, UniAuthService* uniauthService, QWidget *parent = nullptr); virtual ~LoginOptionsWidget(); bool getCurLoginOpt(int& nLoginOptType, int& nDrvId); unsigned getLoginOptCount(); DeviceInfoPtr getFirstDevInfo(); + DeviceInfoPtr getWechatDevice(); int convertDeviceType(int nDevType); void setUser(int uid); @@ -46,6 +75,16 @@ public: DeviceInfoPtr findDeviceByName(const QString &name); void setDeviceDisable(int nDevId, bool bDisable = true); bool isDeviceDisable(int nDevId); + bool getBioAuthEnable(int nType); + bool getQRCodeEnable(); + QString getDefaultDevice(QString strUserName); + QString getDefaultDevice(QString strUserName,int biotype); + QStringList getAllDefDevices(); + void SetExtraInfo(QString extra_info,QString info_type); + bool getHasUkeyOptions(); + void setSelectedPassword(); + void updateUIStatus(); + int getVisibleLoginOptCount(); /** * @brief 进行生物识别认证 @@ -67,21 +106,25 @@ public: return m_isInAuth; } + QPixmap loadSvg(QString path, QString color, int size); public Q_SLOTS: void readDevicesInfo(); void onIdentifyComplete(QDBusPendingCallWatcher *watcher); + void onUkeyIdentifyComplete(QDBusPendingCallWatcher *watcher); void onStatusChanged(int drvid, int status); void onFrameWritten(int drvid); void onUSBDeviceHotPlug(int drvid, int action, int devNum); - void onOptionSelected(int nIndex); + void onOptionSelected(int nIndex, bool keyNavigation = false); + void tabOptionSelected(int option); Q_SIGNALS: - void notifyOptionsChange(unsigned uOptionsCount); - void optionSelected(unsigned uLoginOptType, const DeviceInfoPtr &deviceInfo); + void notifyOptionsChange(unsigned uOptionsCount, bool is_bioBtn); + void optionSelected(unsigned uLoginOptType, const DeviceInfoPtr &deviceInfo, bool keyNavigation); void updateImage(QImage img); void authComplete(bool bResult, int nStatus); void updateAuthMsg(QString strMsg); - + void setLoadingImage(); + void deviceCountChanged(int num); private: void initUI(); void initConnections(); @@ -89,9 +132,8 @@ private: void clearOptionButtons(); void updateOptionButtons(); void startAuth_(); + void startUkeyAuth(); bool getAuthDouble(); - void updateUIStatus(); - QPixmap loadSvg(QString path, QString color, int size); QPixmap drawSymbolicColoredPixmap(QPixmap &source, QString cgColor); private: @@ -110,11 +152,20 @@ private: QVBoxLayout *m_layoutMain = nullptr; QHBoxLayout *m_layoutOptBtns = nullptr; - QLabel *m_labelOptTitle = nullptr; + KLabel *m_labelOptTitle = nullptr; QButtonGroup *m_btnGroup = nullptr; QList m_listDriveId; - QMap m_mapOptBtns; + QMap m_mapOptBtns; QMap> m_mapDisableDev; + int nowAt = -1; + bool at_bioBtn = false; + UniAuthService *m_uniauthService = nullptr; + QList m_listPriority; + Configuration *configuration; + double curFontSize = 0; + double m_ptToPx = 1.0; + QFont sysFont; + bool isShowUkey = false; }; #endif // LOGINOPTIONSWIDGET_H diff --git a/src/machinemodel.cpp b/src/machinemodel.cpp new file mode 100644 index 0000000..957da65 --- /dev/null +++ b/src/machinemodel.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "machinemodel.h" +#include +#include +#include + +std::shared_ptr MachineModel::m_machineModel = nullptr; +std::mutex MachineModel::m_mutex; + +MachineModel::MachineModel(QObject *parent) : QObject(parent) +{ + initMachineType(); +} + +QString MachineModel::getTheMachineType() +{ + return m_machineType; +} + +std::shared_ptr MachineModel::getMachineModelInstance() +{ + if(m_machineModel == nullptr) + { + std::unique_lock lock(m_mutex); + if(m_machineModel == nullptr) + { + m_machineModel = std::shared_ptr(new MachineModel); + } + } + return m_machineModel; +} + +void MachineModel::initMachineType() +{ + QSettings setting(":/assets/data/conf.ini", QSettings::IniFormat); + setting.beginGroup("MachineType");//节点开始 + + QString type = getSysVendor() + getProductFamily(); + qInfo() << __FILE__ << __LINE__ << type; + if (setting.contains(type)) { + m_machineType = setting.value(type).toString(); + } else { + m_machineType = QString(); + } + qInfo() << __FILE__ << __LINE__ << m_machineType; + setting.endGroup();//节点结束 + +} + +const QString MachineModel::getSysVendor() const +{ + QProcess process; + QStringList options; + options << "-c"; + options << "cat /sys/class/dmi/id/sys_vendor"; + process.start("/bin/bash", options); + process.waitForFinished(); + QString result = process.readAllStandardOutput(); + + QStringList list = result.split("\n"); + result = list.at(0); + qInfo() << __FILE__ << __LINE__ << "获取设备厂商为:" << result; + return result; +} + +const QString MachineModel::getProductName() const +{ + QProcess process; + QStringList options; + options << "-c"; + options << "cat /sys/class/dmi/id/product_name"; + process.start("/bin/bash", options); + process.waitForFinished(); + QString result = process.readAllStandardOutput(); + + QStringList list = result.split("\n"); + result = list.at(0); + qInfo() << __FILE__ << __LINE__ << "获取产品名为:" << result; + return result; +} + +const QString MachineModel::getProductFamily() const +{ + QProcess process; + QStringList options; + options << "-c"; + options << "cat /sys/class/dmi/id/product_family"; + process.start("/bin/bash", options); + process.waitForFinished(); + QString result = process.readAllStandardOutput(); + + QStringList list = result.split("\n"); + result = list.at(0); + qInfo() << __FILE__ << __LINE__ << "获取设备Family为:" << result; + return result; +} diff --git a/src/machinemodel.h b/src/machinemodel.h new file mode 100644 index 0000000..7b49b64 --- /dev/null +++ b/src/machinemodel.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef MACHINEMODEL_H +#define MACHINNEMODEL_H + +#include +#include +#include + +class MachineModel : public QObject +{ + Q_OBJECT +public: + QString getTheMachineType(); + static std::shared_ptr getMachineModelInstance(); + +private: + MachineModel(QObject *parent = nullptr); + MachineModel(const MachineModel &); + const MachineModel &operator =(const MachineModel &) = delete; + +private: + void initMachineType(); + const QString getSysVendor() const; + const QString getProductName() const; + const QString getProductFamily() const; + QString m_machineType; + static std::shared_ptr m_machineModel; + static std::mutex m_mutex; + +signals: + +}; + +#endif // MACHINEMODEL_H diff --git a/src/modebutton.cpp b/src/modebutton.cpp new file mode 100644 index 0000000..3b8bb26 --- /dev/null +++ b/src/modebutton.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "modebutton.h" +#include +#include + +ModeButton::ModeButton(QWidget *parent) + : QPushButton(parent) +{ + +} + +void ModeButton::paintEvent(QPaintEvent *event) +{ + QStylePainter p(this); + QStyleOptionButton option; + initStyleOption(&option); + option.state = QStyle::State_Enabled; + p.drawControl(QStyle::CE_PushButton, option); +} + diff --git a/src/modebutton.h b/src/modebutton.h new file mode 100644 index 0000000..dc7944c --- /dev/null +++ b/src/modebutton.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef MODEBUTTON_H +#define MODEBUTTON_H +#include + +class ModeButton : public QPushButton +{ + Q_OBJECT +public: + ModeButton(QWidget *parent = nullptr); + +protected: + void paintEvent(QPaintEvent *event); +}; + +#endif // MODEBUTTON_H diff --git a/src/monitorwatcher.h b/src/monitorwatcher.h index 224aeac..0f10599 100644 --- a/src/monitorwatcher.h +++ b/src/monitorwatcher.h @@ -1,9 +1,9 @@ -/* monitorwatcher.h +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,9 +12,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ #ifndef MONITORWATCHER_H #define MONITORWATCHER_H diff --git a/src/mytabwidget.cpp b/src/mytabwidget.cpp new file mode 100644 index 0000000..dcc2e20 --- /dev/null +++ b/src/mytabwidget.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "mytabwidget.h" +#include +#include +#include + +MyTabWidget::MyTabWidget(QWidget *parent) : QTabWidget(parent) +{ + //隐藏标题栏 + // setWindowFlags(Qt::FramelessWindowHint);//无边框 置顶 + + //设置窗口背景透明 +// setAttribute(Qt::WA_TranslucentBackground,false); + + //设置样式 + +// QWidget *w = new QWidget(this); +// QWidget *k = new QWidget(this); +// this->addTab(w,"111"); +// this->addTab(k,"222"); + + +} + +void MyTabWidget::paintEvent(QPaintEvent *p1) +{ + //绘制样式 + QStyleOption opt; + opt.initFrom(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);//绘制样式 + + QBitmap bmp(this->size()); + bmp.fill(); + QPainter painter(&bmp); + painter.setPen(Qt::NoPen); + painter.setBrush(Qt::black); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawRoundedRect(bmp.rect(), 12, 12); + setMask(bmp); +} diff --git a/src/mytabwidget.h b/src/mytabwidget.h new file mode 100644 index 0000000..732d44d --- /dev/null +++ b/src/mytabwidget.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef MYTABWIDGET_H +#define MYTABWIDGET_H + +#include +#include + +class MyTabWidget : public QTabWidget +{ + Q_OBJECT +public: + explicit MyTabWidget(QWidget *parent = nullptr); + void paintEvent(QPaintEvent *event); + +signals: + +}; + +#endif // WIDGET_H diff --git a/src/networkwatcher.cpp b/src/networkwatcher.cpp index 313eabb..3c57a49 100644 --- a/src/networkwatcher.cpp +++ b/src/networkwatcher.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include #include #include diff --git a/src/networkwatcher.h b/src/networkwatcher.h index 71d3d28..a388266 100644 --- a/src/networkwatcher.h +++ b/src/networkwatcher.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef NETWORKWATCHER_H #define NETWORKWATCHER_H #include diff --git a/src/org.ukui.ScreenSaver.xml b/src/org.ukui.ScreenSaver.xml index 482c477..e0d3a42 100644 --- a/src/org.ukui.ScreenSaver.xml +++ b/src/org.ukui.ScreenSaver.xml @@ -9,6 +9,9 @@ + + + @@ -20,5 +23,12 @@ + + + + + + +
diff --git a/src/pam-tally.c b/src/pam-tally.c index d32f578..ff0642c 100644 --- a/src/pam-tally.c +++ b/src/pam-tally.c @@ -357,14 +357,20 @@ pam_modutil_read(int fd, char *buffer, int count) void get_tally(uid_t uid, int *tfile, struct tallylog *tally) { - char filename[50]={0}; - sprintf(filename,"%s","/tmp/.tallylog"); + char filename[50]={0}; + sprintf(filename,"/tmp/.tallylog.d/.%d",uid); + fprintf(stderr,"new_filename = :%s \n",filename); + void *void_tally = tally; - void *void_tally = tally; - if ((*tfile = open(filename, O_RDONLY)) == -1){ - fprintf(stderr, "open tallylog failed \n"); - return ; - } + if ((*tfile = open(filename, O_RDONLY)) == -1){ + fprintf(stderr, "lseek tallylog failed,Re-open the new file, uid = %d \n",uid); + sprintf(filename,"/tmp/.tallylog"); + fprintf(stderr,"old_filename = :%s \n",filename); + if ((*tfile = open(filename, O_RDONLY)) == -1){ + fprintf(stderr, "open tallylog failed \n"); + return ; + } + } if (lseek(*tfile, (off_t)uid*(off_t)sizeof(*tally), SEEK_SET) == (off_t)-1) { fprintf(stderr, "lseek tallylog failed \n"); diff --git a/src/permissioncheck.h b/src/permissioncheck.h index 94639e5..3af7e9c 100644 --- a/src/permissioncheck.h +++ b/src/permissioncheck.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef PERMISSIONCHECK_H #define PERMISSIONCHECK_H diff --git a/src/powermanager.cpp b/src/powermanager.cpp index 7bc190d..5b9ba34 100644 --- a/src/powermanager.cpp +++ b/src/powermanager.cpp @@ -27,11 +27,16 @@ #include #include #include "powermanager.h" +#include "lockchecker.h" +#include "klabel.h" const static QString login1Service = QStringLiteral("org.freedesktop.login1"); const static QString login1Path = QStringLiteral("/org/freedesktop/login1"); const static QString login1ManagerInterface = QStringLiteral("org.freedesktop.login1.Manager"); +#define NORMAL "normal" +#define FOCUS "focus" + #ifdef USE_INTEL PowerManager::PowerManager(QWidget *parent) : QWidget(parent), @@ -42,11 +47,16 @@ PowerManager::PowerManager(QWidget *parent) setQSS(); } #else -PowerManager::PowerManager(QWidget *parent) +PowerManager::PowerManager(int num, QWidget *parent) : QListWidget(parent), lasttime(QTime::currentTime()) { // resize(ITEM_WIDTH*7, ITEM_HEIGHT); + QFile qssFile(":/qss/assets/authdialog.qss"); + if(qssFile.open(QIODevice::ReadOnly)) { + this->setStyleSheet(qssFile.readAll()); + } + setObjectName("PowerManager"); setFlow(QListWidget::LeftToRight); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -54,8 +64,6 @@ PowerManager::PowerManager(QWidget *parent) //QObject::connect(this,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(powerClicked(QListWidgetItem*))); -// QObject::connect(this, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this,\ -// SLOT(keyboardPressed(QListWidgetItem*,QListWidgetItem*))); sessionInterface = new QDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", @@ -69,13 +77,6 @@ PowerManager::PowerManager(QWidget *parent) QDBusConnection::systemBus(), this); - xEventMonitor = new XEventMonitor(this); - connect(xEventMonitor, SIGNAL(keyPress(const QString &)), this, - SLOT(onGlobalKeyPress(const QString &))); - connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), this, - SLOT(onGlobalkeyRelease(const QString &))); - xEventMonitor->start(); - QDBusReply stateReply = loginInterface->call("CanSuspend"); if(stateReply.isValid() && stateReply.value() == "yes"){ canSuspend = true; @@ -93,45 +94,15 @@ PowerManager::PowerManager(QWidget *parent) initUI(); resize((ITEM_WIDTH+ITEM_SPACING*2)*this->count()-ITEM_SPACING*2, ITEM_HEIGHT+ITEM_SPACING*2); //setCurrentRow(0); + loginedNum = num; } - -void PowerManager::keyboardPressed(QListWidgetItem *item_c, QListWidgetItem *item_p) -{ -// if(item_p){ -// QString name = itemWidget(item_c)->objectName(); -// if(name == rebootWidget->objectName()){ -// rebootFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%),\ -// QLabel:hover{background-color:rgb(255,255,255,40%)"); -// } else if(name == shutdownWidget->objectName()){ -// shutdownFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%)"); -// } else if(suspendWidget && name == suspendWidget->objectName()){ -// suspendFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%)"); -// } else if(hibernateWidget && name == hibernateWidget->objectName()){ -// hibernateFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%)"); -// } -// QString name_p = itemWidget(item_p)->objectName(); -// if(name_p == rebootWidget->objectName()){ -// rebootFace->setStyleSheet("background-color: rgba(255, 255, 255, 20% QLabel:hover{background-color:rgb(255,255,255,40%))"); - -// } else if(name_p == shutdownWidget->objectName()){ -// shutdownFace->setStyleSheet("background-color: rgba(255, 255, 255, 20%\ -// QLabel:hover{background-color:rgb(255,255,255,40%))"); -// } else if(suspendWidget && name_p == suspendWidget->objectName()){ -// suspendFace->setStyleSheet("background-color: rgba(255, 255, 255, 20%\ -// QLabel:hover{background-color:rgb(255,255,255,40%))"); -// } else if(hibernateWidget && name_p == hibernateWidget->objectName()){ -// hibernateFace->setStyleSheet("background-color: rgba(255, 255, 255, 20%); QLabel:hover{background-color:rgb(255,255,255,40%))"); -// } -// } -} - - - bool PowerManager::eventFilter(QObject *obj, QEvent *event) { - if(event->type() != QEvent::MouseButtonPress){ - return false; + /*这里之前使用点击事件,再某些机器上会出现点击睡眠后,先睡眠,再自动唤醒的问题, + * 原因不明,改为鼠标释放事件时无此问题*/ + if(event->type() != QEvent::MouseButtonRelease){ + return QWidget::eventFilter(obj, event); } QString name = obj->objectName(); @@ -149,69 +120,67 @@ bool PowerManager::eventFilter(QObject *obj, QEvent *event) else if(name == "hibernateFace") hibernateWidgetClicked(); - return false; + return QWidget::eventFilter(obj, event); } -void PowerManager::onGlobalKeyPress(const QString &key) +void PowerManager::onGlobalKeyPress(const quint8 &key) { } -void PowerManager::onGlobalkeyRelease(const QString &key) +void PowerManager::onGlobalkeyRelease(const quint8 &key) { - if (key == "Escape") { +// if (key == 9) { // "Escape" - } else if (key == "Left" || key == "Right" || key == "Return" || key == "KP_Enter") { - keyBdRelease(key); - } +// } else if (key == 113 || key == 114 || key == 36 || key == 104) { // "Left" "Right" "Return" "KP_Enter" +// keyBdRelease(key); +// } } -void PowerManager::keyBdRelease(QString key) +void PowerManager::keyBdRelease(int key) { - QString focus = "focus"; - QString normal = "normal"; - if(key == "Right"){ + if(key == Qt::Key_Right){ // "Right" if(nowAt == -1){ nowAt = 0; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 0){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 1; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 1){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 2; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 2){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 3; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 3){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 0; - setButtonStyle(focus); + setButtonStyle(FOCUS); } - } else if(key == "Left") { + } else if(key == Qt::Key_Left) { // "Left" if(nowAt == -1){ nowAt = 3; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 3){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 2; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 2){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 1; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 1){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 0; - setButtonStyle(focus); + setButtonStyle(FOCUS); } else if(nowAt == 0){ - setButtonStyle(normal); + setButtonStyle(NORMAL); nowAt = 3; - setButtonStyle(focus); + setButtonStyle(FOCUS); } - } else if(key == "Return" || key == "KP_Enter"){ + } else if(key == Qt::Key_Return || key == Qt::Key_Enter || key == Qt::Key_Space){ // "Return" "KP_Enter" "Space" if(nowAt == 0 && this->isVisible()) hibernateWidgetClicked(); else if(nowAt == 1 && this->isVisible()) @@ -223,72 +192,23 @@ void PowerManager::keyBdRelease(QString key) } } +void PowerManager::clearStatus() +{ + for(nowAt = 0; nowAt < listLabel.count(); nowAt++) { + setButtonStyle(NORMAL); + } + nowAt = -1; +} void::PowerManager::setButtonStyle(QString Style) { if(Style == "normal") - listLabel.at(nowAt)->setStyleSheet("background-color: rgba(255, 255, 255, 15%);QLabel:hover{background-color:rgb(255,255,255,40%);QLabel:pressed{background-color:rgb(255,255,255,30%))"); + listLabel.at(nowAt)->setStyleSheet("background-color: rgba(255, 255, 255, 15%);\ + QPushButton:hover{background-color:rgba(255,255,255,40%)};QPushButton:pressed:!hover{background-color:rgba(255,255,255,30%)}"); else if(Style == "focus") listLabel.at(nowAt)->setStyleSheet("background-color: rgba(255, 255, 255, 20%);border: 1px solid #296CD9; border-radius: 64px;"); } -QStringList PowerManager::getLoginedUsers() -{ - QStringList m_loginedUser; - QDBusMessage result = loginInterface->call("ListUsers"); - QList outArgs = result.arguments(); - QVariant first = outArgs.at(0); - QDBusArgument dbvFirst = first.value(); - QVariant vFirst = dbvFirst.asVariant(); - const QDBusArgument &dbusArgs = vFirst.value(); - - - QVector loginedUsers; - - dbusArgs.beginArray(); - while (!dbusArgs.atEnd()) { - usersInfo user; - dbusArgs >> user; - loginedUsers.push_back(user); - } - - for (usersInfo user: loginedUsers) { - - QDBusInterface userPertyInterface("org.freedesktop.login1", user.usersPath.path(), - "org.freedesktop.DBus.Properties", - QDBusConnection::systemBus()); - - QDBusReply reply = - userPertyInterface.call("Get", "org.freedesktop.login1.User", "State"); - if (reply.isValid()) { - QString status = reply.value().toString(); - if ("closing" != status) { - m_loginedUser.append(user.usersName); - } - } - } - return m_loginedUser; -} - -QDBusArgument &operator <<(QDBusArgument &arg, const usersInfo &userInfo) -{ - arg.beginStructure(); - arg << userInfo.usersId - << userInfo.usersName - << userInfo.usersPath; - arg.endStructure(); - return arg; -} -const QDBusArgument &operator >>(const QDBusArgument &arg, usersInfo &userInfo) -{ - arg.beginStructure(); - arg >> userInfo.usersId - >> userInfo.usersName - >> userInfo.usersPath; - arg.endStructure(); - return arg; -} - void PowerManager::powerClicked(QListWidgetItem *item) { int interval = lasttime.msecsTo(QTime::currentTime()); @@ -297,7 +217,6 @@ void PowerManager::powerClicked(QListWidgetItem *item) lasttime = QTime::currentTime(); QString name = itemWidget(item)->objectName(); - printf("111111111111111111111111111 name = %s\n",name.toLatin1().data()); // if(name == lockWidget->objectName()) // lockWidgetClicked(); if(switchWidget && name == switchWidget->objectName()) @@ -562,44 +481,97 @@ void PowerManager::setQSS() void PowerManager::doEvent(int type) { switch (type) { - case REBOOT: - sessionInterface->call("reboot"); + case SLEEP: + loginInterface->call("Suspend",true); + emit lock(); + break; + case HIBERNATE: + loginInterface->call("Hibernate",true); + emit lock(); + break; + case REBOOT: + if (is_hibernate && loginedNum > 1) { + Q_EMIT mulUsersLogined(REBOOT); + is_hibernate = false; + } else + loginInterface->call("Reboot", true); + break; + case SHUTDOWN: + if (is_hibernate && loginedNum > 1) { + Q_EMIT mulUsersLogined(SHUTDOWN); + is_hibernate = false; + } else + loginInterface->call("PowerOff", true); break; - case SHOTDOWN: - sessionInterface->call("powerOff"); default: break; } } +void PowerManager::setStartupMode(bool mode) +{ + m_isStartupMode = mode; +} + void PowerManager::suspendWidgetClicked() { - loginInterface->call("Suspend",true); + QVector res = LockChecker::listInhibitor("sleep"); + if (!res.isEmpty()) { + Q_EMIT showInhibitWarning(res, SLEEP); + return; + } emit lock(); + Q_EMIT clickedSuspend(); + loginInterface->call("Suspend",true); } void PowerManager::hibernateWidgetClicked() { - loginInterface->call("Hibernate",true); + QVector res = LockChecker::listInhibitor("sleep"); + if (!res.isEmpty()) { + Q_EMIT showInhibitWarning(res, HIBERNATE); + return; + } emit lock(); + loginInterface->call("Hibernate",true); } void PowerManager::shutdownWidgetClicked() { - if(getLoginedUsers().count() > 1){ - Q_EMIT mulUsersLogined(SHOTDOWN); + QVector res = LockChecker::listInhibitor("shutdown"); + if (!res.isEmpty()) { + Q_EMIT showInhibitWarning(res, SHUTDOWN); + is_hibernate = true; + return; + } else if(loginedNum > 1){ + Q_EMIT mulUsersLogined(SHUTDOWN); + is_hibernate = false; return; } - sessionInterface->call("powerOff"); + if (m_isStartupMode) { + loginInterface->call("PowerOff", true); + } else { + sessionInterface->call("powerOff"); + } } void PowerManager::rebootWidgetClicked() { - if(getLoginedUsers().count() > 1){ + QVector res = LockChecker::listInhibitor("shutdown"); + if (!res.isEmpty()) { + Q_EMIT showInhibitWarning(res, REBOOT); + is_hibernate = true; + return; + } else if(loginedNum > 1){ Q_EMIT mulUsersLogined(REBOOT); + is_hibernate = false; return; } - sessionInterface->call("reboot"); + if (m_isStartupMode) { + loginInterface->call("Reboot", true); + } else { + sessionInterface->call("reboot"); + } } void PowerManager::logoutWidgetCliced() @@ -689,13 +661,15 @@ void PowerManager::initUI() rebootWidget->setObjectName("rebootWidget"); QWidget *rbLabelWidget = new QWidget(this); rbLabelWidget->setFixedSize(130, 130); - rebootFace = new QLabel(rbLabelWidget); + rebootFace = new QPushButton(rbLabelWidget); rebootFace->setObjectName("rebootFace"); - QLabel *rebootLabel = new QLabel(this); - rebootFace->setAlignment(Qt::AlignCenter); + KLabel *rebootLabel = new KLabel(this); + //rebootFace->setAlignment(Qt::AlignCenter); rebootFace->installEventFilter(this); rebootLabel->setAlignment(Qt::AlignCenter); - rebootFace->setPixmap(QPixmap(":/image/assets/reboot.png").scaled(58,58)); + rebootFace->setIcon(QIcon(":/image/assets/reboot.svg")); + rebootFace->setIconSize(QSize(48, 48)); + rebootLabel->setFontSize(16); rebootLabel->setText(tr("Restart")); rebootWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); QVBoxLayout *rebootlayout = new QVBoxLayout(rebootWidget); @@ -707,15 +681,18 @@ void PowerManager::initUI() shutdownWidget->setObjectName("shutdownWidget"); QWidget *shLabelWidget = new QWidget(this); shLabelWidget->setFixedSize(130, 130); - shutdownFace = new QLabel(shLabelWidget); + shutdownFace = new QPushButton(shLabelWidget); shutdownFace->setObjectName("shutdownFace"); - QLabel *shutdownLabel = new QLabel(this); + KLabel *shutdownLabel = new KLabel(this); shutdownLabel->setAlignment(Qt::AlignCenter); - shutdownFace->setAlignment(Qt::AlignCenter); + //shutdownFace->setAlignment(Qt::AlignCenter); shutdownFace->installEventFilter(this); - shutdownFace->setPixmap(QPixmap(":/image/assets/shutdown.png").scaled(58,58)); + shutdownFace->setIcon(QIcon(":/image/assets/shutdown.svg")); + shutdownFace->setIconSize(QSize(48, 48)); + //sysFont.setPointSize(20); + shutdownLabel->setFontSize(16); shutdownLabel->setText(tr("Shut Down")); - shutdownWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + shutdownWidget->setFixedSize(ITEM_WIDTH, ITEM_HEIGHT); QVBoxLayout *shutdownlayout = new QVBoxLayout(shutdownWidget); shutdownlayout->addWidget(shLabelWidget); shutdownlayout->addWidget(shutdownLabel); @@ -733,13 +710,15 @@ void PowerManager::initUI() hibernateWidget->setObjectName("hibernateWidget"); QWidget *hbLabelWidget = new QWidget(this); hbLabelWidget->setFixedSize(130, 130); - hibernateFace = new QLabel(hbLabelWidget); + hibernateFace = new QPushButton(hbLabelWidget); hibernateFace->setObjectName("hibernateFace"); - QLabel *hibernateLabel = new QLabel(this); + KLabel *hibernateLabel = new KLabel(this); hibernateLabel->setAlignment(Qt::AlignCenter); - hibernateFace->setAlignment(Qt::AlignCenter); + //hibernateFace->setAlignment(Qt::AlignCenter); hibernateFace->installEventFilter(this); - hibernateFace->setPixmap(QPixmap(":/image/assets/hibernate.png").scaled(48,48)); + hibernateFace->setIcon(QIcon(":/image/assets/hibernate.svg")); + hibernateFace->setIconSize(QSize(48, 48)); + hibernateLabel->setFontSize(16); hibernateLabel->setText(tr("Hibernate")); hibernateWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); QVBoxLayout *hibernatelayout = new QVBoxLayout(hibernateWidget); @@ -760,13 +739,15 @@ void PowerManager::initUI() suspendWidget->setObjectName("suspendWidget"); QWidget *spLabelWidget = new QWidget(this); spLabelWidget->setFixedSize(130, 130); - suspendFace = new QLabel(spLabelWidget); + suspendFace = new QPushButton(spLabelWidget); suspendFace->setObjectName("suspendFace"); - QLabel *suspendLabel = new QLabel(this); + KLabel *suspendLabel = new KLabel(this); suspendLabel->setAlignment(Qt::AlignCenter); - suspendFace->setAlignment(Qt::AlignCenter); + //suspendFace->setAlignment(Qt::AlignCenter); suspendFace->installEventFilter(this); - suspendFace->setPixmap(QPixmap(":/image/assets/suspend.png").scaled(48,48)); + suspendFace->setIcon(QIcon(":/image/assets/suspend.svg")); + suspendFace->setIconSize(QSize(48, 48)); + suspendLabel->setFontSize(16); suspendLabel->setText(tr("Suspend")); suspendWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); QVBoxLayout *suspendlayout = new QVBoxLayout(suspendWidget); diff --git a/src/powermanager.h b/src/powermanager.h index 3a4a1ee..7199568 100644 --- a/src/powermanager.h +++ b/src/powermanager.h @@ -23,7 +23,7 @@ #include #include #include "config.h" -#include "xeventmonitor.h" +#include "lockchecker.h" #ifdef USE_INTEL #define ITEM_WIDTH 128 #define ITEM_HEIGHT (ITEM_WIDTH + 40) @@ -38,20 +38,14 @@ class PowerManager:public QWidget enum stateType { REBOOT, - SHOTDOWN, - NOTHING + SHUTDOWN, + SLEEP, + HIBERNATE, + NOTHING, }; -struct usersInfo { - int usersId; - QString usersName; - QDBusObjectPath usersPath; -}; - -QDBusArgument &operator <<(QDBusArgument &arg, const usersInfo &userInfo); -const QDBusArgument &operator >>(const QDBusArgument &arg, usersInfo &userInfo); - class QLabel; +class QPushButton; class QListWidget; class QListWidgetItem; class QDBusInterface; @@ -61,13 +55,20 @@ class PowerManager:public QListWidget Q_OBJECT public: - PowerManager(QWidget *parent = 0); + PowerManager(int num = 0, QWidget *parent = 0); #ifdef USE_INTEL bool hibernate(); #else void showNormalSize(); void showSmallSize(); + void keyBdRelease(int key); + void clearStatus(); void doEvent(int type); + void setStartupMode(bool mode); + +public Q_SLOTS: + void onGlobalKeyPress(const quint8 &key); + void onGlobalkeyRelease(const quint8 &key); #endif private: void initUI(); @@ -76,7 +77,7 @@ private: void setQSS(); QWidget *list; #else - QList listLabel; + QList listLabel; int nowAt = -1; QListWidget *list; QWidget *suspendWidget; @@ -85,6 +86,7 @@ private: QDBusInterface *loginInterface; QDBusInterface *actService; int login_Num; + bool is_hibernate = false; bool canSuspend; bool canHibernate; @@ -96,11 +98,12 @@ private: QWidget *rebootWidget; QWidget *shutdownWidget; QTime lasttime; - XEventMonitor *xEventMonitor; - QLabel *rebootFace; - QLabel *shutdownFace; - QLabel *hibernateFace; - QLabel *suspendFace; + QPushButton *rebootFace; + QPushButton *shutdownFace; + QPushButton *hibernateFace; + QPushButton *suspendFace; + int loginedNum = 0; + bool m_isStartupMode = false; private: void lockWidgetClicked(); @@ -109,7 +112,7 @@ private: void rebootWidgetClicked(); QStringList getLoginedUsers(); void shutdownWidgetClicked(); - void keyBdRelease(QString key); + //void keyBdRelease(quint8 key); void setButtonStyle(QString Style); #ifdef USE_INTEL bool reboot(); @@ -122,14 +125,14 @@ private Q_SLOTS: #ifndef USE_INTEL void powerClicked(QListWidgetItem *item); bool eventFilter(QObject *obj, QEvent *event); - void onGlobalKeyPress(const QString &key); - void onGlobalkeyRelease(const QString &key); - void keyboardPressed(QListWidgetItem *item,QListWidgetItem*); + #endif Q_SIGNALS: void switchToUser(); void lock(); void mulUsersLogined(int type); + void showInhibitWarning(QVector &list, int type); + void clickedSuspend(); }; #endif // POWERMANAGER_H diff --git a/src/rootWindowBackground.cpp b/src/rootWindowBackground.cpp new file mode 100644 index 0000000..eb3d534 --- /dev/null +++ b/src/rootWindowBackground.cpp @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rootWindowBackground.h" + +static const XID INVAL_ID = ~0UL; +Pixmap pix = INVAL_ID; +Display *dpy = NULL; +Window root = 0; +Screen *scn = NULL; + +struct RootWindowBGInfo { + bool isValid = false; + int nType; + int nColor; + QString strFileName; + int nOption; + QList listScreen; +}; + +static RootWindowBGInfo g_lastRootWndInfo; + +static QRect getSourceRect(const QRect &destination, const QRect &source) +{ + qreal screenScale = qreal(destination.width()) / qreal(destination.height()); + qreal width = source.width(); + qreal height = source.height(); + + if ((width / height) == screenScale) { + return source; + } + + bool isShortX = (width <= height); + if (isShortX) { + screenScale = qreal(destination.height()) / qreal(destination.width()); + } + + qreal shortEdge = isShortX ? width : height; + qreal longEdge = isShortX ? height : width; + + while (shortEdge > 1) { + qint32 temp = qFloor(shortEdge * screenScale); + if (temp <= longEdge) { + longEdge = temp; + break; + } + + qint32 spacing = qRound(shortEdge / 20); + if (spacing <= 0) { + spacing = 1; + } + shortEdge -= spacing; + } + + QSize sourceSize = source.size(); + if (shortEdge > 1 && longEdge > 1) { + sourceSize.setWidth(isShortX ? shortEdge : longEdge); + sourceSize.setHeight(isShortX ? longEdge : shortEdge); + } + + qint32 offsetX = 0; + qint32 offsetY = 0; + if (source.width() > sourceSize.width()) { + offsetX = (source.width() - sourceSize.width()) / 2; + } + + if (source.height() > sourceSize.height()) { + offsetY = (source.height() - sourceSize.height()) / 2; + } + + QPoint offsetPoint = source.topLeft(); + offsetPoint += QPoint(offsetX, offsetY); + + return QRect(offsetPoint, sourceSize); +} + +static QRect getDestRect(const QRect &destination, const QRect &source) +{ + qreal screenScale = qreal(destination.width()) / qreal(destination.height()); + qreal pixmapScale = qreal(source.width() / source.height()); + qreal width = source.width(); + qreal height = source.height(); + + if (pixmapScale == screenScale) { + return destination; + } + + qreal scaleWidth = destination.width() / width; + qreal scaleHeight = destination.height() / height; + qreal realPixmapWidth = 0; + qreal realPixmapHeight = 0; + + if(pixmapScale < screenScale){ + //图片比例小于屏幕比例时,按照图片和屏幕高度比进行缩放 + realPixmapWidth = width * scaleHeight; + realPixmapHeight = destination.height(); + }else{ + //图片比例大于屏幕比例时,按照图片与屏幕宽度比进行缩放 + realPixmapWidth = destination.width(); + realPixmapHeight = height * scaleWidth; + } + + QSize sourceSize = destination.size(); + qint32 offsetX = 0; + qint32 offsetY = 0; + if (destination.width() == realPixmapWidth) { + offsetY = (destination.height() - realPixmapHeight) / 2; + sourceSize.setHeight(realPixmapHeight); + } else if (destination.height() == realPixmapHeight) { + offsetX = (destination.width() - realPixmapWidth) / 2; + sourceSize.setWidth(realPixmapWidth); + } + + qDebug() << "=========getDestRect sourceSize:" << sourceSize; + QPoint offsetPoint = destination.topLeft(); + offsetPoint += QPoint(offsetX, offsetY); + + return QRect(offsetPoint, sourceSize); +} + +static QRect getSourceRect(const QRect &source, const QRect &screenGeometry, const QRect &screenVirtualGeometry) +{ + qreal pixWidth = source.width(); + qreal pixHeight = source.height(); + + QSize sourceSize = source.size(); + sourceSize.setWidth(screenGeometry.width() / screenVirtualGeometry.width() * pixWidth); + sourceSize.setHeight(screenGeometry.height() / screenVirtualGeometry.height() * pixHeight); + + qint32 offsetX = 0; + qint32 offsetY = 0; + if (screenGeometry.x() > 0) { + offsetX = (screenGeometry.x() / screenVirtualGeometry.width() * pixWidth); + } + + if (screenGeometry.y() > 0) { + offsetY = (screenGeometry.y() / screenVirtualGeometry.height() * pixHeight); + } + + QPoint offsetPoint = source.topLeft(); + offsetPoint += QPoint(offsetX, offsetY); + + return QRect(offsetPoint, sourceSize); +} + +void setRootWindowBackground(bool type,unsigned int color,char *filename, int nOption) +{ + Imlib_Image img; + + if (!dpy){ + dpy = XOpenDisplay(NULL); + if(!dpy) + return; + } + + int width = 0,height = 0; + + width = QApplication::desktop()->geometry().width()*qApp->devicePixelRatio(); + height = QApplication::desktop()->geometry().height()*qApp->devicePixelRatio(); + + if(!scn) + scn = DefaultScreenOfDisplay(dpy); + if(!root) + root = DefaultRootWindow(dpy); + + if (pix != INVAL_ID) { + XFreePixmap(dpy, pix); + pix = INVAL_ID; + } + pix = XCreatePixmap(dpy, root, width, height, + DefaultDepthOfScreen(scn)); + + imlib_context_set_display(dpy); + imlib_context_set_visual(DefaultVisualOfScreen(scn)); + imlib_context_set_colormap(DefaultColormapOfScreen(scn)); + imlib_context_set_drawable(pix); + + if(type == 0){ + img = imlib_load_image(filename); + if (!img) { + fprintf(stderr, "%s:Unable to load image\n", filename); + return ; + } + imlib_context_set_image(img); + + }else if(type == 1){ + img = imlib_create_image(width, height); + imlib_context_set_image(img); + int blue = color & 0xFF; + int green = color >> 8 & 0xFF; + int red = color >> 16 & 0xFF; + + qDebug()<<"red = "<= rect.width()) { + break; + } + } + drawedHeight += newSrcRect.height(); + if (drawedHeight >= rect.height()) { + break; + } + } + } + break; + case WNDBG_OPTION_ZOOM: // 适应 + { + rect = getDestRect(rect, newSrcRect); + qDebug()<<"Zoom:"<screens()){ + if (screen->name() == sscreen->name()) { + QRect srcRect = getSourceRect(newSrcRect, sscreen->geometry(), screen->virtualGeometry()); + imlib_render_image_part_on_drawable_at_size(srcRect.x(), srcRect.y(), + srcRect.width(), srcRect.height(), + rect.x(), rect.y(), + rect.width(),rect.height()); + break; + } + } + } + break; + default: + { + imlib_render_image_part_on_drawable_at_size(newSrcRect.x(), newSrcRect.y(), + newSrcRect.width(), newSrcRect.height(), + rect.x(), rect.y(), + rect.width(),rect.height()); + } + break; + } + } + + imlib_free_image(); +} + +void updateRootWindowBackground() +{ + // 对比新的屏幕尺寸是否有变化 + if (g_lastRootWndInfo.isValid) { + bool isSame = true; + QList listScreen; + for(QScreen *screen : QApplication::screens()){ + //在每个屏幕上绘制背景 + QRect rect = screen->geometry(); + rect.setX(rect.x()*screen->devicePixelRatio()); + rect.setY(rect.y()*screen->devicePixelRatio()); + rect.setWidth(rect.width()*screen->devicePixelRatio()); + rect.setHeight(rect.height()*screen->devicePixelRatio()); + listScreen.append(rect); + } + qDebug()<<"ScreenRects:"< g_lastRootWndInfo.listScreen.size()) { + isSame = false; + } else { + for (int n = 0; n < listScreen.size(); n++) { + if (n < g_lastRootWndInfo.listScreen.size()) { + if (g_lastRootWndInfo.listScreen[n] != listScreen[n]) { + isSame = false; + break; + } + } + } + } + if (!isSame) { + setRootWindowBackground(g_lastRootWndInfo.nType, g_lastRootWndInfo.nColor, + g_lastRootWndInfo.strFileName.toLatin1().data(), g_lastRootWndInfo.nOption); + } + } +} + +void drawBackground(bool isDraw) +{ + if (!dpy) { + return ; + } + if (isDraw) { + if (pix != INVAL_ID) + XSetWindowBackgroundPixmap(dpy, root, pix); + XClearWindow(dpy, root); + } + + while (XPending(dpy)) { + XEvent ev; + XNextEvent(dpy, &ev); + } + if (pix != INVAL_ID) { + XFreePixmap(dpy, pix); + pix = INVAL_ID; + } + XCloseDisplay(dpy); + dpy = NULL; +} + + diff --git a/VirtualKeyboard/src/cursormonitor.h b/src/rootWindowBackground.h similarity index 50% rename from VirtualKeyboard/src/cursormonitor.h rename to src/rootWindowBackground.h index 7722453..5cd0860 100644 --- a/VirtualKeyboard/src/cursormonitor.h +++ b/src/rootWindowBackground.h @@ -1,9 +1,9 @@ -/** +/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) + * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, @@ -12,25 +12,19 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. + * along with this program; if not, see . + * **/ -#ifndef CURSORMONITOR_H -#define CURSORMONITOR_H -#include -#include +typedef enum WNDBG_OPTION_e{ + WNDBG_OPTION_SCALED, // 填充 + WNDBG_OPTION_STRETCHED, // 拉伸 + WNDBG_OPTION_CENTERED, // 居中 + WNDBG_OPTION_WALLPAPER, // 平铺 + WNDBG_OPTION_ZOOM, // 适应 + WNDBG_OPTION_SPANNED // 跨区 +}WNDBG_OPTION; -class CursorMonitor : public QThread -{ - Q_OBJECT -public: - explicit CursorMonitor(QObject *parent = nullptr); - void run(); - -Q_SIGNALS: - void cursorPosChanged(const QPoint& pos); -}; - -#endif // CURSORMONITOR_H +void setRootWindowBackground(bool type,unsigned int color,char *filename, int nOption = 0); +void updateRootWindowBackground(); +void drawBackground(bool isDraw); diff --git a/src/screensaver.cpp b/src/screensavermode.cpp similarity index 99% rename from src/screensaver.cpp rename to src/screensavermode.cpp index 744d33b..37eab3c 100644 --- a/src/screensaver.cpp +++ b/src/screensavermode.cpp @@ -15,7 +15,7 @@ * along with this program; if not, see . * **/ -#include "screensaver.h" +#include "screensavermode.h" #include #include #include diff --git a/src/screensaver.h b/src/screensavermode.h similarity index 94% rename from src/screensaver.h rename to src/screensavermode.h index d3f2ad3..51c738e 100644 --- a/src/screensaver.h +++ b/src/screensavermode.h @@ -15,8 +15,8 @@ * along with this program; if not, see . * **/ -#ifndef SCREENSAVER_H -#define SCREENSAVER_H +#ifndef SCREENSAVER_MODE_H +#define SCREENSAVER_MODE_H #include #include @@ -44,7 +44,7 @@ class ScreenSaver : public QObject public: SaverMode mode; //path is a directory or a file path if mode is SAVER_IMAGE - QString path; + QString path = ""; QString lastPath; //for images saver @@ -74,4 +74,4 @@ Q_DECLARE_METATYPE(ScreenSaver) QDebug &operator<<(QDebug stream, const ScreenSaver &screensaver); -#endif // SCREENSAVER_H +#endif // SCREENSAVER_MODE_H diff --git a/src/screensaverwidget.cpp b/src/screensaverwidget.cpp index e194c54..36bd944 100644 --- a/src/screensaverwidget.cpp +++ b/src/screensaverwidget.cpp @@ -24,6 +24,7 @@ #include #include #include +#include "screensaver.h" #include #include ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent) @@ -33,6 +34,7 @@ ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent) closing(false) { qDebug() << "ScreenSaverWidget::ScreenSaverWidget"; + setAttribute(Qt::WA_DeleteOnClose); setMouseTracking(true); setFocus(); this->installEventFilter(this); @@ -83,8 +85,10 @@ ScreenSaverWidget::~ScreenSaverWidget() void ScreenSaverWidget::closeEvent(QCloseEvent *event) { qDebug() << "ScreenSaverWidget::closeEvent---beginStop"; - if(process.state() != QProcess::NotRunning) + if(process.state() != QProcess::NotRunning) { process.kill(); + process.waitForFinished(200); + } if(!closing){ closing = true; @@ -102,7 +106,7 @@ void ScreenSaverWidget::paintEvent(QPaintEvent *event) if(!screensaver->exists()) { QPainter painter(this); - painter.fillRect(geometry(), Qt::black); + painter.fillRect(0,0,this->width(),this->height(), Qt::black); } if(screensaver->mode == SAVER_IMAGE) { switch(screensaver->effect) { @@ -111,7 +115,7 @@ void ScreenSaverWidget::paintEvent(QPaintEvent *event) QPixmap pixmap(screensaver->path); pixmap.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); QPainter painter(this); - painter.drawPixmap(geometry(), pixmap); + painter.drawPixmap(0,0,this->width(),this->height(), pixmap); break; } case TRANSITION_FADE_IN_OUT: @@ -120,17 +124,15 @@ void ScreenSaverWidget::paintEvent(QPaintEvent *event) QPixmap pixmap1(screensaver->lastPath); pixmap1.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); painter.setOpacity(opacity); - painter.drawPixmap(geometry(), pixmap1); + painter.drawPixmap(0,0,this->width(),this->height(), pixmap1); QPixmap pixmap(screensaver->path); pixmap.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); painter.setOpacity(1 - opacity); - painter.drawPixmap(geometry(), pixmap); + painter.drawPixmap(0,0,this->width(),this->height(), pixmap); break; } } - - } return QWidget::paintEvent(event); } @@ -139,7 +141,9 @@ bool ScreenSaverWidget::eventFilter(QObject *obj, QEvent *event) { if(event->type() == 23) { - XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + if(QX11Info::isPlatformX11()){ + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } } return false; } @@ -147,12 +151,30 @@ bool ScreenSaverWidget::eventFilter(QObject *obj, QEvent *event) /* Embed xscreensavers */ void ScreenSaverWidget::embedXScreensaver(const QString &path) { - QString cmd = path + " -window-id " + QString::number(winId()); - if(process.state() == QProcess::NotRunning) - process.start(cmd); + qDebug()<<"embedXScreensaver path = "<mode == SAVER_SINGLE){ + QString cmd = path + " -window-id " + QString::number(winId()); + if(process.state() == QProcess::NotRunning) + process.start(cmd); + }else if(screensaver->mode == SAVER_DEFAULT || screensaver->mode == SAVER_DEFAULT_CUSTOM){ + if(!m_screensaver){ + m_screensaver = new Screensaver(true,this); + //m_screensaver->resize(1366,768); + //m_screensaver->setGeometry(this->geometry()); + // m_screensaver->setGeometry(0,0,1920,1080); + + } + } } - +void ScreenSaverWidget::resizeEvent(QResizeEvent *event) +{ + if(m_screensaver){ + m_screensaver->setGeometry(0,0,this->width(),this->height()); + } +} void ScreenSaverWidget::onBackgroundChanged(const QString &/*path*/) { diff --git a/src/screensaverwidget.h b/src/screensaverwidget.h index a76d428..7099cba 100644 --- a/src/screensaverwidget.h +++ b/src/screensaverwidget.h @@ -20,8 +20,9 @@ #include #include -#include "screensaver.h" +#include "screensavermode.h" +class Screensaver; class ScreenSaverWidget : public QWidget { Q_OBJECT @@ -34,6 +35,7 @@ protected: void closeEvent(QCloseEvent *); void paintEvent(QPaintEvent *event); bool eventFilter(QObject *obj, QEvent *event); + void resizeEvent(QResizeEvent *event); private: void embedXScreensaver(const QString &path); @@ -46,6 +48,7 @@ private: bool closing; float opacity; QProcess process; + Screensaver *m_screensaver = nullptr; }; #endif // SCREENSAVERWIDGET_H diff --git a/src/screensaverwndadaptor.cpp b/src/screensaverwndadaptor.cpp new file mode 100644 index 0000000..8d4b9a5 --- /dev/null +++ b/src/screensaverwndadaptor.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#include "screensaverwndadaptor.h" + +#include +#include +#include +#include +#include +#include +#include + +ScreenSaverWndAdaptor::ScreenSaverWndAdaptor(FullBackgroundWidget *parent) + : QDBusAbstractAdaptor(parent) + , m_parentWidget(parent) +{ + // constructor + setAutoRelaySignals(true); + + connect(m_parentWidget, SIGNAL(StartupModeChanged(bool)), this, SIGNAL(StartupModeChanged(bool))); +} + +ScreenSaverWndAdaptor::~ScreenSaverWndAdaptor() +{ + +} + +int ScreenSaverWndAdaptor::RegisteSubWnd(quint64 uWndId) +{ + int nWndCount = m_parentWidget->RegisteSubWnd(uWndId); + if (nWndCount >= 0) { + Q_EMIT SubWndChanged(nWndCount); + } + return nWndCount; +} + +int ScreenSaverWndAdaptor::UnRegisteSubWnd(quint64 uWndId) +{ + int nWndCount = m_parentWidget->UnRegisteSubWnd(uWndId); + if (nWndCount >= 0) { + Q_EMIT SubWndChanged(nWndCount); + } + return nWndCount; +} + +QList ScreenSaverWndAdaptor::GetSubWndIds() +{ + return m_parentWidget->GetSubWndIds(); +} + +bool ScreenSaverWndAdaptor::IsStartupMode() +{ + return m_parentWidget->IsStartupMode(); +} diff --git a/src/screensaverwndadaptor.h b/src/screensaverwndadaptor.h new file mode 100644 index 0000000..77c3dde --- /dev/null +++ b/src/screensaverwndadaptor.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ +#ifndef SCREENSAVERWNDADAPTOR_H +#define SCREENSAVERWNDADAPTOR_H + +#include +#include +#include "fullbackgroundwidget.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +class ScreenSaverWndAdaptor : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.ScreenSaverWnd") + Q_CLASSINFO("D-Bus Introspection", "" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "") +public: + ScreenSaverWndAdaptor(FullBackgroundWidget *parent = nullptr); + virtual ~ScreenSaverWndAdaptor(); + +public Q_SLOTS: + int RegisteSubWnd(quint64 uWndId); + int UnRegisteSubWnd(quint64 uWndId); + QList GetSubWndIds(); + bool IsStartupMode(); + +Q_SIGNALS: + void SubWndChanged(int nCount); + void StartupModeChanged(bool isStartup); + +private: + FullBackgroundWidget *m_parentWidget = nullptr; +}; + +#endif // SCREENSAVERWNDADAPTOR_H diff --git a/src/servicemanager.cpp b/src/servicemanager.cpp new file mode 100644 index 0000000..427678e --- /dev/null +++ b/src/servicemanager.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "servicemanager.h" +#include +#include + +#define SERVICE "biometric-authentication.service" +#define DBUS_SERVICE "org.ukui.Biometric" +#define DBUS_PATH "/org/ukui/Biometric" +#define DBUS_INTERFACE "org.ukui.Biometric" + +#define FD_DBUS_SERVICE "org.freedesktop.DBus" +#define FD_DBUS_PATH "/org/freedesktop/DBus" +#define FD_DBUS_INTERFACE "org.freedesktop.DBus" + +ServiceManager *ServiceManager::instance_ = nullptr; + +ServiceManager::ServiceManager(QObject *parent) + : QObject(parent), + dbusService(nullptr), + bioService(nullptr) +{ + init(); +} + +void ServiceManager::init() +{ + if(!dbusService) + { + dbusService = new QDBusInterface(FD_DBUS_SERVICE, + FD_DBUS_PATH, + FD_DBUS_INTERFACE, + QDBusConnection::systemBus()); + connect(dbusService, SIGNAL(NameOwnerChanged(QString, QString, QString)), + this, SLOT(onDBusNameOwnerChanged(QString,QString,QString))); + } +} + +ServiceManager *ServiceManager::instance() +{ + if(!instance_) + { + instance_ = new ServiceManager; + } + return instance_; +} + +bool ServiceManager::connectToService() +{ + if(!bioService) + { + bioService = new QDBusInterface(DBUS_SERVICE, + DBUS_PATH, + DBUS_INTERFACE, + QDBusConnection::systemBus()); + } + return bioService->isValid(); +} + +void ServiceManager::onDBusNameOwnerChanged(const QString &name, + const QString &oldOwner, + const QString &newOwner) +{ + if(name == DBUS_SERVICE) + { + qDebug() << "service status changed:" + << (newOwner.isEmpty() ? "inactivate" : "activate"); + Q_EMIT serviceStatusChanged(!newOwner.isEmpty()); + } +} + +/*! + * \brief checkServiceExist + * 检查生物识别后台服务是否已启动 + */ +bool ServiceManager::serviceExists() +{ + QDBusReply reply = dbusService->call("NameHasOwner", DBUS_SERVICE); + if(!reply.isValid()) + { + qDebug() << "check service exists error:" << reply.error(); + return false; + } + return reply.value(); +} + +/*! + * \brief ServiceManager::apiCompatible + * 检查API版本和服务的版本是否兼容 + */ +bool ServiceManager::apiCompatible() +{ + if(!connectToService()) + return false; + + QDBusReply reply = bioService->call("CheckAppApiVersion", + APP_API_MAJOR, + APP_API_MINOR, + APP_API_FUNC); + if(!reply.isValid()) + { + qDebug() << "check api compatibility error: " << reply.error(); + return false; + } + return (reply.value() == 0); +} diff --git a/src/servicemanager.h b/src/servicemanager.h new file mode 100644 index 0000000..548cf1d --- /dev/null +++ b/src/servicemanager.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#ifndef SERVICEMANAGER_H +#define SERVICEMANAGER_H + +#include +#include + +class ServiceManager : public QObject +{ + Q_OBJECT +public: + static ServiceManager *instance(); + bool serviceExists(); + bool apiCompatible(); + +private: + explicit ServiceManager(QObject *parent = nullptr); + void init(); + bool connectToService(); + +Q_SIGNALS: + void serviceStatusChanged(bool activate); + +public Q_SLOTS: + void onDBusNameOwnerChanged(const QString &name, + const QString &oldOwner, + const QString &newOwner); + +private: + static ServiceManager *instance_; + QDBusInterface *dbusService; + QDBusInterface *bioService; + bool serviceStatus; +}; + +#endif // SERVICEMANAGER_H diff --git a/src/sessionwatcher.cpp b/src/sessionwatcher.cpp index c97d7b8..be05ab5 100644 --- a/src/sessionwatcher.cpp +++ b/src/sessionwatcher.cpp @@ -19,7 +19,9 @@ #include #include #include +#include #include "types.h" +#include "glibinterface.h" #define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" #define KEY_IDLE_DELAY "idleDelay" @@ -27,16 +29,32 @@ #define KEY_IDLE_ACTIVATION_ENABLED "idleActivationEnabled" #define KEY_IDLE_LOCK_ENABLED "idleLockEnabled" #define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" +#define KEY_LOCK_TIMEOUT "lockTimeout" +#define STYLE_TYPE_SCHEMA "org.ukui.style" + +#define GSETTINGS_SCHEMA_SCREENSAVER_DEFAULT "org.ukui.screensaver-default" +#define KEY_SHOW_REST_TIME "showRestTime" // old +#define KEY_SHOW_CUSTOM_REST_TIME "showCustomRestTime" +#define KEY_SHOW_UKUI_REST_TIME "showUkuiRestTime" + +#define POWER_TYPE_SCHENA "org.ukui.power-manager" +#define FREEDESKTOP_UPOWER "org.freedesktop.DBus.Properties" +#define UPOWER_PATH "/org/freedesktop/UPower" +#define UPOWER_SERVICE "org.freedesktop.UPower" +#define UPOWER_DISPLAY_PATH "/org/freedesktop/UPower/devices/DisplayDevice" +#define G_FONT_SIZE (11.0) SessionWatcher::SessionWatcher(QObject *parent) : QObject(parent) { sessionPath = qgetenv("XDG_SESSION_PATH"); + defaultFontSize = getDefaultFontSize(); + QDBusInterface *interface = new QDBusInterface( SM_DBUS_SERVICE, SM_DBUS_PATH, SM_DBUS_INTERFACE, - QDBusConnection::sessionBus()); + QDBusConnection::sessionBus(), this); connect(interface, SIGNAL(StatusChanged(unsigned int)), this, SLOT(onStatusChanged(unsigned int))); @@ -45,19 +63,85 @@ SessionWatcher::SessionWatcher(QObject *parent) : QObject(parent) DM_DBUS_SERVICE, DM_DBUS_PATH, DM_DBUS_INTERFACE, - QDBusConnection::systemBus()); + QDBusConnection::systemBus(), this); connect(displayManagerInterface, SIGNAL(SessionRemoved(QDBusObjectPath)), this, SLOT(onSessionRemoved(QDBusObjectPath))); - settings_delay = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); - connect(settings_delay, &QGSettings::changed, - this, &SessionWatcher::onConfigurationDelayChanged); - idleDelay = settings_delay->get("idle-delay").toInt(); + QStringList keysScreenSaver; + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_SCREENSAVER)){ + m_ssSettings = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); + connect(m_ssSettings, &QGSettings::changed, + this, &SessionWatcher::onSSConfigChanged); + keysScreenSaver = m_ssSettings->keys(); + // 重置屏保从不字段 + if (keysScreenSaver.contains(KEY_IDLE_ACTIVATION_ENABLED)) { + bool isEnable = m_ssSettings->get("idle-activation-enabled").toBool(); + if (!isEnable) { + m_ssSettings->set("idle-activation-enabled", true); + if (keysScreenSaver.contains(KEY_IDLE_DELAY)) { + m_ssSettings->set("idle-delay", -1); + } + } + } + // 重置锁屏时间(不处理超时锁屏220620) + if (keysScreenSaver.contains(KEY_IDLE_LOCK)) { + m_ssSettings->set("idle-lock", -1); + } + idleDelay = m_ssSettings->get("idle-delay").toInt(); + idleLock = m_ssSettings->get("idle-lock").toInt(); - settings_lock = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); - connect(settings_lock, &QGSettings::changed, - this, &SessionWatcher::onConfigurationLockChanged); - idleLock = settings_lock->get("idle-lock").toInt(); + if (keysScreenSaver.contains(KEY_LOCK_TIMEOUT)) { + m_nLockTimeout = m_ssSettings->get("lock-timeout").toInt(); + } + } + + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_SCREENSAVER_DEFAULT)){ + m_sdSettings = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER_DEFAULT, "", this); + // 重置屏保休息时间字段 + QStringList keysScreenSaverDefault = m_sdSettings->keys(); + if (keysScreenSaverDefault.contains(KEY_SHOW_REST_TIME)) { + bool isShow = m_sdSettings->get("show-rest-time").toBool(); + if (!isShow) { + m_sdSettings->set("show-rest-time", true); + if (keysScreenSaverDefault.contains(KEY_SHOW_CUSTOM_REST_TIME)) { + m_sdSettings->set("show-custom-rest-time", isShow); + } + if (keysScreenSaverDefault.contains(KEY_SHOW_UKUI_REST_TIME)) { + m_sdSettings->set("show-ukui-rest-time", isShow); + } + } + } + } + + // for PowerManager + // 同步旧的电源管理唤醒是否需密码配置 + FILE *fp = NULL; + fp = popen("xset s 0 0", "r"); + fclose(fp); + + if(QGSettings::isSchemaInstalled(POWER_TYPE_SCHENA)){ + m_pmSettings = new QGSettings(POWER_TYPE_SCHENA,"", this); + QStringList keys = m_pmSettings->keys(); + if (keys.contains("lockSuspend")) { + bool ret = m_pmSettings->get("lockSuspend").toBool(); + if(ret){ + m_pmSettings->set("lock-suspend",false); + } + } + if (keys.contains("lockHibernate")) { + bool ret = m_pmSettings->get("lockHibernate").toBool(); + if(ret){ + m_pmSettings->set("lock-hibernate",false); + } + } + if (keys.contains("lockBlankScreen") && keysScreenSaver.contains("closeActivationEnabled")) { + bool oldValue = m_pmSettings->get("lockBlankScreen").toBool(); + if(!oldValue && m_ssSettings){ + m_ssSettings->set("close-activation-enabled", oldValue); + m_pmSettings->set("lock-blank-screen", true); + } + } + } QString userName = getenv("USER"); QString configPath; @@ -68,76 +152,63 @@ SessionWatcher::SessionWatcher(QObject *parent) : QObject(parent) file.setPermissions(QFile::WriteUser | QFile::ReadUser | QFile::WriteOther | QFile::ReadOther); } configSettings = new QSettings(configPath, QSettings::IniFormat, this); - if(QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)) + if (QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)) { timegsettings = new QGSettings(TIME_TYPE_SCHEMA,"",this); - int timeType = timegsettings->get("hoursystem").toInt(); - setValue("timeType",timeType); - QString dateType = timegsettings->get("date").toString(); - setValue("dateType",dateType); - connect(timegsettings, &QGSettings::changed, - this, &SessionWatcher::onConfigurationTimeTpChanged); - -// activationEnabled_Key = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); -// connect(activationEnabled_Key, &QGSettings::changed, -// this, &SessionWatcher::activationEnabledChanged); -// idleActivationEnabled = activationEnabled_Key->get("idle-activation-enabled").toBool(); - -// lockEnabled_Key = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); -// connect(lockEnabled_Key, &QGSettings::changed, -// this, &SessionWatcher::lockEnabledChanged); -// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); -// qDebug()<get("idle-delay").toInt(); + int timeType = timegsettings->get("hoursystem").toInt(); + setValue("timeType",timeType); + QString dateType = timegsettings->get("date").toString(); + setValue("dateType",dateType); + connect(timegsettings, &QGSettings::changed, + this, &SessionWatcher::onConfigurationTimeTpChanged); } + + if (QGSettings::isSchemaInstalled(STYLE_TYPE_SCHEMA)) { + stylesettings = new QGSettings(STYLE_TYPE_SCHEMA,"",this); + double fontSize = stylesettings->get("systemFontSize").toDouble(); + setValue("fontSize",fontSize - defaultFontSize); + connect(stylesettings, &QGSettings::changed, + this, &SessionWatcher::onConfigurationTimeTpChanged); + } + + // 监听合盖信号 + QDBusConnection::systemBus().connect( + UPOWER_SERVICE, UPOWER_PATH, FREEDESKTOP_UPOWER, "PropertiesChanged", this, SLOT(onLidWatcherMessage(void))); } -void SessionWatcher::onConfigurationLockChanged(QString key) +void SessionWatcher::onSSConfigChanged(QString strKey) { - if(key == KEY_IDLE_LOCK){ - idleLock = settings_lock->get("idle-lock").toInt(); + if(strKey == KEY_IDLE_DELAY){ + idleDelay = m_ssSettings->get("idle-delay").toInt(); + } else if (strKey == KEY_IDLE_LOCK){ + idleLock = m_ssSettings->get("idle-lock").toInt(); + } else if (strKey == KEY_LOCK_TIMEOUT) { + m_nLockTimeout = m_ssSettings->get("lock-timeout").toInt(); } } void SessionWatcher::onConfigurationTimeTpChanged(QString key) { - if(key == "hoursystem"){ + if (key == "hoursystem") { int timeType = timegsettings->get("hoursystem").toInt(); setValue("timeType",timeType); - } - if(key == "date"){ - qDebug()<<"jinlaile~~~~~~~~~~~~~~key="<get("date").toString(); - qDebug()<<"lsadjfldsa"<get("systemFontSize").toDouble() - defaultFontSize; + setValue("fontSize", fontSize); } } void SessionWatcher::setValue(const QString &key, const QVariant &value) { + if (!configSettings) + return; configSettings->beginGroup("Greeter"); configSettings->setValue(key, value); configSettings->endGroup(); } -//void SessionWatcher::activationEnabledChanged(QString key) -//{ -// if(key == KEY_IDLE_ACTIVATION_ENABLED){ -// idleActivationEnabled = activationEnabled_Key->get("idle-activation-enabled").toBool(); -// } -//} - -//void SessionWatcher::lockEnabledChanged(QString key) -//{ -// if(key == KEY_IDLE_LOCK_ENABLED){ -// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); -// } -//} - void SessionWatcher::onStatusChanged(unsigned int status) { if(status == SESSION_IDLE) { @@ -179,6 +250,7 @@ void SessionWatcher::onStatusChanged(unsigned int status) if(m_timer2 && m_timer2->isActive()){ m_timer2->stop(); } + Q_EMIT sessionIdleExit(); } } @@ -188,3 +260,99 @@ void SessionWatcher::onSessionRemoved(const QDBusObjectPath &objectPath) if(objectPath.path() == sessionPath) exit(0); } + +bool SessionWatcher::isSleepActivationEnable() +{ + if (!m_ssSettings) + return false; + QStringList settingsKeys = m_ssSettings->keys(); + if (settingsKeys.contains("sleepActivationEnabled")) { + return m_ssSettings->get("sleep-activation-enabled").toBool(); + } else { + return false; + } +} + +bool SessionWatcher::isCloseActivationEnable() +{ + if (!m_ssSettings) + return false; + QStringList settingsKeys = m_ssSettings->keys(); + if (settingsKeys.contains("closeActivationEnabled")) { + return m_ssSettings->get("close-activation-enabled").toBool(); + } else { + return false; + } +} + +bool SessionWatcher::isLockEnable() +{ + if (!m_ssSettings) + return false; + QStringList settingsKeys = m_ssSettings->keys(); + if (settingsKeys.contains("lockEnabled")) { + return m_ssSettings->get("lock-enabled").toBool(); + } else { + return false; + } +} + +int SessionWatcher::sleepActivationDelay() +{ + if (!m_pmSettings) + return -1; + QStringList settingsKeys = m_pmSettings->keys(); + if (settingsKeys.contains("sleepComputerAc")) { + return m_pmSettings->get("sleep-computer-ac").toInt(); + } else { + return -1; + } +} + +int SessionWatcher::closeActivationDelay() +{ + if (!m_pmSettings) + return -1; + QStringList settingsKeys = m_pmSettings->keys(); + if (settingsKeys.contains("sleepDisplayAc")) { + return m_pmSettings->get("sleep-display-ac").toInt(); + } else { + return -1; + } +} + +int SessionWatcher::idledelay() +{ + return idleDelay; +} + +int SessionWatcher::locktimeout() +{ + return m_nLockTimeout; +} + +bool SessionWatcher::isLidCloseWithBlank() +{ + if (!m_pmSettings) + return false; + QStringList settingsKeys = m_pmSettings->keys(); + if (settingsKeys.contains("buttonLidAc")) { + QString strAction = m_pmSettings->get("button-lid-ac").toString(); + return (strAction == "blank"); + } else { + return false; + } +} + +void SessionWatcher::onLidWatcherMessage(void) +{ + QDBusInterface iface(UPOWER_SERVICE, UPOWER_PATH, FREEDESKTOP_UPOWER, QDBusConnection::systemBus()); + QDBusReply reply = iface.call("Get", "org.freedesktop.UPower", "LidIsClosed"); + if (reply.isValid()) { + m_lidState = reply.value().toBool(); + Q_EMIT lidStateChanged(m_lidState); + qDebug() << "lid state:" << m_lidState; + } else { + qDebug() << "Failed to get lid closed event!"; + } +} diff --git a/src/sessionwatcher.h b/src/sessionwatcher.h index 9b202d1..2c4a56d 100644 --- a/src/sessionwatcher.h +++ b/src/sessionwatcher.h @@ -31,32 +31,43 @@ class SessionWatcher : public QObject public: explicit SessionWatcher(QObject *parent = nullptr); void setValue(const QString &key, const QVariant &value); + bool isSleepActivationEnable(); + bool isCloseActivationEnable(); + bool isLockEnable(); + int sleepActivationDelay(); + int closeActivationDelay(); + int idledelay(); + bool isLidCloseWithBlank(); // 合盖关屏 + int locktimeout(); + Q_SIGNALS: void sessionIdle(); void sessionLockIdle(); + void sessionIdleExit(); + void lidStateChanged(bool isClosed); private Q_SLOTS: void onStatusChanged(unsigned int status); void onSessionRemoved(const QDBusObjectPath &objectPath); - void onConfigurationDelayChanged(QString key); - void onConfigurationLockChanged(QString key); void onConfigurationTimeTpChanged(QString key); -// void activationEnabledChanged(QString key); -// void lockEnabledChanged(QString key); + void onSSConfigChanged(QString strKey); + void onLidWatcherMessage(void); + private: QString sessionPath; - QGSettings *settings_delay; - QGSettings *settings_lock; - QGSettings *activationEnabled_Key; - QGSettings *lockEnabled_Key; - QGSettings *timegsettings; - QSettings *configSettings; - bool idleActivationEnabled; - bool lockEnabled; - int idleDelay; - int idleLock; + QGSettings *timegsettings = nullptr; + QSettings *configSettings = nullptr; + QGSettings *m_ssSettings = nullptr; + QGSettings *m_pmSettings = nullptr; + QGSettings *m_sdSettings = nullptr; + QGSettings *stylesettings = nullptr; + int idleDelay = -1; + int idleLock = -1; + int m_nLockTimeout = -1; QTimer *m_timer = nullptr; QTimer *m_timer2 = nullptr; + bool m_lidState = false; + double defaultFontSize; }; #endif // SESSIONWATCHER_H diff --git a/src/surewindow.cpp b/src/surewindow.cpp index 7633f15..ee7e4eb 100644 --- a/src/surewindow.cpp +++ b/src/surewindow.cpp @@ -1,20 +1,36 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "surewindow.h" #include "ui_surewindow.h" +#include "configuration.h" #include +#include + SureWindow::SureWindow(QWidget *parent) : QWidget(parent), - ui(new Ui::SureWindow) + ui(new Ui::SureWindow), + configuration(Configuration::instance()) { ui->setupUi(this); - ui->tipLabel->setText(tr("Multiple users are logged in at the same time.Are you sure " - "you want to reboot this system?")); - ui->tipLabel->setStyleSheet("color:white;font:14pt;"); - ui->cancelBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;}" - "QPushButton:hover{background: rgba(255, 255, 255, 0.4);border-radius: 8px;}" - "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); - ui->confirmBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;}" - "QPushButton:hover{background: rgba(255, 255, 255, 0.25);border-radius: 8px;}" - "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); + curFontSize = configuration->getFontSize(); + m_ptToPx = configuration->getPtToPx(); + ui->tipLabel->setFontSize(14 + curFontSize); + //ui->tipLabel->setWordWrap(true); connect(ui->cancelBtn, &QPushButton::clicked, this, [&]() { emit cantelButtonclicked(); }); connect(ui->confirmBtn, &QPushButton::clicked, this, [&]() { emit confirmButtonclicked(); }); } @@ -22,11 +38,76 @@ SureWindow::SureWindow(QWidget *parent) : SureWindow::~SureWindow() { delete ui; - - } -void SureWindow::setText(const QString tips) +void SureWindow::setTips(const QString tips) { + ui->cancelBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;color: white;}" + "QPushButton:hover{background: rgba(255, 255, 255, 0.4);border-radius: 8px;}" + "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); + ui->confirmBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;color: white;}" + "QPushButton:hover{background: rgba(255, 255, 255, 0.4);border-radius: 8px;}" + "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); + sysFont.setPointSize((16 + curFontSize) *m_ptToPx); + ui->confirmBtn->setFont(sysFont); + ui->cancelBtn->setFont(sysFont); + ui->confirmBtn->show(); + ui->tipLabel->show(); + ui->listView->hide(); ui->tipLabel->setText(tips); } + +void SureWindow::setWarning(QVector &list, int type) +{ + switch (type) { + case 0: + ui->tipLabel->setText(tr("The following program is running to prevent the system from reboot!")); + break; + case 1: + ui->tipLabel->setText(tr("The following program is running to prevent the system from shutting down!")); + break; + case 2: + ui->tipLabel->setText(tr("The following program is running to prevent the system from suspend!")); + break; + case 3: + ui->tipLabel->setText(tr("The following program is running to prevent the system from hibernate!")); + break; + default: + break; + } + ui->tipLabel->adjustSize(); + adjustSize(); + ui->listView->show(); + + QStandardItemModel *model = new QStandardItemModel(this); + for (auto iter = list.begin(); iter != list.end(); ++iter) { + QIcon icon; + QString appName = iter->name; + QString iconName = iter->icon; + + if (!iconName.isEmpty() && QIcon::hasThemeIcon(iconName)) { + icon = QIcon::fromTheme(iconName); + } else if (QIcon::hasThemeIcon("application-x-desktop")) { + icon = QIcon::fromTheme("application-x-desktop"); + } + model->appendRow(new QStandardItem(icon, appName)); + } + + ui->listView->verticalScrollMode(); + ui->listView->setStyleSheet("color:white; background-color: rgba(255,255,255,30%); border-radius: 12px;"); + sysFont.setPointSize((10 + curFontSize) *m_ptToPx); + ui->listView->setFont(sysFont); + ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->listView->setIconSize(QSize(32,32)); + ui->listView->setModel(model); + ui->listView->setFixedSize(520, 320); + adjustSize(); + ui->cancelBtn->setFixedSize(120, 48); + + ui->confirmBtn->hide(); + ui->cancelBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;color: white;}" + "QPushButton:hover{background: rgba(255, 255, 255, 0.4);border-radius: 8px;}" + "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); + sysFont.setPointSize((16 + curFontSize) *m_ptToPx); + ui->cancelBtn->setFont(sysFont); +} diff --git a/src/surewindow.h b/src/surewindow.h index 89871ff..7d49b31 100644 --- a/src/surewindow.h +++ b/src/surewindow.h @@ -1,12 +1,32 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef SUREWINDOW_H #define SUREWINDOW_H +#include "lockchecker.h" #include namespace Ui { class SureWindow; } +class Configuration; + class SureWindow : public QWidget { Q_OBJECT @@ -14,7 +34,8 @@ class SureWindow : public QWidget public: explicit SureWindow(QWidget *parent = nullptr); ~SureWindow(); - void setText(const QString tips); + void setTips(const QString tips); + void setWarning(QVector &list, int type); private: Ui::SureWindow *ui; @@ -23,6 +44,12 @@ private: Q_SIGNALS: void cantelButtonclicked(); void confirmButtonclicked(); + +private: + Configuration *configuration; + double curFontSize = 0; + double m_ptToPx = 1.0; + QFont sysFont; }; #endif // SUREWINDOW_H diff --git a/src/surewindow.ui b/src/surewindow.ui index 0f921d5..e2aea7a 100644 --- a/src/surewindow.ui +++ b/src/surewindow.ui @@ -6,8 +6,8 @@ 0 0 - 821 - 631 + 632 + 674 @@ -15,7 +15,7 @@ - 46 + 24 @@ -46,7 +46,7 @@ - + Noto Sans CJK SC @@ -72,11 +72,60 @@ + + + + 0 + + + 19 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 520 + 320 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + 24 + + 5 + @@ -100,8 +149,8 @@ - 96 - 36 + 120 + 48 @@ -113,14 +162,14 @@ - 96 - 36 + 120 + 48 - 96 - 36 + 120 + 48 @@ -158,6 +207,13 @@ + + + KLabel + QLabel +
klabel.h
+
+
diff --git a/src/tabletlockwidget.cpp b/src/tabletlockwidget.cpp index 82e4932..9a18136 100644 --- a/src/tabletlockwidget.cpp +++ b/src/tabletlockwidget.cpp @@ -35,7 +35,7 @@ #include "tabletlockwidget.h" #include "authdialog.h" -#include "virtualkeyboard.h" +#include "virtualkeyboardwidget.h" #include "users.h" #include "displaymanager.h" #include "weathermanager.h" @@ -62,7 +62,7 @@ TabletLockWidget::TabletLockWidget(QWidget *parent) : m_pb_powerManager(new QPushButton(this)), m_pb_networkManager(new QPushButton(this)), m_vKeyboardPB(new QPushButton(this)), - m_vKeyboard(new VirtualKeyboard(this)), + m_vKeyboard(new VirtualKeyboardWidget(this)), m_cancelOrBack(new QPushButton(this)), m_pb_skip(new QPushButton(this)), m_verificationWidget(new VerificationWidget(this)), @@ -78,7 +78,8 @@ TabletLockWidget::TabletLockWidget(QWidget *parent) : m_vKeyboard->installEventFilter(this); this->installEventFilter(this); - powermanager = new PowerManager(this); + powermanager = new PowerManager(0, this); + powermanager->setStartupMode(m_isStartupMode); powermanager->hide(); initUI(); @@ -118,6 +119,14 @@ bool TabletLockWidget::eventFilter(QObject *obj, QEvent *event) return QWidget::eventFilter(obj, event); } +void TabletLockWidget::setStartupMode(bool mode) +{ + m_isStartupMode = mode; + if (powermanager) { + powermanager->setStartupMode(m_isStartupMode); + } +} + void TabletLockWidget::startAuth() { m_digitalAuthDialog->startAuth(); @@ -157,8 +166,8 @@ void TabletLockWidget::initUI() //虚拟键盘 m_vKeyboard->hide(); - connect(m_vKeyboard, &VirtualKeyboard::aboutToClose, - m_vKeyboard, &VirtualKeyboard::hide); + connect(m_vKeyboard, &VirtualKeyboardWidget::aboutToClose, + m_vKeyboard, &VirtualKeyboardWidget::hide); m_vKeyboardPB->setIcon(QIcon(":/image/assets/intel/keyboard.png")); m_vKeyboardPB->setFixedSize(48,48); @@ -225,9 +234,9 @@ void TabletLockWidget::initUI() //Todo 1、锁屏 -》息屏 m_digitalAuthDialog->reset(); Q_EMIT blackSaver(); -#ifdef USE_INTEL +#ifdef USE_INTEL powermanager->hibernate(); -#endif +#endif } else { m_digitalAuthDialog->reset(); m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); @@ -339,7 +348,7 @@ void TabletLockWidget::initConnect() updateNetIcon(m_kylinNM->getConnectStatus()); }); - connect(m_vKeyboard, &VirtualKeyboard::aboutToClose, m_vKeyboard, [=](){ + connect(m_vKeyboard, &VirtualKeyboardWidget::aboutToClose, m_vKeyboard, [=](){ if(m_vKeyboard->isHidden() && m_kylinNM->isVisible()) { m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, this->height() - m_kylinNM->height() - 100, @@ -632,3 +641,17 @@ EduPlatformInterface* TabletLockWidget::getEduPlatformInterface() return m_eduPlatformInterface; } + +void TabletLockWidget::onGlobalKeyPress(const quint8 &key) +{ + if (powermanager && powermanager->isVisible()) { + powermanager->onGlobalKeyPress(key); + } +} + +void TabletLockWidget::onGlobalkeyRelease(const quint8 &key) +{ + if (powermanager && powermanager->isVisible()) { + powermanager->onGlobalkeyRelease(key); + } +} diff --git a/src/tabletlockwidget.h b/src/tabletlockwidget.h index 12be613..8acf3b7 100644 --- a/src/tabletlockwidget.h +++ b/src/tabletlockwidget.h @@ -30,7 +30,7 @@ #include #include -class VirtualKeyboard; +class VirtualKeyboardWidget; class PowerManager; class AuthDialog; class Users; @@ -65,6 +65,11 @@ public: return true; }; // void RecieveKey(int key); + void setStartupMode(bool mode); + +public Q_SLOTS: + void onGlobalKeyPress(const quint8 &key); + void onGlobalkeyRelease(const quint8 &key); Q_SIGNALS: void closed(); @@ -99,7 +104,7 @@ protected: private: AuthDialog *authDialog; - VirtualKeyboard *m_vKeyboard; + VirtualKeyboardWidget *m_vKeyboard; PowerManager *powermanager; QTimer *timer; QMenu *usersMenu; @@ -122,6 +127,7 @@ private: int m_authType; int m_pageType = 0; + bool m_isStartupMode = false; }; #endif // TABLETLOCKWIDGET_H diff --git a/src/types.h b/src/types.h index 42d5522..7153a28 100644 --- a/src/types.h +++ b/src/types.h @@ -56,6 +56,14 @@ enum ScreenStatus #define SS_DBUS_PATH "/" #define SS_DBUS_INTERFACE "org.ukui.ScreenSaver" +#define SSWND_DBUS_SERVICE "org.ukui.ScreenSaverWnd" +#define SSWND_DBUS_PATH "/" +#define SSWND_DBUS_INTERFACE "org.ukui.ScreenSaverWnd" + +#define DESKTOP_DBUS_SERVICE "org.ukui.peony" +#define DESKTOP_DBUS_PATH "/org/ukui/peony" +#define DESKTOP_DBUS_INTERFACE "org.ukui.peony" + #define BIO_ERROR -1 #define BIO_FAILED 0 #define BIO_SUCCESS 1 diff --git a/src/ukss_interface.cpp b/src/ukss_interface.cpp new file mode 100644 index 0000000..11ea9bd --- /dev/null +++ b/src/ukss_interface.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ + +#include "ukss_interface.h" +#include +#include + +int LockByBlank(QString strReason) +{ + QProcess procCmd; + QString strCmd = QString("ukui-screensaver-command -b %1").arg(strReason); + qDebug()<<"LockByBlank,CMD:"<. + * +**/ +#ifndef __UKSS_INTERFACE_H__ +#define __UKSS_INTERFACE_H__ + +#include + +#if defined(UKSSSO_LIBRARY) +# define UKSSSO_EXPORT Q_DECL_EXPORT +#else +# define UKSSSO_EXPORT Q_DECL_IMPORT +#endif + +extern "C" UKSSSO_EXPORT int LockByBlank(QString strReason); + +#endif // __UKSS_INTERFACE_H__ diff --git a/src/ukui-screensaver-backend.cpp b/src/ukui-screensaver-backend.cpp index 63f6351..87ca85d 100644 --- a/src/ukui-screensaver-backend.cpp +++ b/src/ukui-screensaver-backend.cpp @@ -21,7 +21,6 @@ #include #include "interface.h" -#include "sessionwatcher.h" #include "screensaveradaptor.h" #include "types.h" @@ -31,8 +30,6 @@ #include #include -#define POWER_TYPE_SCHENA "org.ukui.power-manager" - void sig_chld(int /*signo*/) { pid_t pid; @@ -43,10 +40,6 @@ void sig_chld(int /*signo*/) int main(int argc, char *argv[]) { -// if(signal(SIGCHLD, sig_chld) == SIG_ERR) { -// perror("signal error"); -// exit(EXIT_FAILURE); -// } initUkuiLog4qt("ukui-screensaver-backend"); // 重启或关机时不被session关掉 qunsetenv("SESSION_MANAGER"); @@ -65,39 +58,19 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - FILE *fp; - - // for PowerManager - fp = popen("xset s 0 0", "r"); - fclose(fp); -// Q_UNUSED(fp) - - QGSettings *powerSettings; - if(QGSettings::isSchemaInstalled(POWER_TYPE_SCHENA)){ - powerSettings = new QGSettings(POWER_TYPE_SCHENA,"",NULL); - QStringList keys = powerSettings->keys(); - if (keys.contains("lockSuspend")) { - bool ret = powerSettings->get("lockSuspend").toBool(); - if(ret){ - powerSettings->set("lock-suspend",false); - } - } - if (keys.contains("lockHibernate")) { - bool ret = powerSettings->get("lockHibernate").toBool(); - if(ret){ - powerSettings->set("lock-hibernate",false); - } - } - } - // 注册DBus Interface *interface = new Interface(); ScreenSaverAdaptor adaptor(interface); QDBusConnection service = QDBusConnection::sessionBus(); - if(!service.registerService(SS_DBUS_SERVICE)) { - qDebug() << service.lastError().message(); - exit(EXIT_FAILURE); + QString sessionDbus = SS_DBUS_SERVICE; + if(!service.registerService(sessionDbus)) { + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");; + sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum); + if(!service.registerService(sessionDbus)) { + qDebug() << service.lastError().message(); + exit(EXIT_FAILURE); + } } if(!service.registerObject(SS_DBUS_PATH, SS_DBUS_SERVICE, &adaptor, QDBusConnection::ExportAllSlots | @@ -107,41 +80,6 @@ int main(int argc, char *argv[]) } qDebug() << service.baseService(); - // 发送DBus信号 - SessionWatcher *watcher = new SessionWatcher; - QObject::connect(watcher, &SessionWatcher::sessionIdle, - interface, &Interface::onSessionIdleReceived); - - QObject::connect(watcher, &SessionWatcher::sessionLockIdle, - interface, &Interface::Lock); - - QObject::connect(watcher, &SessionWatcher::sessionIdle, - &a, [&]{ - QDBusMessage message = QDBusMessage::createSignal(SS_DBUS_PATH, - SS_DBUS_INTERFACE, - "SessionIdle"); - service.send(message); - //qDebug()<<"message="<start(3000); - QObject::connect(checkInterface, SIGNAL(NameLost(QString)), interface, SLOT(onNameLost(QString))); diff --git a/src/ukui-screensaver-checkpass.cpp b/src/ukui-screensaver-checkpass.cpp index 6f48647..165259d 100644 --- a/src/ukui-screensaver-checkpass.cpp +++ b/src/ukui-screensaver-checkpass.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include #include #include diff --git a/src/ukui-screensaver-command.cpp b/src/ukui-screensaver-command.cpp index 1ce2d54..c18808c 100644 --- a/src/ukui-screensaver-command.cpp +++ b/src/ukui-screensaver-command.cpp @@ -24,6 +24,7 @@ #include #include "types.h" #include +#include #define WORKING_DIRECTORY "/usr/share/ukui-screensaver" @@ -53,20 +54,31 @@ int main(int argc, char **argv) QCoreApplication::translate("main", "unlock the screen saver")); QCommandLineOption screensaverOption({"s", QStringLiteral("screensaver")}, QCoreApplication::translate("main", "show the screensaver")); + QCommandLineOption blankOption({"b", QStringLiteral("blank")}, + QCoreApplication::translate("main", "show blank and delay to lock,param:idle/lid/lowpower"), "lid"); parser.addOption(lockOption); parser.addOption(queryOption); parser.addOption(unlockOption); parser.addOption(screensaverOption); + parser.addOption(blankOption); parser.process(a); - if(!parser.isSet(lockOption) && !parser.isSet(queryOption) && !parser.isSet(unlockOption) && !parser.isSet(screensaverOption)) + if(!parser.isSet(lockOption) && !parser.isSet(queryOption) && !parser.isSet(unlockOption) + && !parser.isSet(screensaverOption) && !parser.isSet(blankOption)) return -1; - QDBusInterface *interface = new QDBusInterface(SS_DBUS_SERVICE, + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); + QString sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum); + QDBusInterface *interface = new QDBusInterface(sessionDbus, SS_DBUS_PATH, SS_DBUS_INTERFACE); - + if (!interface->isValid()) { + delete interface; + interface = new QDBusInterface(SS_DBUS_SERVICE, + SS_DBUS_PATH, + SS_DBUS_INTERFACE); + } QDBusReply stateReply = interface->call("GetLockState"); if(!stateReply.isValid()){ qWarning()<< "Get state error:" << stateReply.error(); @@ -90,6 +102,36 @@ int main(int argc, char **argv) QDBusMessage msg = interface->call("ShowScreensaver"); if(msg.type() == QDBusMessage::ErrorMessage) qDebug() << msg.errorMessage(); + } else if (parser.isSet(blankOption) && !stateReply) { + int nLockType = 0; + qDebug()<<"Param:"< bLockSuccess = interface->call("LockByBlank", nLockType); + if(bLockSuccess.isValid() && bLockSuccess.value()) { + bool isLocked = false; + for (int n = 0; n < 20; n++) { + QDBusReply reply = interface->call("GetLockState"); + if (reply.isValid()) { + isLocked = reply.value(); + } + if (isLocked) { + qDebug()<<"LockState:"< #include #include +#include #include #include +#include +#include "plasma-shell-manager.h" #include #include #include #include #include +#include "screensaverwndadaptor.h" #include #include #include "fullbackgroundwidget.h" @@ -42,6 +46,7 @@ #define MAX_FILE_SIZE 1024 * 1024 #define LOG_FILE0 "screensaver_0.log" #define LOG_FILE1 "screensaver_1.log" +#include #define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" #define KEY_LOCK_ENABLED "lock-enabled" @@ -128,6 +133,8 @@ void handler(int signum) #define WORKING_DIRECTORY "/usr/share/ukui-screensaver" int main(int argc, char *argv[]) { + LayerShellQt::Shell::useLayerShell(); + if(argc < 2) return 0; @@ -152,26 +159,57 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); QApplication::setSetuidAllowed(true); + LogindIntegration *m_logind = new LogindIntegration(&a); + QObject::connect(m_logind, &LogindIntegration::requestUnlock, [=]() { + if (window) { + window->closeScreensaver(); + } else { + exit(0); + } + }); + if (!m_logind->isSessionActive()) { + QEventLoop *loopTemp = new QEventLoop(&a); + QObject::connect(m_logind, &LogindIntegration::sessionActiveChanged, [loopTemp](bool isActive) { + qDebug()<<"sessionActiveChanged:"<isRunning()) { + loopTemp->quit(); + } + }); + QObject::connect(m_logind, &LogindIntegration::requestLock, [loopTemp]() { + qDebug()<<"session requestLock!"; + if (loopTemp->isRunning()) { + loopTemp->quit(); + } + }); + loopTemp->exec(); + } //命令行参数解析 QCommandLineParser parser; - parser.setApplicationDescription(QCoreApplication::translate("main", "Dialog for the ukui ScreenSaver.")); + parser.setApplicationDescription(QGuiApplication::translate("main", "Dialog for the ukui ScreenSaver.")); parser.addHelpOption(); parser.addVersionOption(); + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); // 举例说明:将 "-adb" 当成一个选项来看,而不是看成 "-a -b -c" QCommandLineOption lockOption(QStringLiteral("lock"), - QCoreApplication::translate("main", "lock the screen immediately")); + QGuiApplication::translate("main", "lock the screen immediately")); QCommandLineOption lstOption(QStringLiteral("lock-startup"), - QCoreApplication::translate("main", "lock the screen immediately")); + QGuiApplication::translate("main", "lock the screen immediately")); QCommandLineOption sessionIdleOption(QStringLiteral("session-idle"), - QCoreApplication::translate("main", "activated by session idle signal")); + QGuiApplication::translate("main", "activated by session idle signal")); QCommandLineOption lscreensaverOption(QStringLiteral("lock-screensaver"), - QCoreApplication::translate("main", "lock the screen and show screensaver immediately")); + QGuiApplication::translate("main", "lock the screen and show screensaver immediately")); QCommandLineOption screensaverOption(QStringLiteral("screensaver"), - QCoreApplication::translate("main", "show screensaver immediately")); + QGuiApplication::translate("main", "show screensaver immediately")); QCommandLineOption blankOption(QStringLiteral("blank"), - QCoreApplication::translate("main", "lock the screen and show screensaver immediately")); - parser.addOptions({lockOption, lstOption,sessionIdleOption , screensaverOption,blankOption,lscreensaverOption}); + QGuiApplication::translate("main", "lock the screen and show screensaver immediately")); + QCommandLineOption delayOption(QStringLiteral("delay"), + QGuiApplication::translate("main", "show blank screensaver immediately and delay time to show lock"), + QGuiApplication::translate("delay", "how long to show lock"), "0"); + QCommandLineOption hasLockOption(QStringLiteral("has-lock"), + QGuiApplication::translate("main", "show blank screensaver immediately and if lock"), + QGuiApplication::translate("has-lock", "if show lock"), "1"); + parser.addOptions({lockOption, lstOption,sessionIdleOption , screensaverOption,blankOption,lscreensaverOption,delayOption,hasLockOption}); parser.process(a); if(!parser.isSet(sessionIdleOption) @@ -196,15 +234,53 @@ int main(int argc, char *argv[]) window = new FullBackgroundWidget(); - QFile qssFile(":/qss/assets/authdialog.qss"); - if(qssFile.open(QIODevice::ReadOnly)) { - a.setStyleSheet(qssFile.readAll()); +// QFile qssFile(":/qss/assets/authdialog.qss"); +// if(qssFile.open(QIODevice::ReadOnly)) { +// a.setStyleSheet(qssFile.readAll()); +// } +// qssFile.close(); + // 监听会话active状态 + QObject::connect(m_logind, &LogindIntegration::sessionActiveChanged, window, &FullBackgroundWidget::onSessionActiveChanged); + // 注册DBus + ScreenSaverWndAdaptor adaptorWnd(window); + + QDBusConnection service = QDBusConnection::sessionBus(); + QString sessionDbus = SSWND_DBUS_SERVICE; + if(!service.registerService(SSWND_DBUS_SERVICE)) { + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");; + sessionDbus = QString("%1%2").arg(QString(SSWND_DBUS_SERVICE)).arg(displayNum); + if(!service.registerService(sessionDbus)) { + qDebug() << service.lastError().message(); + return 1; + } } - qssFile.close(); + if(!service.registerObject(SSWND_DBUS_PATH, SSWND_DBUS_SERVICE, &adaptorWnd, + QDBusConnection::ExportAllSlots | + QDBusConnection::ExportAllSignals)) { + qDebug() << service.lastError().message(); + return 1; + } + qDebug() << service.baseService(); + if(parser.isSet(blankOption)) { - window->onBlankScreensaver(); + int nDelay = 0; + bool isHasLock = true; + if (parser.isSet(delayOption)){ + int nDelayValue = parser.value(delayOption).toInt(); + if (nDelayValue > 0) { + nDelay = nDelayValue; + } + } + if (parser.isSet(hasLockOption)){ + int nHasLockValue = parser.value(hasLockOption).toInt(); + if (nHasLockValue == 0) { + isHasLock = false; + } + } + qDebug()<<"-------------:"<onBlankScreensaver(nDelay, isHasLock); } #ifndef USE_INTEL @@ -218,14 +294,16 @@ int main(int argc, char *argv[]) if(parser.isSet(lstOption)) { + window->setIsStartup(true); window->lock(); - window->setIsStartup(true); } if(parser.isSet(sessionIdleOption)) { - if(window->onSessionStatusChanged(SESSION_IDLE) == -1) - return 0; + if(window->onSessionStatusChanged(SESSION_IDLE) == -1) { + window->close(); + return 0; + } } if(parser.isSet(lscreensaverOption)) @@ -240,14 +318,30 @@ int main(int argc, char *argv[]) */ if(parser.isSet(screensaverOption)) { - window->showScreensaver(); + window->showScreensaver(true); } #ifdef USE_INTEL window->show(); window->activateWindow(); #endif + + bool isWayland = false; + if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland" && !QX11Info::isPlatformX11()) { + isWayland = true; + } +// if (isWayland){ +// PlasmaShellManager::getInstance(); +// PlasmaShellManager::getInstance()->setAppWindowKeepAbove(true); +// } + if (isWayland) { + if (auto layerShellWindow = LayerShellQt::Window::get(window->windowHandle())) { + layerShellWindow->setExclusiveZone(-1); + layerShellWindow->setLayer(LayerShellQt::Window::LayerOverlay); + layerShellWindow->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityExclusive); + } + } QString username = getenv("USER"); int uid = getuid(); QDBusInterface *interface = new QDBusInterface("cn.kylinos.Kydroid2", diff --git a/src/ukui-screensaver.pro b/src/ukui-screensaver.pro index f8b4b43..aab53d3 100644 --- a/src/ukui-screensaver.pro +++ b/src/ukui-screensaver.pro @@ -44,7 +44,7 @@ SOURCES += \ auxiliary.cpp \ configuration.cpp \ screensaverwidget.cpp \ - screensaver.cpp \ + screensavermode.cpp \ event_monitor.cpp \ monitorwatcher.cpp @@ -58,7 +58,7 @@ HEADERS += \ auxiliary.h \ configuration.h \ screensaverwidget.h \ - screensaver.h \ + screensavermode.h \ event_monitor.h \ monitorwatcher.h @@ -73,7 +73,8 @@ TRANSLATIONS = ../i18n_ts/zh_CN.ts \ ../i18n_ts/ru.ts \ ../i18n_ts/fr.ts \ ../i18n_ts/pt.ts \ - ../i18n_ts/es.ts + ../i18n_ts/es.ts \ + ../i18n_ts/bo_CN.ts target.path = /usr/bin/ diff --git a/src/users.cpp b/src/users.cpp index 03c87e6..1e4a305 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -40,8 +40,15 @@ Users::Users(QObject *parent) : QObject(parent) if (Utils::isCommunity()) { defaultIcon = ":/image/assets/01-default-community.png"; } else { - defaultIcon = ":/image/assets/01-default-commercial.png"; + //优先读取控制面板的默认头像文件,保持登录锁屏默认头像和控制面板一致 + QFile faceFile("/usr/share/ukui/faces/default.png"); + if(faceFile.exists()){ + defaultIcon = "/usr/share/ukui/faces/default.png"; + }else{ + defaultIcon = ":/image/assets/01-default-commercial.png"; + } } + loadUsers(); } diff --git a/src/utils.cpp b/src/utils.cpp index e5b7f50..dc5e9bc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "utils.h" #include diff --git a/src/utils.h b/src/utils.h index 4966654..b00b483 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef UTILS_H #define UTILS_H diff --git a/src/verificationwidget.cpp b/src/verificationwidget.cpp index edbb92f..9acb3e4 100644 --- a/src/verificationwidget.cpp +++ b/src/verificationwidget.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "verificationwidget.h" #include #include diff --git a/src/verificationwidget.h b/src/verificationwidget.h index cbc13e7..973017e 100644 --- a/src/verificationwidget.h +++ b/src/verificationwidget.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef VERIFICATIONWIDGET_H #define VERIFICATIONWIDGET_H diff --git a/src/verticalVerificationwidget.cpp b/src/verticalVerificationwidget.cpp index 1dd912a..e848a45 100644 --- a/src/verticalVerificationwidget.cpp +++ b/src/verticalVerificationwidget.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #include "verticalVerificationwidget.h" #include #include diff --git a/src/verticalVerificationwidget.h b/src/verticalVerificationwidget.h index 749dadc..26a94d4 100644 --- a/src/verticalVerificationwidget.h +++ b/src/verticalVerificationwidget.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * +**/ #ifndef VERTICALVERIFICATIONWIDGET_H #define VERTICALVERIFICATIONWIDGET_H diff --git a/src/weathermanager.cpp b/src/weathermanager.cpp index e1738f2..506b34c 100644 --- a/src/weathermanager.cpp +++ b/src/weathermanager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,17 +40,18 @@ const int weatherReqInterval = 1000 * 60 * 20; //定时更新天气,和麒麟天 const QByteArray schemaWeather = "org.china-weather-data.settings"; static const QMap weatherMap { - {"NA", "55"}, - {"晴", "0"}, - {"多云", "1"}, - {"阴", "2"}, - {"阵雨", "3"}, - {"雷阵雨", "4"}, - {"小雨", "7"}, - {"中雨", "8"}, - {"大雨", "9"}, - {"中到大雨", "9"}, - {"雪", "13"}, + {"晴", "100"},{"多云", "101"},{"少云", "102"},{"晴间多云", "103"},{"阴", "104"}, + {"有风", "200"},{"平静", "201"},{"微风", "202"},{"和风", "203"},{"清风", "204"},{"强风劲风", "205"},{"疾风", "206"},{"大风", "207"},{"烈风", "208"},{"风暴", "209"}, + {"狂暴风", "210"},{"飓风", "211"},{"龙卷风", "212"},{"热带风暴", "213"}, + {"阵雨", "300"},{"强阵雨", "301"},{"雷阵雨", "302"},{"强雷阵雨", "303"},{"雷阵雨伴有冰雹", "304"},{"小雨", "305"},{"中雨", "306"},{"大雨", "307"},{"极端降雨", "308"},{"毛毛雨细雨", "309"}, + {"暴雨", "310"},{"大暴雨", "311"},{"特大暴雨", "312"},{"冻雨", "313"},{"小到中雨", "314"},{"中到大雨", "315"},{"大到暴雨", "316"},{"暴雨到大暴雨", "317"},{"大暴雨到特大暴雨", "318"}, + {"雨", "399"}, + {"小雪", "400"},{"中雪", "401"},{"大雪", "402"},{"暴雪", "403"},{"雨夹雪", "404"},{"雨雪天气", "405"},{"阵雨夹雪", "406"},{"阵雪", "407"},{"小到中雪", "408"},{"中到大雪", "409"}, + {"大到暴雪", "410"},{"雪", "499"}, + {"薄雾", "500"},{"雾", "501"},{"霾", "502"},{"扬沙", "503"},{"浮尘", "504"},{"沙尘暴", "507"},{"强沙尘暴", "508"},{"大雾", "509"}, + {"强浓雾", "510"},{"中度霾", "511"},{"重度霾", "512"},{"严重霾", "513"},{"大雾", "514"},{"特强浓雾", "515"}, + {"热", "900"},{"冷", "901"}, + {"未知", "999"} }; WeatherManager::WeatherManager(QObject *parent) : QObject(parent) @@ -66,6 +67,20 @@ WeatherManager::WeatherManager(QObject *parent) : QObject(parent) m_local_weather_info = new LocalWeatherInfo(this); connect(m_timer, &QTimer::timeout, this, &WeatherManager::weatherRequest); + + m_networkWatcher = new NetWorkWatcher(this); + connect(m_networkWatcher, &NetWorkWatcher::NetworkStateChanged, this, &WeatherManager::onNetworkStateChanged); + + m_networkWatcher->checkOnline(); +} + +void WeatherManager::onNetworkStateChanged(uint state) +{ + qDebug() << state; + if (NM_STATE_CONNECTED_GLOBAL != state) + emit onWeatherUpdate("天气不可用", NULL, NULL); + else + getWeather(); } void WeatherManager::getWeather() @@ -96,6 +111,9 @@ bool WeatherManager::updateLocation() emit onWeatherUpdate(m_local_weather_info->getCityName(), m_local_weather_info->getCondText(), m_local_weather_info->getTemperature()); + + + m_networkWatcher->checkOnline(); return true; } m_city_id = getLogcalCityId(); @@ -153,6 +171,23 @@ QString WeatherManager::getLogcalCityId() void WeatherManager::replyFinished(QNetworkReply *reply) { + if(reply != nullptr && reply->error() != QNetworkReply::NoError) + { + qWarning() << "[WeatherManager][replyFinished] get weather error:(" + << reply->error() << ")" << reply->errorString(); + if (m_networkTryNum < 15) + { + m_networkTryNum++; + QTimer::singleShot(1000, this, [=]{ + weatherRequest(); + }); + } else { + m_networkTryNum = 0; + } + emit onWeatherUpdate("天气不可用", "", ""); + return; + } + //注:天气信息只解析了锁屏需要展示的部分 QByteArray BA; QJsonDocument JD; @@ -180,13 +215,14 @@ void WeatherManager::replyFinished(QNetworkReply *reply) } if (now.contains("tmp")){ - m_temperature = now.mid(4); + m_temperature = now.mid(4) + "°C"; } } emit onWeatherUpdate(m_city_name, m_cond_txt, m_temperature); } } else { qWarning() << "get weather info error : " << JPE.errorString(); + emit onWeatherUpdate("天气不可用", "", ""); } reply->deleteLater(); @@ -202,17 +238,33 @@ QPixmap WeatherManager::getWeatherIcon(QString cond) if (cond.isEmpty()) { qWarning() << "cond info is unknown"; - return QPixmap(":/image/assets/weather/55.png").scaled(32,32); + return QPixmap(":/weather/assets/weather-icon/999.svg").scaled(32,32); } //根据m_cond_txt QString numStr = weatherMap.value(cond); if (!numStr.isEmpty()) { qDebug() << "----------------numStr=" + numStr; - return QPixmap(":/image/assets/weather/" + numStr +".png").scaled(32,32); + return QPixmap(":/weather/assets/weather-icon/" + numStr +".svg").scaled(32,32); } - return QPixmap(":/image/assets/weather/55.png").scaled(32,32); + qWarning() << "天气为|" << cond << "|"; + return QPixmap(":/weather/assets/weather-icon/999.svg").scaled(32,32); +} + +QString WeatherManager::getCityName() +{ + return ""; +} + +QString WeatherManager::getCond() +{ + return ""; +} + +QString WeatherManager::getTemperature() +{ + return ""; } LocalWeatherInfo::LocalWeatherInfo(QObject *parent) diff --git a/src/weathermanager.h b/src/weathermanager.h index b1d2783..3f29c40 100644 --- a/src/weathermanager.h +++ b/src/weathermanager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,8 @@ #include #include +#include "../src/networkwatcher.h" + class QNetworkAccessManager; class QNetworkReply; class LocalWeatherInfo; @@ -39,12 +41,17 @@ Q_SIGNALS: private Q_SLOTS: void replyFinished(QNetworkReply *); + void onNetworkStateChanged(uint state); public: void getWeather(); QPixmap getWeatherIcon(); QPixmap getWeatherIcon(QString cond); + QString getCityName(); + QString getCond(); + QString getTemperature(); + private: bool updateLocation();//更新位置,从用户设置获取城市信息,如有多个,只取第一个,未对接 void weatherRequest(); @@ -63,6 +70,9 @@ private: QGSettings *m_settings; LocalWeatherInfo *m_local_weather_info; + NetWorkWatcher *m_networkWatcher; + + int m_networkTryNum = 0; }; class LocalWeatherInfo : QObject diff --git a/src/xeventmonitor.cpp b/src/xeventmonitor.cpp index 3d2feb4..9eca744 100644 --- a/src/xeventmonitor.cpp +++ b/src/xeventmonitor.cpp @@ -115,7 +115,7 @@ void XEventMonitorPrivate::run() // Receive KeyPress, KeyRelease, ButtonPress, ButtonRelease and MotionNotify events. memset(range, 0, sizeof(XRecordRange)); - range->device_events.first = KeyPress; + range->device_events.first = ButtonPress; range->device_events.last = MotionNotify; // And create the XRECORD context.