From 592e3f7ae2d1431ef53648c6fb757e55b4099047 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 29 Sep 2015 18:29:21 +0300 Subject: [PATCH] preparing for loading photos from local in other thread --- Telegram/SourceFiles/gui/images.h | 23 --- Telegram/SourceFiles/localstorage.cpp | 24 +++ Telegram/SourceFiles/localstorage.h | 3 + .../SourceFiles/mtproto/mtpFileLoader.cpp | 169 ++++++++++-------- Telegram/SourceFiles/mtproto/mtpFileLoader.h | 43 ++++- Telegram/SourceFiles/structs.cpp | 6 +- Telegram/SourceFiles/title.cpp | 1 - Telegram/Telegram.plist | 6 +- Telegram/Telegram.xcodeproj/project.pbxproj | 7 +- 9 files changed, 168 insertions(+), 114 deletions(-) diff --git a/Telegram/SourceFiles/gui/images.h b/Telegram/SourceFiles/gui/images.h index 2d1e4a139f..359d7b318d 100644 --- a/Telegram/SourceFiles/gui/images.h +++ b/Telegram/SourceFiles/gui/images.h @@ -327,29 +327,6 @@ inline bool operator!=(const FileLocation &a, const FileLocation &b) { return !(a == b); } -enum LocationType { - UnknownFileLocation = 0, - DocumentFileLocation = 0x4e45abe9, // mtpc_inputDocumentFileLocation - AudioFileLocation = 0x74dc404d, // mtpc_inputAudioFileLocation - VideoFileLocation = 0x3d0364ec, // mtpc_inputVideoFileLocation -}; -inline LocationType mtpToLocationType(mtpTypeId type) { - switch (type) { - case mtpc_inputDocumentFileLocation: return DocumentFileLocation; - case mtpc_inputAudioFileLocation: return AudioFileLocation; - case mtpc_inputVideoFileLocation: return VideoFileLocation; - default: return UnknownFileLocation; - } -} -inline mtpTypeId mtpFromLocationType(LocationType type) { - switch (type) { - case DocumentFileLocation: return mtpc_inputDocumentFileLocation; - case AudioFileLocation: return mtpc_inputAudioFileLocation; - case VideoFileLocation: return mtpc_inputVideoFileLocation; - case UnknownFileLocation: - default: return 0; - } -} typedef QPair MediaKey; inline uint64 mediaMix32To64(int32 a, int32 b) { return (uint64(*reinterpret_cast(&a)) << 32) | uint64(*reinterpret_cast(&b)); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 67caeda451..d5b292a015 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2272,6 +2272,14 @@ namespace Local { } } + bool startImageLoad(const StorageKey &location) { + StorageMap::iterator j = _imagesMap.find(location); + if (j == _imagesMap.cend()) { + return false; + } + return true; + } + StorageImageSaved readImage(const StorageKey &location) { StorageMap::iterator j = _imagesMap.find(location); if (j == _imagesMap.cend()) { @@ -2325,6 +2333,14 @@ namespace Local { } } + bool startStickerImageLoad(const StorageKey &location) { + StorageMap::iterator j = _stickerImagesMap.find(location); + if (j == _stickerImagesMap.cend()) { + return false; + } + return true; + } + QByteArray readStickerImage(const StorageKey &location) { StorageMap::iterator j = _stickerImagesMap.find(location); if (j == _stickerImagesMap.cend()) { @@ -2377,6 +2393,14 @@ namespace Local { } } + bool startAudioLoad(const StorageKey &location) { + StorageMap::iterator j = _audiosMap.find(location); + if (j == _audiosMap.cend()) { + return false; + } + return true; + } + QByteArray readAudio(const StorageKey &location) { StorageMap::iterator j = _audiosMap.find(location); if (j == _audiosMap.cend()) { diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index 5b20a3f7ae..24597790af 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -120,16 +120,19 @@ namespace Local { void writeImage(const StorageKey &location, const ImagePtr &img); void writeImage(const StorageKey &location, const StorageImageSaved &jpeg, bool overwrite = true); + bool startImageLoad(const StorageKey &location); StorageImageSaved readImage(const StorageKey &location); int32 hasImages(); qint64 storageImagesSize(); void writeStickerImage(const StorageKey &location, const QByteArray &data, bool overwrite = true); + bool startStickerImageLoad(const StorageKey &location); QByteArray readStickerImage(const StorageKey &location); int32 hasStickers(); qint64 storageStickersSize(); void writeAudio(const StorageKey &location, const QByteArray &data, bool overwrite = true); + bool startAudioLoad(const StorageKey &location); QByteArray readAudio(const StorageKey &location); int32 hasAudios(); qint64 storageAudiosSize(); diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp index 5d25cecc9b..d325533c68 100644 --- a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp +++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp @@ -45,8 +45,9 @@ namespace { } mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &volume, int32 local, const uint64 &secret, int32 size) : prev(0), next(0), -priority(0), inQueue(false), complete(false), triedLocal(false), skippedBytes(0), nextRequestOffset(0), lastComplete(false), -dc(dc), locationType(0), volume(volume), local(local), secret(secret), +priority(0), inQueue(false), complete(false), +_localStatus(LocalNotTried), skippedBytes(0), nextRequestOffset(0), lastComplete(false), +dc(dc), _locationType(UnknownFileLocation), volume(volume), local(local), secret(secret), id(0), access(0), fileIsOpen(false), size(size), type(mtpc_storage_fileUnknown) { LoaderQueues::iterator i = queues.find(dc); if (i == queues.cend()) { @@ -55,20 +56,10 @@ id(0), access(0), fileIsOpen(false), size(size), type(mtpc_storage_fileUnknown) queue = &i.value(); } -mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, mtpTypeId locType, const QString &to, int32 size) : prev(0), next(0), -priority(0), inQueue(false), complete(false), triedLocal(false), skippedBytes(0), nextRequestOffset(0), lastComplete(false), -dc(dc), locationType(locType), volume(0), local(0), secret(0), -id(id), access(access), file(to), fname(to), fileIsOpen(false), duplicateInData(false), size(size), type(mtpc_storage_fileUnknown) { - LoaderQueues::iterator i = queues.find(MTP::dld[0] + dc); - if (i == queues.cend()) { - i = queues.insert(MTP::dld[0] + dc, mtpFileLoaderQueue()); - } - queue = &i.value(); -} - -mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, mtpTypeId locType, const QString &to, int32 size, bool todata) : prev(0), next(0), -priority(0), inQueue(false), complete(false), triedLocal(false), skippedBytes(0), nextRequestOffset(0), lastComplete(false), -dc(dc), locationType(locType), volume(0), local(0), secret(0), +mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &to, int32 size, bool todata) : prev(0), next(0), +priority(0), inQueue(false), complete(false), +_localStatus(LocalNotTried), skippedBytes(0), nextRequestOffset(0), lastComplete(false), +dc(dc), _locationType(type), volume(0), local(0), secret(0), id(id), access(access), file(to), fname(to), fileIsOpen(false), duplicateInData(todata), size(size), type(mtpc_storage_fileUnknown) { LoaderQueues::iterator i = queues.find(MTP::dld[0] + dc); if (i == queues.cend()) { @@ -150,11 +141,20 @@ bool mtpFileLoader::loadPart() { int32 limit = DocumentDownloadPartSize; MTPInputFileLocation loc; - switch (locationType) { - case 0: loc = MTP_inputFileLocation(MTP_long(volume), MTP_int(local), MTP_long(secret)); limit = DownloadPartSize; break; - case mtpc_inputVideoFileLocation: loc = MTP_inputVideoFileLocation(MTP_long(id), MTP_long(access)); break; - case mtpc_inputAudioFileLocation: loc = MTP_inputAudioFileLocation(MTP_long(id), MTP_long(access)); break; - case mtpc_inputDocumentFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(id), MTP_long(access)); break; + switch (_locationType) { + case UnknownFileLocation: + loc = MTP_inputFileLocation(MTP_long(volume), MTP_int(local), MTP_long(secret)); + limit = DownloadPartSize; + break; + case VideoFileLocation: + loc = MTP_inputVideoFileLocation(MTP_long(id), MTP_long(access)); + break; + case AudioFileLocation: + loc = MTP_inputAudioFileLocation(MTP_long(id), MTP_long(access)); + break; + case DocumentFileLocation: + loc = MTP_inputDocumentFileLocation(MTP_long(id), MTP_long(access)); + break; default: finishFail(); return false; @@ -188,7 +188,7 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRe Requests::iterator i = requests.find(req); if (i == requests.cend()) return loadNext(); - int32 limit = locationType ? DocumentDownloadPartSize : DownloadPartSize; + int32 limit = (_locationType == UnknownFileLocation) ? DownloadPartSize : DocumentDownloadPartSize; int32 dcIndex = i.value(); _dataRequested[dc].v[dcIndex] -= limit; @@ -254,24 +254,26 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRe App::app()->killDownloadSessionsStart(dc); } - if (!locationType && triedLocal && (fname.isEmpty() || duplicateInData)) { - Local::writeImage(storageKey(dc, volume, local), StorageImageSaved(mtpToStorageType(type), data)); - } else if (locationType && triedLocal) { - if (!fname.isEmpty()) { - Local::writeFileLocation(mediaKey(mtpToLocationType(locationType), dc, id), FileLocation(mtpToStorageType(type), fname)); - } - if (duplicateInData) { - if (locationType == mtpc_inputDocumentFileLocation) { - Local::writeStickerImage(mediaKey(mtpToLocationType(locationType), dc, id), data); - } else if (locationType == mtpc_inputAudioFileLocation) { - Local::writeAudio(mediaKey(mtpToLocationType(locationType), dc, id), data); + if (_localStatus == LocalNotFound || _localStatus == LocalFailed) { + if (_locationType != UnknownFileLocation) { // audio, video, document + MediaKey mkey = mediaKey(_locationType, dc, id); + if (!fname.isEmpty()) { + Local::writeFileLocation(mkey, FileLocation(mtpToStorageType(type), fname)); } + if (duplicateInData) { + if (_locationType == DocumentFileLocation) { + Local::writeStickerImage(mkey, data); + } else if (_locationType == AudioFileLocation) { + Local::writeAudio(mkey, data); + } + } + } else { + Local::writeImage(storageKey(dc, volume, local), StorageImageSaved(mtpToStorageType(type), data)); } } } emit progress(this); loadNext(); -// LOG(("Part loaded, handle time: %1").arg(getms() - ms)); } bool mtpFileLoader::partFailed(const RPCError &error) { @@ -303,54 +305,65 @@ void mtpFileLoader::pause() { removeFromQueue(); } -void mtpFileLoader::start(bool loadFirst, bool prior) { - if (complete) return; - if (!triedLocal) { - if (!locationType) { - triedLocal = true; - StorageImageSaved cached = Local::readImage(storageKey(dc, volume, local)); - if (cached.type != StorageFileUnknown) { - data = cached.data; - type = mtpFromStorageType(cached.type); - } - } else if (locationType) { - if (!fname.isEmpty()) { - triedLocal = true; - } - if (duplicateInData) { - if (locationType == mtpc_inputDocumentFileLocation) { - triedLocal = true; - data = Local::readStickerImage(mediaKey(mtpToLocationType(locationType), dc, id)); - if (!data.isEmpty()) type = mtpc_storage_filePartial; - } else if (locationType == mtpc_inputAudioFileLocation) { - triedLocal = true; - data = Local::readAudio(mediaKey(mtpToLocationType(locationType), dc, id)); - if (!data.isEmpty()) type = mtpc_storage_filePartial; - } - } +bool mtpFileLoader::tryLoadLocal() { + if (_localStatus == LocalNotFound || _localStatus == LocalLoaded || _localStatus == LocalFailed) { + return false; + } + if (_localStatus == LocalLoading) { + return true; + } + + if (_locationType == UnknownFileLocation) { + StorageImageSaved cached = Local::readImage(storageKey(dc, volume, local)); + if (cached.type != StorageFileUnknown) { + data = cached.data; + type = mtpFromStorageType(cached.type); } - if (triedLocal && !data.isEmpty()) { - if (!fname.isEmpty() && duplicateInData) { - if (!fileIsOpen) fileIsOpen = file.open(QIODevice::WriteOnly); - if (!fileIsOpen) { - return finishFail(); - } - if (file.write(data) != qint64(data.size())) { - return finishFail(); - } + } else { + if (duplicateInData) { + MediaKey mkey = mediaKey(_locationType, dc, id); + if (_locationType == DocumentFileLocation) { + data = Local::readStickerImage(mkey); + if (!data.isEmpty()) type = mtpc_storage_filePartial; + } else if (_locationType == AudioFileLocation) { + data = Local::readAudio(mkey); + if (!data.isEmpty()) type = mtpc_storage_filePartial; } - complete = true; - if (fileIsOpen) { - file.close(); - fileIsOpen = false; - psPostprocessFile(QFileInfo(file).absoluteFilePath()); - } - emit App::wnd()->imageLoaded(); - emit progress(this); - return loadNext(); } } + if (data.isEmpty()) { + _localStatus = LocalNotFound; + return false; + } + + _localStatus = LocalLoaded; + if (!fname.isEmpty() && duplicateInData) { + if (!fileIsOpen) fileIsOpen = file.open(QIODevice::WriteOnly); + if (!fileIsOpen) { + finishFail(); + return true; + } + if (file.write(data) != qint64(data.size())) { + finishFail(); + return true; + } + } + complete = true; + if (fileIsOpen) { + file.close(); + fileIsOpen = false; + psPostprocessFile(QFileInfo(file).absoluteFilePath()); + } + emit App::wnd()->imageLoaded(); + emit progress(this); + loadNext(); + return true; +} + +void mtpFileLoader::start(bool loadFirst, bool prior) { + if (complete || tryLoadLocal()) return; + if (!fname.isEmpty() && !duplicateInData && !fileIsOpen) { fileIsOpen = file.open(QIODevice::WriteOnly); if (!fileIsOpen) { @@ -464,7 +477,7 @@ void mtpFileLoader::cancel() { void mtpFileLoader::cancelRequests() { if (requests.isEmpty()) return; - int32 limit = locationType ? DocumentDownloadPartSize : DownloadPartSize; + int32 limit = (_locationType == UnknownFileLocation) ? DownloadPartSize : DocumentDownloadPartSize; DataRequested &dr(_dataRequested[dc]); for (Requests::const_iterator i = requests.cbegin(), e = requests.cend(); i != e; ++i) { MTP::cancel(i.key()); diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.h b/Telegram/SourceFiles/mtproto/mtpFileLoader.h index 0d1368c62b..11236aef08 100644 --- a/Telegram/SourceFiles/mtproto/mtpFileLoader.h +++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.h @@ -21,6 +21,38 @@ namespace MTP { void clearLoaderPriorities(); } +enum LocationType { + UnknownFileLocation = 0, + DocumentFileLocation = 0x4e45abe9, // mtpc_inputDocumentFileLocation + AudioFileLocation = 0x74dc404d, // mtpc_inputAudioFileLocation + VideoFileLocation = 0x3d0364ec, // mtpc_inputVideoFileLocation +}; +inline LocationType mtpToLocationType(mtpTypeId type) { + switch (type) { + case mtpc_inputDocumentFileLocation: return DocumentFileLocation; + case mtpc_inputAudioFileLocation: return AudioFileLocation; + case mtpc_inputVideoFileLocation: return VideoFileLocation; + default: return UnknownFileLocation; + } +} +inline mtpTypeId mtpFromLocationType(LocationType type) { + switch (type) { + case DocumentFileLocation: return mtpc_inputDocumentFileLocation; + case AudioFileLocation: return mtpc_inputAudioFileLocation; + case VideoFileLocation: return mtpc_inputVideoFileLocation; + case UnknownFileLocation: + default: return 0; + } +} + +enum LocalLoadStatus { + LocalNotTried, + LocalNotFound, + LocalLoading, + LocalLoaded, + LocalFailed, +}; + struct mtpFileLoaderQueue; class mtpFileLoader : public QObject, public RPCSender { Q_OBJECT @@ -28,8 +60,7 @@ class mtpFileLoader : public QObject, public RPCSender { public: mtpFileLoader(int32 dc, const uint64 &volume, int32 local, const uint64 &secret, int32 size = 0); - mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, mtpTypeId locType, const QString &to, int32 size); - mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, mtpTypeId locType, const QString &to, int32 size, bool todata); + mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &to, int32 size, bool todata = false); bool done() const; mtpTypeId fileType() const; const QByteArray &bytes() const; @@ -60,8 +91,10 @@ signals: private: mtpFileLoaderQueue *queue; - bool inQueue, complete, triedLocal; - + bool inQueue, complete; + LocalLoadStatus _localStatus; + + bool tryLoadLocal(); void cancelRequests(); typedef QMap Requests; @@ -80,7 +113,7 @@ private: bool partFailed(const RPCError &error); int32 dc; - mtpTypeId locationType; // 0 or mtpc_inputVideoFileLocation / mtpc_inputAudioFileLocation / mtpc_inputDocumentFileLocation + LocationType _locationType; uint64 volume; // for photo locations int32 local; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index fa7154f5a6..7bb04408df 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -646,7 +646,7 @@ id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb) void VideoData::save(const QString &toFile) { cancel(true); - loader = new mtpFileLoader(dc, id, access, mtpc_inputVideoFileLocation, toFile, size); + loader = new mtpFileLoader(dc, id, access, VideoFileLocation, toFile, size); loader->connect(loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(videoLoadProgress(mtpFileLoader*))); loader->connect(loader, SIGNAL(failed(mtpFileLoader*, bool)), App::main(), SLOT(videoLoadFailed(mtpFileLoader*, bool))); loader->start(); @@ -754,7 +754,7 @@ id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size void AudioData::save(const QString &toFile) { cancel(true); - loader = new mtpFileLoader(dc, id, access, mtpc_inputAudioFileLocation, toFile, size, (size < AudioVoiceMsgInMemory)); + loader = new mtpFileLoader(dc, id, access, AudioFileLocation, toFile, size, (size < AudioVoiceMsgInMemory)); loader->connect(loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(audioLoadProgress(mtpFileLoader*))); loader->connect(loader, SIGNAL(failed(mtpFileLoader*, bool)), App::main(), SLOT(audioLoadFailed(mtpFileLoader*, bool))); loader->start(); @@ -940,7 +940,7 @@ void DocumentData::setattributes(const QVector &attributes void DocumentData::save(const QString &toFile) { cancel(true); bool isSticker = (type == StickerDocument) && (dimensions.width() > 0) && (dimensions.height() > 0) && (size < StickerInMemory); - loader = new mtpFileLoader(dc, id, access, mtpc_inputDocumentFileLocation, toFile, size, isSticker); + loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, toFile, size, isSticker); loader->connect(loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(documentLoadProgress(mtpFileLoader*))); loader->connect(loader, SIGNAL(failed(mtpFileLoader*, bool)), App::main(), SLOT(documentLoadFailed(mtpFileLoader*, bool))); loader->start(); diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 1249c32e8a..a4932d05b3 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -94,7 +94,6 @@ TitleWidget::TitleWidget(Window *window) void TitleWidget::paintEvent(QPaintEvent *e) { QPainter p(this); - LOG(("TITLE")); p.fillRect(QRect(0, 0, width(), st::titleHeight), st::titleBG->b); if (!_cancel.isHidden()) { p.setPen(st::titleTextButton.color->p); diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index ada7a92d3a..9fcd3542ea 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -7,13 +7,11 @@ CFBundleGetInfoString Telegram Desktop messaging app CFBundleIdentifier - com.tdesktop.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundlePackageType APPL CFBundleShortVersionString 0.9.2 - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) CFBundleSignature ???? CFBundleURLTypes @@ -31,6 +29,8 @@ + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) NOTE NSPrincipalClass diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index 02e62138a2..1f49f4f1c4 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1340,7 +1340,7 @@ 6DB9C3763D02B1415CD9D565 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0630; + LastUpgradeCheck = 0700; TargetAttributes = { 7CCA95B9FCAD34D929431AD6 = { DevelopmentTeam = 63FLR8MQA9; @@ -1703,6 +1703,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; OBJROOT = ./../Mac/DebugIntermediate; + PRODUCT_BUNDLE_IDENTIFIER = "com.tdesktop.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "Meta Compile"; QT_LIBRARY_SUFFIX = _debug; SDKROOT = macosx; @@ -1721,6 +1722,7 @@ GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; LLVM_LTO = YES; OBJROOT = ./../Mac/ReleaseIntermediate; + PRODUCT_BUNDLE_IDENTIFIER = "com.tdesktop.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "Meta Compile"; QT_LIBRARY_SUFFIX = ""; SDKROOT = macosx; @@ -1880,6 +1882,7 @@ DYLIB_COMPATIBILITY_VERSION = 0.9; DYLIB_CURRENT_VERSION = 0.9.2; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_LINK_WITH_DYNAMIC_LIBRARIES = NO; @@ -2005,6 +2008,7 @@ LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; OBJROOT = ./../Mac/ReleaseIntermediate; + PRODUCT_BUNDLE_IDENTIFIER = "com.tdesktop.$(PRODUCT_NAME:rfc1034identifier)"; QT_LIBRARY_SUFFIX = ""; SDKROOT = macosx; SYMROOT = ./../Mac; @@ -2020,6 +2024,7 @@ GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; MACOSX_DEPLOYMENT_TARGET = 10.8; OBJROOT = ./../Mac/DebugIntermediate; + PRODUCT_BUNDLE_IDENTIFIER = "com.tdesktop.$(PRODUCT_NAME:rfc1034identifier)"; QT_LIBRARY_SUFFIX = _debug; SDKROOT = macosx; SYMROOT = ./../Mac;