diff --git a/CMakeLists.txt b/CMakeLists.txt
index e456192cd..2979473c4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,9 +19,9 @@ include(cmake/validate_special_target.cmake)
include(cmake/version.cmake)
desktop_app_parse_version(Telegram/build/version)
-set(project_langs C CXX)
+set(project_langs ASM C CXX)
if (APPLE)
- set(project_langs C CXX OBJC OBJCXX)
+ list(APPEND project_langs OBJC OBJCXX)
endif()
project(Telegram
@@ -43,9 +43,10 @@ endif()
include(cmake/variables.cmake)
include(cmake/nice_target_sources.cmake)
include(cmake/target_compile_options_if_exists.cmake)
+include(cmake/target_link_frameworks.cmake)
+include(cmake/target_link_optional_libraries.cmake)
include(cmake/target_link_options_if_exists.cmake)
include(cmake/target_link_static_libraries.cmake)
-include(cmake/target_link_frameworks.cmake)
include(cmake/init_target.cmake)
include(cmake/generate_target.cmake)
include(cmake/nuget.cmake)
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 34ba3020c..c9de1df7c 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -189,6 +189,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_filter_chats_limit_title" = "Limit Reached";
"lng_filter_chats_limit1#one" = "Sorry, you can't add more than **{count}** chat to a folder.";
"lng_filter_chats_limit1#other" = "Sorry, you can't add more than **{count}** chats to a folder.";
+"lng_filter_chats_exlude_limit1#one" = "Sorry, you can't exlude more than **{count}** chat from a folder.";
+"lng_filter_chats_exlude_limit1#other" = "Sorry, you can't exlude more than **{count}** chats from a folder.";
"lng_filter_chats_limit2#one" = "You can increase this limit to **{count}** by upgrading to **Telegram Premium**.";
"lng_filter_chats_limit2#other" = "You can increase this limit to **{count}** by upgrading to **Telegram Premium**.";
diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index 9e1d43480..0fabf4cf8 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -10,7 +10,7 @@
+ Version="4.8.11.0" />
Telegram Desktop
Telegram Messenger LLP
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index e1fcc6baf..79fe54aee 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,8,10,0
- PRODUCTVERSION 4,8,10,0
+ FILEVERSION 4,8,11,0
+ PRODUCTVERSION 4,8,11,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop"
- VALUE "FileVersion", "4.8.10.0"
+ VALUE "FileVersion", "4.8.11.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
VALUE "ProductName", "AyuGram Desktop"
- VALUE "ProductVersion", "4.8.10.0"
+ VALUE "ProductVersion", "4.8.11.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index 1cc8fed3c..83e9ddab5 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,8,10,0
- PRODUCTVERSION 4,8,10,0
+ FILEVERSION 4,8,11,0
+ PRODUCTVERSION 4,8,11,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop Updater"
- VALUE "FileVersion", "4.8.10.0"
+ VALUE "FileVersion", "4.8.11.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
VALUE "ProductName", "AyuGram Desktop"
- VALUE "ProductVersion", "4.8.10.0"
+ VALUE "ProductVersion", "4.8.11.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/api/api_chat_filters.cpp b/Telegram/SourceFiles/api/api_chat_filters.cpp
index 2b19deac3..c045263ae 100644
--- a/Telegram/SourceFiles/api/api_chat_filters.cpp
+++ b/Telegram/SourceFiles/api/api_chat_filters.cpp
@@ -510,7 +510,7 @@ void ShowImportError(
if (error == u"CHANNELS_TOO_MUCH"_q) {
window->show(Box(ChannelsLimitBox, session));
} else if (error == u"FILTER_INCLUDE_TOO_MUCH"_q) {
- window->show(Box(FilterChatsLimitBox, session, count));
+ window->show(Box(FilterChatsLimitBox, session, count, true));
} else if (error == u"CHATLISTS_TOO_MUCH"_q) {
window->show(Box(ShareableFiltersLimitBox, session));
} else {
diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp
index 9cfe272f8..291a2675a 100644
--- a/Telegram/SourceFiles/api/api_sending.cpp
+++ b/Telegram/SourceFiles/api/api_sending.cpp
@@ -456,7 +456,6 @@ void SendConfirmedFile(
}());
if (itemToEdit) {
- itemToEdit->savePreviousMedia();
auto edition = HistoryMessageEdition();
edition.isEditHide = (flags & MessageFlag::HideEdited);
edition.editDate = 0;
@@ -468,6 +467,7 @@ void SendConfirmedFile(
edition.useSameMarkup = true;
edition.useSameReplies = true;
edition.useSameReactions = true;
+ edition.savePreviousMedia = true;
itemToEdit->applyEdition(std::move(edition));
} else {
const auto viaBotId = UserId();
diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp
index a469e839e..5772b06c5 100644
--- a/Telegram/SourceFiles/apiwrap.cpp
+++ b/Telegram/SourceFiles/apiwrap.cpp
@@ -3419,7 +3419,7 @@ void ApiWrap::sendSharedContact(
void ApiWrap::sendVoiceMessage(
QByteArray result,
VoiceWaveform waveform,
- int duration,
+ crl::time duration,
const SendAction &action) {
const auto caption = TextWithTags();
const auto to = fileLoadTaskOptions(action);
diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h
index dcab7cde8..5815fd3c0 100644
--- a/Telegram/SourceFiles/apiwrap.h
+++ b/Telegram/SourceFiles/apiwrap.h
@@ -302,7 +302,7 @@ public:
void sendVoiceMessage(
QByteArray result,
VoiceWaveform waveform,
- int duration,
+ crl::time duration,
const SendAction &action);
void sendFiles(
Ui::PreparedList &&list,
diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style
index 3758d8a61..00862eada 100644
--- a/Telegram/SourceFiles/boxes/boxes.style
+++ b/Telegram/SourceFiles/boxes/boxes.style
@@ -607,7 +607,7 @@ groupStickersField: InputField(defaultMultiSelectSearchField) {
textBg: boxBg;
heightMin: 32px;
}
-groupStickersSubTitleHeight: 36px;
+groupStickersSubTitleHeight: 48px;
proxyUsePadding: margins(22px, 6px, 22px, 5px);
proxyTryIPv6Padding: margins(22px, 8px, 22px, 5px);
diff --git a/Telegram/SourceFiles/boxes/choose_filter_box.cpp b/Telegram/SourceFiles/boxes/choose_filter_box.cpp
index ef6b8ecb2..416b30ff1 100644
--- a/Telegram/SourceFiles/boxes/choose_filter_box.cpp
+++ b/Telegram/SourceFiles/boxes/choose_filter_box.cpp
@@ -164,7 +164,8 @@ void FillChooseFilterMenu(
controller->show(Box(
FilterChatsLimitBox,
&controller->session(),
- r.count));
+ r.count,
+ true));
} else if (validator.canAdd()) {
validator.add(id);
}
diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp
index e135fd691..724dd7c47 100644
--- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp
+++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp
@@ -336,14 +336,18 @@ void EditExceptions(
Fn refresh) {
const auto include = (options & Flag::Contacts) != Flags(0);
const auto rules = data->current();
+ const auto session = &window->session();
auto controller = std::make_unique(
- &window->session(),
+ session,
(include
? tr::lng_filters_include_title()
: tr::lng_filters_exclude_title()),
options,
rules.flags() & options,
- include ? rules.always() : rules.never());
+ include ? rules.always() : rules.never(),
+ [=](int count) {
+ return Box(FilterChatsLimitBox, session, count, include);
+ });
const auto rawController = controller.get();
auto initBox = [=](not_null box) {
box->setCloseByOutsideClick(false);
diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp
index 6cce77d60..61e937dfe 100644
--- a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp
+++ b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp
@@ -7,9 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/filters/edit_filter_chats_list.h"
+#include "data/data_premium_limits.h"
#include "history/history.h"
#include "window/window_session_controller.h"
-#include "boxes/premium_limits_box.h"
#include "lang/lang_keys.h"
#include "ui/widgets/labels.h"
#include "ui/wrap/vertical_layout.h"
@@ -99,22 +99,6 @@ private:
return PeerId(FakeChatId(static_cast(flag))).value;
}
-[[nodiscard]] int Limit(
- not_null session,
- const QString &key,
- int fallback) {
- return session->account().appConfig().get(key, fallback);
-}
-
-[[nodiscard]] int Limit(not_null session) {
- const auto premium = session->premium();
- return Limit(session,
- (premium
- ? "dialog_filters_chats_limit_premium"
- : "dialog_filters_chats_limit_default"),
- premium ? 200 : 100);
-}
-
TypeRow::TypeRow(Flag flag) : PeerListRow(TypeId(flag)) {
}
@@ -338,15 +322,18 @@ EditFilterChatsListController::EditFilterChatsListController(
rpl::producer title,
Flags options,
Flags selected,
- const base::flat_set> &peers)
+ const base::flat_set> &peers,
+ LimitBoxFactory limitBox)
: ChatsListBoxController(session)
, _session(session)
+, _limitBox(std::move(limitBox))
, _title(std::move(title))
, _peers(peers)
, _options(options & ~Flag::Chatlist)
, _selected(selected)
-, _limit(Limit(session))
+, _limit(Data::PremiumLimits(session).dialogFiltersChatsCurrent())
, _chatlist(options & Flag::Chatlist) {
+ Expects(_limitBox != nullptr);
}
Main::Session &EditFilterChatsListController::session() const {
@@ -375,8 +362,7 @@ void EditFilterChatsListController::rowClicked(not_null row) {
delegate()->peerListSetRowChecked(row, !row->checked());
updateTitle();
} else {
- delegate()->peerListShowBox(
- Box(FilterChatsLimitBox, _session, count));
+ delegate()->peerListShowBox(_limitBox(count));
}
}
diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.h b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.h
index ce4583184..a9dfd3fa2 100644
--- a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.h
+++ b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.h
@@ -43,13 +43,15 @@ class EditFilterChatsListController final : public ChatsListBoxController {
public:
using Flag = Data::ChatFilter::Flag;
using Flags = Data::ChatFilter::Flags;
+ using LimitBoxFactory = Fn(int)>;
EditFilterChatsListController(
not_null session,
rpl::producer title,
Flags options,
Flags selected,
- const base::flat_set> &peers);
+ const base::flat_set> &peers,
+ LimitBoxFactory limitBox);
[[nodiscard]] Main::Session &session() const override;
[[nodiscard]] Flags chosenOptions() const {
@@ -70,6 +72,7 @@ private:
void updateTitle();
const not_null _session;
+ const LimitBoxFactory _limitBox;
rpl::producer _title;
base::flat_set> _peers;
Flags _options;
diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.cpp b/Telegram/SourceFiles/boxes/premium_limits_box.cpp
index 3fbdc34c1..8980a9028 100644
--- a/Telegram/SourceFiles/boxes/premium_limits_box.cpp
+++ b/Telegram/SourceFiles/boxes/premium_limits_box.cpp
@@ -694,7 +694,8 @@ void PublicLinksLimitBox(
void FilterChatsLimitBox(
not_null box,
not_null session,
- int currentCount) {
+ int currentCount,
+ bool include) {
const auto premium = session->premium();
const auto premiumPossible = session->premiumPossible();
@@ -707,10 +708,12 @@ void FilterChatsLimitBox(
premiumLimit);
auto text = rpl::combine(
- tr::lng_filter_chats_limit1(
- lt_count,
- rpl::single(premium ? premiumLimit : defaultLimit),
- Ui::Text::RichLangValue),
+ (include
+ ? tr::lng_filter_chats_limit1
+ : tr::lng_filter_chats_exlude_limit1)(
+ lt_count,
+ rpl::single(premium ? premiumLimit : defaultLimit),
+ Ui::Text::RichLangValue),
((premium || !premiumPossible)
? rpl::single(TextWithEntities())
: tr::lng_filter_chats_limit2(
diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.h b/Telegram/SourceFiles/boxes/premium_limits_box.h
index bb9115a3e..7bcda6e53 100644
--- a/Telegram/SourceFiles/boxes/premium_limits_box.h
+++ b/Telegram/SourceFiles/boxes/premium_limits_box.h
@@ -35,7 +35,8 @@ void PublicLinksLimitBox(
void FilterChatsLimitBox(
not_null box,
not_null session,
- int currentCount);
+ int currentCount,
+ bool include);
void FilterLinksLimitBox(
not_null box,
not_null session);
diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp
index 32295cf08..237306d84 100644
--- a/Telegram/SourceFiles/boxes/stickers_box.cpp
+++ b/Telegram/SourceFiles/boxes/stickers_box.cpp
@@ -250,6 +250,7 @@ private:
int countMaxNameWidth(bool installedSet) const;
[[nodiscard]] bool skipPremium() const;
+ const style::PeerListItem &_st;
const std::shared_ptr _show;
const not_null _session;
MTP::Sender _api;
@@ -386,7 +387,8 @@ StickersBox::StickersBox(
std::shared_ptr show,
Section section,
bool masks)
-: _show(std::move(show))
+: _st(st::stickersRowItem)
+, _show(std::move(show))
, _session(&_show->session())
, _api(&_session->mtp())
, _tabs(this, st::stickersTabs)
@@ -407,7 +409,8 @@ StickersBox::StickersBox(
QWidget*,
std::shared_ptr show,
not_null megagroup)
-: _show(std::move(show))
+: _st(st::stickersRowItem)
+, _show(std::move(show))
, _session(&_show->session())
, _api(&_session->mtp())
, _section(Section::Installed)
@@ -425,7 +428,8 @@ StickersBox::StickersBox(
QWidget*,
std::shared_ptr show,
const QVector &attachedSets)
-: _show(std::move(show))
+: _st(st::stickersRowItem)
+, _show(std::move(show))
, _session(&_show->session())
, _api(&_session->mtp())
, _section(Section::Attached)
@@ -440,7 +444,8 @@ StickersBox::StickersBox(
QWidget*,
std::shared_ptr show,
const std::vector &emojiSets)
-: _show(std::move(show))
+: _st(st::stickersRowItem)
+, _show(std::move(show))
, _session(&_show->session())
, _api(&_session->mtp())
, _section(Section::Attached)
@@ -1131,6 +1136,7 @@ StickersBox::Inner::Inner(
std::shared_ptr show,
StickersBox::Section section)
: RpWidget(parent)
+, _st(st::stickersRowItem)
, _show(std::move(show))
, _session(&_show->session())
, _api(&_session->mtp())
@@ -1150,11 +1156,11 @@ StickersBox::Inner::Inner(
, _inactiveButtonBg(
ImageRoundRadius::Large,
st::stickersTrendingInstalled.textBg)
-, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
+, _rowHeight(_st.height)
, _shiftingAnimation([=](crl::time now) {
return shiftingAnimationCallback(now);
})
-, _itemsTop(st::membersMarginTop)
+, _itemsTop(st::lineWidth)
, _addText(tr::lng_stickers_featured_add(tr::now))
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
, _undoText(tr::lng_stickers_return(tr::now))
@@ -1169,6 +1175,7 @@ StickersBox::Inner::Inner(
std::shared_ptr show,
not_null megagroup)
: RpWidget(parent)
+, _st(st::stickersRowItem)
, _show(std::move(show))
, _session(&_show->session())
, _api(&_session->mtp())
@@ -1188,11 +1195,11 @@ StickersBox::Inner::Inner(
, _inactiveButtonBg(
ImageRoundRadius::Large,
st::stickersTrendingInstalled.textBg)
-, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
+, _rowHeight(_st.height)
, _shiftingAnimation([=](crl::time now) {
return shiftingAnimationCallback(now);
})
-, _itemsTop(st::membersMarginTop)
+, _itemsTop(st::lineWidth)
, _megagroupSet(megagroup)
, _megagroupSetInput(_megagroupSet->mgInfo->stickerSet)
, _megagroupSetField(
@@ -1328,8 +1335,8 @@ QRect StickersBox::Inner::relativeButtonRect(
buttonh = st.height;
buttonshift = 0;
}
- auto buttonx = width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - buttonw + buttonshift;
- auto buttony = st::contactsPadding.top() + (st::contactsPhotoSize - buttonh) / 2;
+ auto buttonx = width() - st::contactsPadding.right() - buttonw + buttonshift;
+ auto buttony = (_st.height - buttonh) / 2;
return QRect(buttonx, buttony, buttonw, buttonh);
}
@@ -1345,7 +1352,7 @@ void StickersBox::Inner::paintRow(Painter &p, not_null row, int index) {
return -1;
}();
if (index >= 0 && index == selectedIndex) {
- p.fillRect(0, 0, width(), _rowHeight, st::contactsBgOver);
+ p.fillRect(0, 0, width(), _rowHeight, _st.button.textBgOver);
if (row->ripple) {
row->ripple->paint(p, 0, 0, width());
}
@@ -1362,7 +1369,7 @@ void StickersBox::Inner::paintRow(Painter &p, not_null row, int index) {
current = reachedOpacity;
}
}
- auto rect = myrtlrect(st::contactsPadding.left() / 2, st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - st::contactsPadding.left() / 2, _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2));
+ auto rect = myrtlrect(_st.photoPosition.x() / 2, _st.photoPosition.y() / 2, width() - _st.photoPosition.x() - _scrollbar, _rowHeight - _st.photoPosition.y());
p.setOpacity(current);
Ui::Shadow::paint(p, rect, width(), st::boxRoundShadow);
p.setOpacity(1);
@@ -1383,27 +1390,27 @@ void StickersBox::Inner::paintRow(Painter &p, not_null row, int index) {
p.setOpacity(st::stickersRowDisabledOpacity);
}
- auto stickerx = st::contactsPadding.left();
+ auto stickerskip = 0;
if (!_megagroupSet && _isInstalledTab) {
- stickerx += st::stickersReorderIcon.width() + st::stickersReorderSkip;
+ stickerskip += st::stickersReorderIcon.width() + st::stickersReorderSkip;
if (!row->isRecentSet()) {
- st::stickersReorderIcon.paint(p, st::contactsPadding.left(), (_rowHeight - st::stickersReorderIcon.height()) / 2, width());
+ st::stickersReorderIcon.paint(p, _st.photoPosition.x(), (_rowHeight - st::stickersReorderIcon.height()) / 2, width());
}
}
if (row->sticker) {
- paintRowThumbnail(p, row, stickerx);
+ paintRowThumbnail(p, row, stickerskip + _st.photoPosition.x());
}
- int namex = stickerx + st::contactsPhotoSize + st::contactsPadding.left();
- int namey = st::contactsPadding.top() + st::contactsNameTop;
+ int namex = stickerskip + _st.namePosition.x();
+ int namey = _st.namePosition.y();
- int statusx = namex;
- int statusy = st::contactsPadding.top() + st::contactsStatusTop;
+ int statusx = stickerskip + _st.statusPosition.x();
+ int statusy = _st.statusPosition.y();
p.setFont(st::contactsNameStyle.font);
- p.setPen(st::contactsNameFg);
+ p.setPen(_st.nameFg);
p.drawTextLeft(namex, namey, width(), row->title, row->titleWidth);
if (row->isUnread()) {
@@ -1425,7 +1432,7 @@ void StickersBox::Inner::paintRow(Painter &p, not_null row, int index) {
: tr::lng_stickers_count(tr::now, lt_count, row->count);
p.setFont(st::contactsStatusFont);
- p.setPen(st::contactsStatusFg);
+ p.setPen(_st.statusFg);
p.drawTextLeft(statusx, statusy, width(), statusText);
p.setOpacity(1);
@@ -1457,15 +1464,15 @@ void StickersBox::Inner::paintRowThumbnail(
? row->stickerMedia->thumbnail()
: nullptr;
const auto paused = _show->paused(ChatHelpers::PauseReason::Layer);
- const auto x = left + (st::contactsPhotoSize - row->pixw) / 2;
- const auto y = st::contactsPadding.top() + (st::contactsPhotoSize - row->pixh) / 2;
+ const auto x = left + (_st.photoSize - row->pixw) / 2;
+ const auto y = _st.photoPosition.y() + (_st.photoSize - row->pixh) / 2;
if (row->lottie && row->lottie->ready()) {
const auto frame = row->lottie->frame();
const auto size = frame.size() / cIntRetinaFactor();
p.drawImage(
QRect(
- left + (st::contactsPhotoSize - size.width()) / 2,
- st::contactsPadding.top() + (st::contactsPhotoSize - size.height()) / 2,
+ left + (_st.photoSize - size.width()) / 2,
+ _st.photoPosition.y() + (_st.photoSize - size.height()) / 2,
size.width(),
size.height()),
frame);
@@ -1500,9 +1507,7 @@ void StickersBox::Inner::validateLottieAnimation(not_null row) {
row->thumbnailMedia.get(),
row->stickerMedia.get(),
ChatHelpers::StickerLottieSize::SetsListThumbnail,
- QSize(
- st::contactsPhotoSize,
- st::contactsPhotoSize) * cIntRetinaFactor());
+ QSize(_st.photoSize, _st.photoSize) * cIntRetinaFactor());
if (!player) {
return;
}
@@ -1572,15 +1577,12 @@ void StickersBox::Inner::updateRowThumbnail(not_null row) {
}
Unexpected("StickersBox::Inner::updateRowThumbnail: row not found");
}();
- const auto left = st::contactsPadding.left()
+ const auto left = _st.photoPosition.x()
+ ((!_megagroupSet && _isInstalledTab)
? st::stickersReorderIcon.width() + st::stickersReorderSkip
: 0);
- update(
- left,
- rowTop + st::contactsPadding.top(),
- st::contactsPhotoSize,
- st::contactsPhotoSize);
+ const auto top = rowTop + _st.photoPosition.y();
+ update(left, top, _st.photoSize, _st.photoSize);
}
void StickersBox::Inner::paintFakeButton(Painter &p, not_null row, int index) {
@@ -1818,7 +1820,7 @@ void StickersBox::Inner::updateSelected() {
actionSel = -1;
}
if (!_megagroupSet && _isInstalledTab && !row->isRecentSet()) {
- auto dragAreaWidth = st::contactsPadding.left() + st::stickersReorderIcon.width() + st::stickersReorderSkip;
+ auto dragAreaWidth = _st.photoPosition.x() + st::stickersReorderIcon.width() + st::stickersReorderSkip;
auto dragArea = myrtlrect(0, 0, dragAreaWidth, _rowHeight);
inDragArea = dragArea.contains(local);
}
@@ -2142,7 +2144,7 @@ void StickersBox::Inner::rebuildMegagroupSet() {
}
void StickersBox::Inner::rebuild(bool masks) {
- _itemsTop = st::membersMarginTop;
+ _itemsTop = st::lineWidth;
if (_megagroupSet) {
_itemsTop += st::groupStickersFieldPadding.top() + _megagroupSetField->height() + st::groupStickersFieldPadding.bottom();
@@ -2291,11 +2293,11 @@ bool StickersBox::Inner::skipPremium() const {
}
int StickersBox::Inner::countMaxNameWidth(bool installedSet) const {
- int namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
+ int namex = _st.namePosition.x();
if (!_megagroupSet && _isInstalledTab) {
namex += st::stickersReorderIcon.width() + st::stickersReorderSkip;
}
- int namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x();
+ int namew = st::boxWideWidth - namex - st::contactsPadding.right();
if (_isInstalledTab) {
if (!_megagroupSet) {
namew -= _undoWidth - st::stickersUndoRemove.width;
@@ -2401,17 +2403,17 @@ void StickersBox::Inner::fillSetCover(
: QSize(1, 1);
auto pixw = size.width();
auto pixh = size.height();
- if (pixw > st::contactsPhotoSize) {
+ if (pixw > _st.photoSize) {
if (pixw > pixh) {
- pixh = (pixh * st::contactsPhotoSize) / pixw;
- pixw = st::contactsPhotoSize;
+ pixh = (pixh * _st.photoSize) / pixw;
+ pixw = _st.photoSize;
} else {
- pixw = (pixw * st::contactsPhotoSize) / pixh;
- pixh = st::contactsPhotoSize;
+ pixw = (pixw * _st.photoSize) / pixh;
+ pixh = _st.photoSize;
}
- } else if (pixh > st::contactsPhotoSize) {
- pixw = (pixw * st::contactsPhotoSize) / pixh;
- pixh = st::contactsPhotoSize;
+ } else if (pixh > _st.photoSize) {
+ pixw = (pixw * _st.photoSize) / pixh;
+ pixh = _st.photoSize;
}
*outWidth = pixw;
*outHeight = pixh;
diff --git a/Telegram/SourceFiles/boxes/stickers_box.h b/Telegram/SourceFiles/boxes/stickers_box.h
index fa3647691..f0e54374a 100644
--- a/Telegram/SourceFiles/boxes/stickers_box.h
+++ b/Telegram/SourceFiles/boxes/stickers_box.h
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace style {
struct RippleAnimation;
+struct PeerListItem;
} // namespace style
namespace Ui {
@@ -142,6 +143,7 @@ private:
std::array widgets() const;
+ const style::PeerListItem &_st;
const std::shared_ptr _show;
const not_null _session;
MTP::Sender _api;
diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp
index fcb0a1c7b..46481cad6 100644
--- a/Telegram/SourceFiles/calls/calls_panel.cpp
+++ b/Telegram/SourceFiles/calls/calls_panel.cpp
@@ -95,6 +95,7 @@ Panel::Panel(not_null call)
_decline->entity()->setText(tr::lng_call_decline());
_cancel->setDuration(st::callPanelDuration);
_cancel->entity()->setText(tr::lng_call_cancel());
+ _screencast->setDuration(st::callPanelDuration);
initWindow();
initWidget();
@@ -299,6 +300,7 @@ void Panel::initControls() {
_decline->finishAnimating();
_cancel->finishAnimating();
+ _screencast->finishAnimating();
}
void Panel::setIncomingSize(QSize size) {
@@ -595,6 +597,7 @@ void Panel::showControls() {
widget()->showChildren();
_decline->setVisible(_decline->toggled());
_cancel->setVisible(_cancel->toggled());
+ _screencast->setVisible(_screencast->toggled());
const auto shown = !_incomingFrameSize.isEmpty();
_incoming->widget()->setVisible(shown);
@@ -753,12 +756,6 @@ void Panel::updateControlsGeometry() {
updateOutgoingVideoBubbleGeometry();
}
- auto threeWidth = _answerHangupRedial->width()
- + st::callCancel.button.width
- - _screencast->width();
- _decline->moveToLeft((widget()->width() - threeWidth) / 2, _buttonsTop);
- _cancel->moveToLeft((widget()->width() - threeWidth) / 2, _buttonsTop);
-
updateHangupGeometry();
}
@@ -779,22 +776,28 @@ void Panel::updateOutgoingVideoBubbleGeometry() {
}
void Panel::updateHangupGeometry() {
- auto twoWidth = _answerHangupRedial->width() + _screencast->width();
- auto threeWidth = twoWidth + st::callCancel.button.width;
- auto rightFrom = (widget()->width() - threeWidth) / 2;
- auto rightTo = (widget()->width() - twoWidth) / 2;
- auto hangupProgress = (_call
- && _call->state() == State::WaitingUserConfirmation)
+ const auto isWaitingUser = (_call
+ && _call->state() == State::WaitingUserConfirmation);
+ const auto hangupProgress = isWaitingUser
? 0.
: _hangupShownProgress.value(_hangupShown ? 1. : 0.);
- auto hangupRight = anim::interpolate(rightFrom, rightTo, hangupProgress);
- _answerHangupRedial->moveToRight(hangupRight, _buttonsTop);
_answerHangupRedial->setProgress(hangupProgress);
- _mute->moveToRight(hangupRight - _mute->width(), _buttonsTop);
- _screencast->moveToLeft(hangupRight - _mute->width(), _buttonsTop);
- _camera->moveToLeft(
- hangupRight - _mute->width() + _screencast->width(),
- _buttonsTop);
+
+ // Screencast - Camera - Cancel/Decline - Answer/Hangup/Redial - Mute.
+ const auto buttonWidth = st::callCancel.button.width;
+ const auto cancelWidth = buttonWidth * (1. - hangupProgress);
+ const auto cancelLeft = (isWaitingUser)
+ ? ((widget()->width() - buttonWidth) / 2)
+ : (_mute->animating())
+ ? ((widget()->width() - cancelWidth) / 2)
+ : ((widget()->width() / 2) - cancelWidth);
+
+ _cancel->moveToLeft(cancelLeft, _buttonsTop);
+ _decline->moveToLeft(cancelLeft, _buttonsTop);
+ _camera->moveToLeft(cancelLeft - buttonWidth, _buttonsTop);
+ _screencast->moveToLeft(_camera->x() - buttonWidth, _buttonsTop);
+ _answerHangupRedial->moveToLeft(cancelLeft + cancelWidth, _buttonsTop);
+ _mute->moveToLeft(_answerHangupRedial->x() + buttonWidth, _buttonsTop);
if (_startVideo) {
_startVideo->moveToLeft(_camera->x(), _camera->y());
}
@@ -877,7 +880,9 @@ void Panel::stateChanged(State state) {
toggleButton(_decline, incomingWaiting);
toggleButton(_cancel, (isBusy || isWaitingUser));
toggleButton(_mute, !isWaitingUser);
- toggleButton(_screencast, !isWaitingUser);
+ toggleButton(
+ _screencast,
+ !(isBusy || isWaitingUser || incomingWaiting));
const auto hangupShown = !_decline->toggled()
&& !_cancel->toggled();
if (_hangupShown != hangupShown) {
diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style
index e791a7a35..79c85a03d 100644
--- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style
+++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style
@@ -313,10 +313,26 @@ stickersUndoRemove: RoundButton(defaultLightButton) {
}
stickersRemoveSkip: 4px;
stickersReorderIcon: icon {{ "stickers_reorder", menuIconFg }};
-stickersReorderSkip: 13px;
+stickersReorderSkip: 18px;
stickersTabs: defaultTabsSlider;
+stickersRowItem: PeerListItem(defaultPeerListItem) {
+ height: 52px;
+ photoSize: 32px;
+ photoPosition: point(18px, 10px);
+ namePosition: point(66px, 7px);
+ statusPosition: point(66px, 26px);
+ button: OutlineButton(defaultPeerListButton) {
+ textBg: contactsBg;
+ textBgOver: contactsBgOver;
+ ripple: defaultRippleAnimation;
+ }
+ statusFg: contactsStatusFg;
+ statusFgOver: contactsStatusFgOver;
+ statusFgActive: contactsStatusFgOnline;
+}
+
stickerEmojiSkip: 5px;
stickersFeaturedBadgeFont: font(12px bold);
@@ -351,11 +367,7 @@ filtersRemove: IconButton(stickersRemove) {
emojiPanMargins: margins(10px, 10px, 10px, 10px);
-emojiTabs: SettingsSlider(defaultTabsSlider) {
- height: 43px;
- barTop: 40px;
- labelTop: 12px;
-}
+emojiTabs: defaultTabsSlider;
emojiCategoryIconTop: 6px;
emojiPanAnimation: PanelAnimation(defaultPanelAnimation) {
@@ -508,6 +520,7 @@ sendBoxAlbumGroupSkipRight: 5px;
sendBoxAlbumGroupSkipTop: 5px;
sendBoxAlbumGroupRadius: 4px;
sendBoxAlbumGroupSize: size(62px, 25px);
+sendBoxAlbumGroupSizeVertical: size(30px, 50px);
sendBoxAlbumSmallGroupSize: size(30px, 25px);
sendBoxFileGroupSkipTop: 2px;
diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp
index f124b2b3f..ba10ed476 100644
--- a/Telegram/SourceFiles/core/application.cpp
+++ b/Telegram/SourceFiles/core/application.cpp
@@ -123,7 +123,7 @@ void SetCrashAnnotationsGL() {
case Ui::GL::ANGLE::D3D11: return "Direct3D 11";
case Ui::GL::ANGLE::D3D9: return "Direct3D 9";
case Ui::GL::ANGLE::D3D11on12: return "D3D11on12";
- case Ui::GL::ANGLE::OpenGL: return "OpenGL";
+ //case Ui::GL::ANGLE::OpenGL: return "OpenGL";
}
Unexpected("Ui::GL::CurrentANGLE value in SetupANGLE.");
}());
diff --git a/Telegram/SourceFiles/core/changelogs.cpp b/Telegram/SourceFiles/core/changelogs.cpp
index a3eeafb31..957b83f18 100644
--- a/Telegram/SourceFiles/core/changelogs.cpp
+++ b/Telegram/SourceFiles/core/changelogs.cpp
@@ -125,7 +125,15 @@ std::map BetaLogs() {
"- Fix several possible crashes.\n"
"- Deprecate macOS 10.12, Ubuntu 18.04 and CentOS 7 in July.\n"
- }
+ },
+ {
+ 4008011,
+ "- Fix initial video playback speed.\n"
+
+ "- Use native window resize on Windows 11.\n"
+
+ "- Fix memory leak in Direct3D 11 media viewer on Windows.\n"
+ },
};
};
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 072d67dba..df60a4902 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs;
constexpr auto AppNameOld = "AyuGram for Windows"_cs;
constexpr auto AppName = "AyuGram Desktop"_cs;
constexpr auto AppFile = "AyuGram"_cs;
-constexpr auto AppVersion = 4008010;
-constexpr auto AppVersionStr = "4.8.10";
-constexpr auto AppBetaVersion = false;
+constexpr auto AppVersion = 4008011;
+constexpr auto AppVersionStr = "4.8.11";
+constexpr auto AppBetaVersion = true;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp
index 820b7c0d2..7f5821b7c 100644
--- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp
+++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp
@@ -467,16 +467,17 @@ HistoryItem *ScheduledMessages::append(
// probably this message was edited.
if (data.is_edit_hide()) {
existing->applyEdition(HistoryMessageEdition(_session, data));
+ } else {
+ existing->updateSentContent({
+ qs(data.vmessage()),
+ Api::EntitiesFromMTP(
+ _session,
+ data.ventities().value_or_empty())
+ }, data.vmedia());
+ existing->updateReplyMarkup(
+ HistoryMessageMarkupData(data.vreply_markup()));
+ existing->updateForwardedInfo(data.vfwd_from());
}
- existing->updateSentContent({
- qs(data.vmessage()),
- Api::EntitiesFromMTP(
- _session,
- data.ventities().value_or_empty())
- }, data.vmedia());
- existing->updateReplyMarkup(
- HistoryMessageMarkupData(data.vreply_markup()));
- existing->updateForwardedInfo(data.vfwd_from());
existing->updateDate(data.vdate().v);
history->owner().requestItemTextRefresh(existing);
}, [&](const auto &data) {});
diff --git a/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.cpp b/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.cpp
index d1642c0d4..0d166a1e3 100644
--- a/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.cpp
+++ b/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.cpp
@@ -18,6 +18,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
extern "C" {
#include
+#if !defined DESKTOP_APP_USE_PACKAGED && !defined Q_OS_WIN && !defined Q_OS_MAC
+#include
+#endif // !DESKTOP_APP_USE_PACKAGED && !Q_OS_WIN && !Q_OS_MAC
} // extern "C"
namespace FFmpeg {
@@ -85,6 +88,47 @@ void PremultiplyLine(uchar *dst, const uchar *src, int intsCount) {
#endif // LIB_FFMPEG_USE_QT_PRIVATE_API
}
+#if !defined DESKTOP_APP_USE_PACKAGED && !defined Q_OS_WIN && !defined Q_OS_MAC
+[[nodiscard]] auto CheckHwLibs() {
+ auto list = std::deque{
+ AV_PIX_FMT_CUDA,
+ };
+ const auto vdpau = [&] {
+ if (const auto handle = dlopen("libvdpau.so.1", RTLD_LAZY)) {
+ dlclose(handle);
+ }
+ if (dlerror()) {
+ return false;
+ }
+ return true;
+ }();
+ if (vdpau) {
+ list.push_front(AV_PIX_FMT_VDPAU);
+ }
+ const auto va = [&] {
+ const auto list = std::array{
+ "libva-drm.so.1",
+ "libva-x11.so.1",
+ "libva.so.1",
+ "libdrm.so.2",
+ };
+ for (const auto lib : list) {
+ if (const auto handle = dlopen(lib, RTLD_LAZY)) {
+ dlclose(handle);
+ }
+ if (dlerror()) {
+ return false;
+ }
+ }
+ return true;
+ }();
+ if (va) {
+ list.push_front(AV_PIX_FMT_VAAPI);
+ }
+ return list;
+}
+#endif // !DESKTOP_APP_USE_PACKAGED && !Q_OS_WIN && !Q_OS_MAC
+
[[nodiscard]] bool InitHw(AVCodecContext *context, AVHWDeviceType type) {
AVCodecContext *parent = static_cast(context->opaque);
@@ -125,6 +169,9 @@ void PremultiplyLine(uchar *dst, const uchar *src, int intsCount) {
}
return false;
};
+#if !defined DESKTOP_APP_USE_PACKAGED && !defined Q_OS_WIN && !defined Q_OS_MAC
+ static const auto list = CheckHwLibs();
+#else // !DESKTOP_APP_USE_PACKAGED && !Q_OS_WIN && !Q_OS_MAC
const auto list = std::array{
#ifdef Q_OS_WIN
AV_PIX_FMT_D3D11,
@@ -138,6 +185,7 @@ void PremultiplyLine(uchar *dst, const uchar *src, int intsCount) {
AV_PIX_FMT_CUDA,
#endif // Q_OS_WIN || Q_OS_MAC
};
+#endif // DESKTOP_APP_USE_PACKAGED || Q_OS_WIN || Q_OS_MAC
for (const auto format : list) {
if (!has(format)) {
continue;
diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp
index 537a8a66c..d8e7a9fc9 100644
--- a/Telegram/SourceFiles/history/history_item.cpp
+++ b/Telegram/SourceFiles/history/history_item.cpp
@@ -1469,6 +1469,12 @@ void HistoryItem::applyEdition(HistoryMessageEdition &&edition) {
// }
//}
+ const auto updatingSavedLocalEdit = !edition.savePreviousMedia
+ && (_savedLocalEditMediaData != nullptr);
+ if (!_savedLocalEditMediaData && edition.savePreviousMedia) {
+ savePreviousMedia();
+ }
+
if (edition.isEditHide) {
_flags |= MessageFlag::HideEdited;
} else {
@@ -1488,8 +1494,14 @@ void HistoryItem::applyEdition(HistoryMessageEdition &&edition) {
setReplyMarkup(base::take(edition.replyMarkup));
}
if (!isLocalUpdateMedia()) {
- removeFromSharedMediaIndex();
- refreshMedia(edition.mtpMedia);
+ if (updatingSavedLocalEdit) {
+ _savedLocalEditMediaData->media = edition.mtpMedia
+ ? CreateMedia(this, *edition.mtpMedia)
+ : nullptr;
+ } else {
+ removeFromSharedMediaIndex();
+ refreshMedia(edition.mtpMedia);
+ }
}
if (!edition.useSameReactions) {
updateReactions(edition.mtpReactions);
@@ -1500,10 +1512,18 @@ void HistoryItem::applyEdition(HistoryMessageEdition &&edition) {
if (!edition.useSameForwards) {
setForwardsCount(edition.forwards);
}
- setText(_media
+ const auto &checkedMedia = updatingSavedLocalEdit
+ ? _savedLocalEditMediaData->media
+ : _media;
+ auto updatedText = checkedMedia
? edition.textWithEntities
- : EnsureNonEmpty(edition.textWithEntities));
- if (!isLocalUpdateMedia()) {
+ : EnsureNonEmpty(edition.textWithEntities);
+ if (updatingSavedLocalEdit) {
+ _savedLocalEditMediaData->text = std::move(updatedText);
+ } else {
+ setText(std::move(updatedText));
+ }
+ if (!isLocalUpdateMedia() && !updatingSavedLocalEdit) {
indexAsNewItem();
}
if (!edition.useSameReplies) {
@@ -1652,6 +1672,9 @@ void HistoryItem::applySentMessage(
void HistoryItem::updateSentContent(
const TextWithEntities &textWithEntities,
const MTPMessageMedia *media) {
+ if (_savedLocalEditMediaData) {
+ return;
+ }
setText(textWithEntities);
if (_flags & MessageFlag::FromInlineBot) {
if (!media || !_media || !_media->updateInlineResultMedia(*media)) {
diff --git a/Telegram/SourceFiles/history/history_item_edition.h b/Telegram/SourceFiles/history/history_item_edition.h
index 2ca37c71a..b24bf8836 100644
--- a/Telegram/SourceFiles/history/history_item_edition.h
+++ b/Telegram/SourceFiles/history/history_item_edition.h
@@ -29,6 +29,7 @@ struct HistoryMessageEdition {
bool useSameReplies = false;
bool useSameMarkup = false;
bool useSameReactions = false;
+ bool savePreviousMedia = false;
TextWithEntities textWithEntities;
HistoryMessageMarkupData replyMarkup;
HistoryMessageRepliesData replies;
diff --git a/Telegram/SourceFiles/history/view/controls/compose_controls_common.h b/Telegram/SourceFiles/history/view/controls/compose_controls_common.h
index f32132ccb..06f295ee8 100644
--- a/Telegram/SourceFiles/history/view/controls/compose_controls_common.h
+++ b/Telegram/SourceFiles/history/view/controls/compose_controls_common.h
@@ -25,7 +25,7 @@ struct MessageToEdit {
struct VoiceToSend {
QByteArray bytes;
VoiceWaveform waveform;
- int duration = 0;
+ crl::time duration = 0;
Api::SendOptions options;
};
struct SendActionUpdate {
diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
index 6fc441078..242e094cd 100644
--- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
+++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
@@ -77,8 +77,8 @@ enum class FilterType {
return std::clamp(float64(low) / high, 0., 1.);
}
-[[nodiscard]] auto Duration(int samples) {
- return samples / ::Media::Player::kDefaultFrequency;
+[[nodiscard]] crl::time Duration(int samples) {
+ return samples * crl::time(1000) / ::Media::Player::kDefaultFrequency;
}
[[nodiscard]] auto FormatVoiceDuration(int samples) {
diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp b/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp
index 037819498..2b82db6f2 100644
--- a/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp
@@ -55,7 +55,9 @@ namespace {
result.preview = kEmpty;
result.spoilerRepaint = nullptr;
} else {
- result.preview = preview->original();
+ result.preview = Images::Round(
+ preview->original(),
+ ImageRoundRadius::Small);
result.spoilerRepaint = spoiler ? repaint : nullptr;
}
return result;
diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp
index 602f46ae2..d8db92e6d 100644
--- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp
@@ -607,7 +607,7 @@ void ScheduledWidget::send(Api::SendOptions options) {
void ScheduledWidget::sendVoice(
QByteArray bytes,
VoiceWaveform waveform,
- int duration) {
+ crl::time duration) {
const auto callback = [=](Api::SendOptions options) {
sendVoice(bytes, waveform, duration, options);
};
@@ -617,7 +617,7 @@ void ScheduledWidget::sendVoice(
void ScheduledWidget::sendVoice(
QByteArray bytes,
VoiceWaveform waveform,
- int duration,
+ crl::time duration,
Api::SendOptions options) {
session().api().sendVoiceMessage(
bytes,
diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h
index 2173d3dcc..1c715e17e 100644
--- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h
+++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h
@@ -197,11 +197,14 @@ private:
Api::SendOptions options) const;
void send();
void send(Api::SendOptions options);
- void sendVoice(QByteArray bytes, VoiceWaveform waveform, int duration);
void sendVoice(
QByteArray bytes,
VoiceWaveform waveform,
- int duration,
+ crl::time duration);
+ void sendVoice(
+ QByteArray bytes,
+ VoiceWaveform waveform,
+ crl::time duration,
Api::SendOptions options);
void edit(
not_null item,
diff --git a/Telegram/SourceFiles/info/downloads/info_downloads_inner_widget.h b/Telegram/SourceFiles/info/downloads/info_downloads_inner_widget.h
index 2d2047f5e..65b55f4d0 100644
--- a/Telegram/SourceFiles/info/downloads/info_downloads_inner_widget.h
+++ b/Telegram/SourceFiles/info/downloads/info_downloads_inner_widget.h
@@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unique_qptr.h"
namespace Ui {
-class SettingsSlider;
class VerticalLayout;
class SearchFieldController;
} // namespace Ui
diff --git a/Telegram/SourceFiles/info/info_section_widget.h b/Telegram/SourceFiles/info/info_section_widget.h
index 8ff1dbcfa..f53ed505f 100644
--- a/Telegram/SourceFiles/info/info_section_widget.h
+++ b/Telegram/SourceFiles/info/info_section_widget.h
@@ -10,10 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
#include "window/section_widget.h"
-namespace Ui {
-class SettingsSlider;
-} // namespace Ui
-
namespace Window {
class ConnectionState;
} // namespace Window
diff --git a/Telegram/SourceFiles/info/info_wrap_widget.h b/Telegram/SourceFiles/info/info_wrap_widget.h
index 47215d340..5445185e1 100644
--- a/Telegram/SourceFiles/info/info_wrap_widget.h
+++ b/Telegram/SourceFiles/info/info_wrap_widget.h
@@ -15,7 +15,6 @@ enum class SharedMediaType : signed char;
} // namespace Storage
namespace Ui {
-class SettingsSlider;
class FadeShadow;
class PlainShadow;
class PopupMenu;
diff --git a/Telegram/SourceFiles/info/media/info_media_inner_widget.h b/Telegram/SourceFiles/info/media/info_media_inner_widget.h
index 4e305de40..a3e485960 100644
--- a/Telegram/SourceFiles/info/media/info_media_inner_widget.h
+++ b/Telegram/SourceFiles/info/media/info_media_inner_widget.h
@@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/media/info_media_list_widget.h"
namespace Ui {
-class SettingsSlider;
class VerticalLayout;
class SearchFieldController;
} // namespace Ui
diff --git a/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h b/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h
index 3e6819af9..0aaeed54d 100644
--- a/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h
+++ b/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h
@@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unique_qptr.h"
namespace Ui {
-class SettingsSlider;
class VerticalLayout;
} // namespace Ui
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
index e96a5c248..f5baef181 100644
--- a/Telegram/SourceFiles/mainwindow.cpp
+++ b/Telegram/SourceFiles/mainwindow.cpp
@@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/sandbox.h"
#include "core/application.h"
#include "export/export_manager.h"
+#include "inline_bots/bot_attach_web_view.h" // AttachWebView::cancel.
#include "intro/intro_widget.h"
#include "main/main_session.h"
#include "main/main_account.h" // Account::sessionValue.
@@ -198,6 +199,9 @@ void MainWindow::setupPasscodeLock() {
_passcodeLock->showFinished();
setInnerFocus();
}
+ if (const auto sessionController = controller().sessionController()) {
+ sessionController->session().attachWebView().cancel();
+ }
}
void MainWindow::clearPasscodeLock() {
diff --git a/Telegram/SourceFiles/media/audio/media_audio.cpp b/Telegram/SourceFiles/media/audio/media_audio.cpp
index 2fbe37665..9186d3616 100644
--- a/Telegram/SourceFiles/media/audio/media_audio.cpp
+++ b/Telegram/SourceFiles/media/audio/media_audio.cpp
@@ -1560,7 +1560,7 @@ Ui::PreparedFileInformation PrepareForSending(
FFMpegAttributesReader reader(Core::FileLocation(fname), data);
const auto positionMs = crl::time(0);
if (reader.open(positionMs) && reader.duration() > 0) {
- result.duration = reader.duration() / 1000;
+ result.duration = reader.duration();
result.title = reader.title();
result.performer = reader.performer();
result.cover = reader.cover();
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
index 04d814478..fb30c3b4d 100644
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
@@ -900,7 +900,7 @@ void OverlayWidget::savePosition() {
void OverlayWidget::updateGeometry(bool inMove) {
initFullScreen();
- if (_fullscreen) {
+ if (_fullscreen && (!Platform::IsWindows11OrGreater() || !isHidden())) {
updateGeometryToScreen(inMove);
} else if (_windowed && _normalGeometryInited) {
_window->setGeometry(_normalGeometry);
@@ -3209,6 +3209,12 @@ void OverlayWidget::show(OpenRequest request) {
// Count top notch on macOS before counting geometry.
_helper->beforeShow(_fullscreen);
}
+ if (_cachedShow) {
+ _cachedShow->showOrHideBoxOrLayer(
+ v::null,
+ Ui::LayerOption::CloseOther,
+ anim::type::instant);
+ }
if (photo) {
if (contextItem && contextPeer) {
return;
@@ -3529,6 +3535,9 @@ void OverlayWidget::showAndActivate() {
_wasWindowedMode = true;
} else if (_fullscreen) {
_window->showFullScreen();
+ if (Platform::IsWindows11OrGreater()) {
+ updateGeometry();
+ }
} else {
_window->showMaximized();
}
@@ -4045,8 +4054,8 @@ void OverlayWidget::restartAtSeekPosition(crl::time position) {
const auto messageId = _message ? _message->fullId() : FullMsgId();
options.audioId = AudioMsgId(_document, messageId);
options.speed = _stories
- ? Core::App().settings().videoPlaybackSpeed()
- : 1.;
+ ? 1.
+ : Core::App().settings().videoPlaybackSpeed();
if (_pip) {
_pip = nullptr;
}
diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp
index d339bc228..f09fe11f9 100644
--- a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp
+++ b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp
@@ -65,7 +65,7 @@ QByteArray DnsUserAgent() {
static const auto kResult = QByteArray(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/114.0.5735.133 Safari/537.36");
+ "Chrome/115.0.5790.102 Safari/537.36");
return kResult;
}
diff --git a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp
index aad9fe167..33b0ad780 100644
--- a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp
@@ -12,21 +12,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
-#include
-#include
+#include
+
+using namespace gi::repository;
namespace Platform {
namespace File {
void UnsafeOpenUrl(const QString &url) {
- try {
- if (Gio::AppInfo::launch_default_for_uri(
+ {
+ const auto result = Gio::AppInfo::launch_default_for_uri(
url.toStdString(),
- base::Platform::AppLaunchContext())) {
+ base::Platform::AppLaunchContext());
+
+ if (!result) {
+ LOG(("App Error: %1").arg(
+ QString::fromStdString(result.error().what())));
+ } else if (*result) {
return;
}
- } catch (const std::exception &e) {
- LOG(("App Error: %1").arg(QString::fromStdString(e.what())));
}
QDesktopServices::openUrl(url);
@@ -45,14 +49,29 @@ bool UnsafeShowOpenWith(const QString &filepath) {
}
void UnsafeLaunch(const QString &filepath) {
- try {
- if (Gio::AppInfo::launch_default_for_uri(
- Glib::filename_to_uri(filepath.toStdString()),
- base::Platform::AppLaunchContext())) {
- return;
+ if ([&] {
+ const auto filename = GLib::filename_to_uri(filepath.toStdString());
+ if (!filename) {
+ LOG(("App Error: %1").arg(
+ QString::fromStdString(filename.error().what())));
+
+ return false;
}
- } catch (const std::exception &e) {
- LOG(("App Error: %1").arg(QString::fromStdString(e.what())));
+
+ const auto result = Gio::AppInfo::launch_default_for_uri(
+ *filename,
+ base::Platform::AppLaunchContext());
+
+ if (!result) {
+ LOG(("App Error: %1").arg(
+ QString::fromStdString(result.error().what())));
+
+ return false;
+ }
+
+ return *result;
+ }()) {
+ return;
}
if (UnsafeShowOpenWith(filepath)) {
diff --git a/Telegram/SourceFiles/platform/linux/integration_linux.cpp b/Telegram/SourceFiles/platform/linux/integration_linux.cpp
index a465ddefe..f13a96bce 100644
--- a/Telegram/SourceFiles/platform/linux/integration_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/integration_linux.cpp
@@ -17,79 +17,168 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
+#include
+#include
#include
-#include
-typedef GApplication TDesktopApplication;
-typedef GApplicationClass TDesktopApplicationClass;
+namespace Platform {
+namespace {
-G_DEFINE_TYPE(
- TDesktopApplication,
- t_desktop_application,
- G_TYPE_APPLICATION)
+using namespace gi::repository;
-static void t_desktop_application_class_init(
- TDesktopApplicationClass *klass) {
- const auto application_class = G_APPLICATION_CLASS(klass);
+class Application : public Gio::impl::ApplicationImpl {
+public:
+ Application();
- application_class->local_command_line = [](
- GApplication *application,
- char ***arguments,
- int *exit_status) -> gboolean {
- return false;
- };
-
- application_class->command_line = [](
- GApplication *application,
- GApplicationCommandLine *cmdline) {
- return 0;
- };
-
- application_class->before_emit = [](
- GApplication *application,
- GVariant *platformData) {
+ void before_emit_(GLib::Variant platformData) noexcept override {
if (Platform::IsWayland()) {
static const auto keys = {
"activation-token",
"desktop-startup-id",
};
for (const auto &key : keys) {
- const char *token = nullptr;
- g_variant_lookup(platformData, key, "&s", &token);
- if (token) {
- qputenv("XDG_ACTIVATION_TOKEN", token);
+ if (auto token = platformData.lookup_value(key)) {
+ qputenv(
+ "XDG_ACTIVATION_TOKEN",
+ token.get_string(nullptr).c_str());
break;
}
}
}
- };
+ }
- application_class->add_platform_data = [](
- GApplication *application,
- GVariantBuilder *builder) {
+ void activate_() noexcept override {
+ Core::Sandbox::Instance().customEnterFromEventLoop([] {
+ Core::App().activate();
+ });
+ }
+
+ void open_(GFile **files, int n_files, const char*) noexcept override {
+ Core::Sandbox::Instance().customEnterFromEventLoop([&] {
+ for (int i = 0; i < n_files; ++i) {
+ QFileOpenEvent e(
+ QUrl(QString::fromUtf8(g_file_get_uri(files[i]))));
+ QGuiApplication::sendEvent(qApp, &e);
+ }
+ });
+ }
+
+ void add_platform_data_(GLib::VariantBuilder builder) noexcept override {
if (Platform::IsWayland()) {
const auto token = qgetenv("XDG_ACTIVATION_TOKEN");
if (!token.isEmpty()) {
- g_variant_builder_add(
- builder,
- "{sv}",
- "activation-token",
- g_variant_new_string(token.constData()));
+ builder.add_value(
+ GLib::Variant::new_dict_entry(
+ GLib::Variant::new_string("activation-token"),
+ GLib::Variant::new_variant(
+ GLib::Variant::new_string(token.toStdString()))));
qunsetenv("XDG_ACTIVATION_TOKEN");
}
}
- };
+ }
+};
+
+Application::Application()
+: Gio::impl::ApplicationImpl(this) {
+ const auto appId = QGuiApplication::desktopFileName().toStdString();
+ if (Gio::Application::id_is_valid(appId)) {
+ set_application_id(appId);
+ }
+ set_flags(Gio::ApplicationFlags::HANDLES_OPEN_);
+
+ auto actionMap = Gio::ActionMap(*this);
+
+ auto quitAction = Gio::SimpleAction::new_("quit");
+ quitAction.signal_activate().connect([](
+ Gio::SimpleAction,
+ GLib::Variant parameter) {
+ Core::Sandbox::Instance().customEnterFromEventLoop([] {
+ Core::Quit();
+ });
+ });
+ actionMap.add_action(quitAction);
+
+ using Window::Notifications::Manager;
+ using NotificationId = Manager::NotificationId;
+ using NotificationIdTuple = std::invoke_result_t<
+ decltype(&NotificationId::toTuple),
+ NotificationId*
+ >;
+
+ const auto notificationIdVariantType = [] {
+ try {
+ return gi::wrap(
+ Glib::create_variant(
+ NotificationId().toTuple()
+ ).get_type().gobj_copy(),
+ gi::transfer_full,
+ gi::direction_out
+ );
+ } catch (...) {
+ return GLib::VariantType();
+ }
+ }();
+
+ auto notificationActivateAction = Gio::SimpleAction::new_(
+ "notification-activate",
+ notificationIdVariantType);
+
+ notificationActivateAction.signal_activate().connect([](
+ Gio::SimpleAction,
+ GLib::Variant parameter) {
+ Core::Sandbox::Instance().customEnterFromEventLoop([&] {
+ try {
+ const auto &app = Core::App();
+ app.notifications().manager().notificationActivated(
+ NotificationId::FromTuple(
+ Glib::wrap(
+ parameter.gobj_copy_()
+ ).get_dynamic()
+ )
+ );
+ } catch (...) {
+ }
+ });
+ });
+
+ actionMap.add_action(notificationActivateAction);
+
+ auto notificationMarkAsReadAction = Gio::SimpleAction::new_(
+ "notification-mark-as-read",
+ notificationIdVariantType);
+
+ notificationMarkAsReadAction.signal_activate().connect([](
+ Gio::SimpleAction,
+ GLib::Variant parameter) {
+ Core::Sandbox::Instance().customEnterFromEventLoop([&] {
+ try {
+ const auto &app = Core::App();
+ app.notifications().manager().notificationReplied(
+ NotificationId::FromTuple(
+ Glib::wrap(
+ parameter.gobj_copy_()
+ ).get_dynamic()
+ ),
+ {}
+ );
+ } catch (...) {
+ }
+ });
+ });
+
+ actionMap.add_action(notificationMarkAsReadAction);
}
-static void t_desktop_application_init(TDesktopApplication *application) {
+gi::ref_ptr MakeApplication() {
+ const auto result = gi::make_ref();
+ if (const auto registered = result->register_(); !registered) {
+ LOG(("App Error: Failed to register: %1").arg(
+ QString::fromStdString(registered.error().message_())));
+ return nullptr;
+ }
+ return result;
}
-namespace Platform {
-namespace {
-
-using namespace gi::repository;
-namespace Gio = gi::repository::Gio;
-
class LinuxIntegration final : public Integration {
public:
LinuxIntegration();
@@ -103,14 +192,14 @@ private:
void initInhibit();
- static void LaunchNativeApplication();
-
+ const gi::ref_ptr _application;
XdpInhibit::InhibitProxy _inhibitProxy;
base::Platform::XDP::SettingWatcher _darkModeWatcher;
};
LinuxIntegration::LinuxIntegration()
-: _inhibitProxy(
+: _application(MakeApplication())
+, _inhibitProxy(
XdpInhibit::InhibitProxy::new_for_bus_sync(
Gio::BusType::SESSION_,
Gio::DBusProxyFlags::DO_NOT_AUTO_START_AT_CONSTRUCTION_,
@@ -139,16 +228,12 @@ LinuxIntegration::LinuxIntegration()
if (!QCoreApplication::eventDispatcher()->inherits(
"QEventDispatcherGlib")) {
g_warning("Qt is running without GLib event loop integration, "
- "except various functionality to not to work.");
+ "expect various functionality to not to work.");
}
}
void LinuxIntegration::init() {
initInhibit();
-
- Glib::signal_idle().connect_once([] {
- LaunchNativeApplication();
- });
}
void LinuxIntegration::initInhibit() {
@@ -156,7 +241,11 @@ void LinuxIntegration::initInhibit() {
return;
}
- auto uniqueName = _inhibitProxy.get_connection().get_unique_name();
+ auto uniqueName = _inhibitProxy
+ .get_connection()
+ .get_unique_name()
+ .value_or("");
+
uniqueName.erase(0, 1);
uniqueName.replace(uniqueName.find('.'), 1, 1, '_');
@@ -207,115 +296,6 @@ void LinuxIntegration::initInhibit() {
nullptr);
}
-void LinuxIntegration::LaunchNativeApplication() {
- const auto appId = QGuiApplication::desktopFileName().toStdString();
-
- const auto app = Glib::wrap(
- G_APPLICATION(
- g_object_new(
- t_desktop_application_get_type(),
- "application-id",
- ::Gio::Application::id_is_valid(appId)
- ? appId.c_str()
- : nullptr,
- "flags",
- G_APPLICATION_HANDLES_OPEN,
- nullptr)));
-
- app->signal_startup().connect([weak = std::weak_ptr(app)] {
- const auto app = weak.lock();
- if (!app) {
- return;
- }
-
- // GNotification
- InvokeQueued(qApp, [] {
- Core::App().notifications().createManager();
- });
-
- QEventLoop().exec();
- app->quit();
- }, true);
-
- app->signal_activate().connect([] {
- Core::Sandbox::Instance().customEnterFromEventLoop([] {
- Core::App().activate();
- });
- }, true);
-
- app->signal_open().connect([](
- const ::Gio::Application::type_vec_files &files,
- const Glib::ustring &hint) {
- Core::Sandbox::Instance().customEnterFromEventLoop([&] {
- for (const auto &file : files) {
- QFileOpenEvent e(
- QUrl(QString::fromStdString(file->get_uri())));
- QGuiApplication::sendEvent(qApp, &e);
- }
- });
- }, true);
-
- app->add_action("quit", [] {
- Core::Sandbox::Instance().customEnterFromEventLoop([] {
- Core::Quit();
- });
- });
-
- using Window::Notifications::Manager;
- using NotificationId = Manager::NotificationId;
- using NotificationIdTuple = std::invoke_result_t<
- decltype(&NotificationId::toTuple),
- NotificationId*
- >;
-
- const auto notificationIdVariantType = [] {
- try {
- return Glib::create_variant(
- NotificationId().toTuple()
- ).get_type();
- } catch (...) {
- return Glib::VariantType();
- }
- }();
-
- app->add_action_with_parameter(
- "notification-activate",
- notificationIdVariantType,
- [](const Glib::VariantBase ¶meter) {
- Core::Sandbox::Instance().customEnterFromEventLoop([&] {
- try {
- const auto &app = Core::App();
- app.notifications().manager().notificationActivated(
- NotificationId::FromTuple(
- parameter.get_dynamic()
- )
- );
- } catch (...) {
- }
- });
- });
-
- app->add_action_with_parameter(
- "notification-mark-as-read",
- notificationIdVariantType,
- [](const Glib::VariantBase ¶meter) {
- Core::Sandbox::Instance().customEnterFromEventLoop([&] {
- try {
- const auto &app = Core::App();
- app.notifications().manager().notificationReplied(
- NotificationId::FromTuple(
- parameter.get_dynamic()
- ),
- {}
- );
- } catch (...) {
- }
- });
- });
-
- app->run(0, nullptr);
-}
-
} // namespace
std::unique_ptr CreateIntegration() {
diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
index 849af9f37..7448d690e 100644
--- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
@@ -360,6 +360,7 @@ private:
Glib::RefPtr _application;
Glib::RefPtr _notification;
+ const std::string _guid;
Glib::RefPtr _dbusConnection;
Glib::ustring _title;
@@ -390,7 +391,8 @@ NotificationData::NotificationData(
, _id(id)
, _application(UseGNotification()
? Gio::Application::get_default()
- : nullptr) {
+ : nullptr)
+, _guid(_application ? Gio::DBus::generate_guid() : std::string()) {
}
bool NotificationData::init(
@@ -623,13 +625,7 @@ NotificationData::~NotificationData() {
void NotificationData::show() {
if (_application && _notification) {
- _application->send_notification(
- std::to_string(_id.contextId.sessionId)
- + '-'
- + std::to_string(_id.contextId.peerId.value)
- + '-'
- + std::to_string(_id.msgId.bare),
- _notification);
+ _application->send_notification(_guid, _notification);
return;
}
@@ -679,12 +675,7 @@ void NotificationData::show() {
void NotificationData::close() {
if (_application) {
- _application->withdraw_notification(
- std::to_string(_id.contextId.sessionId)
- + '-'
- + std::to_string(_id.contextId.peerId.value)
- + '-'
- + std::to_string(_id.msgId.bare));
+ _application->withdraw_notification(_guid);
_manager->clearNotification(_id);
return;
}
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 0237215bc..d13c6b332 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -382,11 +382,18 @@ bool GenerateServiceFile(bool silent = false) {
md5Hash));
}
- QProcess::execute(u"systemctl"_q, {
- u"--user"_q,
- u"reload"_q,
- u"dbus"_q,
- });
+ try {
+ const auto connection = Gio::DBus::Connection::get_sync(
+ Gio::DBus::BusType::SESSION);
+
+ connection->call_sync(
+ base::Platform::DBus::kObjectPath,
+ base::Platform::DBus::kInterface,
+ "ReloadConfig",
+ {},
+ base::Platform::DBus::kService);
+ } catch (...) {
+ }
return true;
}
diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm
index 3d09662f6..fe3d70c76 100644
--- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm
+++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm
@@ -238,7 +238,6 @@ MainWindow::MainWindow(not_null controller)
: Window::MainWindow(controller)
, _private(std::make_unique(this))
, psMainMenu(this) {
- auto forceOpenGL = std::make_unique(this);
_hideAfterFullScreenTimer.setCallback([this] { hideAndDeactivate(); });
}
diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp
index 0cd7c485f..1829f92a2 100644
--- a/Telegram/SourceFiles/settings/settings_advanced.cpp
+++ b/Telegram/SourceFiles/settings/settings_advanced.cpp
@@ -737,18 +737,19 @@ void SetupANGLE(
tr::lng_settings_angle_backend_d3d11(tr::now),
tr::lng_settings_angle_backend_d3d9(tr::now),
tr::lng_settings_angle_backend_d3d11on12(tr::now),
- tr::lng_settings_angle_backend_opengl(tr::now),
+ //tr::lng_settings_angle_backend_opengl(tr::now),
tr::lng_settings_angle_backend_disabled(tr::now),
};
- const auto backendIndex = [] {
+ const auto disabled = int(options.size()) - 1;
+ const auto backendIndex = [=] {
if (Core::App().settings().disableOpenGL()) {
- return 5;
+ return disabled;
} else switch (Ui::GL::CurrentANGLE()) {
case ANGLE::Auto: return 0;
case ANGLE::D3D11: return 1;
case ANGLE::D3D9: return 2;
case ANGLE::D3D11on12: return 3;
- case ANGLE::OpenGL: return 4;
+ //case ANGLE::OpenGL: return 4;
}
Unexpected("Ui::GL::CurrentANGLE value in SetupANGLE.");
}();
@@ -764,7 +765,7 @@ void SetupANGLE(
return;
}
const auto confirmed = crl::guard(button, [=] {
- const auto nowDisabled = (index == 5);
+ const auto nowDisabled = (index == disabled);
if (!nowDisabled) {
Ui::GL::ChangeANGLE([&] {
switch (index) {
@@ -772,12 +773,12 @@ void SetupANGLE(
case 1: return ANGLE::D3D11;
case 2: return ANGLE::D3D9;
case 3: return ANGLE::D3D11on12;
- case 4: return ANGLE::OpenGL;
+ //case 4: return ANGLE::OpenGL;
}
Unexpected("Index in SetupANGLE.");
}());
}
- const auto wasDisabled = (backendIndex == 5);
+ const auto wasDisabled = (backendIndex == disabled);
if (nowDisabled != wasDisabled) {
Core::App().settings().setDisableOpenGL(nowDisabled);
Local::writeSettings();
diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp
index d001b882a..3f96ab108 100644
--- a/Telegram/SourceFiles/storage/localimageloader.cpp
+++ b/Telegram/SourceFiles/storage/localimageloader.cpp
@@ -526,7 +526,7 @@ FileLoadTask::FileLoadTask(
FileLoadTask::FileLoadTask(
not_null session,
const QByteArray &voice,
- int32 duration,
+ crl::time duration,
const VoiceWaveform &waveform,
const FileLoadTo &to,
const TextWithTags &caption)
@@ -852,8 +852,9 @@ void FileLoadTask::process(Args &&args) {
if (auto song = std::get_if(
&_information->media)) {
isSong = true;
+ const auto seconds = song->duration / 1000;
auto flags = MTPDdocumentAttributeAudio::Flag::f_title | MTPDdocumentAttributeAudio::Flag::f_performer;
- attributes.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(song->duration), MTP_string(song->title), MTP_string(song->performer), MTPstring()));
+ attributes.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(seconds), MTP_string(song->title), MTP_string(song->performer), MTPstring()));
thumbnail = PrepareFileThumbnail(std::move(song->cover));
} else if (auto video = std::get_if(
&_information->media)) {
@@ -867,9 +868,10 @@ void FileLoadTask::process(Args &&args) {
if (video->supportsStreaming) {
flags |= MTPDdocumentAttributeVideo::Flag::f_supports_streaming;
}
+ const auto realSeconds = video->duration / 1000.;
attributes.push_back(MTP_documentAttributeVideo(
MTP_flags(flags),
- MTP_double(video->duration / 1000.),
+ MTP_double(realSeconds),
MTP_int(coverWidth),
MTP_int(coverHeight),
MTPint())); // preload_prefix_size
@@ -971,8 +973,9 @@ void FileLoadTask::process(Args &&args) {
}
if (isVoice) {
+ const auto seconds = _duration / 1000;
auto flags = MTPDdocumentAttributeAudio::Flag::f_voice | MTPDdocumentAttributeAudio::Flag::f_waveform;
- attributes[0] = MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(_duration), MTPstring(), MTPstring(), MTP_bytes(documentWaveformEncode5bit(_waveform)));
+ attributes[0] = MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(seconds), MTPstring(), MTPstring(), MTP_bytes(documentWaveformEncode5bit(_waveform)));
attributes.resize(1);
document = MTP_document(
MTP_flags(0),
diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h
index 3d4354623..97b0ad9ce 100644
--- a/Telegram/SourceFiles/storage/localimageloader.h
+++ b/Telegram/SourceFiles/storage/localimageloader.h
@@ -256,7 +256,7 @@ public:
FileLoadTask(
not_null session,
const QByteArray &voice,
- int32 duration,
+ crl::time duration,
const VoiceWaveform &waveform,
const FileLoadTo &to,
const TextWithTags &caption);
@@ -306,7 +306,7 @@ private:
QString _filepath;
QByteArray _content;
std::unique_ptr _information;
- int32 _duration = 0;
+ crl::time _duration = 0;
VoiceWaveform _waveform;
SendMediaType _type;
TextWithTags _caption;
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp
index 2f847c7c0..3c8f155d6 100644
--- a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp
@@ -259,8 +259,7 @@ void AlbumThumbnail::paintInAlbum(
_lastRectOfButtons = paintButtons(
p,
- geometry.topLeft(),
- geometry.width(),
+ geometry,
shrinkProgress);
_lastRectOfModify = geometry;
}
@@ -460,8 +459,7 @@ void AlbumThumbnail::paintPhoto(Painter &p, int left, int top, int outerWidth) {
_lastRectOfButtons = paintButtons(
p,
- topLeft,
- st::sendMediaPreviewSize,
+ QRect(left, top, st::sendMediaPreviewSize, size.height()),
0);
_lastRectOfModify = QRect(topLeft, size);
@@ -521,7 +519,9 @@ AttachButtonType AlbumThumbnail::buttonTypeFromPoint(QPoint position) const {
}
return (!_lastRectOfButtons.contains(position) && !_isCompressedSticker)
? AttachButtonType::Modify
- : (position.x() < _lastRectOfButtons.center().x())
+ : (_buttons.vertical()
+ ? (position.y() < _lastRectOfButtons.center().y())
+ : (position.x() < _lastRectOfButtons.center().x()))
? AttachButtonType::Edit
: AttachButtonType::Delete;
}
@@ -585,24 +585,31 @@ void AlbumThumbnail::finishAnimations() {
QRect AlbumThumbnail::paintButtons(
QPainter &p,
- QPoint point,
- int outerWidth,
+ QRect geometry,
float64 shrinkProgress) {
const auto &skipRight = st::sendBoxAlbumGroupSkipRight;
const auto &skipTop = st::sendBoxAlbumGroupSkipTop;
- const auto groupWidth = _buttons.width();
-
- // If the width is tiny, it would be better to not display the buttons.
- if (groupWidth > outerWidth) {
+ const auto outerWidth = geometry.width();
+ const auto outerHeight = geometry.height();
+ if (st::sendBoxAlbumGroupSize.width() <= outerWidth) {
+ _buttons.setVertical(false);
+ } else if (st::sendBoxAlbumGroupSize.height() <= outerHeight) {
+ _buttons.setVertical(true);
+ } else {
+ // If the size is tiny, skip the buttons.
return QRect();
}
+ const auto groupWidth = _buttons.width();
+ const auto groupHeight = _buttons.height();
// If the width is too small,
// it would be better to display the buttons in the center.
- const auto groupX = point.x() + ((groupWidth + skipRight * 2 > outerWidth)
+ const auto groupX = geometry.x() + ((groupWidth + skipRight * 2 > outerWidth)
? (outerWidth - groupWidth) / 2
: outerWidth - skipRight - groupWidth);
- const auto groupY = point.y() + skipTop;
+ const auto groupY = geometry.y() + ((groupHeight + skipTop * 2 > outerHeight)
+ ? (outerHeight - groupHeight) / 2
+ : skipTop);
const auto opacity = p.opacity();
p.setOpacity(1.0 - shrinkProgress);
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h
index c3ffac584..1bfd8fc62 100644
--- a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h
@@ -78,8 +78,7 @@ private:
void drawSimpleFrame(QPainter &p, QRect to, QSize size) const;
QRect paintButtons(
QPainter &p,
- QPoint point,
- int outerWidth,
+ QRect geometry,
float64 shrinkProgress);
void paintPlayVideo(QPainter &p, QRect geometry);
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp
index 7ad686350..775218a87 100644
--- a/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp
@@ -25,10 +25,15 @@ void AttachControls::paint(QPainter &p, int x, int y) {
if (full) {
const auto groupHalfWidth = groupWidth / 2;
- QRect leftRect(x, y, groupHalfWidth, groupHeight);
- st::sendBoxAlbumGroupButtonMediaEdit.paintInCenter(p, leftRect);
- QRect rightRect(x + groupHalfWidth, y, groupHalfWidth, groupHeight);
- st::sendBoxAlbumGroupButtonMediaDelete.paintInCenter(p, rightRect);
+ const auto groupHalfHeight = groupHeight / 2;
+ const auto editRect = _vertical
+ ? QRect(x, y, groupWidth, groupHalfHeight)
+ : QRect(x, y, groupHalfWidth, groupHeight);
+ st::sendBoxAlbumGroupButtonMediaEdit.paintInCenter(p, editRect);
+ const auto deleteRect = _vertical
+ ? QRect(x, y + groupHalfHeight, groupWidth, groupHalfHeight)
+ : QRect(x + groupHalfWidth, y, groupHalfWidth, groupHeight);
+ st::sendBoxAlbumGroupButtonMediaDelete.paintInCenter(p, deleteRect);
} else if (_type == Type::EditOnly) {
st::sendBoxAlbumButtonMediaEdit.paintInCenter(p, groupRect);
}
@@ -36,7 +41,9 @@ void AttachControls::paint(QPainter &p, int x, int y) {
int AttachControls::width() const {
return (_type == Type::Full)
- ? st::sendBoxAlbumGroupSize.width()
+ ? (_vertical
+ ? st::sendBoxAlbumGroupSizeVertical.width()
+ : st::sendBoxAlbumGroupSize.width())
: (_type == Type::EditOnly)
? st::sendBoxAlbumSmallGroupSize.width()
: 0;
@@ -44,7 +51,9 @@ int AttachControls::width() const {
int AttachControls::height() const {
return (_type == Type::Full)
- ? st::sendBoxAlbumGroupSize.height()
+ ? (_vertical
+ ? st::sendBoxAlbumGroupSizeVertical.height()
+ : st::sendBoxAlbumGroupSize.height())
: (_type == Type::EditOnly)
? st::sendBoxAlbumSmallGroupSize.height()
: 0;
@@ -54,12 +63,20 @@ AttachControls::Type AttachControls::type() const {
return _type;
}
+bool AttachControls::vertical() const {
+ return _vertical;
+}
+
void AttachControls::setType(Type type) {
if (_type != type) {
_type = type;
}
}
+void AttachControls::setVertical(bool vertical) {
+ _vertical = vertical;
+}
+
AttachControlsWidget::AttachControlsWidget(
not_null parent,
AttachControls::Type type)
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_controls.h b/Telegram/SourceFiles/ui/chat/attach/attach_controls.h
index 9b7ad55c5..bf6992774 100644
--- a/Telegram/SourceFiles/ui/chat/attach/attach_controls.h
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_controls.h
@@ -25,14 +25,17 @@ public:
void paint(QPainter &p, int x, int y);
void setType(Type type);
+ void setVertical(bool vertical);
[[nodiscard]] int width() const;
[[nodiscard]] int height() const;
[[nodiscard]] Type type() const;
+ [[nodiscard]] bool vertical() const;
private:
RoundRect _rect;
Type _type = Type::Full;
+ bool _vertical = false;
};
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h
index f78655c66..c6a74790a 100644
--- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h
@@ -27,7 +27,7 @@ struct PreparedFileInformation {
Editor::PhotoModifications modifications;
};
struct Song {
- int duration = -1;
+ crl::time duration = -1;
QString title;
QString performer;
QImage cover;
diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style
index 4119099de..35f3967c0 100644
--- a/Telegram/SourceFiles/ui/chat/chat.style
+++ b/Telegram/SourceFiles/ui/chat/chat.style
@@ -523,7 +523,7 @@ historyFastShareSize: 31px;
historyFastShareLeft: 13px;
historyFastShareBottom: 5px;
historyFastShareIcon: icon {{ "fast_share", msgServiceFg }};
-historyGoToOriginalIcon: icon {{ "fast_to_original", msgServiceFg }};
+historyGoToOriginalIcon: icon {{ "fast_to_original", msgServiceFg, point(1px, 0px) }};
historyFastCommentsIcon: icon {{ "fast_comments", msgServiceFg }};
historyFastTranscribeIcon: icon {{ "chat/voice_to_text", msgServiceFg }};
diff --git a/Telegram/SourceFiles/ui/controls/silent_toggle.cpp b/Telegram/SourceFiles/ui/controls/silent_toggle.cpp
index e583af790..2968c80fd 100644
--- a/Telegram/SourceFiles/ui/controls/silent_toggle.cpp
+++ b/Telegram/SourceFiles/ui/controls/silent_toggle.cpp
@@ -31,23 +31,29 @@ SilentToggle::SilentToggle(QWidget *parent, not_null channel)
resize(_st.width, _st.height);
- paintRequest(
- ) | rpl::start_with_next([=](const QRect &clip) {
- auto p = QPainter(this);
- paintRipple(p, _st.rippleAreaPosition, nullptr);
-
- //const auto checked = _crossLineAnimation.value(_checked ? 1. : 0.);
- const auto over = isOver();
- (_checked
- ? (over
- ? st::historySilentToggleOnOver
- : st::historySilentToggleOn)
- : (over
- ? st::historySilentToggle.iconOver
- : st::historySilentToggle.icon)).paintInCenter(p, rect());
- }, lifetime());
-
setMouseTracking(true);
+
+ clicks(
+ ) | rpl::start_with_next([=] {
+ setChecked(!_checked);
+ Ui::Tooltip::Show(0, this);
+ _channel->owner().notifySettings().update(_channel, {}, _checked);
+ }, lifetime());
+}
+
+void SilentToggle::paintEvent(QPaintEvent *e) {
+ auto p = QPainter(this);
+ paintRipple(p, _st.rippleAreaPosition, nullptr);
+
+ //const auto checked = _crossLineAnimation.value(_checked ? 1. : 0.);
+ const auto over = isOver();
+ (_checked
+ ? (over
+ ? st::historySilentToggleOnOver
+ : st::historySilentToggleOn)
+ : (over
+ ? st::historySilentToggle.iconOver
+ : st::historySilentToggle.icon)).paintInCenter(p, rect());
}
void SilentToggle::mouseMoveEvent(QMouseEvent *e) {
@@ -62,11 +68,12 @@ void SilentToggle::mouseMoveEvent(QMouseEvent *e) {
void SilentToggle::setChecked(bool checked) {
if (_checked != checked) {
_checked = checked;
- _crossLineAnimation.start(
- [=] { update(); },
- _checked ? 0. : 1.,
- _checked ? 1. : 0.,
- kAnimationDuration);
+ update();
+ // _crossLineAnimation.start(
+ // [=] { update(); },
+ // _checked ? 0. : 1.,
+ // _checked ? 1. : 0.,
+ // kAnimationDuration);
}
}
@@ -75,13 +82,6 @@ void SilentToggle::leaveEventHook(QEvent *e) {
Ui::Tooltip::Hide();
}
-void SilentToggle::mouseReleaseEvent(QMouseEvent *e) {
- setChecked(!_checked);
- RippleButton::mouseReleaseEvent(e);
- Ui::Tooltip::Show(0, this);
- _channel->owner().notifySettings().update(_channel, {}, _checked);
-}
-
QString SilentToggle::tooltipText() const {
return _checked
? tr::lng_wont_be_notified(tr::now)
diff --git a/Telegram/SourceFiles/ui/controls/silent_toggle.h b/Telegram/SourceFiles/ui/controls/silent_toggle.h
index 358f958d5..e38d52fac 100644
--- a/Telegram/SourceFiles/ui/controls/silent_toggle.h
+++ b/Telegram/SourceFiles/ui/controls/silent_toggle.h
@@ -29,8 +29,8 @@ public:
bool tooltipWindowActive() const override;
protected:
+ void paintEvent(QPaintEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
- void mouseReleaseEvent(QMouseEvent *e) override;
void leaveEventHook(QEvent *e) override;
QImage prepareRippleMask() const override;
@@ -42,7 +42,7 @@ private:
not_null _channel;
bool _checked = false;
- Animations::Simple _crossLineAnimation;
+ // Animations::Simple _crossLineAnimation;
};
diff --git a/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp b/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp
index ff30d88c7..174d84d29 100644
--- a/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp
+++ b/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp
@@ -13,7 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
-DiscreteSlider::DiscreteSlider(QWidget *parent) : RpWidget(parent) {
+DiscreteSlider::DiscreteSlider(QWidget *parent, bool snapToLabel)
+: RpWidget(parent)
+, _snapToLabel(snapToLabel) {
setCursor(style::cur_pointer);
}
@@ -80,9 +82,23 @@ void DiscreteSlider::setSections(const std::vector &labels) {
resizeToWidth(width());
}
-int DiscreteSlider::getCurrentActiveLeft() {
- const auto left = _sections.empty() ? 0 : _sections[_selected].left;
- return _a_left.value(left);
+DiscreteSlider::Range DiscreteSlider::getFinalActiveRange() const {
+ const auto raw = _sections.empty() ? nullptr : &_sections[_selected];
+ if (!raw) {
+ return { 0, 0 };
+ }
+ const auto width = _snapToLabel
+ ? std::min(raw->width, raw->label.maxWidth())
+ : raw->width;
+ return { raw->left + ((raw->width - width) / 2), width };
+}
+
+DiscreteSlider::Range DiscreteSlider::getCurrentActiveRange() const {
+ const auto to = getFinalActiveRange();
+ return {
+ int(base::SafeRound(_a_left.value(to.left))),
+ int(base::SafeRound(_a_width.value(to.width))),
+ };
}
template
@@ -138,11 +154,13 @@ void DiscreteSlider::setSelectedSection(int index) {
if (index < 0 || index >= _sections.size()) return;
if (_selected != index) {
- auto from = _sections[_selected].left;
+ const auto from = getFinalActiveRange();
_selected = index;
- auto to = _sections[_selected].left;
- auto duration = getAnimationDuration();
- _a_left.start([this] { update(); }, from, to, duration);
+ const auto to = getFinalActiveRange();
+ const auto duration = getAnimationDuration();
+ const auto updater = [=] { update(); };
+ _a_left.start(updater, from.left, to.left, duration);
+ _a_width.start(updater, from.width, to.width, duration);
_callbackAfterMs = crl::now() + duration;
}
}
@@ -166,7 +184,7 @@ DiscreteSlider::Section::Section(
SettingsSlider::SettingsSlider(
QWidget *parent,
const style::SettingsSlider &st)
-: DiscreteSlider(parent)
+: DiscreteSlider(parent, st.barSnapToLabel)
, _st(st) {
if (_st.barRadius > 0) {
_bar.emplace(_st.barRadius, _st.barFg);
@@ -299,7 +317,7 @@ void SettingsSlider::paintEvent(QPaintEvent *e) {
Painter p(this);
auto clip = e->rect();
- auto activeLeft = getCurrentActiveLeft();
+ auto range = getCurrentActiveRange();
const auto drawRect = [&](QRect rect, bool active = false) {
const auto &bar = active ? _barActive : _bar;
@@ -310,9 +328,14 @@ void SettingsSlider::paintEvent(QPaintEvent *e) {
}
};
enumerateSections([&](Section §ion) {
+ const auto activeWidth = _st.barSnapToLabel
+ ? section.label.maxWidth()
+ : section.width;
+ const auto activeLeft = section.left
+ + (section.width - activeWidth) / 2;
auto active = 1.
- std::clamp(
- qAbs(activeLeft - section.left) / float64(section.width),
+ qAbs(range.left - activeLeft) / float64(section.width),
0.,
1.);
if (section.ripple) {
@@ -322,36 +345,47 @@ void SettingsSlider::paintEvent(QPaintEvent *e) {
section.ripple.reset();
}
}
- auto from = section.left, tofill = section.width;
- if (activeLeft > from) {
- auto fill = qMin(tofill, activeLeft - from);
- drawRect(myrtlrect(from, _st.barTop, fill, _st.barStroke));
- from += fill;
- tofill -= fill;
- }
- if (activeLeft + section.width > from) {
- if (auto fill = qMin(tofill, activeLeft + section.width - from)) {
- drawRect(
- myrtlrect(from, _st.barTop, fill, _st.barStroke),
- true);
+ if (!_st.barSnapToLabel) {
+ auto from = activeLeft, tofill = activeWidth;
+ if (range.left > from) {
+ auto fill = qMin(tofill, range.left - from);
+ drawRect(myrtlrect(from, _st.barTop, fill, _st.barStroke));
from += fill;
tofill -= fill;
}
+ if (range.left + activeWidth > from) {
+ if (auto fill = qMin(tofill, range.left + activeWidth - from)) {
+ drawRect(
+ myrtlrect(from, _st.barTop, fill, _st.barStroke),
+ true);
+ from += fill;
+ tofill -= fill;
+ }
+ }
+ if (tofill) {
+ drawRect(myrtlrect(from, _st.barTop, tofill, _st.barStroke));
+ }
}
- if (tofill) {
- drawRect(myrtlrect(from, _st.barTop, tofill, _st.barStroke));
- }
- if (myrtlrect(section.left, _st.labelTop, section.width, _st.labelStyle.font->height).intersects(clip)) {
+ const auto labelLeft = section.left + (section.width - section.label.maxWidth()) / 2;
+ if (myrtlrect(labelLeft, _st.labelTop, section.label.maxWidth(), _st.labelStyle.font->height).intersects(clip)) {
p.setPen(anim::pen(_st.labelFg, _st.labelFgActive, active));
section.label.drawLeft(
p,
- section.left + (section.width - section.label.maxWidth()) / 2,
+ labelLeft,
_st.labelTop,
section.label.maxWidth(),
width());
}
return true;
});
+ if (_st.barSnapToLabel) {
+ const auto add = _st.barStroke / 2;
+ const auto from = std::max(range.left - add, 0);
+ const auto till = std::min(range.left + range.width + add, width());
+ if (from < till) {
+ drawRect(myrtlrect(from, _st.barTop, till - from, _st.barStroke), true);
+ }
+ }
}
} // namespace Ui
diff --git a/Telegram/SourceFiles/ui/widgets/discrete_sliders.h b/Telegram/SourceFiles/ui/widgets/discrete_sliders.h
index 017108741..e1513e693 100644
--- a/Telegram/SourceFiles/ui/widgets/discrete_sliders.h
+++ b/Telegram/SourceFiles/ui/widgets/discrete_sliders.h
@@ -18,7 +18,7 @@ class RippleAnimation;
class DiscreteSlider : public RpWidget {
public:
- DiscreteSlider(QWidget *parent);
+ DiscreteSlider(QWidget *parent, bool snapToLabel);
void addSection(const QString &label);
void setSections(const std::vector &labels);
@@ -49,10 +49,15 @@ protected:
Ui::Text::String label;
std::unique_ptr ripple;
};
+ struct Range {
+ int left = 0;
+ int width = 0;
+ };
- int getCurrentActiveLeft();
+ [[nodiscard]] Range getFinalActiveRange() const;
+ [[nodiscard]] Range getCurrentActiveRange() const;
- int getSectionsCount() const {
+ [[nodiscard]] int getSectionsCount() const {
return _sections.size();
}
@@ -67,6 +72,7 @@ protected:
void stopAnimation() {
_a_left.stop();
+ _a_width.stop();
}
void setSelectOnPress(bool selectOnPress);
@@ -82,12 +88,14 @@ private:
std::vector _sections;
int _activeIndex = 0;
bool _selectOnPress = true;
+ bool _snapToLabel = false;
rpl::event_stream _sectionActivated;
int _pressed = -1;
int _selected = 0;
Ui::Animations::Simple _a_left;
+ Ui::Animations::Simple _a_width;
int _timerId = -1;
crl::time _callbackAfterMs = 0;
diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp
index 2049d28d1..5a52f4480 100644
--- a/Telegram/SourceFiles/window/notifications_manager.cpp
+++ b/Telegram/SourceFiles/window/notifications_manager.cpp
@@ -40,9 +40,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
-#if __has_include()
-#include
-#endif // __has_include()
+#if __has_include()
+#include
+#endif // __has_include()
namespace Window {
namespace Notifications {
@@ -90,11 +90,12 @@ base::options::toggle OptionGNotification({
.description = "Force enable GLib's GNotification."
" When disabled, autodetect is used.",
.scope = [] {
-#if __has_include()
+#if __has_include()
+ using namespace gi::repository;
return bool(Gio::Application::get_default());
-#else // __has_include()
+#else // __has_include()
return false;
-#endif // __has_include()
+#endif // __has_include()
},
.restartRequired = true,
});
diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile
index 121afb690..f0770e501 100644
--- a/Telegram/build/docker/centos_env/Dockerfile
+++ b/Telegram/build/docker/centos_env/Dockerfile
@@ -26,7 +26,7 @@ RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.n
autoconf automake libtool patch gperf flex \
fontconfig-devel freetype-devel libX11-devel at-spi2-core-devel alsa-lib-devel \
pulseaudio-libs-devel mesa-libGL-devel mesa-libEGL-devel mesa-libgbm-devel \
- libdrm-devel vulkan-devel boost169-devel fmt-devel \
+ libdrm-devel vulkan-devel libva-devel libvdpau-devel boost169-devel fmt-devel \
gtk3-devel perl-XML-Parser pkgconfig bison yasm file which xorg-x11-util-macros \
devtoolset-10-make devtoolset-10-gcc devtoolset-10-gcc-c++ \
devtoolset-10-binutils llvm-toolset-7.0 llvm-toolset-7.0-clang-devel \
@@ -420,6 +420,17 @@ RUN git clone -b libXfixes-5.0.3 --depth=1 {{ GIT_FREEDESKTOP }}/libxfixes.git \
&& cd .. \
&& rm -rf libxfixes
+FROM builder AS libXv
+COPY --link --from=libXext {{ LibrariesPath }}/libXext-cache /
+
+RUN git clone -b libXv-1.0.12 --depth=1 {{ GIT_FREEDESKTOP }}/libxv.git \
+ && cd libxv \
+ && ./autogen.sh --enable-static \
+ && make -j$(nproc) \
+ && make DESTDIR="{{ LibrariesPath }}/libXv-cache" install \
+ && cd .. \
+ && rm -rf libxv
+
FROM builder AS libXrandr
RUN git clone -b libXrandr-1.5.2 --depth=1 {{ GIT_FREEDESKTOP }}/libxrandr.git \
&& cd libxrandr \
@@ -482,6 +493,8 @@ FROM builder AS ffmpeg
COPY --link --from=opus {{ LibrariesPath }}/opus-cache /
COPY --link --from=dav1d {{ LibrariesPath }}/dav1d-cache /
COPY --link --from=libvpx {{ LibrariesPath }}/libvpx-cache /
+COPY --link --from=libXext {{ LibrariesPath }}/libXext-cache /
+COPY --link --from=libXv {{ LibrariesPath }}/libXv-cache /
COPY --link --from=nv-codec-headers {{ LibrariesPath }}/nv-codec-headers-cache /
RUN git init ffmpeg \
@@ -503,15 +516,29 @@ RUN git init ffmpeg \
--enable-libdav1d \
--enable-libopus \
--enable-libvpx \
+ --enable-vaapi \
+ --enable-vdpau \
+ --enable-xlib \
+ --enable-libdrm \
--enable-ffnvcodec \
--enable-nvdec \
--enable-cuvid \
--enable-protocol=file \
+ --enable-hwaccel=av1_vaapi \
--enable-hwaccel=av1_nvdec \
+ --enable-hwaccel=h264_vaapi \
+ --enable-hwaccel=h264_vdpau \
--enable-hwaccel=h264_nvdec \
+ --enable-hwaccel=hevc_vaapi \
+ --enable-hwaccel=hevc_vdpau \
--enable-hwaccel=hevc_nvdec \
+ --enable-hwaccel=mpeg2_vaapi \
+ --enable-hwaccel=mpeg2_vdpau \
--enable-hwaccel=mpeg2_nvdec \
+ --enable-hwaccel=mpeg4_vaapi \
+ --enable-hwaccel=mpeg4_vdpau \
--enable-hwaccel=mpeg4_nvdec \
+ --enable-hwaccel=vp8_vaapi \
--enable-hwaccel=vp8_nvdec \
--enable-decoder=aac \
--enable-decoder=aac_fixed \
@@ -839,6 +866,7 @@ COPY --link --from=xcb-render-util {{ LibrariesPath }}/xcb-render-util-cache /
COPY --link --from=xcb-cursor {{ LibrariesPath }}/xcb-cursor-cache /
COPY --link --from=libXext {{ LibrariesPath }}/libXext-cache /
COPY --link --from=libXfixes {{ LibrariesPath }}/libXfixes-cache /
+COPY --link --from=libXv {{ LibrariesPath }}/libXv-cache /
COPY --link --from=libXtst {{ LibrariesPath }}/libXtst-cache /
COPY --link --from=libXrandr {{ LibrariesPath }}/libXrandr-cache /
COPY --link --from=libXrender {{ LibrariesPath }}/libXrender-cache /
diff --git a/Telegram/build/prepare/linux.sh b/Telegram/build/prepare/linux.sh
index 7a328bc31..d3ee5b5be 100755
--- a/Telegram/build/prepare/linux.sh
+++ b/Telegram/build/prepare/linux.sh
@@ -6,5 +6,6 @@ popd > /dev/null
cd $FullScriptPath/../docker/centos_env
+poetry install
poetry run gen_dockerfile | DOCKER_BUILDKIT=1 docker build -t tdesktop:centos_env -
cd $FullExecPath
diff --git a/Telegram/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py
index a8f611a8c..1b8a37c47 100644
--- a/Telegram/build/prepare/prepare.py
+++ b/Telegram/build/prepare/prepare.py
@@ -1210,7 +1210,7 @@ stage('tg_angle', """
win:
git clone https://github.com/desktop-app/tg_angle.git
cd tg_angle
- git checkout 0bb011f9e4
+ git checkout e3f59e8d0c
mkdir out
cd out
mkdir Debug
diff --git a/Telegram/build/version b/Telegram/build/version
index f7062fb28..41c79ecaa 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 4008010
+AppVersion 4008011
AppVersionStrMajor 4.8
-AppVersionStrSmall 4.8.10
-AppVersionStr 4.8.10
-BetaChannel 0
+AppVersionStrSmall 4.8.11
+AppVersionStr 4.8.11
+BetaChannel 1
AlphaVersion 0
-AppVersionOriginal 4.8.10
+AppVersionOriginal 4.8.11.beta
diff --git a/Telegram/codegen b/Telegram/codegen
index 5a11029c4..2d03abc7d 160000
--- a/Telegram/codegen
+++ b/Telegram/codegen
@@ -1 +1 @@
-Subproject commit 5a11029c461416407a423ac9921356fba0088ab6
+Subproject commit 2d03abc7de8558ae8862688a226b3d5a817dc466
diff --git a/Telegram/lib_base b/Telegram/lib_base
index efd052594..e497dc134 160000
--- a/Telegram/lib_base
+++ b/Telegram/lib_base
@@ -1 +1 @@
-Subproject commit efd052594db9f3d85a2fbcba76db6fdecf226597
+Subproject commit e497dc134de3f8e2933ee0acdbba8bd702ce2130
diff --git a/Telegram/lib_webview b/Telegram/lib_webview
index ebb8b8b91..585056693 160000
--- a/Telegram/lib_webview
+++ b/Telegram/lib_webview
@@ -1 +1 @@
-Subproject commit ebb8b8b91fe357b2c397a3eb98655c585b8c856e
+Subproject commit 5850566934f2f6cae56646c36cb95f85c8a9c752
diff --git a/changelog.txt b/changelog.txt
index 28384f4b3..7fd07c141 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,9 @@
+4.8.11 beta (10.08.23)
+
+- Fix initial video playback speed.
+- Use native window resize on Windows 11.
+- Fix memory leak in Direct3D 11 media viewer on Windows.
+
4.8.10 (28.07.23)
- Send story sharing comments as separate messages.
diff --git a/cmake b/cmake
index 0620bb7b8..ae0986c9e 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 0620bb7b87a0ec9195151fd5eb0cf38656c1280b
+Subproject commit ae0986c9efd28c61783cfe106f8bd1b0ba3b3920
diff --git a/docs/building-linux.md b/docs/building-linux.md
index 83906ac89..6be5a32b4 100644
--- a/docs/building-linux.md
+++ b/docs/building-linux.md
@@ -1,23 +1,23 @@
## Build instructions for Linux using Docker
+### Prepare folder
+
+Choose a folder for the future build, for example **/home/user/TBuild**. It will be named ***BuildPath*** in the rest of this document. All commands will be launched from Terminal.
+
### Obtain your API credentials
You will require **api_id** and **api_hash** to access the Telegram API servers. To learn how to obtain them [click here][api_credentials].
-### Clone source code
+### Clone source code and prepare libraries
+
+Install [poetry](https://python-poetry.org), go to ***BuildPath*** and run
git clone --recursive https://github.com/telegramdesktop/tdesktop.git
-
-### Prepare libraries
-
-Install [poetry](https://python-poetry.org), go to the `tdesktop/Telegram/build/docker/centos_env` directory and run
-
- poetry install
- poetry run gen_dockerfile | DOCKER_BUILDKIT=1 docker build -t tdesktop:centos_env -
+ ./tdesktop/Telegram/build/prepare/linux.sh
### Building the project
-Go up to the `tdesktop` directory and run (using [your **api_id** and **api_hash**](#obtain-your-api-credentials))
+Go to ***BuildPath*/tdesktop** and run (using [your **api_id** and **api_hash**](#obtain-your-api-credentials))
docker run --rm -it \
-v $PWD:/usr/src/tdesktop \