Compare commits

..

36 Commits

Author SHA1 Message Date
John Preston
620639ef83 Version 2.4.7.
- Fix playback display in albums of music files.
- Several crash fixes.
2020-11-05 17:54:49 +03:00
Ilya Fedin
9329ce9059 Pin tg_owt commit in snap and add -DBUILD_SHARED_LIBS=OFF 2020-11-05 17:53:09 +03:00
23rd
42d4fdb89f Fixed preview display of small media in SendFilesBox. 2020-11-05 17:51:28 +03:00
23rd
fad7996e63 Added delete prevent in SendFilesBox when it has single item. 2020-11-05 17:51:27 +03:00
John Preston
039cad21a5 Fix view refresh for album part messages.
Fixes #8974.
2020-11-05 17:50:58 +03:00
John Preston
3fdd6848c5 Fix possible crash on macOS wake. 2020-11-05 15:05:29 +03:00
John Preston
c0043d56ea Fix crash in search row select in privacy edition. 2020-11-05 14:58:46 +03:00
John Preston
ddbd36e446 Cancel search in chat doesn't reset search query. 2020-11-05 14:58:46 +03:00
John Preston
d09ece4203 Fix albums of music files. 2020-11-05 14:58:46 +03:00
Ilya Fedin
2b39da483b Fix IBus portal service name 2020-11-05 14:38:41 +03:00
Ilya Fedin
d9711f8ebd QDir::tempPath already has fallback to /tmp 2020-11-05 14:38:25 +03:00
Ilya Fedin
ede7ad1a4c Remove TDESKTOP_FORCE_PANEL_ICON variable since tdesktop gets current icon theme just fine now 2020-11-05 14:38:03 +03:00
Ilya Fedin
55167ea95b Handle snap icon problem in snapcraft.yaml rather than in code 2020-11-05 14:38:03 +03:00
John Preston
7dffc6e912 Version 2.4.6.
- Fix image compression option when sending files with drag-n-drop.
- Fix caption text selection in media albums.
- Fix drafts display in personal chats in the chats list.
- Bug fixes and other minor improvements.
2020-11-02 13:54:30 +03:00
John Preston
f2867df340 Fix sending of album with videos.
Fixes #8960.
2020-11-02 11:50:14 +03:00
John Preston
a21b6d7416 Fix restoring scroll state with a pinned bar. 2020-11-02 11:44:05 +03:00
John Preston
07f07c5eeb Fix selection in album captions.
Fixes #8950.
2020-11-02 11:26:40 +03:00
John Preston
b179e5332a Improve layout of file albums with views/replies. 2020-11-02 11:26:40 +03:00
John Preston
5cc1871f2f Fix caption/comment label in SendFilesBox. 2020-11-02 11:26:39 +03:00
John Preston
39777f6149 Fix compress images with drag-n-drop.
Fixes #8943.
2020-11-02 11:26:39 +03:00
John Preston
6660206e61 Fix poll results opening from pinned section.
Fixes #8942.
2020-11-02 11:26:39 +03:00
John Preston
9592e7dfc8 Highlight telegram/telegraph/telescope links. 2020-11-02 11:26:39 +03:00
John Preston
4432863612 Fix draft display in dialogs list. 2020-11-02 11:26:39 +03:00
Ilya Fedin
b8018f5a7f Split system drag to a separate method in PiP 2020-11-02 10:23:06 +03:00
Ilya Fedin
44c24f9fff Fix TDESKTOP_USE_PORTAL on gtk environments 2020-11-02 10:20:53 +03:00
Ilya Fedin
204a08df14 Add a cheat code to install launcher on Linux 2020-11-02 10:17:24 +03:00
Ilya Fedin
0881e5b20d Use new AL_SOFT_direct_channels_remix extension 2020-11-02 10:16:34 +03:00
Ilya Fedin
3bd34fcff0 Remove autodark cheat code since there are an UI setting for this 2020-11-02 10:16:34 +03:00
Crist Ye
60f91ebce4 Using MS/Apple official names for stores (#8959) 2020-11-02 11:14:57 +04:00
Ilya Fedin
12a77cffd8 Add flatpak and snap update URLs 2020-11-01 18:30:12 +03:00
Ilya Fedin
03c2fc2c48 Use ibus portal whenever it present 2020-11-01 18:28:52 +03:00
GitHub Action
b7d7ba82f8 Update User-Agent for DNS to Chrome 86.0.4240.111. 2020-11-01 18:28:05 +03:00
Ilya Fedin
ad54fc6459 Try to use portals for file dialog in snap, again 2020-11-01 18:27:31 +03:00
23rd
101ba05ce3 Updated doc for Windows. 2020-11-01 18:26:13 +03:00
John Preston
6ab31219ed Workaround crash in OpenAL library.
Fixes #8887.

See https://github.com/kcat/openal-soft/issues/486
2020-11-01 18:26:04 +03:00
John Preston
8afc245422 Try to workaround MSVC compiler bug. 2020-10-31 15:14:34 +03:00
43 changed files with 383 additions and 219 deletions

View File

@@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.4.5.0" />
Version="2.4.7.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,4,5,0
PRODUCTVERSION 2,4,5,0
FILEVERSION 2,4,7,0
PRODUCTVERSION 2,4,7,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.4.5.0"
VALUE "FileVersion", "2.4.7.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.4.5.0"
VALUE "ProductVersion", "2.4.7.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,4,5,0
PRODUCTVERSION 2,4,5,0
FILEVERSION 2,4,7,0
PRODUCTVERSION 2,4,7,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.4.5.0"
VALUE "FileVersion", "2.4.7.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.4.5.0"
VALUE "ProductVersion", "2.4.7.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -4230,20 +4230,18 @@ void ApiWrap::sendFiles(
auto tasks = std::vector<std::unique_ptr<Task>>();
tasks.reserve(list.files.size());
for (auto &file : list.files) {
if (album) {
if (file.type == Ui::PreparedFile::Type::Photo
&& type != SendMediaType::File) {
type = SendMediaType::Photo;
} else {
type = SendMediaType::File;
}
}
const auto uploadWithType = !album
? type
: (file.type == Ui::PreparedFile::Type::Photo
&& type != SendMediaType::File)
? SendMediaType::Photo
: SendMediaType::File;
tasks.push_back(std::make_unique<FileLoadTask>(
&session(),
file.path,
file.content,
std::move(file.information),
type,
uploadWithType,
to,
caption,
album));

View File

@@ -77,8 +77,12 @@ std::vector<not_null<PeerData*>> PrivacyExceptionsBoxController::getResult() con
}
void PrivacyExceptionsBoxController::rowClicked(not_null<PeerListRow*> row) {
const auto peer = row->peer();
// This call may delete row, if it was a search result row.
delegate()->peerListSetRowChecked(row, !row->checked());
if (const auto channel = row->peer()->asChannel()) {
if (const auto channel = peer->asChannel()) {
if (!channel->membersCountKnown()) {
channel->updateFull();
}

View File

@@ -533,6 +533,9 @@ void SendFilesBox::pushBlock(int from, int till) {
block.takeWidget(),
QMargins(0, _inner->count() ? st::sendMediaRowSkip : 0, 0, 0));
const auto preventDelete =
widget->lifetime().make_state<rpl::event_stream<int>>();
block.itemDeleteRequest(
) | rpl::filter([=] {
return !_removingIndex;
@@ -543,12 +546,19 @@ void SendFilesBox::pushBlock(int from, int till) {
if (index < 0 || index >= _list.files.size()) {
return;
}
// Prevent item delete if it is the only one.
if (_list.files.size() == 1) {
preventDelete->fire_copy(0);
return;
}
_list.files.erase(_list.files.begin() + index);
refreshAllAfterChanges(from);
});
}, widget->lifetime());
block.itemReplaceRequest(
rpl::merge(
block.itemReplaceRequest(),
preventDelete->events()
) | rpl::start_with_next([=](int index) {
const auto replace = [=](Ui::PreparedList list) {
if (list.files.empty()) {
@@ -591,6 +601,7 @@ void SendFilesBox::pushBlock(int from, int till) {
void SendFilesBox::refreshControls() {
refreshTitleText();
updateSendWayControlsVisibility();
updateCaptionPlaceholder();
}
void SendFilesBox::setupSendWayControls() {
@@ -924,6 +935,22 @@ void SendFilesBox::setInnerFocus() {
}
}
void SendFilesBox::saveSendWaySettings() {
auto way = _sendWay.current();
auto oldWay = Core::App().settings().sendFilesWay();
if (_groupFiles->isHidden()) {
way.setGroupFiles(oldWay.groupFiles());
}
if (_list.overrideSendImagesAsPhotos == way.sendImagesAsPhotos()
|| _sendImagesAsPhotos->isHidden()) {
way.setSendImagesAsPhotos(oldWay.sendImagesAsPhotos());
}
if (way != oldWay) {
Core::App().settings().setSendFilesWay(way);
Core::App().saveSettingsDelayed();
}
}
void SendFilesBox::send(
Api::SendOptions options,
bool ctrlShiftEnter) {
@@ -939,19 +966,7 @@ void SendFilesBox::send(
return;
}
auto way = _sendWay.current();
auto oldWay = Core::App().settings().sendFilesWay();
if (_groupFiles->isHidden()) {
way.setGroupFiles(oldWay.groupFiles());
}
if (_list.overrideSendImagesAsPhotos == way.sendImagesAsPhotos()
|| _sendImagesAsPhotos->isHidden()) {
way.setSendImagesAsPhotos(oldWay.sendImagesAsPhotos());
}
if (way != oldWay) {
Core::App().settings().setSendFilesWay(way);
Core::App().saveSettingsDelayed();
}
saveSendWaySettings();
for (auto &block : _blocks) {
block.applyAlbumOrder();
@@ -963,7 +978,7 @@ void SendFilesBox::send(
: TextWithTags();
_confirmedCallback(
std::move(_list),
way,
_sendWay.current(),
std::move(caption),
options,
ctrlShiftEnter);

View File

@@ -135,6 +135,7 @@ private:
void sendSilent();
void sendScheduled();
void captionResized();
void saveSendWaySettings();
void setupDragArea();
void refreshTitleText();

View File

@@ -21,26 +21,6 @@ namespace {
std::map<int, const char*> BetaLogs() {
return {
{
1009020,
"- Fix crash in shared links search.\n"
"- Fix blurred thumbnails in albums with video files.\n"
"- Fix a possible crash in animated stickers rendering."
},
{
1009022,
"- Organize chats into Chat Folders if you have too many chats.\n"
},
{
2000001,
"- Switch between folders using Ctrl+1, ..., Ctrl+8.\n"
"- Fix crash when a pinned in folder chat was added to archive.\n"
"- Fix font issues in Linux version."
},
{
2001008,
"- Add support for full group message history export.\n"
@@ -95,6 +75,16 @@ std::map<int, const char*> BetaLogs() {
"- Enjoy dark native window frame for Telegram night mode on Windows.\n"
},
{
2004006,
"- Fix image compression option when sending files with drag-n-drop.\n"
"- Fix caption text selection in media albums.\n"
"- Fix drafts display in personal chats in the chats list.\n"
"- Bug fixes and other minor improvements.\n"
},
};
};

View File

@@ -25,14 +25,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QGuiApplication>
namespace {
bool UrlRequiresConfirmation(const QUrl &url) {
using namespace qthelp;
return !regex_match(qsl("(^|\\.)(telegram\\.org|telegra\\.ph|telesco\\.pe)$"), url.host(), RegExOption::CaseInsensitive);
}
} // namespace
return !regex_match(
"(^|\\.)(telegram\\.(org|me|dog)|t\\.me|telegra\\.ph|telesco\\.pe)$",
url.host(),
RegExOption::CaseInsensitive);
}
void HiddenUrlClickHandler::Open(QString url, QVariant context) {
url = Core::TryConvertUrlToLocal(url);
@@ -48,7 +48,7 @@ void HiddenUrlClickHandler::Open(QString url, QVariant context) {
open();
} else {
const auto parsedUrl = QUrl::fromUserInput(url);
if (UrlRequiresConfirmation(url)
if (UrlRequiresConfirmation(parsedUrl)
&& QGuiApplication::keyboardModifiers() != Qt::ControlModifier) {
Core::App().hideMediaView();
const auto displayed = parsedUrl.isValid()

View File

@@ -13,6 +13,8 @@ namespace Main {
class Session;
} // namespace Main
[[nodiscard]] bool UrlRequiresConfirmation(const QUrl &url);
class HiddenUrlClickHandler : public UrlClickHandler {
public:
HiddenUrlClickHandler(QString url) : UrlClickHandler(url, false) {

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "core/update_checker.h"
#include "platform/platform_specific.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/base_platform_file_utilities.h"
#include "base/timer.h"
@@ -1575,9 +1576,16 @@ void UpdateApplication() {
return "https://www.microsoft.com/en-us/store/p/telegram-desktop/9nztwsqntd0s";
#elif defined OS_MAC_STORE // OS_WIN_STORE
return "https://itunes.apple.com/ae/app/telegram-desktop/id946399090";
#else // OS_WIN_STORE || OS_MAC_STORE
#elif defined Q_OS_UNIX && !defined Q_OS_MAC // OS_WIN_STORE || OS_MAC_STORE
if (Platform::InFlatpak()) {
return "https://flathub.org/apps/details/org.telegram.desktop";
} else if (Platform::InSnap()) {
return "https://snapcraft.io/telegram-desktop";
}
return "https://desktop.telegram.org";
#endif // OS_WIN_STORE || OS_MAC_STORE
#else // OS_WIN_STORE || OS_MAC_STORE || (defined Q_OS_UNIX && !defined Q_OS_MAC)
return "https://desktop.telegram.org";
#endif // OS_WIN_STORE || OS_MAC_STORE || (defined Q_OS_UNIX && !defined Q_OS_MAC)
}();
UrlClickHandler::Open(url);
} else {

View File

@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Telegram Desktop"_cs;
constexpr auto AppFile = "Telegram"_cs;
constexpr auto AppVersion = 2004005;
constexpr auto AppVersionStr = "2.4.5";
constexpr auto AppVersion = 2004007;
constexpr auto AppVersionStr = "2.4.7";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -368,8 +368,8 @@ void paintRow(
p.setFont(st::dialogsTextFont);
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
if (ShowSendActionInDialogs(history)
&& !history->sendActionPainter()->paint(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {
if (!ShowSendActionInDialogs(history)
|| !history->sendActionPainter()->paint(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {
if (history->cloudDraftTextCache.isEmpty()) {
auto draftWrapped = textcmdLink(1, tr::lng_dialogs_text_from_wrapped(tr::now, lt_from, tr::lng_from_draft(tr::now)));
auto draftText = supportMode
@@ -396,8 +396,8 @@ void paintRow(
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
p.setFont(st::dialogsTextFont);
if (ShowSendActionInDialogs(history)
&& !history->sendActionPainter()->paint(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {
if (!ShowSendActionInDialogs(history)
|| !history->sendActionPainter()->paint(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {
// Empty history
}
} else if (!item->isEmpty()) {

View File

@@ -1795,10 +1795,7 @@ void Widget::onCancelSearchInChat() {
}
setSearchInChat(Key());
}
_inner->clearFilter();
_filter->clear();
_filter->updatePlaceholder();
applyFilterUpdate();
applyFilterUpdate(true);
if (!Adaptive::OneColumn() && !controller()->selectingPeer()) {
emit cancelled();
}

View File

@@ -289,45 +289,6 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
// Binary search should've skipped all the items that are above / below the visible area.
if (TopToBottom) {
if (itembottom <= _visibleAreaTop) {
QStringList debug;
for (const auto &logBlock : history->blocks) {
QStringList debugItems;
for (const auto &logItem : logBlock->messages) {
debugItems.push_back(QString("%1,%2"
).arg(logItem->y()
).arg(logItem->height()
));
}
debug.push_back(QString("b(%1,%2:%3)"
).arg(logBlock->y()
).arg(logBlock->height()
).arg(debugItems.join(';')
));
}
CrashReports::SetAnnotation(
"geometry",
QString("height:%1 "
).arg(history->height()
) + debug.join(';'));
CrashReports::SetAnnotation(
"info",
QString("block:%1(%2,%3), "
"item:%4(%5,%6), "
"limits:%7,%8, "
"has:%9"
).arg(blockIndex
).arg(block->y()
).arg(block->height()
).arg(itemIndex
).arg(view->y()
).arg(view->height()
).arg(_visibleAreaTop
).arg(_visibleAreaBottom
).arg(Logs::b(history->hasPendingResizedItems())
));
Unexpected("itembottom > _visibleAreaTop");
}
Assert(itembottom > _visibleAreaTop);
} else {
Assert(itemtop < _visibleAreaBottom);
@@ -415,8 +376,7 @@ void HistoryInner::enumerateUserpics(Method method) {
auto userpicCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
// Skip all service messages.
const auto item = view->data();
const auto message = item->toHistoryMessage();
if (!message) return true;
if (view->isHidden() || !item->toHistoryMessage()) return true;
if (lowestAttachedItemTop < 0 && view->isAttachedToNext()) {
lowestAttachedItemTop = itemtop + view->marginTop();

View File

@@ -3230,6 +3230,9 @@ void HistoryWidget::doneShow() {
} else {
handlePendingHistoryUpdate();
}
// If we show pinned bar here, we don't want it to change the
// calculated and prepared scrollTop of the messages history.
_preserveScrollTop = true;
preloadHistoryIfNeeded();
updatePinnedViewer();
if (_pinnedBar) {
@@ -3237,6 +3240,7 @@ void HistoryWidget::doneShow() {
}
checkHistoryActivation();
App::wnd()->setInnerFocus();
_preserveScrollTop = false;
}
void HistoryWidget::finishAnimating() {
@@ -5330,7 +5334,7 @@ void HistoryWidget::checkPinnedBarState() {
_pinnedBarHeight = 0;
_pinnedBar->heightValue(
) | rpl::start_with_next([=](int height) {
_topDelta = (height - _pinnedBarHeight);
_topDelta = _preserveScrollTop ? 0 : (height - _pinnedBarHeight);
_pinnedBarHeight = height;
updateHistoryGeometry();
updateControlsGeometry();

View File

@@ -599,6 +599,7 @@ private:
std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
std::unique_ptr<Ui::PinnedBar> _pinnedBar;
int _pinnedBarHeight = 0;
bool _preserveScrollTop = false;
FullMsgId _pinnedClickedId;
std::optional<FullMsgId> _minPinnedId;

View File

@@ -493,6 +493,8 @@ void Element::recountAttachToPreviousInBlocks() {
if (isHidden() || data()->isEmpty()) {
if (const auto next = nextDisplayedInBlocks()) {
next->recountAttachToPreviousInBlocks();
} else if (const auto previous = previousDisplayedInBlocks()) {
previous->setAttachToNext(false);
}
return;
}

View File

@@ -1268,8 +1268,9 @@ void ListWidget::elementStartStickerLoop(not_null<const Element*> view) {
}
void ListWidget::elementShowPollResults(
not_null<PollData*> poll,
FullMsgId context) {
not_null<PollData*> poll,
FullMsgId context) {
_controller->showPollResults(poll, context);
}
void ListWidget::elementShowTooltip(

View File

@@ -135,8 +135,10 @@ QSize Contact::countOptimalSize() {
auto minHeight = st.padding.top() + st.thumbSize + st.padding.bottom();
if (_userId) {
const auto msgsigned = item->Get<HistoryMessageSigned>();
const auto views = item->Get<HistoryMessageViews>();
if ((msgsigned && !msgsigned->isAnonymousRank)
|| item->Has<HistoryMessageViews>()) {
|| (views
&& (views->views.count >= 0 || views->replies.count > 0))) {
minHeight += st::msgDateFont->height - st::msgDateDelta.y();
}
}

View File

@@ -129,18 +129,18 @@ void Document::createComponents(bool caption) {
if (const auto thumbed = Get<HistoryDocumentThumbed>()) {
thumbed->_linksavel = std::make_shared<DocumentSaveClickHandler>(
_data,
_parent->data()->fullId());
_realParent->fullId());
thumbed->_linkopenwithl = std::make_shared<DocumentOpenWithClickHandler>(
_data,
_parent->data()->fullId());
_realParent->fullId());
thumbed->_linkcancell = std::make_shared<DocumentCancelClickHandler>(
_data,
_parent->data()->fullId());
_realParent->fullId());
}
if (const auto voice = Get<HistoryDocumentVoice>()) {
voice->_seekl = std::make_shared<VoiceSeekClickHandler>(
_data,
_parent->data()->fullId());
_realParent->fullId());
}
}
@@ -195,8 +195,10 @@ QSize Document::countOptimalSize() {
auto minHeight = st.padding.top() + st.thumbSize + st.padding.bottom();
const auto msgsigned = item->Get<HistoryMessageSigned>();
const auto views = item->Get<HistoryMessageViews>();
if (!captioned && ((msgsigned && !msgsigned->isAnonymousRank)
|| item->Has<HistoryMessageViews>()
|| (views
&& (views->views.count >= 0 || views->replies.count > 0))
|| _parent->displayEditedBadge())) {
minHeight += st::msgDateFont->height - st::msgDateDelta.y();
}
@@ -259,7 +261,7 @@ void Document::draw(
const auto cornerDownload = downloadInCorner();
if (!_dataMedia->canBePlayed()) {
_dataMedia->automaticLoad(_realParent->fullId(), _parent->data());
_dataMedia->automaticLoad(_realParent->fullId(), _realParent);
}
bool loaded = dataLoaded(), displayLoading = _data->displayLoading();
bool selected = (selection == FullSelection);
@@ -451,7 +453,7 @@ void Document::draw(
auto activew = qRound(availw * progress);
if (!outbg
&& !voice->_playback
&& _parent->data()->hasUnreadMediaFlag()) {
&& _realParent->hasUnreadMediaFlag()) {
activew = availw;
}
auto bar_count = qMin(availw / (st::msgWaveformBar + st::msgWaveformSkip), wf_size);
@@ -505,7 +507,7 @@ void Document::draw(
p.setPen(status);
p.drawTextLeft(nameleft, statustop, width, statusText);
if (_parent->data()->hasUnreadMediaFlag()) {
if (_realParent->hasUnreadMediaFlag()) {
auto w = st::normalFont->width(statusText);
if (w + st::mediaUnreadSkip + st::mediaUnreadSize <= statuswidth) {
p.setPen(Qt::NoPen);
@@ -547,7 +549,7 @@ bool Document::downloadInCorner() const {
return _data->isAudioFile()
&& _data->canBeStreamed()
&& !_data->inappPlaybackFailed()
&& IsServerMsgId(_parent->data()->id);
&& IsServerMsgId(_realParent->id);
}
void Document::drawCornerDownload(Painter &p, bool selected, LayoutMode mode) const {
@@ -685,7 +687,7 @@ TextState Document::textState(
auto waveformbottom = st.padding.top() - topMinus + st::msgWaveformMax + st::msgWaveformMin;
if (QRect(nameleft, nametop, namewidth, waveformbottom - nametop).contains(point)) {
const auto state = ::Media::Player::instance()->getState(AudioMsgId::Type::Voice);
if (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId())
if (state.id == AudioMsgId(_data, _realParent->fullId(), state.id.externalPlayId())
&& !::Media::Player::IsStoppedOrStopping(state.state)) {
if (!voice->seeking()) {
voice->setSeekingStart((point.x() - nameleft) / float64(namewidth));
@@ -812,7 +814,7 @@ bool Document::updateStatusText() const {
if (_data->isVoiceMessage()) {
const auto state = ::Media::Player::instance()->getState(AudioMsgId::Type::Voice);
if (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId())
if (state.id == AudioMsgId(_data, _realParent->fullId(), state.id.externalPlayId())
&& !::Media::Player::IsStoppedOrStopping(state.state)) {
if (auto voice = Get<HistoryDocumentVoice>()) {
bool was = (voice->_playback != nullptr);
@@ -838,19 +840,19 @@ bool Document::updateStatusText() const {
voice->checkPlaybackFinished();
}
}
if (!showPause && (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId()))) {
if (!showPause && (state.id == AudioMsgId(_data, _realParent->fullId(), state.id.externalPlayId()))) {
showPause = ::Media::Player::instance()->isSeeking(AudioMsgId::Type::Voice);
}
} else if (_data->isAudioFile()) {
const auto state = ::Media::Player::instance()->getState(AudioMsgId::Type::Song);
if (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId())
if (state.id == AudioMsgId(_data, _realParent->fullId(), state.id.externalPlayId())
&& !::Media::Player::IsStoppedOrStopping(state.state)) {
statusSize = -1 - (state.position / state.frequency);
realDuration = (state.length / state.frequency);
showPause = ::Media::Player::ShowPauseIcon(state.state);
} else {
}
if (!showPause && (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId()))) {
if (!showPause && (state.id == AudioMsgId(_data, _realParent->fullId(), state.id.externalPlayId()))) {
showPause = ::Media::Player::instance()->isSeeking(AudioMsgId::Type::Song);
}
}
@@ -960,7 +962,7 @@ void Document::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed
} else if (!pressed && voice->seeking()) {
const auto type = AudioMsgId::Type::Voice;
const auto state = ::Media::Player::instance()->getState(type);
if (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId()) && state.length) {
if (state.id == AudioMsgId(_data, _realParent->fullId(), state.id.externalPlayId()) && state.length) {
const auto currentProgress = voice->seekingCurrent();
::Media::Player::instance()->finishSeeking(
AudioMsgId::Type::Voice,

View File

@@ -145,6 +145,16 @@ QSize GroupedMedia::countOptimalSize() {
if (isBubbleBottom()) {
minHeight += st::msgPadding.bottom();
}
} else if (_mode == Mode::Column && _parts.back().item->emptyText()) {
const auto item = _parent->data();
const auto msgsigned = item->Get<HistoryMessageSigned>();
const auto views = item->Get<HistoryMessageViews>();
if ((msgsigned && !msgsigned->isAnonymousRank)
|| (views
&& (views->views.count >= 0 || views->replies.count > 0))
|| displayedEditBadge()) {
minHeight += st::msgDateFont->height - st::msgDateDelta.y();
}
}
const auto groupPadding = groupedPadding();
@@ -205,6 +215,16 @@ QSize GroupedMedia::countCurrentSize(int newWidth) {
if (isBubbleBottom()) {
newHeight += st::msgPadding.bottom();
}
} else if (_mode == Mode::Column && _parts.back().item->emptyText()) {
const auto item = _parent->data();
const auto msgsigned = item->Get<HistoryMessageSigned>();
const auto views = item->Get<HistoryMessageViews>();
if ((msgsigned && !msgsigned->isAnonymousRank)
|| (views
&& (views->views.count >= 0 || views->replies.count > 0))
|| displayedEditBadge()) {
newHeight += st::msgDateFont->height - st::msgDateDelta.y();
}
}
const auto groupPadding = groupedPadding();
@@ -255,7 +275,8 @@ void GroupedMedia::draw(
crl::time ms) const {
const auto groupPadding = groupedPadding();
const auto fullSelection = (selection == FullSelection);
const auto textSelection = !fullSelection
const auto textSelection = (_mode == Mode::Column)
&& !fullSelection
&& !IsSubGroupSelection(selection);
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
const auto &part = _parts[i];

View File

@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/profile/info_profile_values.h"
#include "core/application.h"
#include "core/local_url_handlers.h"
#include "core/click_handler_types.h"
#include "main/main_session.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text/text_utilities.h"
@@ -50,7 +50,7 @@ auto PlainUsernameValue(not_null<PeerData*> peer) {
void StripExternalLinks(TextWithEntities &text) {
const auto local = [](const QString &url) {
return Core::TryConvertUrlToLocal(url).startsWith(qstr("tg://"));
return !UrlRequiresConfirmation(QUrl::fromUserInput(url));
};
const auto notLocal = [&](const EntityInText &entity) {
if (entity.type() == EntityType::CustomUrl) {

View File

@@ -34,6 +34,7 @@ namespace {
constexpr auto kSuppressRatioAll = 0.2;
constexpr auto kSuppressRatioSong = 0.05;
constexpr auto kWaveformCounterBufferSize = 256 * 1024;
constexpr auto kEffectDestructionDelay = crl::time(1000);
QMutex AudioMutex;
ALCdevice *AudioDevice = nullptr;
@@ -179,7 +180,7 @@ void ClosePlaybackDevice(not_null<Instance*> instance) {
LOG(("Audio Info: Closing audio playback device."));
if (Player::mixer()) {
Player::mixer()->detachTracks();
Player::mixer()->prepareToCloseDevice();
}
instance->detachTracks();
@@ -320,6 +321,9 @@ void Mixer::Track::createStream(AudioMsgId::Type type) {
alSourcei(stream.source, AL_LOOPING, 0);
alSourcei(stream.source, AL_SOURCE_RELATIVE, 1);
alSourcei(stream.source, AL_ROLLOFF_FACTOR, 0);
if (alIsExtensionPresent("AL_SOFT_direct_channels_remix")) {
alSourcei(stream.source, alGetEnumValue("AL_DIRECT_CHANNELS_SOFT"), 2);
}
alGenBuffers(3, stream.buffers);
if (speedEffect) {
applySourceSpeedEffect();
@@ -383,9 +387,11 @@ void Mixer::Track::resetSpeedEffect() {
if (isStreamCreated()) {
removeSourceSpeedEffect();
}
OpenAL::alDeleteEffects(1, &speedEffect->effect);
OpenAL::alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
OpenAL::alDeleteFilters(1, &speedEffect->filter);
if (Player::mixer()) {
// Don't destroy effect slot immediately.
// See https://github.com/kcat/openal-soft/issues/486
Player::mixer()->scheduleEffectDestruction(*speedEffect);
}
}
speedEffect->effect = speedEffect->effectSlot = speedEffect->filter = 0;
}
@@ -560,6 +566,7 @@ Mixer::Track::~Track() = default;
Mixer::Mixer(not_null<Audio::Instance*> instance)
: _instance(instance)
, _effectsDestructionTimer([=] { destroyStaleEffectsSafe(); })
, _volumeVideo(kVolumeRound)
, _volumeSong(kVolumeRound)
, _fader(new Fader(&_faderThread))
@@ -622,6 +629,60 @@ void Mixer::onUpdated(const AudioMsgId &audio) {
Media::Player::Updated().notify(audio);
}
// Thread: Any. Must be locked: AudioMutex.
void Mixer::scheduleEffectDestruction(const SpeedEffect &effect) {
_effectsForDestruction.emplace_back(
crl::now() + kEffectDestructionDelay,
effect);
scheduleEffectsDestruction();
}
// Thread: Any. Must be locked: AudioMutex.
void Mixer::scheduleEffectsDestruction() {
if (_effectsForDestruction.empty()) {
return;
}
InvokeQueued(this, [=] {
if (!_effectsDestructionTimer.isActive()) {
_effectsDestructionTimer.callOnce(kEffectDestructionDelay + 1);
}
});
}
// Thread: Main. Locks: AudioMutex.
void Mixer::destroyStaleEffectsSafe() {
QMutexLocker lock(&AudioMutex);
destroyStaleEffects();
}
// Thread: Main. Must be locked: AudioMutex.
void Mixer::destroyStaleEffects() {
const auto now = crl::now();
const auto checkAndDestroy = [&](
const std::pair<crl::time, SpeedEffect> &pair) {
const auto &[when, effect] = pair;
if (when && when > now) {
return false;
}
OpenAL::alDeleteEffects(1, &effect.effect);
OpenAL::alDeleteAuxiliaryEffectSlots(1, &effect.effectSlot);
OpenAL::alDeleteFilters(1, &effect.filter);
return true;
};
_effectsForDestruction.erase(
ranges::remove_if(_effectsForDestruction, checkAndDestroy),
end(_effectsForDestruction));
scheduleEffectsDestruction();
}
// Thread: Main. Must be locked: AudioMutex.
void Mixer::destroyEffectsOnClose() {
for (auto &[when, effect] : _effectsForDestruction) {
when = 0;
}
destroyStaleEffects();
}
void Mixer::onError(const AudioMsgId &audio) {
emit stoppedOnError(audio);
@@ -823,6 +884,7 @@ void Mixer::forceToBufferExternal(const AudioMsgId &audioId) {
_loader->forceToBufferExternal(audioId);
}
// Thread: Main. Locks: AudioMutex.
void Mixer::setSpeedFromExternal(const AudioMsgId &audioId, float64 speed) {
QMutexLocker lock(&AudioMutex);
const auto track = trackForType(audioId.type());
@@ -1160,12 +1222,14 @@ void Mixer::setStoppedState(Track *current, State state) {
}
// Thread: Main. Must be locked: AudioMutex.
void Mixer::detachTracks() {
void Mixer::prepareToCloseDevice() {
for (auto i = 0; i != kTogetherLimit; ++i) {
trackForType(AudioMsgId::Type::Voice, i)->detach();
trackForType(AudioMsgId::Type::Song, i)->detach();
}
_videoTrack.detach();
destroyEffectsOnClose();
}
// Thread: Main. Must be locked: AudioMutex.

View File

@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/attach/attach_prepare.h"
#include "core/file_location.h"
#include "base/bytes.h"
#include "base/timer.h"
#include <QtCore/QTimer>
@@ -145,7 +146,10 @@ public:
// External player audio stream interface.
void feedFromExternal(ExternalSoundPart &&part);
void forceToBufferExternal(const AudioMsgId &audioId);
// Thread: Main. Locks: AudioMutex.
void setSpeedFromExternal(const AudioMsgId &audioId, float64 speed);
Streaming::TimePoint getExternalSyncTimePoint(
const AudioMsgId &audio) const;
crl::time getExternalCorrectedTime(
@@ -158,7 +162,7 @@ public:
TrackState currentState(AudioMsgId::Type type);
// Thread: Main. Must be locked: AudioMutex.
void detachTracks();
void prepareToCloseDevice();
// Thread: Main. Must be locked: AudioMutex.
void reattachIfNeeded();
@@ -193,11 +197,13 @@ signals:
void suppressAll(qint64 duration);
private:
bool fadedStop(AudioMsgId::Type type, bool *fadedStart = 0);
void resetFadeStartPosition(AudioMsgId::Type type, int positionInBuffered = -1);
bool checkCurrentALError(AudioMsgId::Type type);
void externalSoundProgress(const AudioMsgId &audio);
struct SpeedEffect {
uint32 effect = 0;
uint32 effectSlot = 0;
uint32 filter = 0;
int coarseTune = 0;
float64 speed = 1.;
};
class Track {
public:
@@ -206,8 +212,10 @@ private:
// Thread: Any. Must be locked: AudioMutex.
void reattach(AudioMsgId::Type type);
// Thread: Main. Must be locked: AudioMutex.
void detach();
void clear();
void started();
bool isStreamCreated() const;
@@ -215,6 +223,7 @@ private:
int getNotQueuedBufferIndex();
// Thread: Main. Must be locked: AudioMutex.
void setExternalData(std::unique_ptr<ExternalSoundData> data);
void changeSpeedEffect(float64 speed);
@@ -242,13 +251,6 @@ private:
Stream stream;
std::unique_ptr<ExternalSoundData> externalData;
struct SpeedEffect {
uint32 effect = 0;
uint32 effectSlot = 0;
uint32 filter = 0;
int coarseTune = 0;
float64 speed = 1.;
};
std::unique_ptr<SpeedEffect> speedEffect;
crl::time lastUpdateWhen = 0;
crl::time lastUpdatePosition = 0;
@@ -263,6 +265,12 @@ private:
};
bool fadedStop(AudioMsgId::Type type, bool *fadedStart = 0);
void resetFadeStartPosition(AudioMsgId::Type type, int positionInBuffered = -1);
bool checkCurrentALError(AudioMsgId::Type type);
void externalSoundProgress(const AudioMsgId &audio);
// Thread: Any. Must be locked: AudioMutex.
void setStoppedState(Track *current, State state = State::Stopped);
@@ -271,7 +279,18 @@ private:
int *currentIndex(AudioMsgId::Type type);
const int *currentIndex(AudioMsgId::Type type) const;
not_null<Audio::Instance*> _instance;
// Thread: Any. Must be locked: AudioMutex.
void scheduleEffectDestruction(const SpeedEffect &effect);
void scheduleEffectsDestruction();
// Thread: Main. Must be locked: AudioMutex.
void destroyStaleEffects();
void destroyEffectsOnClose();
// Thread: Main. Locks: AudioMutex.
void destroyStaleEffectsSafe();
const not_null<Audio::Instance*> _instance;
int _audioCurrent = 0;
Track _audioTracks[kTogetherLimit];
@@ -281,6 +300,9 @@ private:
Track _videoTrack;
std::vector<std::pair<crl::time, SpeedEffect>> _effectsForDestruction;
base::Timer _effectsDestructionTimer;
QAtomicInt _volumeVideo;
QAtomicInt _volumeSong;

View File

@@ -93,13 +93,15 @@ bool Panel::preventAutoHide() const {
}
void Panel::updateControlsGeometry() {
auto scrollTop = contentTop();
auto width = contentWidth();
auto scrollHeight = qMax(height() - scrollTop - contentBottom() - scrollMarginBottom(), 0);
const auto scrollTop = contentTop();
const auto width = contentWidth();
const auto scrollHeight = qMax(
height() - scrollTop - contentBottom() - scrollMarginBottom(),
0);
if (scrollHeight > 0) {
_scroll->setGeometryToRight(contentRight(), scrollTop, width, scrollHeight);
}
if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
if (const auto widget = static_cast<TWidget*>(_scroll->widget())) {
widget->resizeToWidth(width);
}
}

View File

@@ -706,29 +706,35 @@ void PipPanel::mouseMoveEvent(QMouseEvent *e) {
if (!_dragState
&& (point - _pressPoint).manhattanLength() > distance
&& !_dragDisabled) {
if (Platform::IsWayland()) {
const auto stateEdges = RectPartToQtEdges(*_pressState);
if (stateEdges) {
if (!Platform::StartSystemResize(windowHandle(), stateEdges)) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
windowHandle()->startSystemResize(stateEdges);
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
} else {
if (!Platform::StartSystemMove(windowHandle())) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
windowHandle()->startSystemMove();
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
}
return;
}
_dragState = _pressState;
updateDecorations();
_dragStartGeometry = geometry().marginsRemoved(_padding);
}
if (_dragState) {
processDrag(point);
if (Platform::IsWayland()) {
startSystemDrag();
} else {
processDrag(point);
}
}
}
void PipPanel::startSystemDrag() {
Expects(_dragState.has_value());
const auto stateEdges = RectPartToQtEdges(*_dragState);
if (stateEdges) {
if (!Platform::StartSystemResize(windowHandle(), stateEdges)) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
windowHandle()->startSystemResize(stateEdges);
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
} else {
if (!Platform::StartSystemMove(windowHandle())) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
windowHandle()->startSystemMove();
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
}
}
@@ -783,6 +789,9 @@ void PipPanel::finishDrag(QPoint point) {
const auto position = pos();
const auto clamped = [&] {
auto result = position;
if (Platform::IsWayland()) {
return result;
}
if (result.x() > screen.x() + screen.width() - inner.width()) {
result.setX(screen.x() + screen.width() - inner.width());
}

View File

@@ -83,6 +83,7 @@ private:
void setPositionOnScreen(Position position, QRect available);
QScreen *myScreen() const;
void startSystemDrag();
void processDrag(QPoint point);
void finishDrag(QPoint point);
void updatePositionAnimated();

View File

@@ -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/86.0.4240.75 Safari/537.36");
"Chrome/86.0.4240.111 Safari/537.36");
return kResult;
}

View File

@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/mtproto_dc_options.h"
#include "mtproto/connection_abstract.h"
#include "platform/platform_specific.h"
#include "base/openssl_help.h"
#include "base/qthelp_url.h"
#include "base/unixtime.h"
@@ -633,13 +634,24 @@ void SessionPrivate::tryToSend() {
: _instance->systemVersion();
#if defined OS_MAC_STORE
const auto appVersion = QString::fromLatin1(AppVersionStr)
+ " mac store";
+ " Mac App Store";
#elif defined OS_WIN_STORE // OS_MAC_STORE
const auto appVersion = QString::fromLatin1(AppVersionStr)
+ " win store";
#else // OS_MAC_STORE || OS_WIN_STORE
+ " Microsoft Store";
#elif defined Q_OS_UNIX && !defined Q_OS_MAC // OS_MAC_STORE || OS_WIN_STORE
const auto appVersion = [] {
if (Platform::InFlatpak()) {
return QString::fromLatin1(AppVersionStr)
+ " Flatpak";
} else if (Platform::InSnap()) {
return QString::fromLatin1(AppVersionStr)
+ " Snap";
}
return QString::fromLatin1(AppVersionStr);
}();
#else // OS_MAC_STORE || OS_WIN_STORE || (defined Q_OS_UNIX && !defined Q_OS_MAC)
const auto appVersion = QString::fromLatin1(AppVersionStr);
#endif // OS_MAC_STORE || OS_WIN_STORE
#endif // OS_MAC_STORE || OS_WIN_STORE || (defined Q_OS_UNIX && !defined Q_OS_MAC)
const auto proxyType = _options->proxy.type;
const auto mtprotoProxy = (proxyType == ProxyData::Type::Mtproto);
const auto clientProxyFields = mtprotoProxy

View File

@@ -113,14 +113,15 @@ bool UseNative(Type type = Type::ReadFile) {
// or if QT_QPA_PLATFORMTHEME=(gtk2|gtk3)
// or if portals are used and operation is to open folder
// and portal doesn't support folder choosing
const auto neededForPortal = UseXDGDesktopPortal()
&& type == Type::ReadFolder
const auto neededForPortal = (type == Type::ReadFolder)
&& !CanOpenDirectoryWithPortal();
const auto neededNonForced = DesktopEnvironment::IsGtkBased()
|| neededForPortal;
|| (UseXDGDesktopPortal() && neededForPortal);
const auto excludeNonForced = InFlatpak() || InSnap();
const auto excludeNonForced = InFlatpak()
|| InSnap()
|| (UseXDGDesktopPortal() && !neededForPortal);
return IsGtkIntegrationForced()
|| (neededNonForced && !excludeNonForced);

View File

@@ -58,7 +58,6 @@ namespace Platform {
namespace {
constexpr auto kDisableTrayCounter = "TDESKTOP_DISABLE_TRAY_COUNTER"_cs;
constexpr auto kForcePanelIcon = "TDESKTOP_FORCE_PANEL_ICON"_cs;
constexpr auto kPanelTrayIconName = "telegram-panel"_cs;
constexpr auto kMutePanelTrayIconName = "telegram-mute-panel"_cs;
constexpr auto kAttentionPanelTrayIconName = "telegram-attention-panel"_cs;
@@ -149,8 +148,7 @@ QString GetTrayIconName(int counter, bool muted) {
const auto iconName = GetIconName();
const auto panelIconName = GetPanelIconName(counter, muted);
if (QIcon::hasThemeIcon(panelIconName)
|| qEnvironmentVariableIsSet(kForcePanelIcon.utf8())) {
if (QIcon::hasThemeIcon(panelIconName)) {
return panelIconName;
} else if (QIcon::hasThemeIcon(iconName)) {
return iconName;
@@ -593,9 +591,7 @@ void MainWindow::setSNITrayIcon(int counter, bool muted) {
const auto iconName = GetTrayIconName(counter, muted);
if (qEnvironmentVariableIsSet(kDisableTrayCounter.utf8())
&& !iconName.isEmpty()
&& (!InSnap()
|| qEnvironmentVariableIsSet(kForcePanelIcon.utf8()))) {
&& !iconName.isEmpty()) {
if (_sniTrayIcon->iconName() == iconName) {
return;
}

View File

@@ -132,6 +132,14 @@ bool IsXDGDesktopPortalKDEPresent() {
return Result;
}
bool IsIBusPortalPresent() {
static const auto Result = QDBusInterface(
qsl("org.freedesktop.portal.IBus"),
qsl("/org/freedesktop/IBus")).isValid();
return Result;
}
uint FileChooserPortalVersion() {
static const auto Result = [&]() -> uint {
auto message = QDBusMessage::createMethodCall(
@@ -693,10 +701,6 @@ QString AppRuntimeDirectory() {
runtimeDir = QDir::tempPath();
}
if (runtimeDir.isEmpty()) {
runtimeDir = qsl("/tmp/");
}
if (!runtimeDir.endsWith('/')) {
runtimeDir += '/';
}
@@ -1101,18 +1105,35 @@ void start() {
LOG(("XDG Desktop Portal is not present :("));
}
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
// IBus has changed its socket path several times
// and each change should be synchronized with Qt.
// Moreover, the last time Qt changed the path,
// they didn't introduce a fallback to the old path
// and made the new Qt incompatible with IBus from older distributions.
// Since tdesktop is distributed in static binary form,
// it makes sense to use ibus portal whenever it present
// to ensure compatibility with the maximum range of distributions.
if (IsIBusPortalPresent()) {
LOG(("IBus portal is present! Using it."));
qputenv("IBUS_USE_PORTAL", "1");
}
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
}
void finish() {
}
void InstallLauncher() {
void InstallLauncher(bool force) {
static const auto DisabledByEnv = qEnvironmentVariableIsSet(
"TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION");
// don't update desktop file for alpha version or if updater is disabled
if (cAlphaVersion() || Core::UpdaterDisabled() || DisabledByEnv)
if ((cAlphaVersion() || Core::UpdaterDisabled() || DisabledByEnv)
&& !force) {
return;
}
const auto applicationsPath = QStandardPaths::writableLocation(
QStandardPaths::ApplicationsLocation) + '/';

View File

@@ -41,7 +41,7 @@ QString GetIconName();
inline void IgnoreApplicationActivationRightNow() {
}
void InstallLauncher();
void InstallLauncher(bool force = false);
} // namespace Platform

View File

@@ -157,11 +157,13 @@ ApplicationDelegate *_sharedDelegate = nil;
}
- (void) receiveWakeNote:(NSNotification*)aNotification {
if (Core::IsAppLaunched()) {
Core::App().checkLocalTime();
if (!Core::IsAppLaunched()) {
return;
}
Core::App().checkLocalTime();
LOG(("Audio Info: -receiveWakeNote: received, scheduling detach from audio device"));
LOG(("Audio Info: "
"-receiveWakeNote: received, scheduling detach from audio device"));
Media::Audio::ScheduleDetachFromDeviceSafe();
}

View File

@@ -136,14 +136,6 @@ auto GenerateCodes() {
window->showSettings(Settings::Type::Folders);
}
});
codes.emplace(qsl("autodark"), [](SessionController *window) {
auto text = Core::App().settings().systemDarkModeEnabled() ? qsl("Disable system dark mode?") : qsl("Enable system dark mode?");
Ui::show(Box<ConfirmBox>(text, [=] {
Core::App().settings().setSystemDarkModeEnabled(!Core::App().settings().systemDarkModeEnabled());
Core::App().saveSettingsDelayed();
Ui::hideLayer();
}));
});
codes.emplace(qsl("registertg"), [](SessionController *window) {
Platform::RegisterCustomScheme(true);
Ui::Toast::Show("Forced custom scheme register.");
@@ -165,6 +157,13 @@ auto GenerateCodes() {
});
#endif // Q_OS_WIN || Q_OS_MAC
#if defined Q_OS_UNIX && !defined Q_OS_MAC
codes.emplace(qsl("installauncher"), [](SessionController *window) {
Platform::InstallLauncher(true);
Ui::Toast::Show("Forced launcher installation.");
});
#endif // Q_OS_UNIX && !Q_OS_MAC
auto audioFilters = qsl("Audio files (*.wav *.mp3);;") + FileDialog::AllFilesFilter();
auto audioKeys = {
qsl("msg_incoming"),

View File

@@ -154,11 +154,15 @@ bool PreparedList::canAddCaption(bool sendingAlbum) const {
files,
PreparedFile::Type::File,
&PreparedFile::type);
const auto hasMusic = ranges::contains(
files,
PreparedFile::Type::Music,
&PreparedFile::type);
const auto hasNotGrouped = ranges::contains(
files,
PreparedFile::Type::None,
&PreparedFile::type);
return !hasFiles && !hasNotGrouped;
return !hasFiles && !hasMusic && !hasNotGrouped;
}
bool PreparedList::hasGroupOption(bool slowmode) const {

View File

@@ -126,11 +126,18 @@ void SingleMediaPreview::preparePreview(
_previewWidth = qMax(preview.width(), kMinPreviewWidth);
}
auto maxthumbh = qMin(qRound(1.5 * _previewWidth), st::confirmMaxHeight);
const auto minthumbh = st::sendBoxAlbumGroupHeight
+ st::sendBoxAlbumGroupSkipTop * 2;
_previewHeight = qRound(originalHeight * float64(_previewWidth) / originalWidth);
if (_previewHeight > maxthumbh) {
_previewWidth = qRound(_previewWidth * float64(maxthumbh) / _previewHeight);
accumulate_max(_previewWidth, kMinPreviewWidth);
_previewHeight = maxthumbh;
} else if (_previewHeight < minthumbh) {
_previewWidth = qRound(_previewWidth * float64(minthumbh)
/ _previewHeight);
accumulate_max(_previewWidth, kMinPreviewWidth);
_previewHeight = minthumbh;
}
_previewLeft = (st::boxWideWidth - _previewWidth) / 2;

View File

@@ -1,7 +1,7 @@
AppVersion 2004005
AppVersion 2004007
AppVersionStrMajor 2.4
AppVersionStrSmall 2.4.5
AppVersionStr 2.4.5
AppVersionStrSmall 2.4.7
AppVersionStr 2.4.7
BetaChannel 0
AlphaVersion 0
AppVersionOriginal 2.4.5
AppVersionOriginal 2.4.7

View File

@@ -1,3 +1,15 @@
2.4.7 (05.11.20)
- Fix playback display in albums of music files.
- Several crash fixes.
2.4.6 (02.11.20)
- Fix image compression option when sending files with drag-n-drop.
- Fix caption text selection in media albums.
- Fix drafts display in personal chats in the chats list.
- Bug fixes and other minor improvements.
2.4.5 (30.10.20)
- Pin several messages in any chat, including one-on-one chats.

View File

@@ -105,7 +105,8 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath***
-A Win32 ^
-DWITH_JPEG8=ON ^
-DPNG_SUPPORTED=OFF
cmake --build .
cmake --build . --config Debug
cmake --build . --config Release
cd ..
git clone https://github.com/telegramdesktop/openal-soft.git

View File

@@ -18,8 +18,6 @@ apps:
common-id: org.telegram.desktop
desktop: usr/share/applications/telegram-desktop_telegram-desktop.desktop
environment:
# Use GTK3 cursor theme, icon theme and open/save file dialogs.
QT_QPA_PLATFORMTHEME: gtk3
GTK_USE_PORTAL: 1
plugs:
- alsa
@@ -119,7 +117,10 @@ parts:
snapcraftctl set-version "$version"
sed -i 's|^Icon=.*|Icon=/usr/share/icons/hicolor/512x512/apps/telegram.png|g' lib/xdg/telegramdesktop.desktop
sed -i 's|^Icon=.*|Icon=${SNAP}/meta/gui/icon.png|g' lib/xdg/telegramdesktop.desktop
override-build: |
snapcraftctl build
rm -rf "$SNAPCRAFT_PART_INSTALL/usr/share/icons"
stage:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so.8.2.2
after:
@@ -258,6 +259,7 @@ parts:
webrtc:
source: https://github.com/desktop-app/tg_owt.git
source-depth: 1
source-commit: 12f4a27f2f02f9dd40f9891d8ec6e58bc1ff5263
plugin: cmake
build-packages:
- yasm
@@ -269,6 +271,7 @@ parts:
cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/usr
- -DBUILD_SHARED_LIBS=OFF
- -DJPEG_LIBRARY_RELEASE=$SNAPCRAFT_STAGE/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so
- -DJPEG_INCLUDE_DIR=$SNAPCRAFT_STAGE/usr/include
prime: [-./*]