This commit is contained in:
John Preston 2016-01-30 21:24:50 +03:00
commit 12716a8c40
18 changed files with 227 additions and 56 deletions

View File

@ -23,6 +23,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
NSString *appName = @"Telegram.app"; NSString *appName = @"Telegram.app";
NSString *appDir = nil; NSString *appDir = nil;
NSString *workDir = nil; NSString *workDir = nil;
NSString *crashReportArg = nil;
#ifdef _DEBUG #ifdef _DEBUG
BOOL _debug = YES; BOOL _debug = YES;
@ -101,6 +102,10 @@ int main(int argc, const char * argv[]) {
[formatter setNumberStyle:NSNumberFormatterDecimalStyle]; [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
procId = [[formatter numberFromString:[NSString stringWithUTF8String:argv[i]]] intValue]; procId = [[formatter numberFromString:[NSString stringWithUTF8String:argv[i]]] intValue];
} }
} else if ([@"-crashreport" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
if (++i < argc) {
crashReportArg = [NSString stringWithUTF8String:argv[i]];
}
} else if ([@"-noupdate" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) { } else if ([@"-noupdate" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
update = NO; update = NO;
} else if ([@"-tosettings" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) { } else if ([@"-tosettings" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
@ -214,7 +219,8 @@ int main(int argc, const char * argv[]) {
} }
NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""]; NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""];
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:@"-noupdate", nil]; NSMutableArray *args = [[NSMutableArray alloc] initWithObjects: crashReportArg ? crashReportArg : @"-noupdate", nil];
if (!crashReportArg) {
if (toSettings) [args addObject:@"-tosettings"]; if (toSettings) [args addObject:@"-tosettings"];
if (_debug) [args addObject:@"-debug"]; if (_debug) [args addObject:@"-debug"];
if (startInTray) [args addObject:@"-startintray"]; if (startInTray) [args addObject:@"-startintray"];
@ -224,6 +230,7 @@ int main(int argc, const char * argv[]) {
[args addObject:@"-key"]; [args addObject:@"-key"];
[args addObject:key]; [args addObject:key];
} }
}
writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]); writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
NSError *error = nil; NSError *error = nil;
NSRunningApplication *result = [[NSWorkspace sharedWorkspace] NSRunningApplication *result = [[NSWorkspace sharedWorkspace]

View File

@ -151,6 +151,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading())); connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading()));
connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected())); connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
#ifndef TDESKTOP_DISABLE_AUTOUPDATE #ifndef TDESKTOP_DISABLE_AUTOUPDATE
connect(&_updateCheckTimer, SIGNAL(timeout()), this, SLOT(updateCheck())); connect(&_updateCheckTimer, SIGNAL(timeout()), this, SLOT(updateCheck()));
connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed())); connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
@ -531,12 +533,6 @@ inline Application *application() {
namespace Sandboxer { namespace Sandboxer {
void setClipboardText(const QString &text) {
if (Application *a = application()) {
a->clipboard()->setText(text);
}
}
QRect availableGeometry() { QRect availableGeometry() {
if (Application *a = application()) { if (Application *a = application()) {
return a->desktop()->availableGeometry(); return a->desktop()->availableGeometry();
@ -724,8 +720,7 @@ AppClass::AppClass() : QObject()
application()->installNativeEventFilter(psNativeEventFilter()); application()->installNativeEventFilter(psNativeEventFilter());
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication())); connect(application(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onAppStateChanged(Qt::ApplicationState)));
connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onAppStateChanged(Qt::ApplicationState)));
connect(&_mtpUnpauseTimer, SIGNAL(timeout()), this, SLOT(doMtpUnpause())); connect(&_mtpUnpauseTimer, SIGNAL(timeout()), this, SLOT(doMtpUnpause()));

View File

@ -107,7 +107,6 @@ private:
namespace Sandboxer { namespace Sandboxer {
void setClipboardText(const QString &text);
QRect availableGeometry(); QRect availableGeometry();
QRect screenGeometry(const QPoint &p); QRect screenGeometry(const QPoint &p);
void setActiveWindow(QWidget *window); void setActiveWindow(QWidget *window);

View File

@ -558,12 +558,12 @@ bool checkReadyUpdate() {
QDir().mkpath(QFileInfo(curUpdater).absolutePath()); QDir().mkpath(QFileInfo(curUpdater).absolutePath());
DEBUG_LOG(("Update Info: moving %1 to %2..").arg(updater.absoluteFilePath()).arg(curUpdater)); DEBUG_LOG(("Update Info: moving %1 to %2..").arg(updater.absoluteFilePath()).arg(curUpdater));
if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) { if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) {
UpdateDownloader::clearAll(); UpdateChecker::clearAll();
return false; return false;
} }
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) { if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) {
UpdateDownloader::clearAll(); UpdateChecker::clearAll();
return false; return false;
} }
#endif #endif

View File

@ -82,7 +82,7 @@ void AboutBox::onVersion() {
} }
url = url.arg(qsl("tbeta%1_%2").arg(cRealBetaVersion()).arg(countBetaVersionSignature(cRealBetaVersion()))); url = url.arg(qsl("tbeta%1_%2").arg(cRealBetaVersion()).arg(countBetaVersionSignature(cRealBetaVersion())));
Sandboxer::setClipboardText(url); Application::clipboard()->setText(url);
Ui::showLayer(new InformBox("The link to the current private beta version of Telegram Desktop was copied to the clipboard.")); Ui::showLayer(new InformBox("The link to the current private beta version of Telegram Desktop was copied to the clipboard."));
} else { } else {

View File

@ -750,7 +750,7 @@ void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) {
void SetupChannelBox::mousePressEvent(QMouseEvent *e) { void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
mouseMoveEvent(e); mouseMoveEvent(e);
if (_linkOver) { if (_linkOver) {
Sandboxer::setClipboardText(_channel->invitationUrl); Application::clipboard()->setText(_channel->invitationUrl);
_goodTextLink = lang(lng_create_channel_link_copied); _goodTextLink = lang(lng_create_channel_link_copied);
a_goodOpacity = anim::fvalue(1, 0); a_goodOpacity = anim::fvalue(1, 0);
_a_goodFade.start(); _a_goodFade.start();

View File

@ -212,7 +212,7 @@ void MaxInviteBox::mouseMoveEvent(QMouseEvent *e) {
void MaxInviteBox::mousePressEvent(QMouseEvent *e) { void MaxInviteBox::mousePressEvent(QMouseEvent *e) {
mouseMoveEvent(e); mouseMoveEvent(e);
if (_linkOver) { if (_linkOver) {
Sandboxer::setClipboardText(_link); Application::clipboard()->setText(_link);
_goodTextLink = lang(lng_create_channel_link_copied); _goodTextLink = lang(lng_create_channel_link_copied);
a_goodOpacity = anim::fvalue(1, 0); a_goodOpacity = anim::fvalue(1, 0);
_a_good.start(); _a_good.start();

View File

@ -191,7 +191,7 @@ void UsernameBox::onChanged() {
} }
void UsernameBox::onLinkClick() { void UsernameBox::onLinkClick() {
Sandboxer::setClipboardText(qsl("https://telegram.me/") + getName()); Application::clipboard()->setText(qsl("https://telegram.me/") + getName());
_copiedTextLink = lang(lng_username_copied); _copiedTextLink = lang(lng_username_copied);
update(); update();
} }

View File

@ -4804,8 +4804,22 @@ void HistoryWidget::onDocumentSelect() {
} }
} }
QString _getCrashReportFile(const QMimeData *m) {
if (!m || m->urls().size() != 1) return QString();
QString file(m->urls().at(0).toLocalFile());
if (file.startsWith(qsl("/.file/id="))) file = psConvertFileUrl(file);
return file.endsWith(qstr(".telegramcrash"), Qt::CaseInsensitive) ? file : QString();
}
void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) { void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) {
if (!_peer && !_getCrashReportFile(e->mimeData()).isEmpty()) {
e->setDropAction(Qt::CopyAction);
e->accept();
return;
}
if (!_history) return; if (!_history) return;
if (_peer && (_peer->isChannel() && !_peer->asChannel()->canPublish())) return; if (_peer && (_peer->isChannel() && !_peer->asChannel()->canPublish())) return;
@ -5127,6 +5141,13 @@ bool HistoryWidget::kbWasHidden() const {
} }
void HistoryWidget::dropEvent(QDropEvent *e) { void HistoryWidget::dropEvent(QDropEvent *e) {
if (!_peer && !_getCrashReportFile(e->mimeData()).isEmpty()) {
e->acceptProposedAction();
psExecTelegram(_getCrashReportFile(e->mimeData()));
App::quit();
return;
}
_attachDrag = DragStateNone; _attachDrag = DragStateNone;
updateDragAreas(); updateDragAreas();
e->acceptProposedAction(); e->acceptProposedAction();

View File

@ -108,7 +108,7 @@ private:
QSharedPointer<QFile> files[LogDataCount]; QSharedPointer<QFile> files[LogDataCount];
QTextStream streams[LogDataCount]; QTextStream streams[LogDataCount];
int32 part = -1, index = 0; int32 part = -1;
bool reopen(LogDataType type, int32 dayIndex, const QString &postfix) { bool reopen(LogDataType type, int32 dayIndex, const QString &postfix) {
if (streams[type].device()) { if (streams[type].device()) {
@ -596,14 +596,31 @@ namespace SignalHandlers {
return _writeNumber(stream, num); return _writeNumber(stream, num);
} }
const dump &operator<<(const dump &stream, DWORD num) { const dump &operator<<(const dump &stream, uint32 num) {
return _writeNumber(stream, num); return _writeNumber(stream, num);
} }
const dump &operator<<(const dump &stream, DWORD64 num) { const dump &operator<<(const dump &stream, uint64 num) {
return _writeNumber(stream, num); return _writeNumber(stream, num);
} }
const dump &operator<<(const dump &stream, double num) {
if (num < 0) {
_writeChar('-');
num = -num;
}
_writeNumber(stream, uint64(floor(num)));
_writeChar('.');
num -= floor(num);
for (int i = 0; i < 4; ++i) {
num *= 10;
int digit = int(floor(num));
_writeChar('0' + digit);
num -= digit;
}
return stream;
}
Qt::HANDLE LoggingCrashThreadId = 0; Qt::HANDLE LoggingCrashThreadId = 0;
bool LoggingCrashHeaderWritten = false; bool LoggingCrashHeaderWritten = false;
QMutex LoggingCrashMutex; QMutex LoggingCrashMutex;
@ -665,6 +682,10 @@ namespace SignalHandlers {
dump() << "\n"; dump() << "\n";
LoggingCrashThreadId = 0; LoggingCrashThreadId = 0;
#ifndef Q_OS_WIN
exit(1);
#endif
} }
Status start() { Status start() {
@ -697,11 +718,11 @@ namespace SignalHandlers {
CrashDumpFileNo = fileno(CrashDumpFile); CrashDumpFileNo = fileno(CrashDumpFile);
QByteArray launchedDateTime = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss").toUtf8(); QByteArray launchedDateTime = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss").toUtf8();
t_assert(launchedDateTime.size() < sizeof(LaunchedDateTimeStr)); t_assert(launchedDateTime.size() < int(sizeof(LaunchedDateTimeStr)));
memcpy(LaunchedDateTimeStr, launchedDateTime.constData(), launchedDateTime.size()); memcpy(LaunchedDateTimeStr, launchedDateTime.constData(), launchedDateTime.size());
QByteArray launchedBinaryName = cExeName().toUtf8(); QByteArray launchedBinaryName = cExeName().toUtf8();
t_assert(launchedBinaryName.size() < sizeof(LaunchedBinaryName)); t_assert(launchedBinaryName.size() < int(sizeof(LaunchedBinaryName)));
memcpy(LaunchedBinaryName, launchedBinaryName.constData(), launchedBinaryName.size()); memcpy(LaunchedBinaryName, launchedBinaryName.constData(), launchedBinaryName.size());
signal(SIGABRT, SignalHandlers::Handler); signal(SIGABRT, SignalHandlers::Handler);

View File

@ -93,8 +93,9 @@ namespace SignalHandlers {
}; };
const dump &operator<<(const dump &stream, const char *str); const dump &operator<<(const dump &stream, const char *str);
const dump &operator<<(const dump &stream, int num); const dump &operator<<(const dump &stream, int num);
const dump &operator<<(const dump &stream, DWORD num); const dump &operator<<(const dump &stream, uint32 num);
const dump &operator<<(const dump &stream, DWORD64 num); const dump &operator<<(const dump &stream, uint64 num);
const dump &operator<<(const dump &stream, double num);
enum Status { enum Status {
CantOpen, CantOpen,

View File

@ -26,6 +26,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
#include "localstorage.h" #include "localstorage.h"
#include "passcodewidget.h" #include "passcodewidget.h"
#include <execinfo.h>
namespace { namespace {
QStringList _initLogs; QStringList _initLogs;
@ -38,7 +40,7 @@ namespace {
} }
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) { bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) {
Window *wnd = Application::wnd(); Window *wnd = AppClass::wnd();
if (!wnd) return false; if (!wnd) return false;
return wnd->psFilterNativeEvent(message); return wnd->psFilterNativeEvent(message);
@ -213,7 +215,7 @@ void PsMainWindow::psInitSize() {
bool maximized = false; bool maximized = false;
QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight); QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight);
if (pos.w && pos.h) { if (pos.w && pos.h) {
QList<QScreen*> screens = App::app()->screens(); QList<QScreen*> screens = Application::screens();
for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) { for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) {
QByteArray name = (*i)->name().toUtf8(); QByteArray name = (*i)->name().toUtf8();
if (pos.moncrc == hashCrc32(name.constData(), name.size())) { if (pos.moncrc == hashCrc32(name.constData(), name.size())) {
@ -266,7 +268,7 @@ void PsMainWindow::psSavePosition(Qt::WindowState state) {
int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2, d = 0; int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2, d = 0;
QScreen *chosen = 0; QScreen *chosen = 0;
QList<QScreen*> screens = App::app()->screens(); QList<QScreen*> screens = Application::screens();
for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) { for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) {
int dx = (*i)->geometry().x() + (*i)->geometry().width() / 2 - px; if (dx < 0) dx = -dx; int dx = (*i)->geometry().x() + (*i)->geometry().width() / 2 - px; if (dx < 0) dx = -dx;
int dy = (*i)->geometry().y() + (*i)->geometry().height() / 2 - py; if (dy < 0) dy = -dy; int dy = (*i)->geometry().y() + (*i)->geometry().height() / 2 - py; if (dy < 0) dy = -dy;
@ -422,13 +424,13 @@ void PsMainWindow::psMacUpdateMenu() {
canSelectAll = !edit->text().isEmpty(); canSelectAll = !edit->text().isEmpty();
canUndo = edit->isUndoAvailable(); canUndo = edit->isUndoAvailable();
canRedo = edit->isRedoAvailable(); canRedo = edit->isRedoAvailable();
canPaste = !App::app()->clipboard()->text().isEmpty(); canPaste = !Application::clipboard()->text().isEmpty();
} else if (FlatTextarea *edit = qobject_cast<FlatTextarea*>(focused)) { } else if (FlatTextarea *edit = qobject_cast<FlatTextarea*>(focused)) {
canCut = canCopy = canDelete = edit->textCursor().hasSelection(); canCut = canCopy = canDelete = edit->textCursor().hasSelection();
canSelectAll = !edit->getLastText().isEmpty(); canSelectAll = !edit->getLastText().isEmpty();
canUndo = edit->isUndoAvailable(); canUndo = edit->isUndoAvailable();
canRedo = edit->isRedoAvailable(); canRedo = edit->isRedoAvailable();
canPaste = !App::app()->clipboard()->text().isEmpty(); canPaste = !Application::clipboard()->text().isEmpty();
} else if (HistoryInner *list = qobject_cast<HistoryInner*>(focused)) { } else if (HistoryInner *list = qobject_cast<HistoryInner*>(focused)) {
canCopy = list->canCopySelected(); canCopy = list->canCopySelected();
canDelete = list->canDeleteSelected(); canDelete = list->canDeleteSelected();
@ -519,7 +521,115 @@ bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {
QAbstractNativeEventFilter *psNativeEventFilter() { QAbstractNativeEventFilter *psNativeEventFilter() {
delete _psEventFilter; delete _psEventFilter;
_psEventFilter = new _PsEventFilter(); _psEventFilter = new _PsEventFilter();
installNativeEventFilter(_psEventFilter); return _psEventFilter;
}
void psWriteDump() {
double v = objc_appkitVersion();
SignalHandlers::dump() << "OS-Version: " << v;
}
void psWriteStackTrace(int file) {
void *addresses[1024] = { 0 };
size_t size = backtrace(addresses, 1024);
backtrace_symbols_fd(addresses, size, file);
}
QString demanglestr(const QString &mangled) {
QByteArray cmd = ("c++filt -n " + mangled).toUtf8();
FILE *f = popen(cmd.constData(), "r");
if (!f) return "BAD_SYMBOL_" + mangled;
QString result;
char buffer[4096] = {0};
while (!feof(f)) {
if (fgets(buffer, 4096, f) != NULL) {
result += buffer;
}
}
pclose(f);
return result.trimmed();
}
QString _showCrashDump(const QByteArray &crashdump, QString dumpfile) {
QString initial = QString::fromUtf8(crashdump), result;
QStringList lines = initial.split('\n');
result.reserve(initial.size());
int32 i = 0, l = lines.size();
while (i < l) {
for (; i < l; ++i) {
result.append(lines.at(i)).append('\n');
QString line = lines.at(i).trimmed();
if (line == qstr("Backtrace:")) {
++i;
break;
}
}
for (int32 start = i; i < l; ++i) {
QString line = lines.at(i).trimmed();
if (line.isEmpty()) break;
if (!QRegularExpression(qsl("^\\d+")).match(line).hasMatch()) {
if (!lines.at(i).startsWith(qstr("ERROR: "))) {
result.append(qstr("BAD LINE: "));
}
result.append(line).append('\n');
continue;
}
QStringList lst = line.split(' ', QString::SkipEmptyParts);
result.append(lst.at(0)).append(' ');
for (int j = 1, s = lst.size();;) {
if (lst.at(j).startsWith('_')) {
result.append(demanglestr(lst.at(j)));
if (++j < s) {
result.append(' ');
for (;;) {
result.append(lst.at(j));
if (++j < s) {
result.append(' ');
} else {
break;
}
}
}
break;
} else if (j > 2) {
result.append(lst.at(j));
}
if (++j < s) {
result.append(' ');
} else {
break;
}
}
result.append('\n');
}
}
return result;
}
int psShowCrash(const QString &crashdump) {
QString text;
QFile dump(crashdump);
if (dump.open(QIODevice::ReadOnly)) {
text = qsl("Crash dump file '%1':\n\n").arg(QFileInfo(crashdump).absoluteFilePath());
text += _showCrashDump(dump.readAll(), crashdump);
} else {
text = qsl("ERROR: could not read crash dump file '%1'").arg(QFileInfo(crashdump).absoluteFilePath());
}
QByteArray args[] = { "" };
int a_argc = 1;
char *a_argv[1] = { args[0].data() };
QApplication app(a_argc, a_argv);
ShowCrashReportWindow wnd(text);
return app.exec();
} }
void psDeleteDir(const QString &dir) { void psDeleteDir(const QString &dir) {
@ -666,8 +776,8 @@ void psExecUpdater() {
} }
} }
void psExecTelegram() { void psExecTelegram(const QString &crashreport) {
objc_execTelegram(); objc_execTelegram(crashreport);
} }
void psAutoStart(bool start, bool silent) { void psAutoStart(bool start, bool silent) {

View File

@ -140,6 +140,10 @@ private:
}; };
void psWriteDump();
void psWriteStackTrace(int file);
int psShowCrash(const QString &crashdump);
void psDeleteDir(const QString &dir); void psDeleteDir(const QString &dir);
void psUserActionDone(); void psUserActionDone();
@ -171,7 +175,7 @@ int psCleanup();
int psFixPrevious(); int psFixPrevious();
void psExecUpdater(); void psExecUpdater();
void psExecTelegram(); void psExecTelegram(const QString &crashreport = QString());
bool psShowOpenWithMenu(int x, int y, const QString &file); bool psShowOpenWithMenu(int x, int y, const QString &file);

View File

@ -69,7 +69,7 @@ void objc_openFile(const QString &file, bool openwith);
void objc_start(); void objc_start();
void objc_finish(); void objc_finish();
bool objc_execUpdater(); bool objc_execUpdater();
void objc_execTelegram(); void objc_execTelegram(const QString &crashreport);
void objc_registerCustomScheme(); void objc_registerCustomScheme();
@ -77,6 +77,8 @@ void objc_activateProgram(WId winId);
bool objc_moveFile(const QString &from, const QString &to); bool objc_moveFile(const QString &from, const QString &to);
void objc_deleteDir(const QString &dir); void objc_deleteDir(const QString &dir);
double objc_appkitVersion();
QString objc_appDataPath(); QString objc_appDataPath();
QString objc_downloadPath(); QString objc_downloadPath();
QString objc_currentCountry(); QString objc_currentCountry();

View File

@ -211,7 +211,7 @@ public:
NSNumber *instObj = [[notification userInfo] objectForKey:@"launch"]; NSNumber *instObj = [[notification userInfo] objectForKey:@"launch"];
unsigned long long instLong = instObj ? [instObj unsignedLongLongValue] : 0; unsigned long long instLong = instObj ? [instObj unsignedLongLongValue] : 0;
DEBUG_LOG(("Received notification with instance %1").arg(instLong)); DEBUG_LOG(("Received notification with instance %1").arg(instLong));
if (instLong != Global::LaunchId()) { // other app instance notification if (instLong != Sandbox::LaunchId()) { // other app instance notification
return; return;
} }
if (notification.activationType == NSUserNotificationActivationTypeReplied) { if (notification.activationType == NSUserNotificationActivationTypeReplied) {
@ -283,8 +283,8 @@ void PsMacWindowPrivate::showNotify(uint64 peer, int32 msgId, const QPixmap &pix
NSUserNotification *notification = [[NSUserNotification alloc] init]; NSUserNotification *notification = [[NSUserNotification alloc] init];
NSImage *img = qt_mac_create_nsimage(pix); NSImage *img = qt_mac_create_nsimage(pix);
DEBUG_LOG(("Sending notification with userinfo: peer %1, msgId %2 and instance %3").arg(peer).arg(msgId).arg(Global::LaunchId())); DEBUG_LOG(("Sending notification with userinfo: peer %1, msgId %2 and instance %3").arg(peer).arg(msgId).arg(Sandbox::LaunchId()));
[notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:Global::LaunchId()],@"launch",nil]]; [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:Sandbox::LaunchId()],@"launch",nil]];
[notification setTitle:QNSString(title).s()]; [notification setTitle:QNSString(title).s()];
[notification setSubtitle:QNSString(subtitle).s()]; [notification setSubtitle:QNSString(subtitle).s()];
@ -352,7 +352,7 @@ void PsMacWindowPrivate::clearNotifies(unsigned long long peer) {
NSArray *notifies = [center deliveredNotifications]; NSArray *notifies = [center deliveredNotifications];
for (id notify in notifies) { for (id notify in notifies) {
NSDictionary *dict = [notify userInfo]; NSDictionary *dict = [notify userInfo];
if ([[dict objectForKey:@"peer"] unsignedLongLongValue] == peer && [[dict objectForKey:@"launch"] unsignedLongLongValue] == Global::LaunchId()) { if ([[dict objectForKey:@"peer"] unsignedLongLongValue] == peer && [[dict objectForKey:@"launch"] unsignedLongLongValue] == Sandbox::LaunchId()) {
[center removeDeliveredNotification:notify]; [center removeDeliveredNotification:notify];
} }
} }
@ -950,7 +950,7 @@ void objc_registerCustomScheme() {
#endif #endif
} }
BOOL _execUpdater(BOOL update = YES) { BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) {
NSString *path = @"", *args = @""; NSString *path = @"", *args = @"";
@try { @try {
path = [[NSBundle mainBundle] bundlePath]; path = [[NSBundle mainBundle] bundlePath];
@ -972,6 +972,10 @@ BOOL _execUpdater(BOOL update = YES) {
[args addObject:@"-key"]; [args addObject:@"-key"];
[args addObject:QNSString(cDataFile()).s()]; [args addObject:QNSString(cDataFile()).s()];
} }
if (!crashreport.isEmpty()) {
[args addObject:@"-crashreport"];
[args addObject:QNSString(crashreport).s()];
}
DEBUG_LOG(("Application Info: executing %1 %2").arg(objcString(path)).arg(objcString([args componentsJoinedByString:@" "]))); DEBUG_LOG(("Application Info: executing %1 %2").arg(objcString(path)).arg(objcString([args componentsJoinedByString:@" "])));
if (![NSTask launchedTaskWithLaunchPath:path arguments:args]) { if (![NSTask launchedTaskWithLaunchPath:path arguments:args]) {
@ -992,8 +996,8 @@ bool objc_execUpdater() {
return !!_execUpdater(); return !!_execUpdater();
} }
void objc_execTelegram() { void objc_execTelegram(const QString &crashreport) {
_execUpdater(NO); _execUpdater(NO, crashreport);
} }
void objc_activateProgram(WId winId) { void objc_activateProgram(WId winId) {
@ -1027,6 +1031,10 @@ void objc_deleteDir(const QString &dir) {
[[NSFileManager defaultManager] removeItemAtPath:QNSString(dir).s() error:nil]; [[NSFileManager defaultManager] removeItemAtPath:QNSString(dir).s() error:nil];
} }
double objc_appkitVersion() {
return NSAppKitVersionNumber;
}
QString objc_appDataPath() { QString objc_appDataPath() {
NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]; NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
if (url) { if (url) {

View File

@ -69,7 +69,7 @@ public:
} }
return _index.loadAcquire() - 1; return _index.loadAcquire() - 1;
} }
static const uint64 Bit() { static uint64 Bit() {
return (1 << Index()); return (1 << Index());
} }
@ -86,7 +86,7 @@ public:
class InterfacesMetadata { class InterfacesMetadata {
public: public:
InterfacesMetadata(uint64 mask) : _mask(mask), size(0), last(64) { InterfacesMetadata(uint64 mask) : size(0), last(64), _mask(mask) {
for (int i = 0; i < 64; ++i) { for (int i = 0; i < 64; ++i) {
uint64 m = (1 << i); uint64 m = (1 << i);
if (_mask & m) { if (_mask & m) {

View File

@ -89,8 +89,9 @@ TitleWidget::TitleWidget(Window *window) : TWidget(window)
connect(&_contacts, SIGNAL(clicked()), this, SLOT(onContacts())); connect(&_contacts, SIGNAL(clicked()), this, SLOT(onContacts()));
connect(&_about, SIGNAL(clicked()), this, SLOT(onAbout())); connect(&_about, SIGNAL(clicked()), this, SLOT(onAbout()));
connect(wnd->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(stateChanged(Qt::WindowState))); connect(wnd->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(stateChanged(Qt::WindowState)));
#ifndef TDESKTOP_DISABLE_AUTOUPDATE #ifndef TDESKTOP_DISABLE_AUTOUPDATE
connect(App::app(), SIGNAL(updateReady()), this, SLOT(showUpdateBtn())); Sandboxer::connect(SIGNAL(updateReady()), this, SLOT(showUpdateBtn()));
#endif #endif
if (cPlatform() != dbipWindows) { if (cPlatform() != dbipWindows) {

View File

@ -2209,7 +2209,7 @@ namespace {
zByteArray *ba = (zByteArray*)opaque; zByteArray *ba = (zByteArray*)opaque;
uLong toRead = 0; uLong toRead = 0;
if (!ba->err) { if (!ba->err) {
if (ba->data.size() > ba->pos) { if (ba->data.size() > int(ba->pos)) {
toRead = qMin(size, uLong(ba->data.size() - ba->pos)); toRead = qMin(size, uLong(ba->data.size() - ba->pos));
memcpy(buf, ba->data.constData() + ba->pos, toRead); memcpy(buf, ba->data.constData() + ba->pos, toRead);
ba->pos += toRead; ba->pos += toRead;
@ -2223,7 +2223,7 @@ namespace {
uLong zByteArrayWriteFile(voidpf opaque, voidpf stream, const void* buf, uLong size) { uLong zByteArrayWriteFile(voidpf opaque, voidpf stream, const void* buf, uLong size) {
zByteArray *ba = (zByteArray*)opaque; zByteArray *ba = (zByteArray*)opaque;
if (ba->data.size() < ba->pos + size) { if (ba->data.size() < int(ba->pos + size)) {
ba->data.resize(ba->pos + size); ba->data.resize(ba->pos + size);
} }
memcpy(ba->data.data() + ba->pos, buf, size); memcpy(ba->data.data() + ba->pos, buf, size);
@ -2257,7 +2257,7 @@ namespace {
case ZLIB_FILEFUNC_SEEK_CUR: ba->pos += offset; break; case ZLIB_FILEFUNC_SEEK_CUR: ba->pos += offset; break;
case ZLIB_FILEFUNC_SEEK_END: ba->pos = ba->data.size() + offset; break; case ZLIB_FILEFUNC_SEEK_END: ba->pos = ba->data.size() + offset; break;
} }
if (ba->pos > ba->data.size()) { if (int(ba->pos) > ba->data.size()) {
ba->err = -1; ba->err = -1;
} }
} }
@ -2303,6 +2303,7 @@ void LastCrashedWindow::onCheckingFinished() {
reportPart.setBody(Global::LastCrashDump()); reportPart.setBody(Global::LastCrashDump());
multipart->append(reportPart); multipart->append(reportPart);
#ifdef Q_OS_WIN
QFileInfo dmpFile(_minidumpFull); QFileInfo dmpFile(_minidumpFull);
if (dmpFile.exists() && dmpFile.size() > 0 && dmpFile.size() < 20 * 1024 * 1024 && if (dmpFile.exists() && dmpFile.size() > 0 && dmpFile.size() < 20 * 1024 * 1024 &&
QRegularExpression(qsl("^Telegram\\-[\\d\\.\\-]{1,64}\\.dmp$")).match(dmpFile.fileName()).hasMatch()) { QRegularExpression(qsl("^Telegram\\-[\\d\\.\\-]{1,64}\\.dmp$")).match(dmpFile.fileName()).hasMatch()) {
@ -2354,6 +2355,7 @@ void LastCrashedWindow::onCheckingFinished() {
} }
} }
} }
#endif
_sendReply = _sendManager.post(QNetworkRequest(qsl("https://tdesktop.com/crash.php?act=report")), multipart); _sendReply = _sendManager.post(QNetworkRequest(qsl("https://tdesktop.com/crash.php?act=report")), multipart);
multipart->setParent(_sendReply); multipart->setParent(_sendReply);