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