Add autostart support for linux

This commit is contained in:
Ilya Fedin 2020-01-21 04:10:10 +04:00 committed by John Preston
parent 74942cd06e
commit 05eabfd539
5 changed files with 139 additions and 102 deletions

View File

@ -56,5 +56,6 @@
</qresource>
<qresource prefix="/misc">
<file alias="default_shortcuts-custom.json">../../default_shortcuts-custom.json</file>
<file alias="telegramdesktop.desktop">../../../../lib/xdg/telegramdesktop.desktop</file>
</qresource>
</RCC>

View File

@ -24,6 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtCore/QProcess>
#include <QtCore/QVersionNumber>
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
#include <QtDBus/QDBusInterface>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdlib>
@ -38,6 +42,27 @@ using Platform::File::internal::EscapeShell;
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) {
auto result = system(command.constData());
if (result) {
@ -87,6 +112,61 @@ void FallbackFontConfig() {
#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 Platform {
@ -98,7 +178,7 @@ void SetApplicationIcon(const QIcon &icon) {
bool InSandbox() {
static const auto Sandbox = QFileInfo::exists(
QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation)
+ qsl("/flatpak-info"));
+ qsl("/flatpak-info"));
return Sandbox;
}
@ -258,104 +338,45 @@ void finish() {
void RegisterCustomScheme() {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
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())
return;
const auto applicationsPath = QStandardPaths::writableLocation(
QStandardPaths::ApplicationsLocation) + '/';
#ifndef TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
DEBUG_LOG(("App Info: placing .desktop file"));
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);
GenerateDesktopFile(applicationsPath, qsl("-- %u"));
QString path = cWorkingDir() + qsl("tdata/"), file = path + qsl("telegramdesktop.desktop");
QDir().mkpath(path);
QFile f(file);
if (f.open(QIODevice::WriteOnly)) {
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'"));
}
}
const auto icons =
QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation)
+ qsl("/icons/");
QTextStream s(&f);
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 (!QDir(icons).exists()) QDir().mkpath(icons);
if (RunShellCommand("desktop-file-install --dir=" + EscapeShell(QFile::encodeName(home + qsl(".local/share/applications"))) + " --delete-original " + EscapeShell(QFile::encodeName(file)))) {
DEBUG_LOG(("App Info: removing old .desktop file"));
QFile(qsl("%1.local/share/applications/telegram.desktop").arg(home)).remove();
RunShellCommand("update-desktop-database " + EscapeShell(QFile::encodeName(home + qsl(".local/share/applications"))));
RunShellCommand("xdg-mime default telegramdesktop.desktop x-scheme-handler/tg");
}
} else {
LOG(("App Error: Could not open '%1' for write").arg(file));
const auto 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'"));
}
}
#endif // !TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
DEBUG_LOG(("App Info: registerting for Gnome"));
if (RunShellCommand("gconftool-2 -t string -s /desktop/gnome/url-handlers/tg/command " + EscapeShell(EscapeShell(QFile::encodeName(cExeDir() + cExeName())) + " -- %s"))) {
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");
}
RunShellCommand("update-desktop-database "
+ EscapeShell(QFile::encodeName(applicationsPath)));
DEBUG_LOG(("App Info: placing .protocol file"));
QString services;
if (QDir(home + qsl(".kde4/")).exists()) {
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));
}
}
RunShellCommand("xdg-mime default "
MACRO_TO_STRING(TDESKTOP_LAUNCHER_BASENAME)
".desktop x-scheme-handler/tg");
#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) {
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) {

View File

@ -358,7 +358,7 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
}
#ifndef OS_WIN_STORE
if (Platform::IsWindows()) {
if (Platform::IsWindows() || Platform::IsLinux()) {
const auto minimizedToggled = [] {
return cStartMinimized() && !Global::LocalPasscode();
};
@ -369,9 +369,6 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
const auto minimized = addSlidingCheckbox(
tr::lng_settings_start_min(tr::now),
minimizedToggled());
const auto sendto = addCheckbox(
tr::lng_settings_add_sendto(tr::now),
cSendToMenu());
autostart->checkedChanges(
) | rpl::filter([](bool checked) {
@ -408,6 +405,12 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
) | rpl::start_with_next([=] {
minimized->entity()->setChecked(minimizedToggled());
}, minimized->lifetime());
}
if (Platform::IsWindows()) {
const auto sendto = addCheckbox(
tr::lng_settings_add_sendto(tr::now),
cSendToMenu());
sendto->checkedChanges(
) | rpl::filter([](bool checked) {

View File

@ -2,6 +2,7 @@
Version=1.0
Name=Telegram Desktop
Comment=Official desktop version of Telegram messaging app
TryExec=telegram-desktop
Exec=telegram-desktop -- %u
Icon=telegram
Terminal=false

View File

@ -1,11 +0,0 @@
[Protocol]
exec=/usr/bin/telegram-desktop -- %u
protocol=tg
input=none
output=none
helper=true
listing=false
reading=false
writing=false
makedir=false
deleting=false