Skip to content

Commit b68c477

Browse files
authored
fix: Delay archive loading in Wayland to fix dialog positioning (#385)
* fix: Delay archive loading in Wayland to fix dialog positioning Delay first archive loading by 200ms in Wayland to allow window positioning to complete before showing password dialogs. Prevents dialogs from appearing at (0,0) when opening encrypted archives. Log: fix bug Bug: https://pms.uniontech.com/bug-view-355681.html * Revert "fix(archive): tar.7z use QProcess pipeline instead of shell script" This reverts commit 4310822. * fix(compress): show tar filename during tar.7z compression Display tar filename in progress when compressing tar.7z archives, improving user experience by showing meaningful progress information. 压缩tar.7z时显示tar文件名,提升用户体验。 Log: tar.7z压缩时提示tar文件名 PMS: BUG-356753 Influence: 压缩tar.7z格式时,进度提示显示tar文件名,用户可以看到正在处理的归档文件名称
1 parent 8bfe0be commit b68c477

File tree

6 files changed

+135
-183
lines changed

6 files changed

+135
-183
lines changed

3rdparty/cli7zplugin/cli7zplugin.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,6 @@ bool Cli7zPlugin::isOpenFileFailed(const QString &line)
151151
void Cli7zPlugin::killProcess(bool emitFinished)
152152
{
153153
Q_UNUSED(emitFinished);
154-
if (killTar7zPipelineIfActive()) {
155-
return;
156-
}
157154
if (!m_process) {
158155
return;
159156
}

3rdparty/interface/archiveinterface/cliinterface.cpp

Lines changed: 55 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -470,47 +470,23 @@ PluginFinishType CliInterface::addFiles(const QList<FileEntry> &files, const Com
470470
QFileInfo(m_strArchiveName).path(),
471471
sRenameList);
472472

473-
if (options.bTar_7z) { // 压缩tar.7z:用两个 QProcess 管道,避免 shell 拼接与密码特殊字符问题
473+
if (options.bTar_7z) { // 压缩tar.7z文件
474474
m_isTar7z = true;
475-
m_filesSize = options.qTotalSize;
476-
const QString archivePath = temp_archiveName.isEmpty() ? m_strArchiveName : temp_archiveName;
477-
QStringList tarArgs = m_cliProps->getTar7zTarArgs(fileList, sRenameList);
478-
QStringList sevenZArgs = m_cliProps->getTar7z7zArgs(archivePath, password, options.bHeaderEncryption,
479-
options.iCompressionLevel, options.strCompressionMethod,
480-
options.strEncryptionMethod, options.iVolumeSize);
481-
QString tarPath = QStandardPaths::findExecutable(QStringLiteral("tar"));
482-
QString sevenZPath = QStandardPaths::findExecutable(m_cliProps->property("addProgram").toString());
483-
if (tarPath.isEmpty() || sevenZPath.isEmpty()) {
484-
ret = false;
485-
} else {
486-
m_tar7z_7z = new QProcess();
487-
m_tarProcess = new QProcess();
488-
m_tarProcess->setStandardOutputProcess(m_tar7z_7z);
489-
m_tar7z_7z->setProcessChannelMode(QProcess::MergedChannels);
490-
connect(m_tar7z_7z, &QProcess::readyReadStandardOutput, this, [this]() { readStdout(); });
491-
connect(m_tar7z_7z, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &CliInterface::processFinished);
492-
m_stdOutData.clear();
493-
m_isProcessKilled = false;
494-
m_tarProcess->start(tarPath, tarArgs);
495-
if (m_tarProcess->waitForStarted(5000)) {
496-
m_tar7z_7z->start(sevenZPath, sevenZArgs);
497-
// 不在此处 waitForStarted(7z),避免 7z 等 stdin 时阻塞主线程导致卡死
498-
ret = m_tar7z_7z->state() == QProcess::Starting || m_tar7z_7z->state() == QProcess::Running;
499-
if (ret) {
500-
m_processId = m_tar7z_7z->processId();
501-
m_childProcessId = QVector<qint64>() << m_tarProcess->processId();
502-
}
503-
connect(m_tar7z_7z, &QProcess::errorOccurred, this, [this](QProcess::ProcessError) {
504-
if (m_tar7z_7z && m_tar7z_7z->state() == QProcess::NotRunning) {
505-
processFinished(-1, QProcess::CrashExit);
506-
}
507-
});
508-
} else {
509-
ret = false;
510-
}
511-
if (!ret) {
512-
deleteProcess();
475+
m_filesSize = options.qTotalSize; // 待压缩文件总大小
476+
m_scriptPath = QDir::tempPath() + "/tempScript_" + QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()) + ".sh";
477+
QFile scriptFile(m_scriptPath);
478+
if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
479+
QTextStream out(&scriptFile);
480+
out << "#!/bin/bash\n";
481+
for (const QString &arg : arguments) {
482+
out << arg << "\n";
513483
}
484+
scriptFile.close();
485+
QProcess::execute("chmod", { "+x", m_scriptPath });
486+
ret = runProcess(m_scriptPath, QStringList());
487+
} else {
488+
qWarning() << "Failed to create temporary script file.";
489+
ret = false;
514490
}
515491
} else {
516492
QString processName = m_cliProps->property("addProgram").toString();
@@ -531,11 +507,7 @@ PluginFinishType CliInterface::addFiles(const QList<FileEntry> &files, const Com
531507
qInfo() << "mtp 压缩完成,现在开始移动";
532508
QStringList args_list;
533509
args_list << temp_archiveName << m_strArchiveName;
534-
if (m_tar7z_7z) {
535-
m_tar7z_7z->waitForFinished(-1);
536-
} else if (m_process) {
537-
m_process->waitForFinished();
538-
}
510+
m_process->waitForFinished();
539511
QProcess mover;
540512
ret = 0 == mover.execute("mv", args_list);
541513
ret = mover.exitCode() == QProcess::NormalExit;
@@ -823,53 +795,22 @@ bool CliInterface::runProcess(const QString &programName, const QStringList &arg
823795
return true;
824796
}
825797

826-
bool CliInterface::killTar7zPipelineIfActive()
827-
{
828-
if (!m_tar7z_7z) {
829-
return false;
830-
}
831-
if (m_tarProcess && m_tarProcess->state() != QProcess::NotRunning) {
832-
m_tarProcess->kill();
833-
}
834-
if (m_tar7z_7z->state() != QProcess::NotRunning) {
835-
m_tar7z_7z->kill();
836-
}
837-
m_isProcessKilled = true;
838-
return true;
839-
}
840-
841798
void CliInterface::deleteProcess()
842799
{
843-
if (m_tar7z_7z) {
844-
m_tar7z_7z->blockSignals(true);
845-
if (m_tar7z_7z->state() != QProcess::NotRunning) {
846-
m_tar7z_7z->kill();
847-
m_tar7z_7z->waitForFinished(500);
848-
}
849-
delete m_tar7z_7z;
850-
m_tar7z_7z = nullptr;
851-
if (m_tarProcess) {
852-
m_tarProcess->blockSignals(true);
853-
if (m_tarProcess->state() != QProcess::NotRunning) {
854-
m_tarProcess->kill();
855-
m_tarProcess->waitForFinished(500);
856-
}
857-
delete m_tarProcess;
858-
m_tarProcess = nullptr;
859-
}
860-
return;
861-
}
862800
if (m_process) {
863801
readStdout(true);
864802
m_process->blockSignals(true); // delete m_process之前需要断开所有m_process信号,防止重复处理
865803
delete m_process;
866804
m_process = nullptr;
805+
if(!m_scriptPath.isEmpty()) {
806+
QFile::remove(m_scriptPath);
807+
}
867808
}
868809
}
869810

870811
void CliInterface::handleProgress(const QString &line)
871812
{
872-
if (m_tar7z_7z || (m_process && m_process->program().at(0).contains("7z"))) { // 解析7z相关进度、文件名(含 tar.7z 管道)
813+
if (m_process && m_process->program().at(0).contains("7z")) { // 解析7z相关进度、文件名
873814
int pos = line.indexOf(QLatin1Char('%'));
874815
if (pos > 1) {
875816
int percentage = line.midRef(pos - 3, 3).toInt();
@@ -963,6 +904,29 @@ void CliInterface::handleProgress(const QString &line)
963904

964905
emit signalCurFileName(fileName);
965906
}
907+
} else if (m_process && m_process->program().at(0).contains("tempScript")) {
908+
// 处理tar.7z进度
909+
// "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b 7M + [Content]"
910+
// "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b274M 1 + [Content]"
911+
int pos = line.lastIndexOf(" + [Content]");
912+
if (pos > 1) {
913+
int mPos = line.lastIndexOf("M ");
914+
int bPos = line.lastIndexOf("\b", mPos);
915+
QString tempLine = line.left(mPos);
916+
// 已经压缩的文件大小
917+
qint64 compressedSize = tempLine.right(tempLine.size() - bPos - 1).toLongLong();
918+
// 计算文件大小计算百分比
919+
qint64 percentage = compressedSize * 1024 * 1024 * 100 / m_filesSize;
920+
921+
emit signalprogress(percentage);
922+
// tar.7z 无法获取正在压缩的单个文件名,但可以提示正在打包成 tar 文件
923+
// 发送 tar 文件名提示(去掉 .7z 后缀,显示正在打包的 tar 文件名)
924+
QString tarFileName = QFileInfo(m_strArchiveName).fileName();
925+
if (tarFileName.endsWith(".7z", Qt::CaseInsensitive)) {
926+
tarFileName = tarFileName.left(tarFileName.length() - 3);
927+
}
928+
emit signalCurFileName(tarFileName);
929+
}
966930
}
967931
}
968932

@@ -1072,14 +1036,9 @@ PluginFinishType CliInterface::handleCorrupt()
10721036

10731037
void CliInterface::writeToProcess(const QByteArray &data)
10741038
{
1039+
Q_ASSERT(m_process);
10751040
Q_ASSERT(!data.isNull());
1076-
// tar.7z 管道下 stdin 为 tar 输出,不能写入,密码已通过命令行传入
1077-
if (m_tar7z_7z) {
1078-
return;
1079-
}
1080-
if (!m_process) {
1081-
return;
1082-
}
1041+
10831042
// m_process->write(data);
10841043
m_process->pty()->write(data);
10851044
}
@@ -1336,17 +1295,14 @@ void CliInterface::readStdout(bool handleAll)
13361295
return;
13371296
}
13381297

1339-
QProcess *outProcess = m_tar7z_7z ? m_tar7z_7z : m_process;
1340-
if (!outProcess) {
1341-
return;
1342-
}
1298+
Q_ASSERT(m_process);
13431299

1344-
if (!outProcess->bytesAvailable()) { // 无数据
1300+
if (!m_process->bytesAvailable()) { // 无数据
13451301
return;
13461302
}
13471303

13481304
// 获取命令行输出
1349-
QByteArray dd = outProcess->readAllStandardOutput();
1305+
QByteArray dd = m_process->readAllStandardOutput();
13501306
m_stdOutData += dd;
13511307

13521308
// 换行分割
@@ -1358,10 +1314,12 @@ void CliInterface::readStdout(bool handleAll)
13581314
// }
13591315
bool isWrongPwd = isWrongPasswordMsg(lines.last());
13601316

1361-
// 7z 或 tar.7z 管道:进度行结束无 \n
1362-
bool is7zAdd = m_tar7z_7z || (m_process && m_process->program().at(0).contains("7z") && m_process->program().at(1) != "l");
1363-
if (is7zAdd && !isWrongPwd) {
1364-
handleAll = true;
1317+
if ((m_process->program().at(0).contains("7z") && m_process->program().at(1) != "l") && !isWrongPwd) {
1318+
handleAll = true; // 7z进度行结束无\n
1319+
}
1320+
1321+
if ((m_process->program().at(0).contains("tempScript")) && !isWrongPwd) {
1322+
handleAll = true; // compress .tar.7z progressline has no \n
13651323
}
13661324

13671325
bool foundErrorMessage = (isWrongPwd || isDiskFullMsg(QLatin1String(lines.last()))
@@ -1378,7 +1336,7 @@ void CliInterface::readStdout(bool handleAll)
13781336
// because the last line might be incomplete we leave it for now
13791337
// note, this last line may be an empty string if the stdoutdata ends
13801338
// with a newline
1381-
if (m_process && m_process->program().at(0).contains("unrar")) { // 针对unrar的命令行截取
1339+
if (m_process->program().at(0).contains("unrar")) { // 针对unrar的命令行截取
13821340
m_stdOutData.clear();
13831341
if (lines.count() > 0) {
13841342
if (!(lines[lines.count() - 1].endsWith("%") || lines[lines.count() - 1].endsWith("OK "))) {

3rdparty/interface/archiveinterface/cliinterface.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,6 @@ class CliInterface : public ReadWriteArchiveInterface
143143
*/
144144
virtual void killProcess(bool emitFinished = true) = 0;
145145

146-
/**
147-
* @brief killTar7zPipelineIfActive 若当前为 tar.7z 管道则结束两个进程
148-
* @return 若已结束管道返回 true,否则 false
149-
*/
150-
bool killTar7zPipelineIfActive();
151-
152146
/**
153147
* @brief handleProgress 解析进度并发送进度信号
154148
* @param line
@@ -242,8 +236,6 @@ private slots:
242236
protected:
243237
CliProperties *m_cliProps = nullptr; // 命令属性
244238
/*KProcess*/KPtyProcess *m_process = nullptr; // 工作进程
245-
QProcess *m_tarProcess = nullptr; // 仅 tar.7z 管道:tar 进程
246-
QProcess *m_tar7z_7z = nullptr; // 仅 tar.7z 管道:7z 进程(输出来自此进程)
247239
PluginFinishType m_finishType = PFT_Nomral; // 插件结束类型
248240
QString m_strEncryptedFileName = QString(); // 当前被解压的加密文件名
249241
QVector<qint64> m_childProcessId; // 压缩tar.7z文件的子进程Id
@@ -270,6 +262,7 @@ private slots:
270262
QMap<QString, int> m_mapLongName; // 长文件名统计
271263
QMap<QString, int> m_mapLongDirName; // 长文件夹统计
272264
QMap<QString, int> m_mapRealDirValue; // 真实文件统计
265+
QString m_scriptPath; // 脚本路径
273266
};
274267

275268
#endif // CLIINTERFACE_H

0 commit comments

Comments
 (0)