|
|
@@ -24,6 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
|
#include <QtCore/QProcess>
|
|
|
|
#include <QtCore/QProcess>
|
|
|
|
#include <QtCore/QVersionNumber>
|
|
|
|
#include <QtCore/QVersionNumber>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
|
|
|
|
|
|
|
#include <QtDBus/QDBusInterface>
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstdlib>
|
|
|
@@ -38,6 +42,27 @@ using Platform::File::internal::EscapeShell;
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constexpr auto kDesktopFile = str_const(":/misc/telegramdesktop.desktop");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
|
|
|
|
|
|
|
void SandboxAutostart(bool autostart) {
|
|
|
|
|
|
|
|
QVariantMap options;
|
|
|
|
|
|
|
|
options["reason"] = tr::lng_settings_auto_start(tr::now);
|
|
|
|
|
|
|
|
options["autostart"] = autostart;
|
|
|
|
|
|
|
|
options["commandline"] = QStringList({
|
|
|
|
|
|
|
|
cExeName(),
|
|
|
|
|
|
|
|
qsl("-autostart")
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
options["dbus-activatable"] = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QDBusInterface(
|
|
|
|
|
|
|
|
qsl("org.freedesktop.portal.Desktop"),
|
|
|
|
|
|
|
|
qsl("/org/freedesktop/portal/desktop"),
|
|
|
|
|
|
|
|
qsl("/org/freedesktop/portal/desktop")
|
|
|
|
|
|
|
|
).call(qsl("RequestBackground"), QString(), options);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
bool RunShellCommand(const QByteArray &command) {
|
|
|
|
bool RunShellCommand(const QByteArray &command) {
|
|
|
|
auto result = system(command.constData());
|
|
|
|
auto result = system(command.constData());
|
|
|
|
if (result) {
|
|
|
|
if (result) {
|
|
|
@@ -87,6 +112,61 @@ void FallbackFontConfig() {
|
|
|
|
#endif // !DESKTOP_APP_USE_PACKAGED
|
|
|
|
#endif // !DESKTOP_APP_USE_PACKAGED
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
|
|
|
|
|
|
|
|
DEBUG_LOG(("App Info: placing .desktop file to %1").arg(targetPath));
|
|
|
|
|
|
|
|
if (!QDir(targetPath).exists()) QDir().mkpath(targetPath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const auto targetFile = targetPath
|
|
|
|
|
|
|
|
+ qsl(MACRO_TO_STRING(TDESKTOP_LAUNCHER_BASENAME) ".desktop");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString fileText;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QFile source(str_const_toString(kDesktopFile));
|
|
|
|
|
|
|
|
if (source.open(QIODevice::ReadOnly)) {
|
|
|
|
|
|
|
|
QTextStream s(&source);
|
|
|
|
|
|
|
|
fileText = s.readAll();
|
|
|
|
|
|
|
|
source.close();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
LOG(("App Error: Could not open '%1' for read")
|
|
|
|
|
|
|
|
.arg(str_const_toString(kDesktopFile)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
fileText = fileText.replace(
|
|
|
|
|
|
|
|
QRegularExpression(qsl("^TryExec=.*$"),
|
|
|
|
|
|
|
|
QRegularExpression::MultilineOption),
|
|
|
|
|
|
|
|
qsl("TryExec=")
|
|
|
|
|
|
|
|
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName())));
|
|
|
|
|
|
|
|
fileText = fileText.replace(
|
|
|
|
|
|
|
|
QRegularExpression(qsl("^Exec=.*$"),
|
|
|
|
|
|
|
|
QRegularExpression::MultilineOption),
|
|
|
|
|
|
|
|
qsl("Exec=")
|
|
|
|
|
|
|
|
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName()))
|
|
|
|
|
|
|
|
+ (args.isEmpty() ? QString() : ' ' + args));
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
target.write(fileText.toUtf8());
|
|
|
|
|
|
|
|
target.close();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_LOG(("App Info: removing old .desktop file"));
|
|
|
|
|
|
|
|
QFile(qsl("%1telegram.desktop").arg(targetPath)).remove();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
LOG(("App Error: Could not open '%1' for write").arg(targetFile));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
|
|
namespace Platform {
|
|
|
|
namespace Platform {
|
|
|
@@ -98,7 +178,7 @@ void SetApplicationIcon(const QIcon &icon) {
|
|
|
|
bool InSandbox() {
|
|
|
|
bool InSandbox() {
|
|
|
|
static const auto Sandbox = QFileInfo::exists(
|
|
|
|
static const auto Sandbox = QFileInfo::exists(
|
|
|
|
QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation)
|
|
|
|
QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation)
|
|
|
|
+ qsl("/flatpak-info"));
|
|
|
|
+ qsl("/flatpak-info"));
|
|
|
|
return Sandbox;
|
|
|
|
return Sandbox;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -258,104 +338,45 @@ void finish() {
|
|
|
|
void RegisterCustomScheme() {
|
|
|
|
void RegisterCustomScheme() {
|
|
|
|
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
|
|
|
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
|
|
|
auto home = getHomeDir();
|
|
|
|
auto home = getHomeDir();
|
|
|
|
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty()) return; // don't update desktop file for alpha version
|
|
|
|
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty())
|
|
|
|
|
|
|
|
return; // don't update desktop file for alpha version
|
|
|
|
if (Core::UpdaterDisabled())
|
|
|
|
if (Core::UpdaterDisabled())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const auto applicationsPath = QStandardPaths::writableLocation(
|
|
|
|
|
|
|
|
QStandardPaths::ApplicationsLocation) + '/';
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
|
|
|
#ifndef TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
|
|
|
DEBUG_LOG(("App Info: placing .desktop file"));
|
|
|
|
GenerateDesktopFile(applicationsPath, qsl("-- %u"));
|
|
|
|
if (QDir(home + qsl(".local/")).exists()) {
|
|
|
|
|
|
|
|
QString apps = home + qsl(".local/share/applications/");
|
|
|
|
|
|
|
|
QString icons = home + qsl(".local/share/icons/");
|
|
|
|
|
|
|
|
if (!QDir(apps).exists()) QDir().mkpath(apps);
|
|
|
|
|
|
|
|
if (!QDir(icons).exists()) QDir().mkpath(icons);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString path = cWorkingDir() + qsl("tdata/"), file = path + qsl("telegramdesktop.desktop");
|
|
|
|
const auto icons =
|
|
|
|
QDir().mkpath(path);
|
|
|
|
QStandardPaths::writableLocation(
|
|
|
|
QFile f(file);
|
|
|
|
QStandardPaths::GenericDataLocation)
|
|
|
|
if (f.open(QIODevice::WriteOnly)) {
|
|
|
|
+ qsl("/icons/");
|
|
|
|
QString icon = icons + qsl("telegram.png");
|
|
|
|
|
|
|
|
auto iconExists = QFile(icon).exists();
|
|
|
|
|
|
|
|
if (Local::oldSettingsVersion() < 10021 && iconExists) {
|
|
|
|
|
|
|
|
// Icon was changed.
|
|
|
|
|
|
|
|
if (QFile(icon).remove()) {
|
|
|
|
|
|
|
|
iconExists = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!iconExists) {
|
|
|
|
|
|
|
|
if (QFile(qsl(":/gui/art/logo_256.png")).copy(icon)) {
|
|
|
|
|
|
|
|
DEBUG_LOG(("App Info: Icon copied to 'tdata'"));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QTextStream s(&f);
|
|
|
|
if (!QDir(icons).exists()) QDir().mkpath(icons);
|
|
|
|
s.setCodec("UTF-8");
|
|
|
|
|
|
|
|
s << "[Desktop Entry]\n";
|
|
|
|
|
|
|
|
s << "Version=1.0\n";
|
|
|
|
|
|
|
|
s << "Name=Telegram Desktop\n";
|
|
|
|
|
|
|
|
s << "Comment=Official desktop application for the Telegram messaging service\n";
|
|
|
|
|
|
|
|
s << "TryExec=" << EscapeShell(QFile::encodeName(cExeDir() + cExeName())) << "\n";
|
|
|
|
|
|
|
|
s << "Exec=" << EscapeShell(QFile::encodeName(cExeDir() + cExeName())) << " -- %u\n";
|
|
|
|
|
|
|
|
s << "Icon=telegram\n";
|
|
|
|
|
|
|
|
s << "Terminal=false\n";
|
|
|
|
|
|
|
|
s << "StartupWMClass=TelegramDesktop\n";
|
|
|
|
|
|
|
|
s << "Type=Application\n";
|
|
|
|
|
|
|
|
s << "Categories=Network;InstantMessaging;Qt;\n";
|
|
|
|
|
|
|
|
s << "MimeType=x-scheme-handler/tg;\n";
|
|
|
|
|
|
|
|
s << "Keywords=tg;chat;im;messaging;messenger;sms;tdesktop;\n";
|
|
|
|
|
|
|
|
s << "X-GNOME-UsesNotifications=true\n";
|
|
|
|
|
|
|
|
f.close();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (RunShellCommand("desktop-file-install --dir=" + EscapeShell(QFile::encodeName(home + qsl(".local/share/applications"))) + " --delete-original " + EscapeShell(QFile::encodeName(file)))) {
|
|
|
|
const auto icon = icons + qsl("telegram.png");
|
|
|
|
DEBUG_LOG(("App Info: removing old .desktop file"));
|
|
|
|
auto iconExists = QFile(icon).exists();
|
|
|
|
QFile(qsl("%1.local/share/applications/telegram.desktop").arg(home)).remove();
|
|
|
|
if (Local::oldSettingsVersion() < 10021 && iconExists) {
|
|
|
|
|
|
|
|
// Icon was changed.
|
|
|
|
RunShellCommand("update-desktop-database " + EscapeShell(QFile::encodeName(home + qsl(".local/share/applications"))));
|
|
|
|
if (QFile(icon).remove()) {
|
|
|
|
RunShellCommand("xdg-mime default telegramdesktop.desktop x-scheme-handler/tg");
|
|
|
|
iconExists = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
LOG(("App Error: Could not open '%1' for write").arg(file));
|
|
|
|
if (!iconExists) {
|
|
|
|
|
|
|
|
if (QFile(qsl(":/gui/art/logo_256.png")).copy(icon)) {
|
|
|
|
|
|
|
|
DEBUG_LOG(("App Info: Icon copied to 'tdata'"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // !TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
|
|
|
#endif // !TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_LOG(("App Info: registerting for Gnome"));
|
|
|
|
RunShellCommand("update-desktop-database "
|
|
|
|
if (RunShellCommand("gconftool-2 -t string -s /desktop/gnome/url-handlers/tg/command " + EscapeShell(EscapeShell(QFile::encodeName(cExeDir() + cExeName())) + " -- %s"))) {
|
|
|
|
+ EscapeShell(QFile::encodeName(applicationsPath)));
|
|
|
|
RunShellCommand("gconftool-2 -t bool -s /desktop/gnome/url-handlers/tg/needs_terminal false");
|
|
|
|
|
|
|
|
RunShellCommand("gconftool-2 -t bool -s /desktop/gnome/url-handlers/tg/enabled true");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_LOG(("App Info: placing .protocol file"));
|
|
|
|
RunShellCommand("xdg-mime default "
|
|
|
|
QString services;
|
|
|
|
MACRO_TO_STRING(TDESKTOP_LAUNCHER_BASENAME)
|
|
|
|
if (QDir(home + qsl(".kde4/")).exists()) {
|
|
|
|
".desktop x-scheme-handler/tg");
|
|
|
|
services = home + qsl(".kde4/share/kde4/services/");
|
|
|
|
|
|
|
|
} else if (QDir(home + qsl(".kde/")).exists()) {
|
|
|
|
|
|
|
|
services = home + qsl(".kde/share/kde4/services/");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!services.isEmpty()) {
|
|
|
|
|
|
|
|
if (!QDir(services).exists()) QDir().mkpath(services);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString path = services, file = path + qsl("tg.protocol");
|
|
|
|
|
|
|
|
QFile f(file);
|
|
|
|
|
|
|
|
if (f.open(QIODevice::WriteOnly)) {
|
|
|
|
|
|
|
|
QTextStream s(&f);
|
|
|
|
|
|
|
|
s.setCodec("UTF-8");
|
|
|
|
|
|
|
|
s << "[Protocol]\n";
|
|
|
|
|
|
|
|
s << "exec=" << QFile::decodeName(EscapeShell(QFile::encodeName(cExeDir() + cExeName()))) << " -- %u\n";
|
|
|
|
|
|
|
|
s << "protocol=tg\n";
|
|
|
|
|
|
|
|
s << "input=none\n";
|
|
|
|
|
|
|
|
s << "output=none\n";
|
|
|
|
|
|
|
|
s << "helper=true\n";
|
|
|
|
|
|
|
|
s << "listing=false\n";
|
|
|
|
|
|
|
|
s << "reading=false\n";
|
|
|
|
|
|
|
|
s << "writing=false\n";
|
|
|
|
|
|
|
|
s << "makedir=false\n";
|
|
|
|
|
|
|
|
s << "deleting=false\n";
|
|
|
|
|
|
|
|
f.close();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
LOG(("App Error: Could not open '%1' for write").arg(file));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
|
|
|
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -417,6 +438,28 @@ bool psShowOpenWithMenu(int x, int y, const QString &file) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void psAutoStart(bool start, bool silent) {
|
|
|
|
void psAutoStart(bool start, bool silent) {
|
|
|
|
|
|
|
|
auto home = getHomeDir();
|
|
|
|
|
|
|
|
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty())
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (InSandbox()) {
|
|
|
|
|
|
|
|
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
|
|
|
|
|
|
|
SandboxAutostart(start);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
const auto autostart =
|
|
|
|
|
|
|
|
QStandardPaths::writableLocation(
|
|
|
|
|
|
|
|
QStandardPaths::GenericConfigLocation)
|
|
|
|
|
|
|
|
+ qsl("/autostart/");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (start) {
|
|
|
|
|
|
|
|
GenerateDesktopFile(autostart, qsl("-autostart"));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
QFile::remove(autostart
|
|
|
|
|
|
|
|
+ qsl(MACRO_TO_STRING(TDESKTOP_LAUNCHER_BASENAME)
|
|
|
|
|
|
|
|
".desktop"));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void psSendToMenu(bool send, bool silent) {
|
|
|
|
void psSendToMenu(bool send, bool silent) {
|
|
|
|