diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 540809a09..8b6ee2b29 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -390,7 +390,7 @@ jobs: run: | cd $LibrariesPath - git clone -b 1.16 https://gitlab.freedesktop.org/wayland/wayland + git clone -b 1.18.0 https://gitlab.freedesktop.org/wayland/wayland cd wayland ./autogen.sh \ --enable-static \ diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index ec5d33619..d96ae3e77 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -411,7 +411,7 @@ jobs: uses: actions/cache@v1 with: path: ${{ env.LibrariesPath }}/qt-cache - key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8.diff') }} + key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8/*') }} - name: Use cached Qt 5.12.8. if: steps.cache-qt.outputs.cache-hit == 'true' run: | diff --git a/.github/workflows/snap.yml b/.github/workflows/snap.yml index 8b4cf758c..fd9192cb8 100644 --- a/.github/workflows/snap.yml +++ b/.github/workflows/snap.yml @@ -13,7 +13,6 @@ on: - '!.github/workflows/snap.yml' - 'Telegram/build/**' - 'Telegram/Patches/**' - - '!Telegram/Patches/ffmpeg.diff' - 'Telegram/Resources/uwp/**' - 'Telegram/Resources/winrc/**' - 'Telegram/SourceFiles/platform/win/**' @@ -33,7 +32,6 @@ on: - '!.github/workflows/snap.yml' - 'Telegram/build/**' - 'Telegram/Patches/**' - - '!Telegram/Patches/ffmpeg.diff' - 'Telegram/Resources/uwp/**' - 'Telegram/Resources/winrc/**' - 'Telegram/SourceFiles/platform/win/**' @@ -45,13 +43,13 @@ on: jobs: linux: - name: Ubuntu 18.04 + name: Ubuntu 20.04 if: > !(github.event_name == 'push' && contains(github.event.head_commit.message, '[skip ci]')) && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: UPLOAD_ARTIFACT: "false" diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 898c38880..b229199d4 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -301,7 +301,7 @@ jobs: uses: actions/cache@v1 with: path: ${{ env.LibrariesPath }}/Qt-5.12.8 - key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8.diff') }} + key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8/*') }} - name: Configure Qt 5.12.8. if: steps.cache-qt.outputs.cache-hit != 'true' shell: cmd @@ -397,7 +397,7 @@ jobs: if: env.UPLOAD_ARTIFACT == 'true' shell: cmd run: | - cd %REPO_NAME%\build\bin + cd %REPO_NAME%\out\Debug mkdir artifact move Kotatogram.exe artifact/ move Updater.exe artifact/ @@ -406,4 +406,4 @@ jobs: if: env.UPLOAD_ARTIFACT == 'true' with: name: ${{ env.ARTIFACT_NAME }} - path: ${{ env.REPO_NAME }}\build\bin\artifact\ + path: ${{ env.REPO_NAME }}\out\Debug\artifact\ diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index dd05ac060..461f675c7 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1224,7 +1224,7 @@ endif() set_target_properties(Telegram PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder}) -if ((NOT DESKTOP_APP_DISABLE_AUTOUPDATE OR NOT LINUX) AND NOT build_macstore AND NOT build_winstore) +if ((NOT DESKTOP_APP_DISABLE_AUTOUPDATE OR APPLE) AND NOT build_macstore AND NOT build_winstore) add_executable(Updater WIN32) init_target(Updater) diff --git a/Telegram/Patches/ffmpeg.diff b/Telegram/Patches/ffmpeg.diff deleted file mode 100644 index b5ab619fe..000000000 --- a/Telegram/Patches/ffmpeg.diff +++ /dev/null @@ -1,225 +0,0 @@ -diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile -index 00f93bf59f..52da7036f3 100644 ---- a/libavcodec/aarch64/Makefile -+++ b/libavcodec/aarch64/Makefile -@@ -6,6 +6,7 @@ OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o - OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_init.o - OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_init_aarch64.o - OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_init_aarch64.o -+OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o - OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_init.o - OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o - OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp_init.o -@@ -21,6 +22,7 @@ OBJS-$(CONFIG_VC1DSP) += aarch64/vc1dsp_init_aarch64.o - OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o - OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9dsp_init_10bpp_aarch64.o \ - aarch64/vp9dsp_init_12bpp_aarch64.o \ -+ aarch64/vp9mc_aarch64.o \ - aarch64/vp9dsp_init_aarch64.o - - # ARMv8 optimizations -@@ -41,8 +43,7 @@ NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o - NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \ - aarch64/hpeldsp_neon.o - NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o --NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o \ -- aarch64/simple_idct_neon.o -+NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/simple_idct_neon.o - NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o - NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o - NEON-OBJS-$(CONFIG_VP8DSP) += aarch64/vp8dsp_neon.o -diff --git a/libavcodec/aarch64/idctdsp_init_aarch64.c b/libavcodec/aarch64/idctdsp_init_aarch64.c -index 0406e60830..742a3372e3 100644 ---- a/libavcodec/aarch64/idctdsp_init_aarch64.c -+++ b/libavcodec/aarch64/idctdsp_init_aarch64.c -@@ -21,6 +21,8 @@ - */ - - #include "libavutil/attributes.h" -+#include "libavutil/cpu.h" -+#include "libavutil/arm/cpu.h" - #include "libavcodec/avcodec.h" - #include "libavcodec/idctdsp.h" - #include "idct.h" -@@ -28,7 +30,9 @@ - av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, - unsigned high_bit_depth) - { -- if (!avctx->lowres && !high_bit_depth) { -+ int cpu_flags = av_get_cpu_flags(); -+ -+ if (have_neon(cpu_flags) && !avctx->lowres && !high_bit_depth) { - if (avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_SIMPLEAUTO || - avctx->idct_algo == FF_IDCT_SIMPLENEON) { -diff --git a/libavcodec/aarch64/vp9mc_16bpp_neon.S b/libavcodec/aarch64/vp9mc_16bpp_neon.S -index cac6428709..53b372c262 100644 ---- a/libavcodec/aarch64/vp9mc_16bpp_neon.S -+++ b/libavcodec/aarch64/vp9mc_16bpp_neon.S -@@ -25,31 +25,6 @@ - // const uint8_t *ref, ptrdiff_t ref_stride, - // int h, int mx, int my); - --function ff_vp9_copy128_aarch64, export=1 --1: -- ldp x5, x6, [x2] -- ldp x7, x8, [x2, #16] -- stp x5, x6, [x0] -- ldp x9, x10, [x2, #32] -- stp x7, x8, [x0, #16] -- subs w4, w4, #1 -- ldp x11, x12, [x2, #48] -- stp x9, x10, [x0, #32] -- stp x11, x12, [x0, #48] -- ldp x5, x6, [x2, #64] -- ldp x7, x8, [x2, #80] -- stp x5, x6, [x0, #64] -- ldp x9, x10, [x2, #96] -- stp x7, x8, [x0, #80] -- ldp x11, x12, [x2, #112] -- stp x9, x10, [x0, #96] -- stp x11, x12, [x0, #112] -- add x2, x2, x3 -- add x0, x0, x1 -- b.ne 1b -- ret --endfunc -- - function ff_vp9_avg64_16_neon, export=1 - mov x5, x0 - sub x1, x1, #64 -diff --git a/libavcodec/aarch64/vp9mc_aarch64.S b/libavcodec/aarch64/vp9mc_aarch64.S -new file mode 100644 -index 0000000000..f17a8cf04a ---- /dev/null -+++ b/libavcodec/aarch64/vp9mc_aarch64.S -@@ -0,0 +1,81 @@ -+/* -+ * Copyright (c) 2016 Google Inc. -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "libavutil/aarch64/asm.S" -+ -+// All public functions in this file have the following signature: -+// typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, -+// const uint8_t *ref, ptrdiff_t ref_stride, -+// int h, int mx, int my); -+ -+function ff_vp9_copy128_aarch64, export=1 -+1: -+ ldp x5, x6, [x2] -+ ldp x7, x8, [x2, #16] -+ stp x5, x6, [x0] -+ ldp x9, x10, [x2, #32] -+ stp x7, x8, [x0, #16] -+ subs w4, w4, #1 -+ ldp x11, x12, [x2, #48] -+ stp x9, x10, [x0, #32] -+ stp x11, x12, [x0, #48] -+ ldp x5, x6, [x2, #64] -+ ldp x7, x8, [x2, #80] -+ stp x5, x6, [x0, #64] -+ ldp x9, x10, [x2, #96] -+ stp x7, x8, [x0, #80] -+ ldp x11, x12, [x2, #112] -+ stp x9, x10, [x0, #96] -+ stp x11, x12, [x0, #112] -+ add x2, x2, x3 -+ add x0, x0, x1 -+ b.ne 1b -+ ret -+endfunc -+ -+function ff_vp9_copy64_aarch64, export=1 -+1: -+ ldp x5, x6, [x2] -+ ldp x7, x8, [x2, #16] -+ stp x5, x6, [x0] -+ ldp x9, x10, [x2, #32] -+ stp x7, x8, [x0, #16] -+ subs w4, w4, #1 -+ ldp x11, x12, [x2, #48] -+ stp x9, x10, [x0, #32] -+ stp x11, x12, [x0, #48] -+ add x2, x2, x3 -+ add x0, x0, x1 -+ b.ne 1b -+ ret -+endfunc -+ -+function ff_vp9_copy32_aarch64, export=1 -+1: -+ ldp x5, x6, [x2] -+ ldp x7, x8, [x2, #16] -+ stp x5, x6, [x0] -+ subs w4, w4, #1 -+ stp x7, x8, [x0, #16] -+ add x2, x2, x3 -+ add x0, x0, x1 -+ b.ne 1b -+ ret -+endfunc -diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S -index f67624ca04..abf2bae9db 100644 ---- a/libavcodec/aarch64/vp9mc_neon.S -+++ b/libavcodec/aarch64/vp9mc_neon.S -@@ -25,23 +25,6 @@ - // const uint8_t *ref, ptrdiff_t ref_stride, - // int h, int mx, int my); - --function ff_vp9_copy64_aarch64, export=1 --1: -- ldp x5, x6, [x2] -- ldp x7, x8, [x2, #16] -- stp x5, x6, [x0] -- ldp x9, x10, [x2, #32] -- stp x7, x8, [x0, #16] -- subs w4, w4, #1 -- ldp x11, x12, [x2, #48] -- stp x9, x10, [x0, #32] -- stp x11, x12, [x0, #48] -- add x2, x2, x3 -- add x0, x0, x1 -- b.ne 1b -- ret --endfunc -- - function ff_vp9_avg64_neon, export=1 - mov x5, x0 - 1: -@@ -64,19 +47,6 @@ function ff_vp9_avg64_neon, export=1 - ret - endfunc - --function ff_vp9_copy32_aarch64, export=1 --1: -- ldp x5, x6, [x2] -- ldp x7, x8, [x2, #16] -- stp x5, x6, [x0] -- subs w4, w4, #1 -- stp x7, x8, [x0, #16] -- add x2, x2, x3 -- add x0, x0, x1 -- b.ne 1b -- ret --endfunc -- - function ff_vp9_avg32_neon, export=1 - 1: - ld1 {v2.16b, v3.16b}, [x2], x3 diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 10caa4f8b..a3310c7f1 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -9,7 +9,7 @@ + Version="2.1.13.0" /> Telegram Desktop Telegram FZ-LLC diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 269096c02..9b5d5dfc4 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,1,10,0 - PRODUCTVERSION 2,1,10,0 + FILEVERSION 2,1,13,0 + PRODUCTVERSION 2,1,13,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop" - VALUE "FileVersion", "2.1.10.0" + VALUE "FileVersion", "2.1.13.0" VALUE "LegalCopyright", "Copyright (C) 2014-2020" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "2.1.10.0" + VALUE "ProductVersion", "2.1.13.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index d371e8728..b8ed82512 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,1,10,0 - PRODUCTVERSION 2,1,10,0 + FILEVERSION 2,1,13,0 + PRODUCTVERSION 2,1,13,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop Updater" - VALUE "FileVersion", "2.1.10.0" + VALUE "FileVersion", "2.1.13.0" VALUE "LegalCopyright", "Copyright (C) 2014-2020" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "2.1.10.0" + VALUE "ProductVersion", "2.1.13.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/_other/packer.cpp b/Telegram/SourceFiles/_other/packer.cpp index 79d0d5a8e..9987deda9 100644 --- a/Telegram/SourceFiles/_other/packer.cpp +++ b/Telegram/SourceFiles/_other/packer.cpp @@ -254,7 +254,7 @@ int main(int argc, char *argv[]) } QByteArray inner = f.readAll(); stream << name << quint32(inner.size()) << inner; -#if defined Q_OS_MAC || defined Q_OS_LINUX +#ifdef Q_OS_UNIX stream << (QFileInfo(fullName).isExecutable() ? true : false); #endif } @@ -467,10 +467,12 @@ int main(int argc, char *argv[]) QString outName(QString("tupdate%1").arg(AlphaVersion ? AlphaVersion : version)); #elif defined Q_OS_MAC QString outName((targetosx ? QString("tosxupd%1") : QString("tmacupd%1")).arg(AlphaVersion ? AlphaVersion : version)); -#elif defined Q_OS_LINUX32 +#elif defined Q_OS_UNIX +#ifndef _LP64 QString outName(QString("tlinux32upd%1").arg(AlphaVersion ? AlphaVersion : version)); -#elif defined Q_OS_LINUX64 +#else QString outName(QString("tlinuxupd%1").arg(AlphaVersion ? AlphaVersion : version)); +#endif #else #error Unknown platform! #endif diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 1e8627445..b0b8b4cc9 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -93,6 +93,7 @@ void SendExistingMedia( }; TextUtilities::Trim(caption); auto sentEntities = EntitiesToMTP( + session, caption.entities, ConvertOption::SkipLocal); if (!sentEntities.v.isEmpty()) { diff --git a/Telegram/SourceFiles/api/api_text_entities.cpp b/Telegram/SourceFiles/api/api_text_entities.cpp index 919a18c63..18acbe2f1 100644 --- a/Telegram/SourceFiles/api/api_text_entities.cpp +++ b/Telegram/SourceFiles/api/api_text_entities.cpp @@ -18,11 +18,13 @@ using namespace TextUtilities; } // namespace -EntitiesInText EntitiesFromMTP(const QVector &entities) { +EntitiesInText EntitiesFromMTP( + Main::Session *session, + const QVector &entities) { auto result = EntitiesInText(); if (!entities.isEmpty()) { result.reserve(entities.size()); - for_const (auto &entity, entities) { + for (const auto &entity : entities) { switch (entity.type()) { case mtpc_messageEntityUrl: { auto &d = entity.c_messageEntityUrl(); result.push_back({ EntityType::Url, d.voffset().v, d.vlength().v }); } break; case mtpc_messageEntityTextUrl: { auto &d = entity.c_messageEntityTextUrl(); result.push_back({ EntityType::CustomUrl, d.voffset().v, d.vlength().v, Clean(qs(d.vurl())) }); } break; @@ -32,28 +34,30 @@ EntitiesInText EntitiesFromMTP(const QVector &entities) { case mtpc_messageEntityPhone: break; // Skipping phones. case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break; case mtpc_messageEntityMentionName: { - auto &d = entity.c_messageEntityMentionName(); - auto data = [&d] { - if (auto user = Auth().data().userLoaded(d.vuser_id().v)) { - return MentionNameDataFromFields({ - d.vuser_id().v, - user->accessHash() }); + const auto &d = entity.c_messageEntityMentionName(); + const auto data = [&] { + if (session) { + if (const auto user = session->data().userLoaded(d.vuser_id().v)) { + return MentionNameDataFromFields({ + d.vuser_id().v, + user->accessHash() }); + } } return MentionNameDataFromFields(d.vuser_id().v); - }; - result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data() }); + }(); + result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data }); } break; case mtpc_inputMessageEntityMentionName: { - auto &d = entity.c_inputMessageEntityMentionName(); - auto data = ([&d]() -> QString { - if (d.vuser_id().type() == mtpc_inputUserSelf) { - return MentionNameDataFromFields(Auth().userId()); + const auto &d = entity.c_inputMessageEntityMentionName(); + const auto data = [&] { + if (session && d.vuser_id().type() == mtpc_inputUserSelf) { + return MentionNameDataFromFields(session->userId()); } else if (d.vuser_id().type() == mtpc_inputUser) { auto &user = d.vuser_id().c_inputUser(); return MentionNameDataFromFields({ user.vuser_id().v, user.vaccess_hash().v }); } return QString(); - })(); + }(); if (!data.isEmpty()) { result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data }); } @@ -74,11 +78,12 @@ EntitiesInText EntitiesFromMTP(const QVector &entities) { } MTPVector EntitiesToMTP( + not_null session, const EntitiesInText &entities, ConvertOption option) { auto v = QVector(); v.reserve(entities.size()); - for_const (auto &entity, entities) { + for (const auto &entity : entities) { if (entity.length() <= 0) continue; if (option == ConvertOption::SkipLocal && entity.type() != EntityType::Bold @@ -103,15 +108,15 @@ MTPVector EntitiesToMTP( case EntityType::Cashtag: v.push_back(MTP_messageEntityCashtag(offset, length)); break; case EntityType::Mention: v.push_back(MTP_messageEntityMention(offset, length)); break; case EntityType::MentionName: { - auto inputUser = ([](const QString &data) -> MTPInputUser { + auto inputUser = [&](const QString &data) -> MTPInputUser { auto fields = MentionNameDataToFields(data); - if (fields.userId == Auth().userId()) { + if (session && fields.userId == session->userId()) { return MTP_inputUserSelf(); } else if (fields.userId) { return MTP_inputUser(MTP_int(fields.userId), MTP_long(fields.accessHash)); } return MTP_inputUserEmpty(); - })(entity.data()); + }(entity.data()); if (inputUser.type() != mtpc_inputUserEmpty) { v.push_back(MTP_inputMessageEntityMentionName(offset, length, inputUser)); } diff --git a/Telegram/SourceFiles/api/api_text_entities.h b/Telegram/SourceFiles/api/api_text_entities.h index 836a3d77a..95348d616 100644 --- a/Telegram/SourceFiles/api/api_text_entities.h +++ b/Telegram/SourceFiles/api/api_text_entities.h @@ -9,14 +9,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_entity.h" +namespace Main { +class Session; +} // namespace Main + namespace Api { -EntitiesInText EntitiesFromMTP(const QVector &entities); enum class ConvertOption { WithLocal, SkipLocal, }; -MTPVector EntitiesToMTP( + +[[nodiscard]] EntitiesInText EntitiesFromMTP( + Main::Session *session, + const QVector &entities); + +[[nodiscard]] MTPVector EntitiesToMTP( + not_null session, const EntitiesInText &entities, ConvertOption option = ConvertOption::WithLocal); diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 24fb0ea18..92c4507be 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -411,7 +411,7 @@ void ApiWrap::requestTermsUpdate() { const auto &terms = data.vterms_of_service(); const auto &fields = terms.c_help_termsOfService(); Core::App().lockByTerms( - Window::TermsLock::FromMTP(fields)); + Window::TermsLock::FromMTP(&session(), fields)); requestNext(data); } break; default: Unexpected("Type in requestTermsUpdate()."); @@ -2442,6 +2442,7 @@ void ApiWrap::saveDraftsToCloud() { flags |= MTPmessages_SaveDraft::Flag::f_entities; } auto entities = Api::EntitiesToMTP( + &session(), TextUtilities::ConvertTextTagsToEntities(textWithTags.tags), Api::ConvertOption::SkipLocal); @@ -4674,6 +4675,7 @@ void ApiWrap::editUploadedFile( } auto sentEntities = Api::EntitiesToMTP( + &session(), item->originalText().entities, Api::ConvertOption::SkipLocal); @@ -4826,8 +4828,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) { if (silentPost) { sendFlags |= MTPmessages_SendMessage::Flag::f_silent; } - auto localEntities = Api::EntitiesToMTP(sending.entities); + auto localEntities = Api::EntitiesToMTP( + &session(), + sending.entities); auto sentEntities = Api::EntitiesToMTP( + &session(), sending.entities, Api::ConvertOption::SkipLocal); if (!sentEntities.v.isEmpty()) { @@ -5118,6 +5123,7 @@ void ApiWrap::sendMediaWithRandomId( auto caption = item->originalText(); TextUtilities::Trim(caption); auto sentEntities = Api::EntitiesToMTP( + &session(), caption.entities, Api::ConvertOption::SkipLocal); @@ -5794,6 +5800,7 @@ void ApiWrap::rescheduleMessage( Api::SendOptions options) { const auto text = item->originalText().text; const auto sentEntities = Api::EntitiesToMTP( + &session(), item->originalText().entities, Api::ConvertOption::SkipLocal); const auto media = item->media(); diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 78057584c..f07b4e577 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document_media.h" #include "history/history.h" #include "history/history_item.h" +#include "platform/platform_specific.h" #include "lang/lang_keys.h" #include "layout.h" #include "media/streaming/media_streaming_instance.h" @@ -327,10 +328,6 @@ EditCaptionBox::EditCaptionBox( ) | rpl::start_with_next([&](bool checked) { _asFile = checked; }, _wayWrap->lifetime()); - - if (_animated) { - prepareStreamedPreview(); - } } EditCaptionBox::~EditCaptionBox() = default; @@ -590,6 +587,10 @@ void EditCaptionBox::createEditMediaButton() { } void EditCaptionBox::prepare() { + if (_animated) { + prepareStreamedPreview(); + } + addButton(tr::lng_settings_save(), [this] { save(); }); if (_isAllowedEditMedia) { createEditMediaButton(); @@ -656,7 +657,10 @@ bool EditCaptionBox::fileFromClipboard(not_null data) { if (result.error == Error::None) { return result; } else if (data->hasImage()) { - auto image = qvariant_cast(data->imageData()); + auto image = Platform::GetImageFromClipboard(); + if (image.isNull()) { + image = qvariant_cast(data->imageData()); + } if (!image.isNull()) { _isImage = true; _photo = true; @@ -934,6 +938,7 @@ void EditCaptionBox::save() { TextUtilities::Trim(sending); const auto sentEntities = Api::EntitiesToMTP( + &item->history()->session(), sending.entities, Api::ConvertOption::SkipLocal); if (!sentEntities.v.isEmpty()) { diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 2f1df25c7..3fc3a6df2 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/send_files_box.h" +#include "platform/platform_specific.h" #include "lang/lang_keys.h" #include "storage/localstorage.h" #include "storage/storage_media_prepare.h" @@ -2168,7 +2169,10 @@ bool SendFilesBox::addFiles(not_null data) { if (result.error == Storage::PreparedList::Error::None) { return result; } else if (data->hasImage()) { - auto image = qvariant_cast(data->imageData()); + auto image = Platform::GetImageFromClipboard(); + if (image.isNull()) { + image = qvariant_cast(data->imageData()); + } if (!image.isNull()) { return Storage::PrepareMediaFromImage( std::move(image), diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 9e28c43d5..8e21da0d1 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -326,7 +326,9 @@ void StickersBox::prepare() { _session->api().updateStickers(); if (_installed.widget()) { - connect(_installed.widget(), SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int))); + connect(_installed.widget(), &Inner::draggingScrollDelta, [=](int delta) { + scrollByDraggingDelta(delta); + }); if (!_megagroupSet) { boxClosing() | rpl::start_with_next([=] { saveChanges(); diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 0ac1a04c8..945ad2f1a 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -798,13 +798,9 @@ void Application::notifyFileDialogShown(bool shown) { } QWidget *Application::getModalParent() { -#ifdef Q_OS_LINUX return Platform::IsWayland() ? App::wnd() : nullptr; -#endif // Q_OS_LINUX - - return nullptr; } diff --git a/Telegram/SourceFiles/core/crash_reports.cpp b/Telegram/SourceFiles/core/crash_reports.cpp index cc02f7cb6..8b3a8932f 100644 --- a/Telegram/SourceFiles/core/crash_reports.cpp +++ b/Telegram/SourceFiles/core/crash_reports.cpp @@ -39,7 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "client/crashpad_client.h" #endif // else for MAC_USE_BREAKPAD -#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC #include #include @@ -47,7 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "client/linux/handler/exception_handler.h" -#endif // Q_OS_LINUX64 || Q_OS_LINUX32 +#endif // Q_OS_UNIX #endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS @@ -140,7 +140,7 @@ QMutex ReportingMutex; const char *BreakpadDumpPath = nullptr; const wchar_t *BreakpadDumpPathW = nullptr; -#if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#ifdef Q_OS_UNIX struct sigaction SIG_def[32]; void SignalHandler(int signum, siginfo_t *info, void *ucontext) { @@ -148,9 +148,9 @@ void SignalHandler(int signum, siginfo_t *info, void *ucontext) { sigaction(signum, &SIG_def[signum], 0); } -#else // Q_OS_MAC || Q_OS_LINUX32 || Q_OS_LINUX64 +#else // Q_OS_UNIX void SignalHandler(int signum) { -#endif // else for Q_OS_MAC || Q_OS_LINUX || Q_OS_LINUX64 +#endif // else for Q_OS_UNIX const char* name = 0; switch (signum) { @@ -212,7 +212,7 @@ void SignalHandler(int signum) { } // see https://github.com/benbjohnson/bandicoot -#if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#ifdef Q_OS_UNIX ucontext_t *uc = (ucontext_t*)ucontext; void *caller = 0; @@ -276,9 +276,9 @@ void SignalHandler(int signum) { backtrace_symbols_fd(addresses, size, ReportFileNo); -#else // Q_OS_MAC || Q_OS_LINUX32 || Q_OS_LINUX64 +#else // Q_OS_UNIX dump() << "\nBacktrace omitted.\n"; -#endif // else for Q_OS_MAC || Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // else for Q_OS_UNIX dump() << "\n"; @@ -294,9 +294,9 @@ google_breakpad::ExceptionHandler* BreakpadExceptionHandler = 0; bool DumpCallback(const wchar_t* _dump_dir, const wchar_t* _minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool success) #elif defined Q_OS_MAC // Q_OS_WIN bool DumpCallback(const char* _dump_dir, const char* _minidump_id, void *context, bool success) -#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context, bool success) -#endif // Q_OS_LINUX64 || Q_OS_LINUX32 +#endif // Q_OS_UNIX { if (CrashLogged) return success; CrashLogged = true; @@ -392,7 +392,7 @@ void StartCatching(not_null launcher) { crashpad_client.UseHandler(); } #endif // else for MAC_USE_BREAKPAD -#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 +#elif defined Q_OS_UNIX BreakpadExceptionHandler = new google_breakpad::ExceptionHandler( google_breakpad::MinidumpDescriptor(QFile::encodeName(dumpspath).toStdString()), /*FilterCallback*/ 0, @@ -401,7 +401,7 @@ void StartCatching(not_null launcher) { true, -1 ); -#endif // Q_OS_LINUX64 || Q_OS_LINUX32 +#endif // Q_OS_UNIX #endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS } diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp index 284fe2609..275597523 100644 --- a/Telegram/SourceFiles/core/launcher.cpp +++ b/Telegram/SourceFiles/core/launcher.cpp @@ -291,7 +291,7 @@ void Launcher::init() { QApplication::setApplicationName(qsl("KotatogramDesktop")); -#if defined(Q_OS_LINUX) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) +#if defined Q_OS_UNIX && !defined Q_OS_MAC && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) QApplication::setDesktopFileName(Platform::GetLauncherFilename()); #endif diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index 22659ec1d..bd80fd2dc 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -392,7 +392,9 @@ bool HandleUnknown( const auto callback = [=](const MTPDhelp_deepLinkInfo &result) { const auto text = TextWithEntities{ qs(result.vmessage()), - Api::EntitiesFromMTP(result.ventities().value_or_empty()) + Api::EntitiesFromMTP( + session, + result.ventities().value_or_empty()) }; if (result.is_update_app()) { const auto box = std::make_shared>(); diff --git a/Telegram/SourceFiles/core/sandbox.cpp b/Telegram/SourceFiles/core/sandbox.cpp index da33fa951..84ad8a668 100644 --- a/Telegram/SourceFiles/core/sandbox.cpp +++ b/Telegram/SourceFiles/core/sandbox.cpp @@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "facades.h" #include "app.h" +#include #include namespace Core { @@ -84,9 +85,9 @@ Sandbox::Sandbox( : QApplication(argc, argv) , _mainThreadId(QThread::currentThreadId()) , _handleObservables([=] { - Expects(_application != nullptr); - - _application->call_handleObservables(); + if (_application) { + _application->call_handleObservables(); + } }) , _launcher(launcher) { } @@ -132,6 +133,19 @@ int Sandbox::start() { }); }); + // https://github.com/telegramdesktop/tdesktop/issues/948 + // and https://github.com/telegramdesktop/tdesktop/issues/5022 + const auto restartHint = [](QSessionManager &manager) { + manager.setRestartHint(QSessionManager::RestartNever); + }; + + connect( + this, + &QGuiApplication::saveStateRequest, + this, + restartHint, + Qt::DirectConnection); + if (cManyInstance()) { LOG(("Many instance allowed, starting...")); singleInstanceChecked(); diff --git a/Telegram/SourceFiles/core/ui_integration.cpp b/Telegram/SourceFiles/core/ui_integration.cpp index e330885a3..3596beb9d 100644 --- a/Telegram/SourceFiles/core/ui_integration.cpp +++ b/Telegram/SourceFiles/core/ui_integration.cpp @@ -79,68 +79,68 @@ void UiIntegration::startFontsEnd() { } std::shared_ptr UiIntegration::createLinkHandler( - EntityType type, - const QString &text, - const QString &data, - const TextParseOptions &options) { - switch (type) { + const EntityLinkData &data, + const std::any &context) { + const auto my = std::any_cast(&context); + switch (data.type) { case EntityType::Url: - return (!data.isEmpty() && UrlClickHandler::IsSuspicious(data)) - ? std::make_shared(data) - : nullptr; + return (!data.data.isEmpty() + && UrlClickHandler::IsSuspicious(data.data)) + ? std::make_shared(data.data) + : Integration::createLinkHandler(data, context); case EntityType::CustomUrl: - return !data.isEmpty() - ? std::make_shared(data) - : nullptr; + return !data.data.isEmpty() + ? std::make_shared(data.data) + : Integration::createLinkHandler(data, context); case EntityType::BotCommand: - return std::make_shared(data); + return std::make_shared(data.data); case EntityType::Hashtag: - if (options.flags & TextTwitterMentions) { + if (my && my->type == HashtagMentionType::Twitter) { return std::make_shared( (qsl("https://twitter.com/hashtag/") - + data.mid(1) + + data.data.mid(1) + qsl("?src=hash")), true); - } else if (options.flags & TextInstagramMentions) { + } else if (my && my->type == HashtagMentionType::Instagram) { return std::make_shared( (qsl("https://instagram.com/explore/tags/") - + data.mid(1) + + data.data.mid(1) + '/'), true); } - return std::make_shared(data); + return std::make_shared(data.data); case EntityType::Cashtag: - return std::make_shared(data); + return std::make_shared(data.data); case EntityType::Mention: - if (options.flags & TextTwitterMentions) { + if (my && my->type == HashtagMentionType::Twitter) { return std::make_shared( - qsl("https://twitter.com/") + data.mid(1), + qsl("https://twitter.com/") + data.data.mid(1), true); - } else if (options.flags & TextInstagramMentions) { + } else if (my && my->type == HashtagMentionType::Instagram) { return std::make_shared( - qsl("https://instagram.com/") + data.mid(1) + '/', + qsl("https://instagram.com/") + data.data.mid(1) + '/', true); } - return std::make_shared(data); + return std::make_shared(data.data); case EntityType::MentionName: { - auto fields = TextUtilities::MentionNameDataToFields(data); + auto fields = TextUtilities::MentionNameDataToFields(data.data); if (fields.userId) { return std::make_shared( - text, + data.text, fields.userId, fields.accessHash); } else { - LOG(("Bad mention name: %1").arg(data)); + LOG(("Bad mention name: %1").arg(data.data)); } } break; } - return nullptr; + return Integration::createLinkHandler(data, context); } bool UiIntegration::handleUrlClick( diff --git a/Telegram/SourceFiles/core/ui_integration.h b/Telegram/SourceFiles/core/ui_integration.h index 3cb3e191c..f5e9ff1d9 100644 --- a/Telegram/SourceFiles/core/ui_integration.h +++ b/Telegram/SourceFiles/core/ui_integration.h @@ -13,6 +13,15 @@ namespace Core { class UiIntegration : public Ui::Integration { public: + enum class HashtagMentionType : uchar { + Telegram, + Twitter, + Instagram, + }; + struct Context { + HashtagMentionType type = HashtagMentionType::Telegram; + }; + void postponeCall(FnMut &&callable) override; void registerLeaveSubscription(not_null widget) override; void unregisterLeaveSubscription(not_null widget) override; @@ -27,10 +36,8 @@ public: void startFontsEnd() override; std::shared_ptr createLinkHandler( - EntityType type, - const QString &text, - const QString &data, - const TextParseOptions &options) override; + const EntityLinkData &data, + const std::any &context) override; bool handleUrlClick( const QString &url, const QVariant &context) override; diff --git a/Telegram/SourceFiles/core/update_checker.cpp b/Telegram/SourceFiles/core/update_checker.cpp index ce9eda022..410e52b6c 100644 --- a/Telegram/SourceFiles/core/update_checker.cpp +++ b/Telegram/SourceFiles/core/update_checker.cpp @@ -409,9 +409,9 @@ bool UnpackUpdate(const QString &filepath) { bool executable = false; stream >> relativeName >> fileSize >> fileInnerData; -#if defined Q_OS_MAC || defined Q_OS_LINUX +#ifdef Q_OS_UNIX stream >> executable; -#endif // Q_OS_MAC || Q_OS_LINUX +#endif // Q_OS_UNIX if (stream.status() != QDataStream::Ok) { LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status())); return false; @@ -1511,10 +1511,10 @@ bool checkReadyUpdate() { #elif defined Q_OS_MAC // Q_OS_WIN QString curUpdater = (cExeDir() + cExeName() + qsl("/Contents/Frameworks/Updater")); QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Kotatogram.app/Contents/Frameworks/Updater")); -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC QString curUpdater = (cExeDir() + qsl("Updater")); QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater")); -#endif // Q_OS_LINUX +#endif // Q_OS_UNIX if (!updater.exists()) { QFileInfo current(curUpdater); if (!current.exists()) { @@ -1548,12 +1548,12 @@ bool checkReadyUpdate() { ClearAll(); return false; } -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) { ClearAll(); return false; } -#endif // Q_OS_LINUX +#endif // Q_OS_UNIX #ifdef Q_OS_MAC Platform::RemoveQuarantine(QFileInfo(curUpdater).absolutePath()); diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 80ab34408..4dbd25fcd 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 = 2001010; -constexpr auto AppVersionStr = "2.1.10"; +constexpr auto AppVersion = 2001013; +constexpr auto AppVersionStr = "2.1.13"; constexpr auto AppBetaVersion = true; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index c7efb41c1..76d270c19 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -797,7 +797,9 @@ bool DocumentData::saveToCache() const { || isAnimation() || isVoiceMessage() || (type == WallPaperDocument) - || isTheme()); + || isTheme() + || (mimeString() == qstr("image/png") + && _filename.startsWith("image_"))); } void DocumentData::automaticLoadSettingsChanged() { @@ -1615,10 +1617,10 @@ bool IsExecutableName(const QString &filepath) { qsl("\ applescript action app bin command csh osx workflow terminal url caction \ mpkg pkg scpt scptd xhtm webarchive"); -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC qsl("bin csh deb desktop ksh out pet pkg pup rpm run sh shar \ slp zsh"); -#else // Q_OS_MAC || Q_OS_LINUX +#else // Q_OS_MAC || Q_OS_UNIX qsl("\ ad ade adp app application appref-ms asp asx bas bat bin cdxml cer cfg chi \ chm cmd cnt com cpl crt csh der diagcab dll drv eml exe fon fxp gadget grp \ @@ -1631,7 +1633,7 @@ psm1 pssc pst py py3 pyc pyd pyi pyo pyw pywz pyz rb reg rgs scf scr sct \ search-ms settingcontent-ms shb shs slk sys t tmp u3p url vb vbe vbp vbs \ vbscript vdx vsmacros vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx vtx \ website ws wsc wsf wsh xbap xll xnk xs"); -#endif // !Q_OS_MAC && !Q_OS_LINUX +#endif // !Q_OS_MAC && !Q_OS_UNIX const auto list = joined.split(' '); return base::flat_set(list.begin(), list.end()); }(); diff --git a/Telegram/SourceFiles/data/data_drafts.cpp b/Telegram/SourceFiles/data/data_drafts.cpp index 3e11daf77..af02fd8d5 100644 --- a/Telegram/SourceFiles/data/data_drafts.cpp +++ b/Telegram/SourceFiles/data/data_drafts.cpp @@ -45,14 +45,19 @@ Draft::Draft( , previewCancelled(previewCancelled) { } -void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) { - const auto history = Auth().data().history(peerId); +void ApplyPeerCloudDraft( + not_null session, + PeerId peerId, + const MTPDdraftMessage &draft) { + const auto history = session->data().history(peerId); const auto textWithTags = TextWithTags { qs(draft.vmessage()), TextUtilities::ConvertEntitiesToTextTags( - Api::EntitiesFromMTP(draft.ventities().value_or_empty())) + Api::EntitiesFromMTP( + session, + draft.ventities().value_or_empty())) }; - auto replyTo = draft.vreply_to_msg_id().value_or_empty(); + const auto replyTo = draft.vreply_to_msg_id().value_or_empty(); if (history->skipCloudDraft(textWithTags.text, replyTo, draft.vdate().v)) { return; } @@ -67,8 +72,11 @@ void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) { history->applyCloudDraft(); } -void clearPeerCloudDraft(PeerId peerId, TimeId date) { - const auto history = Auth().data().history(peerId); +void ClearPeerCloudDraft( + not_null session, + PeerId peerId, + TimeId date) { + const auto history = session->data().history(peerId); if (history->skipCloudDraft(QString(), MsgId(0), date)) { return; } diff --git a/Telegram/SourceFiles/data/data_drafts.h b/Telegram/SourceFiles/data/data_drafts.h index c3ccdc3f8..57428e62e 100644 --- a/Telegram/SourceFiles/data/data_drafts.h +++ b/Telegram/SourceFiles/data/data_drafts.h @@ -11,10 +11,20 @@ namespace Ui { class InputField; } // namespace Ui +namespace Main { +class Session; +} // namespace Main + namespace Data { -void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft); -void clearPeerCloudDraft(PeerId peerId, TimeId date); +void ApplyPeerCloudDraft( + not_null session, + PeerId peerId, + const MTPDdraftMessage &draft); +void ClearPeerCloudDraft( + not_null session, + PeerId peerId, + TimeId date); struct Draft { Draft() = default; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 1b47c63dd..134447224 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -244,8 +244,9 @@ TextWithEntities Media::consumedMessageText() const { } std::unique_ptr Media::createView( - not_null message) { - return createView(message, message->data()); + not_null message, + HistoryView::Element *replacing) { + return createView(message, message->data(), replacing); } MediaPhoto::MediaPhoto( @@ -386,7 +387,8 @@ bool MediaPhoto::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaPhoto::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { if (_chat) { return std::make_unique( message, @@ -663,11 +665,15 @@ bool MediaFile::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaFile::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { if (_document->sticker()) { return std::make_unique( message, - std::make_unique(message, _document)); + std::make_unique( + message, + _document, + replacing)); } else if (_document->isAnimation() || _document->isVideoFile()) { return std::make_unique( message, @@ -760,7 +766,8 @@ bool MediaContact::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaContact::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique( message, _contact.userId, @@ -840,7 +847,8 @@ bool MediaLocation::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaLocation::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique( message, _location, @@ -900,7 +908,8 @@ bool MediaCall::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaCall::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique(message, &_call); } @@ -995,7 +1004,8 @@ bool MediaWebPage::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaWebPage::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique(message, _page); } @@ -1086,7 +1096,8 @@ bool MediaGame::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaGame::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique( message, _game, @@ -1151,7 +1162,8 @@ bool MediaInvoice::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaInvoice::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique(message, &_invoice); } @@ -1217,7 +1229,8 @@ bool MediaPoll::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaPoll::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique(message, _poll); } @@ -1274,7 +1287,8 @@ bool MediaDice::updateSentMedia(const MTPMessageMedia &media) { std::unique_ptr MediaDice::createView( not_null message, - not_null realParent) { + not_null realParent, + HistoryView::Element *replacing) { return std::make_unique( message, std::make_unique(message, this)); diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index ab09b28f4..dfae6ce8c 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -111,9 +111,11 @@ public: virtual bool updateSentMedia(const MTPMessageMedia &media) = 0; virtual std::unique_ptr createView( not_null message, - not_null realParent) = 0; + not_null realParent, + HistoryView::Element *replacing = nullptr) = 0; std::unique_ptr createView( - not_null message); + not_null message, + HistoryView::Element *replacing = nullptr); private: const not_null _parent; @@ -152,7 +154,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: not_null _photo; @@ -189,7 +192,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: not_null _document; @@ -218,7 +222,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: SharedContact _contact; @@ -248,7 +253,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: LocationPoint _point; @@ -276,7 +282,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; static QString Text( not_null item, @@ -312,7 +319,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: not_null _page; @@ -343,7 +351,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: not_null _game; @@ -374,7 +383,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: Invoice _invoice; @@ -401,7 +411,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: not_null _poll; @@ -425,7 +436,8 @@ public: bool updateSentMedia(const MTPMessageMedia &media) override; std::unique_ptr createView( not_null message, - not_null realParent) override; + not_null realParent, + HistoryView::Element *replacing = nullptr) override; private: QString _emoji; diff --git a/Telegram/SourceFiles/data/data_poll.cpp b/Telegram/SourceFiles/data/data_poll.cpp index 3bb520a7d..e31c2145d 100644 --- a/Telegram/SourceFiles/data/data_poll.cpp +++ b/Telegram/SourceFiles/data/data_poll.cpp @@ -45,6 +45,14 @@ PollData::PollData(not_null owner, PollId id) , _owner(owner) { } +Data::Session &PollData::owner() const { + return *_owner; +} + +Main::Session &PollData::session() const { + return _owner->session(); +} + bool PollData::closeByTimer() { if (closed()) { return false; @@ -151,6 +159,7 @@ bool PollData::applyResults(const MTPPollResults &results) { auto newSolution = TextWithEntities{ results.vsolution().value_or_empty(), Api::EntitiesFromMTP( + &_owner->session(), results.vsolution_entities().value_or_empty()) }; if (solution != newSolution) { @@ -293,6 +302,7 @@ MTPInputMedia PollDataToInputMedia( TextUtilities::PrepareForSending(solution, prepareFlags); TextUtilities::Trim(solution); const auto sentEntities = Api::EntitiesToMTP( + &poll->session(), solution.entities, Api::ConvertOption::SkipLocal); if (!solution.text.isEmpty()) { diff --git a/Telegram/SourceFiles/data/data_poll.h b/Telegram/SourceFiles/data/data_poll.h index 19c4e59e4..9a0229983 100644 --- a/Telegram/SourceFiles/data/data_poll.h +++ b/Telegram/SourceFiles/data/data_poll.h @@ -11,6 +11,10 @@ namespace Data { class Session; } // namespace Data +namespace Main { +class Session; +} // namespace Main + struct PollAnswer { QString text; QByteArray option; @@ -31,6 +35,9 @@ inline bool operator!=(const PollAnswer &a, const PollAnswer &b) { struct PollData { PollData(not_null owner, PollId id); + [[nodiscard]] Data::Session &owner() const; + [[nodiscard]] Main::Session &session() const; + enum class Flag { Closed = 0x01, PublicVotes = 0x02, diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 75b725b3e..3e49bf176 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -152,7 +152,7 @@ void ScheduledMessages::sendNowSimpleMessage( // we know for sure that a message can't have fields such as the author, // views count, etc. - const auto &history = local->history(); + const auto history = local->history(); auto flags = NewMessageFlags(history->peer) | MTPDmessage::Flag::f_entities | MTPDmessage::Flag::f_from_id @@ -175,7 +175,9 @@ void ScheduledMessages::sendNowSimpleMessage( MTP_string(local->originalText().text), MTP_messageMediaEmpty(), MTPReplyMarkup(), - Api::EntitiesToMTP(local->originalText().entities), + Api::EntitiesToMTP( + &history->session(), + local->originalText().entities), MTP_int(1), MTPint(), MTP_string(), @@ -234,7 +236,7 @@ void ScheduledMessages::checkEntitiesAndUpdate(const MTPDmessage &data) { Assert(existing->date() == kScheduledUntilOnlineTimestamp); existing->updateSentContent({ qs(data.vmessage()), - Api::EntitiesFromMTP(data.ventities().value_or_empty()) + Api::EntitiesFromMTP(_session, data.ventities().value_or_empty()) }, data.vmedia()); existing->updateReplyMarkup(data.vreply_markup()); existing->updateForwardedInfo(data.vfwd_from()); @@ -410,7 +412,9 @@ HistoryItem *ScheduledMessages::append( message.match([&](const MTPDmessage &data) { existing->updateSentContent({ qs(data.vmessage()), - Api::EntitiesFromMTP(data.ventities().value_or_empty()) + Api::EntitiesFromMTP( + _session, + data.ventities().value_or_empty()) }, data.vmedia()); existing->updateReplyMarkup(data.vreply_markup()); existing->updateForwardedInfo(data.vfwd_from()); diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 64fddfbe5..2d0af620e 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -1703,7 +1703,9 @@ bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) { if (const auto existing = message(peerToChannel(peer), data.vid().v)) { existing->updateSentContent({ qs(data.vmessage()), - Api::EntitiesFromMTP(data.ventities().value_or_empty()) + Api::EntitiesFromMTP( + &session(), + data.ventities().value_or_empty()) }, data.vmedia()); existing->updateReplyMarkup(data.vreply_markup()); existing->updateForwardedInfo(data.vfwd_from()); @@ -3725,7 +3727,7 @@ void Session::insertCheckedServiceNotification( MTP_string(sending.text), media, MTPReplyMarkup(), - Api::EntitiesToMTP(sending.entities), + Api::EntitiesToMTP(&session(), sending.entities), MTPint(), MTPint(), MTPstring(), diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 87de0e09c..cf0d6edc6 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -538,13 +538,15 @@ HistoryView::Context InnerWidget::elementContext() { } std::unique_ptr InnerWidget::elementCreate( - not_null message) { - return std::make_unique(this, message); + not_null message, + Element *replacing) { + return std::make_unique(this, message, replacing); } std::unique_ptr InnerWidget::elementCreate( - not_null message) { - return std::make_unique(this, message); + not_null message, + Element *replacing) { + return std::make_unique(this, message, replacing); } bool InnerWidget::elementUnderCursor( @@ -1535,13 +1537,13 @@ void InnerWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton but _mouseSelectType = TextSelectType::Letters; //_widget->noSelectingScroll(); // TODO -#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#if defined Q_OS_UNIX && !defined Q_OS_MAC if (_selectedItem && _selectedText.from != _selectedText.to) { TextUtilities::SetClipboardText( _selectedItem->selectedText(_selectedText), QClipboard::Selection); } -#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // Q_OS_UNIX && !Q_OS_MAC } void InnerWidget::updateSelected() { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h index 3d2d228e4..9ed7773b5 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h @@ -89,9 +89,11 @@ public: // HistoryView::ElementDelegate interface. HistoryView::Context elementContext() override; std::unique_ptr elementCreate( - not_null message) override; + not_null message, + HistoryView::Element *replacing = nullptr) override; std::unique_ptr elementCreate( - not_null message) override; + not_null message, + HistoryView::Element *replacing = nullptr) override; bool elementUnderCursor( not_null view) override; void elementAnimationAutoplayAsync( diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp index eef73cdf3..8b73e684d 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -111,14 +111,16 @@ bool MediaCanHaveCaption(const MTPMessage &message) { return (mediaType == mtpc_messageMediaDocument || mediaType == mtpc_messageMediaPhoto); } -TextWithEntities ExtractEditedText(const MTPMessage &message) { +TextWithEntities ExtractEditedText( + not_null session, + const MTPMessage &message) { if (message.type() != mtpc_message) { return TextWithEntities(); } const auto &data = message.c_message(); return { TextUtilities::Clean(qs(data.vmessage())), - Api::EntitiesFromMTP(data.ventities().value_or_empty()) + Api::EntitiesFromMTP(session, data.ventities().value_or_empty()) }; } @@ -376,19 +378,20 @@ void GenerateItems( Fn callback) { Expects(history->peer->isChannel()); - auto id = event.vid().v; - auto from = Auth().data().user(event.vuser_id().v); - auto channel = history->peer->asChannel(); - auto &action = event.vaction(); - auto date = event.vdate().v; - auto addPart = [&](not_null item) { + const auto session = &history->session(); + const auto id = event.vid().v; + const auto from = Auth().data().user(event.vuser_id().v); + const auto channel = history->peer->asChannel(); + const auto &action = event.vaction(); + const auto date = event.vdate().v; + const auto addPart = [&](not_null item) { return callback(OwnedItem(delegate, item)); }; using Flag = MTPDmessage::Flag; - auto fromName = from->name; - auto fromLink = from->createOpenLink(); - auto fromLinkText = textcmdLink(1, fromName); + const auto fromName = from->name; + const auto fromLink = from->createOpenLink(); + const auto fromLinkText = textcmdLink(1, fromName); auto addSimpleServiceMessage = [&](const QString &text, PhotoData *photo = nullptr) { auto message = HistoryService::PreparedText { text }; @@ -542,7 +545,7 @@ void GenerateItems( }; auto createEditMessage = [&](const MTPDchannelAdminLogEventActionEditMessage &action) { - auto newValue = ExtractEditedText(action.vnew_message()); + auto newValue = ExtractEditedText(session, action.vnew_message()); auto canHaveCaption = MediaCanHaveCaption(action.vnew_message()); auto text = (!canHaveCaption ? tr::lng_admin_log_edited_message @@ -554,7 +557,7 @@ void GenerateItems( fromLinkText); addSimpleServiceMessage(text); - auto oldValue = ExtractEditedText(action.vprev_message()); + auto oldValue = ExtractEditedText(session, action.vprev_message()); auto detachExistingItem = false; auto body = history->createItem( PrepareLogMessage( diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index e8fee9386..96b1f786e 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -2700,7 +2700,10 @@ void History::applyDialog( const auto draft = data.vdraft(); if (draft && draft->type() == mtpc_draftMessage) { - Data::applyPeerCloudDraft(peer->id, draft->c_draftMessage()); + Data::ApplyPeerCloudDraft( + &session(), + peer->id, + draft->c_draftMessage()); } owner().histories().dialogEntryApplied(this); } @@ -3361,7 +3364,9 @@ void HistoryBlock::refreshView(not_null view) { Expects(view->block() == this); const auto item = view->data(); - auto refreshed = item->createView(HistoryInner::ElementDelegate()); + auto refreshed = item->createView( + HistoryInner::ElementDelegate(), + view); auto blockIndex = indexInHistory(); auto itemIndex = view->indexInBlock(); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index d3bc4ccbb..a4c1fc707 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1427,7 +1427,7 @@ void HistoryInner::mouseActionFinish( _widget->noSelectingScroll(); _widget->updateTopBarSelection(); -#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#if defined Q_OS_UNIX && !defined Q_OS_MAC if (!_selected.empty() && _selected.cbegin()->second != FullSelection) { const auto [item, selection] = *_selected.cbegin(); if (const auto view = item->mainView()) { @@ -1436,7 +1436,7 @@ void HistoryInner::mouseActionFinish( QClipboard::Selection); } } -#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // Q_OS_UNIX && !Q_OS_MAC } void HistoryInner::mouseReleaseEvent(QMouseEvent *e) { @@ -2373,7 +2373,7 @@ HistoryInner::~HistoryInner() { for (const auto &item : _animatedStickersPlayed) { if (const auto view = item->mainView()) { if (const auto media = view->media()) { - media->clearStickerLoopPlayed(); + media->stickerClearLoopPlayed(); } } } @@ -3323,12 +3323,20 @@ not_null HistoryInner::ElementDelegate() { return HistoryView::Context::History; } std::unique_ptr elementCreate( - not_null message) override { - return std::make_unique(this, message); + not_null message, + Element *replacing = nullptr) override { + return std::make_unique( + this, + message, + replacing); } std::unique_ptr elementCreate( - not_null message) override { - return std::make_unique(this, message); + not_null message, + Element *replacing = nullptr) override { + return std::make_unique( + this, + message, + replacing); } bool elementUnderCursor( not_null view) override { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 20ec30e1e..1310c283c 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -326,7 +326,8 @@ public: [[nodiscard]] PeerData *displayFrom() const; [[nodiscard]] virtual std::unique_ptr createView( - not_null delegate) = 0; + not_null delegate, + HistoryView::Element *replacing = nullptr) = 0; void updateDate(TimeId newDate); [[nodiscard]] bool canUpdateDate() const; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 6a2232b7c..595f287ed 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -458,7 +458,9 @@ HistoryMessage::HistoryMessage( } const auto textWithEntities = TextWithEntities{ TextUtilities::Clean(qs(data.vmessage())), - Api::EntitiesFromMTP(data.ventities().value_or_empty()) + Api::EntitiesFromMTP( + &history->session(), + data.ventities().value_or_empty()) }; setText(_media ? textWithEntities : EnsureNonEmpty(textWithEntities)); if (const auto groupedId = data.vgrouped_id()) { @@ -1072,7 +1074,9 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) { const auto textWithEntities = TextWithEntities{ qs(message.vmessage()), - Api::EntitiesFromMTP(message.ventities().value_or_empty()) + Api::EntitiesFromMTP( + &history()->session(), + message.ventities().value_or_empty()) }; setReplyMarkup(message.vreply_markup()); if (!isLocalUpdateMedia()) { @@ -1383,8 +1387,9 @@ QString HistoryMessage::notificationHeader() const { } std::unique_ptr HistoryMessage::createView( - not_null delegate) { - return delegate->elementCreate(this); + not_null delegate, + HistoryView::Element *replacing) { + return delegate->elementCreate(this, replacing); } HistoryMessage::~HistoryMessage() { diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index 8b783edf9..52718a245 100644 --- a/Telegram/SourceFiles/history/history_message.h +++ b/Telegram/SourceFiles/history/history_message.h @@ -168,7 +168,8 @@ public: } [[nodiscard]] std::unique_ptr createView( - not_null delegate) override; + not_null delegate, + HistoryView::Element *replacing = nullptr) override; ~HistoryMessage(); diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index 7c45e1691..4109aa92f 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -570,8 +570,9 @@ QString HistoryService::inReplyText() const { } std::unique_ptr HistoryService::createView( - not_null delegate) { - return delegate->elementCreate(this); + not_null delegate, + HistoryView::Element *replacing) { + return delegate->elementCreate(this, replacing); } QString HistoryService::fromLinkText() const { diff --git a/Telegram/SourceFiles/history/history_service.h b/Telegram/SourceFiles/history/history_service.h index fe06d26ad..0b68c1842 100644 --- a/Telegram/SourceFiles/history/history_service.h +++ b/Telegram/SourceFiles/history/history_service.h @@ -105,7 +105,8 @@ public: QString inReplyText() const override; std::unique_ptr createView( - not_null delegate) override; + not_null delegate, + HistoryView::Element *replacing = nullptr) override; ~HistoryService(); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c042f2ed7..3589304b6 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -65,6 +65,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/tabbed_section.h" #include "chat_helpers/bot_keyboard.h" #include "chat_helpers/message_field.h" +#include "platform/platform_specific.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" @@ -2102,6 +2103,7 @@ void HistoryWidget::refreshScheduledToggle() { controller()->showSection( HistoryView::ScheduledMemento(_history)); }); + orderWidgets(); // Raise drag areas to the top. } } } @@ -3068,8 +3070,9 @@ void HistoryWidget::saveEditMsg() { if (webPageId == CancelledWebPageId) { sendFlags |= MTPmessages_EditMessage::Flag::f_no_webpage; } - auto localEntities = Api::EntitiesToMTP(sending.entities); + auto localEntities = Api::EntitiesToMTP(&session(), sending.entities); auto sentEntities = Api::EntitiesToMTP( + &session(), sending.entities, Api::ConvertOption::SkipLocal); if (!sentEntities.v.isEmpty()) { @@ -4605,7 +4608,10 @@ bool HistoryWidget::confirmSendingFiles( } if (hasImage) { - auto image = qvariant_cast(data->imageData()); + auto image = Platform::GetImageFromClipboard(); + if (image.isNull()) { + image = qvariant_cast(data->imageData()); + } if (!image.isNull()) { confirmSendingFiles( std::move(image), @@ -4755,7 +4761,7 @@ void HistoryWidget::sendFileConfirmed( session().user()).flags; TextUtilities::PrepareForSending(caption, prepareFlags); TextUtilities::Trim(caption); - auto localEntities = Api::EntitiesToMTP(caption.entities); + auto localEntities = Api::EntitiesToMTP(&session(), caption.entities); if (itemToEdit) { if (const auto id = itemToEdit->groupId()) { diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index a443315f0..b8ec2414a 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -430,12 +430,17 @@ bool AddRescheduleMessageAction( ? SendMenuType::ScheduledToUser : SendMenuType::Scheduled; + using S = Data::ScheduledMessages; + const auto date = (item->date() == S::kScheduledUntilOnlineTimestamp) + ? HistoryView::DefaultScheduleTime() + : item->date() + 600; + Ui::show( HistoryView::PrepareScheduleBox( &request.navigation->session(), sendMenuType, callback, - item->date() + 600), + date), Ui::LayerOption::KeepOther); }); return true; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index a9c03aa94..340913111 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -56,13 +56,15 @@ bool IsAttachedToPreviousInSavedMessages( std::unique_ptr SimpleElementDelegate::elementCreate( - not_null message) { - return std::make_unique(this, message); + not_null message, + Element *replacing) { + return std::make_unique(this, message, replacing); } std::unique_ptr SimpleElementDelegate::elementCreate( - not_null message) { - return std::make_unique(this, message); + not_null message, + Element *replacing) { + return std::make_unique(this, message, replacing); } bool SimpleElementDelegate::elementUnderCursor( @@ -203,14 +205,15 @@ void DateBadge::paint(Painter &p, int y, int w) const { Element::Element( not_null delegate, - not_null data) + not_null data, + Element *replacing) : _delegate(delegate) , _data(data) , _isScheduledUntilOnline(IsItemScheduledUntilOnline(data)) , _dateTime(_isScheduledUntilOnline ? QDateTime() : ItemDateTime(data)) , _context(delegate->elementContext()) { history()->owner().registerItemView(this); - refreshMedia(); + refreshMedia(replacing); if (_context == Context::History) { history()->setHasPendingResizedItems(); } @@ -342,7 +345,7 @@ bool Element::isHidden() const { return isHiddenByGroup(); } -void Element::refreshMedia() { +void Element::refreshMedia(Element *replacing) { _flags &= ~Flag::HiddenByGroup; const auto item = data(); @@ -365,7 +368,7 @@ void Element::refreshMedia() { } const auto session = &history()->session(); if (const auto media = _data->media()) { - _media = media->createView(this); + _media = media->createView(this, replacing); } else if (_data->isIsolatedEmoji() && session->settings().largeEmoji()) { const auto emoji = _data->isolatedEmoji(); @@ -376,6 +379,7 @@ void Element::refreshMedia() { std::make_unique( this, sticker.document, + replacing, sticker.replacements)); } else { _media = std::make_unique( diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index c14a6347c..e28215c07 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -37,9 +37,11 @@ class ElementDelegate { public: virtual Context elementContext() = 0; virtual std::unique_ptr elementCreate( - not_null message) = 0; + not_null message, + Element *replacing = nullptr) = 0; virtual std::unique_ptr elementCreate( - not_null message) = 0; + not_null message, + Element *replacing = nullptr) = 0; virtual bool elementUnderCursor(not_null view) = 0; virtual void elementAnimationAutoplayAsync( not_null element) = 0; @@ -63,9 +65,11 @@ public: class SimpleElementDelegate : public ElementDelegate { public: std::unique_ptr elementCreate( - not_null message) override; + not_null message, + Element *replacing = nullptr) override; std::unique_ptr elementCreate( - not_null message) override; + not_null message, + Element *replacing = nullptr) override; bool elementUnderCursor(not_null view) override; void elementAnimationAutoplayAsync( not_null element) override; @@ -134,7 +138,8 @@ class Element public: Element( not_null delegate, - not_null data); + not_null data, + Element *replacing); enum class Flag : uchar { NeedsResize = 0x01, @@ -305,7 +310,7 @@ private: virtual QSize performCountOptimalSize() = 0; virtual QSize performCountCurrentSize(int newWidth) = 0; - void refreshMedia(); + void refreshMedia(Element *replacing); const not_null _delegate; const not_null _data; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 621210a16..a6c20021d 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -1107,13 +1107,15 @@ Context ListWidget::elementContext() { } std::unique_ptr ListWidget::elementCreate( - not_null message) { - return std::make_unique(this, message); + not_null message, + Element *replacing) { + return std::make_unique(this, message, replacing); } std::unique_ptr ListWidget::elementCreate( - not_null message) { - return std::make_unique(this, message); + not_null message, + Element *replacing) { + return std::make_unique(this, message, replacing); } bool ListWidget::elementUnderCursor( @@ -2083,7 +2085,7 @@ void ListWidget::mouseActionFinish( _mouseSelectType = TextSelectType::Letters; //_widget->noSelectingScroll(); // #TODO select scroll -#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#if defined Q_OS_UNIX && !defined Q_OS_MAC if (_selectedTextItem && _selectedTextRange.from != _selectedTextRange.to) { if (const auto view = viewForItem(_selectedTextItem)) { @@ -2092,7 +2094,7 @@ void ListWidget::mouseActionFinish( QClipboard::Selection); } } -#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // Q_OS_UNIX && !Q_OS_MAC } void ListWidget::mouseActionUpdate() { diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index 18e6d4dd5..428352e90 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -184,9 +184,11 @@ public: // ElementDelegate interface. Context elementContext() override; std::unique_ptr elementCreate( - not_null message) override; + not_null message, + Element *replacing = nullptr) override; std::unique_ptr elementCreate( - not_null message) override; + not_null message, + Element *replacing = nullptr) override; bool elementUnderCursor(not_null view) override; void elementAnimationAutoplayAsync( not_null view) override; diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 42c2e95bb..e960a2c80 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -217,8 +217,9 @@ LogEntryOriginal::~LogEntryOriginal() = default; Message::Message( not_null delegate, - not_null data) -: Element(delegate, data) { + not_null data, + Element *replacing) +: Element(delegate, data, replacing) { initLogEntryOriginal(); initPsa(); } diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 6ab1dc4db..20d07c42a 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -41,7 +41,8 @@ class Message : public Element, public base::has_weak_ptr { public: Message( not_null delegate, - not_null data); + not_null data, + Element *replacing); int marginTop() const override; int marginBottom() const override; diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp index 13abb00e7..0a329c2fb 100644 --- a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp +++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_scheduled_messages.h" // kScheduledUntilOnlineTimestamp #include "lang/lang_keys.h" +#include "base/event_filter.h" #include "base/unixtime.h" #include "boxes/calendar_box.h" #include "ui/widgets/input_fields.h" @@ -65,17 +66,30 @@ QString TimeString(TimeId time) { ).arg(parsed.minute(), 2, 10, QLatin1Char('0')); } +int ProcessWheelEvent(not_null e) { + // Only a mouse wheel is accepted. + constexpr auto step = static_cast(QWheelEvent::DefaultDeltasPerStep); + const auto delta = e->angleDelta().y(); + const auto absDelta = std::abs(delta); + if (absDelta != step) { + return 0; + } + return (delta / absDelta); +} + class TimePart final : public Ui::MaskedInputField { public: using MaskedInputField::MaskedInputField; void setMaxValue(int value); + void setWheelStep(int value); rpl::producer<> erasePrevious() const; rpl::producer putNext() const; protected: void keyPressEvent(QKeyEvent *e) override; + void wheelEvent(QWheelEvent *e) override; void correctValue( const QString &was, @@ -86,11 +100,21 @@ protected: private: int _maxValue = 0; int _maxDigits = 0; + int _wheelStep = 0; rpl::event_stream<> _erasePrevious; rpl::event_stream _putNext; }; +int Number(not_null field) { + const auto text = field->getLastText(); + auto ref = text.midRef(0); + while (!ref.isEmpty() && ref.at(0) == '0') { + ref = ref.mid(1); + } + return ref.toInt(); +} + class TimeInput final : public Ui::RpWidget { public: TimeInput(QWidget *parent, const QString &value); @@ -121,7 +145,6 @@ private: int hour() const; int minute() const; - int number(const object_ptr &field) const; object_ptr _hour; object_ptr> _separator1; @@ -181,6 +204,10 @@ void TimePart::setMaxValue(int value) { } } +void TimePart::setWheelStep(int value) { + _wheelStep = value; +} + rpl::producer<> TimePart::erasePrevious() const { return _erasePrevious.events(); } @@ -199,6 +226,18 @@ void TimePart::keyPressEvent(QKeyEvent *e) { } } +void TimePart::wheelEvent(QWheelEvent *e) { + const auto direction = ProcessWheelEvent(e); + auto time = Number(this) + (direction * _wheelStep); + const auto max = _maxValue + 1; + if (time < 0) { + time += max; + } else if (time >= max) { + time -= max; + } + setText(QString::number(time)); +} + void TimePart::correctValue( const QString &was, int wasCursor, @@ -290,10 +329,12 @@ TimeInput::TimeInput(QWidget *parent, const QString &value) connect(_hour, &Ui::MaskedInputField::changed, changed); connect(_minute, &Ui::MaskedInputField::changed, changed); _hour->setMaxValue(23); + _hour->setWheelStep(1); _hour->putNext() | rpl::start_with_next([=](QChar ch) { putNext(_minute, ch); }, lifetime()); _minute->setMaxValue(59); + _minute->setWheelStep(10); _minute->erasePrevious() | rpl::start_with_next([=] { erasePrevious(_hour); }, lifetime()); @@ -356,21 +397,12 @@ bool TimeInput::setFocusFast() { return true; } -int TimeInput::number(const object_ptr &field) const { - const auto text = field->getLastText(); - auto ref = text.midRef(0); - while (!ref.isEmpty() && ref.at(0) == '0') { - ref = ref.mid(1); - } - return ref.toInt(); -} - int TimeInput::hour() const { - return number(_hour); + return Number(_hour); } int TimeInput::minute() const { - return number(_minute); + return Number(_minute); } QString TimeInput::valueCurrent() const { @@ -601,6 +633,24 @@ void ScheduleBox( timeInput->setFocusFast(); }, dayInput->lifetime()); + const auto minDate = QDate::currentDate(); + const auto maxDate = minDate.addYears(1).addDays(-1); + + const auto &dayViewport = dayInput->rawTextEdit()->viewport(); + base::install_event_filter(dayViewport, [=](not_null event) { + if (event->type() == QEvent::Wheel) { + const auto e = static_cast(event.get()); + const auto direction = ProcessWheelEvent(e); + if (!direction) { + return base::EventFilterResult::Continue; + } + const auto d = date->current().addDays(direction); + *date = std::clamp(d, minDate, maxDate); + return base::EventFilterResult::Cancel; + } + return base::EventFilterResult::Continue; + }); + content->widthValue( ) | rpl::start_with_next([=](int width) { const auto paddings = width @@ -622,16 +672,19 @@ void ScheduleBox( width); }, content->lifetime()); + const auto calendar = + content->lifetime().make_state>(); QObject::connect(dayInput, &Ui::InputField::focused, [=] { - const auto calendar = std::make_shared>(); + if (*calendar) { + return; + } const auto chosen = [=](QDate chosen) { *date = chosen; (*calendar)->closeBox(); }; const auto finalize = [=](not_null box) { - const auto now = QDate::currentDate(); - box->setMinDate(now); - box->setMaxDate(now.addYears(1).addDays(-1)); + box->setMinDate(minDate); + box->setMaxDate(maxDate); }; *calendar = box->getDelegate()->show(Box( date->current(), diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 24ddbb0d4..04b25058f 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_media_prepare.h" #include "storage/localstorage.h" #include "inline_bots/inline_bot_result.h" +#include "platform/platform_specific.h" #include "lang/lang_keys.h" #include "facades.h" #include "app.h" @@ -265,7 +266,10 @@ bool ScheduledWidget::confirmSendingFiles( } if (hasImage) { - auto image = qvariant_cast(data->imageData()); + auto image = Platform::GetImageFromClipboard(); + if (image.isNull()) { + image = qvariant_cast(data->imageData()); + } if (!image.isNull()) { confirmSendingFiles( std::move(image), diff --git a/Telegram/SourceFiles/history/view/history_view_service_message.cpp b/Telegram/SourceFiles/history/view/history_view_service_message.cpp index 1d7f8e6d8..0b1c071ee 100644 --- a/Telegram/SourceFiles/history/view/history_view_service_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_service_message.cpp @@ -309,8 +309,9 @@ void serviceColorsUpdated() { Service::Service( not_null delegate, - not_null data) -: Element(delegate, data) { + not_null data, + Element *replacing) +: Element(delegate, data, replacing) { } not_null Service::message() const { diff --git a/Telegram/SourceFiles/history/view/history_view_service_message.h b/Telegram/SourceFiles/history/view/history_view_service_message.h index 41d552772..8b86ca1ad 100644 --- a/Telegram/SourceFiles/history/view/history_view_service_message.h +++ b/Telegram/SourceFiles/history/view/history_view_service_message.h @@ -17,7 +17,8 @@ class Service : public Element { public: Service( not_null delegate, - not_null data); + not_null data, + Element *replacing); int marginTop() const override; int marginBottom() const override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.h b/Telegram/SourceFiles/history/view/media/history_view_dice.h index 8022352ca..f412343b7 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_dice.h +++ b/Telegram/SourceFiles/history/view/media/history_view_dice.h @@ -26,8 +26,6 @@ public: ClickHandlerPtr link() override; - void clearStickerLoopPlayed() override { - } bool hasHeavyPart() const override { return (_start ? _start->hasHeavyPart() : false) || (_end ? _end->hasHeavyPart() : false); diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.cpp b/Telegram/SourceFiles/history/view/media/history_view_media.cpp index b31b1c7a5..6e17e04af 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_item.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" +#include "lottie/lottie_single_player.h" #include "storage/storage_shared_media.h" #include "data/data_document.h" #include "ui/text_options.h" @@ -165,6 +166,10 @@ PointState Media::pointState(QPoint point) const { : PointState::Outside; } +std::unique_ptr Media::stickerTakeLottie() { + return nullptr; +} + TextState Media::getStateGrouped( const QRect &geometry, RectParts sides, diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index 52a8155a8..0b16b63be 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -24,6 +24,10 @@ enum class SharedMediaType : signed char; using SharedMediaTypesMask = base::enum_mask; } // namespace Storage +namespace Lottie { +class SinglePlayer; +} // namespace Lottie + namespace HistoryView { enum class PointState : char; @@ -139,8 +143,9 @@ public: } virtual void stopAnimation() { } - virtual void clearStickerLoopPlayed() { + virtual void stickerClearLoopPlayed() { } + virtual std::unique_ptr stickerTakeLottie(); virtual void checkAnimation() { } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp index bfb289d9f..c037056e4 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "history/history_item.h" #include "history/history_item_components.h" +#include "lottie/lottie_single_player.h" #include "data/data_session.h" #include "layout.h" #include "facades.h" @@ -26,6 +27,11 @@ constexpr auto kMaxForwardedBarLines = 4; } // namespace +auto UnwrappedMedia::Content::stickerTakeLottie() +-> std::unique_ptr { + return nullptr; +} + UnwrappedMedia::UnwrappedMedia( not_null parent, std::unique_ptr content) @@ -387,6 +393,10 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const { return result; } +std::unique_ptr UnwrappedMedia::stickerTakeLottie() { + return _content->stickerTakeLottie(); +} + int UnwrappedMedia::calculateFullRight(const QRect &inner) const { const auto rightAligned = _parent->hasOutLayout() && !Adaptive::ChatWide(); const auto infoWidth = _parent->infoWidth() diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h index 509693b59..6a4b01404 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h @@ -32,8 +32,9 @@ public: [[nodiscard]] virtual DocumentData *document() { return nullptr; } - virtual void clearStickerLoopPlayed() { + virtual void stickerClearLoopPlayed() { } + virtual std::unique_ptr stickerTakeLottie(); virtual bool hasHeavyPart() const { return false; } @@ -81,9 +82,10 @@ public: bool hidesForwardedInfo() const override { return _content->hidesForwardedInfo(); } - void clearStickerLoopPlayed() override { - _content->clearStickerLoopPlayed(); + void stickerClearLoopPlayed() override { + _content->stickerClearLoopPlayed(); } + std::unique_ptr stickerTakeLottie() override; bool hasHeavyPart() const override { return _content->hasHeavyPart(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp index f1aa03eb9..01c4254c2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp @@ -57,11 +57,22 @@ namespace { Sticker::Sticker( not_null parent, not_null data, + Element *replacing, const Lottie::ColorReplacements *replacements) : _parent(parent) , _data(data) , _replacements(replacements) { - _data->loadThumbnail(parent->data()->fullId()); + if ((_dataMedia = _data->activeMediaView())) { + dataMediaCreated(); + } else { + _data->loadThumbnail(parent->data()->fullId()); + } + if (const auto media = replacing ? replacing->media() : nullptr) { + _lottie = media->stickerTakeLottie(); + if (_lottie) { + lottieCreated(); + } + } } Sticker::~Sticker() { @@ -266,6 +277,12 @@ void Sticker::ensureDataMediaCreated() const { return; } _dataMedia = _data->createMediaView(); + dataMediaCreated(); +} + +void Sticker::dataMediaCreated() const { + Expects(_dataMedia != nullptr); + _dataMedia->goodThumbnailWanted(); _dataMedia->thumbnailWanted(_parent->data()->fullId()); _parent->history()->owner().registerHeavyViewPart(_parent); @@ -285,6 +302,12 @@ void Sticker::setupLottie() { Stickers::LottieSize::MessageHistory, _size * cIntRetinaFactor(), Lottie::Quality::High); + lottieCreated(); +} + +void Sticker::lottieCreated() { + Expects(_lottie != nullptr); + _parent->history()->owner().registerHeavyViewPart(_parent); _lottie->updates( @@ -318,4 +341,8 @@ void Sticker::unloadLottie() { _parent->checkHeavyPart(); } +std::unique_ptr< Lottie::SinglePlayer> Sticker::stickerTakeLottie() { + return std::move(_lottie); +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.h b/Telegram/SourceFiles/history/view/media/history_view_sticker.h index 7c874d6ee..468748267 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.h +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.h @@ -33,6 +33,7 @@ public: Sticker( not_null parent, not_null data, + Element *replacing = nullptr, const Lottie::ColorReplacements *replacements = nullptr); ~Sticker(); @@ -46,9 +47,10 @@ public: DocumentData *document() override { return _data; } - void clearStickerLoopPlayed() override { + void stickerClearLoopPlayed() override { _lottieOncePlayed = false; } + std::unique_ptr stickerTakeLottie() override; bool hasHeavyPart() const override; void unloadHeavyPart() override; @@ -74,8 +76,10 @@ private: [[nodiscard]] QPixmap paintedPixmap(bool selected) const; void ensureDataMediaCreated() const; + void dataMediaCreated() const; void setupLottie(); + void lottieCreated(); void unloadLottie(); const not_null _parent; diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index e574e7b8d..1160b2f46 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "layout.h" #include "core/click_handler_types.h" +#include "core/ui_integration.h" #include "lang/lang_keys.h" #include "history/history_item_components.h" #include "history/history_item.h" @@ -199,10 +200,17 @@ QSize WebPage::countOptimalSize() { - st::msgPadding.right() - st::webPageLeft); } + auto context = Core::UiIntegration::Context(); + if (_data->siteName == qstr("Twitter")) { + context.type = Core::UiIntegration::HashtagMentionType::Twitter; + } else if (_data->siteName == qstr("Instagram")) { + context.type = Core::UiIntegration::HashtagMentionType::Instagram; + } _description.setMarkedText( st::webPageDescriptionStyle, text, - Ui::WebpageTextDescriptionOptions(_data->siteName)); + Ui::WebpageTextDescriptionOptions(), + context); } if (!displayedSiteName().isEmpty()) { _siteNameLines = 1; diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 3202b95ec..b39d4c15d 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -2107,11 +2107,11 @@ void ListWidget::mouseActionFinish( //_widget->noSelectingScroll(); // #TODO scroll by drag //_widget->updateTopBarSelection(); -#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#if defined Q_OS_UNIX && !defined Q_OS_MAC //if (hasSelectedText()) { // #TODO linux clipboard // TextUtilities::SetClipboardText(_selected.cbegin()->first->selectedText(_selected.cbegin()->second), QClipboard::Selection); //} -#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // Q_OS_UNIX && !Q_OS_MAC } void ListWidget::applyDragSelection() { diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index 3617ac64d..7bd6f7c6f 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -550,7 +550,7 @@ void Sticker::prepareThumbnail() const { } _dataMedia->checkStickerSmall(); if (const auto sticker = _dataMedia->getStickerSmall()) { - if (!_lottie && !_thumbLoaded && _dataMedia->loaded()) { + if (!_lottie && !_thumbLoaded) { const auto thumbSize = getThumbSize(); _thumb = sticker->pix( thumbSize.width(), @@ -679,8 +679,6 @@ Video::Video(not_null context, not_null result) , _link(getResultPreviewHandler()) , _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) , _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) { - Assert(getResultDocument() != nullptr); - if (int duration = content_duration()) { _duration = formatDurationText(duration); _durationWidth = st::normalFont->width(_duration); @@ -688,10 +686,12 @@ Video::Video(not_null context, not_null result) } bool Video::withThumbnail() const { - const auto document = getShownDocument(); - Assert(document != nullptr); - - return document->hasThumbnail(); + if (const auto document = getShownDocument()) { + if (document->hasThumbnail()) { + return true; + } + } + return hasResultThumb(); } void Video::initDimensions() { @@ -761,6 +761,7 @@ void Video::paint(Painter &p, const QRect &clip, const PaintContext *context) co void Video::unloadHeavyPart() { _documentMedia = nullptr; + ItemBase::unloadHeavyPart(); } TextState Video::getState( @@ -776,17 +777,20 @@ TextState Video::getState( } void Video::prepareThumbnail(QSize size) const { - const auto document = getShownDocument(); - if (document->hasThumbnail()) { - if (!_documentMedia) { - _documentMedia = document->createMediaView(); - _documentMedia->thumbnailWanted(fileOrigin()); - } - if (!_documentMedia->thumbnail()) { - return; + if (const auto document = getShownDocument()) { + if (document->hasThumbnail()) { + if (!_documentMedia) { + _documentMedia = document->createMediaView(); + _documentMedia->thumbnailWanted(fileOrigin()); + } + if (!_documentMedia->thumbnail()) { + return; + } } } - const auto thumb = _documentMedia->thumbnail(); + const auto thumb = _documentMedia + ? _documentMedia->thumbnail() + : getResultThumb(fileOrigin()); if (!thumb) { return; } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp index 10b84c87d..1417c14a5 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp @@ -162,7 +162,6 @@ std::unique_ptr Result::Create( } } else if (result->_type == Type::Audio || result->_type == Type::File - || result->_type == Type::Video || result->_type == Type::Sticker || result->_type == Type::Gif) { if (!result->_document) { @@ -175,24 +174,28 @@ std::unique_ptr Result::Create( const auto &r = message->c_botInlineMessageMediaAuto(); const auto message = qs(r.vmessage()); const auto entities = Api::EntitiesFromMTP( + session, r.ventities().value_or_empty()); if (result->_type == Type::Photo) { if (!result->_photo) { return nullptr; } result->sendData = std::make_unique( + session, result->_photo, message, entities); } else if (result->_type == Type::Game) { result->createGame(); result->sendData = std::make_unique( + session, result->_game); } else { if (!result->_document) { return nullptr; } result->sendData = std::make_unique( + session, result->_document, message, entities); @@ -205,22 +208,10 @@ std::unique_ptr Result::Create( case mtpc_botInlineMessageText: { const auto &r = message->c_botInlineMessageText(); result->sendData = std::make_unique( + session, qs(r.vmessage()), - Api::EntitiesFromMTP(r.ventities().value_or_empty()), + Api::EntitiesFromMTP(session, r.ventities().value_or_empty()), r.is_no_webpage()); - if (result->_type == Type::Photo) { - if (!result->_photo) { - return nullptr; - } - } else if (result->_type == Type::Audio - || result->_type == Type::File - || result->_type == Type::Video - || result->_type == Type::Sticker - || result->_type == Type::Gif) { - if (!result->_document) { - return nullptr; - } - } if (const auto markup = r.vreply_markup()) { result->_mtpKeyboard = std::make_unique(*markup); } @@ -230,7 +221,9 @@ std::unique_ptr Result::Create( // #TODO layer 72 save period and send live location?.. auto &r = message->c_botInlineMessageMediaGeo(); if (r.vgeo().type() == mtpc_geoPoint) { - result->sendData = std::make_unique(r.vgeo().c_geoPoint()); + result->sendData = std::make_unique( + session, + r.vgeo().c_geoPoint()); } else { badAttachment = true; } @@ -242,7 +235,13 @@ std::unique_ptr Result::Create( case mtpc_botInlineMessageMediaVenue: { auto &r = message->c_botInlineMessageMediaVenue(); if (r.vgeo().type() == mtpc_geoPoint) { - result->sendData = std::make_unique(r.vgeo().c_geoPoint(), qs(r.vvenue_id()), qs(r.vprovider()), qs(r.vtitle()), qs(r.vaddress())); + result->sendData = std::make_unique( + session, + r.vgeo().c_geoPoint(), + qs(r.vvenue_id()), + qs(r.vprovider()), + qs(r.vtitle()), + qs(r.vaddress())); } else { badAttachment = true; } @@ -253,7 +252,11 @@ std::unique_ptr Result::Create( case mtpc_botInlineMessageMediaContact: { auto &r = message->c_botInlineMessageMediaContact(); - result->sendData = std::make_unique(qs(r.vfirst_name()), qs(r.vlast_name()), qs(r.vphone_number())); + result->sendData = std::make_unique( + session, + qs(r.vfirst_name()), + qs(r.vlast_name()), + qs(r.vphone_number())); if (const auto markup = r.vreply_markup()) { result->_mtpKeyboard = std::make_unique(*markup); } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp index 62ef1c29c..22391e413 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp @@ -79,7 +79,7 @@ QString SendDataCommon::getErrorOnSend( SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const { SentMTPMessageFields result; result.text = MTP_string(_message); - result.entities = Api::EntitiesToMTP(_entities); + result.entities = Api::EntitiesToMTP(&session(), _entities); return result; } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h index 745a69573..bcc5aabfd 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h @@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_location_manager.h" +namespace Main { +class Session; +} // namespace Main + class History; namespace InlineBots { @@ -22,11 +26,16 @@ namespace internal { // For each type of message that can be sent there will be a subclass. class SendData { public: - SendData() = default; + explicit SendData(not_null session) : _session(session) { + } SendData(const SendData &other) = delete; SendData &operator=(const SendData &other) = delete; virtual ~SendData() = default; + [[nodiscard]] Main::Session &session() const { + return *_session; + } + virtual bool isValid() const = 0; virtual void addToHistory( @@ -54,6 +63,9 @@ public: virtual QString getLayoutTitle(const Result *owner) const; virtual QString getLayoutDescription(const Result *owner) const; +private: + not_null _session; + }; // This class implements addHistory() for most of the types hiding @@ -61,6 +73,8 @@ public: // Only SendFile and SendPhoto work by their own. class SendDataCommon : public SendData { public: + using SendData::SendData; + struct SentMTPMessageFields { MTPString text = MTP_string(); MTPVector entities = MTP_vector(); @@ -91,10 +105,12 @@ public: class SendText : public SendDataCommon { public: SendText( + not_null session, const QString &message, const EntitiesInText &entities, bool/* noWebPage*/) - : _message(message) + : SendDataCommon(session) + , _message(message) , _entities(entities) { } @@ -113,7 +129,11 @@ private: // Message with geo location point media. class SendGeo : public SendDataCommon { public: - explicit SendGeo(const MTPDgeoPoint &point) : _location(point) { + SendGeo( + not_null session, + const MTPDgeoPoint &point) + : SendDataCommon(session) + , _location(point) { } bool isValid() const override { @@ -137,13 +157,19 @@ private: // Message with venue media. class SendVenue : public SendDataCommon { public: - SendVenue(const MTPDgeoPoint &point, const QString &venueId, - const QString &provider, const QString &title, const QString &address) - : _location(point) - , _venueId(venueId) - , _provider(provider) - , _title(title) - , _address(address) { + SendVenue( + not_null session, + const MTPDgeoPoint &point, + const QString &venueId, + const QString &provider, + const QString &title, + const QString &address) + : SendDataCommon(session) + , _location(point) + , _venueId(venueId) + , _provider(provider) + , _title(title) + , _address(address) { } bool isValid() const override { @@ -168,10 +194,15 @@ private: // Message with shared contact media. class SendContact : public SendDataCommon { public: - SendContact(const QString &firstName, const QString &lastName, const QString &phoneNumber) - : _firstName(firstName) - , _lastName(lastName) - , _phoneNumber(phoneNumber) { + SendContact( + not_null session, + const QString &firstName, + const QString &lastName, + const QString &phoneNumber) + : SendDataCommon(session) + , _firstName(firstName) + , _lastName(lastName) + , _phoneNumber(phoneNumber) { } bool isValid() const override { @@ -191,10 +222,12 @@ private: class SendPhoto : public SendData { public: SendPhoto( + not_null session, PhotoData *photo, const QString &message, const EntitiesInText &entities) - : _photo(photo) + : SendData(session) + , _photo(photo) , _message(message) , _entities(entities) { } @@ -231,10 +264,12 @@ private: class SendFile : public SendData { public: SendFile( + not_null session, DocumentData *document, const QString &message, const EntitiesInText &entities) - : _document(document) + : SendData(session) + , _document(document) , _message(message) , _entities(entities) { } @@ -270,8 +305,9 @@ private: // Message with game. class SendGame : public SendData { public: - SendGame(GameData *game) - : _game(game) { + SendGame(not_null session, GameData *game) + : SendData(session) + , _game(game) { } bool isValid() const override { diff --git a/Telegram/SourceFiles/intro/intro_code.cpp b/Telegram/SourceFiles/intro/intro_code.cpp index 25e3a455a..02d038af5 100644 --- a/Telegram/SourceFiles/intro/intro_code.cpp +++ b/Telegram/SourceFiles/intro/intro_code.cpp @@ -248,7 +248,9 @@ void CodeWidget::codeSubmitDone(const MTPauth_Authorization &result) { }, [&](const MTPDauth_authorizationSignUpRequired &data) { if (const auto terms = data.vterms_of_service()) { terms->match([&](const MTPDhelp_termsOfService &data) { - getData()->termsLock = Window::TermsLock::FromMTP(data); + getData()->termsLock = Window::TermsLock::FromMTP( + nullptr, + data); }); } else { getData()->termsLock = Window::TermsLock(); diff --git a/Telegram/SourceFiles/intro/intro_widget.cpp b/Telegram/SourceFiles/intro/intro_widget.cpp index 87e048d83..bb8a0e67c 100644 --- a/Telegram/SourceFiles/intro/intro_widget.cpp +++ b/Telegram/SourceFiles/intro/intro_widget.cpp @@ -146,7 +146,7 @@ void Widget::handleUpdate(const MTPUpdate &update) { }, [&](const MTPDupdateServiceNotification &data) { const auto text = TextWithEntities{ qs(data.vmessage()), - Api::EntitiesFromMTP(data.ventities().v) + Api::EntitiesFromMTP(nullptr, data.ventities().v) }; Ui::show(Box(text)); }, [](const auto &) {}); diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index f7479b725..cfbc69a84 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -343,7 +343,7 @@ void start(not_null launcher) { workingDirChosen = true; } else { -#if defined Q_OS_MAC || defined Q_OS_LINUX +#ifdef Q_OS_UNIX if (!cWorkingDir().isEmpty()) { // This value must come from TelegramForcePortable @@ -358,16 +358,16 @@ void start(not_null launcher) { } workingDirChosen = true; -#if defined Q_OS_LINUX && !defined _DEBUG // fix first version +#if !defined Q_OS_MAC && !defined _DEBUG // fix first version moveOldDataFrom = initialWorkingDir; -#endif // Q_OS_LINUX && !_DEBUG +#endif // !Q_OS_MAC && !_DEBUG -#elif defined Q_OS_WINRT // Q_OS_MAC || Q_OS_LINUX +#elif defined Q_OS_WINRT // Q_OS_UNIX cForceWorkingDir(psAppDataPath()); workingDirChosen = true; -#elif defined OS_WIN_STORE // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT +#elif defined OS_WIN_STORE // Q_OS_UNIX || Q_OS_WINRT #ifdef _DEBUG cForceWorkingDir(cExeDir()); @@ -385,7 +385,7 @@ void start(not_null launcher) { workingDirChosen = true; } -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || OS_WIN_STORE +#endif // Q_OS_UNIX || Q_OS_WINRT || OS_WIN_STORE } @@ -561,7 +561,7 @@ void writeDebug(const char *file, int32 line, const QString &v) { //OutputDebugString(reinterpret_cast(msg.utf16())); #elif defined Q_OS_MAC //objc_outputDebugString(msg); -#elif defined Q_OS_LINUX && defined _DEBUG +#elif defined Q_OS_UNIX && defined _DEBUG //std::cout << msg.toUtf8().constData(); #endif } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 59c98b85d..610170dc5 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -400,6 +400,15 @@ MainWidget::MainWidget( floatPlayerClosed(itemId); }, lifetime()); + // Load current userpic and keep it loaded. + Notify::PeerUpdateValue( + session().user(), + Notify::PeerUpdate::Flag::PhotoChanged + ) | rpl::start_with_next([=] { + [[maybe_unused]] const auto image = session().user()->currentUserpic( + _selfUserpicView); + }, lifetime()); + _ptsWaiter.setRequesting(true); updateScrollColors(); setupConnectingWidget(); @@ -3821,7 +3830,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) { } item->updateSentContent({ sent.text, - Api::EntitiesFromMTP(list.value_or_empty()) + Api::EntitiesFromMTP(&session(), list.value_or_empty()) }, d.vmedia()); item->contributeToSlowmode(d.vdate().v); if (!wasAlready) { @@ -4330,7 +4339,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { const auto &d = update.c_updateServiceNotification(); const auto text = TextWithEntities { qs(d.vmessage()), - Api::EntitiesFromMTP(d.ventities().v) + Api::EntitiesFromMTP(&session(), d.ventities().v) }; if (IsForceLogoutNotification(d)) { Core::App().forceLogOut(text); @@ -4604,9 +4613,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { const auto &data = update.c_updateDraftMessage(); const auto peerId = peerFromMTP(data.vpeer()); data.vdraft().match([&](const MTPDdraftMessage &data) { - Data::applyPeerCloudDraft(peerId, data); + Data::ApplyPeerCloudDraft(&session(), peerId, data); }, [&](const MTPDdraftMessageEmpty &data) { - Data::clearPeerCloudDraft( + Data::ClearPeerCloudDraft( + &session(), peerId, data.vdate().value_or_empty()); }); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 843e0cda5..01835f3d3 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -38,6 +38,7 @@ struct PeerUpdate; namespace Data { class WallPaper; +class CloudImageView; } // namespace Data namespace Dialogs { @@ -107,7 +108,9 @@ class MainWidget public: using SectionShow = Window::SectionShow; - MainWidget(QWidget *parent, not_null controller); + MainWidget( + QWidget *parent, + not_null controller); [[nodiscard]] Main::Session &session() const; @@ -463,6 +466,8 @@ private: int _thirdColumnWidth = 0; Ui::Animations::Simple _a_dialogsWidth; + std::shared_ptr _selfUserpicView; + object_ptr _sideShadow; object_ptr _thirdShadow = { nullptr }; object_ptr _firstColumnResizeArea = { nullptr }; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index f37ad5101..7031e0e31 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -139,7 +139,7 @@ void MainWindow::createTrayIconMenu() { ? tr::ktg_settings_disable_sound_from_tray(tr::now) : tr::ktg_settings_enable_sound_from_tray(tr::now); - if (Platform::IsLinux()) { + if (Platform::IsLinux() && !Platform::IsWayland()) { trayIconMenu->addAction(tr::ktg_open_from_tray(tr::now), this, SLOT(showFromTray())); } trayIconMenu->addAction(tr::lng_minimize_to_tray(tr::now), this, SLOT(minimizeToTray())); @@ -593,12 +593,12 @@ void MainWindow::updateTrayMenu(bool force) { if (!trayIconMenu || (Platform::IsWindows() && !force)) return; auto actions = trayIconMenu->actions(); - if (Platform::IsLinux()) { + if (Platform::IsLinux() && !Platform::IsWayland()) { auto minimizeAction = actions.at(1); minimizeAction->setEnabled(isVisible()); } else { updateIsActive(0); - auto active = isActive(); + auto active = Platform::IsWayland() ? isVisible() : isActive(); auto toggleAction = actions.at(0); disconnect(toggleAction, SIGNAL(triggered(bool)), this, SLOT(minimizeToTray())); disconnect(toggleAction, SIGNAL(triggered(bool)), this, SLOT(showFromTray())); @@ -607,7 +607,7 @@ void MainWindow::updateTrayMenu(bool force) { ? tr::lng_minimize_to_tray(tr::now) : tr::ktg_open_from_tray(tr::now)); } - auto notificationAction = actions.at(Platform::IsLinux() ? 2 : 1); + auto notificationAction = actions.at(Platform::IsLinux() && !Platform::IsWayland() ? 2 : 1); auto notificationActionText = Global::DesktopNotify() ? tr::lng_disable_notifications_from_tray(tr::now) : tr::lng_enable_notifications_from_tray(tr::now); @@ -738,7 +738,7 @@ void MainWindow::handleTrayIconActication( updateTrayMenu(true); QTimer::singleShot(1, this, SLOT(psShowTrayMenu())); } else if (!skipTrayClick()) { - if (isActive()) { + if (Platform::IsWayland() ? isVisible() : isActive()) { minimizeToTray(); } else { showFromTray(reason); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index a1aca5b3a..0f74011aa 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -353,11 +353,11 @@ OverlayWidget::OverlayWidget() } }, lifetime()); -#ifdef Q_OS_LINUX +#if defined Q_OS_UNIX && !defined Q_OS_MAC setWindowFlags(Qt::FramelessWindowHint | Qt::MaximizeUsingFullscreenGeometryHint); -#else // Q_OS_LINUX +#else // Q_OS_UNIX && !Q_OS_MAC setWindowFlags(Qt::FramelessWindowHint); -#endif // Q_OS_LINUX +#endif // Q_OS_UNIX && !Q_OS_MAC moveToScreen(); setAttribute(Qt::WA_NoSystemBackground, true); setAttribute(Qt::WA_TranslucentBackground, true); @@ -1538,6 +1538,21 @@ Data::FileOrigin OverlayWidget::fileOrigin() const { return Data::FileOrigin(); } +Data::FileOrigin OverlayWidget::fileOrigin(const Entity &entity) const { + if (const auto item = entity.item) { + return item->fullId(); + } else if (!entity.data.is>()) { + return Data::FileOrigin(); + } + const auto photo = entity.data.get_unchecked>(); + if (_user) { + return Data::FileOriginUserPhoto(_user->bareId(), photo->id); + } else if (_peer && _peer->userpicPhotoId() == photo->id) { + return Data::FileOriginPeerPhoto(_peer->id); + } + return Data::FileOrigin(); +} + bool OverlayWidget::validSharedMedia() const { if (auto key = sharedMediaKey()) { if (!_sharedMedia) { @@ -1883,8 +1898,6 @@ void OverlayWidget::showPhoto(not_null photo, HistoryItem *context) _firstOpenedPeerPhoto = false; assignMediaPointer(photo); - refreshMediaViewer(); - displayPhoto(photo, context); preloadData(0); activateControls(); @@ -1897,8 +1910,6 @@ void OverlayWidget::showPhoto(not_null photo, not_null co _firstOpenedPeerPhoto = true; assignMediaPointer(photo); - refreshMediaViewer(); - displayPhoto(photo, nullptr); preloadData(0); activateControls(); @@ -2031,6 +2042,7 @@ void OverlayWidget::displayDocument( initThemePreview(); } else { _documentMedia->automaticLoad(fileOrigin(), item); + _document->saveFromDataSilent(); auto &location = _document->location(true); if (location.accessEnable()) { const auto &path = location.name(); @@ -2144,11 +2156,11 @@ void OverlayWidget::displayFinished() { updateControls(); if (isHidden()) { Ui::Platform::UpdateOverlayed(this); -#ifdef Q_OS_LINUX +#if defined Q_OS_UNIX && !defined Q_OS_MAC showFullScreen(); -#else // Q_OS_LINUX +#else // Q_OS_UNIX && !Q_OS_MAC show(); -#endif // Q_OS_LINUX +#endif // Q_OS_UNIX && !Q_OS_MAC Ui::Platform::ShowOverAll(this); activateWindow(); QApplication::setActiveWindow(this); @@ -3420,16 +3432,17 @@ OverlayWidget::Entity OverlayWidget::entityByIndex(int index) const { return { std::nullopt, nullptr }; } -void OverlayWidget::setContext(base::optional_variant< +void OverlayWidget::setContext( + base::optional_variant< not_null, not_null> context) { - if (auto item = base::get_if>(&context)) { + if (const auto item = base::get_if>(&context)) { _msgid = (*item)->fullId(); _canForwardItem = (*item)->allowsForward(); _canDeleteItem = (*item)->canDelete(); _history = (*item)->history(); _peer = _history->peer; - } else if (auto peer = base::get_if>(&context)) { + } else if (const auto peer = base::get_if>(&context)) { _msgid = FullMsgId(); _canForwardItem = _canDeleteItem = false; _history = (*peer)->owner().history(*peer); @@ -3498,15 +3511,15 @@ void OverlayWidget::preloadData(int delta) { auto entity = entityByIndex(index); if (auto photo = base::get_if>(&entity.data)) { const auto [i, ok] = photos.emplace((*photo)->createMediaView()); - (*i)->wanted(Data::PhotoSize::Small, fileOrigin()); - (*photo)->load(fileOrigin(), LoadFromCloudOrLocal, true); + (*i)->wanted(Data::PhotoSize::Small, fileOrigin(entity)); + (*photo)->load(fileOrigin(entity), LoadFromCloudOrLocal, true); } else if (auto document = base::get_if>( &entity.data)) { const auto [i, ok] = documents.emplace( (*document)->createMediaView()); - (*i)->thumbnailWanted(fileOrigin()); + (*i)->thumbnailWanted(fileOrigin(entity)); if (!(*i)->canBePlayed()) { - (*i)->automaticLoad(fileOrigin(), entity.item); + (*i)->automaticLoad(fileOrigin(entity), entity.item); } } } diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 5ccabe462..34c2673cf 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -239,7 +239,8 @@ private: bool validCollage() const; void validateCollage(); - Data::FileOrigin fileOrigin() const; + [[nodiscard]] Data::FileOrigin fileOrigin() const; + [[nodiscard]] Data::FileOrigin fileOrigin(const Entity& entity) const; void refreshFromLabel(HistoryItem *item); void refreshCaption(HistoryItem *item); diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp index f026db604..c129c2616 100644 --- a/Telegram/SourceFiles/media/view/media_view_pip.cpp +++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp @@ -438,7 +438,8 @@ PipPanel::Position PipPanel::countPosition() const { const auto right = left + result.geometry.width(); const auto top = result.geometry.y(); const auto bottom = top + result.geometry.height(); - if (!_dragState || *_dragState != RectPart::Center) { + if ((!_dragState || *_dragState != RectPart::Center) + && !Platform::IsWayland()) { if (left == available.x()) { result.attached |= RectPart::Left; } else if (right == available.x() + available.width()) { @@ -514,6 +515,11 @@ void PipPanel::setPositionOnScreen(Position position, QRect available) { std::max(normalized.width(), minimalSize.width()), std::max(normalized.height(), minimalSize.height())); + // Apply maximal size. + const auto maximalSize = (_ratio.width() > _ratio.height()) + ? QSize(fit.width(), fit.width() * _ratio.height() / _ratio.width()) + : QSize(fit.height() * _ratio.width() / _ratio.height(), fit.height()); + // Apply left-right screen borders. const auto skip = st::pipBorderSkip; const auto inner = screen.marginsRemoved({ skip, skip, skip, skip }); @@ -547,8 +553,10 @@ void PipPanel::setPositionOnScreen(Position position, QRect available) { geometry += _padding; setGeometry(geometry); - setMinimumSize(geometry.size()); - setMaximumSize(geometry.size()); + setMinimumSize(minimalSize); + setMaximumSize( + std::max(minimalSize.width(), maximalSize.width()), + std::max(minimalSize.height(), maximalSize.height())); updateDecorations(); update(); } @@ -671,6 +679,40 @@ void PipPanel::mouseMoveEvent(QMouseEvent *e) { if (!_dragState && (point - _pressPoint).manhattanLength() > distance && !_dragDisabled) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED + if (Platform::IsWayland()) { + switch (*_pressState) { + case RectPart::Center: + windowHandle()->startSystemMove(); + break; + case RectPart::TopLeft: + windowHandle()->startSystemResize(Qt::TopEdge | Qt::LeftEdge); + break; + case RectPart::TopRight: + windowHandle()->startSystemResize(Qt::TopEdge | Qt::RightEdge); + break; + case RectPart::BottomRight: + windowHandle()->startSystemResize(Qt::BottomEdge | Qt::RightEdge); + break; + case RectPart::BottomLeft: + windowHandle()->startSystemResize(Qt::BottomEdge | Qt::LeftEdge); + break; + case RectPart::Left: + windowHandle()->startSystemResize(Qt::LeftEdge); + break; + case RectPart::Top: + windowHandle()->startSystemResize(Qt::TopEdge); + break; + case RectPart::Right: + windowHandle()->startSystemResize(Qt::RightEdge); + break; + case RectPart::Bottom: + windowHandle()->startSystemResize(Qt::BottomEdge); + break; + } + return; + } +#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED _dragState = _pressState; updateDecorations(); _dragStartGeometry = geometry().marginsRemoved(_padding); @@ -722,8 +764,6 @@ void PipPanel::processDrag(QPoint point) { const auto newGeometry = valid.marginsAdded(_padding); _positionAnimation.stop(); setGeometry(newGeometry); - setMinimumSize(newGeometry.size()); - setMaximumSize(newGeometry.size()); } } @@ -810,8 +850,6 @@ void PipPanel::updateDecorations() { _useTransparency = use; setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency); setGeometry(newGeometry); - setMinimumSize(newGeometry.size()); - setMaximumSize(newGeometry.size()); update(); } diff --git a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp index 92c028651..65c43d9c8 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gdk_helper.cpp @@ -72,10 +72,10 @@ bool GdkHelperLoadGtk3(QLibrary &lib) { void GdkHelperLoad(QLibrary &lib) { gdk_helper_loaded = GtkLoaded::GtkNone; - if (GdkHelperLoadGtk2(lib)) { - gdk_helper_loaded = GtkLoaded::Gtk2; - } else if (GdkHelperLoadGtk3(lib)) { + if (GdkHelperLoadGtk3(lib)) { gdk_helper_loaded = GtkLoaded::Gtk3; + } else if (GdkHelperLoadGtk2(lib)) { + gdk_helper_loaded = GtkLoaded::Gtk2; } } diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.cpp b/Telegram/SourceFiles/platform/linux/linux_libs.cpp index 3465099cb..9e94a18b1 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libs.cpp @@ -69,24 +69,19 @@ void gtkMessageHandler( bool setupGtkBase(QLibrary &lib_gtk) { if (!load(lib_gtk, "gtk_init_check", gtk_init_check)) return false; if (!load(lib_gtk, "gtk_settings_get_default", gtk_settings_get_default)) return false; - if (!load(lib_gtk, "gtk_menu_new", gtk_menu_new)) return false; - if (!load(lib_gtk, "gtk_menu_get_type", gtk_menu_get_type)) return false; - if (!load(lib_gtk, "gtk_menu_item_new_with_label", gtk_menu_item_new_with_label)) return false; - if (!load(lib_gtk, "gtk_menu_item_set_label", gtk_menu_item_set_label)) return false; - if (!load(lib_gtk, "gtk_menu_shell_append", gtk_menu_shell_append)) return false; - if (!load(lib_gtk, "gtk_menu_shell_get_type", gtk_menu_shell_get_type)) return false; if (!load(lib_gtk, "gtk_widget_show", gtk_widget_show)) return false; if (!load(lib_gtk, "gtk_widget_hide", gtk_widget_hide)) return false; - if (!load(lib_gtk, "gtk_widget_get_toplevel", gtk_widget_get_toplevel)) return false; - if (!load(lib_gtk, "gtk_widget_get_visible", gtk_widget_get_visible)) return false; if (!load(lib_gtk, "gtk_widget_get_window", gtk_widget_get_window)) return false; - if (!load(lib_gtk, "gtk_widget_set_sensitive", gtk_widget_set_sensitive)) return false; if (!load(lib_gtk, "gtk_widget_realize", gtk_widget_realize)) return false; if (!load(lib_gtk, "gtk_widget_hide_on_delete", gtk_widget_hide_on_delete)) return false; if (!load(lib_gtk, "gtk_widget_destroy", gtk_widget_destroy)) return false; if (!load(lib_gtk, "gtk_clipboard_get", gtk_clipboard_get)) return false; if (!load(lib_gtk, "gtk_clipboard_store", gtk_clipboard_store)) return false; + if (!load(lib_gtk, "gtk_clipboard_wait_for_contents", gtk_clipboard_wait_for_contents)) return false; + if (!load(lib_gtk, "gtk_clipboard_wait_for_image", gtk_clipboard_wait_for_image)) return false; + if (!load(lib_gtk, "gtk_selection_data_targets_include_image", gtk_selection_data_targets_include_image)) return false; + if (!load(lib_gtk, "gtk_selection_data_free", gtk_selection_data_free)) return false; if (!load(lib_gtk, "gtk_file_chooser_dialog_new", gtk_file_chooser_dialog_new)) return false; if (!load(lib_gtk, "gtk_file_chooser_get_type", gtk_file_chooser_get_type)) return false; if (!load(lib_gtk, "gtk_image_get_type", gtk_image_get_type)) return false; @@ -122,22 +117,23 @@ bool setupGtkBase(QLibrary &lib_gtk) { if (!load(lib_gtk, "g_type_check_instance_cast", g_type_check_instance_cast)) return false; if (!load(lib_gtk, "g_type_check_instance_is_a", g_type_check_instance_is_a)) return false; if (!load(lib_gtk, "g_signal_connect_data", g_signal_connect_data)) return false; - if (!load(lib_gtk, "g_signal_handler_disconnect", g_signal_handler_disconnect)) return false; if (!load(lib_gtk, "g_object_get", g_object_get)) return false; - if (!load(lib_gtk, "g_object_ref_sink", g_object_ref_sink)) return false; if (!load(lib_gtk, "g_object_unref", g_object_unref)) return false; if (!load(lib_gtk, "g_free", g_free)) return false; - if (!load(lib_gtk, "g_list_foreach", g_list_foreach)) return false; - if (!load(lib_gtk, "g_list_free", g_list_free)) return false; - if (!load(lib_gtk, "g_list_free_full", g_list_free_full)) return false; - if (!load(lib_gtk, "g_error_free", g_error_free)) return false; if (!load(lib_gtk, "g_slist_free", g_slist_free)) return false; if (!load(lib_gtk, "g_log_set_handler", g_log_set_handler)) return false; if (!load(lib_gtk, "g_log_default_handler", g_log_default_handler)) return false; + if (!load(lib_gtk, "gdk_atom_intern", gdk_atom_intern)) return false; + if (!load(lib_gtk, "gdk_pixbuf_get_has_alpha", gdk_pixbuf_get_has_alpha)) return false; + if (!load(lib_gtk, "gdk_pixbuf_get_pixels", gdk_pixbuf_get_pixels)) return false; + if (!load(lib_gtk, "gdk_pixbuf_get_width", gdk_pixbuf_get_width)) return false; + if (!load(lib_gtk, "gdk_pixbuf_get_height", gdk_pixbuf_get_height)) return false; + if (!load(lib_gtk, "gdk_pixbuf_get_rowstride", gdk_pixbuf_get_rowstride)) return false; + if (load(lib_gtk, "gdk_set_allowed_backends", gdk_set_allowed_backends)) { // We work only with X11 GDK backend. // Otherwise we get segfault in Ubuntu 17.04 in gtk_init_check() call. @@ -178,23 +174,18 @@ bool setupGtkBase(QLibrary &lib_gtk) { #ifndef TDESKTOP_DISABLE_GTK_INTEGRATION f_gtk_init_check gtk_init_check = nullptr; f_gtk_settings_get_default gtk_settings_get_default = nullptr; -f_gtk_menu_new gtk_menu_new = nullptr; -f_gtk_menu_get_type gtk_menu_get_type = nullptr; -f_gtk_menu_item_new_with_label gtk_menu_item_new_with_label = nullptr; -f_gtk_menu_item_set_label gtk_menu_item_set_label = nullptr; -f_gtk_menu_shell_append gtk_menu_shell_append = nullptr; -f_gtk_menu_shell_get_type gtk_menu_shell_get_type = nullptr; f_gtk_widget_show gtk_widget_show = nullptr; f_gtk_widget_hide gtk_widget_hide = nullptr; -f_gtk_widget_get_toplevel gtk_widget_get_toplevel = nullptr; -f_gtk_widget_get_visible gtk_widget_get_visible = nullptr; f_gtk_widget_get_window gtk_widget_get_window = nullptr; -f_gtk_widget_set_sensitive gtk_widget_set_sensitive = nullptr; f_gtk_widget_realize gtk_widget_realize = nullptr; f_gtk_widget_hide_on_delete gtk_widget_hide_on_delete = nullptr; f_gtk_widget_destroy gtk_widget_destroy = nullptr; f_gtk_clipboard_get gtk_clipboard_get = nullptr; f_gtk_clipboard_store gtk_clipboard_store = nullptr; +f_gtk_clipboard_wait_for_contents gtk_clipboard_wait_for_contents = nullptr; +f_gtk_clipboard_wait_for_image gtk_clipboard_wait_for_image = nullptr; +f_gtk_selection_data_targets_include_image gtk_selection_data_targets_include_image = nullptr; +f_gtk_selection_data_free gtk_selection_data_free = nullptr; f_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new = nullptr; f_gtk_file_chooser_get_type gtk_file_chooser_get_type = nullptr; f_gtk_image_get_type gtk_image_get_type = nullptr; @@ -232,32 +223,16 @@ f_gtk_dialog_run gtk_dialog_run = nullptr; f_g_type_check_instance_cast g_type_check_instance_cast = nullptr; f_g_type_check_instance_is_a g_type_check_instance_is_a = nullptr; f_g_signal_connect_data g_signal_connect_data = nullptr; -f_g_signal_handler_disconnect g_signal_handler_disconnect = nullptr; -f_gdk_init_check gdk_init_check = nullptr; -f_gdk_pixbuf_new_from_data gdk_pixbuf_new_from_data = nullptr; -f_gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file = nullptr; +f_gdk_atom_intern gdk_atom_intern = nullptr; f_gdk_pixbuf_new_from_file_at_size gdk_pixbuf_new_from_file_at_size = nullptr; -f_gtk_status_icon_new_from_pixbuf gtk_status_icon_new_from_pixbuf = nullptr; -f_gtk_status_icon_set_from_pixbuf gtk_status_icon_set_from_pixbuf = nullptr; -f_gtk_status_icon_new_from_file gtk_status_icon_new_from_file = nullptr; -f_gtk_status_icon_set_from_file gtk_status_icon_set_from_file = nullptr; -f_gtk_status_icon_set_title gtk_status_icon_set_title = nullptr; -f_gtk_status_icon_set_tooltip_text gtk_status_icon_set_tooltip_text = nullptr; -f_gtk_status_icon_set_visible gtk_status_icon_set_visible = nullptr; -f_gtk_status_icon_is_embedded gtk_status_icon_is_embedded = nullptr; -f_gtk_status_icon_get_geometry gtk_status_icon_get_geometry = nullptr; -f_gtk_status_icon_position_menu gtk_status_icon_position_menu = nullptr; -f_gtk_menu_popup gtk_menu_popup = nullptr; -f_gtk_get_current_event_time gtk_get_current_event_time = nullptr; +f_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha = nullptr; +f_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels = nullptr; +f_gdk_pixbuf_get_width gdk_pixbuf_get_width = nullptr; +f_gdk_pixbuf_get_height gdk_pixbuf_get_height = nullptr; +f_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride = nullptr; f_g_object_get g_object_get = nullptr; -f_g_object_ref_sink g_object_ref_sink = nullptr; f_g_object_unref g_object_unref = nullptr; -f_g_idle_add g_idle_add = nullptr; f_g_free g_free = nullptr; -f_g_list_foreach g_list_foreach = nullptr; -f_g_list_free g_list_free = nullptr; -f_g_list_free_full g_list_free_full = nullptr; -f_g_error_free g_error_free = nullptr; f_g_slist_free g_slist_free = nullptr; f_g_log_set_handler g_log_set_handler = nullptr; f_g_log_default_handler g_log_default_handler = nullptr; @@ -265,6 +240,10 @@ f_g_log_default_handler g_log_default_handler = nullptr; void start() { #ifndef TDESKTOP_DISABLE_GTK_INTEGRATION + if (!UseGtkIntegration()) { + return; + } + DEBUG_LOG(("Loading libraries")); bool gtkLoaded = false; @@ -279,23 +258,7 @@ void start() { } if (gtkLoaded) { - load(lib_gtk, "gdk_init_check", gdk_init_check); - load(lib_gtk, "gdk_pixbuf_new_from_data", gdk_pixbuf_new_from_data); - load(lib_gtk, "gdk_pixbuf_new_from_file", gdk_pixbuf_new_from_file); load(lib_gtk, "gdk_pixbuf_new_from_file_at_size", gdk_pixbuf_new_from_file_at_size); - load(lib_gtk, "gtk_status_icon_new_from_pixbuf", gtk_status_icon_new_from_pixbuf); - load(lib_gtk, "gtk_status_icon_set_from_pixbuf", gtk_status_icon_set_from_pixbuf); - load(lib_gtk, "gtk_status_icon_new_from_file", gtk_status_icon_new_from_file); - load(lib_gtk, "gtk_status_icon_set_from_file", gtk_status_icon_set_from_file); - load(lib_gtk, "gtk_status_icon_set_title", gtk_status_icon_set_title); - load(lib_gtk, "gtk_status_icon_set_tooltip_text", gtk_status_icon_set_tooltip_text); - load(lib_gtk, "gtk_status_icon_set_visible", gtk_status_icon_set_visible); - load(lib_gtk, "gtk_status_icon_is_embedded", gtk_status_icon_is_embedded); - load(lib_gtk, "gtk_status_icon_get_geometry", gtk_status_icon_get_geometry); - load(lib_gtk, "gtk_status_icon_position_menu", gtk_status_icon_position_menu); - load(lib_gtk, "gtk_menu_popup", gtk_menu_popup); - load(lib_gtk, "gtk_get_current_event_time", gtk_get_current_event_time); - load(lib_gtk, "g_idle_add", g_idle_add); internal::GdkHelperLoad(lib_gtk); diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.h b/Telegram/SourceFiles/platform/linux/linux_libs.h index 472d2dcbf..3feb7387f 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.h +++ b/Telegram/SourceFiles/platform/linux/linux_libs.h @@ -47,42 +47,15 @@ extern f_gtk_init_check gtk_init_check; typedef GtkSettings* (*f_gtk_settings_get_default)(void); extern f_gtk_settings_get_default gtk_settings_get_default; -typedef GtkWidget* (*f_gtk_menu_new)(void); -extern f_gtk_menu_new gtk_menu_new; - -typedef GType (*f_gtk_menu_get_type)(void) G_GNUC_CONST; -extern f_gtk_menu_get_type gtk_menu_get_type; - -typedef GtkWidget* (*f_gtk_menu_item_new_with_label)(const gchar *label); -extern f_gtk_menu_item_new_with_label gtk_menu_item_new_with_label; - -typedef void (*f_gtk_menu_item_set_label)(GtkMenuItem *menu_item, const gchar *label); -extern f_gtk_menu_item_set_label gtk_menu_item_set_label; - -typedef void (*f_gtk_menu_shell_append)(GtkMenuShell *menu_shell, GtkWidget *child); -extern f_gtk_menu_shell_append gtk_menu_shell_append; - -typedef GType (*f_gtk_menu_shell_get_type)(void) G_GNUC_CONST; -extern f_gtk_menu_shell_get_type gtk_menu_shell_get_type; - typedef void (*f_gtk_widget_show)(GtkWidget *widget); extern f_gtk_widget_show gtk_widget_show; typedef void (*f_gtk_widget_hide)(GtkWidget *widget); extern f_gtk_widget_hide gtk_widget_hide; -typedef GtkWidget* (*f_gtk_widget_get_toplevel)(GtkWidget *widget); -extern f_gtk_widget_get_toplevel gtk_widget_get_toplevel; - -typedef gboolean (*f_gtk_widget_get_visible)(GtkWidget *widget); -extern f_gtk_widget_get_visible gtk_widget_get_visible; - typedef GdkWindow* (*f_gtk_widget_get_window)(GtkWidget *widget); extern f_gtk_widget_get_window gtk_widget_get_window; -typedef void (*f_gtk_widget_set_sensitive)(GtkWidget *widget, gboolean sensitive); -extern f_gtk_widget_set_sensitive gtk_widget_set_sensitive; - typedef void (*f_gtk_widget_realize)(GtkWidget *widget); extern f_gtk_widget_realize gtk_widget_realize; @@ -98,6 +71,18 @@ extern f_gtk_clipboard_get gtk_clipboard_get; typedef void (*f_gtk_clipboard_store)(GtkClipboard *clipboard); extern f_gtk_clipboard_store gtk_clipboard_store; +typedef GtkSelectionData* (*f_gtk_clipboard_wait_for_contents)(GtkClipboard *clipboard, GdkAtom target); +extern f_gtk_clipboard_wait_for_contents gtk_clipboard_wait_for_contents; + +typedef GdkPixbuf* (*f_gtk_clipboard_wait_for_image)(GtkClipboard *clipboard); +extern f_gtk_clipboard_wait_for_image gtk_clipboard_wait_for_image; + +typedef gboolean (*f_gtk_selection_data_targets_include_image)(const GtkSelectionData *selection_data, gboolean writable); +extern f_gtk_selection_data_targets_include_image gtk_selection_data_targets_include_image; + +typedef void (*f_gtk_selection_data_free)(GtkSelectionData *data); +extern f_gtk_selection_data_free gtk_selection_data_free; + typedef GtkWidget* (*f_gtk_file_chooser_dialog_new)(const gchar *title, GtkWindow *parent, GtkFileChooserAction action, const gchar *first_button_text, ...) G_GNUC_NULL_TERMINATED; extern f_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new; @@ -190,16 +175,6 @@ inline Result *g_type_cic_helper(Object *instance, GType iface_type) { return reinterpret_cast(g_type_check_instance_cast(reinterpret_cast(instance), iface_type)); } -template -inline GtkMenu *gtk_menu_cast(Object *obj) { - return g_type_cic_helper(obj, gtk_menu_get_type()); -} - -template -inline GtkMenuShell *gtk_menu_shell_cast(Object *obj) { - return g_type_cic_helper(obj, gtk_menu_get_type()); -} - typedef GType (*f_gtk_dialog_get_type)(void) G_GNUC_CONST; extern f_gtk_dialog_get_type gtk_dialog_get_type; @@ -273,84 +248,36 @@ inline gulong g_signal_connect_swapped_helper(gpointer instance, const gchar *de return g_signal_connect_data(instance, detailed_signal, c_handler, data, destroy_data, G_CONNECT_SWAPPED); } -typedef void (*f_g_signal_handler_disconnect)(gpointer instance, gulong handler_id); -extern f_g_signal_handler_disconnect g_signal_handler_disconnect; - -typedef gboolean (*f_gdk_init_check)(gint *argc, gchar ***argv); -extern f_gdk_init_check gdk_init_check; - -typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_data)(const guchar *data, GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, int width, int height, int rowstride, GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data); -extern f_gdk_pixbuf_new_from_data gdk_pixbuf_new_from_data; - -typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_file)(const gchar *filename, GError **error); -extern f_gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file; +typedef GdkAtom (*f_gdk_atom_intern)(const gchar *atom_name, gboolean only_if_exists); +extern f_gdk_atom_intern gdk_atom_intern; typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_file_at_size)(const gchar *filename, int width, int height, GError **error); extern f_gdk_pixbuf_new_from_file_at_size gdk_pixbuf_new_from_file_at_size; -typedef GtkStatusIcon* (*f_gtk_status_icon_new_from_pixbuf)(GdkPixbuf *pixbuf); -extern f_gtk_status_icon_new_from_pixbuf gtk_status_icon_new_from_pixbuf; +typedef gboolean (*f_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf); +extern f_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha; -typedef void (*f_gtk_status_icon_set_from_pixbuf)(GtkStatusIcon *status_icon, GdkPixbuf *pixbuf); -extern f_gtk_status_icon_set_from_pixbuf gtk_status_icon_set_from_pixbuf; +typedef guchar* (*f_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf); +extern f_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels; -typedef GtkStatusIcon* (*f_gtk_status_icon_new_from_file)(const gchar *filename); -extern f_gtk_status_icon_new_from_file gtk_status_icon_new_from_file; +typedef int (*f_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf); +extern f_gdk_pixbuf_get_width gdk_pixbuf_get_width; -typedef void (*f_gtk_status_icon_set_from_file)(GtkStatusIcon *status_icon, const gchar *filename); -extern f_gtk_status_icon_set_from_file gtk_status_icon_set_from_file; +typedef int (*f_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf); +extern f_gdk_pixbuf_get_height gdk_pixbuf_get_height; -typedef void (*f_gtk_status_icon_set_title)(GtkStatusIcon *status_icon, const gchar *title); -extern f_gtk_status_icon_set_title gtk_status_icon_set_title; - -typedef void (*f_gtk_status_icon_set_tooltip_text)(GtkStatusIcon *status_icon, const gchar *title); -extern f_gtk_status_icon_set_tooltip_text gtk_status_icon_set_tooltip_text; - -typedef void (*f_gtk_status_icon_set_visible)(GtkStatusIcon *status_icon, gboolean visible); -extern f_gtk_status_icon_set_visible gtk_status_icon_set_visible; - -typedef gboolean (*f_gtk_status_icon_is_embedded)(GtkStatusIcon *status_icon); -extern f_gtk_status_icon_is_embedded gtk_status_icon_is_embedded; - -typedef gboolean (*f_gtk_status_icon_get_geometry)(GtkStatusIcon *status_icon, GdkScreen **screen, GdkRectangle *area, GtkOrientation *orientation); -extern f_gtk_status_icon_get_geometry gtk_status_icon_get_geometry; - -typedef void (*f_gtk_status_icon_position_menu)(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data); -extern f_gtk_status_icon_position_menu gtk_status_icon_position_menu; - -typedef void (*f_gtk_menu_popup)(GtkMenu *menu, GtkWidget *parent_menu_shell, GtkWidget *parent_menu_item, GtkMenuPositionFunc func, gpointer data, guint button, guint32 activate_time); -extern f_gtk_menu_popup gtk_menu_popup; - -typedef guint32 (*f_gtk_get_current_event_time)(void); -extern f_gtk_get_current_event_time gtk_get_current_event_time; +typedef int (*f_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf); +extern f_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride; typedef void (*f_g_object_get)(gpointer object, const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED; extern f_g_object_get g_object_get; -typedef gpointer (*f_g_object_ref_sink)(gpointer object); -extern f_g_object_ref_sink g_object_ref_sink; - typedef void (*f_g_object_unref)(gpointer object); extern f_g_object_unref g_object_unref; -typedef guint (*f_g_idle_add)(GSourceFunc function, gpointer data); -extern f_g_idle_add g_idle_add; - typedef void (*f_g_free)(gpointer mem); extern f_g_free g_free; -typedef void (*f_g_list_foreach)(GList *list, GFunc func, gpointer user_data); -extern f_g_list_foreach g_list_foreach; - -typedef void (*f_g_list_free)(GList *list); -extern f_g_list_free g_list_free; - -typedef void (*f_g_list_free_full)(GList *list, GDestroyNotify free_func); -extern f_g_list_free_full g_list_free_full; - -typedef void (*f_g_error_free)(GError *error); -extern f_g_error_free g_error_free; - typedef void (*f_g_slist_free)(GSList *list); extern f_g_slist_free g_slist_free; diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 73770b77f..565419bd1 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -443,6 +443,11 @@ void ForceDisabled(QAction *action, bool disabled) { MainWindow::MainWindow(not_null controller) : Window::MainWindow(controller) { +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION + if (Libs::gtk_clipboard_get != nullptr) { + _gtkClipboard = Libs::gtk_clipboard_get(Libs::gdk_atom_intern("CLIPBOARD", true)); + } +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION } void MainWindow::initHook() { diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index e181e3626..de74c3ef8 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -18,6 +18,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #endif +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION +typedef struct _GtkClipboard GtkClipboard; +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION + + namespace Platform { class MainWindow : public Window::MainWindow { @@ -70,6 +75,12 @@ public slots: #endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION + GtkClipboard *gtkClipboard() { + return _gtkClipboard; + } +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION + protected: void initHook() override; void unreadCounterChangedHook() override; @@ -133,6 +144,10 @@ private: void attachToSNITrayIcon(); #endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION + GtkClipboard *_gtkClipboard = nullptr; +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION + }; } // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 2c780726a..51ee31a92 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/linux/notifications_manager_linux.h" #ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION +#include "base/platform/base_platform_info.h" #include "platform/linux/specific_linux.h" #include "history/history.h" #include "lang/lang_keys.h" @@ -70,7 +71,7 @@ void GetSupported() { } Checked = true; - if (Global::NativeNotifications()) { + if (Global::NativeNotifications() && !Platform::IsWayland()) { ComputeSupported(true); } else { ComputeSupported(); @@ -474,7 +475,8 @@ std::unique_ptr Create( #ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION GetSupported(); - if (Global::NativeNotifications() && Supported()) { + if ((Global::NativeNotifications() && Supported()) + || Platform::IsWayland()) { return std::make_unique(system); } #endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION @@ -488,6 +490,10 @@ Manager::Private::Private(not_null manager, Type type) , _manager(manager) { qDBusRegisterMetaType(); + if (!Supported()) { + return; + } + const auto serverInformation = GetServerInformation(); const auto capabilities = GetCapabilities(); @@ -520,6 +526,8 @@ void Manager::Private::showNotification( const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + if (!Supported()) return; + auto notification = std::make_shared( _manager, title, @@ -558,6 +566,8 @@ void Manager::Private::showNotification( } void Manager::Private::clearAll() { + if (!Supported()) return; + auto temp = base::take(_notifications); for_const (auto ¬ifications, temp) { for_const (auto notification, notifications) { @@ -567,6 +577,8 @@ void Manager::Private::clearAll() { } void Manager::Private::clearFromHistory(not_null history) { + if (!Supported()) return; + auto i = _notifications.find(history->peer->id); if (i != _notifications.cend()) { auto temp = base::take(i.value()); @@ -579,6 +591,8 @@ void Manager::Private::clearFromHistory(not_null history) { } void Manager::Private::clearNotification(PeerId peerId, MsgId msgId) { + if (!Supported()) return; + auto i = _notifications.find(peerId); if (i != _notifications.cend()) { i.value().remove(msgId); diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index a7ed69de3..44b1b2a61 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -55,6 +55,8 @@ constexpr auto kXDGDesktopPortalService = "org.freedesktop.portal.Desktop"_cs; constexpr auto kXDGDesktopPortalObjectPath = "/org/freedesktop/portal/desktop"_cs; constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs; +QStringList PlatformThemes; + #ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION void PortalAutostart(bool autostart, bool silent = false) { QVariantMap options; @@ -295,14 +297,22 @@ bool IsStaticBinary() { #endif // !DESKTOP_APP_USE_PACKAGED } +bool UseGtkIntegration() { +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION + static const auto Result = !qEnvironmentVariableIsSet( + "TDESKTOP_DISABLE_GTK_INTEGRATION"); + + return Result; +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION + + return false; +} + bool IsGtkIntegrationForced() { #ifndef TDESKTOP_DISABLE_GTK_INTEGRATION static const auto Result = [&] { - const auto platformThemes = QString::fromUtf8(qgetenv("QT_QPA_PLATFORMTHEME")) - .split(':', QString::SkipEmptyParts); - - return platformThemes.contains(qstr("gtk3"), Qt::CaseInsensitive) - || platformThemes.contains(qstr("gtk2"), Qt::CaseInsensitive); + return PlatformThemes.contains(qstr("gtk3"), Qt::CaseInsensitive) + || PlatformThemes.contains(qstr("gtk2"), Qt::CaseInsensitive); }(); return Result; @@ -346,7 +356,6 @@ bool UseXDGDesktopPortal() { return ( DesktopEnvironment::IsKDE() - || InSnap() || envVar ) && portalPresent; }(); @@ -510,6 +519,43 @@ QString GetIconName() { return Result; } +QImage GetImageFromClipboard() { + QImage data; + +#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION + if (!App::wnd()->gtkClipboard()) { + return data; + } + + auto gsel = Libs::gtk_clipboard_wait_for_contents( + App::wnd()->gtkClipboard(), + Libs::gdk_atom_intern("TARGETS", true)); + + if (gsel) { + if (Libs::gtk_selection_data_targets_include_image(gsel, false)) { + auto img = Libs::gtk_clipboard_wait_for_image(App::wnd()->gtkClipboard()); + + if (img) { + data = QImage( + Libs::gdk_pixbuf_get_pixels(img), + Libs::gdk_pixbuf_get_width(img), + Libs::gdk_pixbuf_get_height(img), + Libs::gdk_pixbuf_get_rowstride(img), + Libs::gdk_pixbuf_get_has_alpha(img) + ? QImage::Format_RGBA8888 + : QImage::Format_RGB888).copy(); + + Libs::g_object_unref(img); + } + } + + Libs::gtk_selection_data_free(gsel); + } +#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION + + return data; +} + std::optional LastUserInputTime() { // TODO: a fallback pure-X11 implementation, this one covers only major DEs on X11 and Wayland // an example: https://stackoverflow.com/q/9049087 @@ -697,6 +743,9 @@ int psFixPrevious() { namespace Platform { void start() { + PlatformThemes = QString::fromUtf8(qgetenv("QT_QPA_PLATFORMTHEME")) + .split(':', QString::SkipEmptyParts); + LOG(("Launcher filename: %1").arg(GetLauncherFilename())); #ifdef TDESKTOP_USE_FONTCONFIG_FALLBACK @@ -706,6 +755,16 @@ void start() { qputenv("PULSE_PROP_application.name", AppName.utf8()); qputenv("PULSE_PROP_application.icon_name", GetIconName().toLatin1()); + // if gtk integration and qgtk3/qgtk2 platformtheme (or qgtk2 style) + // is used at the same time, the app will crash + if (UseGtkIntegration() + && !IsStaticBinary() + && !qEnvironmentVariableIsSet( + "TDESKTOP_I_KNOW_ABOUT_GTK_INCOMPATIBILITY")) { + qunsetenv("QT_QPA_PLATFORMTHEME"); + qunsetenv("QT_STYLE_OVERRIDE"); + } + if(IsStaticBinary() || InAppImage() || InFlatpak() diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.h b/Telegram/SourceFiles/platform/linux/specific_linux.h index 041d6f795..1e6f1d99e 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.h +++ b/Telegram/SourceFiles/platform/linux/specific_linux.h @@ -24,6 +24,7 @@ bool InFlatpak(); bool InSnap(); bool InAppImage(); bool IsStaticBinary(); +bool UseGtkIntegration(); bool IsGtkIntegrationForced(); bool UseGtkFileDialog(); bool IsQtPluginsBundled(); @@ -34,10 +35,8 @@ bool CanOpenDirectoryWithPortal(); QString ProcessNameByPID(const QString &pid); QString RealExecutablePath(int argc, char *argv[]); -QString CurrentExecutablePath(int argc, char *argv[]); QString AppRuntimeDirectory(); -QString SingleInstanceLocalServerName(const QString &hash); QString GetLauncherBasename(); QString GetLauncherFilename(); diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.h b/Telegram/SourceFiles/platform/mac/specific_mac.h index 09de68ff9..fc591e968 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.h +++ b/Telegram/SourceFiles/platform/mac/specific_mac.h @@ -16,10 +16,6 @@ class LocationPoint; namespace Platform { -QString CurrentExecutablePath(int argc, char *argv[]); - -QString SingleInstanceLocalServerName(const QString &hash); - void RemoveQuarantine(const QString &path); inline void FallbackFontConfigCheckBegin() { @@ -28,6 +24,10 @@ inline void FallbackFontConfigCheckBegin() { inline void FallbackFontConfigCheckEnd() { } +inline QImage GetImageFromClipboard() { + return {}; +} + namespace ThirdParty { inline void start() { diff --git a/Telegram/SourceFiles/platform/platform_audio.h b/Telegram/SourceFiles/platform/platform_audio.h index 7705b2ef7..6ec8ec6dd 100644 --- a/Telegram/SourceFiles/platform/platform_audio.h +++ b/Telegram/SourceFiles/platform/platform_audio.h @@ -19,7 +19,9 @@ void DeInit(); // Platform dependent implementations. -#if defined Q_OS_MAC || defined Q_OS_LINUX +#if defined Q_OS_WINRT || defined Q_OS_WIN +#include "platform/win/audio_win.h" +#else // Q_OS_WINRT || Q_OS_WIN namespace Platform { namespace Audio { @@ -31,6 +33,4 @@ inline void DeInit() { } // namespace Audio } // namespace Platform -#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX -#include "platform/win/audio_win.h" -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN +#endif // Q_OS_WINRT || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/platform_file_utilities.h b/Telegram/SourceFiles/platform/platform_file_utilities.h index b78adf552..cd70b78a6 100644 --- a/Telegram/SourceFiles/platform/platform_file_utilities.h +++ b/Telegram/SourceFiles/platform/platform_file_utilities.h @@ -46,8 +46,8 @@ bool Get( #ifdef Q_OS_MAC #include "platform/mac/file_utilities_mac.h" -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC #include "platform/linux/file_utilities_linux.h" -#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX +#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX #include "platform/win/file_utilities_win.h" -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN +#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WINRT || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/platform_launcher.h b/Telegram/SourceFiles/platform/platform_launcher.h index 27180d00b..d79aea65c 100644 --- a/Telegram/SourceFiles/platform/platform_launcher.h +++ b/Telegram/SourceFiles/platform/platform_launcher.h @@ -23,8 +23,8 @@ namespace Platform { #ifdef Q_OS_MAC #include "platform/mac/launcher_mac.h" -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC #include "platform/linux/launcher_linux.h" -#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX +#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX #include "platform/win/launcher_win.h" -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN +#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WINRT || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/platform_main_window.h b/Telegram/SourceFiles/platform/platform_main_window.h index 33277c901..4bdb93981 100644 --- a/Telegram/SourceFiles/platform/platform_main_window.h +++ b/Telegram/SourceFiles/platform/platform_main_window.h @@ -19,8 +19,8 @@ class MainWindow; #ifdef Q_OS_MAC #include "platform/mac/main_window_mac.h" -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC #include "platform/linux/main_window_linux.h" -#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX +#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX #include "platform/win/main_window_win.h" -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN +#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/platform_notifications_manager.h b/Telegram/SourceFiles/platform/platform_notifications_manager.h index f0cdb152e..4afeadf97 100644 --- a/Telegram/SourceFiles/platform/platform_notifications_manager.h +++ b/Telegram/SourceFiles/platform/platform_notifications_manager.h @@ -27,8 +27,8 @@ namespace Notifications { #ifdef Q_OS_MAC #include "platform/mac/notifications_manager_mac.h" -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC #include "platform/linux/notifications_manager_linux.h" -#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX +#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX #include "platform/win/notifications_manager_win.h" -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN +#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h index db963f599..c05e717ce 100644 --- a/Telegram/SourceFiles/platform/platform_specific.h +++ b/Telegram/SourceFiles/platform/platform_specific.h @@ -28,6 +28,8 @@ enum class SystemSettingsType { void SetWatchingMediaKeys(bool watching); void SetApplicationIcon(const QIcon &icon); +QString CurrentExecutablePath(int argc, char *argv[]); +QString SingleInstanceLocalServerName(const QString &hash); void RegisterCustomScheme(bool force = false); PermissionStatus GetPermissionStatus(PermissionType type); void RequestPermission(PermissionType type, Fn resultCallback); @@ -41,6 +43,7 @@ bool OpenSystemSettings(SystemSettingsType type); void IgnoreApplicationActivationRightNow(); bool AutostartSupported(); +QImage GetImageFromClipboard(); namespace ThirdParty { @@ -52,8 +55,8 @@ void finish(); #ifdef Q_OS_MAC #include "platform/mac/specific_mac.h" -#elif defined Q_OS_LINUX // Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_MAC #include "platform/linux/specific_linux.h" -#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX +#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX #include "platform/win/specific_win.h" -#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN +#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/platform_window_title.h b/Telegram/SourceFiles/platform/platform_window_title.h index 6aea66396..d8d57cbb3 100644 --- a/Telegram/SourceFiles/platform/platform_window_title.h +++ b/Telegram/SourceFiles/platform/platform_window_title.h @@ -26,7 +26,7 @@ void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRe #include "platform/mac/window_title_mac.h" #elif defined Q_OS_WIN // Q_OS_MAC #include "platform/win/window_title_win.h" -#elif defined Q_OS_WINRT || defined Q_OS_LINUX // Q_OS_MAC || Q_OS_WIN +#elif defined Q_OS_WINRT || defined Q_OS_UNIX // Q_OS_MAC || Q_OS_WIN namespace Platform { @@ -44,4 +44,4 @@ inline void PreviewWindowFramePaint(QImage &preview, const style::palette &palet } // namespace Platform -#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX +#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_UNIX diff --git a/Telegram/SourceFiles/platform/win/specific_win.h b/Telegram/SourceFiles/platform/win/specific_win.h index 17092a1c4..eb70f1e13 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.h +++ b/Telegram/SourceFiles/platform/win/specific_win.h @@ -19,10 +19,6 @@ namespace Platform { inline void SetWatchingMediaKeys(bool watching) { } -QString CurrentExecutablePath(int argc, char *argv[]); - -QString SingleInstanceLocalServerName(const QString &hash); - inline void IgnoreApplicationActivationRightNow() { } @@ -32,6 +28,10 @@ inline void FallbackFontConfigCheckBegin() { inline void FallbackFontConfigCheckEnd() { } +inline QImage GetImageFromClipboard() { + return {}; +} + namespace ThirdParty { void start(); diff --git a/Telegram/SourceFiles/qt_static_plugins.cpp b/Telegram/SourceFiles/qt_static_plugins.cpp index 4174957d3..82a4cdb6b 100644 --- a/Telegram/SourceFiles/qt_static_plugins.cpp +++ b/Telegram/SourceFiles/qt_static_plugins.cpp @@ -20,7 +20,7 @@ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) #elif defined Q_OS_MAC // Q_OS_WIN Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin) Q_IMPORT_PLUGIN(QGenericEnginePlugin) -#elif defined Q_OS_LINUX // Q_OS_WIN | Q_OS_MAC +#elif defined Q_OS_UNIX // Q_OS_WIN | Q_OS_MAC Q_IMPORT_PLUGIN(ShmServerBufferPlugin) Q_IMPORT_PLUGIN(DmaBufServerBufferPlugin) Q_IMPORT_PLUGIN(DrmEglServerBufferPlugin) @@ -44,10 +44,10 @@ Q_IMPORT_PLUGIN(QNetworkManagerEnginePlugin) Q_IMPORT_PLUGIN(QIbusPlatformInputContextPlugin) Q_IMPORT_PLUGIN(QXdgDesktopPortalThemePlugin) #endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION -#endif // Q_OS_WIN | Q_OS_MAC | Q_OS_LINUX +#endif // Q_OS_WIN | Q_OS_MAC | Q_OS_UNIX #endif // !DESKTOP_APP_USE_PACKAGED -#ifdef Q_OS_LINUX +#if defined Q_OS_UNIX && !defined Q_OS_MAC #if !defined DESKTOP_APP_USE_PACKAGED || defined DESKTOP_APP_USE_PACKAGED_LAZY Q_IMPORT_PLUGIN(QWaylandMaterialDecorationPlugin) Q_IMPORT_PLUGIN(NimfInputContextPlugin) @@ -69,4 +69,4 @@ Q_IMPORT_PLUGIN(Qt5CTStylePlugin) Q_IMPORT_PLUGIN(LXQtPlatformThemePlugin) #endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION #endif // DESKTOP_APP_USE_PACKAGED_LAZY_PLATFORMTHEMES -#endif // Q_OS_LINUX +#endif // Q_OS_UNIX && !Q_OS_MAC diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp index cf0cfa09c..945f6706d 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications.cpp @@ -499,11 +499,11 @@ void NotificationsCount::SampleWidget::destroyDelayed() { _deleted = true; // Ubuntu has a lag if deleteLater() called immediately. -#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#if defined Q_OS_UNIX && !defined Q_OS_MAC QTimer::singleShot(1000, [this] { delete this; }); -#else // Q_OS_LINUX32 || Q_OS_LINUX64 +#else // Q_OS_UNIX && !Q_OS_MAC deleteLater(); -#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // Q_OS_UNIX && !Q_OS_MAC } void SetupAdvancedNotifications( @@ -633,7 +633,7 @@ void SetupNotificationsContent( return QString(); } else if (Platform::IsWindows()) { return tr::lng_settings_use_windows(tr::now); - } else if (Platform::IsLinux()) { + } else if (Platform::IsLinux() && !Platform::IsWayland()) { return tr::lng_settings_use_native_notifications(tr::now); } return QString(); @@ -651,6 +651,9 @@ void SetupNotificationsContent( }(); const auto advancedSlide = !Platform::IsMac10_8OrGreater() +#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION + && !Platform::IsWayland() +#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION ? container->add( object_ptr>( container, diff --git a/Telegram/SourceFiles/stdafx.h b/Telegram/SourceFiles/stdafx.h index 5e5d6ead2..c92c010c2 100644 --- a/Telegram/SourceFiles/stdafx.h +++ b/Telegram/SourceFiles/stdafx.h @@ -79,9 +79,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #endif // OS_MAC_OLD // Fix Google Breakpad build for Mac App Store and Linux version -#if defined Q_OS_MAC || defined Q_OS_LINUX +#ifdef Q_OS_UNIX #define __STDC_FORMAT_MACROS -#endif // Q_OS_MAC || Q_OS_LINUX +#endif // Q_OS_UNIX #include #include diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index 24c548285..8f6198201 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/clip/media_clip_reader.h" #include "mtproto/facade.h" #include "lottie/lottie_animation.h" +#include "history/history.h" #include "history/history_item.h" #include "boxes/send_files_box.h" #include "boxes/confirm_box.h" @@ -129,6 +130,7 @@ MTPInputSingleMedia PrepareAlbumItemMedia( auto caption = item->originalText(); TextUtilities::Trim(caption); auto sentEntities = Api::EntitiesToMTP( + &item->history()->session(), caption.entities, Api::ConvertOption::SkipLocal); const auto flags = !sentEntities.v.isEmpty() diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index 79010e8b4..3b8c6d361 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -453,7 +453,7 @@ void Helper::applyInfo( info.date = data.vdate().v; info.text = TextWithEntities{ qs(data.vmessage()), - Api::EntitiesFromMTP(data.ventities().v) }; + Api::EntitiesFromMTP(&user->session(), data.ventities().v) }; if (info.text.empty()) { remove(); } else if (_userInformation[user] != info) { @@ -544,6 +544,7 @@ void Helper::saveInfo( TextUtilities::Trim(text); const auto entities = Api::EntitiesToMTP( + &user->session(), text.entities, Api::ConvertOption::SkipLocal); _userInfoSaving[user].requestId = _api.request(MTPhelp_EditUserInfo( diff --git a/Telegram/SourceFiles/ui/text_options.cpp b/Telegram/SourceFiles/ui/text_options.cpp index 3d7c3414d..99247f568 100644 --- a/Telegram/SourceFiles/ui/text_options.cpp +++ b/Telegram/SourceFiles/ui/text_options.cpp @@ -110,32 +110,6 @@ TextParseOptions WebpageDescriptionOptions = { Qt::LayoutDirectionAuto, // dir }; -TextParseOptions TwitterDescriptionOptions = { - TextParseLinks - | TextParseMentions - | TextTwitterMentions - | TextParseHashtags - | TextTwitterHashtags - | TextParseMultiline - | TextParseRichText, // flags - 0, // maxw - 0, // maxh - Qt::LayoutDirectionAuto, // dir -}; - -TextParseOptions InstagramDescriptionOptions = { - TextParseLinks - | TextParseMentions - | TextInstagramMentions - | TextParseHashtags - | TextInstagramHashtags - | TextParseMultiline - | TextParseRichText, // flags - 0, // maxw - 0, // maxh - Qt::LayoutDirectionAuto, // dir -}; - bool UseBotTextOptions( not_null history, not_null author) { @@ -171,8 +145,6 @@ void InitTextOptions() { WebpageTitleOptions.maxh = st::webPageTitleFont->height * 2; WebpageTitleOptions.maxw = WebpageDescriptionOptions.maxw - = TwitterDescriptionOptions.maxw - = InstagramDescriptionOptions.maxw = st::msgMaxWidth - st::msgPadding.left() - st::webPageLeft @@ -204,13 +176,7 @@ const TextParseOptions &WebpageTextTitleOptions() { return WebpageTitleOptions; } -const TextParseOptions &WebpageTextDescriptionOptions( - const QString &siteName) { - if (siteName == qstr("Twitter")) { - return TwitterDescriptionOptions; - } else if (siteName == qstr("Instagram")) { - return InstagramDescriptionOptions; - } +const TextParseOptions &WebpageTextDescriptionOptions() { return WebpageDescriptionOptions; } diff --git a/Telegram/SourceFiles/ui/text_options.h b/Telegram/SourceFiles/ui/text_options.h index d40d292a1..85b0a80c3 100644 --- a/Telegram/SourceFiles/ui/text_options.h +++ b/Telegram/SourceFiles/ui/text_options.h @@ -23,8 +23,7 @@ const TextParseOptions &ItemTextBotNoMonoOptions(); const TextParseOptions &ItemTextServiceOptions(); const TextParseOptions &WebpageTextTitleOptions(); -const TextParseOptions &WebpageTextDescriptionOptions( - const QString &siteName = QString()); +const TextParseOptions &WebpageTextDescriptionOptions(); const TextParseOptions &NameTextOptions(); const TextParseOptions &DialogTextOptions(); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 017a37119..c75cec785 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -139,7 +139,7 @@ QIcon CreateOfficialIcon(Main::Account *account) { QIcon CreateIcon(Main::Account *account) { auto result = CreateOfficialIcon(account); -#ifdef Q_OS_LINUX +#if defined Q_OS_UNIX && !defined Q_OS_MAC if ( (!account || !account->sessionExists() @@ -635,7 +635,7 @@ bool MainWindow::minimizeToTray() { } void MainWindow::reActivateWindow() { -#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 +#if defined Q_OS_UNIX && !defined Q_OS_MAC const auto reActivate = [=] { if (const auto w = App::wnd()) { if (auto f = QApplication::focusWidget()) { @@ -650,7 +650,7 @@ void MainWindow::reActivateWindow() { }; crl::on_main(this, reActivate); base::call_delayed(200, this, reActivate); -#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +#endif // Q_OS_UNIX && !Q_OS_MAC } void MainWindow::showRightColumn(object_ptr widget) { diff --git a/Telegram/SourceFiles/window/window_lock_widgets.cpp b/Telegram/SourceFiles/window/window_lock_widgets.cpp index 6489273b8..e7469c5b0 100644 --- a/Telegram/SourceFiles/window/window_lock_widgets.cpp +++ b/Telegram/SourceFiles/window/window_lock_widgets.cpp @@ -185,13 +185,15 @@ void PasscodeLockWidget::setInnerFocus() { _passcode->setFocusFast(); } -TermsLock TermsLock::FromMTP(const MTPDhelp_termsOfService &data) { +TermsLock TermsLock::FromMTP( + Main::Session *session, + const MTPDhelp_termsOfService &data) { const auto minAge = data.vmin_age_confirm(); return { bytes::make_vector(data.vid().c_dataJSON().vdata().v), TextWithEntities { TextUtilities::Clean(qs(data.vtext())), - Api::EntitiesFromMTP(data.ventities().v) }, + Api::EntitiesFromMTP(session, data.ventities().v) }, (minAge ? std::make_optional(minAge->v) : std::nullopt), data.is_popup() }; diff --git a/Telegram/SourceFiles/window/window_lock_widgets.h b/Telegram/SourceFiles/window/window_lock_widgets.h index 848fbafd8..6b22588d0 100644 --- a/Telegram/SourceFiles/window/window_lock_widgets.h +++ b/Telegram/SourceFiles/window/window_lock_widgets.h @@ -19,6 +19,10 @@ class RoundButton; class CheckView; } // namespace Ui +namespace Main { +class Session; +} // namespace Main + namespace Window { class Controller; @@ -83,7 +87,9 @@ struct TermsLock { return !(*this == other); } - static TermsLock FromMTP(const MTPDhelp_termsOfService &data); + static TermsLock FromMTP( + Main::Session *session, + const MTPDhelp_termsOfService &data); }; diff --git a/Telegram/ThirdParty/materialdecoration b/Telegram/ThirdParty/materialdecoration index e58c870f2..90b26e827 160000 --- a/Telegram/ThirdParty/materialdecoration +++ b/Telegram/ThirdParty/materialdecoration @@ -1 +1 @@ -Subproject commit e58c870f2365178b0553664d762a7a2aeae99bd4 +Subproject commit 90b26e827e27b829b208a3d906c38ca91cb2c50d diff --git a/Telegram/build/version b/Telegram/build/version index 2e9acaed3..4d1e03a16 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 2001010 +AppVersion 2001013 AppVersionStrMajor 2.1 -AppVersionStrSmall 2.1.10 -AppVersionStr 2.1.10 +AppVersionStrSmall 2.1.13 +AppVersionStr 2.1.13 BetaChannel 0 AlphaVersion 0 -AppVersionOriginal 2.1.10 +AppVersionOriginal 2.1.13 diff --git a/Telegram/cmake/telegram_options.cmake b/Telegram/cmake/telegram_options.cmake index 9bf5b4eb2..56f481882 100644 --- a/Telegram/cmake/telegram_options.cmake +++ b/Telegram/cmake/telegram_options.cmake @@ -8,6 +8,7 @@ option(TDESKTOP_USE_FONTCONFIG_FALLBACK "Use custom fonts.conf (Linux only)." OF option(TDESKTOP_USE_GTK_FILE_DIALOG "Use custom code for GTK file dialog (Linux only)." OFF) option(TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME "Disable automatic 'tg://' URL scheme handler registration." ${DESKTOP_APP_USE_PACKAGED}) option(TDESKTOP_DISABLE_NETWORK_PROXY "Disable all code for working through Socks5 or MTProxy." OFF) +option(TDESKTOP_DISABLE_GTK_INTEGRATION "Disable all code for GTK integration (Linux only)." OFF) option(TDESKTOP_USE_PACKAGED_TGVOIP "Find libtgvoip using CMake instead of bundled one." ${DESKTOP_APP_USE_PACKAGED}) option(TDESKTOP_API_TEST "Use test API credentials." OFF) option(KTGDESKTOP_ENABLE_PACKER "Enable building update packer on non-special targets." OFF) @@ -48,8 +49,8 @@ if (NOT DESKTOP_APP_USE_PACKAGED) set(TDESKTOP_USE_GTK_FILE_DIALOG ON) endif() -if (NOT TDESKTOP_USE_GTK_FILE_DIALOG) - set(TDESKTOP_DISABLE_GTK_INTEGRATION ON) +if (TDESKTOP_USE_GTK_FILE_DIALOG) + set(TDESKTOP_DISABLE_GTK_INTEGRATION OFF) endif() if (DESKTOP_APP_DISABLE_SPELLCHECK) diff --git a/Telegram/lib_base b/Telegram/lib_base index 486003d41..3017da83c 160000 --- a/Telegram/lib_base +++ b/Telegram/lib_base @@ -1 +1 @@ -Subproject commit 486003d41751c1c775513598c8a4154cd294a136 +Subproject commit 3017da83c15e5e27244ab66526fea8cc3bddb7cf diff --git a/Telegram/lib_spellcheck b/Telegram/lib_spellcheck index 48865e514..135783777 160000 --- a/Telegram/lib_spellcheck +++ b/Telegram/lib_spellcheck @@ -1 +1 @@ -Subproject commit 48865e514979b4e2610fe6ca22bbb145bcfab4ea +Subproject commit 1357837771a8b237c8a6ce90060f5a4f0fd5e339 diff --git a/Telegram/lib_storage b/Telegram/lib_storage index 5d2cb6bda..538a72e5d 160000 --- a/Telegram/lib_storage +++ b/Telegram/lib_storage @@ -1 +1 @@ -Subproject commit 5d2cb6bda4d24887a336caacf835b9143319f4eb +Subproject commit 538a72e5d3aedb660d3a399cc883067ada16e9cf diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 3018a9caf..7afb927ac 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 3018a9cafe8cb843c18cd201e40d4edde6255be0 +Subproject commit 7afb927acff954c592af05d5621d50556cb9f0ca diff --git a/changelog.txt b/changelog.txt index f02079cdb..882e8c7be 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,18 @@ +2.1.13 (23.06.20) + +- Fix photos loading. +- Fix Picture-in-Picture window movement on Wayland in Linux. + +2.1.12 (17.06.20) + +- Fix sticker and video results in inline bots. +- Fix clipboard issues in Linux. +- Fix several crashes. + +2.1.11 (08.06.20) + +- Fix launching on old Linux systems. + 2.1.10 (05.06.20) - Improve memory usage. diff --git a/cmake b/cmake index 63f0ef5c6..03bde956c 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 63f0ef5c6352b3ff1f3c862a53e6266cb599725f +Subproject commit 03bde956c59b5344177f9ec9780058a9ba7304c8 diff --git a/docs/building-cmake.md b/docs/building-cmake.md index 0d81c907c..c72c89913 100644 --- a/docs/building-cmake.md +++ b/docs/building-cmake.md @@ -54,7 +54,7 @@ Go to ***BuildPath*** and run git clone https://github.com/desktop-app/patches.git cd patches - git checkout 2b9afa7 + git checkout 0ba67e2 cd ../ git clone https://github.com/xiph/opus @@ -192,7 +192,7 @@ Go to ***BuildPath*** and run git clone git://repo.or.cz/openal-soft.git cd openal-soft - git checkout openal-soft-1.20.1 + git checkout openal-soft-1.19.1 cd build cmake .. \ -DLIBTYPE:STRING=STATIC \ @@ -212,7 +212,7 @@ Go to ***BuildPath*** and run sudo make install_sw cd .. - git clone -b 1.16 https://gitlab.freedesktop.org/wayland/wayland + git clone -b 1.18.0 https://gitlab.freedesktop.org/wayland/wayland cd wayland ./autogen.sh \ --enable-static \ diff --git a/docs/building-msvc.md b/docs/building-msvc.md index c18bf7be0..f17782532 100644 --- a/docs/building-msvc.md +++ b/docs/building-msvc.md @@ -32,7 +32,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 b08b497 + git checkout 0ba67e2 cd ../ git clone https://chromium.googlesource.com/external/gyp cd gyp @@ -176,7 +176,7 @@ Go to ***BuildPath*\\tdesktop\\Telegram** and run (using [your **api_id** and ** For better debugging you may want to install Qt Visual Studio Tools: -* Open **Tools** -> **Extensions and Updates...** +* Open **Extensions** -> **Manage Extensions** * Go to **Online** tab * Search for **Qt** * Install **Qt Visual Studio Tools** extension diff --git a/docs/building-xcode.md b/docs/building-xcode.md index 91bdc4c50..5a105d5ad 100644 --- a/docs/building-xcode.md +++ b/docs/building-xcode.md @@ -29,7 +29,7 @@ Go to ***BuildPath*** and run git clone https://github.com/desktop-app/patches.git cd patches - git checkout 2b9afa7 + git checkout 0ba67e2 cd ../ git clone https://chromium.googlesource.com/external/gyp git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git diff --git a/snap/scripts/telegram-launch b/snap/scripts/telegram-launch deleted file mode 100755 index f8dc3b182..000000000 --- a/snap/scripts/telegram-launch +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -if [ ! -d $SNAP/kf5/usr ]; then - runtime="kde-frameworks-5-core18" - slot="kde-frameworks-5-core18:kde-frameworks-5-core18-slot" - - echo "You need to connect this snap to the $runtime snap." - echo "" - echo "You can do this with those commands:" - echo "snap install $runtime" - echo "snap refresh $runtime" - echo "snap connect $SNAP_NAME:kde-frameworks-5-plug $slot" - exit 1 -fi - -exec telegram-desktop "$@" \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 43715fce0..6ce20f35b 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -2,24 +2,24 @@ name: kotatogram-desktop adopt-info: kotatogram icon: Telegram/Resources/art/icon512@2x.png -base: core18 +base: core20 grade: stable confinement: strict architectures: - build-on: amd64 - - build-on: i386 - build-on: arm64 - build-on: armhf - build-on: ppc64el apps: - kotatogram-desktop: - command: kotatogram-launch + telegram-desktop: + command: bin/desktop-launch kotatogram-desktop common-id: io.github.kotatogram - desktop: share/applications/kotatogramdesktop.desktop - extensions: - - kde-neon + desktop: usr/share/applications/kotatogramdesktop.desktop + environment: + # Use GTK3 cursor theme, icon theme and open/save file dialogs. + QT_QPA_PLATFORMTHEME: gtk3 plugs: - alsa - audio-playback @@ -64,163 +64,125 @@ parts: plugin: cmake source: . source-type: git - parse-info: [share/metainfo/kotatogramdesktop.appdata.xml] + parse-info: [usr/share/metainfo/kotatogramdesktop.appdata.xml] build-environment: - - CFLAGS: "$CFLAGS -I$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.3" - - CXXFLAGS: "$CXXFLAGS -I$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.3" - build-snaps: - - kde-frameworks-5-core18-sdk - - kde-frameworks-5-core18 + - LD_LIBRARY_PATH: $SNAPCRAFT_STAGE/usr/lib build-packages: - - gcc-8 - - g++-8 + - qtbase5-private-dev - libasound2-dev - libglib2.0-dev - - libglvnd-dev - libgtk-3-dev - liblzma-dev - libopus-dev - libpulse-dev + - libqt5svg5-dev + - libqt5waylandclient5-dev + - libqt5x11extras5-dev - libssl-dev - zlib1g-dev stage-packages: + - qt5-image-formats-plugins + - qtwayland5 + - libasound2 - libgtk-3-0 - liblzma5 - configflags: - - -DCMAKE_C_COMPILER=gcc-8 - - -DCMAKE_CXX_COMPILER=g++-8 - - -DCMAKE_AUTOMOC_MOC_OPTIONS=-I$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.3 + - libopus0 + - libpulse0 + - libqt5svg5 + - libqt5waylandclient5 + - libqt5x11extras5 + - libssl1.1 + - zlib1g + cmake-parameters: - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_INSTALL_PREFIX=/usr - -DTDESKTOP_API_ID=611335 - -DTDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c - -DDESKTOP_APP_USE_PACKAGED_LAZY=ON - -DDESKTOP_APP_USE_PACKAGED_FONTS=OFF - - -DTDESKTOP_USE_FONTCONFIG_FALLBACK=ON - -DTDESKTOP_USE_GTK_FILE_DIALOG=ON + - -DDESKTOP_APP_QTWAYLANDCLIENT_PRIVATE_HEADERS=$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.8 override-pull: | snapcraftctl pull version="$(git describe --tags | sed -r 's,^k([0-9]\.[0-9]),\1,')" snapcraftctl set-version "$version" - sed -i 's|^Icon=.*|Icon=/share/icons/hicolor/512x512/apps/kotatogram.png|g' lib/xdg/kotatogramdesktop.desktop + sed -i 's|^Icon=.*|Icon=/usr/share/icons/hicolor/512x512/apps/kotatogram.png|g' lib/xdg/kotatogramdesktop.desktop after: - - cmake + - desktop-qt5 - ffmpeg - openal - qtwayland - kotatogram-launcher: - plugin: dump - source: snap/scripts - organize: - kotatogram-launch: bin/kotatogram-launch - - patches: - plugin: dump - source: Telegram/Patches - prime: [-./*] - - qtconf: - plugin: nil - override-build: | - KF5_DIR=/snap/kde-frameworks-5-core18-sdk/current - - install -d "$SNAPCRAFT_PART_INSTALL/usr/include/$SNAPCRAFT_ARCH_TRIPLET" - cp -a $KF5_DIR/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5 "$SNAPCRAFT_PART_INSTALL/usr/include/$SNAPCRAFT_ARCH_TRIPLET" - - install -d "$SNAPCRAFT_PART_INSTALL/usr/lib/$SNAPCRAFT_ARCH_TRIPLET" - cp -a $KF5_DIR/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 "$SNAPCRAFT_PART_INSTALL/usr/lib/$SNAPCRAFT_ARCH_TRIPLET" - - cat << EOF > "$SNAPCRAFT_PART_INSTALL/qt.conf" - [Paths] - Prefix=$KF5_DIR/usr - ArchData=lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 - Binaries=lib/qt5/bin - Data=share/qt5 - Documentation=share/qt5/doc - Examples=lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/examples - Headers=$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5 - HostBinaries=lib/qt5/bin - HostData=$SNAPCRAFT_STAGE/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 - HostLibraries=lib/$SNAPCRAFT_ARCH_TRIPLET - Imports=lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/imports - Libraries=lib/$SNAPCRAFT_ARCH_TRIPLET - LibraryExecutables=lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/libexec - Plugins=lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins - Qml2Imports=lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/qml - Settings=/etc/xdg - Translations=share/qt5/translations - EOF - stage: - - -usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqwayland* - - -usr/lib/x86_64-linux-gnu/qt5/plugins/wayland* - - -usr/lib/x86_64-linux-gnu/qt5/qml/QtWayland - prime: [-./*] - - cmake: - source: "https://gitlab.kitware.com/cmake/cmake.git" - source-depth: 1 - source-tag: v3.16.4 - source-type: git + desktop-qt5: + source: https://github.com/ubuntu/snapcraft-desktop-helpers.git + source-subdir: qt plugin: make - override-build: | - ${SNAPCRAFT_PART_SRC}/bootstrap \ - --parallel=${SNAPCRAFT_PARALLEL_BUILD_COUNT} \ - -- \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/ \ - -DBUILD_TESTING=OFF - snapcraftctl build + make-parameters: ["FLAVOR=qt5"] build-packages: - build-essential - - libssl-dev - - libncurses5-dev + - qtbase5-dev + - dpkg-dev stage-packages: - - libssl1.1 - - libncurses5 - - libtinfo5 - prime: [-./*] + - libxkbcommon0 + - ttf-ubuntu-font-family + - dmz-cursor-theme + - light-themes + - adwaita-icon-theme + - gnome-themes-standard + - shared-mime-info + - libqt5gui5 + - libgdk-pixbuf2.0-0 + - libqt5svg5 # for loading icon themes which are svg + - try: [appmenu-qt5] # not available on core18 + - locales-all + - xdg-user-dirs + - fcitx-frontend-qt5 - nasm: - source: https://repo.or.cz/nasm.git - source-depth: 1 - source-tag: nasm-2.14.02 - plugin: autotools - override-build: | - ./autogen.sh - ./configure --prefix= - make -j$(nproc) - install -d "$SNAPCRAFT_PART_INSTALL/bin" - install nasm "$SNAPCRAFT_PART_INSTALL/bin/nasm" - install ndisasm "$SNAPCRAFT_PART_INSTALL/bin/ndisasm" - prime: [-./*] + qt5-xdgdesktopportal-platform: + plugin: nil + stage-packages: + - qt5-xdgdesktopportal-platformtheme + + # Qt checks that ibus-daemon binary is present, otherwise doesn't work + ibus: + plugin: nil + stage-packages: + - ibus dav1d: source: https://github.com/videolan/dav1d.git source-depth: 1 source-tag: 0.6.0 plugin: meson + build-packages: + - nasm meson-parameters: - --prefix=/usr + - --libdir=lib - -Denable_tools=false - -Denable_tests=false prime: - -./usr/include - - -./usr/lib/*/pkgconfig - after: - - nasm + - -./usr/lib/pkgconfig ffmpeg: source: https://github.com/FFmpeg/FFmpeg.git source-depth: 1 - source-branch: release/4.2 + source-branch: release/4.3 plugin: autotools build-packages: + - nasm - libopus-dev - libva-dev - libvdpau-dev - configflags: + stage-packages: + - libopus0 + - libva2 + - libva-drm2 + - libvdpau1 + autotools-configure-parameters: - --prefix=/usr - --disable-static - --disable-debug @@ -325,15 +287,10 @@ parts: - --enable-demuxer=wav - --enable-muxer=ogg - --enable-muxer=opus - override-pull: | - snapcraftctl pull - patch -p1 < "$SNAPCRAFT_STAGE/ffmpeg.diff" prime: - -./usr/include - -./usr/lib/pkgconfig after: - - patches - - nasm - dav1d openal: @@ -346,59 +303,33 @@ parts: - libpulse-dev - libsndio-dev - portaudio19-dev - configflags: + stage-packages: + - libasound2 + - libpulse0 + - libportaudio2 + - libsndio7.0 + cmake-parameters: - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_INSTALL_PREFIX=/usr - -DALSOFT_EXAMPLES=OFF - -DALSOFT_TESTS=OFF - -DALSOFT_UTILS=OFF - -DALSOFT_CONFIG=OFF prime: - - -./include - - -./lib/cmake - - -./lib/pkgconfig - - qtimageformats: - source: https://github.com/qt/qtimageformats.git - source-depth: 1 - source-tag: v5.12.3 - plugin: dump - build-snaps: - - kde-frameworks-5-core18-sdk - - kde-frameworks-5-core18 - build-packages: - - libglvnd-dev - override-build: | - KF5_DIR=/snap/kde-frameworks-5-core18-sdk/current - - $KF5_DIR/usr/lib/qt5/bin/qmake -qtconf "$SNAPCRAFT_STAGE/qt.conf" - make -j$(nproc) - make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL/tmp" install - - cp -a "$SNAPCRAFT_PART_INSTALL/tmp/$KF5_DIR/." "$SNAPCRAFT_PART_INSTALL" - rm -r "$SNAPCRAFT_PART_INSTALL/tmp" - after: - - qtconf + - -./usr/include + - -./usr/lib/cmake + - -./usr/lib/pkgconfig qtwayland: source: https://github.com/qt/qtwayland.git source-depth: 1 - source-tag: v5.12.3 + source-tag: v5.12.8 plugin: dump - build-snaps: - - kde-frameworks-5-core18-sdk - - kde-frameworks-5-core18 - build-packages: - - libglvnd-dev override-build: | - KF5_DIR=/snap/kde-frameworks-5-core18-sdk/current - - $KF5_DIR/usr/lib/qt5/bin/qmake -qtconf "$SNAPCRAFT_STAGE/qt.conf" + qmake make -j$(nproc) - make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL/tmp" install - - cp -a "$SNAPCRAFT_PART_INSTALL/tmp/$KF5_DIR/." "$SNAPCRAFT_PART_INSTALL" - cp -a "$SNAPCRAFT_PART_INSTALL/tmp/$SNAPCRAFT_STAGE/." "$SNAPCRAFT_PART_INSTALL" - rm -r "$SNAPCRAFT_PART_INSTALL/tmp" + make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL" install after: - - qtconf + - desktop-qt5 + stage: [-./usr/lib] prime: [-./*]