Compare commits

..

52 Commits

Author SHA1 Message Date
John Preston
05f43cabdf Beta version 2.4.9.
- Fix crash in tray icon removing. (macOS only)
2020-11-06 17:24:30 +03:00
John Preston
65ba81f504 Beta version 2.4.8.
- Upgrade Qt to version 5.15.1.
- Upgrade FFmpeg to version 4.2.
- Upgrade OpenAL to version 1.20.1.
2020-11-06 11:21:34 +03:00
John Preston
71de246411 Disable Linux GLIBC wraps for special builds. 2020-11-06 11:21:34 +03:00
John Preston
547251f67c Fix deprecation warnings when building with FFmpeg 4.2. 2020-11-06 11:21:34 +03:00
John Preston
951bb22c38 Update docs/docker to use FFmpeg 4.2 / OpenAL 1.20.1. 2020-11-06 11:21:34 +03:00
John Preston
d9df82642d Patch FFmpeg asm objects for Xcode 12 linking. 2020-11-06 11:21:34 +03:00
John Preston
74d2313784 Build Linux version with Qt 5.15.1 in CentOS 7 docker. 2020-11-06 11:21:34 +03:00
John Preston
80c4ecb9bf Migrate CentOS docker file to Qt 5.15.1. 2020-11-06 11:21:34 +03:00
John Preston
b1e2beba2c Fix macOS tray icon on Big Sur & Qt 5.15.1. 2020-11-06 11:21:34 +03:00
John Preston
117de5a1f9 Build macOS version with Qt 5.15.1. 2020-11-06 11:21:34 +03:00
John Preston
9210cf6d36 Build Windows version with Qt 5.15.1. 2020-11-06 11:21:34 +03:00
Ilya Fedin
f7dcf6ce81 Hide IsXDGDesktopPortalPresent in a private namespace 2020-11-06 11:20:47 +03:00
Ilya Fedin
6c023084d9 Move the excluding portal checks to UseXDGDesktopPortal 2020-11-06 11:20:47 +03:00
Ilya Fedin
f521275acc Fix AreQtPluginsBundled to include static binary 2020-11-06 09:57:47 +03:00
Ilya Fedin
aec2b8df7e Fix choosing directories in snap and flatpak 2020-11-06 09:48:42 +03:00
Ilya Fedin
5c8820d5d8 Use QClipboard::supportsSelection instead of ifdefs 2020-11-06 08:56:50 +03:00
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
105 changed files with 965 additions and 722 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.9.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,9,0
PRODUCTVERSION 2,4,9,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.9.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.4.5.0"
VALUE "ProductVersion", "2.4.9.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,9,0
PRODUCTVERSION 2,4,9,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.9.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.4.5.0"
VALUE "ProductVersion", "2.4.9.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -42,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "base/openssl_help.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "base/call_delayed.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
@@ -3277,7 +3278,7 @@ void ApiWrap::requestMessageAfterDate(
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
// This should give us the first message with date >= desired_date.
auto offsetId = 0;
auto offsetDate = static_cast<int>(QDateTime(date).toTime_t()) - 1;
auto offsetDate = static_cast<int>(base::QDateToDateTime(date).toTime_t()) - 1;
auto addOffset = -1;
auto limit = 1;
auto maxId = 0;
@@ -3365,7 +3366,7 @@ void ApiWrap::jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date) {
// const QDate &date,
// Callback &&callback) {
// const auto offsetId = 0;
// const auto offsetDate = static_cast<TimeId>(QDateTime(date).toTime_t());
// const auto offsetDate = static_cast<TimeId>(base::QDateToDateTime(date).toTime_t());
// const auto addOffset = -2;
// const auto limit = 1;
// const auto hash = 0;
@@ -4230,20 +4231,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

@@ -178,7 +178,7 @@ void PeerListBox::resizeEvent(QResizeEvent *e) {
void PeerListBox::paintEvent(QPaintEvent *e) {
Painter p(this);
for (auto rect : e->region().rects()) {
for (const auto rect : e->region()) {
p.fillRect(rect, st::contactsBg);
}
}

View File

@@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "core/core_cloud_password.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "styles/style_layers.h"
@@ -694,7 +695,7 @@ void EditRestrictedBox::showRestrictUntil() {
highlighted,
[this](const QDate &date) {
setRestrictUntil(
static_cast<int>(QDateTime(date).toTime_t()));
static_cast<int>(base::QDateToDateTime(date).toTime_t()));
}),
Ui::LayerOption::KeepOther);
_restrictUntilBox->setMaxDate(

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

@@ -981,7 +981,7 @@ void Panel::paint(QRect clip) {
if (!_incoming->isHidden()) {
region = region.subtracted(QRegion(_incoming->geometry()));
}
for (const auto rect : region.rects()) {
for (const auto rect : region) {
p.fillRect(rect, st::callBgOpaque);
}
if (_incoming && _incoming->isHidden()) {

View File

@@ -171,10 +171,8 @@ bool SuggestionsWidget::eventHook(QEvent *e) {
}
void SuggestionsWidget::scrollByWheelEvent(not_null<QWheelEvent*> e) {
const auto horizontal = (e->angleDelta().x() != 0)
|| (e->orientation() == Qt::Horizontal);
const auto vertical = (e->angleDelta().y() != 0)
|| (e->orientation() == Qt::Vertical);
const auto horizontal = (e->angleDelta().x() != 0);
const auto vertical = (e->angleDelta().y() != 0);
const auto current = scrollCurrent();
const auto scroll = [&] {
if (horizontal) {

View File

@@ -614,8 +614,8 @@ bool StickersListWidget::Footer::eventHook(QEvent *e) {
void StickersListWidget::Footer::scrollByWheelEvent(
not_null<QWheelEvent*> e) {
auto horizontal = (e->angleDelta().x() != 0 || e->orientation() == Qt::Horizontal);
auto vertical = (e->angleDelta().y() != 0 || e->orientation() == Qt::Vertical);
auto horizontal = (e->angleDelta().x() != 0);
auto vertical = (e->angleDelta().y() != 0);
if (horizontal) {
_horizontal = true;
}

View File

@@ -79,6 +79,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtWidgets/QDesktopWidget>
#include <QtCore/QMimeDatabase>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
namespace Core {
namespace {
@@ -941,7 +942,7 @@ QPoint Application::getPointForCallPanelCenter() const {
if (const auto window = activeWindow()) {
return window->getPointForCallPanelCenter();
}
return QApplication::desktop()->screenGeometry().center();
return QGuiApplication::primaryScreen()->geometry().center();
}
// macOS Qt bug workaround, sometimes no leaveEvent() gets to the nested widgets.

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,20 @@ 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"
},
{
2004008,
"- Upgrade several third party libraries to latest versions.\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

@@ -39,7 +39,7 @@ PreLaunchWindow::PreLaunchWindow(QString title) {
setWindowTitle(title.isEmpty() ? qsl("Telegram") : title);
QPalette p(palette());
p.setColor(QPalette::Background, QColor(255, 255, 255));
p.setColor(QPalette::Window, QColor(255, 255, 255));
setPalette(p);
QLabel tmp(this);
@@ -79,7 +79,7 @@ PreLaunchLabel::PreLaunchLabel(QWidget *parent) : QLabel(parent) {
setFont(labelFont);
QPalette p(palette());
p.setColor(QPalette::Foreground, QColor(0, 0, 0));
p.setColor(QPalette::WindowText, QColor(0, 0, 0));
setPalette(p);
show();
};
@@ -97,7 +97,7 @@ PreLaunchInput::PreLaunchInput(QWidget *parent, bool password) : QLineEdit(paren
setFont(logFont);
QPalette p(palette());
p.setColor(QPalette::Foreground, QColor(0, 0, 0));
p.setColor(QPalette::WindowText, QColor(0, 0, 0));
setPalette(p);
QLineEdit::setTextMargins(0, 0, 0, 0);
@@ -115,7 +115,7 @@ PreLaunchLog::PreLaunchLog(QWidget *parent) : QTextEdit(parent) {
setFont(logFont);
QPalette p(palette());
p.setColor(QPalette::Foreground, QColor(96, 96, 96));
p.setColor(QPalette::WindowText, QColor(96, 96, 96));
setPalette(p);
setReadOnly(true);
@@ -783,7 +783,7 @@ void LastCrashedWindow::updateControls() {
}
QRect scr(QApplication::primaryScreen()->availableGeometry());
QSize s(2 * padding + QFontMetrics(_label.font()).width(qsl("Last time Telegram Desktop was not closed properly.")) + padding + _networkSettings.width(), h);
QSize s(2 * padding + QFontMetrics(_label.font()).horizontalAdvance(qsl("Last time Telegram Desktop was not closed properly.")) + padding + _networkSettings.width(), h);
if (s == size()) {
resizeEvent(0);
} else {

View File

@@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/invoke_queued.h"
#include "base/qthelp_url.h"
#include "base/qthelp_regex.h"
#include "base/qt_adapters.h"
#include "ui/effects/animations.h"
#include "facades.h"
#include "app.h"
@@ -35,9 +36,6 @@ namespace {
constexpr auto kEmptyPidForCommandResponse = 0ULL;
using ErrorSignal = void(QLocalSocket::*)(QLocalSocket::LocalSocketError);
const auto QLocalSocket_error = ErrorSignal(&QLocalSocket::error);
QChar _toHex(ushort v) {
v = v & 0x000F;
return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v));
@@ -112,7 +110,7 @@ int Sandbox::start() {
[=] { socketDisconnected(); });
connect(
&_localSocket,
QLocalSocket_error,
base::QLocalSocket_error,
[=](QLocalSocket::LocalSocketError error) { socketError(error); });
connect(
&_localSocket,

View File

@@ -7,11 +7,13 @@ 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"
#include "base/bytes.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "storage/localstorage.h"
#include "core/application.h"
#include "core/changelogs.h"
@@ -57,9 +59,6 @@ bool UpdaterIsDisabled = false;
std::weak_ptr<Updater> UpdaterInstance;
using ErrorSignal = void(QNetworkReply::*)(QNetworkReply::NetworkError);
const auto QNetworkReply_error = ErrorSignal(&QNetworkReply::error);
using Progress = UpdateChecker::Progress;
using State = UpdateChecker::State;
@@ -625,7 +624,7 @@ void HttpChecker::start() {
_reply->connect(_reply, &QNetworkReply::finished, [=] {
gotResponse();
});
_reply->connect(_reply, QNetworkReply_error, [=](auto e) {
_reply->connect(_reply, base::QNetworkReply_error, [=](auto e) {
gotFailure(e);
});
}
@@ -664,7 +663,7 @@ void HttpChecker::clearSentRequest() {
return;
}
reply->disconnect(reply, &QNetworkReply::finished, nullptr, nullptr);
reply->disconnect(reply, QNetworkReply_error, nullptr, nullptr);
reply->disconnect(reply, base::QNetworkReply_error, nullptr, nullptr);
reply->abort();
reply->deleteLater();
_manager = nullptr;
@@ -818,7 +817,7 @@ void HttpLoaderActor::sendRequest() {
&HttpLoaderActor::partFinished);
connect(
_reply.get(),
QNetworkReply_error,
base::QNetworkReply_error,
this,
&HttpLoaderActor::partFailed);
connect(
@@ -1575,9 +1574,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

@@ -170,17 +170,10 @@ namespace ThirdParty {
LOG(("MTP Error: dynlock_create callback is set without dynlock_lock callback!"));
}
av_register_all();
avcodec_register_all();
av_lockmgr_register(_ffmpegLockManager);
_sslInited = true;
}
void finish() {
av_lockmgr_register(nullptr);
CRYPTO_cleanup_all_ex_data();
#ifndef LIBRESSL_VERSION_NUMBER
FIPS_mode_set(0);

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 AppBetaVersion = false;
constexpr auto AppVersion = 2004009;
constexpr auto AppVersionStr = "2.4.9";
constexpr auto AppBetaVersion = true;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h"
#include "data/data_user.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
namespace Data {
namespace {
@@ -39,7 +40,7 @@ int OnlinePhraseChangeInSeconds(TimeId online, TimeId now) {
return (hours + 1) * 3600 - (now - online);
}
const auto nowFull = base::unixtime::parse(now);
const auto tomorrow = QDateTime(nowFull.date().addDays(1));
const auto tomorrow = base::QDateToDateTime(nowFull.date().addDays(1));
return std::max(static_cast<TimeId>(nowFull.secsTo(tomorrow)), 0);
}

View File

@@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h"
#include "data/data_channel.h"
#include "data/data_document.h"
#include "base/qt_adapters.h"
#include "ui/image/image.h"
#include "ui/text/text_entity.h"
@@ -26,7 +27,7 @@ QString SiteNameFromUrl(const QString &url) {
if (m.hasMatch()) pretty = pretty.mid(m.capturedLength());
int32 slash = pretty.indexOf('/');
if (slash > 0) pretty = pretty.mid(0, slash);
QStringList components = pretty.split('.', QString::SkipEmptyParts);
QStringList components = pretty.split('.', base::QStringSkipEmptyParts);
if (components.size() >= 2) {
components = components.mid(components.size() - 2);
return components.at(0).at(0).toUpper() + components.at(0).mid(1) + '.' + components.at(1);

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

@@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/file_utilities.h"
#include "boxes/calendar_box.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "main/main_session.h"
#include "styles/style_widgets.h"
#include "styles/style_export.h"
@@ -478,7 +479,7 @@ void SettingsWidget::editDateLimit(
}));
};
const auto callback = crl::guard(this, [=](const QDate &date) {
done(base::unixtime::serialize(QDateTime(date)));
done(base::unixtime::serialize(base::QDateToDateTime(date)));
if (const auto weak = shared->data()) {
weak->closeBox();
}

View File

@@ -174,7 +174,7 @@ CodecPointer MakeCodecPointer(not_null<AVStream*> stream) {
LogError(qstr("avcodec_parameters_to_context"), error);
return {};
}
av_codec_set_pkt_timebase(context, stream->time_base);
context->pkt_timebase = stream->time_base;
av_opt_set(context, "threads", "auto", 0);
av_opt_set_int(context, "refcounted_frames", 1, 0);

View File

@@ -1503,13 +1503,13 @@ void InnerWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton but
_mouseSelectType = TextSelectType::Letters;
//_widget->noSelectingScroll(); // TODO
#if defined Q_OS_UNIX && !defined Q_OS_MAC
if (_selectedItem && _selectedText.from != _selectedText.to) {
if (QGuiApplication::clipboard()->supportsSelection()
&& _selectedItem
&& _selectedText.from != _selectedText.to) {
TextUtilities::SetClipboardText(
_selectedItem->selectedText(_selectedText),
QClipboard::Selection);
}
#endif // Q_OS_UNIX && !Q_OS_MAC
}
void InnerWidget::updateSelected() {

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();
@@ -1422,8 +1382,9 @@ void HistoryInner::mouseActionFinish(
_widget->noSelectingScroll();
_widget->updateTopBarSelection();
#if defined Q_OS_UNIX && !defined Q_OS_MAC
if (!_selected.empty() && _selected.cbegin()->second != FullSelection) {
if (QGuiApplication::clipboard()->supportsSelection()
&& !_selected.empty()
&& _selected.cbegin()->second != FullSelection) {
const auto [item, selection] = *_selected.cbegin();
if (const auto view = item->mainView()) {
TextUtilities::SetClipboardText(
@@ -1431,7 +1392,6 @@ void HistoryInner::mouseActionFinish(
QClipboard::Selection);
}
}
#endif // Q_OS_UNIX && !Q_OS_MAC
}
void HistoryInner::mouseReleaseEvent(QMouseEvent *e) {

View File

@@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "window/window_session_controller.h"
#include "facades.h"
#include "base/qt_adapters.h"
#include "styles/style_widgets.h"
#include "styles/style_chat.h"
@@ -109,7 +110,7 @@ HiddenSenderInfo::HiddenSenderInfo(const QString &name)
, colorPeerId(Data::FakePeerIdForJustName(name))
, userpic(Data::PeerUserpicColor(colorPeerId), name) {
nameText.setText(st::msgNameStyle, name, Ui::NameTextOptions());
const auto parts = name.trimmed().split(' ', QString::SkipEmptyParts);
const auto parts = name.trimmed().split(' ', base::QStringSkipEmptyParts);
firstName = parts[0];
for (const auto &part : parts.mid(1)) {
if (!lastName.isEmpty()) {

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(
@@ -2221,16 +2222,15 @@ void ListWidget::mouseActionFinish(
_mouseSelectType = TextSelectType::Letters;
//_widget->noSelectingScroll(); // #TODO select scroll
#if defined Q_OS_UNIX && !defined Q_OS_MAC
if (_selectedTextItem
if (QGuiApplication::clipboard()->supportsSelection()
&& _selectedTextItem
&& _selectedTextRange.from != _selectedTextRange.to) {
if (const auto view = viewForItem(_selectedTextItem)) {
TextUtilities::SetClipboardText(
view->selectedText(_selectedTextRange),
QClipboard::Selection);
}
}
}
#endif // Q_OS_UNIX && !Q_OS_MAC
}
void ListWidget::mouseActionUpdate() {

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

@@ -2118,11 +2118,9 @@ void ListWidget::mouseActionFinish(
//_widget->noSelectingScroll(); // #TODO scroll by drag
//_widget->updateTopBarSelection();
#if defined Q_OS_UNIX && !defined Q_OS_MAC
//if (hasSelectedText()) { // #TODO linux clipboard
//if (QGuiApplication::clipboard()->supportsSelection() && hasSelectedText()) { // #TODO linux clipboard
// TextUtilities::SetClipboardText(_selected.cbegin()->first->selectedText(_selected.cbegin()->second), QClipboard::Selection);
//}
#endif // Q_OS_UNIX && !Q_OS_MAC
}
void ListWidget::applyDragSelection() {

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

@@ -253,8 +253,9 @@ void Instance::Inner::start(Fn<void(Update)> updated, Fn<void()> error) {
d->ioContext = avio_alloc_context(d->ioBuffer, FFmpeg::kAVBlockSize, 1, static_cast<void*>(d.get()), &Private::_read_data, &Private::_write_data, &Private::_seek_data);
int res = 0;
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
AVOutputFormat *fmt = 0;
while ((fmt = av_oformat_next(fmt))) {
const AVOutputFormat *fmt = nullptr;
void *i = nullptr;
while ((fmt = av_muxer_iterate(&i))) {
if (fmt->name == qstr("opus")) {
break;
}
@@ -265,7 +266,7 @@ void Instance::Inner::start(Fn<void(Update)> updated, Fn<void()> error) {
return;
}
if ((res = avformat_alloc_output_context2(&d->fmtContext, fmt, 0, 0)) < 0) {
if ((res = avformat_alloc_output_context2(&d->fmtContext, (AVOutputFormat*)fmt, 0, 0)) < 0) {
LOG(("Audio Error: Unable to avformat_alloc_output_context2 for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
fail();
return;

View File

@@ -550,7 +550,7 @@ bool FFMpegLoader::openCodecContext() {
));
return false;
}
av_codec_set_pkt_timebase(_codecContext, stream->time_base);
_codecContext->pkt_timebase = stream->time_base;
av_opt_set_int(_codecContext, "refcounted_frames", 1, 0);
if ((res = avcodec_open2(_codecContext, codec, 0)) < 0) {

View File

@@ -312,7 +312,7 @@ bool FFMpegReaderImplementation::start(Mode mode, crl::time &positionMs) {
LOG(("Gif Error: Unable to avcodec_parameters_to_context %1, error %2, %3").arg(logData()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
return false;
}
av_codec_set_pkt_timebase(_codecContext, _fmtContext->streams[_streamId]->time_base);
_codecContext->pkt_timebase = _fmtContext->streams[_streamId]->time_base;
av_opt_set_int(_codecContext, "refcounted_frames", 1, 0);
const auto codec = avcodec_find_decoder(_codecContext->codec_id);

View File

@@ -226,7 +226,7 @@ public:
~Manager();
int loadLevel() const {
return _loadLevel.load();
return _loadLevel;
}
void append(Reader *reader, const Core::FileLocation &location, const QByteArray &data);
void start(Reader *reader);

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

@@ -350,6 +350,12 @@ OverlayWidget::OverlayWidget()
if (Platform::IsLinux()) {
setWindowFlags(Qt::FramelessWindowHint
| Qt::MaximizeUsingFullscreenGeometryHint);
} else if (Platform::IsMac()) {
// Without Qt::Tool starting with Qt 5.15.1 this widget
// when being opened from a fullscreen main window was
// opening not as overlay over the main window, but as
// a separate fullscreen window with a separate space.
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
} else {
setWindowFlags(Qt::FramelessWindowHint);
}
@@ -2962,13 +2968,11 @@ void OverlayWidget::validatePhotoCurrentImage() {
void OverlayWidget::paintEvent(QPaintEvent *e) {
const auto r = e->rect();
const auto &region = e->region();
const auto rects = region.rects();
const auto region = e->region();
const auto contentShown = _photo || documentContentShown();
const auto bgRects = contentShown
? (region - contentRect()).rects()
: rects;
const auto bgRegion = contentShown
? (region - contentRect())
: region;
auto ms = crl::now();
@@ -2982,7 +2986,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
const auto m = p.compositionMode();
p.setCompositionMode(QPainter::CompositionMode_Source);
const auto bgColor = _fullScreenVideo ? st::mediaviewVideoBg : st::mediaviewBg;
for (const auto &rect : bgRects) {
for (const auto rect : bgRegion) {
p.fillRect(rect, bgColor);
}
p.setCompositionMode(m);
@@ -3078,7 +3082,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
auto o = overLevel(OverLeftNav);
if (o > 0) {
p.setOpacity(o * co);
for (const auto &rect : rects) {
for (const auto &rect : region) {
const auto fill = _leftNav.intersected(rect);
if (!fill.isEmpty()) p.fillRect(fill, st::mediaviewControlBg);
}
@@ -3094,7 +3098,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
auto o = overLevel(OverRightNav);
if (o > 0) {
p.setOpacity(o * co);
for (const auto &rect : rects) {
for (const auto &rect : region) {
const auto fill = _rightNav.intersected(rect);
if (!fill.isEmpty()) p.fillRect(fill, st::mediaviewControlBg);
}
@@ -3110,7 +3114,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
auto o = overLevel(OverClose);
if (o > 0) {
p.setOpacity(o * co);
for (const auto &rect : rects) {
for (const auto &rect : region) {
const auto fill = _closeNav.intersected(rect);
if (!fill.isEmpty()) p.fillRect(fill, st::mediaviewControlBg);
}
@@ -4145,7 +4149,7 @@ bool OverlayWidget::eventHook(QEvent *e) {
} else {
_accumScroll += ev->angleDelta();
if (ev->phase() == Qt::ScrollEnd) {
if (ev->orientation() == Qt::Horizontal) {
if (ev->angleDelta().x() != 0) {
if (_accumScroll.x() * _accumScroll.x() > _accumScroll.y() * _accumScroll.y() && _accumScroll.x() != 0) {
moveToNext(_accumScroll.x() > 0 ? -1 : 1);
}

View File

@@ -334,7 +334,7 @@ Qt::Edges RectPartToQtEdges(RectPart rectPart) {
return Qt::BottomEdge;
}
return 0;
return Qt::Edges();
}
} // namespace
@@ -591,7 +591,7 @@ void PipPanel::paintEvent(QPaintEvent *e) {
QPainter p(this);
if (_useTransparency) {
Ui::Platform::StartTranslucentPaint(p, e->region().rects());
Ui::Platform::StartTranslucentPaint(p, e->region());
}
auto request = FrameRequest();
@@ -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

@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/details/mtproto_tcp_socket.h"
#include "base/invoke_queued.h"
#include "base/qt_adapters.h"
namespace MTP::details {
@@ -33,12 +34,9 @@ TcpSocket::TcpSocket(not_null<QThread*> thread, const QNetworkProxy &proxy)
&_socket,
&QTcpSocket::readyRead,
wrap([=] { _readyRead.fire({}); }));
using ErrorSignal = void(QTcpSocket::*)(QAbstractSocket::SocketError);
const auto QTcpSocket_error = ErrorSignal(&QAbstractSocket::error);
connect(
&_socket,
QTcpSocket_error,
base::QTcpSocket_error,
wrap([=](Error e) { handleError(e); }));
}

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/bytes.h"
#include "base/invoke_queued.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include <QtCore/QtEndian>
#include <range/v3/algorithm/reverse.hpp>
@@ -470,12 +471,9 @@ TlsSocket::TlsSocket(
&_socket,
&QTcpSocket::readyRead,
wrap([=] { plainReadyRead(); }));
using ErrorSignal = void(QTcpSocket::*)(QAbstractSocket::SocketError);
const auto QTcpSocket_error = ErrorSignal(&QAbstractSocket::error);
connect(
&_socket,
QTcpSocket_error,
base::QTcpSocket_error,
wrap([=](Error e) { handleError(e); }));
}

View File

@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/facade.h"
#include "mtproto/connection_tcp.h"
#include "storage/serialize_common.h"
#include "base/qt_adapters.h"
#include <QtCore/QFile>
#include <QtCore/QRegularExpression>
@@ -779,7 +780,7 @@ bool DcOptions::loadFromFile(const QString &path) {
stream.setCodec("UTF-8");
while (!stream.atEnd()) {
auto line = stream.readLine();
auto components = line.split(QRegularExpression(R"(\s)"), QString::SkipEmptyParts);
auto components = line.split(QRegularExpression(R"(\s)"), base::QStringSkipEmptyParts);
if (components.isEmpty() || components[0].startsWith('#')) {
continue;
}

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

@@ -79,9 +79,9 @@ bool CheckPhoneByPrefixesRules(const QString &phone, const QString &rules) {
}
QByteArray ConcatenateDnsTxtFields(const std::vector<DnsEntry> &response) {
auto entries = QMap<int, QString>();
auto entries = QMultiMap<int, QString>();
for (const auto &entry : response) {
entries.insertMulti(INT_MAX - entry.data.size(), entry.data);
entries.insert(INT_MAX - entry.data.size(), entry.data);
}
return QStringList(entries.values()).join(QString()).toLatin1();
}

View File

@@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_components.h"
#include "history/view/history_view_cursor_state.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "ui/effects/round_checkbox.h"
#include "ui/image/image.h"
#include "ui/text/format_values.h"
@@ -1518,7 +1519,7 @@ Link::Link(
domain = parts.at(2);
}
parts = domain.split('@').back().split('.', QString::SkipEmptyParts);
parts = domain.split('@').back().split('.', base::QStringSkipEmptyParts);
if (parts.size() > 1) {
_letter = parts.at(parts.size() - 2).at(0).toUpper();
if (_title.isEmpty()) {

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/linux/linux_desktop_environment.h"
#include "platform/linux/specific_linux.h"
#include "storage/localstorage.h"
#include "base/qt_adapters.h"
#include <QtGui/QDesktopServices>
@@ -113,14 +114,17 @@ 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 sandboxedOrCustomPortal = InFlatpak()
|| InSnap()
|| UseXDGDesktopPortal();
const auto neededForPortal = (type == Type::ReadFolder)
&& !CanOpenDirectoryWithPortal();
const auto neededNonForced = DesktopEnvironment::IsGtkBased()
|| neededForPortal;
|| (sandboxedOrCustomPortal && neededForPortal);
const auto excludeNonForced = InFlatpak() || InSnap();
const auto excludeNonForced = sandboxedOrCustomPortal && !neededForPortal;
return IsGtkIntegrationForced()
|| (neededNonForced && !excludeNonForced);
@@ -384,7 +388,7 @@ QStringList cleanFilterList(const QString &filter) {
int i = regexp.indexIn(f);
if (i >= 0)
f = regexp.cap(2);
return f.split(QLatin1Char(' '), QString::SkipEmptyParts);
return f.split(QLatin1Char(' '), base::QStringSkipEmptyParts);
}
} // namespace
@@ -582,7 +586,6 @@ GtkFileChooserAction gtkFileChooserAction(QFileDialog::FileMode fileMode, QFileD
else
return GTK_FILE_CHOOSER_ACTION_SAVE;
case QFileDialog::Directory:
case QFileDialog::DirectoryOnly:
default:
if (acceptMode == QFileDialog::AcceptOpen)
return GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;

View File

@@ -141,7 +141,7 @@ private:
void hideHelper();
// Options
QFileDialog::Options _options = { 0 };
QFileDialog::Options _options;
QString _windowTitle = "Choose file";
QString _initialDirectory;
QStringList _initialFiles;

View File

@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/linux/linux_desktop_environment.h"
#include "platform/linux/specific_linux.h"
#include "base/qt_adapters.h"
namespace Platform {
namespace DesktopEnvironment {
@@ -22,7 +23,7 @@ QString GetEnv(const char *name) {
Type Compute() {
auto xdgCurrentDesktop = GetEnv("XDG_CURRENT_DESKTOP").toLower();
auto list = xdgCurrentDesktop.split(':', QString::SkipEmptyParts);
auto list = xdgCurrentDesktop.split(':', base::QStringSkipEmptyParts);
auto desktopSession = GetEnv("DESKTOP_SESSION").toLower();
auto slash = desktopSession.lastIndexOf('/');
auto kdeSession = GetEnv("KDE_SESSION_VERSION");

View File

@@ -1,30 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
void *__wrap_aligned_alloc(size_t alignment, size_t size) {
void *result = NULL;
return (posix_memalign(&result, alignment, size) == 0)
? result
: NULL;
}
int enable_secure_inited = 0;
int enable_secure = 1;
char *__wrap_secure_getenv(const char *name) {
if (enable_secure_inited == 0) {
enable_secure_inited = 1;
enable_secure = (geteuid() != getuid())
|| (getegid() != getgid());
}
return enable_secure ? NULL : getenv(name);
}

View File

@@ -1,50 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include <time.h>
#include <stdint.h>
#if defined(_M_IX86) || defined(__i386__)
#define GETTIME_GLIBC_VERSION "2.2"
#elif defined(_M_ARM) || defined(__arm__)
#define GETTIME_GLIBC_VERSION "2.4"
#else
#error Please add glibc wraps for your architecture
#endif
int __clock_gettime_glibc_old(clockid_t clk_id, struct timespec *tp);
__asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION);
int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) {
return __clock_gettime_glibc_old(clk_id, tp);
}
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p);
int64_t __wrap___divmoddi4(int64_t num, int64_t den, int64_t *rem_p) {
int minus = 0;
int64_t v;
if (num < 0) {
num = -num;
minus = 1;
}
if (den < 0) {
den = -den;
minus ^= 1;
}
v = __udivmoddi4(num, den, (uint64_t *)rem_p);
if (minus) {
v = -v;
if (rem_p)
*rem_p = -(*rem_p);
}
return v;
}

View File

@@ -1,25 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include <time.h>
#if defined(_M_X64) || defined(__x86_64__)
#define GETTIME_GLIBC_VERSION "2.2.5"
#elif defined(__aarch64__)
#define GETTIME_GLIBC_VERSION "2.17"
#else
#error Please add glibc wraps for your architecture
#endif
int __clock_gettime_glibc_old(clockid_t clk_id, struct timespec *tp);
__asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION);
int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) {
return __clock_gettime_glibc_old(clk_id, tp);
}

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

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/linux/linux_libs.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_xcb_utilities_linux.h"
#include "base/qt_adapters.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "mainwindow.h"
@@ -124,6 +125,14 @@ void PortalAutostart(bool autostart, bool silent = false) {
}
}
bool IsXDGDesktopPortalPresent() {
static const auto Result = QDBusInterface(
kXDGDesktopPortalService.utf16(),
kXDGDesktopPortalObjectPath.utf16()).isValid();
return Result;
}
bool IsXDGDesktopPortalKDEPresent() {
static const auto Result = QDBusInterface(
qsl("org.freedesktop.impl.portal.desktop.kde"),
@@ -132,6 +141,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(
@@ -232,14 +249,14 @@ bool GenerateDesktopFile(
QRegularExpression::MultilineOption),
qsl("TryExec=")
+ QFile::encodeName(cExeDir() + cExeName())
.replace('\\', qsl("\\\\")));
.replace('\\', "\\\\"));
fileText = fileText.replace(
QRegularExpression(
qsl("^Exec=.*$"),
QRegularExpression::MultilineOption),
qsl("Exec=")
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName()))
.replace('\\', qsl("\\\\"))
.replace('\\', "\\\\")
+ (args.isEmpty() ? QString() : ' ' + args));
} else {
fileText = fileText.replace(
@@ -627,34 +644,29 @@ bool IsGtkIntegrationForced() {
}
bool AreQtPluginsBundled() {
#ifdef DESKTOP_APP_USE_PACKAGED_LAZY
#if !defined DESKTOP_APP_USE_PACKAGED || defined DESKTOP_APP_USE_PACKAGED_LAZY
return true;
#else // DESKTOP_APP_USE_PACKAGED_LAZY
return false;
#endif // !DESKTOP_APP_USE_PACKAGED_LAZY
}
bool IsXDGDesktopPortalPresent() {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
static const auto Result = QDBusInterface(
kXDGDesktopPortalService.utf16(),
kXDGDesktopPortalObjectPath.utf16()).isValid();
return Result;
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
#else // !DESKTOP_APP_USE_PACKAGED || DESKTOP_APP_USE_PACKAGED_LAZY
return false;
#endif // DESKTOP_APP_USE_PACKAGED && !DESKTOP_APP_USE_PACKAGED_LAZY
}
bool UseXDGDesktopPortal() {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
static const auto Result = [&] {
const auto onlyIn = AreQtPluginsBundled()
// it is handled by Qt for flatpak and snap
&& !InFlatpak()
&& !InSnap();
const auto envVar = qEnvironmentVariableIsSet("TDESKTOP_USE_PORTAL");
const auto portalPresent = IsXDGDesktopPortalPresent();
const auto neededForKde = DesktopEnvironment::IsKDE()
&& IsXDGDesktopPortalKDEPresent();
return (neededForKde || envVar) && portalPresent;
return onlyIn
&& portalPresent
&& (neededForKde || envVar);
}();
return Result;
@@ -693,10 +705,6 @@ QString AppRuntimeDirectory() {
runtimeDir = QDir::tempPath();
}
if (runtimeDir.isEmpty()) {
runtimeDir = qsl("/tmp/");
}
if (!runtimeDir.endsWith('/')) {
runtimeDir += '/';
}
@@ -1018,7 +1026,7 @@ namespace Platform {
void start() {
PlatformThemes = QString::fromUtf8(qgetenv("QT_QPA_PLATFORMTHEME"))
.split(':', QString::SkipEmptyParts);
.split(':', base::QStringSkipEmptyParts);
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
@@ -1082,37 +1090,49 @@ void start() {
qputenv("QT_WAYLAND_DECORATION", "material");
}
if (AreQtPluginsBundled()
// it is handled by Qt for flatpak and snap
&& !InFlatpak()
&& !InSnap()) {
LOG(("Checking for XDG Desktop Portal..."));
// this can give us a chance to use
// a proper file dialog for current session
if (IsXDGDesktopPortalPresent()) {
LOG(("XDG Desktop Portal is present!"));
if (UseXDGDesktopPortal()) {
LOG(("Using XDG Desktop Portal."));
qputenv("QT_QPA_PLATFORMTHEME", "xdgdesktopportal");
} else {
LOG(("Not using XDG Desktop Portal."));
}
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
// this can give us a chance to use
// a proper file dialog for current session
DEBUG_LOG(("Checking for XDG Desktop Portal..."));
if (IsXDGDesktopPortalPresent()) {
DEBUG_LOG(("XDG Desktop Portal is present!"));
if (UseXDGDesktopPortal()) {
LOG(("Using XDG Desktop Portal."));
qputenv("QT_QPA_PLATFORMTHEME", "xdgdesktopportal");
} else {
LOG(("XDG Desktop Portal is not present :("));
DEBUG_LOG(("Not using XDG Desktop Portal."));
}
} else {
DEBUG_LOG(("XDG Desktop Portal is not present :("));
}
// 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) + '/';
@@ -1230,27 +1250,35 @@ void OpenSystemSettingsForPermission(PermissionType type) {
bool OpenSystemSettings(SystemSettingsType type) {
if (type == SystemSettingsType::Audio) {
auto options = std::vector<QString>();
const auto add = [&](const char *option) {
options.emplace_back(option);
struct Command {
QString command;
QStringList arguments;
};
auto options = std::vector<Command>();
const auto add = [&](const char *option, const char *arg = nullptr) {
auto command = Command{ .command = option };
if (arg) {
command.arguments.push_back(arg);
}
options.push_back(std::move(command));
};
if (DesktopEnvironment::IsUnity()) {
add("unity-control-center sound");
add("unity-control-center", "sound");
} else if (DesktopEnvironment::IsKDE()) {
add("kcmshell5 kcm_pulseaudio");
add("kcmshell4 phonon");
add("kcmshell5", "kcm_pulseaudio");
add("kcmshell4", "phonon");
} else if (DesktopEnvironment::IsGnome()) {
add("gnome-control-center sound");
add("gnome-control-center", "sound");
} else if (DesktopEnvironment::IsCinnamon()) {
add("cinnamon-settings sound");
add("cinnamon-settings", "sound");
} else if (DesktopEnvironment::IsMATE()) {
add("mate-volume-control");
}
add("pavucontrol-qt");
add("pavucontrol");
add("alsamixergui");
return ranges::any_of(options, [](const QString &command) {
return QProcess::startDetached(command);
return ranges::any_of(options, [](const Command &command) {
return QProcess::startDetached(command.command, command.arguments);
});
}
return true;

View File

@@ -23,26 +23,22 @@ inline void SetWatchingMediaKeys(bool watching) {
bool InFlatpak();
bool InSnap();
bool IsStaticBinary();
bool AreQtPluginsBundled();
bool UseGtkIntegration();
bool IsGtkIntegrationForced();
bool AreQtPluginsBundled();
bool IsXDGDesktopPortalPresent();
bool UseXDGDesktopPortal();
bool CanOpenDirectoryWithPortal();
QString AppRuntimeDirectory();
QString GetLauncherBasename();
QString GetLauncherFilename();
QString GetIconName();
void InstallLauncher(bool force = false);
inline void IgnoreApplicationActivationRightNow() {
}
void InstallLauncher();
} // namespace Platform
inline void psCheckLocalSocket(const QString &serverName) {

View File

@@ -9,10 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/mac/base_utilities_mac.h"
#include "lang/lang_keys.h"
#include "base/qt_adapters.h"
#include "styles/style_window.h"
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtGui/QScreen>
#include <Cocoa/Cocoa.h>
#include <CoreFoundation/CFURL.h>
@@ -398,7 +399,11 @@ bool UnsafeShowOpenWithDropdown(const QString &filepath, QPoint menuPosition) {
NSString *file = Q2NSString(filepath);
@try {
OpenFileWithInterface *menu = [[[OpenFileWithInterface alloc] init:file] autorelease];
auto r = QApplication::desktop()->screenGeometry(menuPosition);
const auto screen = base::QScreenNearestTo(menuPosition);
if (!screen) {
return false;
}
const auto r = screen->availableGeometry();
auto x = menuPosition.x();
auto y = r.y() + r.height() - menuPosition.y();
return !![menu popupAtX:x andY:y];

View File

@@ -65,7 +65,6 @@ protected:
void titleVisibilityChangedHook() override;
void unreadCounterChangedHook() override;
QImage psTrayIcon(bool selected = false) const;
bool hasTrayIcon() const override {
return trayIcon;
}
@@ -77,8 +76,6 @@ protected:
QSystemTrayIcon *trayIcon = nullptr;
QMenu *trayIconMenu = nullptr;
QImage trayImg, trayImgSel;
void psTrayMenuUpdated();
void psSetupTrayIcon();
virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
@@ -95,6 +92,7 @@ private:
void hideAndDeactivate();
void updateTitleCounter();
void updateIconCounters();
[[nodiscard]] QIcon generateIconForTray(int counter, bool muted) const;
std::unique_ptr<Private> _private;

View File

@@ -124,6 +124,17 @@ private:
};
[[nodiscard]] QImage TrayIconBack(bool darkMode) {
static const auto WithColor = [](QColor color) {
return st::macTrayIcon.instance(color, 100);
};
static const auto DarkModeResult = WithColor({ 255, 255, 255 });
static const auto LightModeResult = WithColor({ 0, 0, 0, 180 });
auto result = darkMode ? DarkModeResult : LightModeResult;
result.detach();
return result;
}
} // namespace
class MainWindow::Private {
@@ -200,7 +211,6 @@ private:
- (void) darkModeChanged:(NSNotification *)aNotification {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
Core::App().domain().notifyUnreadBadgeChanged();
});
}
@@ -485,9 +495,6 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
auto forceOpenGL = std::make_unique<QOpenGLWidget>(this);
#endif // !OS_MAC_OLD
trayImg = st::macTrayIcon.instance(QColor(0, 0, 0, 180), 100);
trayImgSel = st::macTrayIcon.instance(QColor(255, 255, 255), 100);
_hideAfterFullScreenTimer.setCallback([this] { hideAndDeactivate(); });
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
@@ -543,10 +550,6 @@ void MainWindow::hideAndDeactivate() {
hide();
}
QImage MainWindow::psTrayIcon(bool selected) const {
return selected ? trayImgSel : trayImg;
}
void MainWindow::psShowTrayMenu() {
}
@@ -566,14 +569,13 @@ void MainWindow::psTrayMenuUpdated() {
void MainWindow::psSetupTrayIcon() {
if (!trayIcon) {
trayIcon = new QSystemTrayIcon(this);
QIcon icon(QPixmap::fromImage(psTrayIcon(), Qt::ColorOnly));
icon.addPixmap(QPixmap::fromImage(psTrayIcon(true), Qt::ColorOnly), QIcon::Selected);
trayIcon->setIcon(icon);
trayIcon->setIcon(generateIconForTray(
Core::App().unreadBadge(),
Core::App().unreadBadgeMuted()));
attachToTrayIcon(trayIcon);
} else {
updateIconCounters();
}
updateIconCounters();
trayIcon->show();
}
@@ -651,21 +653,31 @@ void MainWindow::updateIconCounters() {
_private->setWindowBadge(string);
if (trayIcon) {
bool dm = Platform::IsDarkMenuBar();
auto &bg = (muted ? st::trayCounterBgMute : st::trayCounterBg);
QIcon icon;
QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true));
img.detach();
imgsel.detach();
int32 size = 22 * cIntRetinaFactor();
_placeCounter(img, size, counter, bg, (dm && muted) ? st::trayCounterFgMacInvert : st::trayCounterFg);
_placeCounter(imgsel, size, counter, st::trayCounterBgMacInvert, st::trayCounterFgMacInvert);
icon.addPixmap(App::pixmapFromImageInPlace(std::move(img)));
icon.addPixmap(App::pixmapFromImageInPlace(std::move(imgsel)), QIcon::Selected);
trayIcon->setIcon(icon);
trayIcon->setIcon(generateIconForTray(counter, muted));
}
}
QIcon MainWindow::generateIconForTray(int counter, bool muted) const {
auto result = QIcon();
auto lightMode = TrayIconBack(false);
auto darkMode = TrayIconBack(true);
auto lightModeActive = darkMode;
auto darkModeActive = darkMode;
lightModeActive.detach();
darkModeActive.detach();
const auto size = 22 * cIntRetinaFactor();
const auto &bg = (muted ? st::trayCounterBgMute : st::trayCounterBg);
_placeCounter(lightMode, size, counter, bg, st::trayCounterFg);
_placeCounter(darkMode, size, counter, bg, muted ? st::trayCounterFgMacInvert : st::trayCounterFg);
_placeCounter(lightModeActive, size, counter, st::trayCounterBgMacInvert, st::trayCounterFgMacInvert);
_placeCounter(darkModeActive, size, counter, st::trayCounterBgMacInvert, st::trayCounterFgMacInvert);
result.addPixmap(App::pixmapFromImageInPlace(std::move(lightMode)), QIcon::Normal, QIcon::Off);
result.addPixmap(App::pixmapFromImageInPlace(std::move(darkMode)), QIcon::Normal, QIcon::On);
result.addPixmap(App::pixmapFromImageInPlace(std::move(lightModeActive)), QIcon::Active, QIcon::Off);
result.addPixmap(App::pixmapFromImageInPlace(std::move(darkModeActive)), QIcon::Active, QIcon::On);
return result;
}
void MainWindow::initShadows() {
_private->enableShadow(winId());
}

View File

@@ -47,8 +47,6 @@ using Manager = Platform::Notifications::Manager;
} // namespace
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
@interface NotificationDelegate : NSObject<NSUserNotificationCenterDelegate> {
}
@@ -267,7 +265,7 @@ void Manager::Private::showNotification(
: peer->isRepliesChat()
? Ui::EmptyUserpic::GenerateRepliesMessages(st::notifyMacPhotoSize)
: peer->genUserpic(userpicView, st::notifyMacPhotoSize);
NSImage *img = [qt_mac_create_nsimage(userpic) autorelease];
NSImage *img = Q2NSImage(userpic.toImage());
[notification setContentImage:img];
}

View File

@@ -39,8 +39,6 @@ constexpr auto kIgnoreActivationTimeoutMs = 500;
} // namespace
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
using Platform::Q2NSString;
using Platform::NS2QString;
@@ -157,11 +155,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();
}
@@ -212,10 +212,9 @@ void SetApplicationIcon(const QIcon &icon) {
if (!icon.isNull()) {
auto pixmap = icon.pixmap(1024, 1024);
pixmap.setDevicePixelRatio(cRetinaFactor());
image = static_cast<NSImage*>(qt_mac_create_nsimage(pixmap));
image = Q2NSImage(pixmap.toImage());
}
[[NSApplication sharedApplication] setApplicationIconImage:image];
[image release];
}
} // namespace Platform

View File

@@ -43,7 +43,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#import <AppKit/NSSegmentedControl.h>
#import <AppKit/NSTextField.h>
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
using TouchBar::kCircleDiameter;
using TouchBar::CreateNSImageFromStyleIcon;
@@ -96,32 +95,32 @@ struct PickerScrubberItem {
}
void updateThumbnail() {
if (!document || !qpixmap.isNull()) {
if (!document || !image.isNull()) {
return;
}
const auto image = mediaView->getStickerSmall();
if (!image) {
const auto sticker = mediaView->getStickerSmall();
if (!sticker) {
return;
}
const auto size = image->size()
const auto size = sticker->size()
.scaled(kCircleDiameter, kCircleDiameter, Qt::KeepAspectRatio);
qpixmap = image->pixSingle(
image = sticker->pixSingle(
size.width(),
size.height(),
kCircleDiameter,
kCircleDiameter,
ImageRoundRadius::None);
ImageRoundRadius::None).toImage();
}
bool isStickerLoaded() const {
return !qpixmap.isNull();
return !image.isNull();
}
QString title = QString();
DocumentData *document = nullptr;
std::shared_ptr<Data::DocumentMedia> mediaView = nullptr;
QPixmap qpixmap;
QImage image;
EmojiPtr emoji = nullptr;
};
@@ -140,21 +139,25 @@ struct PickerScrubberItemsHolder {
};
using Platform::Q2NSString;
using Platform::Q2NSImage;
NSImage *CreateNSImageFromEmoji(EmojiPtr emoji) {
const auto s = kIdealIconSize * cIntRetinaFactor();
auto pixmap = QPixmap(s, s);
pixmap.setDevicePixelRatio(cRetinaFactor());
pixmap.fill(Qt::black);
Painter paint(&pixmap);
PainterHighQualityEnabler hq(paint);
Ui::Emoji::Draw(
paint,
std::move(emoji),
Ui::Emoji::GetSizeTouchbar(),
0,
0);
return [qt_mac_create_nsimage(pixmap) autorelease];
auto image = QImage(
QSize(kIdealIconSize, kIdealIconSize) * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(cRetinaFactor());
image.fill(Qt::black);
{
Painter paint(&image);
PainterHighQualityEnabler hq(paint);
Ui::Emoji::Draw(
paint,
emoji,
Ui::Emoji::GetSizeTouchbar(),
0,
0);
}
return Q2NSImage(image);
}
auto ActiveChat(not_null<Window::Controller*> controller) {
@@ -421,8 +424,7 @@ void AppendEmojiPacks(
PickerScrubberItemView *itemView = [scrubber
makeItemWithIdentifier:kStickerItemIdentifier
owner:self];
itemView.imageView.image = [qt_mac_create_nsimage(item.qpixmap)
autorelease];
itemView.imageView.image = Q2NSImage(item.image);
itemView->documentId = document->id;
return itemView;
} else if (const auto emoji = item.emoji) {

View File

@@ -20,7 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#import <AppKit/NSSlider.h>
#import <AppKit/NSSliderTouchBarItem.h>
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
using TouchBar::kCircleDiameter;
using TouchBar::CreateNSImageFromStyleIcon;

View File

@@ -9,9 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#ifndef OS_OSX
#import <AppKit/NSTextField.h>
#include "base/platform/mac/base_utilities_mac.h"
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
#import <AppKit/NSTextField.h>
namespace TouchBar {
@@ -21,10 +21,9 @@ int WidthFromString(NSString *s) {
}
NSImage *CreateNSImageFromStyleIcon(const style::icon &icon, int size) {
const auto instance = icon.instance(QColor(255, 255, 255, 255), 100);
auto pixmap = QPixmap::fromImage(instance);
pixmap.setDevicePixelRatio(cRetinaFactor());
NSImage *image = [qt_mac_create_nsimage(pixmap) autorelease];
auto instance = icon.instance(QColor(255, 255, 255, 255), 100);
instance.setDevicePixelRatio(cRetinaFactor());
NSImage *image = Platform::Q2NSImage(instance);
[image setSize:NSMakeSize(size, size)];
return image;
}

View File

@@ -358,11 +358,7 @@ bool Get(
dialog.setAcceptMode(QFileDialog::AcceptOpen);
} else if (type == Type::ReadFolder) { // save dir
dialog.setAcceptMode(QFileDialog::AcceptOpen);
// We use "obsolete" value ::DirectoryOnly instead of ::Directory + ::ShowDirsOnly
// because in Windows XP native dialog this one works, while the "preferred" one
// shows a native file choose dialog where you can't choose a directory, only open one.
dialog.setFileMode(QFileDialog::DirectoryOnly);
dialog.setFileMode(QFileDialog::Directory);
dialog.setOption(QFileDialog::ShowDirsOnly);
} else { // save file
dialog.setFileMode(QFileDialog::AnyFile);

View File

@@ -199,7 +199,7 @@ void MainWindow::psRefreshTaskbarIcon() {
refresher->setWindowFlags(static_cast<Qt::WindowFlags>(Qt::Tool) | Qt::FramelessWindowHint);
refresher->setGeometry(x() + 1, y() + 1, 1, 1);
auto palette = refresher->palette();
palette.setColor(QPalette::Background, (isActiveWindow() ? st::titleBgActive : st::titleBg)->c);
palette.setColor(QPalette::Window, (isActiveWindow() ? st::titleBgActive : st::titleBg)->c);
refresher->setPalette(palette);
refresher->show();
refresher->activateWindow();

View File

@@ -72,7 +72,7 @@ public:
}
template <typename Predicate>
void sortItems(Predicate predicate) {
qSort(_items.begin(), _items.end(), std::move(predicate));
std::sort(_items.begin(), _items.end(), std::move(predicate));
}
void setPreloadMoreCallback(Fn<void()> callback) {

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

@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/file_download_web.h"
#include "storage/cache/storage_cache_types.h"
#include "base/qt_adapters.h"
#include <QtNetwork/QAuthenticator>
@@ -19,9 +20,6 @@ constexpr auto kResetDownloadPrioritiesTimeout = crl::time(200);
std::weak_ptr<WebLoadManager> GlobalLoadManager;
using ErrorSignal = void(QNetworkReply::*)(QNetworkReply::NetworkError);
const auto QNetworkReply_error = ErrorSignal(&QNetworkReply::error);
[[nodiscard]] std::shared_ptr<WebLoadManager> GetManager() {
auto result = GlobalLoadManager.lock();
if (!result) {
@@ -270,7 +268,7 @@ not_null<QNetworkReply*> WebLoadManager::send(int id, const QString &url) {
failed(id, result, error);
};
connect(result, &QNetworkReply::downloadProgress, handleProgress);
connect(result, QNetworkReply_error, handleError);
connect(result, base::QNetworkReply_error, handleError);
return result;
}

View File

@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "base/unixtime.h"
#include "base/call_delayed.h"
#include "base/qt_adapters.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "apiwrap.h"
@@ -484,7 +485,7 @@ void Autocomplete::submitValue(const QString &value) {
const auto contact = value.mid(
prefix.size(),
(line > 0) ? (line - prefix.size()) : -1);
const auto parts = contact.split(' ', QString::SkipEmptyParts);
const auto parts = contact.split(' ', base::QStringSkipEmptyParts);
if (parts.size() > 1) {
const auto phone = parts[0];
const auto firstName = parts[1];

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

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/multi_select.h"
#include "ui/effects/ripple_animation.h"
#include "data/data_countries.h"
#include "base/qt_adapters.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_intro.h"
@@ -248,7 +249,7 @@ CountrySelectBox::Inner::Inner(QWidget *parent, Type type)
: QString());
const auto namesList = std::move(full).toLower().split(
QRegularExpression("[\\s\\-]"),
QString::SkipEmptyParts);
base::QStringSkipEmptyParts);
auto &names = _namesList.emplace_back();
names.reserve(namesList.size());
for (const auto &name : namesList) {

View File

@@ -358,7 +358,6 @@ void SeparatePanel::initGeometry(QSize size) {
st::lineWidth,
st::lineWidth);
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
const auto screen = QApplication::desktop()->screenGeometry(center);
const auto rect = [&] {
const QRect initRect(QPoint(), size);
return initRect.translated(center - initRect.center()).marginsAdded(_padding);

View File

@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/edit_color_box.h"
#include "lang/lang_keys.h"
#include "base/call_delayed.h"
#include "base/qt_adapters.h"
namespace Window {
namespace Theme {
@@ -154,7 +155,7 @@ void EditorBlock::Row::fillSearchIndex() {
_searchWords.clear();
_searchStartChars.clear();
auto toIndex = _name + ' ' + _copyOf + ' ' + TextUtilities::RemoveAccents(_description.toString()) + ' ' + _valueString;
auto words = toIndex.toLower().split(SearchSplitter, QString::SkipEmptyParts);
auto words = toIndex.toLower().split(SearchSplitter, base::QStringSkipEmptyParts);
for_const (auto &word, words) {
_searchWords.insert(word);
_searchStartChars.insert(word[0]);

View File

@@ -393,7 +393,7 @@ Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) {
>= (window()->height() - getResizeArea(Qt::BottomEdge))) {
return Qt::BottomEdge;
} else {
return 0;
return Qt::Edges();
}
}

View File

@@ -134,73 +134,13 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
Error "Backup folder not found!"
fi
./configure.sh
./build/docker/centos_env/run.sh /usr/src/tdesktop/Telegram/build/docker/build.sh
cd $ProjectPath
cmake --build . --config Release --target Telegram -- -j8
cd $ReleasePath
echo "$BinaryName build complete!"
if [ ! -f "$ReleasePath/$BinaryName" ]; then
Error "$BinaryName not found!"
fi
# BadCount=`objdump -T $ReleasePath/$BinaryName | grep GLIBC_2\.1[6-9] | wc -l`
# if [ "$BadCount" != "0" ]; then
# Error "Bad GLIBC usages found: $BadCount"
# fi
# BadCount=`objdump -T $ReleasePath/$BinaryName | grep GLIBC_2\.2[0-9] | wc -l`
# if [ "$BadCount" != "0" ]; then
# Error "Bad GLIBC usages found: $BadCount"
# fi
BadCount=`objdump -T $ReleasePath/$BinaryName | grep GCC_4\.[3-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/$BinaryName | grep GCC_[5-9]\. | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
if [ ! -f "$ReleasePath/Updater" ]; then
Error "Updater not found!"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GLIBC_2\.1[6-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GLIBC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GLIBC_2\.2[0-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GLIBC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GCC_4\.[3-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GCC_[5-9]\. | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
echo "Dumping debug symbols.."
"$HomePath/../../Libraries/breakpad/out/Default/dump_syms" "$ReleasePath/$BinaryName" > "$ReleasePath/$BinaryName.sym"
echo "Done!"
echo "Stripping the executable.."
strip -s "$ReleasePath/$BinaryName"
echo "Done!"
echo "Removing RPATH.."
chrpath -d "$ReleasePath/$BinaryName"
echo "Done!"
echo "Copying from docker result folder."
cp "$ReleasePath/root/$BinaryName" "$ReleasePath/$BinaryName"
cp "$ReleasePath/root/$BinaryName.sym" "$ReleasePath/$BinaryName.sym"
cp "$ReleasePath/root/Updater" "$ReleasePath/Updater"
cp "$ReleasePath/root/Packer" "$ReleasePath/Packer"
echo "Preparing version $AppVersionStrFull, executing Packer.."
cd "$ReleasePath"

102
Telegram/build/docker/build.sh Executable file
View File

@@ -0,0 +1,102 @@
#!/bin/bash
set -e
FullExecPath=$PWD
pushd `dirname $0` > /dev/null
FullScriptPath=`pwd`
popd > /dev/null
if [ ! -d "$FullScriptPath/../../../../DesktopPrivate" ]; then
echo ""
echo "This script is for building the production version of Telegram Desktop."
echo ""
echo "For building custom versions please visit the build instructions page at:"
echo "https://github.com/telegramdesktop/tdesktop/#build-instructions"
exit
fi
Run () {
scl enable devtoolset-8 -- "$@"
}
HomePath="$FullScriptPath/../.."
cd $HomePath
ProjectPath="$HomePath/../out"
ReleasePath="$ProjectPath/Release"
BinaryName="Telegram"
if [ ! -f "/usr/bin/cmake" ]; then
ln -s cmake3 /usr/bin/cmake
fi
Run ./configure.sh
cd $ProjectPath
Run cmake --build . --config Release --target Telegram -- -j8
cd $ReleasePath
echo "$BinaryName build complete!"
if [ ! -f "$ReleasePath/$BinaryName" ]; then
Error "$BinaryName not found!"
fi
# BadCount=`objdump -T $ReleasePath/$BinaryName | grep GLIBC_2\.1[6-9] | wc -l`
# if [ "$BadCount" != "0" ]; then
# Error "Bad GLIBC usages found: $BadCount"
# fi
# BadCount=`objdump -T $ReleasePath/$BinaryName | grep GLIBC_2\.2[0-9] | wc -l`
# if [ "$BadCount" != "0" ]; then
# Error "Bad GLIBC usages found: $BadCount"
# fi
BadCount=`objdump -T $ReleasePath/$BinaryName | grep GCC_4\.[3-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/$BinaryName | grep GCC_[5-9]\. | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
if [ ! -f "$ReleasePath/Updater" ]; then
Error "Updater not found!"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GLIBC_2\.1[6-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GLIBC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GLIBC_2\.2[0-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GLIBC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GCC_4\.[3-9] | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
BadCount=`objdump -T $ReleasePath/Updater | grep GCC_[5-9]\. | wc -l`
if [ "$BadCount" != "0" ]; then
Error "Bad GCC usages found: $BadCount"
fi
echo "Dumping debug symbols.."
/dump_syms "$ReleasePath/$BinaryName" > "$ReleasePath/$BinaryName.sym"
echo "Done!"
echo "Stripping the executable.."
strip -s "$ReleasePath/$BinaryName"
echo "Done!"
rm -rf "$ReleasePath/root"
mkdir "$ReleasePath/root"
mv "$ReleasePath/$BinaryName" "$ReleasePath/root/"
mv "$ReleasePath/$BinaryName.sym" "$ReleasePath/root/"
mv "$ReleasePath/Updater" "$ReleasePath/root/"
mv "$ReleasePath/Packer" "$ReleasePath/root/"

View File

@@ -2,8 +2,9 @@ FROM centos:7 AS builder
ENV GIT https://github.com
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig
ENV QT 5_12_8
ENV QT_PREFIX /usr/local/desktop-app/Qt-5.12.8
ENV QT 5_15_1
ENV QT_TAG v5.15.1
ENV QT_PREFIX /usr/local/desktop-app/Qt-5.15.1
ENV OPENSSL_VER 1_1_1
ENV OPENSSL_PREFIX /usr/local/desktop-app/openssl-1.1.1
@@ -18,6 +19,7 @@ RUN yum -y install git cmake3 zlib-devel gtk2-devel libICE-devel \
devtoolset-8-make devtoolset-8-gcc devtoolset-8-gcc-c++ \
devtoolset-8-binutils
SHELL [ "scl", "enable", "devtoolset-8", "--", "bash", "-c" ]
RUN ln -s cmake3 /usr/bin/cmake
ENV LibrariesPath /usr/src/Libraries
@@ -25,16 +27,16 @@ WORKDIR $LibrariesPath
FROM builder AS patches
RUN git clone $GIT/desktop-app/patches.git
RUN cd patches && git checkout b00f25d
RUN cd patches && git checkout e052c49
FROM builder AS libffi
RUN git clone -b v3.3 --depth=1 $GIT/libffi/libffi.git
WORKDIR libffi
RUN scl enable devtoolset-8 -- ./autogen.sh
RUN scl enable devtoolset-8 -- ./configure --enable-static --disable-docs
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libffi-cache" install
RUN ./autogen.sh
RUN ./configure --enable-static --disable-docs
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libffi-cache" install
WORKDIR ..
RUN rm -rf libffi
@@ -43,9 +45,9 @@ FROM builder AS xz
RUN git clone -b v5.2.5 https://git.tukaani.org/xz.git
WORKDIR xz
RUN scl enable devtoolset-8 -- cmake3 -B build . -DCMAKE_BUILD_TYPE=Release
RUN scl enable devtoolset-8 -- cmake3 --build build -j$(nproc)
RUN DESTDIR="$LibrariesPath/xz-cache" scl enable devtoolset-8 -- cmake3 --install build
RUN cmake3 -B build . -DCMAKE_BUILD_TYPE=Release
RUN cmake3 --build build -j$(nproc)
RUN DESTDIR="$LibrariesPath/xz-cache" cmake3 --install build
WORKDIR ..
RUN rm -rf xz
@@ -54,14 +56,14 @@ FROM builder AS mozjpeg
RUN git clone -b v4.0.1-rc2 --depth=1 $GIT/mozilla/mozjpeg.git
WORKDIR mozjpeg
RUN scl enable devtoolset-8 -- cmake3 -B build . \
RUN cmake3 -B build . \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DWITH_JPEG8=ON \
-DPNG_SUPPORTED=OFF
RUN scl enable devtoolset-8 -- cmake3 --build build -j$(nproc)
RUN DESTDIR="$LibrariesPath/mozjpeg-cache" scl enable devtoolset-8 -- cmake3 --install build
RUN cmake3 --build build -j$(nproc)
RUN DESTDIR="$LibrariesPath/mozjpeg-cache" cmake3 --install build
WORKDIR ..
RUN rm -rf mozjpeg
@@ -70,10 +72,10 @@ FROM builder AS opus
RUN git clone -b v1.3 --depth=1 $GIT/xiph/opus.git
WORKDIR opus
RUN scl enable devtoolset-8 -- ./autogen.sh
RUN scl enable devtoolset-8 -- ./configure
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/opus-cache" install
RUN ./autogen.sh
RUN ./configure
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/opus-cache" install
WORKDIR ..
RUN rm -rf opus
@@ -82,9 +84,9 @@ FROM builder AS xcb-proto
RUN git clone -b xcb-proto-1.14 --depth=1 https://gitlab.freedesktop.org/xorg/proto/xcbproto.git
WORKDIR xcbproto
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/xcb-proto-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-proto-cache" install
WORKDIR ..
RUN rm -rf xcbproto
@@ -95,20 +97,71 @@ COPY --from=xcb-proto ${LibrariesPath}/xcb-proto-cache /
RUN git clone -b libxcb-1.14 --depth=1 https://gitlab.freedesktop.org/xorg/lib/libxcb.git
WORKDIR libxcb
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/xcb-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-cache" install
WORKDIR ..
RUN rm -rf libxcb
FROM builder AS xcb-wm
RUN git clone --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-wm.git
WORKDIR libxcb-wm
RUN git checkout 0.4.1
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-wm-cache" install
FROM builder AS xcb-util
RUN git clone --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-util.git
WORKDIR libxcb-util
RUN git checkout 0.4.0
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-util-cache" install
FROM builder AS xcb-image
COPY --from=xcb-util ${LibrariesPath}/xcb-util-cache /
RUN git clone --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-image.git
WORKDIR libxcb-image
RUN git checkout 0.4.0
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-image-cache" install
FROM builder AS xcb-keysyms
RUN git clone --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-keysyms.git
WORKDIR libxcb-keysyms
RUN git checkout 0.4.0
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-keysyms-cache" install
FROM builder AS xcb-render-util
RUN git clone --recursive https://gitlab.freedesktop.org/xorg/lib/libxcb-render-util.git
WORKDIR libxcb-render-util
RUN git checkout 0.3.9
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xcb-render-util-cache" install
FROM builder AS libXext
RUN git clone -b libXext-1.3.4 --depth=1 https://gitlab.freedesktop.org/xorg/lib/libxext.git
WORKDIR libxext
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libXext-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libXext-cache" install
WORKDIR ..
RUN rm -rf libxext
@@ -117,9 +170,9 @@ FROM builder AS libXfixes
RUN git clone -b libXfixes-5.0.3 --depth=1 https://gitlab.freedesktop.org/xorg/lib/libxfixes.git
WORKDIR libxfixes
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libXfixes-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libXfixes-cache" install
WORKDIR ..
RUN rm -rf libxfixes
@@ -128,9 +181,9 @@ FROM builder AS libXi
RUN git clone -b libXi-1.7.10 --depth=1 https://gitlab.freedesktop.org/xorg/lib/libxi.git
WORKDIR libxi
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libXi-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libXi-cache" install
WORKDIR ..
RUN rm -rf libxi
@@ -139,9 +192,9 @@ FROM builder AS libXrender
RUN git clone -b libXrender-0.9.10 --depth=1 https://gitlab.freedesktop.org/xorg/lib/libxrender.git
WORKDIR libxrender
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libXrender-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libXrender-cache" install
WORKDIR ..
RUN rm -rf libxrender
@@ -152,13 +205,13 @@ COPY --from=libffi ${LibrariesPath}/libffi-cache /
RUN git clone -b 1.18.0 --depth=1 https://gitlab.freedesktop.org/wayland/wayland.git
WORKDIR wayland
RUN scl enable devtoolset-8 -- ./autogen.sh \
RUN ./autogen.sh \
--enable-static \
--disable-documentation \
--disable-dtd-validation
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/wayland-cache" install
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/wayland-cache" install
WORKDIR ..
RUN rm -rf wayland
@@ -173,9 +226,9 @@ COPY --from=wayland ${LibrariesPath}/wayland-cache /
RUN git clone -b 2.9.0 --depth=1 $GIT/intel/libva.git
WORKDIR libva
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libva-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libva-cache" install
WORKDIR ..
RUN rm -rf libva
@@ -184,9 +237,9 @@ FROM builder AS libvdpau
RUN git clone -b libvdpau-1.2 --depth=1 https://gitlab.freedesktop.org/vdpau/libvdpau.git
WORKDIR libvdpau
RUN scl enable devtoolset-8 -- ./autogen.sh --enable-static
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/libvdpau-cache" install
RUN ./autogen.sh --enable-static
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/libvdpau-cache" install
WORKDIR ..
RUN rm -rf libvdpau
@@ -197,10 +250,10 @@ COPY --from=opus ${LibrariesPath}/opus-cache /
COPY --from=libva ${LibrariesPath}/libva-cache /
COPY --from=libvdpau ${LibrariesPath}/libvdpau-cache /
RUN git clone -b release/3.4 --depth=1 $GIT/FFmpeg/FFmpeg.git ffmpeg
RUN git clone -b release/4.2 --depth=1 $GIT/FFmpeg/FFmpeg.git ffmpeg
WORKDIR ffmpeg
RUN scl enable devtoolset-8 -- ./configure \
RUN ./configure \
--disable-debug \
--disable-programs \
--disable-doc \
@@ -302,14 +355,14 @@ RUN scl enable devtoolset-8 -- ./configure \
--enable-muxer=ogg \
--enable-muxer=opus
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/ffmpeg-cache" install
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/ffmpeg-cache" install
FROM builder AS openal
RUN git clone -b openal-soft-1.20.1 --depth=1 $GIT/kcat/openal-soft.git
RUN git clone -b fix_mono --depth=1 $GIT/telegramdesktop/openal-soft.git
WORKDIR openal-soft
RUN scl enable devtoolset-8 -- cmake3 -B build . \
RUN cmake3 -B build . \
-DCMAKE_BUILD_TYPE=Release \
-DLIBTYPE:STRING=STATIC \
-DALSOFT_EXAMPLES=OFF \
@@ -317,8 +370,8 @@ RUN scl enable devtoolset-8 -- cmake3 -B build . \
-DALSOFT_UTILS=OFF \
-DALSOFT_CONFIG=OFF
RUN scl enable devtoolset-8 -- cmake3 --build build -j$(nproc)
RUN DESTDIR="$LibrariesPath/openal-cache" scl enable devtoolset-8 -- cmake3 --install build
RUN cmake3 --build build -j$(nproc)
RUN DESTDIR="$LibrariesPath/openal-cache" cmake3 --install build
WORKDIR ..
RUN rm -rf openal
@@ -329,9 +382,9 @@ RUN git clone -b OpenSSL_${OPENSSL_VER}-stable --depth=1 \
$GIT/openssl/openssl.git $opensslDir
WORKDIR ${opensslDir}
RUN scl enable devtoolset-8 -- ./config --prefix="$OPENSSL_PREFIX" no-tests
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/openssl-cache" install_sw
RUN ./config --prefix="$OPENSSL_PREFIX" no-tests
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/openssl-cache" install_sw
WORKDIR ..
RUN rm -rf $opensslDir
@@ -340,14 +393,14 @@ FROM builder AS xkbcommon
RUN git clone -b xkbcommon-0.8.4 --depth=1 $GIT/xkbcommon/libxkbcommon.git
WORKDIR libxkbcommon
RUN scl enable devtoolset-8 -- ./autogen.sh \
RUN ./autogen.sh \
--disable-docs \
--disable-wayland \
--with-xkb-config-root=/usr/share/X11/xkb \
--with-x-locale-root=/usr/share/X11/locale
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$LibrariesPath/xkbcommon-cache" install
RUN make -j$(nproc)
RUN make DESTDIR="$LibrariesPath/xkbcommon-cache" install
WORKDIR ..
RUN rm -rf libxkbcommon
@@ -357,6 +410,11 @@ FROM patches AS qt
COPY --from=libffi ${LibrariesPath}/libffi-cache /
COPY --from=mozjpeg ${LibrariesPath}/mozjpeg-cache /
COPY --from=xcb ${LibrariesPath}/xcb-cache /
COPY --from=xcb-wm ${LibrariesPath}/xcb-wm-cache /
COPY --from=xcb-util ${LibrariesPath}/xcb-util-cache /
COPY --from=xcb-image ${LibrariesPath}/xcb-image-cache /
COPY --from=xcb-keysyms ${LibrariesPath}/xcb-keysyms-cache /
COPY --from=xcb-render-util ${LibrariesPath}/xcb-render-util-cache /
COPY --from=libXext ${LibrariesPath}/libXext-cache /
COPY --from=libXfixes ${LibrariesPath}/libXfixes-cache /
COPY --from=libXi ${LibrariesPath}/libXi-cache /
@@ -365,37 +423,42 @@ COPY --from=wayland ${LibrariesPath}/wayland-cache /
COPY --from=openssl ${LibrariesPath}/openssl-cache /
COPY --from=xkbcommon ${LibrariesPath}/xkbcommon-cache /
RUN git clone -b v5.12.8 --depth=1 git://code.qt.io/qt/qt5.git qt_${QT}
RUN git clone -b ${QT_TAG} --depth=1 git://code.qt.io/qt/qt5.git qt_${QT}
WORKDIR qt_${QT}
RUN perl init-repository --module-subset=qtbase,qtwayland,qtimageformats,qtsvg
RUN git submodule update qtbase qtwayland qtimageformats qtsvg
WORKDIR qtbase
RUN find ../../patches/qtbase_${QT} -type f -print0 | sort -z | xargs -r0 git apply
WORKDIR ../qtwayland
RUN find ../../patches/qtwayland_${QT} -type f -print0 | sort -z | xargs -r0 git apply
WORKDIR ..
RUN scl enable devtoolset-8 -- ./configure -prefix "$QT_PREFIX" \
# I couldn't make it work with direct ./configure call :(
RUN echo './configure -prefix '$'\"''$QT_PREFIX'$'\"'' \
-release \
-opensource \
-confirm-license \
-xcb \
-qt-libpng \
-qt-harfbuzz \
-qt-pcre \
-qt-xcb \
-no-icu \
-no-gtk \
-no-feature-wayland-server \
-static \
-dbus-runtime \
-openssl-linked \
-I "$OPENSSL_PREFIX/include" OPENSSL_LIBS="$OPENSSL_PREFIX/lib/libssl.a $OPENSSL_PREFIX/lib/libcrypto.a -lz -ldl -lpthread" \
-I '$'\"''$OPENSSL_PREFIX/include'$'\"'' \
OPENSSL_LIBS='$'\"''$OPENSSL_PREFIX/lib/libssl.a $OPENSSL_PREFIX/lib/libcrypto.a -lz -ldl -lpthread'$'\"'' \
-nomake examples \
-nomake tests \
-L /usr/local/lib64
-L /usr/local/lib64' >> ./run_configure.sh
RUN cat ./run_configure.sh
RUN chmod a+x ./run_configure.sh
RUN ./run_configure.sh
RUN rm ./run_configure.sh
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make INSTALL_ROOT="$LibrariesPath/qt-cache" install
RUN make -j$(nproc)
RUN make INSTALL_ROOT="$LibrariesPath/qt-cache" install
WORKDIR ..
RUN rm -rf qt_${QT}
@@ -419,9 +482,9 @@ RUN git checkout 9f2a7bb1
RUN git apply ../patches/gyp.diff
WORKDIR ../breakpad
RUN scl enable devtoolset-8 -- ./configure
RUN scl enable devtoolset-8 -- make -j$(nproc)
RUN scl enable devtoolset-8 -- make DESTDIR="$BreakpadCache" install
RUN ./configure
RUN make -j$(nproc)
RUN make DESTDIR="$BreakpadCache" install
WORKDIR src
RUN rm -rf testing
@@ -432,8 +495,8 @@ RUN sed -i 's/minidump_upload.m/minidump_upload.cc/' linux/tools_linux.gypi
RUN ../../../gyp/gyp --depth=. --generator-output=.. -Goutput_dir=../out tools.gyp --format=cmake
WORKDIR ../../out/Default
RUN scl enable devtoolset-8 -- cmake3 .
RUN scl enable devtoolset-8 -- cmake3 --build . --target dump_syms -j$(nproc)
RUN cmake3 .
RUN cmake3 --build . --target dump_syms -j$(nproc)
RUN mv dump_syms $BreakpadCache
WORKDIR ..
@@ -451,7 +514,7 @@ RUN git clone $GIT/desktop-app/tg_owt.git
WORKDIR tg_owt
RUN git checkout c73a471
RUN scl enable devtoolset-8 -- cmake3 -B out/Release . \
RUN cmake3 -B out/Release . \
-DCMAKE_BUILD_TYPE=Release \
-DTG_OWT_SPECIAL_TARGET=linux \
-DTG_OWT_LIBJPEG_INCLUDE_PATH=/usr/local/include \
@@ -459,7 +522,17 @@ RUN scl enable devtoolset-8 -- cmake3 -B out/Release . \
-DTG_OWT_OPUS_INCLUDE_PATH=/usr/local/include/opus \
-DTG_OWT_FFMPEG_INCLUDE_PATH=/usr/local/include
RUN scl enable devtoolset-8 -- cmake3 --build out/Release
RUN cmake3 --build out/Release -- -j8
RUN cmake3 -B out/Debug . \
-DCMAKE_BUILD_TYPE=Debug \
-DTG_OWT_SPECIAL_TARGET=linux \
-DTG_OWT_LIBJPEG_INCLUDE_PATH=/usr/local/include \
-DTG_OWT_OPENSSL_INCLUDE_PATH=$OPENSSL_PREFIX/include \
-DTG_OWT_OPUS_INCLUDE_PATH=/usr/local/include/opus \
-DTG_OWT_FFMPEG_INCLUDE_PATH=/usr/local/include
RUN cmake3 --build out/Debug -- -j8
FROM builder
@@ -468,6 +541,11 @@ COPY --from=xz ${LibrariesPath}/xz-cache /
COPY --from=mozjpeg ${LibrariesPath}/mozjpeg-cache /
COPY --from=opus ${LibrariesPath}/opus-cache /
COPY --from=xcb ${LibrariesPath}/xcb-cache /
COPY --from=xcb-wm ${LibrariesPath}/xcb-wm-cache /
COPY --from=xcb-util ${LibrariesPath}/xcb-util-cache /
COPY --from=xcb-image ${LibrariesPath}/xcb-image-cache /
COPY --from=xcb-keysyms ${LibrariesPath}/xcb-keysyms-cache /
COPY --from=xcb-render-util ${LibrariesPath}/xcb-render-util-cache /
COPY --from=libXext ${LibrariesPath}/libXext-cache /
COPY --from=libXfixes ${LibrariesPath}/libXfixes-cache /
COPY --from=libXi ${LibrariesPath}/libXi-cache /

View File

@@ -0,0 +1,7 @@
set -e
FullExecPath=$PWD
pushd `dirname $0` > /dev/null
FullScriptPath=`pwd`
popd > /dev/null
docker build -t tdesktop:centos_env "$FullScriptPath/"

View File

@@ -0,0 +1,21 @@
set -e
FullExecPath=$PWD
pushd `dirname $0` > /dev/null
FullScriptPath=`pwd`
popd > /dev/null
if [ ! -d "$FullScriptPath/../../../../../DesktopPrivate" ]; then
echo ""
echo "This script is for building the production version of Telegram Desktop."
echo ""
echo "For building custom versions please visit the build instructions page at:"
echo "https://github.com/telegramdesktop/tdesktop/#build-instructions"
exit
fi
Command="$1"
if [ "$Command" == "" ]; then
Command="scl enable devtoolset-8 -- bash"
fi
docker run -it --rm --cpus=8 --memory=10g -v $HOME/Telegram/DesktopPrivate:/usr/src/DesktopPrivate -v $HOME/Telegram/tdesktop:/usr/src/tdesktop tdesktop:centos_env $Command

View File

@@ -1,7 +1,7 @@
AppVersion 2004005
AppVersion 2004009
AppVersionStrMajor 2.4
AppVersionStrSmall 2.4.5
AppVersionStr 2.4.5
BetaChannel 0
AppVersionStrSmall 2.4.9
AppVersionStr 2.4.9
BetaChannel 1
AlphaVersion 0
AppVersionOriginal 2.4.5
AppVersionOriginal 2.4.9.beta

View File

@@ -1,3 +1,25 @@
2.4.9 beta (06.11.20)
- Fix crash in tray icon removing. (macOS only)
2.4.8 beta (06.11.20)
- Upgrade Qt to version 5.15.1.
- Upgrade FFmpeg to version 4.2.
- Upgrade OpenAL to version 1.20.1.
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.

Some files were not shown because too many files have changed in this diff Show More