Updated TDesktop sources to 2.1.17 beta

This commit is contained in:
Eric Kotato 2020-07-03 04:39:44 +03:00
commit f633857744
90 changed files with 610 additions and 348 deletions

View file

@ -738,6 +738,8 @@ PRIVATE
media/audio/media_audio_track.h
media/audio/media_child_ffmpeg_loader.cpp
media/audio/media_child_ffmpeg_loader.h
media/audio/media_openal_functions.cpp
media/audio/media_openal_functions.h
media/clip/media_clip_check_streaming.cpp
media/clip/media_clip_check_streaming.h
media/clip/media_clip_ffmpeg.cpp

View file

@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.1.16.0" />
Version="2.1.17.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>

View file

@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,16,0
PRODUCTVERSION 2,1,16,0
FILEVERSION 2,1,17,0
PRODUCTVERSION 2,1,17,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "2.1.16.0"
VALUE "FileVersion", "2.1.17.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.16.0"
VALUE "ProductVersion", "2.1.17.0"
END
END
BLOCK "VarFileInfo"

View file

@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,16,0
PRODUCTVERSION 2,1,16,0
FILEVERSION 2,1,17,0
PRODUCTVERSION 2,1,17,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "2.1.16.0"
VALUE "FileVersion", "2.1.17.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.16.0"
VALUE "ProductVersion", "2.1.17.0"
END
END
BLOCK "VarFileInfo"

View file

