fix: 修复 Deepin 系统上显示“开发者模式未开启”的问题

没有区分 Deepin 和 UOS,在 Deepin 上对开发者模式状态文件进行判断,可能造成错误

Log: 添加判断区分 Deepin 和 UOS,仅在 UOS 判断开发者模式状态文件;优化 main 函数长度,将环境变量设置和 config.ini 读写放入 Utils 独立静态函数中调用;修复从托盘打开主界面时透明度动画不流畅的问题;优化关闭窗口动画代码,与打开窗口动画代码合并;修复主窗口关闭时,从托盘打开关于对话框后,调起主窗口会遮挡关于对话框的问题
This commit is contained in:
zty199
2023-02-05 22:20:19 +08:00
parent de2db98324
commit ab6c3d37d2
9 changed files with 228 additions and 106 deletions

View File

@@ -1,9 +1,23 @@
#include "utils.h"
#include "application.h"
#include <QDBusInterface>
#include <DSysInfo>
// Author: chatGPT
#include <QDBusInterface>
#include <QProcessEnvironment>
#include <QSettings>
#include <QStandardPaths>
#include <QFile>
#define UOSDeveloperModeFile "/var/lib/deepin/developer-mode/enabled"
/**
* @author chatGPT
* @brief Utils::sendNotification 发送系统通知
* @param icon 图标名称
* @param title 通知标题
* @param body 通知内容
*/
void Utils::sendNotification(const QString &icon, const QString &title, const QString &body)
{
QDBusInterface interface("org.freedesktop.Notifications",
@@ -22,3 +36,149 @@ void Utils::sendNotification(const QString &icon, const QString &title, const QS
interface.callWithArgumentList(QDBus::AutoDetect, "Notify", args);
}
/**
* @brief Utils::isDDE 判断是否使用 DDE 桌面环境
* @return
*/
bool Utils::isDDE()
{
bool isDDE = true;
if (!QString::fromUtf8(qgetenv("XDG_CURRENT_DESKTOP")).toLower().startsWith("deepin"))
{
qputenv("XDG_CURRENT_DESKTOP", "Deepin");
isDDE = false;
}
return isDDE;
}
/**
* @brief Utils::isWayland 判断是否使用 wayland 显示协议
* @return bool true: 使用 wayland 显示协议 false: 使用 x11 显示协议
*/
bool Utils::isWayland()
{
bool isWayland = false;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString XDG_SESSION_TYPE = env.value(QStringLiteral("XDG_SESSION_TYPE"));
QString WAYLAND_DISPLAY = env.value(QStringLiteral("WAYLAND_DISPLAY"));
if (XDG_SESSION_TYPE == QLatin1String("wayland") || WAYLAND_DISPLAY.contains(QLatin1String("wayland"), Qt::CaseInsensitive))
{
isWayland = true;
}
return isWayland;
}
/**
* @brief Utils::initConfig 初始化 config.ini 配置文件,去除废弃字段
*/
void Utils::initConfig()
{
// WARNING: 请在 组织名称 和 应用程序名称 初始化完成后调用
bool useWayland = true;
QSettings config(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/config.ini", QSettings::IniFormat);
if (config.contains("build/useWayland"))
{
useWayland = config.value("build/useWayland").toBool();
}
config.remove("build/isDeepinOS");
config.remove("build/isWayland");
config.remove("build/useWayland");
config.setValue("runtime/isDDE", isDDE());
config.setValue("runtime/isWayland", isWayland());
// Check config file, if there is no wayland config, then set it to default, which means use wayland if possible.
if (!config.contains("runtime/useWayland"))
{
config.setValue("runtime/useWayland", useWayland);
}
config.sync(); // 写入更改至 config.ini并同步最新内容
checkUOSDeveloperMode(); // Check UOS developer mode
}
/**
* @brief Utils::isUOS 判断是否为 UOS 操作系统
* @return bool true: UOS 操作系统 false: 非 UOS 操作系统
*/
bool Utils::isUOS()
{
// WARNING: 请在 组织名称 和 应用程序名称 初始化完成后调用
bool isUOS = false;
QSettings config(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/config.ini", QSettings::IniFormat);
if (Dtk::Core::DSysInfo::productType() == Dtk::Core::DSysInfo::Uos)
{
isUOS = true;
config.setValue("UOS/isUOS", true);
}
else
{
isUOS = false;
config.remove("UOS");
}
config.sync(); // 写入更改至 config.ini并同步最新内容
return isUOS;
}
/**
* @brief Utils::setQPAPlatform Set display backend
*/
void Utils::setQPAPlatform()
{
// WARNING: 请在 initConfig() 执行后调用
bool isDDE = Utils::isDDE(); // WARNING: 只能执行一次,后续执行时环境变量已经被覆盖,导致判断错误
bool isWayland = Utils::isWayland();
QSettings config(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/config.ini", QSettings::IniFormat);
bool useWayland = config.value("runtime/useWayland").toBool();
qDebug() << "System Wayland enabled:" << isWayland << "Spark Wayland enabled:" << useWayland;
if (isWayland && useWayland && !(Dtk::Core::DSysInfo::isDeepin() || isDDE))
{
qputenv("QT_QPA_PLATFORM", "wayland");
}
else if (isWayland && useWayland && (Dtk::Core::DSysInfo::isDeepin() && isDDE))
{
qputenv("QT_QPA_PLATFORM", "dwayland");
}
else
{
qputenv("QT_QPA_PLATFORM", "dxcb");
}
}
/**
* @brief Utils::checkUOSDeveloperMode Check UOS developer mode
*/
void Utils::checkUOSDeveloperMode()
{
QSettings config(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/config.ini", QSettings::IniFormat);
QFile file(UOSDeveloperModeFile);
if (Utils::isUOS() && file.exists() && file.open(QFile::ReadOnly | QFile::Text))
{
QString lineData = QString::fromUtf8(file.readLine());
bool devmode = lineData.trimmed().toInt();
qDebug() << "UOS Developer Mode Status:" << devmode;
config.setValue("UOS/EnableDeveloperMode", devmode);
}
else
{
/**
* NOTE: Utils::isUOS() 中,判断为非 UOS 时已经从 config 中删除 UOS 组,
* 此处若包含该字段则一定是 UOS直接写入开发者模式开关状态即可
*/
if (config.contains("UOS/EnableDeveloperMode"))
{
config.setValue("UOS/EnableDeveloperMode", false);
}
}
file.close();
config.sync(); // 写入更改至 config.ini并同步最新内容
}

View File

@@ -7,6 +7,12 @@ class Utils
{
public:
static void sendNotification(const QString &icon, const QString &title, const QString &body);
static bool isDDE();
static bool isWayland();
static void initConfig();
static bool isUOS();
static void setQPAPlatform();
static void checkUOSDeveloperMode();
};
#endif // UTILS_H

View File

@@ -1,8 +1,5 @@
#include "widgetanimation.h"
WidgetAnimation::WidgetAnimation()
{
}
#include "widgets/base/basewidgetopacity.h"
void WidgetAnimation::widgetShake(QWidget *pWidget, int nRange)
{
@@ -28,27 +25,35 @@ void WidgetAnimation::widgetShake(QWidget *pWidget, int nRange)
QPropertyAnimation *WidgetAnimation::createWidgetOpacity(QWidget *pWidget, bool isAppear)
{
QPropertyAnimation *animation = new QPropertyAnimation(pWidget, "windowOpacity", pWidget);
// 设置动画效果
animation->setEasingCurve(QEasingCurve::Linear);
// 设置动画时间(单位:毫秒)
animation->setDuration(500);
// 设置动画步长值,以及在该位置时显示的透明度
if (isAppear)
{
animation->setKeyValueAt(0, 0);
// m_animation->setKeyValueAt(0.5, 0);
animation->setKeyValueAt(1, 1);
// 设置动画效果
animation->setEasingCurve(QEasingCurve::Linear);
// 设置动画步长值,以及在该位置时显示的透明度(即动画关键帧)
animation->setKeyValueAt(0.0, 0.0);
animation->setKeyValueAt(1.0, 1.0);
}
else
{
animation->setKeyValueAt(0, 1);
animation->setKeyValueAt(1, 0);
animation->setEasingCurve(QEasingCurve::OutQuart);
animation->setKeyValueAt(0.0, 1.0);
animation->setKeyValueAt(1.0, 0.0);
QObject::connect(animation, &QPropertyAnimation::finished, pWidget, [=]() { pWidget->close(); });
}
QObject::connect(animation, &QPropertyAnimation::valueChanged, pWidget, [=]()
{
pWidget->update(); // NOTE: 保证窗口透明度动画平滑
});
return animation;
}
void WidgetAnimation::widgetOpacity(QWidget *pWidget, bool isAppear)
{
// 开始动画
createWidgetOpacity(pWidget, isAppear)->start();
// 启动/关闭动画
createWidgetOpacity(pWidget, isAppear)->start(QPropertyAnimation::DeleteWhenStopped);
}

View File

@@ -1,14 +1,12 @@
#ifndef WIDGETANIMATION_H
#define WIDGETANIMATION_H
#include <QObject>
#include <QWidget>
#include <QPropertyAnimation>
class WidgetAnimation
{
public:
WidgetAnimation();
static void widgetShake(QWidget *pWidget, int nRange);
static QPropertyAnimation* createWidgetOpacity(QWidget *pWidget, bool isAppear);