Add methods to detect appimage, static binary and forced gtk dialog

This commit is contained in:
Ilya Fedin 2020-04-25 09:45:46 +04:00 committed by John Preston
parent 422831fa79
commit 7f890122e6
2 changed files with 108 additions and 38 deletions

View File

@ -194,30 +194,31 @@ bool GenerateDesktopFile(
QFile target(targetFile);
if (target.open(QIODevice::WriteOnly)) {
#ifdef DESKTOP_APP_USE_PACKAGED
fileText = fileText.replace(
QRegularExpression(
qsl("^Exec=(.*) -- %u$"),
QRegularExpression::MultilineOption),
qsl("Exec=\\1")
+ (args.isEmpty() ? QString() : ' ' + args));
#else // DESKTOP_APP_USE_PACKAGED
fileText = fileText.replace(
QRegularExpression(
qsl("^TryExec=.*$"),
QRegularExpression::MultilineOption),
qsl("TryExec=")
+ QFile::encodeName(cExeDir() + cExeName())
.replace('\\', qsl("\\\\")));
fileText = fileText.replace(
QRegularExpression(
qsl("^Exec=.*$"),
QRegularExpression::MultilineOption),
qsl("Exec=")
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName()))
.replace('\\', qsl("\\\\"))
+ (args.isEmpty() ? QString() : ' ' + args));
#endif // !DESKTOP_APP_USE_PACKAGED
if (IsStaticBinary() || InAppImage()) {
fileText = fileText.replace(
QRegularExpression(
qsl("^TryExec=.*$"),
QRegularExpression::MultilineOption),
qsl("TryExec=")
+ QFile::encodeName(cExeDir() + cExeName())
.replace('\\', qsl("\\\\")));
fileText = fileText.replace(
QRegularExpression(
qsl("^Exec=.*$"),
QRegularExpression::MultilineOption),
qsl("Exec=")
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName()))
.replace('\\', qsl("\\\\"))
+ (args.isEmpty() ? QString() : ' ' + args));
} else {
fileText = fileText.replace(
QRegularExpression(
qsl("^Exec=(.*) -- %u$"),
QRegularExpression::MultilineOption),
qsl("Exec=\\1")
+ (args.isEmpty() ? QString() : ' ' + args));
}
target.write(fileText.toUtf8());
target.close();
@ -249,6 +250,27 @@ bool InSnap() {
return Snap;
}
bool InAppImage() {
static const auto AppImage = qEnvironmentVariableIsSet("APPIMAGE");
return AppImage;
}
bool IsStaticBinary() {
#ifdef DESKTOP_APP_USE_PACKAGED
return false;
#else // DESKTOP_APP_USE_PACKAGED
return true;
#endif // !DESKTOP_APP_USE_PACKAGED
}
bool IsGtkFileDialogForced() {
#ifdef TDESKTOP_FORCE_GTK_FILE_DIALOG
return true;
#else // TDESKTOP_FORCE_GTK_FILE_DIALOG
return false;
#endif // !TDESKTOP_FORCE_GTK_FILE_DIALOG
}
bool IsXDGDesktopPortalPresent() {
#ifdef TDESKTOP_DISABLE_DBUS_INTEGRATION
static const auto XDGDesktopPortalPresent = false;
@ -266,7 +288,11 @@ bool UseXDGDesktopPortal() {
const auto envVar = qEnvironmentVariableIsSet("TDESKTOP_USE_PORTAL");
const auto portalPresent = IsXDGDesktopPortalPresent();
return (DesktopEnvironment::IsKDE() || envVar) && portalPresent;
return (
DesktopEnvironment::IsKDE()
|| InSnap()
|| envVar
) && portalPresent;
}();
return UsePortal;
@ -288,7 +314,7 @@ QString ProcessNameByPID(const QString &pid) {
return QString();
}
QString CurrentExecutablePath(int argc, char *argv[]) {
QString RealExecutablePath(int argc, char *argv[]) {
const auto processName = ProcessNameByPID(qsl("self"));
// Fallback to the first command line argument.
@ -299,6 +325,25 @@ QString CurrentExecutablePath(int argc, char *argv[]) {
: QString();
}
QString CurrentExecutablePath(int argc, char *argv[]) {
if (InAppImage()) {
const auto appimagePath = QString::fromUtf8(qgetenv("APPIMAGE"));
const auto appimagePathList = appimagePath.split('/');
if (qEnvironmentVariableIsSet("ARGV0")
&& appimagePathList.size() >= 5
&& appimagePathList[1] == qstr("run")
&& appimagePathList[2] == qstr("user")
&& appimagePathList[4] == qstr("appimagelauncherfs")) {
return QString::fromUtf8(qgetenv("ARGV0"));
}
return appimagePath;
}
return RealExecutablePath(argc, argv);
}
QString AppRuntimeDirectory() {
static const auto RuntimeDirectory = [&] {
auto runtimeDir = QStandardPaths::writableLocation(
@ -356,6 +401,20 @@ QString GetLauncherBasename() {
.arg(cExeName());
}
if (InAppImage()) {
const auto appimagePath = qsl("file://%1%2")
.arg(cExeDir())
.arg(cExeName())
.toUtf8();
char md5Hash[33] = { 0 };
hashMd5Hex(appimagePath.constData(), appimagePath.size(), md5Hash);
return qsl("appimagekit_%1-%2")
.arg(md5Hash)
.arg(AppName.utf16().replace(' ', '_'));
}
const auto possibleBasenames = std::vector<QString>{
qsl(MACRO_TO_STRING(TDESKTOP_LAUNCHER_BASENAME)),
qsl("Telegram")
@ -564,6 +623,10 @@ namespace Platform {
void start() {
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
if (InAppImage()) {
qputenv("LIBGL_ALWAYS_INDIRECT", "1");
}
#ifdef TDESKTOP_USE_FONTCONFIG_FALLBACK
FallbackFontConfig();
#endif // TDESKTOP_USE_FONTCONFIG_FALLBACK
@ -571,21 +634,24 @@ void start() {
qputenv("PULSE_PROP_application.name", AppName.utf8());
qputenv("PULSE_PROP_application.icon_name", GetIconName().toLatin1());
#ifdef TDESKTOP_FORCE_GTK_FILE_DIALOG
LOG(("Checking for XDG Desktop Portal..."));
// this can give us a chance to use a proper file dialog for current session
if (IsXDGDesktopPortalPresent()) {
LOG(("XDG Desktop Portal is present!"));
if (UseXDGDesktopPortal()) {
LOG(("Usage of XDG Desktop Portal is enabled."));
qputenv("QT_QPA_PLATFORMTHEME", "xdgdesktopportal");
if(IsStaticBinary()
|| InAppImage()
|| InSnap()
|| IsGtkFileDialogForced()) {
LOG(("Checking for XDG Desktop Portal..."));
// this can give us a chance to use a proper file dialog for current session
if (IsXDGDesktopPortalPresent()) {
LOG(("XDG Desktop Portal is present!"));
if (UseXDGDesktopPortal()) {
LOG(("Usage of XDG Desktop Portal is enabled."));
qputenv("QT_QPA_PLATFORMTHEME", "xdgdesktopportal");
} else {
LOG(("Usage of XDG Desktop Portal is disabled."));
}
} else {
LOG(("Usage of XDG Desktop Portal is disabled."));
LOG(("XDG Desktop Portal is not present :("));
}
} else {
LOG(("XDG Desktop Portal is not present :("));
}
#endif // TDESKTOP_FORCE_GTK_FILE_DIALOG
}
void finish() {

View File

@ -22,11 +22,15 @@ inline void SetWatchingMediaKeys(bool watching) {
bool InSandbox();
bool InSnap();
bool InAppImage();
bool IsStaticBinary();
bool IsGtkFileDialogForced();
bool IsXDGDesktopPortalPresent();
bool UseXDGDesktopPortal();
QString ProcessNameByPID(const QString &pid);
QString RealExecutablePath(int argc, char *argv[]);
QString CurrentExecutablePath(int argc, char *argv[]);
QString AppRuntimeDirectory();