mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Move some code around.
Move logs:SignalHandlers to core/crash_reports:CrashReports. Move all pre-launch windows to core/crash_report_window module. Move some global code to core/launcher:Launcher. It should replace settings / platform_specific module in some way.
This commit is contained in:
parent
9d4558de2b
commit
97c15865a5
Telegram
SourceFiles
apiwrap.cppapp.cppapplication.cppapplication.h
boxes
chat_helpers
core
dialogs
history
logs.cpplogs.hmain.cppmainwidget.cppmainwindow.cppmainwindow.hmedia
messenger.cppmessenger.hmtproto
platform
settings.cppsettings.hstorage
ui/text
build
gyp
@ -946,7 +946,7 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers:
|
||||
request(base::take(_stickersClearRecentRequestId)).cancel();
|
||||
|
||||
auto writeInstalled = true, writeRecent = false, writeCloudRecent = false, writeFaved = false, writeArchived = false;
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = Stickers::GetRecentPack();
|
||||
auto &sets = Auth().data().stickerSetsRef();
|
||||
|
||||
_stickersOrder = localOrder;
|
||||
|
@ -46,6 +46,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "numbers.h"
|
||||
#include "observer_peer.h"
|
||||
#include "auth_session.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
@ -472,7 +473,7 @@ namespace {
|
||||
QString pname = (showPhoneChanged || phoneChanged || nameChanged) ? ((showPhone && !phone.isEmpty()) ? formatPhone(phone) : QString()) : data->nameOrPhone;
|
||||
|
||||
if (!minimal && d.is_self() && uname != data->username) {
|
||||
SignalHandlers::setCrashAnnotation("Username", uname);
|
||||
CrashReports::SetAnnotation("Username", uname);
|
||||
}
|
||||
data->setName(fname, lname, pname, uname);
|
||||
if (d.has_photo()) {
|
||||
|
@ -26,8 +26,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/localstorage.h"
|
||||
#include "autoupdater.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "messenger.h"
|
||||
#include "base/timer.h"
|
||||
#include "core/crash_report_window.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -71,8 +73,13 @@ QString _escapeFrom7bit(const QString &str) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Application::Application(int &argc, char **argv) : QApplication(argc, argv) {
|
||||
QByteArray d(QFile::encodeName(QDir(cWorkingDir()).absolutePath()));
|
||||
Application::Application(
|
||||
not_null<Core::Launcher*> launcher,
|
||||
int &argc,
|
||||
char **argv)
|
||||
: QApplication(argc, argv)
|
||||
, _launcher(launcher) {
|
||||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
char h[33] = { 0 };
|
||||
hashMd5Hex(d.constData(), d.size(), h);
|
||||
#ifndef OS_MAC_STORE
|
||||
@ -206,12 +213,12 @@ void Application::singleInstanceChecked() {
|
||||
if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) {
|
||||
new NotStartedWindow();
|
||||
} else {
|
||||
SignalHandlers::Status status = SignalHandlers::start();
|
||||
if (status == SignalHandlers::CantOpen) {
|
||||
const auto status = CrashReports::Start();
|
||||
if (status == CrashReports::CantOpen) {
|
||||
new NotStartedWindow();
|
||||
} else if (status == SignalHandlers::LastCrashed) {
|
||||
} else if (status == CrashReports::LastCrashed) {
|
||||
if (Sandbox::LastCrashDump().isEmpty()) { // don't handle bad closing for now
|
||||
if (SignalHandlers::restart() == SignalHandlers::CantOpen) {
|
||||
if (CrashReports::Restart() == CrashReports::CantOpen) {
|
||||
new NotStartedWindow();
|
||||
} else {
|
||||
Sandbox::launch();
|
||||
@ -313,7 +320,7 @@ void Application::startApplication() {
|
||||
|
||||
void Application::createMessenger() {
|
||||
Expects(!App::quitting());
|
||||
_messengerInstance = std::make_unique<Messenger>();
|
||||
_messengerInstance = std::make_unique<Messenger>(_launcher);
|
||||
}
|
||||
|
||||
void Application::closeApplication() {
|
||||
|
@ -21,11 +21,16 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
class UpdateChecker;
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
} // namespace Core
|
||||
|
||||
class Application : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Application(int &argc, char **argv);
|
||||
Application(not_null<Core::Launcher*> launcher, int &argc, char **argv);
|
||||
|
||||
bool event(QEvent *e) override;
|
||||
|
||||
@ -55,6 +60,7 @@ private:
|
||||
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
|
||||
typedef QList<LocalClient> LocalClients;
|
||||
|
||||
not_null<Core::Launcher*> _launcher;
|
||||
std::unique_ptr<Messenger> _messengerInstance;
|
||||
|
||||
QString _localServerName, _localSocketReadData;
|
||||
|
@ -1551,13 +1551,13 @@ int StickersBox::Inner::fillSetCount(const Stickers::Set &set) const {
|
||||
auto customIt = Auth().data().stickerSets().constFind(Stickers::CustomSetId);
|
||||
if (customIt != Auth().data().stickerSets().cend()) {
|
||||
added = customIt->stickers.size();
|
||||
for_const (auto &sticker, cGetRecentStickers()) {
|
||||
for_const (auto &sticker, Stickers::GetRecentPack()) {
|
||||
if (customIt->stickers.indexOf(sticker.first) < 0) {
|
||||
++added;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
added = cGetRecentStickers().size();
|
||||
added = Stickers::GetRecentPack().size();
|
||||
}
|
||||
}
|
||||
return result + added;
|
||||
|
@ -347,7 +347,7 @@ void SetsReceived(const QVector<MTPStickerSet> &data, int32 hash) {
|
||||
}
|
||||
}
|
||||
auto writeRecent = false;
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = GetRecentPack();
|
||||
for (auto it = sets.begin(), e = sets.end(); it != e;) {
|
||||
bool installed = (it->flags & MTPDstickerSet::Flag::f_installed);
|
||||
bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured);
|
||||
@ -449,7 +449,7 @@ void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector<MTP
|
||||
}
|
||||
|
||||
auto writeRecent = false;
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = GetRecentPack();
|
||||
for (auto i = recent.begin(); i != recent.cend();) {
|
||||
if (it->stickers.indexOf(i->first) >= 0 && pack.indexOf(i->first) < 0) {
|
||||
i = recent.erase(i);
|
||||
@ -748,7 +748,7 @@ Set *FeedSetFull(const MTPmessages_StickerSet &data) {
|
||||
}
|
||||
|
||||
auto writeRecent = false;
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = GetRecentPack();
|
||||
for (auto i = recent.begin(); i != recent.cend();) {
|
||||
if (set->stickers.indexOf(i->first) >= 0 && pack.indexOf(i->first) < 0) {
|
||||
i = recent.erase(i);
|
||||
@ -816,4 +816,56 @@ QString GetSetTitle(const MTPDstickerSet &s) {
|
||||
return title;
|
||||
}
|
||||
|
||||
RecentStickerPack &GetRecentPack() {
|
||||
if (cRecentStickers().isEmpty() && !cRecentStickersPreload().isEmpty()) {
|
||||
const auto p = cRecentStickersPreload();
|
||||
cSetRecentStickersPreload(RecentStickerPreload());
|
||||
|
||||
auto &recent = cRefRecentStickers();
|
||||
recent.reserve(p.size());
|
||||
for (const auto &preloaded : p) {
|
||||
const auto document = App::document(preloaded.first);
|
||||
if (!document || !document->sticker()) continue;
|
||||
|
||||
recent.push_back(qMakePair(document, preloaded.second));
|
||||
}
|
||||
}
|
||||
return cRefRecentStickers();
|
||||
}
|
||||
|
||||
void IncrementRecentHashtag(RecentHashtagPack &recent, const QString &tag) {
|
||||
auto i = recent.begin(), e = recent.end();
|
||||
for (; i != e; ++i) {
|
||||
if (i->first == tag) {
|
||||
++i->second;
|
||||
if (qAbs(i->second) > 0x4000) {
|
||||
for (auto j = recent.begin(); j != e; ++j) {
|
||||
if (j->second > 1) {
|
||||
j->second /= 2;
|
||||
} else if (j->second > 0) {
|
||||
j->second = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i != recent.begin(); --i) {
|
||||
if (qAbs((i - 1)->second) > qAbs(i->second)) {
|
||||
break;
|
||||
}
|
||||
qSwap(*i, *(i - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == e) {
|
||||
while (recent.size() >= 64) recent.pop_back();
|
||||
recent.push_back(qMakePair(tag, 1));
|
||||
for (i = recent.end() - 1; i != recent.begin(); --i) {
|
||||
if ((i - 1)->second > i->second) {
|
||||
break;
|
||||
}
|
||||
qSwap(*i, *(i - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Stickers
|
||||
|
@ -85,4 +85,8 @@ Set *FeedSetFull(const MTPmessages_StickerSet &data);
|
||||
|
||||
QString GetSetTitle(const MTPDstickerSet &s);
|
||||
|
||||
RecentStickerPack &GetRecentPack();
|
||||
|
||||
void IncrementRecentHashtag(RecentHashtagPack &recent, const QString &tag);
|
||||
|
||||
} // namespace Stickers
|
||||
|
@ -1090,7 +1090,7 @@ void StickersListWidget::removeRecentSticker(int section, int index) {
|
||||
clearSelection();
|
||||
bool refresh = false;
|
||||
auto sticker = _mySets[section].pack[index];
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = Stickers::GetRecentPack();
|
||||
for (int32 i = 0, l = recent.size(); i < l; ++i) {
|
||||
if (recent.at(i).first == sticker) {
|
||||
recent.removeAt(i);
|
||||
@ -1302,7 +1302,7 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
|
||||
_custom.clear();
|
||||
clearSelection();
|
||||
auto &sets = Auth().data().stickerSets();
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = Stickers::GetRecentPack();
|
||||
auto customIt = sets.constFind(Stickers::CustomSetId);
|
||||
auto cloudIt = sets.constFind(Stickers::CloudRecentSetId);
|
||||
|
||||
@ -1773,7 +1773,7 @@ void StickersListWidget::removeSet(uint64 setId) {
|
||||
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetShortName(MTP_string(it->shortName)))).send();
|
||||
}
|
||||
auto writeRecent = false;
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = Stickers::GetRecentPack();
|
||||
for (auto i = recent.begin(); i != recent.cend();) {
|
||||
if (it->stickers.indexOf(i->first) >= 0) {
|
||||
i = recent.erase(i);
|
||||
|
1080
Telegram/SourceFiles/core/crash_report_window.cpp
Normal file
1080
Telegram/SourceFiles/core/crash_report_window.cpp
Normal file
File diff suppressed because it is too large
Load Diff
226
Telegram/SourceFiles/core/crash_report_window.h
Normal file
226
Telegram/SourceFiles/core/crash_report_window.h
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class PreLaunchWindow : public QWidget {
|
||||
public:
|
||||
PreLaunchWindow(QString title = QString());
|
||||
void activate();
|
||||
int basicSize() const {
|
||||
return _size;
|
||||
}
|
||||
~PreLaunchWindow();
|
||||
|
||||
static PreLaunchWindow *instance();
|
||||
|
||||
protected:
|
||||
|
||||
int _size;
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchLabel : public QLabel {
|
||||
public:
|
||||
PreLaunchLabel(QWidget *parent);
|
||||
void setText(const QString &text);
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchInput : public QLineEdit {
|
||||
public:
|
||||
PreLaunchInput(QWidget *parent, bool password = false);
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchLog : public QTextEdit {
|
||||
public:
|
||||
PreLaunchLog(QWidget *parent);
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchButton : public QPushButton {
|
||||
public:
|
||||
PreLaunchButton(QWidget *parent, bool confirm = true);
|
||||
void setText(const QString &text);
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchCheckbox : public QCheckBox {
|
||||
public:
|
||||
PreLaunchCheckbox(QWidget *parent);
|
||||
void setText(const QString &text);
|
||||
|
||||
};
|
||||
|
||||
class NotStartedWindow : public PreLaunchWindow {
|
||||
public:
|
||||
NotStartedWindow();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
void updateControls();
|
||||
|
||||
PreLaunchLabel _label;
|
||||
PreLaunchLog _log;
|
||||
PreLaunchButton _close;
|
||||
|
||||
};
|
||||
|
||||
class LastCrashedWindow : public PreLaunchWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LastCrashedWindow();
|
||||
|
||||
public slots:
|
||||
void onViewReport();
|
||||
void onSaveReport();
|
||||
void onSendReport();
|
||||
void onGetApp();
|
||||
|
||||
void onNetworkSettings();
|
||||
void onNetworkSettingsSaved(QString host, quint32 port, QString username, QString password);
|
||||
void onContinue();
|
||||
|
||||
void onCheckingFinished();
|
||||
void onSendingError(QNetworkReply::NetworkError e);
|
||||
void onSendingFinished();
|
||||
void onSendingProgress(qint64 uploaded, qint64 total);
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void onUpdateRetry();
|
||||
void onUpdateSkip();
|
||||
|
||||
void onUpdateChecking();
|
||||
void onUpdateLatest();
|
||||
void onUpdateDownloading(qint64 ready, qint64 total);
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
QString minidumpFileName();
|
||||
void updateControls();
|
||||
|
||||
QString _host, _username, _password;
|
||||
quint32 _port;
|
||||
|
||||
PreLaunchLabel _label, _pleaseSendReport, _yourReportName, _minidump;
|
||||
PreLaunchLog _report;
|
||||
PreLaunchButton _send, _sendSkip, _networkSettings, _continue, _showReport, _saveReport, _getApp;
|
||||
PreLaunchCheckbox _includeUsername;
|
||||
|
||||
QString _minidumpName, _minidumpFull, _reportText;
|
||||
QString _reportUsername, _reportTextNoUsername;
|
||||
QByteArray getCrashReportRaw() const;
|
||||
|
||||
bool _reportShown, _reportSaved;
|
||||
|
||||
void excludeReportUsername();
|
||||
|
||||
enum SendingState {
|
||||
SendingNoReport,
|
||||
SendingUpdateCheck,
|
||||
SendingNone,
|
||||
SendingTooOld,
|
||||
SendingTooMany,
|
||||
SendingUnofficial,
|
||||
SendingProgress,
|
||||
SendingUploading,
|
||||
SendingFail,
|
||||
SendingDone,
|
||||
};
|
||||
SendingState _sendingState;
|
||||
|
||||
PreLaunchLabel _updating;
|
||||
qint64 _sendingProgress, _sendingTotal;
|
||||
|
||||
QNetworkAccessManager _sendManager;
|
||||
QNetworkReply *_checkReply, *_sendReply;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
PreLaunchButton _updatingCheck, _updatingSkip;
|
||||
enum UpdatingState {
|
||||
UpdatingNone,
|
||||
UpdatingCheck,
|
||||
UpdatingLatest,
|
||||
UpdatingDownload,
|
||||
UpdatingFail,
|
||||
UpdatingReady
|
||||
};
|
||||
UpdatingState _updatingState;
|
||||
QString _newVersionDownload;
|
||||
|
||||
void setUpdatingState(UpdatingState state, bool force = false);
|
||||
void setDownloadProgress(qint64 ready, qint64 total);
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
QString getReportField(const QLatin1String &name, const QLatin1String &prefix);
|
||||
void addReportFieldPart(const QLatin1String &name, const QLatin1String &prefix, QHttpMultiPart *multipart);
|
||||
|
||||
};
|
||||
|
||||
class NetworkSettingsWindow : public PreLaunchWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NetworkSettingsWindow(QWidget *parent, QString host, quint32 port, QString username, QString password);
|
||||
|
||||
signals:
|
||||
void saved(QString host, quint32 port, QString username, QString password);
|
||||
|
||||
public slots:
|
||||
void onSave();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
void updateControls();
|
||||
|
||||
PreLaunchLabel _hostLabel, _portLabel, _usernameLabel, _passwordLabel;
|
||||
PreLaunchInput _hostInput, _portInput, _usernameInput, _passwordInput;
|
||||
PreLaunchButton _save, _cancel;
|
||||
|
||||
QWidget *_parent;
|
||||
|
||||
};
|
||||
|
||||
class ShowCrashReportWindow : public PreLaunchWindow {
|
||||
public:
|
||||
ShowCrashReportWindow(const QString &text);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
private:
|
||||
PreLaunchLog _log;
|
||||
|
||||
};
|
576
Telegram/SourceFiles/core/crash_reports.cpp
Normal file
576
Telegram/SourceFiles/core/crash_reports.cpp
Normal file
@ -0,0 +1,576 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <new>
|
||||
#include <mutex>
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
|
||||
// see https://blog.inventic.eu/2012/08/qt-and-google-breakpad/
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4091)
|
||||
#include "client/windows/handler/exception_handler.h"
|
||||
#pragma warning(pop)
|
||||
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef MAC_USE_BREAKPAD
|
||||
#include "client/mac/handler/exception_handler.h"
|
||||
#else // MAC_USE_BREAKPAD
|
||||
#include "client/crashpad_client.h"
|
||||
#endif // else for MAC_USE_BREAKPAD
|
||||
|
||||
#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 // Q_OS_MAC
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "client/linux/handler/exception_handler.h"
|
||||
|
||||
#endif // Q_OS_LINUX64 || Q_OS_LINUX32
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
|
||||
namespace CrashReports {
|
||||
namespace {
|
||||
|
||||
using Annotations = std::map<std::string, std::string>;
|
||||
using AnnotationRefs = std::map<std::string, const QString*>;
|
||||
|
||||
Annotations ProcessAnnotations;
|
||||
AnnotationRefs ProcessAnnotationRefs;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
|
||||
QString ReportPath;
|
||||
FILE *ReportFile = nullptr;
|
||||
int ReportFileNo = 0;
|
||||
char LaunchedDateTimeStr[32] = { 0 };
|
||||
char LaunchedBinaryName[256] = { 0 };
|
||||
|
||||
void SafeWriteChar(char ch) {
|
||||
fwrite(&ch, 1, 1, ReportFile);
|
||||
}
|
||||
|
||||
template <bool Unsigned, typename Type>
|
||||
struct writeNumberSignAndRemoveIt {
|
||||
static void call(Type &number) {
|
||||
if (number < 0) {
|
||||
SafeWriteChar('-');
|
||||
number = -number;
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename Type>
|
||||
struct writeNumberSignAndRemoveIt<true, Type> {
|
||||
static void call(Type &number) {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
const dump &SafeWriteNumber(const dump &stream, Type number) {
|
||||
if (!ReportFile) return stream;
|
||||
|
||||
writeNumberSignAndRemoveIt<(Type(-1) > Type(0)), Type>::call(number);
|
||||
Type upper = 1, prev = number / 10;
|
||||
while (prev >= upper) {
|
||||
upper *= 10;
|
||||
}
|
||||
while (upper > 0) {
|
||||
int digit = (number / upper);
|
||||
SafeWriteChar('0' + digit);
|
||||
number -= digit * upper;
|
||||
upper /= 10;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
using ReservedMemoryChunk = std::array<gsl::byte, 1024 * 1024>;
|
||||
std::unique_ptr<ReservedMemoryChunk> ReservedMemory;
|
||||
|
||||
void InstallOperatorNewHandler() {
|
||||
ReservedMemory = std::make_unique<ReservedMemoryChunk>();
|
||||
std::set_new_handler([] {
|
||||
std::set_new_handler(nullptr);
|
||||
ReservedMemory.reset();
|
||||
Unexpected("Could not allocate!");
|
||||
});
|
||||
}
|
||||
|
||||
Qt::HANDLE ReportingThreadId = nullptr;
|
||||
bool ReportingHeaderWritten = false;
|
||||
QMutex ReportingMutex;
|
||||
|
||||
const char *BreakpadDumpPath = nullptr;
|
||||
const wchar_t *BreakpadDumpPathW = nullptr;
|
||||
|
||||
#if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
||||
struct sigaction SIG_def[32];
|
||||
|
||||
void SignalHandler(int signum, siginfo_t *info, void *ucontext) {
|
||||
if (signum > 0) {
|
||||
sigaction(signum, &SIG_def[signum], 0);
|
||||
}
|
||||
|
||||
#else // Q_OS_MAC || Q_OS_LINUX32 || Q_OS_LINUX64
|
||||
void SignalHandler(int signum) {
|
||||
#endif // else for Q_OS_MAC || Q_OS_LINUX || Q_OS_LINUX64
|
||||
|
||||
const char* name = 0;
|
||||
switch (signum) {
|
||||
case SIGABRT: name = "SIGABRT"; break;
|
||||
case SIGSEGV: name = "SIGSEGV"; break;
|
||||
case SIGILL: name = "SIGILL"; break;
|
||||
case SIGFPE: name = "SIGFPE"; break;
|
||||
#ifndef Q_OS_WIN
|
||||
case SIGBUS: name = "SIGBUS"; break;
|
||||
case SIGSYS: name = "SIGSYS"; break;
|
||||
#endif // !Q_OS_WIN
|
||||
}
|
||||
|
||||
Qt::HANDLE thread = QThread::currentThreadId();
|
||||
if (thread == ReportingThreadId) return;
|
||||
|
||||
QMutexLocker lock(&ReportingMutex);
|
||||
ReportingThreadId = thread;
|
||||
|
||||
if (!ReportingHeaderWritten) {
|
||||
ReportingHeaderWritten = true;
|
||||
auto dec2hex = [](int value) -> char {
|
||||
if (value >= 0 && value < 10) {
|
||||
return '0' + value;
|
||||
} else if (value >= 10 && value < 16) {
|
||||
return 'a' + (value - 10);
|
||||
}
|
||||
return '#';
|
||||
};
|
||||
|
||||
for (const auto &i : ProcessAnnotationRefs) {
|
||||
QByteArray utf8 = i.second->toUtf8();
|
||||
std::string wrapped;
|
||||
wrapped.reserve(4 * utf8.size());
|
||||
for (auto ch : utf8) {
|
||||
auto uch = static_cast<uchar>(ch);
|
||||
wrapped.append("\\x", 2).append(1, dec2hex(uch >> 4)).append(1, dec2hex(uch & 0x0F));
|
||||
}
|
||||
ProcessAnnotations[i.first] = wrapped;
|
||||
}
|
||||
|
||||
const Annotations c_ProcessAnnotations(ProcessAnnotations);
|
||||
for (const auto &i : c_ProcessAnnotations) {
|
||||
dump() << i.first.c_str() << ": " << i.second.c_str() << "\n";
|
||||
}
|
||||
psWriteDump();
|
||||
dump() << "\n";
|
||||
}
|
||||
if (name) {
|
||||
dump() << "Caught signal " << signum << " (" << name << ") in thread " << uint64(thread) << "\n";
|
||||
} else if (signum == -1) {
|
||||
dump() << "Google Breakpad caught a crash, minidump written in thread " << uint64(thread) << "\n";
|
||||
if (BreakpadDumpPath) {
|
||||
dump() << "Minidump: " << BreakpadDumpPath << "\n";
|
||||
} else if (BreakpadDumpPathW) {
|
||||
dump() << "Minidump: " << BreakpadDumpPathW << "\n";
|
||||
}
|
||||
} else {
|
||||
dump() << "Caught signal " << signum << " in thread " << uint64(thread) << "\n";
|
||||
}
|
||||
|
||||
// see https://github.com/benbjohnson/bandicoot
|
||||
#if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
||||
ucontext_t *uc = (ucontext_t*)ucontext;
|
||||
|
||||
void *caller = 0;
|
||||
if (uc) {
|
||||
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
|
||||
/* OSX < 10.6 */
|
||||
#if defined(__x86_64__)
|
||||
caller = (void*)uc->uc_mcontext->__ss.__rip;
|
||||
#elif defined(__i386__)
|
||||
caller = (void*)uc->uc_mcontext->__ss.__eip;
|
||||
#else
|
||||
caller = (void*)uc->uc_mcontext->__ss.__srr0;
|
||||
#endif
|
||||
#elif defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
|
||||
/* OSX >= 10.6 */
|
||||
#if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
|
||||
caller = (void*)uc->uc_mcontext->__ss.__rip;
|
||||
#else
|
||||
caller = (void*)uc->uc_mcontext->__ss.__eip;
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
/* Linux */
|
||||
#if defined(__i386__)
|
||||
caller = (void*)uc->uc_mcontext.gregs[14]; /* Linux 32 */
|
||||
#elif defined(__X86_64__) || defined(__x86_64__)
|
||||
caller = (void*)uc->uc_mcontext.gregs[16]; /* Linux 64 */
|
||||
#elif defined(__ia64__) /* Linux IA64 */
|
||||
caller = (void*)uc->uc_mcontext.sc_ip;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void *addresses[132] = { 0 };
|
||||
size_t size = backtrace(addresses, 128);
|
||||
|
||||
/* overwrite sigaction with caller's address */
|
||||
if (caller) {
|
||||
for (int i = size; i > 1; --i) {
|
||||
addresses[i + 3] = addresses[i];
|
||||
}
|
||||
addresses[2] = (void*)0x1;
|
||||
addresses[3] = caller;
|
||||
addresses[4] = (void*)0x1;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
dump() << "\nBase image addresses:\n";
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
Dl_info info;
|
||||
dump() << i << " ";
|
||||
if (dladdr(addresses[i], &info)) {
|
||||
dump() << uint64(info.dli_fbase) << " (" << info.dli_fname << ")\n";
|
||||
} else {
|
||||
dump() << "_unknown_module_\n";
|
||||
}
|
||||
}
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
dump() << "\nBacktrace:\n";
|
||||
|
||||
backtrace_symbols_fd(addresses, size, ReportFileNo);
|
||||
|
||||
#else // Q_OS_MAC || Q_OS_LINUX32 || Q_OS_LINUX64
|
||||
dump() << "\nBacktrace:\n";
|
||||
|
||||
psWriteStackTrace();
|
||||
#endif // else for Q_OS_MAC || Q_OS_LINUX32 || Q_OS_LINUX64
|
||||
|
||||
dump() << "\n";
|
||||
|
||||
ReportingThreadId = nullptr;
|
||||
}
|
||||
|
||||
bool SetSignalHandlers = true;
|
||||
bool CrashLogged = false;
|
||||
#if !defined Q_OS_MAC || defined MAC_USE_BREAKPAD
|
||||
google_breakpad::ExceptionHandler* BreakpadExceptionHandler = 0;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
bool DumpCallback(const wchar_t* _dump_dir, const wchar_t* _minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool success)
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
bool DumpCallback(const char* _dump_dir, const char* _minidump_id, void *context, bool success)
|
||||
#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 // Q_OS_MAC
|
||||
bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context, bool success)
|
||||
#endif // Q_OS_LINUX64 || Q_OS_LINUX32
|
||||
{
|
||||
if (CrashLogged) return success;
|
||||
CrashLogged = true;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
BreakpadDumpPathW = _minidump_id;
|
||||
SignalHandler(-1);
|
||||
#else // Q_OS_WIN
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
BreakpadDumpPath = _minidump_id;
|
||||
#else // Q_OS_MAC
|
||||
BreakpadDumpPath = md.path();
|
||||
#endif // else for Q_OS_MAC
|
||||
SignalHandler(-1, 0, 0);
|
||||
#endif // else for Q_OS_WIN
|
||||
return success;
|
||||
}
|
||||
#endif // !Q_OS_MAC || MAC_USE_BREAKPAD
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
|
||||
} // namespace
|
||||
|
||||
void StartCatching() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
ProcessAnnotations["Binary"] = cExeName().toUtf8().constData();
|
||||
ProcessAnnotations["ApiId"] = QString::number(ApiId).toUtf8().constData();
|
||||
ProcessAnnotations["Version"] = (cBetaVersion() ? qsl("%1 beta").arg(cBetaVersion()) : (cAlphaVersion() ? qsl("%1 alpha") : qsl("%1")).arg(AppVersion)).toUtf8().constData();
|
||||
ProcessAnnotations["Launched"] = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss").toUtf8().constData();
|
||||
ProcessAnnotations["Platform"] = cPlatformString().toUtf8().constData();
|
||||
ProcessAnnotations["UserTag"] = QString::number(Sandbox::UserTag(), 16).toUtf8().constData();
|
||||
|
||||
QString dumpspath = cWorkingDir() + qsl("tdata/dumps");
|
||||
QDir().mkpath(dumpspath);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
BreakpadExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
dumpspath.toStdWString(),
|
||||
google_breakpad::ExceptionHandler::FilterCallback(nullptr),
|
||||
DumpCallback,
|
||||
(void*)nullptr, // callback_context
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL,
|
||||
MINIDUMP_TYPE(MiniDumpNormal),
|
||||
// MINIDUMP_TYPE(MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithThreadInfo | MiniDumpWithProcessThreadData | MiniDumpWithFullMemoryInfo | MiniDumpWithUnloadedModules | MiniDumpWithFullAuxiliaryState | MiniDumpIgnoreInaccessibleMemory | MiniDumpWithTokenInformation),
|
||||
(const wchar_t*)nullptr, // pipe_name
|
||||
(const google_breakpad::CustomClientInfo*)nullptr
|
||||
);
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
|
||||
#ifdef MAC_USE_BREAKPAD
|
||||
#ifndef _DEBUG
|
||||
BreakpadExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
QFile::encodeName(dumpspath).toStdString(),
|
||||
/*FilterCallback*/ 0,
|
||||
DumpCallback,
|
||||
/*context*/ 0,
|
||||
true,
|
||||
0
|
||||
);
|
||||
#endif // !_DEBUG
|
||||
SetSignalHandlers = false;
|
||||
#else // MAC_USE_BREAKPAD
|
||||
crashpad::CrashpadClient crashpad_client;
|
||||
std::string handler = (cExeDir() + cExeName() + qsl("/Contents/Helpers/crashpad_handler")).toUtf8().constData();
|
||||
std::string database = QFile::encodeName(dumpspath).constData();
|
||||
if (crashpad_client.StartHandler(base::FilePath(handler),
|
||||
base::FilePath(database),
|
||||
std::string(),
|
||||
ProcessAnnotations,
|
||||
std::vector<std::string>(),
|
||||
false)) {
|
||||
crashpad_client.UseHandler();
|
||||
}
|
||||
#endif // else for MAC_USE_BREAKPAD
|
||||
#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32
|
||||
BreakpadExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
google_breakpad::MinidumpDescriptor(QFile::encodeName(dumpspath).toStdString()),
|
||||
/*FilterCallback*/ 0,
|
||||
DumpCallback,
|
||||
/*context*/ 0,
|
||||
true,
|
||||
-1
|
||||
);
|
||||
#endif // Q_OS_LINUX64 || Q_OS_LINUX32
|
||||
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
}
|
||||
|
||||
void FinishCatching() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
#if !defined Q_OS_MAC || defined MAC_USE_BREAKPAD
|
||||
|
||||
delete base::take(BreakpadExceptionHandler);
|
||||
|
||||
#endif // !Q_OS_MAC || MAC_USE_BREAKPAD
|
||||
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
}
|
||||
|
||||
Status Start() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
ReportPath = cWorkingDir() + qsl("tdata/working");
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
FILE *f = nullptr;
|
||||
if (_wfopen_s(&f, ReportPath.toStdWString().c_str(), L"rb") != 0) {
|
||||
f = nullptr;
|
||||
} else {
|
||||
#else // !Q_OS_WIN
|
||||
if (FILE *f = fopen(QFile::encodeName(ReportPath).constData(), "rb")) {
|
||||
#endif // else for !Q_OS_WIN
|
||||
QByteArray lastdump;
|
||||
char buffer[256 * 1024] = { 0 };
|
||||
int32 read = fread(buffer, 1, 256 * 1024, f);
|
||||
if (read > 0) {
|
||||
lastdump.append(buffer, read);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
Sandbox::SetLastCrashDump(lastdump);
|
||||
|
||||
LOG(("Opened '%1' for reading, the previous Telegram Desktop launch was not finished properly :( Crash log size: %2").arg(ReportPath).arg(lastdump.size()));
|
||||
|
||||
return LastCrashed;
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
return Restart();
|
||||
}
|
||||
|
||||
Status Restart() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
if (ReportFile) {
|
||||
return Started;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (_wfopen_s(&ReportFile, ReportPath.toStdWString().c_str(), L"wb") != 0) {
|
||||
ReportFile = nullptr;
|
||||
}
|
||||
#else // Q_OS_WIN
|
||||
ReportFile = fopen(QFile::encodeName(ReportPath).constData(), "wb");
|
||||
#endif // else for Q_OS_WIN
|
||||
if (ReportFile) {
|
||||
#ifdef Q_OS_WIN
|
||||
ReportFileNo = _fileno(ReportFile);
|
||||
#else // Q_OS_WIN
|
||||
ReportFileNo = fileno(ReportFile);
|
||||
#endif // else for Q_OS_WIN
|
||||
if (SetSignalHandlers) {
|
||||
#ifndef Q_OS_WIN
|
||||
struct sigaction sigact;
|
||||
|
||||
sigact.sa_sigaction = SignalHandler;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
|
||||
|
||||
sigaction(SIGABRT, &sigact, &SIG_def[SIGABRT]);
|
||||
sigaction(SIGSEGV, &sigact, &SIG_def[SIGSEGV]);
|
||||
sigaction(SIGILL, &sigact, &SIG_def[SIGILL]);
|
||||
sigaction(SIGFPE, &sigact, &SIG_def[SIGFPE]);
|
||||
sigaction(SIGBUS, &sigact, &SIG_def[SIGBUS]);
|
||||
sigaction(SIGSYS, &sigact, &SIG_def[SIGSYS]);
|
||||
#else // !Q_OS_WIN
|
||||
signal(SIGABRT, SignalHandler);
|
||||
signal(SIGSEGV, SignalHandler);
|
||||
signal(SIGILL, SignalHandler);
|
||||
signal(SIGFPE, SignalHandler);
|
||||
#endif // else for !Q_OS_WIN
|
||||
}
|
||||
|
||||
InstallOperatorNewHandler();
|
||||
|
||||
return Started;
|
||||
}
|
||||
|
||||
LOG(("FATAL: Could not open '%1' for writing!").arg(ReportPath));
|
||||
|
||||
return CantOpen;
|
||||
#else // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
return Started;
|
||||
#endif // else for !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
}
|
||||
|
||||
void Finish() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
FinishCatching();
|
||||
|
||||
if (ReportFile) {
|
||||
fclose(ReportFile);
|
||||
ReportFile = nullptr;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
_wunlink(ReportPath.toStdWString().c_str());
|
||||
#else // Q_OS_WIN
|
||||
unlink(ReportPath.toUtf8().constData());
|
||||
#endif // else for Q_OS_WIN
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
}
|
||||
|
||||
void SetAnnotation(const std::string &key, const QString &value) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker lock(&mutex);
|
||||
|
||||
if (!value.trimmed().isEmpty()) {
|
||||
ProcessAnnotations[key] = value.toUtf8().constData();
|
||||
} else {
|
||||
ProcessAnnotations.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
void SetAnnotationRef(const std::string &key, const QString *valuePtr) {
|
||||
if (valuePtr) {
|
||||
ProcessAnnotationRefs[key] = valuePtr;
|
||||
} else {
|
||||
ProcessAnnotationRefs.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
dump::~dump() {
|
||||
if (ReportFile) {
|
||||
fflush(ReportFile);
|
||||
}
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, const char *str) {
|
||||
if (!ReportFile) return stream;
|
||||
|
||||
fwrite(str, 1, strlen(str), ReportFile);
|
||||
return stream;
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, const wchar_t *str) {
|
||||
if (!ReportFile) return stream;
|
||||
|
||||
for (int i = 0, l = wcslen(str); i < l; ++i) {
|
||||
if (str[i] >= 0 && str[i] < 128) {
|
||||
SafeWriteChar(char(str[i]));
|
||||
} else {
|
||||
SafeWriteChar('?');
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, int num) {
|
||||
return SafeWriteNumber(stream, num);
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, unsigned int num) {
|
||||
return SafeWriteNumber(stream, num);
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, unsigned long num) {
|
||||
return SafeWriteNumber(stream, num);
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, unsigned long long num) {
|
||||
return SafeWriteNumber(stream, num);
|
||||
}
|
||||
|
||||
const dump &operator<<(const dump &stream, double num) {
|
||||
if (num < 0) {
|
||||
SafeWriteChar('-');
|
||||
num = -num;
|
||||
}
|
||||
SafeWriteNumber(stream, uint64(floor(num)));
|
||||
SafeWriteChar('.');
|
||||
num -= floor(num);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
num *= 10;
|
||||
int digit = int(floor(num));
|
||||
SafeWriteChar('0' + digit);
|
||||
num -= digit;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // namespace CrashReports
|
81
Telegram/SourceFiles/core/crash_reports.h
Normal file
81
Telegram/SourceFiles/core/crash_reports.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace CrashReports {
|
||||
|
||||
struct dump {
|
||||
~dump();
|
||||
};
|
||||
const dump &operator<<(const dump &stream, const char *str);
|
||||
const dump &operator<<(const dump &stream, const wchar_t *str);
|
||||
const dump &operator<<(const dump &stream, int num);
|
||||
const dump &operator<<(const dump &stream, unsigned int num);
|
||||
const dump &operator<<(const dump &stream, unsigned long num);
|
||||
const dump &operator<<(const dump &stream, unsigned long long num);
|
||||
const dump &operator<<(const dump &stream, double num);
|
||||
|
||||
enum Status {
|
||||
CantOpen,
|
||||
LastCrashed,
|
||||
Started
|
||||
};
|
||||
Status Start();
|
||||
Status Restart(); // can be only CantOpen or Started
|
||||
void Finish();
|
||||
|
||||
void SetAnnotation(const std::string &key, const QString &value);
|
||||
inline void ClearAnnotation(const std::string &key) {
|
||||
SetAnnotation(key, QString());
|
||||
}
|
||||
|
||||
// Remembers value pointer and tries to add the value to the crash report.
|
||||
// Attention! You should call clearCrashAnnotationRef(key) before destroying value.
|
||||
void SetAnnotationRef(const std::string &key, const QString *valuePtr);
|
||||
inline void ClearAnnotationRef(const std::string &key) {
|
||||
SetAnnotationRef(key, nullptr);
|
||||
}
|
||||
|
||||
void StartCatching();
|
||||
void FinishCatching();
|
||||
|
||||
} // namespace CrashReports
|
||||
|
||||
namespace base {
|
||||
namespace assertion {
|
||||
|
||||
inline void log(const char *message, const char *file, int line) {
|
||||
const auto info = QStringLiteral("%1 %2:%3"
|
||||
).arg(message
|
||||
).arg(file
|
||||
).arg(line
|
||||
);
|
||||
const auto entry = QStringLiteral("Assertion Failed! ") + info;
|
||||
|
||||
#ifdef LOG
|
||||
LOG((entry));
|
||||
#endif // LOG
|
||||
|
||||
CrashReports::SetAnnotation("Assertion", info);
|
||||
}
|
||||
|
||||
} // namespace assertion
|
||||
} // namespace base
|
106
Telegram/SourceFiles/core/launcher.cpp
Normal file
106
Telegram/SourceFiles/core/launcher.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/launcher.h"
|
||||
|
||||
#include "platform/platform_launcher.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "application.h"
|
||||
|
||||
namespace Core {
|
||||
namespace {
|
||||
|
||||
QStringList ReadArguments(int argc, char *argv[]) {
|
||||
auto result = QStringList();
|
||||
result.reserve(argc);
|
||||
for (auto i = 0; i != argc; ++i) {
|
||||
result.push_back(fromUtf8Safe(argv[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Launcher> Launcher::Create(int argc, char *argv[]) {
|
||||
return std::make_unique<Platform::Launcher>(argc, argv);
|
||||
}
|
||||
|
||||
Launcher::Launcher(int argc, char *argv[])
|
||||
: _argc(argc)
|
||||
, _argv(argv)
|
||||
, _arguments(ReadArguments(argc, argv)) {
|
||||
InitFromCommandLine(argc, argv);
|
||||
}
|
||||
|
||||
void Launcher::init() {
|
||||
QCoreApplication::setApplicationName(qsl("TelegramDesktop"));
|
||||
|
||||
#ifndef OS_MAC_OLD
|
||||
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true);
|
||||
#endif // OS_MAC_OLD
|
||||
|
||||
initHook();
|
||||
}
|
||||
|
||||
int Launcher::exec() {
|
||||
init();
|
||||
|
||||
if (cLaunchMode() == LaunchModeFixPrevious) {
|
||||
return psFixPrevious();
|
||||
} else if (cLaunchMode() == LaunchModeCleanup) {
|
||||
return psCleanup();
|
||||
}
|
||||
|
||||
// both are finished in Application::closeApplication
|
||||
Logs::start(this); // must be started before Platform is started
|
||||
Platform::start(); // must be started before QApplication is created
|
||||
|
||||
auto result = 0;
|
||||
{
|
||||
Application app(this, _argc, _argv);
|
||||
result = app.exec();
|
||||
}
|
||||
|
||||
DEBUG_LOG(("Telegram finished, result: %1").arg(result));
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (cRestartingUpdate()) {
|
||||
DEBUG_LOG(("Application Info: executing updater to install update..."));
|
||||
psExecUpdater();
|
||||
} else
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (cRestarting()) {
|
||||
DEBUG_LOG(("Application Info: executing Telegram, because of restart..."));
|
||||
psExecTelegram();
|
||||
}
|
||||
|
||||
CrashReports::Finish();
|
||||
Platform::finish();
|
||||
Logs::finish();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString Launcher::argumentsString() const {
|
||||
return _arguments.join(' ');
|
||||
}
|
||||
|
||||
} // namespace Core
|
45
Telegram/SourceFiles/core/launcher.h
Normal file
45
Telegram/SourceFiles/core/launcher.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
|
||||
class Launcher {
|
||||
public:
|
||||
Launcher(int argc, char *argv[]);
|
||||
|
||||
static std::unique_ptr<Launcher> Create(int argc, char *argv[]);
|
||||
|
||||
int exec();
|
||||
|
||||
QString argumentsString() const;
|
||||
|
||||
private:
|
||||
void init();
|
||||
virtual void initHook() = 0;
|
||||
|
||||
int _argc;
|
||||
char **_argv;
|
||||
QStringList _arguments;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Core
|
@ -36,6 +36,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "apiwrap.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "observer_peer.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "auth_session.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/window_controller.h"
|
||||
@ -2123,7 +2124,7 @@ void DialogsInner::saveRecentHashtags(const QString &text) {
|
||||
recent = cRecentSearchHashtags();
|
||||
}
|
||||
found = true;
|
||||
incrementRecentHashtag(recent, text.mid(i + 1, next - i - 1));
|
||||
Stickers::IncrementRecentHashtag(recent, text.mid(i + 1, next - i - 1));
|
||||
}
|
||||
if (found) {
|
||||
cSetRecentSearchHashtags(recent);
|
||||
|
@ -38,6 +38,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
#include "data/data_channel_admins.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -1499,7 +1500,7 @@ void History::addToSharedMedia(std::vector<MsgId> (&medias)[kSharedMediaTypeCoun
|
||||
}
|
||||
value.push_back(indices.join(","));
|
||||
}
|
||||
SignalHandlers::setCrashAnnotation("full", value.join(";"));
|
||||
CrashReports::SetAnnotation("full", value.join(";"));
|
||||
Assert(!"History desync caught!");
|
||||
//// Logging
|
||||
|
||||
@ -1631,11 +1632,11 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice) {
|
||||
|
||||
logged.push_back(QString::number(minAdded));
|
||||
logged.push_back(QString::number(maxAdded));
|
||||
SignalHandlers::setCrashAnnotation("old_minmaxwas_minmaxadd", logged.join(";"));
|
||||
CrashReports::SetAnnotation("old_minmaxwas_minmaxadd", logged.join(";"));
|
||||
|
||||
addBlockToSharedMedia(block);
|
||||
|
||||
SignalHandlers::setCrashAnnotation("old_minmaxwas_minmaxadd", "");
|
||||
CrashReports::ClearAnnotation("old_minmaxwas_minmaxadd");
|
||||
|
||||
if (isChannel()) {
|
||||
asChannelHistory()->checkJoinedMessage();
|
||||
@ -1693,7 +1694,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice) {
|
||||
}
|
||||
logged.push_back(QString::number(minAdded));
|
||||
logged.push_back(QString::number(maxAdded));
|
||||
SignalHandlers::setCrashAnnotation("new_minmaxwas_minmaxadd", logged.join(";"));
|
||||
CrashReports::SetAnnotation("new_minmaxwas_minmaxadd", logged.join(";"));
|
||||
|
||||
if (!atLeastOneAdded) {
|
||||
newLoaded = true;
|
||||
@ -1701,7 +1702,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice) {
|
||||
}
|
||||
addToSharedMedia(medias, wasLoadedAtBottom != loadedAtBottom());
|
||||
|
||||
SignalHandlers::setCrashAnnotation("new_minmaxwas_minmaxadd", "");
|
||||
CrashReports::ClearAnnotation("new_minmaxwas_minmaxadd");
|
||||
}
|
||||
|
||||
if (!wasLoadedAtBottom) {
|
||||
|
@ -79,6 +79,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "inline_bots/inline_results_widget.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -2292,7 +2293,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
|
||||
if (_preloadRequest == requestId) {
|
||||
auto to = toMigrated ? _migrated : _history;
|
||||
if (cBetaVersion()) {
|
||||
SignalHandlers::setCrashAnnotation("old_debugstr", QString(
|
||||
CrashReports::SetAnnotation("old_debugstr", QString(
|
||||
"%1_%2_%3_%4:%5_%6 (%7)"
|
||||
).arg(PeerString(_debug_preloadDownPeer)
|
||||
).arg(_debug_preloadOffsetId
|
||||
@ -2307,7 +2308,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
|
||||
addMessagesToFront(peer, *histList);
|
||||
|
||||
if (cBetaVersion()) {
|
||||
SignalHandlers::setCrashAnnotation("old_debugstr", QString());
|
||||
CrashReports::ClearAnnotation("old_debugstr");
|
||||
}
|
||||
|
||||
_preloadRequest = 0;
|
||||
@ -2319,7 +2320,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
|
||||
} else if (_preloadDownRequest == requestId) {
|
||||
auto to = toMigrated ? _migrated : _history;
|
||||
if (cBetaVersion()) {
|
||||
SignalHandlers::setCrashAnnotation("new_debugstr", QString(
|
||||
CrashReports::SetAnnotation("new_debugstr", QString(
|
||||
"%1_%2_%3_%4:%5_%6 (%7)"
|
||||
).arg(PeerString(_debug_preloadDownPeer)
|
||||
).arg(_debug_preloadDownOffsetId
|
||||
@ -2334,7 +2335,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
|
||||
addMessagesToBack(peer, *histList);
|
||||
|
||||
if (cBetaVersion()) {
|
||||
SignalHandlers::setCrashAnnotation("new_debugstr", QString());
|
||||
CrashReports::ClearAnnotation("new_debugstr");
|
||||
}
|
||||
|
||||
_preloadDownRequest = 0;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,60 +20,61 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class MTPlong;
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
} // namespace Core
|
||||
|
||||
namespace Logs {
|
||||
|
||||
void start();
|
||||
bool started();
|
||||
void finish();
|
||||
void start(not_null<Core::Launcher*> launcher);
|
||||
bool started();
|
||||
void finish();
|
||||
|
||||
bool instanceChecked();
|
||||
void multipleInstances();
|
||||
bool instanceChecked();
|
||||
void multipleInstances();
|
||||
|
||||
void closeMain();
|
||||
void closeMain();
|
||||
|
||||
void writeMain(const QString &v);
|
||||
void writeMain(const QString &v);
|
||||
|
||||
void writeDebug(const char *file, int32 line, const QString &v);
|
||||
void writeTcp(const QString &v);
|
||||
void writeMtp(int32 dc, const QString &v);
|
||||
void writeDebug(const char *file, int32 line, const QString &v);
|
||||
void writeTcp(const QString &v);
|
||||
void writeMtp(int32 dc, const QString &v);
|
||||
|
||||
QString full();
|
||||
|
||||
inline const char *b(bool v) {
|
||||
return v ? "[TRUE]" : "[FALSE]";
|
||||
}
|
||||
|
||||
struct MemoryBuffer {
|
||||
MemoryBuffer(const void *ptr, uint32 size) : p(ptr), s(size) {
|
||||
}
|
||||
QString str() const {
|
||||
QString result;
|
||||
const uchar *buf((const uchar*)p);
|
||||
const char *hex = "0123456789ABCDEF";
|
||||
result.reserve(s * 3);
|
||||
for (uint32 i = 0; i < s; ++i) {
|
||||
result += hex[(buf[i] >> 4)];
|
||||
result += hex[buf[i] & 0x0F];
|
||||
result += ' ';
|
||||
}
|
||||
result.chop(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
const void *p;
|
||||
uint32 s;
|
||||
};
|
||||
|
||||
inline MemoryBuffer mb(const void *ptr, uint32 size) {
|
||||
return MemoryBuffer(ptr, size);
|
||||
}
|
||||
|
||||
QString vector(const QVector<MTPlong> &ids);
|
||||
QString vector(const QVector<uint64> &ids);
|
||||
QString full();
|
||||
|
||||
inline const char *b(bool v) {
|
||||
return v ? "[TRUE]" : "[FALSE]";
|
||||
}
|
||||
|
||||
struct MemoryBuffer {
|
||||
MemoryBuffer(const void *ptr, uint32 size) : p(ptr), s(size) {
|
||||
}
|
||||
QString str() const {
|
||||
QString result;
|
||||
const uchar *buf((const uchar*)p);
|
||||
const char *hex = "0123456789ABCDEF";
|
||||
result.reserve(s * 3);
|
||||
for (uint32 i = 0; i < s; ++i) {
|
||||
result += hex[(buf[i] >> 4)];
|
||||
result += hex[buf[i] & 0x0F];
|
||||
result += ' ';
|
||||
}
|
||||
result.chop(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
const void *p;
|
||||
uint32 s;
|
||||
|
||||
};
|
||||
|
||||
inline MemoryBuffer mb(const void *ptr, uint32 size) {
|
||||
return MemoryBuffer(ptr, size);
|
||||
}
|
||||
|
||||
} // namespace Logs
|
||||
|
||||
#define LOG(msg) (Logs::writeMain(QString msg))
|
||||
//usage LOG(("log: %1 %2").arg(1).arg(2))
|
||||
|
||||
@ -85,47 +86,3 @@ namespace Logs {
|
||||
|
||||
#define MTP_LOG(dc, msg) { if (cDebug() || !Logs::started()) Logs::writeMtp(dc, QString msg); }
|
||||
//usage MTP_LOG(dc, ("log: %1 %2").arg(1).arg(2))
|
||||
|
||||
namespace SignalHandlers {
|
||||
|
||||
struct dump {
|
||||
~dump();
|
||||
};
|
||||
const dump &operator<<(const dump &stream, const char *str);
|
||||
const dump &operator<<(const dump &stream, const wchar_t *str);
|
||||
const dump &operator<<(const dump &stream, int num);
|
||||
const dump &operator<<(const dump &stream, unsigned int num);
|
||||
const dump &operator<<(const dump &stream, unsigned long num);
|
||||
const dump &operator<<(const dump &stream, unsigned long long num);
|
||||
const dump &operator<<(const dump &stream, double num);
|
||||
enum Status {
|
||||
CantOpen,
|
||||
LastCrashed,
|
||||
Started
|
||||
};
|
||||
Status start();
|
||||
Status restart(); // can be only CantOpen or Started
|
||||
void finish();
|
||||
|
||||
void setCrashAnnotation(const std::string &key, const QString &value);
|
||||
|
||||
// Remembers value pointer and tries to add the value to the crash report.
|
||||
// Attention! You should call clearCrashAnnotationRef(key) before destroying value.
|
||||
void setCrashAnnotationRef(const std::string &key, const QString *valuePtr);
|
||||
inline void clearCrashAnnotationRef(const std::string &key) {
|
||||
setCrashAnnotationRef(key, nullptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace base {
|
||||
namespace assertion {
|
||||
|
||||
inline void log(const char *message, const char *file, int line) {
|
||||
auto info = QStringLiteral("%1 %2:%3").arg(message).arg(file).arg(line);
|
||||
LOG(("Assertion Failed! ") + info);
|
||||
SignalHandlers::setCrashAnnotation("Assertion", info);
|
||||
}
|
||||
|
||||
} // namespace assertion
|
||||
} // namespace base
|
||||
|
@ -18,49 +18,9 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "application.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "core/launcher.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
#ifndef Q_OS_MAC // Retina display support is working fine, others are not.
|
||||
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true);
|
||||
#endif // Q_OS_MAC
|
||||
QCoreApplication::setApplicationName(qsl("TelegramDesktop"));
|
||||
|
||||
InitFromCommandLine(argc, argv);
|
||||
if (cLaunchMode() == LaunchModeFixPrevious) {
|
||||
return psFixPrevious();
|
||||
} else if (cLaunchMode() == LaunchModeCleanup) {
|
||||
return psCleanup();
|
||||
}
|
||||
|
||||
// both are finished in Application::closeApplication
|
||||
Logs::start(); // must be started before Platform is started
|
||||
Platform::start(); // must be started before QApplication is created
|
||||
|
||||
int result = 0;
|
||||
{
|
||||
Application app(argc, argv);
|
||||
result = app.exec();
|
||||
}
|
||||
|
||||
DEBUG_LOG(("Telegram finished, result: %1").arg(result));
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (cRestartingUpdate()) {
|
||||
DEBUG_LOG(("Application Info: executing updater to install update..."));
|
||||
psExecUpdater();
|
||||
} else
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (cRestarting()) {
|
||||
DEBUG_LOG(("Application Info: executing Telegram, because of restart..."));
|
||||
psExecTelegram();
|
||||
}
|
||||
|
||||
SignalHandlers::finish();
|
||||
Platform::finish();
|
||||
Logs::finish();
|
||||
|
||||
return result;
|
||||
const auto launcher = Core::Launcher::Create(argc, argv);
|
||||
return launcher ? launcher->exec() : 1;
|
||||
}
|
||||
|
@ -1574,7 +1574,7 @@ void MainWidget::saveRecentHashtags(const QString &text) {
|
||||
recent = cRecentWriteHashtags();
|
||||
}
|
||||
found = true;
|
||||
incrementRecentHashtag(recent, text.mid(i + 1, next - i - 1));
|
||||
Stickers::IncrementRecentHashtag(recent, text.mid(i + 1, next - i - 1));
|
||||
}
|
||||
if (found) {
|
||||
cSetRecentWriteHashtags(recent);
|
||||
@ -4389,7 +4389,7 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
|
||||
|
||||
// Remove that sticker from old recent, now it is in cloud recent stickers.
|
||||
bool writeOldRecent = false;
|
||||
auto &recent = cGetRecentStickers();
|
||||
auto &recent = Stickers::GetRecentPack();
|
||||
for (auto i = recent.begin(), e = recent.end(); i != e; ++i) {
|
||||
if (i->first == sticker) {
|
||||
writeOldRecent = true;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -224,219 +224,3 @@ private:
|
||||
Local::ClearManager *_clearManager = nullptr;
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchWindow : public TWidget {
|
||||
public:
|
||||
|
||||
PreLaunchWindow(QString title = QString());
|
||||
void activate();
|
||||
int basicSize() const {
|
||||
return _size;
|
||||
}
|
||||
~PreLaunchWindow();
|
||||
|
||||
static PreLaunchWindow *instance();
|
||||
|
||||
protected:
|
||||
|
||||
int _size;
|
||||
|
||||
};
|
||||
|
||||
class PreLaunchLabel : public QLabel {
|
||||
public:
|
||||
PreLaunchLabel(QWidget *parent);
|
||||
void setText(const QString &text);
|
||||
};
|
||||
|
||||
class PreLaunchInput : public QLineEdit {
|
||||
public:
|
||||
PreLaunchInput(QWidget *parent, bool password = false);
|
||||
};
|
||||
|
||||
class PreLaunchLog : public QTextEdit {
|
||||
public:
|
||||
PreLaunchLog(QWidget *parent);
|
||||
};
|
||||
|
||||
class PreLaunchButton : public QPushButton {
|
||||
public:
|
||||
PreLaunchButton(QWidget *parent, bool confirm = true);
|
||||
void setText(const QString &text);
|
||||
};
|
||||
|
||||
class PreLaunchCheckbox : public QCheckBox {
|
||||
public:
|
||||
PreLaunchCheckbox(QWidget *parent);
|
||||
void setText(const QString &text);
|
||||
};
|
||||
|
||||
class NotStartedWindow : public PreLaunchWindow {
|
||||
public:
|
||||
|
||||
NotStartedWindow();
|
||||
|
||||
protected:
|
||||
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
|
||||
void updateControls();
|
||||
|
||||
PreLaunchLabel _label;
|
||||
PreLaunchLog _log;
|
||||
PreLaunchButton _close;
|
||||
|
||||
};
|
||||
|
||||
class LastCrashedWindow : public PreLaunchWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
LastCrashedWindow();
|
||||
|
||||
public slots:
|
||||
|
||||
void onViewReport();
|
||||
void onSaveReport();
|
||||
void onSendReport();
|
||||
void onGetApp();
|
||||
|
||||
void onNetworkSettings();
|
||||
void onNetworkSettingsSaved(QString host, quint32 port, QString username, QString password);
|
||||
void onContinue();
|
||||
|
||||
void onCheckingFinished();
|
||||
void onSendingError(QNetworkReply::NetworkError e);
|
||||
void onSendingFinished();
|
||||
void onSendingProgress(qint64 uploaded, qint64 total);
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void onUpdateRetry();
|
||||
void onUpdateSkip();
|
||||
|
||||
void onUpdateChecking();
|
||||
void onUpdateLatest();
|
||||
void onUpdateDownloading(qint64 ready, qint64 total);
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
protected:
|
||||
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
|
||||
QString minidumpFileName();
|
||||
void updateControls();
|
||||
|
||||
QString _host, _username, _password;
|
||||
quint32 _port;
|
||||
|
||||
PreLaunchLabel _label, _pleaseSendReport, _yourReportName, _minidump;
|
||||
PreLaunchLog _report;
|
||||
PreLaunchButton _send, _sendSkip, _networkSettings, _continue, _showReport, _saveReport, _getApp;
|
||||
PreLaunchCheckbox _includeUsername;
|
||||
|
||||
QString _minidumpName, _minidumpFull, _reportText;
|
||||
QString _reportUsername, _reportTextNoUsername;
|
||||
QByteArray getCrashReportRaw() const;
|
||||
|
||||
bool _reportShown, _reportSaved;
|
||||
|
||||
void excludeReportUsername();
|
||||
|
||||
enum SendingState {
|
||||
SendingNoReport,
|
||||
SendingUpdateCheck,
|
||||
SendingNone,
|
||||
SendingTooOld,
|
||||
SendingTooMany,
|
||||
SendingUnofficial,
|
||||
SendingProgress,
|
||||
SendingUploading,
|
||||
SendingFail,
|
||||
SendingDone,
|
||||
};
|
||||
SendingState _sendingState;
|
||||
|
||||
PreLaunchLabel _updating;
|
||||
qint64 _sendingProgress, _sendingTotal;
|
||||
|
||||
QNetworkAccessManager _sendManager;
|
||||
QNetworkReply *_checkReply, *_sendReply;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
PreLaunchButton _updatingCheck, _updatingSkip;
|
||||
enum UpdatingState {
|
||||
UpdatingNone,
|
||||
UpdatingCheck,
|
||||
UpdatingLatest,
|
||||
UpdatingDownload,
|
||||
UpdatingFail,
|
||||
UpdatingReady
|
||||
};
|
||||
UpdatingState _updatingState;
|
||||
QString _newVersionDownload;
|
||||
|
||||
void setUpdatingState(UpdatingState state, bool force = false);
|
||||
void setDownloadProgress(qint64 ready, qint64 total);
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
QString getReportField(const QLatin1String &name, const QLatin1String &prefix);
|
||||
void addReportFieldPart(const QLatin1String &name, const QLatin1String &prefix, QHttpMultiPart *multipart);
|
||||
|
||||
};
|
||||
|
||||
class NetworkSettingsWindow : public PreLaunchWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
NetworkSettingsWindow(QWidget *parent, QString host, quint32 port, QString username, QString password);
|
||||
|
||||
signals:
|
||||
|
||||
void saved(QString host, quint32 port, QString username, QString password);
|
||||
|
||||
public slots:
|
||||
|
||||
void onSave();
|
||||
|
||||
protected:
|
||||
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
|
||||
void updateControls();
|
||||
|
||||
PreLaunchLabel _hostLabel, _portLabel, _usernameLabel, _passwordLabel;
|
||||
PreLaunchInput _hostInput, _portInput, _usernameInput, _passwordInput;
|
||||
PreLaunchButton _save, _cancel;
|
||||
|
||||
QWidget *_parent;
|
||||
|
||||
};
|
||||
|
||||
class ShowCrashReportWindow : public PreLaunchWindow {
|
||||
public:
|
||||
|
||||
ShowCrashReportWindow(const QString &text);
|
||||
|
||||
protected:
|
||||
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
private:
|
||||
|
||||
PreLaunchLog _log;
|
||||
|
||||
};
|
||||
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "media/media_audio_ffmpeg_loader.h"
|
||||
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr AVSampleFormat AudioToFormat = AV_SAMPLE_FMT_S16;
|
||||
@ -423,7 +425,7 @@ AudioPlayerLoader::ReadResult FFMpegLoader::readFromReadyFrame(QByteArray &resul
|
||||
).arg(ptrdiff_t(frame->extended_data[0])
|
||||
).arg(ptrdiff_t(frame->data[1])
|
||||
);
|
||||
SignalHandlers::setCrashAnnotation(key, value);
|
||||
CrashReports::SetAnnotation(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,7 +437,7 @@ AudioPlayerLoader::ReadResult FFMpegLoader::readFromReadyFrame(QByteArray &resul
|
||||
|
||||
if (frame->extended_data[1] == nullptr) {
|
||||
const auto key = "ffmpeg_" + std::to_string(ptrdiff_t(this));
|
||||
SignalHandlers::setCrashAnnotation(key, QString());
|
||||
CrashReports::ClearAnnotation(key);
|
||||
}
|
||||
|
||||
int32 resultLen = av_samples_get_buffer_size(0, AudioToChannels, res, AudioToFormat, 1);
|
||||
|
@ -75,7 +75,9 @@ struct Messenger::Private {
|
||||
base::Timer quitTimer;
|
||||
};
|
||||
|
||||
Messenger::Messenger() : QObject()
|
||||
Messenger::Messenger(not_null<Core::Launcher*> launcher)
|
||||
: QObject()
|
||||
, _launcher(launcher)
|
||||
, _private(std::make_unique<Private>())
|
||||
, _langpack(std::make_unique<Lang::Instance>())
|
||||
, _audio(std::make_unique<Media::Audio::Instance>())
|
||||
|
@ -24,6 +24,17 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "mtproto/auth_key.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
class AuthSession;
|
||||
class AuthSessionData;
|
||||
class MainWidget;
|
||||
class FileUploader;
|
||||
class Translator;
|
||||
class MediaView;
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
} // namespace Core
|
||||
|
||||
namespace App {
|
||||
void quit();
|
||||
} // namespace App
|
||||
@ -36,13 +47,6 @@ using AuthKeyPtr = std::shared_ptr<AuthKey>;
|
||||
using AuthKeysList = std::vector<AuthKeyPtr>;
|
||||
} // namespace MTP
|
||||
|
||||
class AuthSession;
|
||||
class AuthSessionData;
|
||||
class MainWidget;
|
||||
class FileUploader;
|
||||
class Translator;
|
||||
class MediaView;
|
||||
|
||||
namespace Media {
|
||||
namespace Audio {
|
||||
class Instance;
|
||||
@ -59,13 +63,17 @@ class Messenger final : public QObject, public RPCSender, private base::Subscrib
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Messenger();
|
||||
Messenger(not_null<Core::Launcher*> launcher);
|
||||
|
||||
Messenger(const Messenger &other) = delete;
|
||||
Messenger &operator=(const Messenger &other) = delete;
|
||||
|
||||
~Messenger();
|
||||
|
||||
not_null<Core::Launcher*> launcher() const {
|
||||
return _launcher;
|
||||
}
|
||||
|
||||
// Windows interface.
|
||||
MainWindow *getActiveWindow() const;
|
||||
bool closeActiveWindow();
|
||||
@ -220,6 +228,8 @@ private:
|
||||
|
||||
void loggedOut();
|
||||
|
||||
not_null<Core::Launcher*> _launcher;
|
||||
|
||||
QMap<FullMsgId, PeerId> photoUpdates;
|
||||
|
||||
QMap<MTP::DcId, TimeMs> killDownloadSessionTimes;
|
||||
|
@ -45,6 +45,15 @@ constexpr auto kMaxModExpSize = 256;
|
||||
// Don't try to handle messages larger than this size.
|
||||
constexpr auto kMaxMessageLength = 16 * 1024 * 1024;
|
||||
|
||||
QString LogIdsVector(const QVector<MTPlong> &ids) {
|
||||
if (!ids.size()) return "[]";
|
||||
auto idsStr = QString("[%1").arg(ids.cbegin()->v);
|
||||
for (const auto &id : ids) {
|
||||
idsStr += QString(", %2").arg(id.v);
|
||||
}
|
||||
return idsStr + "]";
|
||||
}
|
||||
|
||||
bool IsGoodModExpFirst(const openssl::BigNum &modexp, const openssl::BigNum &prime) {
|
||||
auto diff = prime - modexp;
|
||||
if (modexp.failed() || prime.failed() || diff.failed()) {
|
||||
@ -1432,7 +1441,7 @@ void ConnectionPrivate::handleReceived() {
|
||||
// send acks
|
||||
uint32 toAckSize = ackRequestData.size();
|
||||
if (toAckSize) {
|
||||
DEBUG_LOG(("MTP Info: will send %1 acks, ids: %2").arg(toAckSize).arg(Logs::vector(ackRequestData)));
|
||||
DEBUG_LOG(("MTP Info: will send %1 acks, ids: %2").arg(toAckSize).arg(LogIdsVector(ackRequestData)));
|
||||
emit sendAnythingAsync(MTPAckSendWaiting);
|
||||
}
|
||||
|
||||
@ -1546,7 +1555,7 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
|
||||
auto &ids = msg.c_msgs_ack().vmsg_ids.v;
|
||||
uint32 idsCount = ids.size();
|
||||
|
||||
DEBUG_LOG(("Message Info: acks received, ids: %1").arg(Logs::vector(ids)));
|
||||
DEBUG_LOG(("Message Info: acks received, ids: %1").arg(LogIdsVector(ids)));
|
||||
if (!idsCount) return (badTime ? HandleResult::Ignored : HandleResult::Success);
|
||||
|
||||
if (badTime) {
|
||||
@ -1676,7 +1685,7 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
|
||||
msg.read(from, end);
|
||||
auto &ids = msg.c_msgs_state_req().vmsg_ids.v;
|
||||
auto idsCount = ids.size();
|
||||
DEBUG_LOG(("Message Info: msgs_state_req received, ids: %1").arg(Logs::vector(ids)));
|
||||
DEBUG_LOG(("Message Info: msgs_state_req received, ids: %1").arg(LogIdsVector(ids)));
|
||||
if (!idsCount) return HandleResult::Success;
|
||||
|
||||
QByteArray info(idsCount, Qt::Uninitialized);
|
||||
@ -1787,7 +1796,7 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
|
||||
|
||||
QVector<MTPlong> toAck;
|
||||
|
||||
DEBUG_LOG(("Message Info: msgs all info received, msgId %1, reqMsgIds: %2, states %3").arg(msgId).arg(Logs::vector(ids)).arg(Logs::mb(states.data(), states.length()).str()));
|
||||
DEBUG_LOG(("Message Info: msgs all info received, msgId %1, reqMsgIds: %2, states %3").arg(msgId).arg(LogIdsVector(ids)).arg(Logs::mb(states.data(), states.length()).str()));
|
||||
handleMsgsStates(ids, states, toAck);
|
||||
|
||||
requestsAcked(toAck);
|
||||
@ -1856,7 +1865,7 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
|
||||
auto &ids = msg.c_msg_resend_req().vmsg_ids.v;
|
||||
|
||||
auto idsCount = ids.size();
|
||||
DEBUG_LOG(("Message Info: resend of msgs requested, ids: %1").arg(Logs::vector(ids)));
|
||||
DEBUG_LOG(("Message Info: resend of msgs requested, ids: %1").arg(LogIdsVector(ids)));
|
||||
if (!idsCount) return (badTime ? HandleResult::Ignored : HandleResult::Success);
|
||||
|
||||
QVector<quint64> toResend(ids.size());
|
||||
@ -2087,7 +2096,7 @@ bool ConnectionPrivate::requestsFixTimeSalt(const QVector<MTPlong> &ids, int32 s
|
||||
void ConnectionPrivate::requestsAcked(const QVector<MTPlong> &ids, bool byResponse) {
|
||||
uint32 idsCount = ids.size();
|
||||
|
||||
DEBUG_LOG(("Message Info: requests acked, ids %1").arg(Logs::vector(ids)));
|
||||
DEBUG_LOG(("Message Info: requests acked, ids %1").arg(LogIdsVector(ids)));
|
||||
|
||||
RPCCallbackClears clearedAcked;
|
||||
QVector<MTPlong> toAckMore;
|
||||
|
@ -246,7 +246,7 @@ mtpRequestId Session::send(const TRequest &request, RPCResponseHandler callbacks
|
||||
sendPrepared(reqSerialized, msCanWait);
|
||||
} catch (Exception &e) {
|
||||
requestId = 0;
|
||||
rpcErrorOccured(requestId, callbacks.onFail, rpcClientError("NO_REQUEST_ID", QString("send() failed to queue request, exception: %1").arg(e.what())));
|
||||
requestPrepareFailed(callbacks.onFail, e);
|
||||
}
|
||||
if (requestId) registerRequest(requestId, toMainDC ? -getDcWithShift() : getDcWithShift());
|
||||
return requestId;
|
||||
|
@ -23,9 +23,22 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "mtproto/connection.h"
|
||||
#include "mtproto/dcenter.h"
|
||||
#include "mtproto/auth_key.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
namespace MTP {
|
||||
namespace internal {
|
||||
namespace {
|
||||
|
||||
QString LogIds(const QVector<uint64> &ids) {
|
||||
if (!ids.size()) return "[]";
|
||||
auto idsStr = QString("[%1").arg(*ids.cbegin());
|
||||
for (const auto id : ids) {
|
||||
idsStr += QString(", %2").arg(id);
|
||||
}
|
||||
return idsStr + "]";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SessionData::setKey(const AuthKeyPtr &key) {
|
||||
if (_authKey != key) {
|
||||
@ -140,6 +153,23 @@ bool Session::rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &o
|
||||
return _instance->rpcErrorOccured(requestId, onFail, err);
|
||||
}
|
||||
|
||||
void Session::requestPrepareFailed(
|
||||
const RPCFailHandlerPtr &onFail,
|
||||
Exception &e) {
|
||||
CrashReports::SetAnnotation("RequestException", QString::fromLatin1(e.what()));
|
||||
Unexpected("Exception in Session::send()");
|
||||
|
||||
const auto requestId = 0;
|
||||
const auto error = rpcClientError(
|
||||
"NO_REQUEST_ID",
|
||||
QString(
|
||||
"send() failed to queue request, exception: %1"
|
||||
).arg(
|
||||
e.what()
|
||||
));
|
||||
rpcErrorOccured(requestId, onFail, error);
|
||||
}
|
||||
|
||||
void Session::restart() {
|
||||
if (_killed) {
|
||||
DEBUG_LOG(("Session Error: can't restart a killed session"));
|
||||
@ -271,7 +301,7 @@ void Session::checkRequestsByTimer() {
|
||||
}
|
||||
|
||||
if (stateRequestIds.size()) {
|
||||
DEBUG_LOG(("MTP Info: requesting state of msgs: %1").arg(Logs::vector(stateRequestIds)));
|
||||
DEBUG_LOG(("MTP Info: requesting state of msgs: %1").arg(LogIds(stateRequestIds)));
|
||||
{
|
||||
QWriteLocker locker(data.stateRequestMutex());
|
||||
for (uint32 i = 0, l = stateRequestIds.size(); i < l; ++i) {
|
||||
|
@ -356,6 +356,7 @@ private:
|
||||
mtpRequestId storeRequest(mtpRequest &request, const RPCResponseHandler &parser);
|
||||
mtpRequest getRequest(mtpRequestId requestId);
|
||||
bool rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err);
|
||||
void requestPrepareFailed(const RPCFailHandlerPtr &onFail, Exception &e);
|
||||
|
||||
not_null<Instance*> _instance;
|
||||
std::unique_ptr<Connection> _connection;
|
||||
|
28
Telegram/SourceFiles/platform/linux/launcher_linux.cpp
Normal file
28
Telegram/SourceFiles/platform/linux/launcher_linux.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "platform/linux/launcher_linux.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
void Launcher::initHook() {
|
||||
}
|
||||
|
||||
} // namespace
|
36
Telegram/SourceFiles/platform/linux/launcher_linux.h
Normal file
36
Telegram/SourceFiles/platform/linux/launcher_linux.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/launcher.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
class Launcher : public Core::Launcher {
|
||||
public:
|
||||
using Core::Launcher::Launcher;
|
||||
|
||||
private:
|
||||
void initHook() override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Platform
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "platform/linux/file_utilities_linux.h"
|
||||
#include "platform/platform_notifications_manager.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -598,7 +599,7 @@ bool _execUpdater(bool update = true, const QString &crashreport = QString()) {
|
||||
}
|
||||
|
||||
Logs::closeMain();
|
||||
SignalHandlers::finish();
|
||||
CrashReports::Finish();
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1: return false;
|
||||
|
36
Telegram/SourceFiles/platform/mac/launcher_mac.h
Normal file
36
Telegram/SourceFiles/platform/mac/launcher_mac.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/launcher.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
class Launcher : public Core::Launcher {
|
||||
public:
|
||||
using Core::Launcher::Launcher;
|
||||
|
||||
private:
|
||||
void initHook() override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Platform
|
32
Telegram/SourceFiles/platform/mac/launcher_mac.mm
Normal file
32
Telegram/SourceFiles/platform/mac/launcher_mac.mm
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "platform/mac/launcher_mac.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
void Launcher::initHook() {
|
||||
#ifndef OS_MAC_OLD
|
||||
// macOS Retina display support is working fine, others are not.
|
||||
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false);
|
||||
#endif // OS_MAC_OLD
|
||||
}
|
||||
|
||||
} // namespace Platform
|
@ -17,19 +17,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "platform/mac/specific_mac.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "application.h"
|
||||
#include "mainwidget.h"
|
||||
#include "history/history_widget.h"
|
||||
|
||||
#include "core/crash_reports.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "passcodewidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "history/history_location_manager.h"
|
||||
#include "platform/mac/mac_utilities.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
@ -92,7 +91,7 @@ QAbstractNativeEventFilter *psNativeEventFilter() {
|
||||
|
||||
void psWriteDump() {
|
||||
double v = objc_appkitVersion();
|
||||
SignalHandlers::dump() << "OS-Version: " << v;
|
||||
CrashReports::dump() << "OS-Version: " << v;
|
||||
}
|
||||
|
||||
QString demanglestr(const QString &mangled) {
|
||||
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "styles/style_window.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "base/timer.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <CoreFoundation/CFURL.h>
|
||||
@ -441,7 +442,7 @@ BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) {
|
||||
|
||||
DEBUG_LOG(("Application Info: executing %1 %2").arg(NS2QString(path)).arg(NS2QString([args componentsJoinedByString:@" "])));
|
||||
Logs::closeMain();
|
||||
SignalHandlers::finish();
|
||||
CrashReports::Finish();
|
||||
if (![NSTask launchedTaskWithLaunchPath:path arguments:args]) {
|
||||
DEBUG_LOG(("Task not launched while executing %1 %2").arg(NS2QString(path)).arg(NS2QString([args componentsJoinedByString:@" "])));
|
||||
return NO;
|
||||
|
43
Telegram/SourceFiles/platform/platform_launcher.h
Normal file
43
Telegram/SourceFiles/platform/platform_launcher.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Platform {
|
||||
|
||||
//class Launcher : public Core::Launcher {
|
||||
//public:
|
||||
// using Core::Launcher::Launcher;
|
||||
//
|
||||
// ...
|
||||
//
|
||||
//};
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
// Platform dependent implementations.
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "platform/mac/launcher_mac.h"
|
||||
#elif defined Q_OS_LINUX // Q_OS_MAC
|
||||
#include "platform/linux/launcher_linux.h"
|
||||
#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
||||
#include "platform/win/launcher_win.h"
|
||||
#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN
|
28
Telegram/SourceFiles/platform/win/launcher_win.cpp
Normal file
28
Telegram/SourceFiles/platform/win/launcher_win.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "platform/win/launcher_win.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
void Launcher::initHook() {
|
||||
}
|
||||
|
||||
} // namespace
|
36
Telegram/SourceFiles/platform/win/launcher_win.h
Normal file
36
Telegram/SourceFiles/platform/win/launcher_win.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/launcher.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
class Launcher : public Core::Launcher {
|
||||
public:
|
||||
using Core::Launcher::Launcher;
|
||||
|
||||
private:
|
||||
void initHook() override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Platform
|
@ -32,6 +32,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/localstorage.h"
|
||||
#include "passcodewidget.h"
|
||||
#include "base/task_queue.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
#include <Shobjidl.h>
|
||||
#include <shellapi.h>
|
||||
@ -687,7 +688,7 @@ void psExecTelegram(const QString &crashreport) {
|
||||
|
||||
DEBUG_LOG(("Application Info: executing %1 %2").arg(cExeDir() + cExeName()).arg(targs));
|
||||
Logs::closeMain();
|
||||
SignalHandlers::finish();
|
||||
CrashReports::Finish();
|
||||
HINSTANCE r = ShellExecute(0, 0, telegram.toStdWString().c_str(), targs.toStdWString().c_str(), wdir.isEmpty() ? 0 : wdir.toStdWString().c_str(), SW_SHOWNORMAL);
|
||||
if (long(r) < 32) {
|
||||
DEBUG_LOG(("Application Error: failed to execute %1, working directory: '%2', result: %3").arg(telegram).arg(wdir).arg(long(r)));
|
||||
@ -1291,7 +1292,7 @@ QString psPrepareCrashDump(const QByteArray &crashdump, QString dumpfile) {
|
||||
void psWriteStackTrace() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
if (!LoadDbgHelp()) {
|
||||
SignalHandlers::dump() << "ERROR: Could not load dbghelp.dll!\n";
|
||||
CrashReports::dump() << "ERROR: Could not load dbghelp.dll!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1348,17 +1349,17 @@ void psWriteStackTrace() {
|
||||
// deeper frame could not be found.
|
||||
// CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386!
|
||||
if (!stackWalk64(imageType, hProcess, hThread, &s, &c, ReadProcessMemoryRoutine64, symFunctionTableAccess64, symGetModuleBase64, NULL)) {
|
||||
SignalHandlers::dump() << "ERROR: Call to StackWalk64() failed!\n";
|
||||
CrashReports::dump() << "ERROR: Call to StackWalk64() failed!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (s.AddrPC.Offset == s.AddrReturn.Offset) {
|
||||
SignalHandlers::dump() << s.AddrPC.Offset << "\n";
|
||||
SignalHandlers::dump() << "ERROR: StackWalk64() endless callstack!";
|
||||
CrashReports::dump() << s.AddrPC.Offset << "\n";
|
||||
CrashReports::dump() << "ERROR: StackWalk64() endless callstack!";
|
||||
return;
|
||||
}
|
||||
if (s.AddrPC.Offset != 0) { // we seem to have a valid PC
|
||||
SignalHandlers::dump() << s.AddrPC.Offset << "\n";
|
||||
CrashReports::dump() << s.AddrPC.Offset << "\n";
|
||||
}
|
||||
|
||||
if (s.AddrReturn.Offset == 0) {
|
||||
|
@ -20,14 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "settings.h"
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
#include "data/data_document.h"
|
||||
|
||||
bool gRtl = false;
|
||||
Qt::LayoutDirection gLangDir = gRtl ? Qt::RightToLeft : Qt::LeftToRight;
|
||||
|
||||
QString gArguments;
|
||||
|
||||
bool gAlphaVersion = AppAlphaVersion;
|
||||
uint64 gBetaVersion = AppBetaVersion;
|
||||
uint64 gRealBetaVersion = AppBetaVersion;
|
||||
@ -168,7 +163,8 @@ void ParseCommandLineArguments(const QStringList &arguments) {
|
||||
gKeyFile = parseResult.value("-key", QStringList()).join(QString());
|
||||
gLaunchMode = parseResult.contains("-autostart") ? LaunchModeAutoStart
|
||||
: parseResult.contains("-fixprevious") ? LaunchModeFixPrevious
|
||||
: parseResult.contains("-cleanup") ? LaunchModeCleanup : LaunchModeNormal;
|
||||
: parseResult.contains("-cleanup") ? LaunchModeCleanup
|
||||
: LaunchModeNormal;
|
||||
gNoStartUpdate = parseResult.contains("-noupdate");
|
||||
gStartToSettings = parseResult.contains("-tosettings");
|
||||
gStartInTray = parseResult.contains("-startintray");
|
||||
@ -182,13 +178,11 @@ void ParseCommandLineArguments(const QStringList &arguments) {
|
||||
|
||||
void InitFromCommandLine(int argc, char *argv[]) {
|
||||
Expects(argc >= 0);
|
||||
|
||||
auto arguments = QStringList();
|
||||
arguments.reserve(argc);
|
||||
for (auto i = 0; i != argc; ++i) {
|
||||
arguments.push_back(fromUtf8Safe(argv[i]));
|
||||
}
|
||||
gArguments = arguments.join(' ');
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#ifndef OS_MAC_OLD
|
||||
@ -252,20 +246,3 @@ void InitFromCommandLine(int argc, char *argv[]) {
|
||||
|
||||
ParseCommandLineArguments(arguments);
|
||||
}
|
||||
|
||||
RecentStickerPack &cGetRecentStickers() {
|
||||
if (cRecentStickers().isEmpty() && !cRecentStickersPreload().isEmpty()) {
|
||||
RecentStickerPreload p(cRecentStickersPreload());
|
||||
cSetRecentStickersPreload(RecentStickerPreload());
|
||||
|
||||
RecentStickerPack &recent(cRefRecentStickers());
|
||||
recent.reserve(p.size());
|
||||
for (RecentStickerPreload::const_iterator i = p.cbegin(), e = p.cend(); i != e; ++i) {
|
||||
DocumentData *doc = App::document(i->first);
|
||||
if (!doc || !doc->sticker()) continue;
|
||||
|
||||
recent.push_back(qMakePair(doc, i->second));
|
||||
}
|
||||
}
|
||||
return cRefRecentStickers();
|
||||
}
|
||||
|
@ -20,8 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
void InitFromCommandLine(int argc, char *argv[]);
|
||||
|
||||
extern bool gDebug;
|
||||
inline bool cDebug() {
|
||||
#if defined _DEBUG
|
||||
@ -55,8 +53,6 @@ inline bool rtl() {
|
||||
return cRtl();
|
||||
}
|
||||
|
||||
DeclareReadSetting(QString, Arguments);
|
||||
|
||||
DeclareSetting(bool, AlphaVersion);
|
||||
DeclareSetting(uint64, BetaVersion);
|
||||
DeclareSetting(uint64, RealBetaVersion);
|
||||
@ -169,15 +165,13 @@ DeclareRefSetting(EmojiColorVariants, EmojiVariants);
|
||||
|
||||
class DocumentData;
|
||||
|
||||
typedef QList<QPair<DocumentData*, int16> > RecentStickerPackOld;
|
||||
typedef QVector<QPair<uint64, ushort> > RecentStickerPreload;
|
||||
typedef QVector<QPair<DocumentData*, ushort> > RecentStickerPack;
|
||||
typedef QList<QPair<DocumentData*, int16>> RecentStickerPackOld;
|
||||
typedef QVector<QPair<uint64, ushort>> RecentStickerPreload;
|
||||
typedef QVector<QPair<DocumentData*, ushort>> RecentStickerPack;
|
||||
DeclareSetting(RecentStickerPreload, RecentStickersPreload);
|
||||
DeclareRefSetting(RecentStickerPack, RecentStickers);
|
||||
|
||||
RecentStickerPack &cGetRecentStickers();
|
||||
|
||||
typedef QList<QPair<QString, ushort> > RecentHashtagPack;
|
||||
typedef QList<QPair<QString, ushort>> RecentHashtagPack;
|
||||
DeclareRefSetting(RecentHashtagPack, RecentWriteHashtags);
|
||||
DeclareSetting(RecentHashtagPack, RecentSearchHashtags);
|
||||
|
||||
@ -203,41 +197,6 @@ inline bool passcodeCanTry() {
|
||||
return dt >= 30000;
|
||||
}
|
||||
|
||||
inline void incrementRecentHashtag(RecentHashtagPack &recent, const QString &tag) {
|
||||
RecentHashtagPack::iterator i = recent.begin(), e = recent.end();
|
||||
for (; i != e; ++i) {
|
||||
if (i->first == tag) {
|
||||
++i->second;
|
||||
if (qAbs(i->second) > 0x4000) {
|
||||
for (RecentHashtagPack::iterator j = recent.begin(); j != e; ++j) {
|
||||
if (j->second > 1) {
|
||||
j->second /= 2;
|
||||
} else if (j->second > 0) {
|
||||
j->second = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i != recent.begin(); --i) {
|
||||
if (qAbs((i - 1)->second) > qAbs(i->second)) {
|
||||
break;
|
||||
}
|
||||
qSwap(*i, *(i - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == e) {
|
||||
while (recent.size() >= 64) recent.pop_back();
|
||||
recent.push_back(qMakePair(tag, 1));
|
||||
for (i = recent.end() - 1; i != recent.begin(); --i) {
|
||||
if ((i - 1)->second > i->second) {
|
||||
break;
|
||||
}
|
||||
qSwap(*i, *(i - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeclareSetting(QStringList, SendPaths);
|
||||
DeclareSetting(QString, StartUrl);
|
||||
|
||||
@ -271,5 +230,3 @@ DeclareSetting(int32, AutoDownloadPhoto);
|
||||
DeclareSetting(int32, AutoDownloadAudio);
|
||||
DeclareSetting(int32, AutoDownloadGif);
|
||||
DeclareSetting(bool, AutoPlayGif);
|
||||
|
||||
void settingsParseArgs(int argc, char *argv[]);
|
||||
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/localstorage.h"
|
||||
#include "platform/platform_file_utilities.h"
|
||||
#include "auth_session.h"
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
@ -722,11 +723,11 @@ bool mtpFileLoader::feedPart(int offset, base::const_byte_span bytes) {
|
||||
// Debugging weird out of memory crashes.
|
||||
auto info = QString("offset: %1, size: %2, cancelled: %3, finished: %4, filename: '%5', tocache: %6, fromcloud: %7, data: %8, fullsize: %9").arg(offset).arg(bytes.size()).arg(Logs::b(_cancelled)).arg(Logs::b(_finished)).arg(_filename).arg(int(_toCache)).arg(int(_fromCloud)).arg(_data.size()).arg(_size);
|
||||
info += QString(", locationtype: %1, inqueue: %2, localstatus: %3").arg(int(_locationType)).arg(Logs::b(_inQueue)).arg(int(_localStatus));
|
||||
SignalHandlers::setCrashAnnotation("DebugInfo", info);
|
||||
CrashReports::SetAnnotation("DebugInfo", info);
|
||||
}
|
||||
_data.reserve(offset + bytes.size());
|
||||
if (offset > 100 * 1024 * 1024) {
|
||||
SignalHandlers::setCrashAnnotation("DebugInfo", QString());
|
||||
CrashReports::ClearAnnotation("DebugInfo");
|
||||
}
|
||||
|
||||
if (offset > _data.size()) {
|
||||
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "storage/serialize_document.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "observer_peer.h"
|
||||
@ -1778,7 +1779,7 @@ void _writeUserSettings() {
|
||||
}
|
||||
|
||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||
size += sizeof(quint32) + sizeof(qint32) + (Stickers::GetRecentPack().isEmpty() ? Stickers::GetRecentPack().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||
size += sizeof(quint32) + Serialize::stringSize(cDialogLastPath());
|
||||
size += sizeof(quint32) + 3 * sizeof(qint32);
|
||||
size += sizeof(quint32) + 2 * sizeof(qint32);
|
||||
@ -1822,11 +1823,11 @@ void _writeUserSettings() {
|
||||
}
|
||||
data.stream << quint32(dbiEmojiVariants) << cEmojiVariants();
|
||||
{
|
||||
RecentStickerPreload v(cRecentStickersPreload());
|
||||
auto v = cRecentStickersPreload();
|
||||
if (v.isEmpty()) {
|
||||
v.reserve(cGetRecentStickers().size());
|
||||
for (RecentStickerPack::const_iterator i = cGetRecentStickers().cbegin(), e = cGetRecentStickers().cend(); i != e; ++i) {
|
||||
v.push_back(qMakePair(i->first->id, i->second));
|
||||
v.reserve(Stickers::GetRecentPack().size());
|
||||
for_const (auto &pair, Stickers::GetRecentPack()) {
|
||||
v.push_back(qMakePair(pair.first->id, pair.second));
|
||||
}
|
||||
}
|
||||
data.stream << quint32(dbiRecentStickers) << v;
|
||||
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "ui/text/text_block.h"
|
||||
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
// COPIED FROM qtextlayout.cpp AND MODIFIED
|
||||
namespace {
|
||||
|
||||
@ -327,7 +329,7 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi
|
||||
QString part = str.mid(_from, length);
|
||||
|
||||
// Attempt to catch a crash in text processing
|
||||
SignalHandlers::setCrashAnnotationRef("CrashString", &part);
|
||||
CrashReports::SetAnnotationRef("CrashString", &part);
|
||||
|
||||
QStackTextEngine engine(part, blockFont->f);
|
||||
QTextLayout layout(&engine);
|
||||
@ -338,7 +340,7 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi
|
||||
|
||||
layout.endLayout();
|
||||
|
||||
SignalHandlers::clearCrashAnnotationRef("CrashString");
|
||||
CrashReports::ClearAnnotationRef("CrashString");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,3 +398,8 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||
fi
|
||||
|
||||
echo "Version $AppVersionStrFull is ready!";
|
||||
echo -en "\007";
|
||||
sleep 1;
|
||||
echo -en "\007";
|
||||
sleep 1;
|
||||
echo -en "\007";
|
||||
|
@ -141,8 +141,14 @@
|
||||
<(src_loc)/core/click_handler.h
|
||||
<(src_loc)/core/click_handler_types.cpp
|
||||
<(src_loc)/core/click_handler_types.h
|
||||
<(src_loc)/core/crash_report_window.cpp
|
||||
<(src_loc)/core/crash_report_window.h
|
||||
<(src_loc)/core/crash_reports.cpp
|
||||
<(src_loc)/core/crash_reports.h
|
||||
<(src_loc)/core/file_utilities.cpp
|
||||
<(src_loc)/core/file_utilities.h
|
||||
<(src_loc)/core/launcher.cpp
|
||||
<(src_loc)/core/launcher.h
|
||||
<(src_loc)/core/single_timer.cpp
|
||||
<(src_loc)/core/single_timer.h
|
||||
<(src_loc)/core/tl_help.h
|
||||
@ -398,6 +404,8 @@
|
||||
<(src_loc)/platform/linux/linux_libs.h
|
||||
<(src_loc)/platform/linux/file_utilities_linux.cpp
|
||||
<(src_loc)/platform/linux/file_utilities_linux.h
|
||||
<(src_loc)/platform/linux/launcher_linux.cpp
|
||||
<(src_loc)/platform/linux/launcher_linux.h
|
||||
<(src_loc)/platform/linux/main_window_linux.cpp
|
||||
<(src_loc)/platform/linux/main_window_linux.h
|
||||
<(src_loc)/platform/linux/notifications_manager_linux.cpp
|
||||
@ -406,6 +414,8 @@
|
||||
<(src_loc)/platform/linux/specific_linux.h
|
||||
<(src_loc)/platform/mac/file_utilities_mac.mm
|
||||
<(src_loc)/platform/mac/file_utilities_mac.h
|
||||
<(src_loc)/platform/mac/launcher_mac.mm
|
||||
<(src_loc)/platform/mac/launcher_mac.h
|
||||
<(src_loc)/platform/mac/mac_iconv_helper.c
|
||||
<(src_loc)/platform/mac/mac_utilities.mm
|
||||
<(src_loc)/platform/mac/mac_utilities.h
|
||||
@ -423,6 +433,8 @@
|
||||
<(src_loc)/platform/win/audio_win.h
|
||||
<(src_loc)/platform/win/file_utilities_win.cpp
|
||||
<(src_loc)/platform/win/file_utilities_win.h
|
||||
<(src_loc)/platform/win/launcher_win.cpp
|
||||
<(src_loc)/platform/win/launcher_win.h
|
||||
<(src_loc)/platform/win/main_window_win.cpp
|
||||
<(src_loc)/platform/win/main_window_win.h
|
||||
<(src_loc)/platform/win/notifications_manager_win.cpp
|
||||
@ -440,6 +452,7 @@
|
||||
<(src_loc)/platform/win/windows_range_v3_helpers.h
|
||||
<(src_loc)/platform/platform_audio.h
|
||||
<(src_loc)/platform/platform_file_utilities.h
|
||||
<(src_loc)/platform/platform_launcher.h
|
||||
<(src_loc)/platform/platform_main_window.h
|
||||
<(src_loc)/platform/platform_notifications_manager.h
|
||||
<(src_loc)/platform/platform_specific.h
|
||||
|
Loading…
Reference in New Issue
Block a user