From ff481c810fa2c07aa721493fac9ec687c630c334 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 1 Jan 2016 15:42:06 +0800 Subject: [PATCH] trying to optimize ClipReader --- Telegram/SourceFiles/dropdown.cpp | 2 +- Telegram/SourceFiles/gui/animation.cpp | 168 +++++++++++++++--------- Telegram/SourceFiles/gui/animation.h | 18 ++- Telegram/SourceFiles/localstorage.cpp | 22 ++++ Telegram/SourceFiles/settingswidget.cpp | 26 ++-- Telegram/SourceFiles/window.cpp | 10 +- 6 files changed, 159 insertions(+), 87 deletions(-) diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 015a815c18becf..458504bf7d9512 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -1303,7 +1303,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) { } void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) { - InlinePaintContext context(getms(), false, _previewShown, false); + InlinePaintContext context(getms(), false, Ui::isLayerShown() || Ui::isMediaViewShown() || _previewShown, false); int32 top = st::emojiPanHeader; int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width()); diff --git a/Telegram/SourceFiles/gui/animation.cpp b/Telegram/SourceFiles/gui/animation.cpp index 79c64b8d3a1072..7d43fb68e14686 100644 --- a/Telegram/SourceFiles/gui/animation.cpp +++ b/Telegram/SourceFiles/gui/animation.cpp @@ -184,7 +184,7 @@ void AnimationManager::clipCallback(ClipReader *reader, qint32 threadIndex, qint ClipReader::callback(reader, threadIndex, ClipReaderNotification(notification)); } -QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, QImage &cache, bool hasAlpha) { +QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, bool hasAlpha, QImage &cache) { bool badSize = (original.width() != request.framew) || (original.height() != request.frameh); bool needOuter = (request.outerw != request.framew) || (request.outerh != request.frameh); if (badSize || needOuter || hasAlpha || request.rounded) { @@ -258,14 +258,16 @@ ClipReader::Frame *ClipReader::frameToShow() const { // 0 means not ready return _frames + (((step + 1) / 2) % 3); } -ClipReader::Frame *ClipReader::frameToWrite() const { // 0 means not ready - int32 step = _step.loadAcquire(); - if (step == FirstFrameNotReadStep) { - return _frames; - } else if (step == WaitingForRequestStep) { +ClipReader::Frame *ClipReader::frameToWrite(int32 *index) const { // 0 means not ready + int32 step = _step.loadAcquire(), i = 0; + if (step == WaitingForRequestStep) { + if (index) *index = 0; return 0; + } else if (step != FirstFrameNotReadStep) { + i = (((step + 3) / 2) % 3); } - return _frames + (((step + 3) / 2) % 3); + if (index) *index = i; + return _frames + i; } ClipReader::Frame *ClipReader::frameToRequestOther(bool check) const { @@ -342,10 +344,10 @@ QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 oute frame->request.frameh = frameh * factor; frame->request.outerw = outerw * factor; frame->request.outerh = outerh * factor; - frame->pix = QPixmap(); - QImage cache; - frame->pix = _prepareFrame(frame->request, frame->original, cache, true); + QImage cacheForResize; + frame->pix = QPixmap(); + frame->pix = _prepareFrame(frame->request, frame->original, true, cacheForResize); Frame *other = frameToRequestOther(true); if (other) other->request = frame->request; @@ -830,8 +832,7 @@ class ClipReaderPrivate { , _location(_data.isEmpty() ? new FileLocation(location) : 0) , _accessed(false) , _implementation(0) - , _currentHasAlpha(true) - , _nextHasAlpha(true) + , _frame(_frames) , _width(0) , _height(0) , _previousMs(0) @@ -850,12 +851,12 @@ class ClipReaderPrivate { if (!_implementation && !init()) { return error(); } - if (_currentOriginal.isNull()) { - if (!_implementation->readNextFrame(_currentOriginal, _currentHasAlpha, QSize())) { + if (_frame->original.isNull()) { + if (!_implementation->readNextFrame(_frame->original, _frame->alpha, QSize())) { return error(); } - _width = _currentOriginal.width(); - _height = _currentOriginal.height(); + _width = _frame->original.width(); + _height = _frame->original.height(); return ClipProcessReinit; } return ClipProcessWait; @@ -868,12 +869,12 @@ class ClipReaderPrivate { return start(ms); } - if (_current.isNull()) { // first frame read, but not yet prepared - _currentOriginal.setDevicePixelRatio(_request.factor); + if (_frame->pix.isNull()) { // first frame read, but not yet prepared + _frame->original.setDevicePixelRatio(_request.factor); _previousMs = _currentMs; _currentMs = ms; - _current = _prepareFrame(_request, _currentOriginal, _currentCache, _currentHasAlpha); + _frame->pix = _prepareFrame(_request, _frame->original, _frame->alpha, _frame->cache); if (!prepareNextFrame()) { return error(); @@ -906,20 +907,16 @@ class ClipReaderPrivate { void swapBuffers(uint64 ms = 0) { _previousMs = _currentMs; _currentMs = qMax(ms, _nextUpdateMs); - qSwap(_currentOriginal, _nextOriginal); - qSwap(_current, _next); - qSwap(_currentCache, _nextCache); - qSwap(_currentHasAlpha, _nextHasAlpha); } bool prepareNextFrame() { - if (!_implementation->readNextFrame(_nextOriginal, _nextHasAlpha, QSize(_request.framew, _request.frameh))) { + if (!_implementation->readNextFrame(_frame->original, _frame->alpha, QSize(_request.framew, _request.frameh))) { return false; } _nextUpdateMs = _currentMs + nextFrameDelay(); - _nextOriginal.setDevicePixelRatio(_request.factor); - _next = QPixmap(); - _next = _prepareFrame(_request, _nextOriginal, _nextCache, _nextHasAlpha); + _frame->original.setDevicePixelRatio(_request.factor); + _frame->pix = QPixmap(); + _frame->pix = _prepareFrame(_request, _frame->original, _frame->alpha, _frame->cache); return true; } @@ -979,9 +976,16 @@ class ClipReaderPrivate { ClipReaderImplementation *_implementation; ClipFrameRequest _request; - QPixmap _current, _next; - QImage _currentOriginal, _nextOriginal, _currentCache, _nextCache; - bool _currentHasAlpha, _nextHasAlpha; + struct Frame { + Frame() : alpha(true) { + } + QPixmap pix; + QImage original, cache; + bool alpha; + }; + Frame _frames[3]; + Frame *_frame; + int32 _width, _height; uint64 _previousMs, _currentMs, _nextUpdateMs; @@ -1016,34 +1020,58 @@ void ClipReadManager::start(ClipReader *reader) { } void ClipReadManager::update(ClipReader *reader) { - QMutexLocker lock(&_readerPointersMutex); - _readerPointers.insert(reader, reader->_private); + QReadLocker lock(&_readerPointersMutex); + ReaderPointers::const_iterator i = _readerPointers.constFind(reader); + if (i == _readerPointers.cend()) { + lock.unlock(); + + QWriteLocker lock(&_readerPointersMutex); + _readerPointers.insert(reader, MutableAtomicInt(1)); + } else { + i->v.storeRelease(1); + } emit processDelayed(); } void ClipReadManager::stop(ClipReader *reader) { - QMutexLocker lock(&_readerPointersMutex); + if (!carries(reader)) return; + + QWriteLocker lock(&_readerPointersMutex); _readerPointers.remove(reader); emit processDelayed(); } bool ClipReadManager::carries(ClipReader *reader) const { - QMutexLocker lock(&_readerPointersMutex); + QReadLocker lock(&_readerPointersMutex); return _readerPointers.contains(reader); } -bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) { - QMutexLocker lock(&_readerPointersMutex); +ClipReadManager::ReaderPointers::iterator ClipReadManager::unsafeFindReaderPointer(ClipReaderPrivate *reader) { ReaderPointers::iterator it = _readerPointers.find(reader->_interface); - if (it != _readerPointers.cend() && it.key()->_private != reader) { - it = _readerPointers.end(); // it is a new reader which was realloced in the same address - } + + // could be a new reader which was realloced in the same address + return (it == _readerPointers.cend() || it.key()->_private == reader) ? it : _readerPointers.end(); +} + +ClipReadManager::ReaderPointers::const_iterator ClipReadManager::constUnsafeFindReaderPointer(ClipReaderPrivate *reader) const { + ReaderPointers::const_iterator it = _readerPointers.constFind(reader->_interface); + + // could be a new reader which was realloced in the same address + return (it == _readerPointers.cend() || it.key()->_private == reader) ? it : _readerPointers.cend(); +} + +bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) { + QReadLocker lock(&_readerPointersMutex); + ReaderPointers::const_iterator it = constUnsafeFindReaderPointer(reader); if (result == ClipProcessError) { if (it != _readerPointers.cend()) { it.key()->error(); emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit); - _readerPointers.erase(it); + lock.unlock(); + QWriteLocker lock(&_readerPointersMutex); + ReaderPointers::iterator i = unsafeFindReaderPointer(reader); + if (i != _readerPointers.cend()) _readerPointers.erase(i); } return false; } @@ -1066,9 +1094,9 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess if (result == ClipProcessReinit || result == ClipProcessRepaint || result == ClipProcessStarted) { ClipReader::Frame *frame = it.key()->frameToWrite(); t_assert(frame != 0); - frame->pix = QPixmap(); - frame->pix = reader->_current; - frame->original = reader->_currentOriginal; + frame->clear(); + frame->pix = reader->_frame->pix; + frame->original = reader->_frame->original; frame->displayed = false; it.key()->moveToNextWrite(); if (result == ClipProcessReinit) { @@ -1082,7 +1110,7 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess ClipReadManager::ResultHandleState ClipReadManager::handleResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) { if (!handleProcessResult(reader, result, ms)) { - _loadLevel.fetchAndAddRelaxed(-1 * (reader->_currentOriginal.isNull() ? AverageGifSize : reader->_width * reader->_height)); + _loadLevel.fetchAndAddRelaxed(-1 * (reader->_frame->original.isNull() ? AverageGifSize : reader->_width * reader->_height)); delete reader; return ResultHandleRemove; } @@ -1110,27 +1138,37 @@ void ClipReadManager::process() { uint64 ms = getms(), minms = ms + 86400 * 1000ULL; { - QMutexLocker lock(&_readerPointersMutex); - for (ReaderPointers::iterator i = _readerPointers.begin(), e = _readerPointers.end(); i != e; ++i) { - if (i.value()) { - Readers::iterator it = _readers.find(i.value()); - if (it == _readers.cend()) { - _readers.insert(i.value(), 0); + QReadLocker lock(&_readerPointersMutex); + for (ReaderPointers::iterator it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) { + if (it->v.loadAcquire()) { + Readers::iterator i = _readers.find(it.key()->_private); + if (i == _readers.cend()) { + _readers.insert(it.key()->_private, 0); } else { - it.value() = ms; - if (it.key()->_paused && !i.key()->_paused.loadAcquire()) { - it.key()->_paused = false; + i.value() = ms; + if (i.key()->_paused && !it.key()->_paused.loadAcquire()) { + i.key()->_paused = false; } } - ClipReader::Frame *frame = i.key()->frameToWrite(); - if (frame) i.value()->_request = frame->request; - i.value() = 0; + ClipReader::Frame *frame = it.key()->frameToWrite(); + if (frame) it.key()->_private->_request = frame->request; + it->v.storeRelease(0); } } } for (Readers::iterator i = _readers.begin(), e = _readers.end(); i != e;) { if (i.value() <= ms) { + { + QReadLocker lock(&_readerPointersMutex); + ReaderPointers::const_iterator it = constUnsafeFindReaderPointer(i.key()); + if (it != _readerPointers.cend()) { + int32 index = 0; + ClipReader::Frame *frame = it.key()->frameToWrite(&index); + if (frame) frame->clear(); + i.key()->_frame = i.key()->_frames + index; + } + } ClipProcessResult result = i.key()->process(ms); ResultHandleState state = handleResult(i.key(), result, ms); @@ -1167,13 +1205,13 @@ void ClipReadManager::finish() { } void ClipReadManager::clear() { - QMutexLocker lock(&_readerPointersMutex); - for (ReaderPointers::iterator i = _readerPointers.begin(), e = _readerPointers.end(); i != e; ++i) { - if (i.value()) { - i.key()->_private = 0; - } - } - _readerPointers.clear(); + { + QWriteLocker lock(&_readerPointersMutex); + for (ReaderPointers::iterator it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) { + it.key()->_private = 0; + } + _readerPointers.clear(); + } for (Readers::iterator i = _readers.begin(), e = _readers.end(); i != e; ++i) { delete i.key(); @@ -1195,12 +1233,12 @@ MTPDocumentAttribute clipReadAnimatedAttributes(const QString &fname, const QByt if (reader->readNextFrame(cover, hasAlpha, QSize())) { if (cover.width() > 0 && cover.height() > 0 && cover.width() < cover.height() * 10 && cover.height() < cover.width() * 10) { if (hasAlpha) { - QImage cache; + QImage cacheForResize; ClipFrameRequest request; request.framew = request.outerw = cover.width(); request.frameh = request.outerh = cover.height(); request.factor = 1; - cover = _prepareFrame(request, cover, cache, hasAlpha).toImage(); + cover = _prepareFrame(request, cover, hasAlpha, cacheForResize).toImage(); } int32 duration = reader->duration(); delete reader; diff --git a/Telegram/SourceFiles/gui/animation.h b/Telegram/SourceFiles/gui/animation.h index 4ae1fa8e107e0a..ef932df53b6f57 100644 --- a/Telegram/SourceFiles/gui/animation.h +++ b/Telegram/SourceFiles/gui/animation.h @@ -563,6 +563,10 @@ class ClipReader { struct Frame { Frame() : displayed(false), when(0) { } + void clear() { + pix = QPixmap(); + original = QImage(); + } QPixmap pix; QImage original; ClipFrameRequest request; @@ -571,7 +575,7 @@ class ClipReader { }; mutable Frame _frames[3]; Frame *frameToShow() const; // 0 means not ready - Frame *frameToWrite() const; // 0 means not ready + Frame *frameToWrite(int32 *index = 0) const; // 0 means not ready Frame *frameToRequestOther(bool check) const; void moveToNextShow() const; void moveToNextWrite() const; @@ -629,9 +633,17 @@ public slots: void clear(); QAtomicInt _loadLevel; - typedef QMap ReaderPointers; + struct MutableAtomicInt { + MutableAtomicInt(int value) : v(value) { + } + mutable QAtomicInt v; + }; + typedef QMap ReaderPointers; ReaderPointers _readerPointers; - mutable QMutex _readerPointersMutex; + mutable QReadWriteLock _readerPointersMutex; + + ReaderPointers::const_iterator constUnsafeFindReaderPointer(ClipReaderPrivate *reader) const; + ReaderPointers::iterator unsafeFindReaderPointer(ClipReaderPrivate *reader); bool handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index de6800d5bdc413..d7dfc9d9e033d0 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -3594,6 +3594,7 @@ namespace Local { struct ClearManagerData { QThread *thread; StorageMap images, stickers, audios; + WebFilesMap webFiles; QMutex mutex; QList tasks; bool working; @@ -3693,6 +3694,22 @@ namespace Local { _storageStickersSize = 0; _mapChanged = true; } + if (data->webFiles.isEmpty()) { + data->webFiles = _webFilesMap; + } else { + for (WebFilesMap::const_iterator i = _webFilesMap.cbegin(), e = _webFilesMap.cend(); i != e; ++i) { + QString k = i.key(); + while (data->webFiles.constFind(k) != data->webFiles.cend()) { + k += '#'; + } + data->webFiles.insert(k, i.value()); + } + } + if (!_webFilesMap.isEmpty()) { + _webFilesMap.clear(); + _storageWebFilesSize = 0; + _writeLocations(); + } if (data->audios.isEmpty()) { data->audios = _audiosMap; } else { @@ -3745,6 +3762,7 @@ namespace Local { int task = 0; bool result = false; StorageMap images, stickers, audios; + WebFilesMap webFiles; { QMutexLocker lock(&data->mutex); if (data->tasks.isEmpty()) { @@ -3755,6 +3773,7 @@ namespace Local { images = data->images; stickers = data->stickers; audios = data->audios; + webFiles = data->webFiles; } switch (task) { case ClearManagerAll: { @@ -3786,6 +3805,9 @@ namespace Local { for (StorageMap::const_iterator i = audios.cbegin(), e = audios.cend(); i != e; ++i) { clearKey(i.value().first, UserPath); } + for (WebFilesMap::const_iterator i = webFiles.cbegin(), e = webFiles.cend(); i != e; ++i) { + clearKey(i.value().first, UserPath); + } result = true; break; } diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index 6668bfc4ea54a1..ea3cfe7e858f2e 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -462,7 +462,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { top += st::setHeaderSkip; #ifndef TDESKTOP_DISABLE_AUTOUPDATE - top += _autoUpdate.height(); + top += _autoUpdate.height(); QString textToDraw; if (cAutoUpdate()) { switch (_updatingState) { @@ -485,7 +485,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { if (cPlatform() == dbipWindows) { top += _workmodeTray.height() + st::setLittleSkip; top += _workmodeWindow.height() + st::setSectionSkip; - + top += _autoStart.height() + st::setLittleSkip; top += _startMinimized.height() + st::setSectionSkip; @@ -500,12 +500,12 @@ void SettingsInner::paintEvent(QPaintEvent *e) { p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_scale_label)); top += st::setHeaderSkip; top += _dpiAutoScale.height() + st::setLittleSkip; - + top += _dpiSlider.height() + st::dpiFont4->height; int32 sLeft = _dpiSlider.x() + _dpiWidth1 / 2, sWidth = _dpiSlider.width(); float64 sStep = (sWidth - _dpiWidth1 / 2 - _dpiWidth4 / 2) / float64(dbisScaleCount - 2); p.setFont(st::dpiFont1->f); - + p.setPen((scaleIs(dbisOne) ? st::dpiActive : st::dpiInactive)->p); p.drawText(sLeft + qRound(0 * sStep) - _dpiWidth1 / 2, top - (st::dpiFont4->height - st::dpiFont1->height) / 2 - st::dpiFont1->descent, scaleLabel(dbisOne)); p.setFont(st::dpiFont2->f); @@ -519,7 +519,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { p.drawText(sLeft + qRound(3 * sStep) - _dpiWidth4 / 2, top - (st::dpiFont4->height - st::dpiFont4->height) / 2 - st::dpiFont4->descent, scaleLabel(dbisTwo)); p.setFont(st::linkFont->f); } - + if (self()) { // chat options p.setFont(st::setHeaderFont->f); @@ -575,7 +575,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { top += st::setHeaderSkip; - int32 cntImages = Local::hasImages() + Local::hasStickers(), cntAudios = Local::hasAudios(); + int32 cntImages = Local::hasImages() + Local::hasStickers() + Local::hasWebFiles(), cntAudios = Local::hasAudios(); if (cntImages > 0 && cntAudios > 0) { if (_localStorageHeight != 2) { cntAudios = 0; @@ -587,7 +587,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { } } if (cntImages > 0) { - QString cnt = lng_settings_images_cached(lt_count, cntImages, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize())); + QString cnt = lng_settings_images_cached(lt_count, cntImages, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize() + Local::storageWebFilesSize())); p.drawText(_left + st::setHeaderLeft, top + st::linkFont->ascent, cnt); } if (_localStorageHeight == 2) top += _localStorageClear.height() + st::setLittleSkip; @@ -644,7 +644,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { p.setPen(st::setHeaderColor->p); p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_advanced)); top += st::setHeaderSkip; - + p.setFont(st::linkFont->f); p.setPen(st::black->p); if (self()) { @@ -702,7 +702,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { if (cPlatform() == dbipWindows) { _workmodeTray.move(_left, top); top += _workmodeTray.height() + st::setLittleSkip; _workmodeWindow.move(_left, top); top += _workmodeWindow.height() + st::setSectionSkip; - + _autoStart.move(_left, top); top += _autoStart.height() + st::setLittleSkip; _startMinimized.move(_left, top); top += _startMinimized.height() + st::setSectionSkip; @@ -715,7 +715,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { _dpiAutoScale.move(_left, top); top += _dpiAutoScale.height() + st::setLittleSkip; _dpiSlider.move(_left, top); top += _dpiSlider.height() + st::dpiFont4->height; } - + // chat options if (self()) { top += st::setHeaderSkip; @@ -739,7 +739,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { // local storage _localStorageClear.move(_left + st::setWidth - _localStorageClear.width(), top + st::setHeaderTop + st::setHeaderFont->ascent - st::linkFont->ascent); top += st::setHeaderSkip; - if ((Local::hasImages() || Local::hasStickers()) && Local::hasAudios()) { + if ((Local::hasImages() || Local::hasStickers() || Local::hasWebFiles()) && Local::hasAudios()) { _localStorageHeight = 2; top += _localStorageClear.height() + st::setLittleSkip; } else { @@ -1031,7 +1031,7 @@ void SettingsInner::showAll() { _workmodeTray.hide(); } _workmodeWindow.hide(); - + _autoStart.hide(); _startMinimized.hide(); @@ -1163,7 +1163,7 @@ void SettingsInner::onUpdatePhotoCancel() { void SettingsInner::onUpdatePhoto() { saveError(); - QStringList imgExtensions(cImgExtensions()); + QStringList imgExtensions(cImgExtensions()); QString filter(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;All files (*.*)")); QImage img; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 0351168269e24c..9a35a4ef6847fd 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -453,9 +453,9 @@ void Window::firstShow() { trayIconMenu = new QMenu(this); trayIconMenu->setFont(QFont("Tahoma")); #endif - QString notificationItem = lang(cDesktopNotify() + QString notificationItem = lang(cDesktopNotify() ? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray); - + if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) { trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true); trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true); @@ -940,7 +940,7 @@ void Window::paintEvent(QPaintEvent *e) { HitTestType Window::hitTest(const QPoint &p) const { int x(p.x()), y(p.y()), w(width()), h(height()); - + const int32 raw = psResizeRowWidth(); if (!windowState().testFlag(Qt::WindowMaximized)) { if (y < raw) { @@ -1019,7 +1019,7 @@ void Window::mouseMoveEvent(QMouseEvent *e) { if (dragging) { if (windowState().testFlag(Qt::WindowMaximized)) { setWindowState(windowState() & ~Qt::WindowMaximized); - + dragStart = e->globalPos() - frameGeometry().topLeft(); } else { move(e->globalPos() - dragStart); @@ -1260,7 +1260,7 @@ Window::TempDirState Window::localStorageState() { if (_clearManager && _clearManager->hasTask(Local::ClearManagerStorage)) { return TempDirRemoving; } - return (Local::hasImages() || Local::hasStickers() || Local::hasAudios()) ? TempDirExists : TempDirEmpty; + return (Local::hasImages() || Local::hasStickers() || Local::hasWebFiles() || Local::hasAudios()) ? TempDirExists : TempDirEmpty; } void Window::tempDirDelete(int task) {