diff --git a/Telegram/Resources/qrc/telegram/telegram.qrc b/Telegram/Resources/qrc/telegram/telegram.qrc index 87ee77587..2a9d64d3c 100644 --- a/Telegram/Resources/qrc/telegram/telegram.qrc +++ b/Telegram/Resources/qrc/telegram/telegram.qrc @@ -56,5 +56,6 @@ ../../default_shortcuts-custom.json + ../../../../lib/xdg/telegramdesktop.desktop diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 07c371d2e..764ab3804 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -24,6 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION +#include +#endif + #include #include #include @@ -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) { diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp index eb06cb7ba..3e613ee5a 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced.cpp @@ -358,7 +358,7 @@ void SetupTrayContent(not_null 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 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 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) { diff --git a/lib/xdg/telegramdesktop.desktop b/lib/xdg/telegramdesktop.desktop index 858a8268e..f4676ce69 100644 --- a/lib/xdg/telegramdesktop.desktop +++ b/lib/xdg/telegramdesktop.desktop @@ -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 diff --git a/lib/xdg/tg.protocol b/lib/xdg/tg.protocol deleted file mode 100644 index a4b083acb..000000000 --- a/lib/xdg/tg.protocol +++ /dev/null @@ -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