@ -1364,7 +1364,10 @@ void RevokePublicLinkBox::prepare() {
addButton(tr::lng_cancel(), [=] { closeBox(); });
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_inner->resizeToWidth(st::boxWideWidth);
setDimensions(st::boxWideWidth, _innerTop + _inner->height());

View file

@ -203,7 +203,10 @@ BackgroundBox::Inner::Inner(
}
requestPapers();
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [=](const Update &update) {
if (update.paletteChanged()) {

View file

@ -419,9 +419,10 @@ BackgroundPreviewBox::BackgroundPreviewBox(
if (_media) {
_media->thumbnailWanted(_paper.fileOrigin());
}
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() {

View file

@ -891,9 +891,10 @@ ConfirmInviteBox::ConfirmInviteBox(
_photo = photo->createMediaView();
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) {
subscribe(_session->downloaderTaskFinished(), [=] {
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
} else {
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(

View file

@ -259,9 +259,9 @@ auto AddButtonWithLoader(
)
);
*buttonState = localLoaderValues->events_starting_with(
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
) | rpl::map([=](Loader *loader) {
*buttonState = localLoaderValues->events_starting_with(
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
) | rpl::map([=](Loader *loader) {
return (loader && loader->id() == id)
? loader->state()
: rpl::single(

View file

@ -291,7 +291,8 @@ EditCaptionBox::EditCaptionBox(
Assert(_thumbnailImageLoaded || _refreshThumbnail);
if (!_thumbnailImageLoaded) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (_thumbnailImageLoaded
|| (_photoMedia && !_photoMedia->image(PhotoSize::Large))
|| (_documentMedia && !_documentMedia->thumbnail())) {
@ -299,7 +300,7 @@ EditCaptionBox::EditCaptionBox(
}
_refreshThumbnail();
update();
});
}, lifetime());
}
_field.create(
this,

View file

@ -698,9 +698,10 @@ PeerListContent::PeerListContent(
, _st(st)
, _controller(controller)
, _rowHeight(_st.item.height) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
using UpdateFlag = Data::PeerUpdate::Flag;
_controller->session().changes().peerUpdates(

View file

@ -570,9 +570,10 @@ ShareBox::Inner::Inner(
update.oldFirstLetters);
}, lifetime());
subscribe(_navigation->session().downloaderTaskFinished(), [=] {
_navigation->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
if (update.paletteChanged()) {

View file

@ -308,7 +308,10 @@ StickerSetBox::Inner::Inner(
_controller->session().api().updateStickers();
subscribe(_controller->session().downloaderTaskFinished(), [this] { update(); });
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
setMouseTracking(true);
}

View file

@ -1002,10 +1002,12 @@ Main::Session &StickersBox::Inner::session() const {
}
void StickersBox::Inner::setup() {
subscribe(session().downloaderTaskFinished(), [this] {
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
readVisibleSets();
});
}, lifetime());
setMouseTracking(true);
}

View file

@ -446,9 +446,10 @@ void Panel::initLayout() {
}, lifetime());
processUserPhoto();
subscribe(_user->session().downloaderTaskFinished(), [=] {
_user->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
refreshUserPhoto();
});
}, lifetime());
createDefaultCacheImage();
Ui::Platform::InitOnTopPanel(this);

View file

@ -161,12 +161,14 @@ bool BotKeyboard::moderateKeyActivate(int key) {
App::activateBotCommand(item, 0, index);
return true;
}
} else if (key == Qt::Key_Q) {
if (const auto user = item->history()->peer->asUser()) {
if (user->isBot() && item->from() == user) {
} else if (const auto user = item->history()->peer->asUser()) {
if (user->isBot() && item->from() == user) {
if (key == Qt::Key_Q) {
App::sendBotCommand(user, user, qsl("/translate"));
return true;
} else if (key == Qt::Key_W) {
App::sendBotCommand(user, user, qsl("/eng"));
}
return true;
}
}
}

View file

@ -571,16 +571,20 @@ bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::KeyPress) {
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
if (!(ev->modifiers() & (Qt::AltModifier | Qt::ControlModifier | Qt::ShiftModifier | Qt::MetaModifier))) {
const auto key = ev->key();
if (!hidden) {
if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down || (!_srows.empty() && (ev->key() == Qt::Key_Left || ev->key() == Qt::Key_Right))) {
return _inner->moveSel(ev->key());
} else if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) {
if (key == Qt::Key_Up || key == Qt::Key_Down || (!_srows.empty() && (key == Qt::Key_Left || key == Qt::Key_Right))) {
return _inner->moveSel(key);
} else if (key == Qt::Key_Enter || key == Qt::Key_Return) {
return _inner->chooseSelected(ChooseMethod::ByEnter);
}
}
if (moderate && ((ev->key() >= Qt::Key_1 && ev->key() <= Qt::Key_9) || ev->key() == Qt::Key_Q)) {
if (moderate
&& ((key >= Qt::Key_1 && key <= Qt::Key_9)
|| key == Qt::Key_Q
|| key == Qt::Key_W)) {
bool handled = false;
emit moderateKeyActivate(ev->key(), &handled);
emit moderateKeyActivate(key, &handled);
return handled;
}
} else if (ev->modifiers() & Qt::ControlModifier) {
@ -608,9 +612,10 @@ FieldAutocompleteInner::FieldAutocompleteInner(
, _brows(brows)
, _srows(srows)
, _previewTimer([=] { showPreview(); }) {
subscribe(
controller->session().downloaderTaskFinished(),
[=] { update(); });
controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
}
void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {

View file

@ -153,9 +153,10 @@ GifsListWidget::GifsListWidget(
refreshSavedGifs();
}, lifetime());
subscribe(controller->session().downloaderTaskFinished(), [this] {
controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(controller->gifPauseLevelChanged(), [=] {
if (!controller->isGifPausedAtLeastFor(

View file

@ -204,7 +204,7 @@ std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
if (!strong->image) {
strong->load = nullptr;
strong->image.emplace(std::move(image));
_session->downloaderTaskFinished().notify();
_session->notifyDownloaderTaskFinished();
}
}
}

View file

@ -104,9 +104,7 @@ struct StickerIcon {
};
class StickersListWidget::Footer
: public TabbedSelector::InnerFooter
, private base::Subscriber {
class StickersListWidget::Footer : public TabbedSelector::InnerFooter {
public:
explicit Footer(not_null<StickersListWidget*> parent);
@ -131,7 +129,7 @@ protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
bool event(QEvent *e) override;
bool eventHook(QEvent *e) override;
void processHideFinished() override;
@ -248,9 +246,10 @@ StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent)
_iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth;
subscribe(_pan->session().downloaderTaskFinished(), [=] {
_pan->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
void StickersListWidget::Footer::clearHeavyData() {
@ -599,7 +598,7 @@ void StickersListWidget::Footer::finishDragging() {
updateSelected();
}
bool StickersListWidget::Footer::event(QEvent *e) {
bool StickersListWidget::Footer::eventHook(QEvent *e) {
if (e->type() == QEvent::TouchBegin) {
} else if (e->type() == QEvent::Wheel) {
if (!_icons.empty()
@ -608,7 +607,7 @@ bool StickersListWidget::Footer::event(QEvent *e) {
scrollByWheelEvent(static_cast<QWheelEvent*>(e));
}
}
return InnerFooter::event(e);
return InnerFooter::eventHook(e);
}
void StickersListWidget::Footer::scrollByWheelEvent(
@ -889,12 +888,13 @@ StickersListWidget::StickersListWidget(
Box<StickersBox>(controller, StickersBox::Section::Installed));
});
subscribe(session().downloaderTaskFinished(), [=] {
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (isVisible()) {
update();
readVisibleFeatured(getVisibleTop(), getVisibleBottom());
}
});
}, lifetime());
session().changes().peerUpdates(
Data::PeerUpdate::Flag::StickersSet

View file

@ -938,7 +938,7 @@ void TabbedSelector::Inner::panelHideFinished() {
}
TabbedSelector::InnerFooter::InnerFooter(QWidget *parent)
: TWidget(parent) {
: RpWidget(parent) {
resize(st::emojiPanWidth, st::emojiFooterHeight);
}

View file

@ -276,7 +276,7 @@ private:
};
class TabbedSelector::InnerFooter : public TWidget {
class TabbedSelector::InnerFooter : public Ui::RpWidget {
public:
InnerFooter(QWidget *parent);

View file

@ -24,36 +24,43 @@ std::map<int, const char*> BetaLogs() {
return {
{
1009020,
"\xE2\x80\xA2 Fix crash in shared links search.\n"
"- Fix crash in shared links search.\n"
"\xE2\x80\xA2 Fix blurred thumbnails in albums with video files.\n"
"- Fix blurred thumbnails in albums with video files.\n"
"\xE2\x80\xA2 Fix a possible crash in animated stickers rendering."
"- Fix a possible crash in animated stickers rendering."
},
{
1009022,
"\xE2\x80\xA2 Organize chats into Chat Folders "
"if you have too many chats.\n"
"- Organize chats into Chat Folders if you have too many chats.\n"
},
{
2000001,
"\xE2\x80\xA2 Switch between folders using Ctrl+1, ..., Ctrl+8.\n"
"- Switch between folders using Ctrl+1, ..., Ctrl+8.\n"
"\xE2\x80\xA2 Fix crash when a pinned in folder chat "
"was added to archive.\n"
"- Fix crash when a pinned in folder chat was added to archive.\n"
"\xE2\x80\xA2 Fix font issues in Linux version."
"- Fix font issues in Linux version."
},
{
2001008,
"\xE2\x80\xA2 Add support for full group message history export.\n"
"- Add support for full group message history export.\n"
"\xE2\x80\xA2 Allow export of a single chat message history "
"in JSON format."
"- Allow export of a single chat message history in JSON format."
},
{
2001014,
"\xE2\x80\xA2 Support for multiple accounts."
"- Support for multiple accounts."
},
{
2001017,
"- Fix messages editing in a non-active account.\n"
"- Fix large animated emoji messages editing.\n"
"- Fix high definition GIF animations opening in media viewer.\n"
"- Multiple crash fixes."
}
};
};
@ -196,10 +203,18 @@ void Changelogs::addBetaLog(int changeVersion, const char *changes) {
if (_oldVersion >= changeVersion) {
return;
}
const auto text = [&] {
static const auto simple = u"\n- "_q;
static const auto separator = QString::fromUtf8("\n\xE2\x80\xA2 ");
auto result = QString::fromUtf8(changes).trimmed();
if (result.startsWith(simple.midRef(1))) {
result = separator.mid(1) + result.mid(simple.size() - 1);
}
return result.replace(simple, separator);
}();
const auto version = FormatVersionDisplay(changeVersion);
const auto text = qsl("New in version %1:\n\n").arg(version)
+ QString::fromUtf8(changes).trimmed();
addLocalLog(text);
const auto log = qsl("New in version %1:\n\n").arg(version) + text;
addLocalLog(log);
}
} // namespace Core

View file

@ -458,7 +458,7 @@ void Settings::resetOnLastLogout() {
//_videoPipGeometry = QByteArray();
_dictionariesEnabled = std::vector<int>();
_autoDownloadDictionaries = true;
_mainMenuAccountsShown = false;
_mainMenuAccountsShown = true;
_tabbedSelectorSectionEnabled = false; // per-window
_floatPlayerColumn = Window::Column::Second; // per-window
_floatPlayerCorner = RectPart::TopRight; // per-window

View file

@ -464,7 +464,7 @@ private:
QByteArray _videoPipGeometry;
rpl::variable<std::vector<int>> _dictionariesEnabled;
rpl::variable<bool> _autoDownloadDictionaries = true;
rpl::variable<bool> _mainMenuAccountsShown = false;
rpl::variable<bool> _mainMenuAccountsShown = true;
bool _tabbedSelectorSectionEnabled = false; // per-window
Window::Column _floatPlayerColumn; // per-window
RectPart _floatPlayerCorner; // per-window

View file

@ -282,6 +282,19 @@ void Launcher::init() {
prepareSettings();
static QtMessageHandler originalMessageHandler = nullptr;
originalMessageHandler = qInstallMessageHandler([](
QtMsgType type,
const QMessageLogContext &context,
const QString &msg) {
if (originalMessageHandler) {
originalMessageHandler(type, context, msg);
}
if (Logs::DebugEnabled() || !Logs::started()) {
LOG((msg));
}
});
QApplication::setApplicationName(qsl("KotatogramDesktop"));
#if defined Q_OS_UNIX && !defined Q_OS_MAC && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)

View file

@ -74,11 +74,11 @@ const auto CommandByName = base::flat_map<QString, Command>{
{ qsl("first_chat") , Command::ChatFirst },
{ qsl("last_chat") , Command::ChatLast },
{ qsl("self_chat") , Command::ChatSelf },
{ qsl("previous_folder") , Command::FolderPrevious },
{ qsl("next_folder") , Command::FolderNext },
{ qsl("all_chats") , Command::ShowAllChats },
{ qsl("folder1") , Command::ShowFolder1 },
{ qsl("folder2") , Command::ShowFolder2 },
{ qsl("folder3") , Command::ShowFolder3 },
@ -137,11 +137,11 @@ const auto CommandNames = base::flat_map<Command, QString>{
{ Command::ChatFirst , qsl("first_chat") },
{ Command::ChatLast , qsl("last_chat") },
{ Command::ChatSelf , qsl("self_chat") },
{ Command::FolderPrevious , qsl("previous_folder") },
{ Command::FolderNext , qsl("next_folder") },
{ Command::ShowAllChats , qsl("all_chats") },
{ Command::ShowFolder1 , qsl("folder1") },
{ Command::ShowFolder2 , qsl("folder2") },
{ Command::ShowFolder3 , qsl("folder3") },

View file

@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/const_string.h"
#include "kotato/version.h"
#define TDESKTOP_REQUESTED_ALPHA_VERSION (2001007004ULL)
#define TDESKTOP_REQUESTED_ALPHA_VERSION (0ULL)
#ifdef TDESKTOP_ALLOW_CLOSED_ALPHA
#define TDESKTOP_ALPHA_VERSION TDESKTOP_REQUESTED_ALPHA_VERSION
@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Kotatogram Desktop"_cs;
constexpr auto AppFile = "Kotatogram"_cs;
constexpr auto AppVersion = 2001016;
constexpr auto AppVersionStr = "2.1.16";
constexpr auto AppVersion = 2001017;
constexpr auto AppVersionStr = "2.1.17";
constexpr auto AppBetaVersion = true;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View file

@ -26,7 +26,7 @@ void CloudImageView::set(
not_null<Main::Session*> session,
QImage image) {
_image.emplace(std::move(image));
session->downloaderTaskFinished().notify();
session->notifyDownloaderTaskFinished();
}
CloudImage::CloudImage() = default;

View file

@ -222,8 +222,7 @@ void CloudThemes::loadDocumentAndInvoke(
return;
}
if (!alreadyWaiting) {
base::ObservableViewer(
_session->downloaderTaskFinished()
_session->downloaderTaskFinished(
) | rpl::filter([=, &value] {
return value.documentMedia->loaded();
}) | rpl::start_with_next([=, &value] {

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_specific.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/view/media/history_view_gif.h"
#include "window/window_session_controller.h"
#include "storage/cache/storage_cache_database.h"
#include "boxes/confirm_box.h"
@ -340,7 +341,9 @@ void DocumentOpenClickHandler::Open(
|| data->isVideoMessage()) {
const auto msgId = context ? context->fullId() : FullMsgId();
Media::Player::instance()->playPause({ data, msgId });
} else if (context && data->isAnimation()) {
} else if (context
&& data->isAnimation()
&& HistoryView::Gif::CanPlayInline(data)) {
data->owner().requestAnimationPlayInline(context);
} else {
Core::App().showDocument(data, context);

View file

@ -169,7 +169,7 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
return;
}
_goodThumbnail = std::make_unique<Image>(std::move(thumbnail));
_owner->session().downloaderTaskFinished().notify();
_owner->session().notifyDownloaderTaskFinished();
}
Image *DocumentMedia::thumbnailInline() const {
@ -207,7 +207,7 @@ QSize DocumentMedia::thumbnailSize() const {
void DocumentMedia::setThumbnail(QImage thumbnail) {
_thumbnail = std::make_unique<Image>(std::move(thumbnail));
_owner->session().downloaderTaskFinished().notify();
_owner->session().notifyDownloaderTaskFinished();
}
QByteArray DocumentMedia::videoThumbnailContent() const {

View file

@ -82,7 +82,7 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
Qt::SmoothTransformation);
}
_images[index] = std::make_unique<Image>(std::move(image));
_owner->session().downloaderTaskFinished().notify();
_owner->session().notifyDownloaderTaskFinished();
}
bool PhotoMedia::loaded() const {

View file

@ -1279,7 +1279,8 @@ rpl::producer<not_null<ViewElement*>> Session::viewResizeRequest() const {
void Session::requestItemViewRefresh(not_null<HistoryItem*> item) {
if (const auto view = item->mainView()) {
view->setPendingResize();
notifyHistoryChangeDelayed(item->history());
view->refreshInBlock();
}
_itemViewRefreshRequest.fire_copy(item);
}

View file

@ -34,7 +34,7 @@ void StickersSetThumbnailView::set(
} else {
_image = std::make_unique<Image>(std::move(image));
}
session->downloaderTaskFinished().notify();
session->notifyDownloaderTaskFinished();
}
Image *StickersSetThumbnailView::image() const {

View file

@ -140,7 +140,10 @@ InnerWidget::InnerWidget(
});
_cancelSearchFromUser->hide();
subscribe(session().downloaderTaskFinished(), [=] { update(); });
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
subscribe(Core::App().notifications().settingsChanged(), [=](
Window::Notifications::ChangeType change) {

View file

@ -161,7 +161,8 @@ void Widget::BottomButton::paintEvent(QPaintEvent *e) {
Widget::Widget(
QWidget *parent,
not_null<Window::SessionController*> controller)
: Window::AbstractSectionWidget(parent, controller)
: Window::AbstractSectionWidget(parent, controller)
, _api(&controller->session().mtp())
, _searchControls(this)
, _mainMenuToggle(_searchControls, st::dialogsMenuToggle)
, _searchForNarrowFilters(_searchControls, st::dialogsSearchForNarrowFilters)
@ -435,7 +436,9 @@ void Widget::fullSearchRefreshOn(rpl::producer<> events) {
_searchTimer.stop();
_searchCache.clear();
_singleMessageSearch.clear();
_searchQueries.clear();
for (const auto &[requestId, query] : base::take(_searchQueries)) {
session().api().request(requestId).cancel();
}
_searchQuery = QString();
_scroll->scrollToY(0);
cancelSearchRequest();
@ -771,7 +774,7 @@ bool Widget::onSearchMessages(bool searchCache) {
auto q = _filter->getLastText().trimmed();
if (q.isEmpty() && !_searchFromUser) {
cancelSearchRequest();
session().api().request(base::take(_peerSearchRequest)).cancel();
_api.request(base::take(_peerSearchRequest)).cancel();
return true;
}
if (searchCache) {
@ -781,8 +784,8 @@ bool Widget::onSearchMessages(bool searchCache) {
if (!success) {
return false;
}
const auto i = _searchCache.constFind(q);
if (i != _searchCache.cend()) {
const auto i = _searchCache.find(q);
if (i != _searchCache.end()) {
_searchQuery = q;
_searchQueryFrom = _searchFromUser;
_searchNextRate = 0;
@ -792,7 +795,7 @@ bool Widget::onSearchMessages(bool searchCache) {
_searchInChat
? SearchRequestType::PeerFromStart
: SearchRequestType::FromStart,
i.value(),
i->second,
0);
result = true;
}
@ -836,7 +839,7 @@ bool Widget::onSearchMessages(bool searchCache) {
_searchInHistoryRequest = 0;
finish();
}).send();
_searchQueries.insert(_searchRequest, _searchQuery);
_searchQueries.emplace(_searchRequest, _searchQuery);
return _searchRequest;
});
//} else if (const auto feed = _searchInChat.feed()) { // #feed
@ -853,7 +856,7 @@ bool Widget::onSearchMessages(bool searchCache) {
// }).fail([=](const RPCError &error) {
// searchFailed(type, error, _searchRequest);
// }).send();
// _searchQueries.insert(_searchRequest, _searchQuery);
// _searchQueries.emplace(_searchRequest, _searchQuery);
} else {
const auto type = SearchRequestType::FromStart;
const auto flags = session().settings().skipArchiveInSearch()
@ -873,23 +876,23 @@ bool Widget::onSearchMessages(bool searchCache) {
}).fail([=](const RPCError &error) {
searchFailed(type, error, _searchRequest);
}).send();
_searchQueries.insert(_searchRequest, _searchQuery);
_searchQueries.emplace(_searchRequest, _searchQuery);
}
}
const auto query = Api::ConvertPeerSearchQuery(q);
if (searchForPeersRequired(query)) {
if (searchCache) {
auto i = _peerSearchCache.constFind(query);
if (i != _peerSearchCache.cend()) {
auto i = _peerSearchCache.find(query);
if (i != _peerSearchCache.end()) {
_peerSearchQuery = query;
_peerSearchRequest = 0;
peerSearchReceived(i.value(), 0);
peerSearchReceived(i->second, 0);
result = true;
}
} else if (_peerSearchQuery != query) {
_peerSearchQuery = query;
_peerSearchFull = false;
_peerSearchRequest = session().api().request(MTPcontacts_Search(
_peerSearchRequest = _api.request(MTPcontacts_Search(
MTP_string(_peerSearchQuery),
MTP_int(SearchPeopleLimit)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
@ -897,7 +900,7 @@ bool Widget::onSearchMessages(bool searchCache) {
}).fail([=](const RPCError &error, mtpRequestId requestId) {
peopleFailed(error, requestId);
}).send();
_peerSearchQueries.insert(_peerSearchRequest, _peerSearchQuery);
_peerSearchQueries.emplace(_peerSearchRequest, _peerSearchQuery);
}
} else {
_peerSearchQuery = query;
@ -1013,7 +1016,7 @@ void Widget::onSearchMore() {
finish();
}).send();
if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery);
_searchQueries.emplace(_searchRequest, _searchQuery);
}
return _searchRequest;
});
@ -1036,7 +1039,7 @@ void Widget::onSearchMore() {
// searchFailed(type, error, _searchRequest);
// }).send();
// if (!offsetId) {
// _searchQueries.insert(_searchRequest, _searchQuery);
// _searchQueries.emplace(_searchRequest, _searchQuery);
// }
} else {
const auto type = offsetId
@ -1062,7 +1065,7 @@ void Widget::onSearchMore() {
searchFailed(type, error, _searchRequest);
}).send();
if (!offsetId) {
_searchQueries.insert(_searchRequest, _searchQuery);
_searchQueries.emplace(_searchRequest, _searchQuery);
}
}
} else if (_searchInMigrated && !_searchFullMigrated) {
@ -1115,8 +1118,8 @@ void Widget::searchReceived(
if (state == WidgetState::Filtered) {
if (type == SearchRequestType::FromStart || type == SearchRequestType::PeerFromStart) {
auto i = _searchQueries.find(requestId);
if (i != _searchQueries.cend()) {
_searchCache[i.value()] = result;
if (i != _searchQueries.end()) {
_searchCache[i->second] = result;
_searchQueries.erase(i);
}
}
@ -1224,9 +1227,8 @@ void Widget::peerSearchReceived(
auto q = _peerSearchQuery;
if (state == WidgetState::Filtered) {
auto i = _peerSearchQueries.find(requestId);
if (i != _peerSearchQueries.cend()) {
q = i.value();
_peerSearchCache[q] = result;
if (i != _peerSearchQueries.end()) {
_peerSearchCache[i->second] = result;
_peerSearchQueries.erase(i);
}
}
@ -1368,7 +1370,9 @@ void Widget::applyFilterUpdate(bool force) {
if (filterText.isEmpty()) {
_peerSearchCache.clear();
_peerSearchQueries.clear();
for (const auto &[requestId, query] : base::take(_peerSearchQueries)) {
_api.request(requestId).cancel();
}
_peerSearchQuery = QString();
}
@ -1425,7 +1429,9 @@ void Widget::setSearchInChat(Key chat, UserData *from) {
void Widget::clearSearchCache() {
_searchCache.clear();
_singleMessageSearch.clear();
_searchQueries.clear();
for (const auto &[requestId, query] : base::take(_searchQueries)) {
session().api().request(requestId).cancel();
}
_searchQuery = QString();
_searchQueryFrom = nullptr;
cancelSearchRequest();
@ -1729,10 +1735,8 @@ void Widget::scrollToEntry(const RowDescriptor &entry) {
void Widget::cancelSearchRequest() {
session().api().request(base::take(_searchRequest)).cancel();
if (_searchInHistoryRequest) {
session().data().histories().cancelRequest(_searchInHistoryRequest);
_searchInHistoryRequest = 0;
}
session().data().histories().cancelRequest(
base::take(_searchInHistoryRequest));
}
bool Widget::onCancelSearch() {

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h"
#include "ui/widgets/scroll_area.h"
#include "ui/special_buttons.h"
#include "mtproto/sender.h"
#include "api/api_single_message_search.h"
class RPCError;
@ -174,6 +175,8 @@ private:
void startScrollUpButtonAnimation(bool shown);
void updateScrollUpPosition();
MTP::Sender _api;
bool _dragInScroll = false;
bool _dragForward = false;
QTimer _chooseByDragTimer;
@ -225,11 +228,11 @@ private:
int _searchInHistoryRequest = 0; // Not real mtpRequestId.
mtpRequestId _searchRequest = 0;
QMap<QString, MTPmessages_Messages> _searchCache;
base::flat_map<QString, MTPmessages_Messages> _searchCache;
Api::SingleMessageSearch _singleMessageSearch;
QMap<mtpRequestId, QString> _searchQueries;
QMap<QString, MTPcontacts_Found> _peerSearchCache;
QMap<mtpRequestId, QString> _peerSearchQueries;
base::flat_map<mtpRequestId, QString> _searchQueries;
base::flat_map<QString, MTPcontacts_Found> _peerSearchCache;
base::flat_map<mtpRequestId, QString> _peerSearchQueries;
QPixmap _widthAnimationCache;

View file

@ -230,6 +230,7 @@ void showPeerProfile(not_null<PeerData*> peer) {
if (const auto controller = window->sessionController()) {
if (&controller->session() == &peer->session()) {
controller->showPeerInfo(peer);
return;
}
}
if (&Core::App().domain().active() != &peer->session().account()) {

View file

@ -178,10 +178,6 @@ HistoryInner::HistoryInner(
) | rpl::start_with_next(
[this](auto view) { viewRemoved(view); },
lifetime());
session().data().itemViewRefreshRequest(
) | rpl::start_with_next(
[this](auto item) { refreshView(item); },
lifetime());
rpl::merge(
session().data().historyUnloaded(),
session().data().historyCleared()
@ -1316,32 +1312,15 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
}
void HistoryInner::viewRemoved(not_null<const Element*> view) {
if (_dragSelFrom == view) {
_dragSelFrom = nullptr;
}
if (_dragSelTo == view) {
_dragSelTo = nullptr;
}
if (_scrollDateLastItem == view) {
_scrollDateLastItem = nullptr;
}
}
void HistoryInner::refreshView(not_null<HistoryItem*> item) {
const auto dragSelFrom = (_dragSelFrom && _dragSelFrom->data() == item);
const auto dragSelTo = (_dragSelTo && _dragSelTo->data() == item);
const auto scrollDateLastItem = (_scrollDateLastItem
&& _scrollDateLastItem->data() == item);
item->refreshMainView();
if (dragSelFrom) {
_dragSelFrom = item->mainView();
}
if (dragSelTo) {
_dragSelTo = item->mainView();
}
if (scrollDateLastItem) {
_scrollDateLastItem = item->mainView();
}
const auto refresh = [&](auto &saved) {
if (saved == view) {
const auto now = view->data()->mainView();
saved = (now && now != view) ? now : nullptr;
}
};
refresh(_dragSelFrom);
refresh(_dragSelTo);
refresh(_scrollDateLastItem);
}
void HistoryInner::mouseActionFinish(

View file

@ -239,7 +239,6 @@ private:
void itemRemoved(not_null<const HistoryItem*> item);
void viewRemoved(not_null<const Element*> view);
void refreshView(not_null<HistoryItem*> item);
void touchResetSpeed();
void touchUpdateSpeed();

View file

@ -307,7 +307,11 @@ HistoryWidget::HistoryWidget(
, _topShadow(this) {
setAcceptDrops(true);
subscribe(session().downloaderTaskFinished(), [=] { update(); });
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
_historyDown->addClickHandler([=] { historyDownClicked(); });
_unreadMentions->addClickHandler([=] { showNextUnreadMention(); });
@ -500,15 +504,6 @@ HistoryWidget::HistoryWidget(
}
}, lifetime());
session().data().itemViewRefreshRequest(
) | rpl::start_with_next([=](not_null<HistoryItem*> item) {
// While HistoryInner doesn't own item views we must refresh them
// even if the list is not yet created / was destroyed.
if (!_list) {
item->refreshMainView();
}
}, lifetime());
Core::App().settings().largeEmojiChanges(
) | rpl::start_with_next([=] {
crl::on_main(this, [=] {

View file

@ -577,6 +577,9 @@ void TopBarWidget::updateSearchVisibility() {
}
void TopBarWidget::updateControlsGeometry() {
if (!_activeChat) {
return;
}
auto hasSelected = (_selectedCount > 0);
auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.));
auto otherButtonsTop = selectedButtonsTop + st::topBarHeight;
@ -663,7 +666,9 @@ void TopBarWidget::setAnimatingMode(bool enabled) {
}
void TopBarWidget::updateControlsVisibility() {
if (_animatingMode) {
if (!_activeChat) {
return;
} else if (_animatingMode) {
hideChildren();
return;
}
@ -708,14 +713,12 @@ void TopBarWidget::updateControlsVisibility() {
void TopBarWidget::updateMembersShowArea() {
const auto membersShowAreaNeeded = [&] {
auto peer = _controller->content()->peer();
const auto peer = _activeChat.peer();
if ((_selectedCount > 0) || !peer) {
return false;
}
if (auto chat = peer->asChat()) {
} else if (const auto chat = peer->asChat()) {
return chat->amIn();
}
if (auto megagroup = peer->asMegagroup()) {
} else if (const auto megagroup = peer->asMegagroup()) {
return megagroup->canViewMembers()
&& (megagroup->membersCount()
< megagroup->session().serverConfig().chatSizeMax);

View file

@ -51,11 +51,6 @@ int gifMaxStatusWidth(DocumentData *document) {
return result;
}
[[nodiscard]] bool CanPlayInline(not_null<DocumentData*> document) {
const auto dimensions = document->dimensions;
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
}
} // namespace
struct Gif::Streamed {
@ -110,6 +105,11 @@ Gif::~Gif() {
}
}
bool Gif::CanPlayInline(not_null<DocumentData*> document) {
const auto dimensions = document->dimensions;
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
}
QSize Gif::sizeForAspectRatio() const {
// We use size only for aspect ratio and we want to have it
// as close to the thumbnail as possible.

View file

@ -110,6 +110,8 @@ public:
void refreshParentId(not_null<HistoryItem*> realParent) override;
[[nodiscard]] static bool CanPlayInline(not_null<DocumentData*> document);
private:
struct Streamed;

View file

@ -172,7 +172,9 @@ PointState Media::pointState(QPoint point) const {
: PointState::Outside;
}
std::unique_ptr<Lottie::SinglePlayer> Media::stickerTakeLottie() {
std::unique_ptr<Lottie::SinglePlayer> Media::stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) {
return nullptr;
}

View file

@ -26,6 +26,7 @@ using SharedMediaTypesMask = base::enum_mask<SharedMediaType>;
namespace Lottie {
class SinglePlayer;
struct ColorReplacements;
} // namespace Lottie
namespace HistoryView {
@ -145,7 +146,9 @@ public:
}
virtual void stickerClearLoopPlayed() {
}
virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie();
virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements);
virtual void checkAnimation() {
}

View file

@ -28,7 +28,9 @@ constexpr auto kMaxForwardedBarLines = 4;
} // namespace
auto UnwrappedMedia::Content::stickerTakeLottie()
auto UnwrappedMedia::Content::stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements)
-> std::unique_ptr<Lottie::SinglePlayer> {
return nullptr;
}
@ -394,8 +396,10 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
return result;
}
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie() {
return _content->stickerTakeLottie();
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) {
return _content->stickerTakeLottie(data, replacements);
}
int UnwrappedMedia::calculateFullRight(const QRect &inner) const {

View file

@ -34,7 +34,9 @@ public:
}
virtual void stickerClearLoopPlayed() {
}
virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie();
virtual std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements);
virtual bool hasHeavyPart() const {
return false;
}
@ -85,7 +87,9 @@ public:
void stickerClearLoopPlayed() override {
_content->stickerClearLoopPlayed();
}
std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie() override;
std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) override;
bool hasHeavyPart() const override {
return _content->hasHeavyPart();

View file

@ -71,7 +71,7 @@ Sticker::Sticker(
_data->loadThumbnail(parent->data()->fullId());
}
if (const auto media = replacing ? replacing->media() : nullptr) {
_lottie = media->stickerTakeLottie();
_lottie = media->stickerTakeLottie(_data, _replacements);
if (_lottie) {
lottieCreated();
}
@ -344,8 +344,12 @@ void Sticker::unloadLottie() {
_parent->checkHeavyPart();
}
std::unique_ptr< Lottie::SinglePlayer> Sticker::stickerTakeLottie() {
return std::move(_lottie);
std::unique_ptr<Lottie::SinglePlayer> Sticker::stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) {
return (data == _data && replacements == _replacements)
? std::move(_lottie)
: nullptr;
}
} // namespace HistoryView

View file

@ -50,7 +50,9 @@ public:
void stickerClearLoopPlayed() override {
_lottieOncePlayed = false;
}
std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie() override;
std::unique_ptr<Lottie::SinglePlayer> stickerTakeLottie(
not_null<DocumentData*> data,
const Lottie::ColorReplacements *replacements) override;
bool hasHeavyPart() const override;
void unloadHeavyPart() override;

View file

@ -590,21 +590,27 @@ void ListWidget::start() {
invalidatePaletteCache();
}
}, lifetime());
ObservableViewer(
session().downloaderTaskFinished()
) | rpl::start_with_next([this] { update(); }, lifetime());
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
session().data().itemLayoutChanged(
) | rpl::start_with_next([this](auto item) {
itemLayoutChanged(item);
}, lifetime());
session().data().itemRemoved(
) | rpl::start_with_next([this](auto item) {
itemRemoved(item);
}, lifetime());
session().data().itemRepaintRequest(
) | rpl::start_with_next([this](auto item) {
repaintItem(item);
}, lifetime());
_controller->mediaSourceQueryValue(
) | rpl::start_with_next([this]{
restart();

View file

@ -681,7 +681,7 @@ void ActionsFiller::addClearHistoryAction(not_null<UserData*> user) {
_wrap,
tr::lng_profile_clear_history(),
rpl::single(true),
Window::ClearHistoryHandler(user));
Window::ClearHistoryHandler(user));
}
void ActionsFiller::addDeleteConversationAction(

View file

@ -58,9 +58,11 @@ Inner::Inner(
setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent);
subscribe(_controller->session().downloaderTaskFinished(), [this] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(controller->gifPauseLevelChanged(), [this] {
if (!_controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults)) {
update();

View file

@ -187,16 +187,18 @@ void PasswordCheckWidget::requestPasswordData() {
).done([=](const MTPaccount_Password &result) {
_sentRequest = 0;
result.match([&](const MTPDaccount_password &data) {
_request = Core::ParseCloudPasswordCheckRequest(data);
auto request = Core::ParseCloudPasswordCheckRequest(data);
if (request && request.id) {
_request = std::move(request);
} else {
// Maybe the password was removed? Just submit it once again.
}
passwordChecked();
});
}).send();
}
void PasswordCheckWidget::passwordChecked() {
if (!_request || !_request.id) {
return serverError();
}
const auto check = Core::ComputeCloudPasswordCheck(
_request,
_passwordHash);

View file

@ -725,6 +725,9 @@ void Widget::paintEvent(QPaintEvent *e) {
}
void Widget::resizeEvent(QResizeEvent *e) {
if (_stepHistory.empty()) {
return;
}
for (const auto step : _stepHistory) {
step->setGeometry(rect());
}

View file

@ -542,7 +542,7 @@ void CloudManager::performSwitchToCustom() {
};
const auto text = tr::lng_sure_save_language(tr::now)
+ "\n\n"
+ getValue(tr::lng_sure_save_language.base);
+ getValue(tr::lng_sure_save_language.base);
const auto change = [=] {
_langpack.switchToCustomFile(filePath);
App::restart();

View file

@ -270,6 +270,13 @@ not_null<Main::Account*> Domain::add(MTP::Environment environment) {
_local->startAdded(account, std::move(config));
watchSession(account);
_accountsChanges.fire({});
auto &settings = Core::App().settings();
if (_accounts.size() == 2 && !settings.mainMenuAccountsShown()) {
settings.setMainMenuAccountsShown(true);
Core::App().saveSettingsDelayed();
}
return account;
}

View file

@ -181,7 +181,11 @@ Storage::Domain &Session::domainLocal() const {
return _account->domainLocal();
}
base::Observable<void> &Session::downloaderTaskFinished() {
void Session::notifyDownloaderTaskFinished() {
downloader().notifyTaskFinished();
}
rpl::producer<> Session::downloaderTaskFinished() const {
return downloader().taskFinished();
}

View file

@ -121,7 +121,8 @@ public:
-> const base::flat_set<not_null<Window::SessionController*>> &;
// Shortcuts.
[[nodiscard]] base::Observable<void> &downloaderTaskFinished();
void notifyDownloaderTaskFinished();
[[nodiscard]] rpl::producer<> downloaderTaskFinished() const;
[[nodiscard]] MTP::DcId mainDcId() const;
[[nodiscard]] MTP::Instance &mtp() const;
[[nodiscard]] const MTP::ConfigFields &serverConfig() const;

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/audio/media_child_ffmpeg_loader.h"
#include "media/audio/media_audio_loaders.h"
#include "media/audio/media_audio_track.h"
#include "media/audio/media_openal_functions.h"
#include "media/streaming/media_streaming_utility.h"
#include "data/data_document.h"
#include "data/data_file_origin.h"
@ -22,9 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <al.h>
#include <alc.h>
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
#include <alext.h>
#endif // !TDESKTOP_DISABLE_OPENAL_EFFECTS
#include <numeric>
@ -205,6 +203,7 @@ void Start(not_null<Instance*> instance) {
auto loglevel = getenv("ALSOFT_LOGLEVEL");
LOG(("OpenAL Logging Level: %1").arg(loglevel ? loglevel : "(not set)"));
OpenAL::LoadEFXExtension();
EnumeratePlaybackDevices();
EnumerateCaptureDevices();
@ -281,11 +280,7 @@ void StopDetachIfNotUsedSafe() {
}
bool SupportsSpeedControl() {
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
return true;
#else // TDESKTOP_DISABLE_OPENAL_EFFECTS
return false;
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
return OpenAL::HasEFXExtension();
}
} // namespace Audio
@ -331,40 +326,44 @@ void Mixer::Track::createStream(AudioMsgId::Type type) {
alSourcei(stream.source, AL_SOURCE_RELATIVE, 1);
alSourcei(stream.source, AL_ROLLOFF_FACTOR, 0);
alGenBuffers(3, stream.buffers);
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
if (speedEffect) {
applySourceSpeedEffect();
} else {
removeSourceSpeedEffect();
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::removeSourceSpeedEffect() {
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, 0);
alSourcei(stream.source, AL_DIRECT_FILTER, AL_FILTER_NULL);
if (!Audio::SupportsSpeedControl()) {
return;
}
alSource3i(stream.source, alGetEnumValue("AL_AUXILIARY_SEND_FILTER"), alGetEnumValue("AL_EFFECTSLOT_NULL"), 0, 0);
alSourcei(stream.source, alGetEnumValue("AL_DIRECT_FILTER"), alGetEnumValue("AL_FILTER_NULL"));
alSourcef(stream.source, AL_PITCH, 1.f);
}
void Mixer::Track::applySourceSpeedEffect() {
if (!Audio::SupportsSpeedControl()) {
return;
}
Expects(speedEffect != nullptr);
if (!speedEffect->effect || !alIsEffect(speedEffect->effect)) {
alGenAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
alGenEffects(1, &speedEffect->effect);
alGenFilters(1, &speedEffect->filter);
alEffecti(speedEffect->effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
alFilteri(speedEffect->filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
alFilterf(speedEffect->filter, AL_LOWPASS_GAIN, 0.f);
if (!speedEffect->effect || !OpenAL::alIsEffect(speedEffect->effect)) {
OpenAL::alGenAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
OpenAL::alGenEffects(1, &speedEffect->effect);
OpenAL::alGenFilters(1, &speedEffect->filter);
OpenAL::alEffecti(speedEffect->effect, alGetEnumValue("AL_EFFECT_TYPE"), alGetEnumValue("AL_EFFECT_PITCH_SHIFTER"));
OpenAL::alFilteri(speedEffect->filter, alGetEnumValue("AL_FILTER_TYPE"), alGetEnumValue("AL_FILTER_LOWPASS"));
OpenAL::alFilterf(speedEffect->filter, alGetEnumValue("AL_LOWPASS_GAIN"), 0.f);
}
alEffecti(speedEffect->effect, AL_PITCH_SHIFTER_COARSE_TUNE, speedEffect->coarseTune);
alAuxiliaryEffectSloti(speedEffect->effectSlot, AL_EFFECTSLOT_EFFECT, speedEffect->effect);
OpenAL::alEffecti(speedEffect->effect, alGetEnumValue("AL_PITCH_SHIFTER_COARSE_TUNE"), speedEffect->coarseTune);
OpenAL::alAuxiliaryEffectSloti(speedEffect->effectSlot, alGetEnumValue("AL_EFFECTSLOT_EFFECT"), speedEffect->effect);
alSourcef(stream.source, AL_PITCH, speedEffect->speed);
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, speedEffect->effectSlot, 0, 0);
alSourcei(stream.source, AL_DIRECT_FILTER, speedEffect->filter);
alSource3i(stream.source, alGetEnumValue("AL_AUXILIARY_SEND_FILTER"), speedEffect->effectSlot, 0, 0);
alSourcei(stream.source, alGetEnumValue("AL_DIRECT_FILTER"), speedEffect->filter);
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::destroyStream() {
if (isStreamCreated()) {
@ -375,26 +374,26 @@ void Mixer::Track::destroyStream() {
for (auto i = 0; i != 3; ++i) {
stream.buffers[i] = 0;
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
resetSpeedEffect();
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::resetSpeedEffect() {
if (!Audio::SupportsSpeedControl()) {
return;
}
if (!speedEffect) {
return;
} else if (speedEffect->effect && alIsEffect(speedEffect->effect)) {
} else if (speedEffect->effect && OpenAL::alIsEffect(speedEffect->effect)) {
if (isStreamCreated()) {
removeSourceSpeedEffect();
}
alDeleteEffects(1, &speedEffect->effect);
alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
alDeleteFilters(1, &speedEffect->filter);
OpenAL::alDeleteEffects(1, &speedEffect->effect);
OpenAL::alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
OpenAL::alDeleteFilters(1, &speedEffect->filter);
}
speedEffect->effect = speedEffect->effectSlot = speedEffect->filter = 0;
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::reattach(AudioMsgId::Type type) {
if (isStreamCreated()
@ -531,14 +530,15 @@ int Mixer::Track::getNotQueuedBufferIndex() {
void Mixer::Track::setExternalData(
std::unique_ptr<ExternalSoundData> data) {
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
changeSpeedEffect(data ? data->speed : 1.);
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
externalData = std::move(data);
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::changeSpeedEffect(float64 speed) {
if (!Audio::SupportsSpeedControl()) {
return;
}
if (speed != 1.) {
if (!speedEffect) {
speedEffect = std::make_unique<SpeedEffect>();
@ -553,7 +553,6 @@ void Mixer::Track::changeSpeedEffect(float64 speed) {
speedEffect = nullptr;
}
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::resetStream() {
if (isStreamCreated()) {
@ -830,13 +829,11 @@ void Mixer::forceToBufferExternal(const AudioMsgId &audioId) {
}
void Mixer::setSpeedFromExternal(const AudioMsgId &audioId, float64 speed) {
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
QMutexLocker lock(&AudioMutex);
const auto track = trackForType(audioId.type());
if (track->state.id == audioId) {
track->changeSpeedEffect(speed);
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
Streaming::TimePoint Mixer::getExternalSyncTimePoint(

View file

@ -215,9 +215,7 @@ private:
int getNotQueuedBufferIndex();
void setExternalData(std::unique_ptr<ExternalSoundData> data);
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void changeSpeedEffect(float64 speed);
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
~Track();
@ -243,7 +241,6 @@ private:
Stream stream;
std::unique_ptr<ExternalSoundData> externalData;
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
struct SpeedEffect {
uint32 effect = 0;
uint32 effectSlot = 0;
@ -252,7 +249,6 @@ private:
float64 speed = 1.;
};
std::unique_ptr<SpeedEffect> speedEffect;
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
crl::time lastUpdateWhen = 0;
crl::time lastUpdatePosition = 0;
@ -260,11 +256,9 @@ private:
void createStream(AudioMsgId::Type type);
void destroyStream();
void resetStream();
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void resetSpeedEffect();
void applySourceSpeedEffect();
void removeSourceSpeedEffect();
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
};

View file

@ -0,0 +1,90 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "media/audio/media_openal_functions.h"
#include <al.h>
namespace OpenAL {
void LoadEFXExtension() {
#define LOAD_PROC(x) ((x) = reinterpret_cast<decltype(x)>(alGetProcAddress(#x)))
LOAD_PROC(alGenEffects);
LOAD_PROC(alDeleteEffects);
LOAD_PROC(alIsEffect);
LOAD_PROC(alEffecti);
LOAD_PROC(alEffectiv);
LOAD_PROC(alEffectf);
LOAD_PROC(alEffectfv);
LOAD_PROC(alGetEffecti);
LOAD_PROC(alGetEffectiv);
LOAD_PROC(alGetEffectf);
LOAD_PROC(alGetEffectfv);
LOAD_PROC(alGenFilters);
LOAD_PROC(alDeleteFilters);
LOAD_PROC(alIsFilter);
LOAD_PROC(alFilteri);
LOAD_PROC(alFilteriv);
LOAD_PROC(alFilterf);
LOAD_PROC(alFilterfv);
LOAD_PROC(alGetFilteri);
LOAD_PROC(alGetFilteriv);
LOAD_PROC(alGetFilterf);
LOAD_PROC(alGetFilterfv);
LOAD_PROC(alGenAuxiliaryEffectSlots);
LOAD_PROC(alDeleteAuxiliaryEffectSlots);
LOAD_PROC(alIsAuxiliaryEffectSlot);
LOAD_PROC(alAuxiliaryEffectSloti);
LOAD_PROC(alAuxiliaryEffectSlotiv);
LOAD_PROC(alAuxiliaryEffectSlotf);
LOAD_PROC(alAuxiliaryEffectSlotfv);
LOAD_PROC(alGetAuxiliaryEffectSloti);
LOAD_PROC(alGetAuxiliaryEffectSlotiv);
LOAD_PROC(alGetAuxiliaryEffectSlotf);
LOAD_PROC(alGetAuxiliaryEffectSlotfv);
#undef LOAD_PROC
}
bool HasEFXExtension() {
return (alGenEffects != nullptr)
&& (alDeleteEffects != nullptr)
&& (alIsEffect != nullptr)
&& (alEffecti != nullptr)
&& (alEffectiv != nullptr)
&& (alEffectf != nullptr)
&& (alEffectfv != nullptr)
&& (alGetEffecti != nullptr)
&& (alGetEffectiv != nullptr)
&& (alGetEffectf != nullptr)
&& (alGetEffectfv != nullptr)
&& (alGenFilters != nullptr)
&& (alDeleteFilters != nullptr)
&& (alIsFilter != nullptr)
&& (alFilteri != nullptr)
&& (alFilteriv != nullptr)
&& (alFilterf != nullptr)
&& (alFilterfv != nullptr)
&& (alGetFilteri != nullptr)
&& (alGetFilteriv != nullptr)
&& (alGetFilterf != nullptr)
&& (alGetFilterfv != nullptr)
&& (alGenAuxiliaryEffectSlots != nullptr)
&& (alDeleteAuxiliaryEffectSlots != nullptr)
&& (alIsAuxiliaryEffectSlot != nullptr)
&& (alAuxiliaryEffectSloti != nullptr)
&& (alAuxiliaryEffectSlotiv != nullptr)
&& (alAuxiliaryEffectSlotf != nullptr)
&& (alAuxiliaryEffectSlotfv != nullptr)
&& (alGetAuxiliaryEffectSloti != nullptr)
&& (alGetAuxiliaryEffectSlotiv != nullptr)
&& (alGetAuxiliaryEffectSlotf != nullptr)
&& (alGetAuxiliaryEffectSlotfv != nullptr);
}
} // namespace OpenAL

View file

@ -0,0 +1,56 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <alext.h>
namespace OpenAL {
/* Effect object functions */
inline LPALGENEFFECTS alGenEffects;
inline LPALDELETEEFFECTS alDeleteEffects;
inline LPALISEFFECT alIsEffect;
inline LPALEFFECTI alEffecti;
inline LPALEFFECTIV alEffectiv;
inline LPALEFFECTF alEffectf;
inline LPALEFFECTFV alEffectfv;
inline LPALGETEFFECTI alGetEffecti;
inline LPALGETEFFECTIV alGetEffectiv;
inline LPALGETEFFECTF alGetEffectf;
inline LPALGETEFFECTFV alGetEffectfv;
/* Filter object functions */
inline LPALGENFILTERS alGenFilters;
inline LPALDELETEFILTERS alDeleteFilters;
inline LPALISFILTER alIsFilter;
inline LPALFILTERI alFilteri;
inline LPALFILTERIV alFilteriv;
inline LPALFILTERF alFilterf;
inline LPALFILTERFV alFilterfv;
inline LPALGETFILTERI alGetFilteri;
inline LPALGETFILTERIV alGetFilteriv;
inline LPALGETFILTERF alGetFilterf;
inline LPALGETFILTERFV alGetFilterfv;
/* Auxiliary Effect Slot object functions */
inline LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
inline LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
inline LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
inline LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
inline LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
inline LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
inline LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
inline LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
inline LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
inline LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
inline LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
void LoadEFXExtension();
bool HasEFXExtension();
} // namespace OpenAL

View file

@ -3534,8 +3534,7 @@ void OverlayWidget::setSession(not_null<Main::Session*> session) {
_session = session;
setWindowIcon(Window::CreateIcon(session));
base::ObservableViewer(
session->downloaderTaskFinished()
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (!isHidden()) {
updateControls();

View file

@ -20,7 +20,7 @@ int __clock_gettime_glibc_old(clockid_t clk_id, struct timespec *tp);
__asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION);
int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) {
return __clock_gettime_glibc_old(clk_id, tp);
return __clock_gettime_glibc_old(clk_id, tp);
}
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p);

View file

@ -20,6 +20,6 @@ __asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_V
int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) {
return __clock_gettime_glibc_old(clk_id, tp);
return __clock_gettime_glibc_old(clk_id, tp);
}

View file

@ -810,8 +810,7 @@ void AppendEmojiPacks(
[self setNeedsDisplayInRect:PeerRectByIndex(userpicIndex)];
};
const auto listenToDownloaderFinished = [=] {
base::ObservableViewer(
_session->downloaderTaskFinished()
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
const auto all = ranges::all_of(_pins, [=](const auto &pin) {
return (!pin->peer->hasUserpic())
@ -1191,8 +1190,7 @@ void AppendEmojiPacks(
[self updateImage];
return;
}
base::ObservableViewer(
document->session().downloaderTaskFinished()
document->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
_image = _media->getStickerSmall();
if (_image) {

View file

@ -301,6 +301,8 @@ void Manager::Private::clearingThreadLoop() {
_clearingTasks.clear();
}
@autoreleasepool {
auto clearBySpecial = [&](NSDictionary *notificationUserInfo) {
NSNumber *sessionObject = [notificationUserInfo objectForKey:@"session"];
const auto notificationSessionId = sessionObject ? [sessionObject unsignedLongLongValue] : 0;
@ -332,6 +334,8 @@ void Manager::Private::clearingThreadLoop() {
}
}
}
}
}
}

View file

@ -7,26 +7,43 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/win/windows_dlls.h"
#include "base/platform/win/base_windows_safe_library.h"
#include <VersionHelpers.h>
#include <QtCore/QSysInfo>
namespace Platform {
namespace Dlls {
f_SetDllDirectory SetDllDirectory;
HINSTANCE LibKernel32;
using base::Platform::SafeLoadLibrary;
using base::Platform::LoadMethod;
void init() {
static bool inited = false;
if (inited) return;
inited = true;
LibKernel32 = LoadLibrary(L"KERNEL32.DLL");
load(LibKernel32, "SetDllDirectoryW", SetDllDirectory);
if (SetDllDirectory) {
// Remove the current directory from the DLL search order.
SetDllDirectory(L"");
// Remove the current directory from the DLL search order.
::SetDllDirectory(L"");
const auto list = {
u"dbghelp.dll"_q,
u"dbgcore.dll"_q,
u"propsys.dll"_q,
u"winsta.dll"_q,
u"textinputframework.dll"_q,
u"uxtheme.dll"_q,
u"igdumdim32.dll"_q,
u"amdhdl32.dll"_q,
u"wtsapi32.dll"_q,
u"propsys.dll"_q,
u"combase.dll"_q,
u"dwmapi.dll"_q,
u"rstrtmgr.dll"_q,
u"psapi.dll"_q,
};
for (const auto &lib : list) {
SafeLoadLibrary(lib);
}
}
@ -53,59 +70,50 @@ f_RmShutdown RmShutdown;
f_RmEndSession RmEndSession;
f_GetProcessMemoryInfo GetProcessMemoryInfo;
HINSTANCE LibUxTheme;
HINSTANCE LibShell32;
HINSTANCE LibWtsApi32;
HINSTANCE LibPropSys;
HINSTANCE LibComBase;
HINSTANCE LibDwmApi;
HINSTANCE LibRstrtMgr;
HINSTANCE LibPsApi;
void start() {
init();
LibShell32 = LoadLibrary(L"SHELL32.DLL");
load(LibShell32, "SHAssocEnumHandlers", SHAssocEnumHandlers);
load(LibShell32, "SHCreateItemFromParsingName", SHCreateItemFromParsingName);
load(LibShell32, "SHOpenWithDialog", SHOpenWithDialog);
load(LibShell32, "OpenAs_RunDLLW", OpenAs_RunDLL);
load(LibShell32, "SHQueryUserNotificationState", SHQueryUserNotificationState);
load(LibShell32, "SHChangeNotify", SHChangeNotify);
load(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID);
const auto LibShell32 = SafeLoadLibrary(u"shell32.dll"_q);
LoadMethod(LibShell32, "SHAssocEnumHandlers", SHAssocEnumHandlers);
LoadMethod(LibShell32, "SHCreateItemFromParsingName", SHCreateItemFromParsingName);
LoadMethod(LibShell32, "SHOpenWithDialog", SHOpenWithDialog);
LoadMethod(LibShell32, "OpenAs_RunDLLW", OpenAs_RunDLL);
LoadMethod(LibShell32, "SHQueryUserNotificationState", SHQueryUserNotificationState);
LoadMethod(LibShell32, "SHChangeNotify", SHChangeNotify);
LoadMethod(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID);
LibUxTheme = LoadLibrary(L"UXTHEME.DLL");
load(LibUxTheme, "SetWindowTheme", SetWindowTheme);
const auto LibUxTheme = SafeLoadLibrary(u"uxtheme.dll"_q);
LoadMethod(LibUxTheme, "SetWindowTheme", SetWindowTheme);
if (IsWindowsVistaOrGreater()) {
LibWtsApi32 = LoadLibrary(L"WTSAPI32.DLL");
load(LibWtsApi32, "WTSRegisterSessionNotification", WTSRegisterSessionNotification);
load(LibWtsApi32, "WTSUnRegisterSessionNotification", WTSUnRegisterSessionNotification);
const auto LibWtsApi32 = SafeLoadLibrary(u"wtsapi32.dll"_q);
LoadMethod(LibWtsApi32, "WTSRegisterSessionNotification", WTSRegisterSessionNotification);
LoadMethod(LibWtsApi32, "WTSUnRegisterSessionNotification", WTSUnRegisterSessionNotification);
LibPropSys = LoadLibrary(L"PROPSYS.DLL");
load(LibPropSys, "PropVariantToString", PropVariantToString);
load(LibPropSys, "PSStringFromPropertyKey", PSStringFromPropertyKey);
const auto LibPropSys = SafeLoadLibrary(u"propsys.dll"_q);
LoadMethod(LibPropSys, "PropVariantToString", PropVariantToString);
LoadMethod(LibPropSys, "PSStringFromPropertyKey", PSStringFromPropertyKey);
if (IsWindows8OrGreater()) {
LibComBase = LoadLibrary(L"COMBASE.DLL");
load(LibComBase, "RoGetActivationFactory", RoGetActivationFactory);
load(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference);
load(LibComBase, "WindowsDeleteString", WindowsDeleteString);
const auto LibComBase = SafeLoadLibrary(u"combase.dll"_q);
LoadMethod(LibComBase, "RoGetActivationFactory", RoGetActivationFactory);
LoadMethod(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference);
LoadMethod(LibComBase, "WindowsDeleteString", WindowsDeleteString);
}
LibDwmApi = LoadLibrary(L"DWMAPI.DLL");
load(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled);
const auto LibDwmApi = SafeLoadLibrary(u"dwmapi.dll"_q);
LoadMethod(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled);
LibRstrtMgr = LoadLibrary(L"RSTRTMGR.DLL");
load(LibRstrtMgr, "RmStartSession", RmStartSession);
load(LibRstrtMgr, "RmRegisterResources", RmRegisterResources);
load(LibRstrtMgr, "RmGetList", RmGetList);
load(LibRstrtMgr, "RmShutdown", RmShutdown);
load(LibRstrtMgr, "RmEndSession", RmEndSession);
const auto LibRstrtMgr = SafeLoadLibrary(u"rstrtmgr.dll"_q);
LoadMethod(LibRstrtMgr, "RmStartSession", RmStartSession);
LoadMethod(LibRstrtMgr, "RmRegisterResources", RmRegisterResources);
LoadMethod(LibRstrtMgr, "RmGetList", RmGetList);
LoadMethod(LibRstrtMgr, "RmShutdown", RmShutdown);
LoadMethod(LibRstrtMgr, "RmEndSession", RmEndSession);
}
LibPsApi = LoadLibrary(L"PSAPI.DLL");
load(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo);
const auto LibPsApi = SafeLoadLibrary(u"psapi.dll"_q);
LoadMethod(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo);
}
} // namespace Dlls

View file

@ -30,14 +30,6 @@ extern f_SetDllDirectory SetDllDirectory;
void start();
template <typename Function>
bool load(HINSTANCE library, LPCSTR name, Function &func) {
if (!library) return false;
func = reinterpret_cast<Function>(GetProcAddress(library, name));
return (func != nullptr);
}
// UXTHEME.DLL
using f_SetWindowTheme = HRESULT(FAR STDAPICALLTYPE*)(
HWND hWnd,

View file

@ -26,8 +26,8 @@ class GroupMembersWidget : public PeerListWidget {
public:
GroupMembersWidget(
QWidget *parent,
not_null<PeerData*> peer,
QWidget *parent,
not_null<PeerData*> peer,
const style::PeerListItem &st);
int onlineCount() const {

View file

@ -33,7 +33,11 @@ PeerListWidget::PeerListWidget(
, _removeText(removeText)
, _removeWidth(st::normalFont->width(_removeText)) {
setMouseTracking(true);
subscribe(peer->session().downloaderTaskFinished(), [=] { update(); });
peer->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
}
int PeerListWidget::resizeGetHeight(int newWidth) {

View file

@ -577,6 +577,7 @@ void SetupMultiAccountNotifications(
AddSkip(container);
AddDividerText(container, tr::lng_settings_notify_all_about());
AddSkip(container);
}
void SetupNotificationsContent(

View file

@ -38,8 +38,11 @@ public:
void enqueue(not_null<Task*> task, int priority);
void remove(not_null<Task*> task);
[[nodiscard]] base::Observable<void> &taskFinished() {
return _taskFinishedObservable;
void notifyTaskFinished() {
_taskFinished.fire({});
}
[[nodiscard]] rpl::producer<> taskFinished() const {
return _taskFinished.events();
}
int changeRequestedAmount(MTP::DcId dcId, int index, int delta);
@ -101,7 +104,7 @@ private:
const not_null<ApiWrap*> _api;
base::Observable<void> _taskFinishedObservable;
rpl::event_stream<> _taskFinished;
base::flat_map<MTP::DcId, DcBalanceData> _balanceData;
base::Timer _resetGenerationTimer;

View file

@ -140,7 +140,7 @@ void FileLoader::finishWithBytes(const QByteArray &data) {
Platform::File::PostprocessDownloaded(
QFileInfo(_file).absoluteFilePath());
}
_session->downloaderTaskFinished().notify();
_session->notifyDownloaderTaskFinished();
_updates.fire_done();
}
@ -440,7 +440,7 @@ bool FileLoader::finalizeResult() {
_cacheTag));
}
}
_session->downloaderTaskFinished().notify();
_session->notifyDownloaderTaskFinished();
_updates.fire_done();
return true;
}

View file

@ -388,7 +388,7 @@ void start() {
EncryptedDescriptor settings;
if (!DecryptLocal(settings, settingsEncrypted, SettingsKey)) {
LOG(("App Error: could not decrypt settings from settings file, maybe bad passcode..."));
LOG(("App Error: could not decrypt settings from settings file..."));
return writeSettings();
}
@ -426,7 +426,12 @@ void start() {
void writeSettings() {
if (!_settingsWriteAllowed) {
_settingsRewriteNeeded = true;
return;
// We need to generate SettingsKey anyway,
// for the moveLegacyBackground to work.
if (SettingsKey) {
return;
}
}
if (_basePath.isEmpty()) {
LOG(("App Error: _basePath is empty in writeSettings()"));
@ -446,6 +451,11 @@ void writeSettings() {
}
settings.writeData(_settingsSalt);
if (!_settingsWriteAllowed) {
EncryptedDescriptor data(0);
settings.writeEncrypted(data, SettingsKey);
return;
}
const auto configSerialized = LookupFallbackConfig().serialize();
const auto applicationSettings = Core::App().settings().serialize();

View file

@ -639,8 +639,7 @@ void UserpicButton::setupPeerViewers() {
update();
}, lifetime());
base::ObservableViewer(
_peer->session().downloaderTaskFinished()
_peer->session().downloaderTaskFinished(
) | rpl::filter([=] {
return _waiting;
}) | rpl::start_with_next([=] {

View file

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme.h"
#include "storage/file_download.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "history/history.h"
#include "history/history_item.h"
#include "platform/platform_specific.h"
@ -229,14 +230,16 @@ void Manager::showNextFromQueue() {
void Manager::subscribeToSession(not_null<Main::Session*> session) {
auto i = _subscriptions.find(session);
if (i == _subscriptions.end()) {
i = _subscriptions.emplace(session, base::Subscription()).first;
session->lifetime().add([=] {
i = _subscriptions.emplace(session).first;
session->account().sessionChanges(
) | rpl::start_with_next([=] {
_subscriptions.remove(session);
});
} else if (i->second) {
}, i->second.lifetime);
} else if (i->second.subscription) {
return;
}
i->second = session->downloaderTaskFinished().add_subscription([=] {
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
auto found = false;
for (const auto &notification : _notifications) {
if (const auto history = notification->maybeHistory()) {
@ -247,9 +250,9 @@ void Manager::subscribeToSession(not_null<Main::Session*> session) {
}
}
if (!found) {
_subscriptions[session].destroy();
_subscriptions[session].subscription.destroy();
}
});
}, i->second.subscription);
}
void Manager::moveWidgets() {

View file

@ -56,6 +56,10 @@ private:
friend class internal::Widget;
using Notification = internal::Notification;
using HideAllButton = internal::HideAllButton;
struct SessionSubscription {
rpl::lifetime subscription;
rpl::lifetime lifetime;
};
[[nodiscard]] QPixmap hiddenUserpicPlaceholder() const;
@ -91,7 +95,7 @@ private:
std::vector<std::unique_ptr<Notification>> _notifications;
base::flat_map<
not_null<Main::Session*>,
base::Subscription> _subscriptions;
SessionSubscription> _subscriptions;
std::unique_ptr<HideAllButton> _hideAll;

View file

@ -666,8 +666,7 @@ void CloudList::subscribeToDownloadFinished() {
if (_downloadFinishedLifetime) {
return;
}
base::ObservableViewer(
_window->session().downloaderTaskFinished()
_window->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
auto &&waiting = _elements | ranges::view::filter(&Element::waiting);
const auto still = ranges::count_if(waiting, [&](Element &element) {

View file

@ -578,7 +578,10 @@ MainMenu::MainMenu(
_version->setRichText(textcmdLink(1, currentVersionText()));
_version->setLink(1, std::make_shared<UrlClickHandler>(qsl("https://github.com/kotatogram/kotatogram-desktop")));
subscribe(_controller->session().downloaderTaskFinished(), [=] { update(); });
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_controller->session().changes().peerUpdates(
_controller->session().user(),

View file

@ -36,9 +36,10 @@ MediaPreviewWidget::MediaPreviewWidget(
, _controller(controller)
, _emojiSize(Ui::Emoji::GetSizeLarge() / cIntRetinaFactor()) {
setAttribute(Qt::WA_TransparentForMouseEvents);
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
QRect MediaPreviewWidget::updateArea() const {

View file

@ -105,15 +105,16 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
|| e->type() == QEvent::MouseButtonPress) {
if(window()->isAncestorOf(static_cast<QWidget*>(obj))) {
const auto mouseEvent = static_cast<QMouseEvent*>(e);
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint());
if (e->type() == QEvent::MouseMove) {
updateCursor(mouseEvent->windowPos().toPoint());
updateCursor(edges);
}
if(e->type() == QEvent::MouseButtonPress
&& mouseEvent->button() == Qt::LeftButton
&& window()->windowState() != Qt::WindowMaximized) {
return startResize(mouseEvent->windowPos().toPoint());
return startResize(edges);
}
}
} else if (e->type() == QEvent::Leave) {
@ -195,9 +196,7 @@ Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) {
}
}
void TitleWidgetQt::updateCursor(const QPoint &pos) {
const auto edges = edgesFromPos(pos);
void TitleWidgetQt::updateCursor(Qt::Edges edges) {
if (!edges || window()->windowState() == Qt::WindowMaximized) {
while (QGuiApplication::overrideCursor()) {
QGuiApplication::restoreOverrideCursor();
@ -221,9 +220,9 @@ void TitleWidgetQt::updateCursor(const QPoint &pos) {
}
}
bool TitleWidgetQt::startResize(const QPoint &pos) {
bool TitleWidgetQt::startResize(Qt::Edges edges) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
if (const auto edges = edgesFromPos(pos)) {
if (edges) {
return window()->windowHandle()->startSystemResize(edges);
}
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED

View file

@ -41,8 +41,8 @@ private:
void updateControlsPosition();
Qt::Edges edgesFromPos(const QPoint &pos);
void updateCursor(const QPoint &pos);
bool startResize(const QPoint &pos);
void updateCursor(Qt::Edges edges);
bool startResize(Qt::Edges edges);
const style::WindowTitle &_st;
object_ptr<Ui::IconButton> _minimize;

View file

@ -1,7 +1,7 @@
AppVersion 2001016
AppVersion 2001017
AppVersionStrMajor 2.1
AppVersionStrSmall 2.1.16
AppVersionStr 2.1.16
AppVersionStrSmall 2.1.17
AppVersionStr 2.1.17
BetaChannel 1
AlphaVersion 0
AppVersionOriginal 2.1.16.beta
AppVersionOriginal 2.1.17.beta

@ -1 +1 @@
Subproject commit 3017da83c15e5e27244ab66526fea8cc3bddb7cf
Subproject commit 01ca681ab3aecda8c372b1bb77999f3b7b7a52c6

@ -1 +1 @@
Subproject commit 2a063957da89554214ed52e2d7b94f1fa08668ce
Subproject commit 11a39d9d941e4cd1c60a0c97352cbf89700f42fc

View file

@ -1,3 +1,10 @@
2.1.17 beta (02.07.20)
- Fix messages editing in a non-active account.
- Fix large animated emoji messages editing.
- Fix high definition GIF animations opening in media viewer.
- Multiple crash fixes.
2.1.16 beta (01.07.20)
- Crash fix.

2
cmake

@ -1 +1 @@
Subproject commit 6b36a649dc0061138cf60bac65d9a40a5c9faea3
Subproject commit 9346d5f89510c4f9e340a0e26a1f8c2244e7de29