diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index fb608fe1d..e450b5af6 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -9,7 +9,7 @@
+ Version="2.8.1.0" />
Telegram Desktop
Telegram Messenger LLP
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index cffdb2fe1..9a3edda30 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,7,10,0
- PRODUCTVERSION 2,7,10,0
+ FILEVERSION 2,8,1,0
+ PRODUCTVERSION 2,8,1,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.7.10.0"
+ VALUE "FileVersion", "2.8.1.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "2.7.10.0"
+ VALUE "ProductVersion", "2.8.1.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index 9c4998e52..a3602049b 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,7,10,0
- PRODUCTVERSION 2,7,10,0
+ FILEVERSION 2,8,1,0
+ PRODUCTVERSION 2,8,1,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.7.10.0"
+ VALUE "FileVersion", "2.8.1.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "2.7.10.0"
+ VALUE "ProductVersion", "2.8.1.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index e2a1b8a3a..127a5113b 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -23,7 +23,7 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Kotatogram Desktop"_cs;
constexpr auto AppFile = "Kotatogram"_cs;
-constexpr auto AppVersion = 2007010;
-constexpr auto AppVersionStr = "2.7.10";
+constexpr auto AppVersion = 2008001;
+constexpr auto AppVersionStr = "2.8.1";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
diff --git a/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp b/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp
deleted file mode 100644
index 468f58cb6..000000000
--- a/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp
+++ /dev/null
@@ -1,526 +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 "platform/linux/linux_mpris_support.h"
-
-#include "base/platform/base_platform_info.h"
-#include "base/platform/linux/base_linux_glibmm_helper.h"
-#include "media/audio/media_audio.h"
-#include "media/player/media_player_instance.h"
-#include "data/data_file_origin.h"
-#include "data/data_document.h"
-#include "data/data_document_media.h"
-#include "core/sandbox.h"
-#include "core/application.h"
-#include "core/core_settings.h"
-#include "main/main_domain.h"
-#include "main/main_account.h"
-#include "main/main_session.h"
-#include "mainwindow.h"
-#include "mainwidget.h"
-
-#include
-#include
-
-#include
-#include
-
-namespace Platform {
-namespace internal {
-namespace {
-
-constexpr auto kService = "org.mpris.MediaPlayer2.Kotatogram"_cs;
-constexpr auto kObjectPath = "/org/mpris/MediaPlayer2"_cs;
-constexpr auto kFakeTrackPath = "/org/kotatogram/desktop/track/0"_cs;
-constexpr auto kInterface = "org.mpris.MediaPlayer2"_cs;
-constexpr auto kPlayerInterface = "org.mpris.MediaPlayer2.Player"_cs;
-constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
-
-constexpr auto kIntrospectionXML = R"INTROSPECTION(
-
-
-
-
-
-
-
-
-
-
-
-
-
-)INTROSPECTION"_cs;
-
-constexpr auto kPlayerIntrospectionXML = R"INTROSPECTION(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-)INTROSPECTION"_cs;
-
-auto CreateMetadata(
- const Media::Player::TrackState &state,
- Data::DocumentMedia *trackView) {
- std::map result;
-
- if (Media::Player::IsStoppedOrStopping(state.state)) {
- return result;
- }
-
- result["mpris:trackid"] = Glib::wrap(g_variant_new_object_path(
- kFakeTrackPath.utf8().constData()));
- result["mpris:length"] = Glib::Variant::create(
- state.length * 1000);
- result["xesam:title"] = Glib::Variant::create(
- "Unknown Track");
-
- const auto audioData = state.id.audio();
- if (audioData) {
- if (!audioData->filename().isEmpty()) {
- result["xesam:title"] = Glib::Variant<
- Glib::ustring
- >::create(audioData->filename().toStdString());
- }
-
- if (audioData->isSong()) {
- const auto songData = audioData->song();
- if (!songData->performer.isEmpty()) {
- result["xesam:artist"] = Glib::Variant<
- std::vector
- >::create({ songData->performer.toStdString() });
- }
- if (!songData->title.isEmpty()) {
- result["xesam:title"] = Glib::Variant<
- Glib::ustring
- >::create(songData->title.toStdString());
- }
- }
- }
-
- if (trackView) {
- trackView->thumbnailWanted(Data::FileOrigin());
- if (trackView->thumbnail()) {
- QByteArray thumbnailData;
- QBuffer thumbnailBuffer(&thumbnailData);
- trackView->thumbnail()->original().save(
- &thumbnailBuffer,
- "JPG",
- 87);
-
- result["mpris:artUrl"] = Glib::Variant<
- Glib::ustring
- >::create("data:image/jpeg;base64,"
- + thumbnailData
- .toBase64()
- .toStdString());
- }
- }
-
- return result;
-}
-
-auto PlaybackStatus(Media::Player::State state) {
- return (state == Media::Player::State::Playing)
- ? "Playing"
- : Media::Player::IsPausedOrPausing(state)
- ? "Paused"
- : "Stopped";
-}
-
-void HandleMethodCall(
- const Glib::RefPtr &connection,
- const Glib::ustring &sender,
- const Glib::ustring &object_path,
- const Glib::ustring &interface_name,
- const Glib::ustring &method_name,
- const Glib::VariantContainerBase ¶meters,
- const Glib::RefPtr &invocation) {
- Core::Sandbox::Instance().customEnterFromEventLoop([&] {
- try {
- auto parametersCopy = parameters;
-
- if (method_name == "Quit") {
- if (const auto main = App::main()) {
- main->closeBothPlayers();
- }
- } else if (method_name == "Raise") {
- if (const auto window = App::wnd()) {
- window->showFromTray();
- }
- } else if (method_name == "Next") {
- Media::Player::instance()->next();
- } else if (method_name == "Pause") {
- Media::Player::instance()->pause();
- } else if (method_name == "Play") {
- Media::Player::instance()->play();
- } else if (method_name == "PlayPause") {
- Media::Player::instance()->playPause();
- } else if (method_name == "Previous") {
- Media::Player::instance()->previous();
- } else if (method_name == "Seek") {
- const auto offset = base::Platform::GlibVariantCast(
- parametersCopy.get_child(0));
-
- const auto state = Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType());
-
- Media::Player::instance()->finishSeeking(
- Media::Player::instance()->getActiveType(),
- float64(state.position * 1000 + offset)
- / (state.length * 1000));
- } else if (method_name == "SetPosition") {
- const auto position = base::Platform::GlibVariantCast(
- parametersCopy.get_child(1));
-
- const auto state = Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType());
-
- Media::Player::instance()->finishSeeking(
- Media::Player::instance()->getActiveType(),
- float64(position) / (state.length * 1000));
- } else if (method_name == "Stop") {
- Media::Player::instance()->stop();
- } else {
- return;
- }
-
- invocation->return_value({});
- } catch (...) {
- }
- });
-}
-
-void HandleGetProperty(
- Glib::VariantBase &property,
- const Glib::RefPtr &connection,
- const Glib::ustring &sender,
- const Glib::ustring &object_path,
- const Glib::ustring &interface_name,
- const Glib::ustring &property_name) {
- Core::Sandbox::Instance().customEnterFromEventLoop([&] {
- if (property_name == "CanQuit") {
- property = Glib::Variant::create(true);
- } else if (property_name == "CanRaise") {
- property = Glib::Variant::create(!IsWayland());
- } else if (property_name == "CanSetFullscreen") {
- property = Glib::Variant::create(false);
- } else if (property_name == "DesktopEntry") {
- property = Glib::Variant::create(
- QGuiApplication::desktopFileName().chopped(8).toStdString());
- } else if (property_name == "Fullscreen") {
- property = Glib::Variant::create(false);
- } else if (property_name == "HasTrackList") {
- property = Glib::Variant::create(false);
- } else if (property_name == "Identity") {
- property = Glib::Variant::create(
- std::string(AppName));
- } else if (property_name == "SupportedMimeTypes") {
- property = Glib::Variant>::create({});
- } else if (property_name == "SupportedUriSchemes") {
- property = Glib::Variant>::create({});
- } else if (property_name == "CanControl") {
- property = Glib::Variant::create(true);
- } else if (property_name == "CanGoNext") {
- property = Glib::Variant::create(true);
- } else if (property_name == "CanGoPrevious") {
- property = Glib::Variant::create(true);
- } else if (property_name == "CanPause") {
- property = Glib::Variant::create(true);
- } else if (property_name == "CanPlay") {
- property = Glib::Variant::create(true);
- } else if (property_name == "CanSeek") {
- property = Glib::Variant::create(true);
- } else if (property_name == "MaximumRate") {
- property = Glib::Variant::create(1.0);
- } else if (property_name == "Metadata") {
- const auto state = Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType());
-
- const auto trackView = [&]() -> std::shared_ptr {
- const auto audioData = state.id.audio();
- if (audioData && audioData->isSongWithCover()) {
- return audioData->activeMediaView();
- }
- return nullptr;
- }();
-
- property = base::Platform::MakeGlibVariant(
- CreateMetadata(state, trackView.get()));
- } else if (property_name == "MinimumRate") {
- property = Glib::Variant::create(1.0);
- } else if (property_name == "PlaybackStatus") {
- const auto state = Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType());
-
- property = Glib::Variant::create(
- PlaybackStatus(state.state));
- } else if (property_name == "Position") {
- const auto state = Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType());
-
- property = Glib::Variant::create(state.position * 1000);
- } else if (property_name == "Rate") {
- property = Glib::Variant::create(1.0);
- } else if (property_name == "Volume") {
- property = Glib::Variant::create(
- Core::App().settings().songVolume());
- }
- });
-}
-
-bool HandleSetProperty(
- const Glib::RefPtr &connection,
- const Glib::ustring &sender,
- const Glib::ustring &object_path,
- const Glib::ustring &interface_name,
- const Glib::ustring &property_name,
- const Glib::VariantBase &value) {
- try {
- if (property_name == "Fullscreen") {
- } else if (property_name == "Rate") {
- } else if (property_name == "Volume") {
- Core::Sandbox::Instance().customEnterFromEventLoop([&] {
- Core::App().settings().setSongVolume(
- base::Platform::GlibVariantCast(value));
- });
- } else {
- return false;
- }
-
- return true;
- } catch (...) {
- }
-
- return false;
-}
-
-const Gio::DBus::InterfaceVTable InterfaceVTable(
- sigc::ptr_fun(&HandleMethodCall),
- sigc::ptr_fun(&HandleGetProperty),
- sigc::ptr_fun(&HandleSetProperty));
-
-void PlayerPropertyChanged(
- const Glib::ustring &name,
- const Glib::VariantBase &value) {
- try {
- const auto connection = Gio::DBus::Connection::get_sync(
- Gio::DBus::BusType::BUS_TYPE_SESSION);
-
- connection->emit_signal(
- std::string(kObjectPath),
- std::string(kPropertiesInterface),
- "PropertiesChanged",
- {},
- base::Platform::MakeGlibVariant(std::tuple{
- Glib::ustring(std::string(kPlayerInterface)),
- std::map{
- { name, value },
- },
- std::vector{},
- }));
- } catch (...) {
- }
-}
-
-void Seeked(gint64 position) {
- try {
- const auto connection = Gio::DBus::Connection::get_sync(
- Gio::DBus::BusType::BUS_TYPE_SESSION);
-
- connection->emit_signal(
- std::string(kObjectPath),
- std::string(kPlayerInterface),
- "Seeked",
- {},
- base::Platform::MakeGlibVariant(std::tuple{
- position,
- }));
- } catch (...) {
- }
-}
-
-} // namespace
-
-class MPRISSupport::Private {
-public:
- void updateTrackState(const Media::Player::TrackState &state);
-
- Glib::RefPtr dbusConnection;
- Glib::RefPtr introspectionData;
- Glib::RefPtr playerIntrospectionData;
-
- uint ownId = 0;
- uint registerId = 0;
- uint playerRegisterId = 0;
-
- Glib::ustring playbackStatus;
- gint64 position = 0;
-
- DocumentData *audioData = nullptr;
- std::shared_ptr trackView;
- Image *thumbnail = nullptr;
-
- rpl::lifetime lifetime;
-};
-
-void MPRISSupport::Private::updateTrackState(
- const Media::Player::TrackState &state) {
- const auto currentAudioData = state.id.audio();
- const auto currentPosition = state.position * 1000;
- const auto currentPlaybackStatus = PlaybackStatus(state.state);
-
- if (currentAudioData != audioData) {
- audioData = currentAudioData;
- if (audioData && audioData->isSongWithCover()) {
- trackView = audioData->createMediaView();
- thumbnail = trackView->thumbnail();
- } else {
- trackView = nullptr;
- thumbnail = nullptr;
- }
-
- PlayerPropertyChanged(
- "Metadata",
- Glib::Variant<
- std::map
- >::create(CreateMetadata(state, trackView.get())));
- }
-
- if (trackView && (trackView->thumbnail() != thumbnail)) {
- thumbnail = trackView->thumbnail();
- PlayerPropertyChanged(
- "Metadata",
- Glib::Variant<
- std::map
- >::create(CreateMetadata(state, trackView.get())));
- }
-
- if (currentPlaybackStatus != playbackStatus) {
- playbackStatus = currentPlaybackStatus;
- PlayerPropertyChanged(
- "PlaybackStatus",
- Glib::Variant::create(playbackStatus));
- }
-
- if (currentPosition != position) {
- const auto positionDifference = position - currentPosition;
- if (positionDifference > 1000000 || positionDifference < -1000000) {
- Seeked(currentPosition);
- }
-
- position = currentPosition;
- }
-}
-
-MPRISSupport::MPRISSupport()
-: _private(std::make_unique()) {
- try {
- _private->introspectionData = Gio::DBus::NodeInfo::create_for_xml(
- std::string(kIntrospectionXML));
-
- _private->playerIntrospectionData = Gio::DBus::NodeInfo::create_for_xml(
- std::string(kPlayerIntrospectionXML));
-
- _private->ownId = Gio::DBus::own_name(
- Gio::DBus::BusType::BUS_TYPE_SESSION,
- std::string(kService));
-
- _private->dbusConnection = Gio::DBus::Connection::get_sync(
- Gio::DBus::BusType::BUS_TYPE_SESSION);
-
- _private->registerId = _private->dbusConnection->register_object(
- std::string(kObjectPath),
- _private->introspectionData->lookup_interface(),
- InterfaceVTable);
-
- _private->playerRegisterId = _private->dbusConnection->register_object(
- std::string(kObjectPath),
- _private->playerIntrospectionData->lookup_interface(),
- InterfaceVTable);
-
- _private->updateTrackState(
- Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType()));
-
- Core::App().domain().active().session().downloaderTaskFinished(
- ) | rpl::start_with_next([=] {
- _private->updateTrackState(
- Media::Player::instance()->getState(
- Media::Player::instance()->getActiveType()));
- }, _private->lifetime);
-
- Media::Player::instance()->updatedNotifier(
- ) | rpl::filter([=](const Media::Player::TrackState &state) {
- return state.id.type() == Media::Player::instance()->getActiveType();
- }) | rpl::start_with_next([=](
- const Media::Player::TrackState &state) {
- _private->updateTrackState(state);
- }, _private->lifetime);
-
- Core::App().settings().songVolumeChanges(
- ) | rpl::start_with_next([=](float64 volume) {
- PlayerPropertyChanged(
- "Volume",
- Glib::Variant::create(volume));
- }, _private->lifetime);
- } catch (...) {
- }
-}
-
-MPRISSupport::~MPRISSupport() {
- if (_private->dbusConnection) {
- if (_private->playerRegisterId) {
- _private->dbusConnection->unregister_object(
- _private->playerRegisterId);
- }
-
- if (_private->registerId) {
- _private->dbusConnection->unregister_object(
- _private->registerId);
- }
- }
-
- if (_private->ownId) {
- Gio::DBus::unown_name(_private->ownId);
- }
-}
-
-} // namespace internal
-} // namespace Platform
diff --git a/Telegram/SourceFiles/ui/widgets/continuous_sliders.cpp b/Telegram/SourceFiles/ui/widgets/continuous_sliders.cpp
index ba11fc0f8..e74362b8b 100644
--- a/Telegram/SourceFiles/ui/widgets/continuous_sliders.cpp
+++ b/Telegram/SourceFiles/ui/widgets/continuous_sliders.cpp
@@ -268,7 +268,9 @@ void MediaSlider::paintEvent(QPaintEvent *e) {
+ (alwaysSeekSize / 2.)
+ value * (length - alwaysSeekSize))
: qRound(from + value * length);
- const auto till = std::max(mid, qRound(from + receivedTill * length));
+ const auto till = horizontal
+ ? std::max(mid, qRound(from + receivedTill * length))
+ : mid;
const auto end = from + length;
const auto activeFg = disabled
? _st.activeFgDisabled
diff --git a/Telegram/build/version b/Telegram/build/version
index 690117d47..00b5e08fa 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 2007010
-AppVersionStrMajor 2.7
-AppVersionStrSmall 2.7.10
-AppVersionStr 2.7.10
-BetaChannel 1
+AppVersion 2008001
+AppVersionStrMajor 2.8
+AppVersionStrSmall 2.8.1
+AppVersionStr 2.8.1
+BetaChannel 0
AlphaVersion 0
-AppVersionOriginal 2.7.10.beta
+AppVersionOriginal 2.8.1
diff --git a/Telegram/lib_base b/Telegram/lib_base
index 8606220f0..4e6e96106 160000
--- a/Telegram/lib_base
+++ b/Telegram/lib_base
@@ -1 +1 @@
-Subproject commit 8606220f04b83bf5dfe750d7459a7ae8e79866ef
+Subproject commit 4e6e961064473c7f656aa6754ef2a25a4066c84a
diff --git a/changelog.txt b/changelog.txt
index d7792af0d..93469a964 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,15 @@
+2.8.1 (26.06.21)
+
+- Fix crash in audio player volume slider.
+
+2.8 (24.06.21)
+
+- Start video conferences from Voice Chats in any group.
+- Share your screen or video from your camera with up to 30 participants (limit to be increased soon).
+- Talk without video with an unlimited number of participants.
+- Create voice chats from the info page of any group where you are an admin.
+- Group video calls are supported natively on all devices, including iPads and laptops.
+
2.7.10 beta (22.06.21)
- Added ability to mix together bold, italic and other formatting.
diff --git a/cmake b/cmake
index 10efb6461..57e8f3f66 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 10efb6461fb585c5686dc0b7b05b8b572eb0b9bd
+Subproject commit 57e8f3f6669c430f3d515d083530aba2f1f33271
diff --git a/docs/building-msvc-x64.md b/docs/building-msvc-x64.md
index b9157a10e..b64f425c4 100644
--- a/docs/building-msvc-x64.md
+++ b/docs/building-msvc-x64.md
@@ -34,7 +34,7 @@ Open **x64 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath***
cd ThirdParty
git clone https://github.com/desktop-app/patches.git
cd patches
- git checkout ad34925
+ git checkout 7f8a282
cd ../
git clone https://chromium.googlesource.com/external/gyp
cd gyp
@@ -55,7 +55,7 @@ Open **x64 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath***
git clone https://github.com/desktop-app/patches.git
cd patches
- git checkout ad34925
+ git checkout 7f8a282
cd ..
git clone https://github.com/desktop-app/lzma.git
diff --git a/docs/building-msvc.md b/docs/building-msvc.md
index 4b69bdda4..1aba4c4bc 100644
--- a/docs/building-msvc.md
+++ b/docs/building-msvc.md
@@ -34,7 +34,7 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath***
cd ThirdParty
git clone https://github.com/desktop-app/patches.git
cd patches
- git checkout ad34925
+ git checkout 7f8a282
cd ../
git clone https://chromium.googlesource.com/external/gyp
cd gyp
@@ -55,7 +55,7 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath***
git clone https://github.com/desktop-app/patches.git
cd patches
- git checkout ad34925
+ git checkout 7f8a282
cd ..
git clone https://github.com/desktop-app/lzma.git
diff --git a/docs/building-xcode.md b/docs/building-xcode.md
index a3854402a..284124cf1 100644
--- a/docs/building-xcode.md
+++ b/docs/building-xcode.md
@@ -268,8 +268,8 @@ Go to ***BuildPath*** and run
cd ../../..
build/gyp_crashpad.py -Dmac_deployment_target=10.10
- ninja -C out/Debug
- ninja -C out/Release
+ ninja -C out/Debug base crashpad_util crashpad_client crashpad_handler
+ ninja -C out/Release base crashpad_util crashpad_client crashpad_handler
cd ..
git clone git://code.qt.io/qt/qt5.git qt_5_15_2