feat: GPU切换回退保护逻辑
- switchGpu切换前写入备份文件(.gpu-switch-backup)记录之前模式 - init()检测未确认的切换,启动30秒自动回退计时器 - QML弹出'显示是否正常'确认覆盖层,支持手动确认/回退/超时自动回退 - confirmSwitchSuccess()用户确认正常后删除备份 - restoreFromBackup()自动恢复之前模式并发送通知 - primeOffloadEnabled属性检测当前PRIME offload状态 - switchGpu改用environment.d方式,不需要root/pkexec - 翻译更新:回退确认相关8条新增
This commit is contained in:
+158
-4
@@ -28,6 +28,9 @@ GraphicsDriverApplet::GraphicsDriverApplet(QObject *parent)
|
||||
, m_ready(false)
|
||||
, m_lastAlertTime(0)
|
||||
, m_tempAlertEnabled(true)
|
||||
, m_switchPending(false)
|
||||
, m_restoreCountdown(0)
|
||||
, m_restoreTimer(nullptr)
|
||||
{
|
||||
QSettings settings("deepin", "graphics-driver-applet");
|
||||
m_tempAlertEnabled = settings.value("tempAlertEnabled", true).toBool();
|
||||
@@ -45,6 +48,29 @@ bool GraphicsDriverApplet::load()
|
||||
bool GraphicsDriverApplet::init()
|
||||
{
|
||||
detectGpus();
|
||||
|
||||
// 检查是否有未确认的 GPU 切换(上次切换后可能黑屏)
|
||||
QFile backup(backupFilePath());
|
||||
if (backup.exists()) {
|
||||
// 有备份文件,说明上次切换未确认,启动 30 秒回退计时器
|
||||
m_switchPending = true;
|
||||
m_restoreCountdown = 30;
|
||||
emit switchPendingChanged();
|
||||
emit restoreCountdownChanged();
|
||||
|
||||
m_restoreTimer = new QTimer(this);
|
||||
connect(m_restoreTimer, &QTimer::timeout, this, [this]() {
|
||||
m_restoreCountdown--;
|
||||
emit restoreCountdownChanged();
|
||||
if (m_restoreCountdown <= 0) {
|
||||
restoreFromBackup();
|
||||
}
|
||||
});
|
||||
m_restoreTimer->start(1000);
|
||||
|
||||
qDebug() << "Unconfirmed GPU switch detected, auto-restore in 30s";
|
||||
}
|
||||
|
||||
return DApplet::init();
|
||||
}
|
||||
|
||||
@@ -115,6 +141,35 @@ void GraphicsDriverApplet::setTempAlertEnabled(bool enabled)
|
||||
emit tempAlertEnabledChanged();
|
||||
}
|
||||
|
||||
bool GraphicsDriverApplet::primeOffloadEnabled() const
|
||||
{
|
||||
QString configPath = QDir::homePath() + "/.config/environment.d/nvidia-prime.conf";
|
||||
QFile file(configPath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false;
|
||||
QString content = QTextStream(&file).readAll();
|
||||
return content.contains("__NV_PRIME_RENDER_OFFLOAD=1");
|
||||
}
|
||||
|
||||
bool GraphicsDriverApplet::switchPending() const
|
||||
{
|
||||
return m_switchPending;
|
||||
}
|
||||
|
||||
int GraphicsDriverApplet::restoreCountdown() const
|
||||
{
|
||||
return m_restoreCountdown;
|
||||
}
|
||||
|
||||
QString GraphicsDriverApplet::primeConfigPath()
|
||||
{
|
||||
return QDir::homePath() + "/.config/environment.d/nvidia-prime.conf";
|
||||
}
|
||||
|
||||
QString GraphicsDriverApplet::backupFilePath()
|
||||
{
|
||||
return QDir::homePath() + "/.config/environment.d/.gpu-switch-backup";
|
||||
}
|
||||
|
||||
void GraphicsDriverApplet::refreshDeviceInfo()
|
||||
{
|
||||
detectGpus();
|
||||
@@ -649,10 +704,109 @@ void GraphicsDriverApplet::readGpuProcesses()
|
||||
bool GraphicsDriverApplet::switchGpu(const QString &mode)
|
||||
{
|
||||
// mode: "nvidia" / "intel" / "on-demand"
|
||||
QProcess process;
|
||||
process.start("pkexec", {"prime-select", "set", mode});
|
||||
process.waitForFinished(30000);
|
||||
return process.exitCode() == 0;
|
||||
QString configPath = primeConfigPath();
|
||||
QString backupPath = backupFilePath();
|
||||
QString configDir = QDir::homePath() + "/.config/environment.d";
|
||||
QDir().mkpath(configDir);
|
||||
|
||||
// 保存当前模式到备份文件(用于回退)
|
||||
QString prevMode = primeOffloadEnabled() ? "nvidia" : "on-demand";
|
||||
QFile backupFile(backupPath);
|
||||
if (backupFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream(&backupFile) << prevMode;
|
||||
backupFile.close();
|
||||
}
|
||||
|
||||
if (mode == "intel") {
|
||||
QFile::remove(configPath);
|
||||
} else if (mode == "nvidia") {
|
||||
QFile file(configPath);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream(&file) << "__NV_PRIME_RENDER_OFFLOAD=1\n"
|
||||
<< "__GLX_VENDOR_LIBRARY_NAME=nvidia\n";
|
||||
file.close();
|
||||
}
|
||||
} else if (mode == "on-demand") {
|
||||
QFile::remove(configPath);
|
||||
}
|
||||
|
||||
sendNotification(tr("GPU Mode Switched"),
|
||||
tr("Switched to %1 mode. Please re-login to take effect.").arg(mode));
|
||||
|
||||
detectGpuMode();
|
||||
emit primeOffloadEnabledChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphicsDriverApplet::confirmSwitchSuccess()
|
||||
{
|
||||
// 用户确认显示正常,删除备份文件
|
||||
QFile::remove(backupFilePath());
|
||||
|
||||
m_switchPending = false;
|
||||
m_restoreCountdown = 0;
|
||||
emit switchPendingChanged();
|
||||
emit restoreCountdownChanged();
|
||||
|
||||
if (m_restoreTimer) {
|
||||
m_restoreTimer->stop();
|
||||
m_restoreTimer->deleteLater();
|
||||
m_restoreTimer = nullptr;
|
||||
}
|
||||
|
||||
qDebug() << "GPU switch confirmed by user";
|
||||
}
|
||||
|
||||
void GraphicsDriverApplet::restoreSwitch()
|
||||
{
|
||||
// 用户手动请求回退
|
||||
restoreFromBackup();
|
||||
}
|
||||
|
||||
void GraphicsDriverApplet::restoreFromBackup()
|
||||
{
|
||||
// 从备份文件恢复
|
||||
QFile backupFile(backupFilePath());
|
||||
if (!backupFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
m_switchPending = false;
|
||||
emit switchPendingChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
QString prevMode = QTextStream(&backupFile).readAll().trimmed();
|
||||
backupFile.close();
|
||||
QFile::remove(backupFilePath());
|
||||
|
||||
QString configPath = primeConfigPath();
|
||||
|
||||
if (prevMode == "nvidia") {
|
||||
QFile file(configPath);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream(&file) << "__NV_PRIME_RENDER_OFFLOAD=1\n"
|
||||
<< "__GLX_VENDOR_LIBRARY_NAME=nvidia\n";
|
||||
file.close();
|
||||
}
|
||||
} else {
|
||||
QFile::remove(configPath);
|
||||
}
|
||||
|
||||
m_switchPending = false;
|
||||
m_restoreCountdown = 0;
|
||||
emit switchPendingChanged();
|
||||
emit restoreCountdownChanged();
|
||||
emit primeOffloadEnabledChanged();
|
||||
|
||||
if (m_restoreTimer) {
|
||||
m_restoreTimer->stop();
|
||||
m_restoreTimer->deleteLater();
|
||||
m_restoreTimer = nullptr;
|
||||
}
|
||||
|
||||
sendNotification(tr("GPU Mode Restored"),
|
||||
tr("Reverted to %1 mode. Please re-login to take effect.").arg(prevMode));
|
||||
|
||||
qDebug() << "GPU mode restored to" << prevMode;
|
||||
}
|
||||
|
||||
D_APPLET_CLASS(GraphicsDriverApplet)
|
||||
|
||||
Reference in New Issue
Block a user