mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 13:17:08 +02:00
Merge branch 'dev' of https://github.com/telegramdesktop/tdesktop into telegramdesktop-dev2
This commit is contained in:
commit
eb9b35461b
45 changed files with 489 additions and 403 deletions
7
.github/workflows/docker.yml
vendored
7
.github/workflows/docker.yml
vendored
|
@ -25,7 +25,12 @@ jobs:
|
|||
submodules: recursive
|
||||
|
||||
- name: First set up.
|
||||
run: curl -sSL https://install.python-poetry.org | python3 -
|
||||
run: |
|
||||
sudo apt update
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
|
||||
- name: Free up some disk space.
|
||||
uses: jlumbroso/free-disk-space@76866dbe54312617f00798d1762df7f43def6e5c
|
||||
|
||||
- name: Docker image build.
|
||||
run: |
|
||||
|
|
3
.github/workflows/snap.yml
vendored
3
.github/workflows/snap.yml
vendored
|
@ -60,6 +60,9 @@ jobs:
|
|||
sudo snap run lxd init --auto
|
||||
sudo snap run lxd waitready
|
||||
|
||||
- name: Free up some disk space.
|
||||
uses: jlumbroso/free-disk-space@76866dbe54312617f00798d1762df7f43def6e5c
|
||||
|
||||
- name: Telegram Desktop snap build.
|
||||
run: sg lxd -c 'snap run snapcraft -v'
|
||||
|
||||
|
|
|
@ -1774,5 +1774,6 @@ if (LINUX AND DESKTOP_APP_USE_PACKAGED)
|
|||
install(FILES "Resources/art/icon256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon512.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/512x512/apps" RENAME "telegram.png")
|
||||
install(FILES "../lib/xdg/org.ayugram.desktop.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications")
|
||||
install(FILES "../lib/xdg/org.telegram.desktop.service" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/dbus-1/services")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/org.ayugram.desktop.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo")
|
||||
endif()
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="4.8.3.0" />
|
||||
Version="4.8.4.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
|
|
@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,8,3,0
|
||||
PRODUCTVERSION 4,8,3,0
|
||||
FILEVERSION 4,8,4,0
|
||||
PRODUCTVERSION 4,8,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -62,10 +62,10 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Radolyn Labs"
|
||||
VALUE "FileDescription", "AyuGram Desktop"
|
||||
VALUE "FileVersion", "4.8.3.0"
|
||||
VALUE "FileVersion", "4.8.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
|
||||
VALUE "ProductName", "AyuGram Desktop"
|
||||
VALUE "ProductVersion", "4.8.3.0"
|
||||
VALUE "ProductVersion", "4.8.4.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,8,3,0
|
||||
PRODUCTVERSION 4,8,3,0
|
||||
FILEVERSION 4,8,4,0
|
||||
PRODUCTVERSION 4,8,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -53,10 +53,10 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Radolyn Labs"
|
||||
VALUE "FileDescription", "AyuGram Desktop Updater"
|
||||
VALUE "FileVersion", "4.8.3.0"
|
||||
VALUE "FileVersion", "4.8.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
|
||||
VALUE "ProductName", "AyuGram Desktop"
|
||||
VALUE "ProductVersion", "4.8.3.0"
|
||||
VALUE "ProductVersion", "4.8.4.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -7,12 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "packer.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
//Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
|
||||
#endif
|
||||
|
||||
bool BetaChannel = false;
|
||||
quint64 AlphaVersion = 0;
|
||||
bool OnlyAlphaKey = false;
|
||||
|
|
|
@ -46,6 +46,7 @@ string updaterName;
|
|||
string workDir;
|
||||
string exeName;
|
||||
string exePath;
|
||||
string argv0;
|
||||
|
||||
FILE *_logFile = 0;
|
||||
void openLog() {
|
||||
|
@ -388,6 +389,8 @@ int main(int argc, char *argv[]) {
|
|||
exeName = argv[i];
|
||||
} else if (equal(argv[i], "-exepath") && ++i < argc) {
|
||||
exePath = argv[i];
|
||||
} else if (equal(argv[i], "-argv0") && ++i < argc) {
|
||||
argv0 = argv[i];
|
||||
}
|
||||
}
|
||||
if (exeName.empty() || exeName.find('/') != string::npos) {
|
||||
|
@ -461,15 +464,14 @@ int main(int argc, char *argv[]) {
|
|||
writeLog("Error: short exe name!");
|
||||
}
|
||||
|
||||
auto fullBinaryPath = exePath + exeName;
|
||||
const auto path = fullBinaryPath.c_str();
|
||||
const auto fullBinaryPath = exePath + exeName;
|
||||
|
||||
auto values = vector<string>();
|
||||
const auto push = [&](string arg) {
|
||||
// Force null-terminated .data() call result.
|
||||
values.push_back(arg + char(0));
|
||||
};
|
||||
push(path);
|
||||
push(!argv0.empty() ? argv0 : fullBinaryPath);
|
||||
push("-noupdate");
|
||||
if (autostart) push("-autostart");
|
||||
if (debug) push("-debug");
|
||||
|
@ -498,7 +500,7 @@ int main(int argc, char *argv[]) {
|
|||
writeLog("fork() failed!");
|
||||
return 1;
|
||||
case 0:
|
||||
execv(args[0], args.data());
|
||||
execv(fullBinaryPath.c_str(), args.data());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,9 +143,8 @@ struct Application::Private {
|
|||
Settings settings;
|
||||
};
|
||||
|
||||
Application::Application(not_null<Launcher*> launcher)
|
||||
Application::Application()
|
||||
: QObject()
|
||||
, _launcher(launcher)
|
||||
, _private(std::make_unique<Private>())
|
||||
, _platformIntegration(Platform::Integration::Create())
|
||||
, _batterySaving(std::make_unique<base::BatterySaving>())
|
||||
|
@ -945,11 +944,11 @@ rpl::producer<> Application::materializeLocalDraftsRequests() const {
|
|||
void Application::switchDebugMode() {
|
||||
if (Logs::DebugEnabled()) {
|
||||
Logs::SetDebugEnabled(false);
|
||||
_launcher->writeDebugModeSetting();
|
||||
Launcher::Instance().writeDebugModeSetting();
|
||||
Restart();
|
||||
} else {
|
||||
Logs::SetDebugEnabled(true);
|
||||
_launcher->writeDebugModeSetting();
|
||||
Launcher::Instance().writeDebugModeSetting();
|
||||
DEBUG_LOG(("Debug logs started."));
|
||||
if (_lastActivePrimaryWindow) {
|
||||
_lastActivePrimaryWindow->hideLayer();
|
||||
|
@ -957,10 +956,6 @@ void Application::switchDebugMode() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::writeInstallBetaVersionsSetting() {
|
||||
_launcher->writeInstallBetaVersionsSetting();
|
||||
}
|
||||
|
||||
Main::Account &Application::activeAccount() const {
|
||||
return _domain->active();
|
||||
}
|
||||
|
@ -1767,10 +1762,8 @@ void Application::startShortcuts() {
|
|||
|
||||
void Application::RegisterUrlScheme() {
|
||||
base::Platform::RegisterUrlScheme(base::Platform::UrlSchemeDescriptor{
|
||||
.executable = (!Platform::IsLinux() || !Core::UpdaterDisabled())
|
||||
? (cExeDir() + cExeName())
|
||||
: cExeName(),
|
||||
.arguments = Sandbox::Instance().customWorkingDir()
|
||||
.executable = Platform::ExecutablePathForShortcuts(),
|
||||
.arguments = Launcher::Instance().customWorkingDir()
|
||||
? u"-workdir \"%1\""_q.arg(cWorkingDir())
|
||||
: QString(),
|
||||
.protocol = u"tg"_q,
|
||||
|
|
|
@ -103,7 +103,6 @@ class Instance;
|
|||
|
||||
namespace Core {
|
||||
|
||||
class Launcher;
|
||||
struct LocalUrlHandler;
|
||||
class Settings;
|
||||
class Tray;
|
||||
|
@ -126,16 +125,13 @@ public:
|
|||
MTP::ProxyData now;
|
||||
};
|
||||
|
||||
Application(not_null<Launcher*> launcher);
|
||||
Application();
|
||||
Application(const Application &other) = delete;
|
||||
Application &operator=(const Application &other) = delete;
|
||||
~Application();
|
||||
|
||||
void run();
|
||||
|
||||
[[nodiscard]] Launcher &launcher() const {
|
||||
return *_launcher;
|
||||
}
|
||||
[[nodiscard]] Platform::Integration &platformIntegration() const {
|
||||
return *_platformIntegration;
|
||||
}
|
||||
|
@ -319,7 +315,6 @@ public:
|
|||
[[nodiscard]] rpl::producer<> materializeLocalDraftsRequests() const;
|
||||
|
||||
void switchDebugMode();
|
||||
void writeInstallBetaVersionsSetting();
|
||||
|
||||
void preventOrInvoke(Fn<void()> &&callback);
|
||||
|
||||
|
@ -381,7 +376,6 @@ private:
|
|||
};
|
||||
InstanceSetter _setter = { this };
|
||||
|
||||
const not_null<Launcher*> _launcher;
|
||||
rpl::event_stream<ProxyChange> _proxyChanges;
|
||||
|
||||
// Some fields are just moved from the declaration.
|
||||
|
|
|
@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "core/crash_reports.h"
|
||||
#include "core/application.h"
|
||||
#include "core/launcher.h"
|
||||
#include "core/sandbox.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "core/ui_integration.h"
|
||||
|
@ -250,7 +249,6 @@ LastCrashedWindow::UpdaterData::UpdaterData(QWidget *buttonParent)
|
|||
}
|
||||
|
||||
LastCrashedWindow::LastCrashedWindow(
|
||||
not_null<Core::Launcher*> launcher,
|
||||
const QByteArray &crashdump,
|
||||
Fn<void()> launch)
|
||||
: _dumpraw(crashdump)
|
||||
|
|
|
@ -20,10 +20,6 @@ namespace MTP {
|
|||
struct ProxyData;
|
||||
} // namespace MTP
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
} // namespace Core
|
||||
|
||||
class PreLaunchWindow : public QWidget {
|
||||
public:
|
||||
PreLaunchWindow(QString title = QString());
|
||||
|
@ -94,10 +90,7 @@ private:
|
|||
class LastCrashedWindow : public PreLaunchWindow {
|
||||
|
||||
public:
|
||||
LastCrashedWindow(
|
||||
not_null<Core::Launcher*> launcher,
|
||||
const QByteArray &crashdump,
|
||||
Fn<void()> launch);
|
||||
LastCrashedWindow(const QByteArray &crashdump, Fn<void()> launch);
|
||||
|
||||
rpl::producer<MTP::ProxyData> proxyChanges() const;
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ QString PlatformString() {
|
|||
Unexpected("Platform in CrashReports::PlatformString.");
|
||||
}
|
||||
|
||||
void StartCatching(not_null<Core::Launcher*> launcher) {
|
||||
void StartCatching() {
|
||||
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
|
||||
ProcessAnnotations["Binary"] = cExeName().toUtf8().constData();
|
||||
ProcessAnnotations["ApiId"] = QString::number(ApiId).toUtf8().constData();
|
||||
|
@ -324,7 +324,7 @@ void StartCatching(not_null<Core::Launcher*> launcher) {
|
|||
: u"%1"_q).arg(AppVersion)).toUtf8().constData();
|
||||
ProcessAnnotations["Launched"] = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss").toUtf8().constData();
|
||||
ProcessAnnotations["Platform"] = PlatformString().toUtf8().constData();
|
||||
ProcessAnnotations["UserTag"] = QString::number(launcher->installationTag(), 16).toUtf8().constData();
|
||||
ProcessAnnotations["UserTag"] = QString::number(Core::Launcher::Instance().installationTag(), 16).toUtf8().constData();
|
||||
|
||||
QString dumpspath = cWorkingDir() + u"tdata/dumps"_q;
|
||||
QDir().mkpath(dumpspath);
|
||||
|
|
|
@ -7,10 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
} // namespace Core
|
||||
|
||||
namespace CrashReports {
|
||||
|
||||
QString PlatformString();
|
||||
|
@ -53,7 +49,7 @@ inline void ClearAnnotationRef(const std::string &key) {
|
|||
SetAnnotationRef(key, nullptr);
|
||||
}
|
||||
|
||||
void StartCatching(not_null<Core::Launcher*> launcher);
|
||||
void StartCatching();
|
||||
void FinishCatching();
|
||||
|
||||
} // namespace CrashReports
|
||||
|
|
|
@ -281,6 +281,8 @@ base::options::toggle OptionFractionalScalingEnabled({
|
|||
const char kOptionFractionalScalingEnabled[] = "fractional-scaling-enabled";
|
||||
const char kOptionFreeType[] = "freetype";
|
||||
|
||||
Launcher *Launcher::InstanceSetter::Instance = nullptr;
|
||||
|
||||
std::unique_ptr<Launcher> Launcher::Create(int argc, char *argv[]) {
|
||||
return std::make_unique<Platform::Launcher>(argc, argv);
|
||||
}
|
||||
|
@ -288,15 +290,18 @@ std::unique_ptr<Launcher> Launcher::Create(int argc, char *argv[]) {
|
|||
Launcher::Launcher(int argc, char *argv[])
|
||||
: _argc(argc)
|
||||
, _argv(argv)
|
||||
, _arguments(readArguments(_argc, _argv))
|
||||
, _baseIntegration(_argc, _argv) {
|
||||
crl::toggle_fp_exceptions(true);
|
||||
|
||||
base::Integration::Set(&_baseIntegration);
|
||||
}
|
||||
|
||||
void Launcher::init() {
|
||||
_arguments = readArguments(_argc, _argv);
|
||||
Launcher::~Launcher() {
|
||||
InstanceSetter::Instance = nullptr;
|
||||
}
|
||||
|
||||
void Launcher::init() {
|
||||
prepareSettings();
|
||||
initQtMessageLogging();
|
||||
|
||||
|
@ -343,7 +348,7 @@ int Launcher::exec() {
|
|||
}
|
||||
|
||||
// Must be started before Platform is started.
|
||||
Logs::start(this);
|
||||
Logs::start();
|
||||
base::options::init(cWorkingDir() + "tdata/experimental_options.json");
|
||||
|
||||
// Must be called after options are inited.
|
||||
|
@ -425,8 +430,8 @@ QStringList Launcher::readArguments(int argc, char *argv[]) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
QString Launcher::argumentsString() const {
|
||||
return _arguments.join(' ');
|
||||
const QStringList &Launcher::arguments() const {
|
||||
return _arguments;
|
||||
}
|
||||
|
||||
bool Launcher::customWorkingDir() const {
|
||||
|
@ -436,17 +441,6 @@ bool Launcher::customWorkingDir() const {
|
|||
void Launcher::prepareSettings() {
|
||||
auto path = base::Platform::CurrentExecutablePath(_argc, _argv);
|
||||
LOG(("Executable path before check: %1").arg(path));
|
||||
if (!path.isEmpty()) {
|
||||
auto info = QFileInfo(path);
|
||||
if (info.isSymLink()) {
|
||||
info = QFileInfo(info.symLinkTarget());
|
||||
}
|
||||
if (info.exists()) {
|
||||
const auto dir = info.absoluteDir().absolutePath();
|
||||
gExeDir = (dir.endsWith('/') ? dir : (dir + '/'));
|
||||
gExeName = info.fileName();
|
||||
}
|
||||
}
|
||||
if (cExeName().isEmpty()) {
|
||||
LOG(("WARNING: Could not compute executable path, some features will be disabled."));
|
||||
}
|
||||
|
@ -558,7 +552,7 @@ void Launcher::processArguments() {
|
|||
|
||||
int Launcher::executeApplication() {
|
||||
FilteredCommandLineArguments arguments(_argc, _argv);
|
||||
Sandbox sandbox(this, arguments.count(), arguments.values());
|
||||
Sandbox sandbox(arguments.count(), arguments.values());
|
||||
Ui::MainQueueProcessor processor;
|
||||
base::ConcurrentTimerEnvironment environment;
|
||||
return sandbox.start();
|
||||
|
|
|
@ -20,9 +20,15 @@ public:
|
|||
|
||||
static std::unique_ptr<Launcher> Create(int argc, char *argv[]);
|
||||
|
||||
static Launcher &Instance() {
|
||||
Expects(InstanceSetter::Instance != nullptr);
|
||||
|
||||
return *InstanceSetter::Instance;
|
||||
}
|
||||
|
||||
virtual int exec();
|
||||
|
||||
QString argumentsString() const;
|
||||
const QStringList &arguments() const;
|
||||
bool customWorkingDir() const;
|
||||
|
||||
uint64 installationTag() const;
|
||||
|
@ -32,7 +38,7 @@ public:
|
|||
void writeDebugModeSetting();
|
||||
void writeInstallBetaVersionsSetting();
|
||||
|
||||
virtual ~Launcher() = default;
|
||||
virtual ~Launcher();
|
||||
|
||||
protected:
|
||||
enum class UpdaterLaunch {
|
||||
|
@ -61,6 +67,17 @@ private:
|
|||
|
||||
int executeApplication();
|
||||
|
||||
struct InstanceSetter {
|
||||
InstanceSetter(not_null<Launcher*> instance) {
|
||||
Expects(Instance == nullptr);
|
||||
|
||||
Instance = instance;
|
||||
}
|
||||
|
||||
static Launcher *Instance;
|
||||
};
|
||||
InstanceSetter _setter = { this };
|
||||
|
||||
int _argc;
|
||||
char **_argv;
|
||||
QStringList _arguments;
|
||||
|
|
|
@ -80,13 +80,9 @@ QString _escapeFrom7bit(const QString &str) {
|
|||
|
||||
bool Sandbox::QuitOnStartRequested = false;
|
||||
|
||||
Sandbox::Sandbox(
|
||||
not_null<Core::Launcher*> launcher,
|
||||
int &argc,
|
||||
char **argv)
|
||||
Sandbox::Sandbox(int &argc, char **argv)
|
||||
: QApplication(argc, argv)
|
||||
, _mainThreadId(QThread::currentThreadId())
|
||||
, _launcher(launcher) {
|
||||
, _mainThreadId(QThread::currentThreadId()) {
|
||||
setQuitOnLastWindowClosed(false);
|
||||
}
|
||||
|
||||
|
@ -109,7 +105,8 @@ int Sandbox::start() {
|
|||
hashMd5Hex(d.constData(), d.size(), h.data());
|
||||
_lockFile = std::make_unique<QLockFile>(QDir::tempPath() + '/' + h + '-' + cGUIDStr());
|
||||
_lockFile->setStaleLockTime(0);
|
||||
if (!_lockFile->tryLock() && _launcher->customWorkingDir()) {
|
||||
if (!_lockFile->tryLock()
|
||||
&& Launcher::Instance().customWorkingDir()) {
|
||||
// On Windows, QLockFile has problems detecting a stale lock
|
||||
// if the machine's hostname contains characters outside the US-ASCII character set.
|
||||
if constexpr (Platform::IsWindows()) {
|
||||
|
@ -204,7 +201,7 @@ void Sandbox::launchApplication() {
|
|||
}
|
||||
setupScreenScale();
|
||||
|
||||
_application = std::make_unique<Application>(_launcher);
|
||||
_application = std::make_unique<Application>();
|
||||
|
||||
// Ideally this should go to constructor.
|
||||
// But we want to catch all native events and Application installs
|
||||
|
@ -405,7 +402,6 @@ void Sandbox::singleInstanceChecked() {
|
|||
}
|
||||
_lastCrashDump = crashdump;
|
||||
auto window = new LastCrashedWindow(
|
||||
_launcher,
|
||||
_lastCrashDump,
|
||||
[=] { launchApplication(); });
|
||||
window->proxyChanges(
|
||||
|
@ -533,14 +529,6 @@ void Sandbox::refreshGlobalProxy() {
|
|||
}
|
||||
}
|
||||
|
||||
bool Sandbox::customWorkingDir() const {
|
||||
return _launcher->customWorkingDir();
|
||||
}
|
||||
|
||||
uint64 Sandbox::installationTag() const {
|
||||
return _launcher->installationTag();
|
||||
}
|
||||
|
||||
void Sandbox::checkForEmptyLoopNestingLevel() {
|
||||
// _loopNestingLevel == _eventNestingLevel means that we had a
|
||||
// native event in a nesting loop that didn't get a notify() call
|
||||
|
|
|
@ -19,7 +19,6 @@ class QLockFile;
|
|||
|
||||
namespace Core {
|
||||
|
||||
class Launcher;
|
||||
class UpdateChecker;
|
||||
class Application;
|
||||
|
||||
|
@ -33,7 +32,7 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
Sandbox(not_null<Launcher*> launcher, int &argc, char **argv);
|
||||
Sandbox(int &argc, char **argv);
|
||||
|
||||
Sandbox(const Sandbox &other) = delete;
|
||||
Sandbox &operator=(const Sandbox &other) = delete;
|
||||
|
@ -41,8 +40,6 @@ public:
|
|||
int start();
|
||||
|
||||
void refreshGlobalProxy();
|
||||
bool customWorkingDir() const;
|
||||
uint64 installationTag() const;
|
||||
|
||||
void postponeCall(FnMut<void()> &&callable);
|
||||
bool notify(QObject *receiver, QEvent *e) override;
|
||||
|
@ -116,7 +113,6 @@ private:
|
|||
std::vector<int> _previousLoopNestingLevels;
|
||||
std::vector<PostponedCall> _postponedCalls;
|
||||
|
||||
not_null<Launcher*> _launcher;
|
||||
std::unique_ptr<Application> _application;
|
||||
|
||||
QString _localServerName, _localSocketReadData;
|
||||
|
|
|
@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs;
|
|||
constexpr auto AppNameOld = "AyuGram for Windows"_cs;
|
||||
constexpr auto AppName = "AyuGram Desktop"_cs;
|
||||
constexpr auto AppFile = "AyuGram"_cs;
|
||||
constexpr auto AppVersion = 4008003;
|
||||
constexpr auto AppVersionStr = "4.8.3";
|
||||
constexpr auto AppVersion = 4008004;
|
||||
constexpr auto AppVersionStr = "4.8.4";
|
||||
constexpr auto AppBetaVersion = false;
|
||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||
|
|
|
@ -343,10 +343,10 @@ bool WritingEntry() {
|
|||
return WritingEntryFlag;
|
||||
}
|
||||
|
||||
void start(not_null<Core::Launcher*> launcher) {
|
||||
void start() {
|
||||
Assert(LogsData == nullptr);
|
||||
|
||||
if (!launcher->checkPortableVersionFolder()) {
|
||||
if (!Core::Launcher::Instance().checkPortableVersionFolder()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -414,8 +414,8 @@ void start(not_null<Core::Launcher*> launcher) {
|
|||
|
||||
QDir().mkpath(cWorkingDir() + u"tdata"_q);
|
||||
|
||||
launcher->workingFolderReady();
|
||||
CrashReports::StartCatching(launcher);
|
||||
Core::Launcher::Instance().workingFolderReady();
|
||||
CrashReports::StartCatching();
|
||||
|
||||
if (!LogsData->openMain()) {
|
||||
delete LogsData;
|
||||
|
@ -430,7 +430,7 @@ void start(not_null<Core::Launcher*> launcher) {
|
|||
LOG(("Executable dir: %1, name: %2").arg(cExeDir(), cExeName()));
|
||||
LOG(("Initial working dir: %1").arg(initialWorkingDir));
|
||||
LOG(("Working dir: %1").arg(cWorkingDir()));
|
||||
LOG(("Command line: %1").arg(launcher->argumentsString()));
|
||||
LOG(("Command line: %1").arg(Core::Launcher::Instance().arguments().join(' ')));
|
||||
|
||||
if (!LogsData) {
|
||||
LOG(("FATAL: Could not open '%1' for writing log!"
|
||||
|
|
|
@ -11,17 +11,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/assertion.h"
|
||||
#include "base/debug_log.h"
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
} // namespace Core
|
||||
|
||||
namespace Logs {
|
||||
|
||||
void SetDebugEnabled(bool enabled);
|
||||
bool DebugEnabled();
|
||||
[[nodiscard]] bool WritingEntry();
|
||||
|
||||
void start(not_null<Core::Launcher*> launcher);
|
||||
void start();
|
||||
bool started();
|
||||
void finish();
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ QByteArray DnsUserAgent() {
|
|||
static const auto kResult = QByteArray(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/113.0.5672.63 Safari/537.36");
|
||||
"Chrome/114.0.5735.133 Safari/537.36");
|
||||
return kResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,20 +8,89 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "platform/linux/integration_linux.h"
|
||||
|
||||
#include "platform/platform_integration.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "base/platform/linux/base_linux_glibmm_helper.h"
|
||||
#include "base/platform/linux/base_linux_xdp_utilities.h"
|
||||
#include "core/sandbox.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "base/random.h"
|
||||
|
||||
#include <xdpinhibit/xdpinhibit.hpp>
|
||||
#include <glibmm.h>
|
||||
#include <QtCore/QAbstractEventDispatcher>
|
||||
|
||||
using namespace gi::repository;
|
||||
#include <xdpinhibit/xdpinhibit.hpp>
|
||||
#include <giomm.h>
|
||||
|
||||
typedef GApplication TDesktopApplication;
|
||||
typedef GApplicationClass TDesktopApplicationClass;
|
||||
|
||||
G_DEFINE_TYPE(
|
||||
TDesktopApplication,
|
||||
t_desktop_application,
|
||||
G_TYPE_APPLICATION)
|
||||
|
||||
static void t_desktop_application_class_init(
|
||||
TDesktopApplicationClass *klass) {
|
||||
const auto application_class = G_APPLICATION_CLASS(klass);
|
||||
|
||||
application_class->local_command_line = [](
|
||||
GApplication *application,
|
||||
char ***arguments,
|
||||
int *exit_status) -> gboolean {
|
||||
return false;
|
||||
};
|
||||
|
||||
application_class->command_line = [](
|
||||
GApplication *application,
|
||||
GApplicationCommandLine *cmdline) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
application_class->before_emit = [](
|
||||
GApplication *application,
|
||||
GVariant *platformData) {
|
||||
if (Platform::IsWayland()) {
|
||||
static const auto keys = {
|
||||
"activation-token",
|
||||
"desktop-startup-id",
|
||||
};
|
||||
for (const auto &key : keys) {
|
||||
const char *token = nullptr;
|
||||
g_variant_lookup(platformData, key, "&s", &token);
|
||||
if (token) {
|
||||
qputenv("XDG_ACTIVATION_TOKEN", token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
application_class->add_platform_data = [](
|
||||
GApplication *application,
|
||||
GVariantBuilder *builder) {
|
||||
if (Platform::IsWayland()) {
|
||||
const auto token = qgetenv("XDG_ACTIVATION_TOKEN");
|
||||
if (!token.isEmpty()) {
|
||||
g_variant_builder_add(
|
||||
builder,
|
||||
"{sv}",
|
||||
"activation-token",
|
||||
g_variant_new_string(token.constData()));
|
||||
qunsetenv("XDG_ACTIVATION_TOKEN");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void t_desktop_application_init(TDesktopApplication *application) {
|
||||
}
|
||||
|
||||
namespace Platform {
|
||||
namespace {
|
||||
|
||||
using namespace gi::repository;
|
||||
namespace Gio = gi::repository::Gio;
|
||||
|
||||
class LinuxIntegration final : public Integration {
|
||||
public:
|
||||
LinuxIntegration();
|
||||
|
@ -33,6 +102,10 @@ private:
|
|||
return _inhibitProxy;
|
||||
}
|
||||
|
||||
void initInhibit();
|
||||
|
||||
static void LaunchNativeApplication();
|
||||
|
||||
XdpInhibit::InhibitProxy _inhibitProxy;
|
||||
base::Platform::XDP::SettingWatcher _darkModeWatcher;
|
||||
};
|
||||
|
@ -61,9 +134,25 @@ LinuxIntegration::LinuxIntegration()
|
|||
}
|
||||
}
|
||||
}) {
|
||||
LOG(("Icon theme: %1").arg(QIcon::themeName()));
|
||||
LOG(("Fallback icon theme: %1").arg(QIcon::fallbackThemeName()));
|
||||
|
||||
if (!QCoreApplication::eventDispatcher()->inherits(
|
||||
"QEventDispatcherGlib")) {
|
||||
g_warning("Qt is running without GLib event loop integration, "
|
||||
"except various functionality to not to work.");
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxIntegration::init() {
|
||||
initInhibit();
|
||||
|
||||
Glib::signal_idle().connect_once([] {
|
||||
LaunchNativeApplication();
|
||||
});
|
||||
}
|
||||
|
||||
void LinuxIntegration::initInhibit() {
|
||||
if (!_inhibitProxy) {
|
||||
return;
|
||||
}
|
||||
|
@ -119,6 +208,111 @@ void LinuxIntegration::init() {
|
|||
nullptr);
|
||||
}
|
||||
|
||||
void LinuxIntegration::LaunchNativeApplication() {
|
||||
const auto appId = QGuiApplication::desktopFileName()
|
||||
.chopped(8)
|
||||
.toStdString();
|
||||
|
||||
const auto app = Glib::wrap(
|
||||
G_APPLICATION(
|
||||
g_object_new(
|
||||
t_desktop_application_get_type(),
|
||||
"application-id",
|
||||
::Gio::Application::id_is_valid(appId)
|
||||
? appId.c_str()
|
||||
: nullptr,
|
||||
"flags",
|
||||
G_APPLICATION_HANDLES_OPEN,
|
||||
nullptr)));
|
||||
|
||||
app->signal_startup().connect([=] {
|
||||
// GNotification
|
||||
InvokeQueued(qApp, [] {
|
||||
Core::App().notifications().createManager();
|
||||
});
|
||||
|
||||
QEventLoop().exec();
|
||||
app->quit();
|
||||
}, true);
|
||||
|
||||
app->signal_activate().connect([] {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||
Core::App().activate();
|
||||
});
|
||||
}, true);
|
||||
|
||||
app->signal_open().connect([](
|
||||
const ::Gio::Application::type_vec_files &files,
|
||||
const Glib::ustring &hint) {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
for (const auto &file : files) {
|
||||
QFileOpenEvent e(
|
||||
QUrl(QString::fromStdString(file->get_uri())));
|
||||
QGuiApplication::sendEvent(qApp, &e);
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
app->add_action("quit", [] {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||
Core::Quit();
|
||||
});
|
||||
});
|
||||
|
||||
using Window::Notifications::Manager;
|
||||
using NotificationId = Manager::NotificationId;
|
||||
using NotificationIdTuple = std::invoke_result_t<
|
||||
decltype(&NotificationId::toTuple),
|
||||
NotificationId*
|
||||
>;
|
||||
|
||||
const auto notificationIdVariantType = [] {
|
||||
try {
|
||||
return base::Platform::MakeGlibVariant(
|
||||
NotificationId().toTuple()).get_type();
|
||||
} catch (...) {
|
||||
return Glib::VariantType();
|
||||
}
|
||||
}();
|
||||
|
||||
app->add_action_with_parameter(
|
||||
"notification-activate",
|
||||
notificationIdVariantType,
|
||||
[](const Glib::VariantBase ¶meter) {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
try {
|
||||
const auto &app = Core::App();
|
||||
app.notifications().manager().notificationActivated(
|
||||
NotificationId::FromTuple(
|
||||
base::Platform::GlibVariantCast<
|
||||
NotificationIdTuple
|
||||
>(parameter)));
|
||||
} catch (...) {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app->add_action_with_parameter(
|
||||
"notification-mark-as-read",
|
||||
notificationIdVariantType,
|
||||
[](const Glib::VariantBase ¶meter) {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
try {
|
||||
const auto &app = Core::App();
|
||||
app.notifications().manager().notificationReplied(
|
||||
NotificationId::FromTuple(
|
||||
base::Platform::GlibVariantCast<
|
||||
NotificationIdTuple
|
||||
>(parameter)),
|
||||
{});
|
||||
} catch (...) {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app->run(0, nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Integration> CreateIntegration() {
|
||||
|
|
|
@ -24,8 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Platform {
|
||||
namespace {
|
||||
|
||||
Launcher *LauncherInstance = nullptr;
|
||||
|
||||
class Arguments {
|
||||
public:
|
||||
void push(QByteArray argument) {
|
||||
|
@ -48,23 +46,13 @@ private:
|
|||
} // namespace
|
||||
|
||||
Launcher::Launcher(int argc, char *argv[])
|
||||
: Core::Launcher(argc, argv)
|
||||
, _arguments(argv, argv + argc) {
|
||||
Expects(LauncherInstance == nullptr);
|
||||
|
||||
LauncherInstance = this;
|
||||
}
|
||||
|
||||
Launcher &Launcher::Instance() {
|
||||
Expects(LauncherInstance != nullptr);
|
||||
|
||||
return *LauncherInstance;
|
||||
: Core::Launcher(argc, argv) {
|
||||
}
|
||||
|
||||
int Launcher::exec() {
|
||||
for (auto i = begin(_arguments), e = end(_arguments); i != e; ++i) {
|
||||
if (*i == "-webviewhelper" && std::distance(i, e) > 1) {
|
||||
Webview::WebKitGTK::SetSocketPath(*(i + 1));
|
||||
for (auto i = arguments().begin(), e = arguments().end(); i != e; ++i) {
|
||||
if (*i == u"-webviewhelper"_q && std::distance(i, e) > 1) {
|
||||
Webview::WebKitGTK::SetSocketPath((i + 1)->toStdString());
|
||||
return Webview::WebKitGTK::Exec();
|
||||
}
|
||||
}
|
||||
|
@ -81,17 +69,23 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const auto binaryPath = (action == UpdaterLaunch::JustRelaunch)
|
||||
? (cExeDir() + cExeName())
|
||||
: (cWriteProtected()
|
||||
const auto justRelaunch = action == UpdaterLaunch::JustRelaunch;
|
||||
const auto writeProtectedUpdate = action == UpdaterLaunch::PerformUpdate
|
||||
&& cWriteProtected();
|
||||
|
||||
const auto binaryPath = justRelaunch
|
||||
? QFile::encodeName(cExeDir() + cExeName())
|
||||
: QFile::encodeName(cWriteProtected()
|
||||
? (cWorkingDir() + u"tupdates/temp/Updater"_q)
|
||||
: (cExeDir() + u"Updater"_q));
|
||||
|
||||
auto argumentsList = Arguments();
|
||||
if (action == UpdaterLaunch::PerformUpdate && cWriteProtected()) {
|
||||
if (writeProtectedUpdate) {
|
||||
argumentsList.push("pkexec");
|
||||
}
|
||||
argumentsList.push(QFile::encodeName(binaryPath));
|
||||
argumentsList.push((justRelaunch && !arguments().isEmpty())
|
||||
? QFile::encodeName(arguments().first())
|
||||
: binaryPath);
|
||||
|
||||
if (cLaunchMode() == LaunchModeAutoStart) {
|
||||
argumentsList.push("-autostart");
|
||||
|
@ -107,7 +101,7 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
|
|||
argumentsList.push(QFile::encodeName(cDataFile()));
|
||||
}
|
||||
|
||||
if (action == UpdaterLaunch::JustRelaunch) {
|
||||
if (justRelaunch) {
|
||||
argumentsList.push("-noupdate");
|
||||
argumentsList.push("-tosettings");
|
||||
if (customWorkingDir()) {
|
||||
|
@ -121,6 +115,10 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
|
|||
argumentsList.push(QFile::encodeName(cExeName()));
|
||||
argumentsList.push("-exepath");
|
||||
argumentsList.push(QFile::encodeName(cExeDir()));
|
||||
if (!arguments().isEmpty()) {
|
||||
argumentsList.push("-argv0");
|
||||
argumentsList.push(QFile::encodeName(arguments().first()));
|
||||
}
|
||||
if (customWorkingDir()) {
|
||||
argumentsList.push("-workdir_custom");
|
||||
}
|
||||
|
@ -137,11 +135,15 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
|
|||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1: return false;
|
||||
case 0: execvp(args[0], args); return false;
|
||||
case 0:
|
||||
execvp(
|
||||
writeProtectedUpdate ? args[0] : binaryPath.constData(),
|
||||
args);
|
||||
return false;
|
||||
}
|
||||
|
||||
// pkexec needs an alive parent
|
||||
if (action == UpdaterLaunch::PerformUpdate && cWriteProtected()) {
|
||||
if (writeProtectedUpdate) {
|
||||
waitpid(pid, nullptr, 0);
|
||||
// launch new version in the same environment
|
||||
return launchUpdater(UpdaterLaunch::JustRelaunch);
|
||||
|
|
|
@ -15,16 +15,12 @@ class Launcher : public Core::Launcher {
|
|||
public:
|
||||
Launcher(int argc, char *argv[]);
|
||||
|
||||
static Launcher &Instance();
|
||||
|
||||
int exec() override;
|
||||
|
||||
private:
|
||||
void initHook() override;
|
||||
bool launchUpdater(UpdaterLaunch action) override;
|
||||
|
||||
std::vector<std::string> _arguments;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Platform
|
||||
|
|
|
@ -123,12 +123,15 @@ WaylandIntegration::~WaylandIntegration() = default;
|
|||
WaylandIntegration *WaylandIntegration::Instance() {
|
||||
if (!IsWayland()) return nullptr;
|
||||
static std::optional<WaylandIntegration> instance(std::in_place);
|
||||
base::qt_signal_producer(
|
||||
QGuiApplication::platformNativeInterface(),
|
||||
&QObject::destroyed
|
||||
) | rpl::start_with_next([&] {
|
||||
instance = std::nullopt;
|
||||
}, instance->_private->lifetime);
|
||||
[[maybe_unused]] static const auto Inited = [] {
|
||||
base::qt_signal_producer(
|
||||
QGuiApplication::platformNativeInterface(),
|
||||
&QObject::destroyed
|
||||
) | rpl::start_with_next([] {
|
||||
instance = std::nullopt;
|
||||
}, instance->_private->lifetime);
|
||||
return true;
|
||||
}();
|
||||
if (!instance) return nullptr;
|
||||
return &*instance;
|
||||
}
|
||||
|
|
|
@ -8,20 +8,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "platform/linux/specific_linux.h"
|
||||
|
||||
#include "base/random.h"
|
||||
#include "base/options.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "base/platform/linux/base_linux_glibmm_helper.h"
|
||||
#include "base/platform/linux/base_linux_dbus_utilities.h"
|
||||
#include "base/platform/linux/base_linux_xdp_utilities.h"
|
||||
#include "platform/linux/linux_desktop_environment.h"
|
||||
#include "platform/linux/linux_wayland_integration.h"
|
||||
#include "platform/platform_launcher.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwindow.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "core/sandbox.h"
|
||||
#include "core/launcher.h"
|
||||
#include "core/application.h"
|
||||
#include "core/local_url_handlers.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "window/window_controller.h"
|
||||
|
@ -35,7 +32,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <QtWidgets/QSystemTrayIcon>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QAbstractEventDispatcher>
|
||||
|
||||
#include <kshell.h>
|
||||
#include <ksandbox.h>
|
||||
|
@ -56,57 +52,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
using namespace Platform;
|
||||
using Platform::internal::WaylandIntegration;
|
||||
|
||||
typedef GApplication TDesktopApplication;
|
||||
typedef GApplicationClass TDesktopApplicationClass;
|
||||
|
||||
G_DEFINE_TYPE(
|
||||
TDesktopApplication,
|
||||
t_desktop_application,
|
||||
G_TYPE_APPLICATION)
|
||||
|
||||
static void t_desktop_application_class_init(
|
||||
TDesktopApplicationClass *klass) {
|
||||
const auto application_class = G_APPLICATION_CLASS(klass);
|
||||
|
||||
application_class->before_emit = [](
|
||||
GApplication *application,
|
||||
GVariant *platformData) {
|
||||
if (Platform::IsWayland()) {
|
||||
static const auto keys = {
|
||||
"activation-token",
|
||||
"desktop-startup-id",
|
||||
};
|
||||
for (const auto &key : keys) {
|
||||
const char *token = nullptr;
|
||||
g_variant_lookup(platformData, key, "&s", &token);
|
||||
if (token) {
|
||||
qputenv("XDG_ACTIVATION_TOKEN", token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
application_class->add_platform_data = [](
|
||||
GApplication *application,
|
||||
GVariantBuilder *builder) {
|
||||
if (Platform::IsWayland()) {
|
||||
const auto token = qgetenv("XDG_ACTIVATION_TOKEN");
|
||||
if (!token.isEmpty()) {
|
||||
g_variant_builder_add(
|
||||
builder,
|
||||
"{sv}",
|
||||
"activation-token",
|
||||
g_variant_new_string(token.constData()));
|
||||
qunsetenv("XDG_ACTIVATION_TOKEN");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void t_desktop_application_init(TDesktopApplication *application) {
|
||||
}
|
||||
|
||||
namespace Platform {
|
||||
namespace {
|
||||
|
||||
|
@ -138,7 +83,7 @@ bool PortalAutostart(bool start, bool silent) {
|
|||
|
||||
std::vector<Glib::ustring> commandline;
|
||||
commandline.push_back(cExeName().toStdString());
|
||||
if (Core::Sandbox::Instance().customWorkingDir()) {
|
||||
if (Core::Launcher::Instance().customWorkingDir()) {
|
||||
commandline.push_back("-workdir");
|
||||
commandline.push_back(cWorkingDir().toStdString());
|
||||
}
|
||||
|
@ -232,121 +177,13 @@ bool PortalAutostart(bool start, bool silent) {
|
|||
return !error;
|
||||
}
|
||||
|
||||
void LaunchGApplication() {
|
||||
Glib::signal_idle().connect_once([] {
|
||||
const auto appId = QGuiApplication::desktopFileName()
|
||||
.chopped(8)
|
||||
.toStdString();
|
||||
|
||||
const auto app = Glib::wrap(
|
||||
G_APPLICATION(
|
||||
g_object_new(
|
||||
t_desktop_application_get_type(),
|
||||
"application-id",
|
||||
Gio::Application::id_is_valid(appId)
|
||||
? appId.c_str()
|
||||
: nullptr,
|
||||
"flags",
|
||||
G_APPLICATION_HANDLES_OPEN,
|
||||
nullptr)));
|
||||
|
||||
app->signal_startup().connect([=] {
|
||||
// GNotification
|
||||
InvokeQueued(qApp, [] {
|
||||
Core::App().notifications().createManager();
|
||||
});
|
||||
|
||||
QEventLoop().exec();
|
||||
app->quit();
|
||||
}, true);
|
||||
|
||||
app->signal_activate().connect([] {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||
if (Core::IsAppLaunched()) {
|
||||
Core::App().activate();
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
app->signal_open().connect([](
|
||||
const Gio::Application::type_vec_files &files,
|
||||
const Glib::ustring &hint) {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
for (const auto &file : files) {
|
||||
QFileOpenEvent e(
|
||||
QUrl(QString::fromStdString(file->get_uri())));
|
||||
QGuiApplication::sendEvent(qApp, &e);
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
app->add_action("quit", [] {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||
Core::Quit();
|
||||
});
|
||||
});
|
||||
|
||||
using Window::Notifications::Manager;
|
||||
using NotificationId = Manager::NotificationId;
|
||||
using NotificationIdTuple = std::invoke_result_t<
|
||||
decltype(&NotificationId::toTuple),
|
||||
NotificationId*
|
||||
>;
|
||||
|
||||
const auto notificationIdVariantType = [] {
|
||||
try {
|
||||
return base::Platform::MakeGlibVariant(
|
||||
NotificationId().toTuple()).get_type();
|
||||
} catch (...) {
|
||||
return Glib::VariantType();
|
||||
}
|
||||
}();
|
||||
|
||||
app->add_action_with_parameter(
|
||||
"notification-activate",
|
||||
notificationIdVariantType,
|
||||
[](const Glib::VariantBase ¶meter) {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
try {
|
||||
const auto &app = Core::App();
|
||||
app.notifications().manager().notificationActivated(
|
||||
NotificationId::FromTuple(
|
||||
base::Platform::GlibVariantCast<
|
||||
NotificationIdTuple
|
||||
>(parameter)));
|
||||
} catch (...) {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app->add_action_with_parameter(
|
||||
"notification-mark-as-read",
|
||||
notificationIdVariantType,
|
||||
[](const Glib::VariantBase ¶meter) {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||
try {
|
||||
const auto &app = Core::App();
|
||||
app.notifications().manager().notificationReplied(
|
||||
NotificationId::FromTuple(
|
||||
base::Platform::GlibVariantCast<
|
||||
NotificationIdTuple
|
||||
>(parameter)),
|
||||
{});
|
||||
} catch (...) {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app->run(0, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
bool GenerateDesktopFile(
|
||||
const QString &targetPath,
|
||||
const QStringList &args = {},
|
||||
bool onlyMainGroup = false,
|
||||
bool silent = false) {
|
||||
if (targetPath.isEmpty() || cExeName().isEmpty()) {
|
||||
const auto executable = ExecutablePathForShortcuts();
|
||||
if (targetPath.isEmpty() || executable.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -388,11 +225,7 @@ bool GenerateDesktopFile(
|
|||
target->set_string(
|
||||
group,
|
||||
"TryExec",
|
||||
KShell::joinArgs({
|
||||
!Core::UpdaterDisabled()
|
||||
? (cExeDir() + cExeName())
|
||||
: cExeName()
|
||||
}).replace(
|
||||
KShell::joinArgs({ executable }).replace(
|
||||
'\\',
|
||||
qstr("\\\\")).toStdString());
|
||||
}
|
||||
|
@ -400,10 +233,8 @@ bool GenerateDesktopFile(
|
|||
if (target->has_key(group, "Exec")) {
|
||||
if (group == "Desktop Entry" && !args.isEmpty()) {
|
||||
QStringList exec;
|
||||
exec.append(!Core::UpdaterDisabled()
|
||||
? (cExeDir() + cExeName())
|
||||
: cExeName());
|
||||
if (Core::Sandbox::Instance().customWorkingDir()) {
|
||||
exec.append(executable);
|
||||
if (Core::Launcher::Instance().customWorkingDir()) {
|
||||
exec.append(u"-workdir"_q);
|
||||
exec.append(cWorkingDir());
|
||||
}
|
||||
|
@ -423,10 +254,8 @@ bool GenerateDesktopFile(
|
|||
qstr("\\")));
|
||||
|
||||
if (!exec.isEmpty()) {
|
||||
exec[0] = !Core::UpdaterDisabled()
|
||||
? (cExeDir() + cExeName())
|
||||
: cExeName();
|
||||
if (Core::Sandbox::Instance().customWorkingDir()) {
|
||||
exec[0] = executable;
|
||||
if (Core::Launcher::Instance().customWorkingDir()) {
|
||||
exec.insert(1, u"-workdir"_q);
|
||||
exec.insert(2, cWorkingDir());
|
||||
}
|
||||
|
@ -479,7 +308,7 @@ bool GenerateDesktopFile(
|
|||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
hashMd5Hex(d.constData(), d.size(), md5Hash);
|
||||
|
||||
if (!Core::Sandbox::Instance().customWorkingDir()) {
|
||||
if (!Core::Launcher::Instance().customWorkingDir()) {
|
||||
const auto exePath = QFile::encodeName(
|
||||
cExeDir() + cExeName());
|
||||
hashMd5Hex(exePath.constData(), exePath.size(), md5Hash);
|
||||
|
@ -493,6 +322,55 @@ bool GenerateDesktopFile(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GenerateServiceFile(bool silent = false) {
|
||||
const auto executable = ExecutablePathForShortcuts();
|
||||
if (executable.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto targetPath = QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericDataLocation) + u"/dbus-1/services/"_q;
|
||||
|
||||
const auto targetFile = targetPath
|
||||
+ QGuiApplication::desktopFileName().chopped(8)
|
||||
+ u".service"_q;
|
||||
|
||||
DEBUG_LOG(("App Info: placing .service file to %1").arg(targetPath));
|
||||
if (!QDir(targetPath).exists()) QDir().mkpath(targetPath);
|
||||
|
||||
const auto target = Glib::KeyFile::create();
|
||||
constexpr auto group = "D-BUS Service";
|
||||
|
||||
target->set_string(
|
||||
group,
|
||||
"Name",
|
||||
QGuiApplication::desktopFileName().chopped(8).toStdString());
|
||||
|
||||
target->set_string(
|
||||
group,
|
||||
"Exec",
|
||||
KShell::joinArgs({ executable }).replace(
|
||||
'\\',
|
||||
qstr("\\\\")).toStdString());
|
||||
|
||||
try {
|
||||
target->save_to_file(targetFile.toStdString());
|
||||
} catch (const std::exception &e) {
|
||||
if (!silent) {
|
||||
LOG(("App Error: %1").arg(QString::fromStdString(e.what())));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QProcess::execute(u"systemctl"_q, {
|
||||
u"--user"_q,
|
||||
u"reload"_q,
|
||||
u"dbus"_q,
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InstallLauncher() {
|
||||
static const auto DisabledByEnv = !qEnvironmentVariableIsEmpty(
|
||||
"DESKTOPINTEGRATION");
|
||||
|
@ -506,6 +384,7 @@ void InstallLauncher() {
|
|||
QStandardPaths::ApplicationsLocation) + '/';
|
||||
|
||||
GenerateDesktopFile(applicationsPath);
|
||||
GenerateServiceFile();
|
||||
|
||||
const auto icons = QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericDataLocation) + u"/icons/"_q;
|
||||
|
@ -615,6 +494,20 @@ bool SkipTaskbarSupported() {
|
|||
return false;
|
||||
}
|
||||
|
||||
QString ExecutablePathForShortcuts() {
|
||||
if (Core::UpdaterDisabled()) {
|
||||
const auto &arguments = Core::Launcher::Instance().arguments();
|
||||
if (!arguments.isEmpty()) {
|
||||
const auto result = QFileInfo(arguments.first()).fileName();
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return cExeName();
|
||||
}
|
||||
return cExeDir() + cExeName();
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
QString psAppDataPath() {
|
||||
|
@ -676,7 +569,7 @@ void start() {
|
|||
|
||||
if (!Core::UpdaterDisabled()) {
|
||||
QByteArray md5Hash(h);
|
||||
if (!Launcher::Instance().customWorkingDir()) {
|
||||
if (!Core::Launcher::Instance().customWorkingDir()) {
|
||||
const auto exePath = QFile::encodeName(
|
||||
cExeDir() + cExeName());
|
||||
|
||||
|
@ -726,6 +619,8 @@ void start() {
|
|||
h,
|
||||
cGUIDStr(),
|
||||
u"%1"_q).toStdString());
|
||||
|
||||
InstallLauncher();
|
||||
}
|
||||
|
||||
void finish() {
|
||||
|
@ -796,17 +691,6 @@ QImage DefaultApplicationIcon() {
|
|||
namespace ThirdParty {
|
||||
|
||||
void start() {
|
||||
LOG(("Icon theme: %1").arg(QIcon::themeName()));
|
||||
LOG(("Fallback icon theme: %1").arg(QIcon::fallbackThemeName()));
|
||||
|
||||
if (!QCoreApplication::eventDispatcher()->inherits(
|
||||
"QEventDispatcherGlib")) {
|
||||
g_warning("Qt is running without GLib event loop integration, "
|
||||
"except various functionality to not to work.");
|
||||
}
|
||||
|
||||
InstallLauncher();
|
||||
LaunchGApplication();
|
||||
}
|
||||
|
||||
void finish() {
|
||||
|
|
|
@ -40,6 +40,10 @@ inline uint64 ActivationWindowId(not_null<QWidget*> window) {
|
|||
inline void ActivateOtherProcess(uint64 processId, uint64 windowId) {
|
||||
}
|
||||
|
||||
inline QString ExecutablePathForShortcuts() {
|
||||
return cExeDir() + cExeName();
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
inline void start() {
|
||||
|
|
|
@ -46,10 +46,9 @@ bool TrayIconSupported();
|
|||
bool SkipTaskbarSupported();
|
||||
void WriteCrashDumpDetails();
|
||||
void NewVersionLaunched(int oldVersion);
|
||||
|
||||
[[nodiscard]] QImage DefaultApplicationIcon();
|
||||
|
||||
[[nodiscard]] bool PreventsQuit(Core::QuitReason reason);
|
||||
[[nodiscard]] QString ExecutablePathForShortcuts();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
|
||||
[[nodiscard]] std::optional<bool> IsDarkMode();
|
||||
|
|
|
@ -42,6 +42,10 @@ void SetWindowPriority(not_null<QWidget*> window, uint32 priority);
|
|||
// Activate window with windowId (if found) or the largest priority.
|
||||
void ActivateOtherProcess(uint64 processId, uint64 windowId);
|
||||
|
||||
inline QString ExecutablePathForShortcuts() {
|
||||
return cExeDir() + cExeName();
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
void start();
|
||||
|
|
|
@ -18,7 +18,7 @@ QByteArray gAlphaPrivateKey;
|
|||
|
||||
bool gManyInstance = false;
|
||||
QString gKeyFile;
|
||||
QString gWorkingDir, gExeDir, gExeName;
|
||||
QString gWorkingDir;
|
||||
|
||||
QStringList gSendPaths;
|
||||
QString gStartUrl;
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/integration.h"
|
||||
#include "ui/style/style_core.h"
|
||||
|
||||
#define DeclareReadSetting(Type, Name) extern Type g##Name; \
|
||||
|
@ -56,11 +57,15 @@ inline void cForceWorkingDir(const QString &newDir) {
|
|||
}
|
||||
|
||||
}
|
||||
DeclareReadSetting(QString, ExeName);
|
||||
DeclareReadSetting(QString, ExeDir);
|
||||
inline QString cExeName() {
|
||||
return base::Integration::Instance().executableName();
|
||||
}
|
||||
inline QString cExeDir() {
|
||||
return base::Integration::Instance().executableDir();
|
||||
}
|
||||
DeclareSetting(QString, DialogLastPath);
|
||||
DeclareSetting(QString, DialogHelperPath);
|
||||
inline const QString &cDialogHelperPathFinal() {
|
||||
inline QString cDialogHelperPathFinal() {
|
||||
return cDialogHelperPath().isEmpty() ? cExeDir() : cDialogHelperPath();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "core/launcher.h"
|
||||
#include "core/application.h"
|
||||
#include "tray.h"
|
||||
#include "storage/localstorage.h"
|
||||
|
@ -224,7 +225,7 @@ void SetupUpdate(
|
|||
return (toggled != cInstallBetaVersion());
|
||||
}) | rpl::start_with_next([=](bool toggled) {
|
||||
cSetInstallBetaVersion(toggled);
|
||||
Core::App().writeInstallBetaVersionsSetting();
|
||||
Core::Launcher::Instance().writeInstallBetaVersionsSetting();
|
||||
|
||||
Core::UpdateChecker checker;
|
||||
checker.stop();
|
||||
|
|
|
@ -28,7 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "storage/localimageloader.h"
|
||||
#include "core/sandbox.h"
|
||||
#include "core/launcher.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "main/main_session.h"
|
||||
|
@ -138,7 +138,7 @@ void EditInfoBox::setInnerFocus() {
|
|||
}
|
||||
|
||||
uint32 OccupationTag() {
|
||||
return uint32(Core::Sandbox::Instance().installationTag() & 0xFFFFFFFF);
|
||||
return uint32(Core::Launcher::Instance().installationTag() & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
QString NormalizeName(QString name) {
|
||||
|
@ -268,7 +268,7 @@ Helper::Helper(not_null<Main::Session*> session)
|
|||
}).fail([=] {
|
||||
setSupportName(
|
||||
u"[rand^"_q
|
||||
+ QString::number(Core::Sandbox::Instance().installationTag())
|
||||
+ QString::number(Core::Launcher::Instance().installationTag())
|
||||
+ ']');
|
||||
}).send();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{%- set OPENSSL_PREFIX = "/usr/local/desktop-app/openssl-1.1.1" -%}
|
||||
{%- set CMAKE_VER = "3.26.3" -%}
|
||||
{%- set CMAKE_FILE = "cmake-" ~ CMAKE_VER ~ "-Linux-x86_64.sh" -%}
|
||||
{%- set CFLAGS_DEBUG = "-g -pipe -fPIC -fstack-protector-all -fstack-clash-protection -D_GLIBCXX_ASSERTIONS" -%}
|
||||
{%- set CFLAGS_DEBUG = "-g -pipe -fPIC -fstack-protector-all -fstack-clash-protection -fcf-protection -D_GLIBCXX_ASSERTIONS" -%}
|
||||
{%- set CFLAGS_LTO = "-flto=auto -ffat-lto-objects" -%}
|
||||
{%- set LibrariesPath = "/usr/src/Libraries" -%}
|
||||
|
||||
|
@ -52,14 +52,14 @@ FROM builder-base AS builder
|
|||
ENV AR gcc-ar
|
||||
ENV RANLIB gcc-ranlib
|
||||
ENV NM gcc-nm
|
||||
ENV CFLAGS {% if DEBUG %}-g{% endif %} -O3 {% if LTO %}{{ CFLAGS_LTO }}{% endif %} -pipe -fPIC -fstack-protector-all -fstack-clash-protection -DNDEBUG -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS
|
||||
ENV CFLAGS {% if DEBUG %}-g{% endif %} -O3 {% if LTO %}{{ CFLAGS_LTO }}{% endif %} -pipe -fPIC -fstack-protector-all -fstack-clash-protection -fcf-protection -DNDEBUG -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS
|
||||
ENV CXXFLAGS $CFLAGS
|
||||
|
||||
FROM builder AS patches
|
||||
RUN git init patches \
|
||||
&& cd patches \
|
||||
&& git remote add origin {{ GIT }}/desktop-app/patches.git \
|
||||
&& git fetch --depth=1 origin a1b912c90eaab470ef283622a8f890ee6264dae7 \
|
||||
&& git fetch --depth=1 origin 963f5b0c2a57f7e90239e64c9e14ed5f043e637e \
|
||||
&& git reset --hard FETCH_HEAD \
|
||||
&& rm -rf .git
|
||||
|
||||
|
@ -729,10 +729,6 @@ RUN git clone -b {{ QT_TAG }} --depth=1 https://code.qt.io/qt/qt5.git qt_{{ QT }
|
|||
&& git submodule update --init --recursive --depth=1 qtbase qtdeclarative qtwayland qtimageformats qtsvg qtshadertools \
|
||||
&& cd qtbase \
|
||||
&& find ../../patches/qtbase_{{ QT }} -type f -print0 | sort -z | xargs -r0 git apply \
|
||||
&& cd ../qtdeclarative \
|
||||
&& sed -i '/add_subdirectory(quickcontrols)/d' src/CMakeLists.txt \
|
||||
&& sed -i '/add_subdirectory(quickdialogs)/d' src/CMakeLists.txt \
|
||||
&& sed -i '/add_subdirectory(quicknativestyle)/d' src/CMakeLists.txt \
|
||||
&& cd .. \
|
||||
&& ./configure -prefix "{{ QT_PREFIX }}" \
|
||||
CMAKE_BUILD_TYPE=None \
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
cd Telegram
|
||||
./configure.sh "$@"
|
||||
|
|
|
@ -3,10 +3,13 @@ from os import environ
|
|||
from os.path import dirname
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
def checkEnv(envName, defaultValue):
|
||||
return bool(len(environ[envName])) if envName in environ else defaultValue
|
||||
|
||||
def main():
|
||||
print(Environment(loader=FileSystemLoader(dirname(__file__))).get_template("Dockerfile").render(
|
||||
DEBUG=bool(len(environ["DEBUG"])) if "DEBUG" in environ else True,
|
||||
LTO=bool(len(environ["LTO"])) if "LTO" in environ else True,
|
||||
DEBUG=checkEnv("DEBUG", True),
|
||||
LTO=checkEnv("LTO", True),
|
||||
))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -673,7 +673,7 @@ mac:
|
|||
|
||||
stage('dav1d', """
|
||||
win:
|
||||
git clone -b 1.0.0 --depth 1 https://code.videolan.org/videolan/dav1d.git
|
||||
git clone -b 1.2.1 --depth 1 https://code.videolan.org/videolan/dav1d.git
|
||||
cd dav1d
|
||||
depends:python/Scripts/activate.bat
|
||||
%THIRDPARTY_DIR%\\python\\Scripts\\activate.bat
|
||||
|
@ -710,7 +710,7 @@ release:
|
|||
|
||||
stage('libde265', """
|
||||
win:
|
||||
git clone --depth 1 -b v1.0.11 https://github.com/strukturag/libde265.git
|
||||
git clone --depth 1 -b v1.0.12 https://github.com/strukturag/libde265.git
|
||||
cd libde265
|
||||
cmake . ^
|
||||
-A %WIN32X64% ^
|
||||
|
@ -734,7 +734,7 @@ release:
|
|||
|
||||
stage('libheif', """
|
||||
win:
|
||||
git clone --depth 1 -b v1.15.1 https://github.com/strukturag/libheif.git
|
||||
git clone --depth 1 -b v1.16.2 https://github.com/strukturag/libheif.git
|
||||
cd libheif
|
||||
%THIRDPARTY_DIR%\\msys64\\usr\\bin\\sed.exe -i 's/LIBHEIF_EXPORTS/LIBDE265_STATIC_BUILD/g' libheif/CMakeLists.txt
|
||||
%THIRDPARTY_DIR%\\msys64\\usr\\bin\\sed.exe -i 's/HAVE_VISIBILITY/LIBHEIF_STATIC_BUILD/g' libheif/CMakeLists.txt
|
||||
|
@ -762,7 +762,7 @@ release:
|
|||
|
||||
stage('libjxl', """
|
||||
win:
|
||||
git clone -b v0.8.1 --depth 1 --recursive --shallow-submodules https://github.com/libjxl/libjxl.git
|
||||
git clone -b v0.8.2 --depth 1 --recursive --shallow-submodules https://github.com/libjxl/libjxl.git
|
||||
cd libjxl
|
||||
cmake . ^
|
||||
-A %WIN32X64% ^
|
||||
|
|
|
@ -63,20 +63,11 @@ def getOutput(command):
|
|||
sys.exit(1)
|
||||
return output.decode('utf-8')
|
||||
|
||||
def prepareSources():
|
||||
workpath = os.getcwd()
|
||||
os.chdir('../..')
|
||||
rootpath = os.getcwd()
|
||||
finalpath = rootpath + '/out/Release/sources.tar'
|
||||
if os.path.exists(finalpath):
|
||||
os.remove(finalpath)
|
||||
if os.path.exists(finalpath + '.gz'):
|
||||
os.remove(finalpath + '.gz')
|
||||
tmppath = rootpath + '/out/Release/tmp.tar'
|
||||
print('Preparing source tarball...')
|
||||
if (call(('git archive --prefix=tdesktop-' + version + '-full/ -o ' + finalpath + ' v' + version).split()) != 0):
|
||||
os.remove(finalpath)
|
||||
sys.exit(1)
|
||||
def invoke(command):
|
||||
return call(command.split()) == 0
|
||||
|
||||
def appendSubmodules(appendTo, root, rootRevision):
|
||||
startpath = os.getcwd()
|
||||
lines = getOutput('git submodule foreach').split('\n')
|
||||
for line in lines:
|
||||
if len(line) == 0:
|
||||
|
@ -84,23 +75,48 @@ def prepareSources():
|
|||
match = re.match(r"^Entering '([^']+)'$", line)
|
||||
if not match:
|
||||
print('Bad line: ' + line)
|
||||
sys.exit(1)
|
||||
return False
|
||||
path = match.group(1)
|
||||
revision = getOutput('git rev-parse v' + version + ':' + path).split('\n')[0]
|
||||
subroot = root + '/' + path
|
||||
revision = getOutput('git rev-parse ' + rootRevision + ':' + path).split('\n')[0]
|
||||
print('Adding submodule ' + path + '...')
|
||||
os.chdir(path)
|
||||
if (call(('git archive --prefix=tdesktop-' + version + '-full/' + path + '/ ' + revision + ' -o ' + tmppath).split()) != 0):
|
||||
os.remove(finalpath)
|
||||
os.remove(tmppath)
|
||||
sys.exit(1)
|
||||
if (call(('gtar --concatenate --file=' + finalpath + ' ' + tmppath).split()) != 0):
|
||||
os.remove(finalpath)
|
||||
os.remove(tmppath)
|
||||
sys.exit(1)
|
||||
os.remove(tmppath)
|
||||
os.chdir(rootpath)
|
||||
tmppath = appendTo + '_tmp'
|
||||
if not invoke('git archive --prefix=' + subroot + '/ ' + revision + ' -o ' + tmppath + '.tar'):
|
||||
os.remove(appendTo + '.tar')
|
||||
os.remove(tmppath + '.tar')
|
||||
return False
|
||||
if not appendSubmodules(tmppath, subroot, revision):
|
||||
return False
|
||||
if not invoke('gtar --concatenate --file=' + appendTo + '.tar ' + tmppath + '.tar'):
|
||||
os.remove(appendTo + '.tar')
|
||||
os.remove(tmppath + '.tar')
|
||||
return False
|
||||
os.remove(tmppath + '.tar')
|
||||
os.chdir(startpath)
|
||||
return True
|
||||
|
||||
def prepareSources():
|
||||
workpath = os.getcwd()
|
||||
os.chdir('../..')
|
||||
rootpath = os.getcwd()
|
||||
finalpart = rootpath + '/out/Release/sources'
|
||||
finalpath = finalpart + '.tar'
|
||||
if os.path.exists(finalpath):
|
||||
os.remove(finalpath)
|
||||
if os.path.exists(finalpath + '.gz'):
|
||||
os.remove(finalpath + '.gz')
|
||||
tmppath = rootpath + '/out/Release/tmp.tar'
|
||||
print('Preparing source tarball...')
|
||||
revision = 'v' + version
|
||||
targetRoot = 'tdesktop-' + version + '-full';
|
||||
if not invoke('git archive --prefix=' + targetRoot + '/ -o ' + finalpath + ' ' + revision):
|
||||
os.remove(finalpath)
|
||||
sys.exit(1)
|
||||
if not appendSubmodules(finalpart, targetRoot, revision):
|
||||
sys.exit(1)
|
||||
print('Compressing...')
|
||||
if (call(('gzip -9 ' + finalpath).split()) != 0):
|
||||
if not invoke('gzip -9 ' + finalpath):
|
||||
os.remove(finalpath)
|
||||
sys.exit(1)
|
||||
os.chdir(workpath)
|
||||
|
@ -254,12 +270,12 @@ if r.status_code == 404:
|
|||
checkResponseCode(r, 201)
|
||||
|
||||
tagname = 'v' + version
|
||||
call("git fetch origin".split())
|
||||
invoke("git fetch origin")
|
||||
if stable == 1:
|
||||
call("git push launchpad {}:master".format(tagname).split())
|
||||
invoke("git push launchpad {}:master".format(tagname))
|
||||
else:
|
||||
call("git push launchpad {}:beta".format(tagname).split())
|
||||
call("git push --tags launchpad".split())
|
||||
invoke("git push launchpad {}:beta".format(tagname))
|
||||
invoke("git push --tags launchpad")
|
||||
|
||||
r = requests.get(url + 'repos/telegramdesktop/tdesktop/releases/tags/v' + version)
|
||||
checkResponseCode(r, 200)
|
||||
|
@ -307,9 +323,8 @@ for file in files:
|
|||
checkResponseCode(r, 201)
|
||||
|
||||
print('Success! Removing.')
|
||||
return_code = call(["rm", file_path])
|
||||
if return_code != 0:
|
||||
print('Bad rm code: ' + str(return_code))
|
||||
if not invoke('rm ' + file_path):
|
||||
print('Bad rm return code :(')
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
AppVersion 4008003
|
||||
AppVersion 4008004
|
||||
AppVersionStrMajor 4.8
|
||||
AppVersionStrSmall 4.8.3
|
||||
AppVersionStr 4.8.3
|
||||
AppVersionStrSmall 4.8.4
|
||||
AppVersionStr 4.8.4
|
||||
BetaChannel 0
|
||||
AlphaVersion 0
|
||||
AppVersionOriginal 4.8.3
|
||||
AppVersionOriginal 4.8.4
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
4.8.4 (13.06.23)
|
||||
|
||||
- Fix opening links on Linux.
|
||||
|
||||
4.8.3 (31.05.23)
|
||||
|
||||
- Fix main window focus from notifications with disabled animations.
|
||||
|
|
|
@ -13,7 +13,7 @@ You will require **api_id** and **api_hash** to access the Telegram API servers.
|
|||
Go to ***BuildPath*** and run
|
||||
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
brew install git automake cmake wget pkg-config gnu-tar
|
||||
brew install git automake cmake wget pkg-config gnu-tar ninja
|
||||
|
||||
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ Categories=Chat;Network;InstantMessaging;Qt;
|
|||
MimeType=x-scheme-handler/tg;
|
||||
Keywords=tg;chat;im;messaging;messenger;sms;tdesktop;
|
||||
Actions=quit;
|
||||
DBusActivatable=true
|
||||
SingleMainWindow=true
|
||||
X-GNOME-UsesNotifications=true
|
||||
X-GNOME-SingleWindow=true
|
||||
|
|
3
lib/xdg/org.telegram.desktop.service
Normal file
3
lib/xdg/org.telegram.desktop.service
Normal file
|
@ -0,0 +1,3 @@
|
|||
[D-BUS Service]
|
||||
Name=org.telegram.desktop
|
||||
Exec=telegram-desktop
|
|
@ -28,9 +28,11 @@ apps:
|
|||
- camera
|
||||
- desktop
|
||||
- desktop-legacy
|
||||
- gsettings
|
||||
- hardware-observe
|
||||
- home
|
||||
- network
|
||||
- network-bind
|
||||
- network-status
|
||||
- opengl
|
||||
- removable-media
|
||||
|
@ -52,7 +54,6 @@ plugs:
|
|||
mount-host-font-cache: false
|
||||
# Support for common GTK themes
|
||||
# https://forum.snapcraft.io/t/how-to-use-the-system-gtk-theme-via-the-gtk-common-themes-snap/6235
|
||||
gsettings:
|
||||
gtk-3-themes:
|
||||
interface: content
|
||||
target: $SNAP/data-dir/themes
|
||||
|
|
Loading…
Add table
Reference in a new issue