Merge remote-tracking branch 'tdesktop/dev' into dev
This commit is contained in:
commit
9c7d8cc1e1
56 changed files with 1756 additions and 613 deletions
13
.github/workflows/linux.yml
vendored
13
.github/workflows/linux.yml
vendored
|
|
@ -71,7 +71,7 @@ jobs:
|
|||
libgtk2.0-dev libice-dev libsm-dev libicu-dev libdrm-dev dh-autoreconf \
|
||||
autoconf automake build-essential libxml2-dev libass-dev libfreetype6-dev \
|
||||
libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev \
|
||||
libvorbis-dev libenchant-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
|
||||
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev libxcb-keysyms1-dev libxcb-icccm4-dev libatspi2.0-dev \
|
||||
libxcb-render-util0-dev libxcb-util0-dev libxcb-xkb-dev libxrender-dev \
|
||||
libasound-dev libpulse-dev libxcb-sync0-dev libxcb-randr0-dev libegl1-mesa-dev \
|
||||
|
|
@ -323,7 +323,7 @@ jobs:
|
|||
run: |
|
||||
cd $LibrariesPath
|
||||
|
||||
git clone -b openal-soft-1.19.1 --depth=1 $GIT/kcat/openal-soft.git
|
||||
git clone -b openal-soft-1.20.1 --depth=1 $GIT/kcat/openal-soft.git
|
||||
cd openal-soft/build
|
||||
cmake -D LIBTYPE:STRING=STATIC ..
|
||||
make -j$(nproc)
|
||||
|
|
@ -342,14 +342,15 @@ jobs:
|
|||
run: |
|
||||
cd $LibrariesPath
|
||||
|
||||
opensslDir=openssl_${OPENSSL_VER}
|
||||
git clone -b OpenSSL_${OPENSSL_VER}-stable --depth=1 \
|
||||
$GIT/openssl/openssl openssl_${OPENSSL_VER}
|
||||
cd openssl_${OPENSSL_VER}
|
||||
$GIT/openssl/openssl $opensslDir
|
||||
cd $opensslDir
|
||||
./config --prefix=$LibrariesPath/openssl-cache
|
||||
make -j$(nproc)
|
||||
sudo make install
|
||||
sudo make install_sw
|
||||
cd ..
|
||||
rm -rf openssl_${OPENSSL_VER}
|
||||
rm -rf $opensslDir
|
||||
- name: OpenSSL install.
|
||||
run: |
|
||||
cd $LibrariesPath
|
||||
|
|
|
|||
4
.github/workflows/mac.yml
vendored
4
.github/workflows/mac.yml
vendored
|
|
@ -26,11 +26,11 @@ jobs:
|
|||
GIT: "https://github.com"
|
||||
PREFIX: "/usr/local/macos"
|
||||
MACOSX_DEPLOYMENT_TARGET: "10.12"
|
||||
XZ: "xz-5.0.5"
|
||||
XZ: "xz-5.2.4"
|
||||
QT: "5_12_5"
|
||||
OPENSSL_VER: "1_1_1"
|
||||
QT_PREFIX: "/usr/local/desktop-app/Qt-5.12.5"
|
||||
LIBICONV_VER: "libiconv-1.15"
|
||||
LIBICONV_VER: "libiconv-1.16"
|
||||
UPLOAD_ARTIFACT: "false"
|
||||
ONLY_CACHE: "false"
|
||||
MANUAL_CACHING: "2"
|
||||
|
|
|
|||
19
.github/workflows/snap.yml
vendored
19
.github/workflows/snap.yml
vendored
|
|
@ -47,6 +47,10 @@ jobs:
|
|||
md5cache=$(md5sum CMAKE_CACHE_KEY.txt | cut -c -32)
|
||||
echo ::set-env name=CMAKE_CACHE_KEY::$md5cache
|
||||
|
||||
awk -v RS="" -v ORS="\n\n" '/^ ffmpeg:/' snap/snapcraft.yaml > FFMPEG_CACHE_KEY.txt
|
||||
md5cache=$(md5sum FFMPEG_CACHE_KEY.txt | cut -c -32)
|
||||
echo ::set-env name=FFMPEG_CACHE_KEY::$md5cache
|
||||
|
||||
- name: CMake cache.
|
||||
id: cache-cmake
|
||||
uses: actions/cache@v1
|
||||
|
|
@ -58,6 +62,17 @@ jobs:
|
|||
if: steps.cache-cmake.outputs.cache-hit != 'true'
|
||||
run: snapcraft build --destructive-mode cmake
|
||||
|
||||
- name: FFmpeg cache.
|
||||
id: cache-ffmpeg
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: parts/ffmpeg
|
||||
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}-${{ env.FFMPEG_CACHE_KEY }}
|
||||
|
||||
- name: FFmpeg build.
|
||||
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
|
||||
run: snapcraft build --destructive-mode ffmpeg
|
||||
|
||||
- name: Kotatogram Desktop snap build.
|
||||
if: env.ONLY_CACHE == 'false'
|
||||
run: snapcraft --destructive-mode
|
||||
|
|
@ -80,5 +95,5 @@ jobs:
|
|||
|
||||
- name: Remove unneeded directories for cache.
|
||||
run: |
|
||||
rm -rf parts/cmake/{build,src,ubuntu}
|
||||
rm -rf parts/cmake/state/{stage,prime}
|
||||
rm -rf parts/{cmake,ffmpeg}/{build,src,ubuntu}
|
||||
rm -rf parts/{cmake,ffmpeg}/state/{stage,prime}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ project(Telegram
|
|||
)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Telegram)
|
||||
|
||||
get_filename_component(third_party_loc "Telegram/ThirdParty" REALPATH)
|
||||
get_filename_component(submodules_loc "Telegram" REALPATH)
|
||||
|
||||
include(cmake/variables.cmake)
|
||||
include(cmake/nice_target_sources.cmake)
|
||||
include(cmake/target_link_static_libraries.cmake)
|
||||
|
|
|
|||
|
|
@ -39,4 +39,4 @@ Full list of features will rewritten later, for now you can use one of `control-
|
|||
[flatpak]: https://flathub.org/apps/details/io.github.kotatogram
|
||||
[changelog]: https://github.com/kotatogram/kotatogram-desktop/blob/dev/kotatogram_changes.txt
|
||||
[preview_image]: https://github.com/kotatogram/kotatogram-desktop/blob/dev/docs/assets/ktg_preview.png "Preview of Kotatogram Desktop"
|
||||
[preview_image_url]: https://github.com/kotatogram/kotatogram-desktop/blob/dev/docs/assets/ktg_preview.png
|
||||
[preview_image_url]: https://github.com/kotatogram/kotatogram-desktop/blob/dev/docs/assets/ktg_preview.png
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ PRIVATE
|
|||
desktop-app::external_lz4
|
||||
desktop-app::external_rlottie
|
||||
desktop-app::external_zlib
|
||||
desktop-app::external_minizip
|
||||
desktop-app::external_qt
|
||||
desktop-app::external_qr_code_generator
|
||||
desktop-app::external_crash_reports
|
||||
|
|
@ -1219,14 +1220,15 @@ endif()
|
|||
|
||||
if (LINUX AND DESKTOP_APP_USE_PACKAGED)
|
||||
include(GNUInstallDirs)
|
||||
configure_file("../lib/xdg/kotatogramdesktop.appdata.xml.in" "${CMAKE_CURRENT_BINARY_DIR}/kotatogramdesktop.appdata.xml" @ONLY)
|
||||
install(TARGETS Telegram RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(FILES "Resources/art/icon16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon48.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon512.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/512x512/apps" RENAME "kotatogram.png")
|
||||
install(FILES "Resources/art/icon16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon48.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/64x64/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon512.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/512x512/apps" RENAME "telegram.png")
|
||||
install(FILES "../lib/xdg/kotatogramdesktop.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" RENAME "${TDESKTOP_LAUNCHER_BASENAME}.desktop")
|
||||
install(FILES "../lib/xdg/kotatogramdesktop.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME "${TDESKTOP_LAUNCHER_BASENAME}.appdata.xml")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kotatogramdesktop.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" RENAME "${TDESKTOP_LAUNCHER_BASENAME}.appdata.xml")
|
||||
endif()
|
||||
|
|
|
|||
225
Telegram/Patches/ffmpeg.diff
Normal file
225
Telegram/Patches/ffmpeg.diff
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
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
|
||||
|
|
@ -2239,6 +2239,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
"lng_linux_menu_undo" = "Undo";
|
||||
"lng_linux_menu_redo" = "Redo";
|
||||
"lng_linux_menu_tools" = "Tools";
|
||||
"lng_linux_menu_help" = "Help";
|
||||
|
||||
"lng_linux_no_audio_prefs" = "You don't have any audio configuration applications installed.";
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="1.9.19.0" />
|
||||
Version="1.9.20.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>
|
||||
|
|
|
|||
|
|
@ -1503,7 +1503,8 @@ void ApiWrap::applyLastParticipantsList(
|
|||
channel->mgInfo->lastAdmins.clear();
|
||||
channel->mgInfo->lastRestricted.clear();
|
||||
channel->mgInfo->lastParticipants.clear();
|
||||
channel->mgInfo->lastParticipantsStatus = MegagroupInfo::LastParticipantsUpToDate;
|
||||
channel->mgInfo->lastParticipantsStatus = MegagroupInfo::LastParticipantsUpToDate
|
||||
| MegagroupInfo::LastParticipantsOnceReceived;
|
||||
|
||||
auto botStatus = channel->mgInfo->botStatus;
|
||||
const auto emptyAdminRights = MTP_chatAdminRights(MTP_flags(0));
|
||||
|
|
|
|||
|
|
@ -206,8 +206,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
|
|||
if (_chat) {
|
||||
maxListSize += (_chat->participants.empty() ? _chat->lastAuthors.size() : _chat->participants.size());
|
||||
} else if (_channel && _channel->isMegagroup()) {
|
||||
if (_channel->mgInfo->lastParticipants.empty() || _channel->lastParticipantsCountOutdated()) {
|
||||
} else {
|
||||
if (!_channel->lastParticipantsRequestNeeded()) {
|
||||
maxListSize += _channel->mgInfo->lastParticipants.size();
|
||||
}
|
||||
}
|
||||
|
|
@ -274,7 +273,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
|
|||
}
|
||||
} else if (_channel && _channel->isMegagroup()) {
|
||||
QMultiMap<int32, UserData*> ordered;
|
||||
if (_channel->mgInfo->lastParticipants.empty() || _channel->lastParticipantsCountOutdated()) {
|
||||
if (_channel->lastParticipantsRequestNeeded()) {
|
||||
Auth().api().requestLastParticipants(_channel);
|
||||
} else {
|
||||
mrows.reserve(mrows.size() + _channel->mgInfo->lastParticipants.size());
|
||||
|
|
|
|||
|
|
@ -133,27 +133,22 @@ void DownloadDictionaryInBackground(
|
|||
const auto id = langs[counter];
|
||||
counter++;
|
||||
const auto destroyer = [=] {
|
||||
// This is a temporary workaround.
|
||||
const auto copyId = id;
|
||||
const auto copyLangs = langs;
|
||||
const auto copySession = session;
|
||||
const auto copyCounter = counter;
|
||||
BackgroundLoader = nullptr;
|
||||
BackgroundLoaderChanged.fire(0);
|
||||
|
||||
if (DictionaryExists(copyId)) {
|
||||
auto dicts = copySession->settings().dictionariesEnabled();
|
||||
if (!ranges::contains(dicts, copyId)) {
|
||||
dicts.push_back(copyId);
|
||||
copySession->settings().setDictionariesEnabled(std::move(dicts));
|
||||
copySession->saveSettingsDelayed();
|
||||
if (DictionaryExists(id)) {
|
||||
auto dicts = session->settings().dictionariesEnabled();
|
||||
if (!ranges::contains(dicts, id)) {
|
||||
dicts.push_back(id);
|
||||
session->settings().setDictionariesEnabled(std::move(dicts));
|
||||
session->saveSettingsDelayed();
|
||||
}
|
||||
}
|
||||
|
||||
if (copyCounter >= copyLangs.size()) {
|
||||
if (counter >= langs.size()) {
|
||||
return;
|
||||
}
|
||||
DownloadDictionaryInBackground(copySession, copyCounter, copyLangs);
|
||||
DownloadDictionaryInBackground(session, counter, langs);
|
||||
};
|
||||
if (DictionaryExists(id)) {
|
||||
destroyer();
|
||||
|
|
@ -194,20 +189,21 @@ DictLoader::DictLoader(
|
|||
}
|
||||
|
||||
void DictLoader::unpack(const QString &path) {
|
||||
Expects(_destroyCallback);
|
||||
crl::async([=] {
|
||||
const auto success = Spellchecker::UnpackDictionary(path, id());
|
||||
if (success) {
|
||||
QFile(path).remove();
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
crl::on_main(success ? _destroyCallback : [=] { fail(); });
|
||||
crl::on_main([=] { fail(); });
|
||||
});
|
||||
}
|
||||
|
||||
void DictLoader::destroy() {
|
||||
Expects(_destroyCallback);
|
||||
|
||||
_destroyCallback();
|
||||
crl::on_main(_destroyCallback);
|
||||
}
|
||||
|
||||
void DictLoader::fail() {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ private:
|
|||
void unpack(const QString &path) override;
|
||||
void fail() override;
|
||||
|
||||
// Be sure to always call it in the main thread.
|
||||
Fn<void()> _destroyCallback;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
|
|
|||
|
|
@ -18,33 +18,6 @@ namespace {
|
|||
|
||||
std::map<int, const char*> BetaLogs() {
|
||||
return {
|
||||
{
|
||||
1008005,
|
||||
"\xE2\x80\xA2 Create new themes based on your color "
|
||||
"and wallpaper choices.\n"
|
||||
|
||||
"\xE2\x80\xA2 Share your themes with other users via links.\n"
|
||||
|
||||
"\xE2\x80\xA2 Update your theme for all its users "
|
||||
"when you change something.\n"
|
||||
},
|
||||
{
|
||||
1009000,
|
||||
"\xE2\x80\xA2 System spell checker on Windows 8+ and macOS 10.12+.\n"
|
||||
},
|
||||
{
|
||||
1009002,
|
||||
"\xE2\x80\xA2 Videos in chats start playing automatically.\n"
|
||||
|
||||
"\xE2\x80\xA2 Resume playback from where you left off "
|
||||
"when watching long videos.\n"
|
||||
|
||||
"\xE2\x80\xA2 Control videos, GIFs and round video messages "
|
||||
"automatic playback in "
|
||||
"Settings > Advanced > Automatic media download.\n"
|
||||
|
||||
"\xE2\x80\xA2 Spell checker on Linux using Enchant.\n"
|
||||
},
|
||||
{
|
||||
1009010,
|
||||
"\xE2\x80\xA2 Switch to the Picture-in-Picture mode "
|
||||
|
|
@ -63,12 +36,19 @@ std::map<int, const char*> BetaLogs() {
|
|||
|
||||
"\xE2\x80\xA2 Bug fixes and other minor improvements."
|
||||
},
|
||||
|
||||
{
|
||||
1009017,
|
||||
"\xE2\x80\xA2 Spell checker on Windows 7.\n"
|
||||
|
||||
"\xE2\x80\xA2 Bug fixes and other minor improvements."
|
||||
},
|
||||
{
|
||||
1009020,
|
||||
"\xE2\x80\xA2 Fix crash in shared links search.\n"
|
||||
|
||||
"\xE2\x80\xA2 Fix blurred thumbnails in albums with video files.\n"
|
||||
|
||||
"\xE2\x80\xA2 Fix a possible crash in animated stickers rendering."
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ void Launcher::init() {
|
|||
prepareSettings();
|
||||
|
||||
QApplication::setApplicationName(qsl("KotatogramDesktop"));
|
||||
QApplication::setApplicationDisplayName(AppName.utf16());
|
||||
|
||||
#if defined(Q_OS_LINUX) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
QApplication::setDesktopFileName(Platform::GetLauncherFilename());
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ void Sandbox::socketError(QLocalSocket::LocalSocketError e) {
|
|||
psCheckLocalSocket(_localServerName);
|
||||
|
||||
if (!_localServer.listen(_localServerName)) {
|
||||
LOG(("Failed to start listening to %1 server, error %2").arg(_localServerName).arg(int(_localServer.serverError())));
|
||||
LOG(("Failed to start listening to %1 server: %2").arg(_localServerName).arg(_localServer.errorString()));
|
||||
return App::quit();
|
||||
}
|
||||
#endif // !Q_OS_WINRT
|
||||
|
|
|
|||
|
|
@ -341,6 +341,20 @@ bool ChannelData::isGroupAdmin(not_null<UserData*> user) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ChannelData::lastParticipantsRequestNeeded() const {
|
||||
if (!mgInfo) {
|
||||
return false;
|
||||
} else if (mgInfo->lastParticipantsCount == membersCount()) {
|
||||
mgInfo->lastParticipantsStatus
|
||||
&= ~MegagroupInfo::LastParticipantsCountOutdated;
|
||||
}
|
||||
return mgInfo->lastParticipants.empty()
|
||||
|| !(mgInfo->lastParticipantsStatus
|
||||
& MegagroupInfo::LastParticipantsOnceReceived)
|
||||
|| (mgInfo->lastParticipantsStatus
|
||||
& MegagroupInfo::LastParticipantsCountOutdated);
|
||||
}
|
||||
|
||||
QString ChannelData::adminRank(not_null<UserData*> user) const {
|
||||
if (!isGroupAdmin(user)) {
|
||||
return QString();
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public:
|
|||
|
||||
enum LastParticipantsStatus {
|
||||
LastParticipantsUpToDate = 0x00,
|
||||
LastParticipantsOnceReceived = 0x01,
|
||||
LastParticipantsCountOutdated = 0x02,
|
||||
};
|
||||
mutable int lastParticipantsStatus = LastParticipantsUpToDate;
|
||||
|
|
@ -219,21 +220,8 @@ public:
|
|||
void markForbidden();
|
||||
|
||||
[[nodiscard]] bool isGroupAdmin(not_null<UserData*> user) const;
|
||||
[[nodiscard]] bool lastParticipantsRequestNeeded() const;
|
||||
[[nodiscard]] QString adminRank(not_null<UserData*> user) const;
|
||||
|
||||
[[nodiscard]] bool lastParticipantsCountOutdated() const {
|
||||
if (!mgInfo
|
||||
|| !(mgInfo->lastParticipantsStatus
|
||||
& MegagroupInfo::LastParticipantsCountOutdated)) {
|
||||
return false;
|
||||
}
|
||||
if (mgInfo->lastParticipantsCount == membersCount()) {
|
||||
mgInfo->lastParticipantsStatus
|
||||
&= ~MegagroupInfo::LastParticipantsCountOutdated;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
[[nodiscard]] bool isMegagroup() const {
|
||||
return flags() & MTPDchannel::Flag::f_megagroup;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr auto kMemoryForCache = 32 * 1024 * 1024;
|
||||
// Updated Mar 3, 2020: Increase the size of the memory cache for media, to prevent items still being displayed from being unloaded.
|
||||
constexpr auto kMemoryForCache = 128 * 1024 * 1024; // was 32, updated to 128
|
||||
const auto kAnimatedStickerDimensions = QSize(512, 512);
|
||||
|
||||
using FilePathResolve = DocumentData::FilePathResolve;
|
||||
|
|
|
|||
|
|
@ -5171,6 +5171,8 @@ int HistoryWidget::countInitialScrollTop() {
|
|||
}
|
||||
|
||||
void HistoryWidget::createUnreadBarIfBelowVisibleArea(int withScrollTop) {
|
||||
Expects(_history != nullptr);
|
||||
|
||||
if (_history->unreadBar()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -5292,7 +5294,7 @@ void HistoryWidget::updateHistoryGeometry(
|
|||
newScrollTop = countInitialScrollTop();
|
||||
_historyInited = true;
|
||||
_scrollToAnimation.stop();
|
||||
} else if (wasAtBottom && !loadedDown) {
|
||||
} else if (wasAtBottom && !loadedDown && !_history->unreadBar()) {
|
||||
newScrollTop = countAutomaticScrollTop();
|
||||
} else {
|
||||
newScrollTop = std::min(
|
||||
|
|
|
|||
|
|
@ -280,6 +280,16 @@ bool Element::isUnderCursor() const {
|
|||
return _delegate->elementUnderCursor(this);
|
||||
}
|
||||
|
||||
bool Element::isLastAndSelfMessage() const {
|
||||
if (!hasOutLayout()) {
|
||||
return false;
|
||||
}
|
||||
if (const auto last = data()->_history->lastMessage()) {
|
||||
return last == data();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Element::setPendingResize() {
|
||||
_flags |= Flag::NeedsResize;
|
||||
if (_context == Context::History) {
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ public:
|
|||
bool pendingResize() const;
|
||||
bool isUnderCursor() const;
|
||||
|
||||
bool isLastAndSelfMessage() const;
|
||||
|
||||
bool isAttachedToPrevious() const;
|
||||
bool isAttachedToNext() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -896,7 +896,7 @@ void TopBarWidget::updateOnlineDisplay() {
|
|||
}
|
||||
} else if (const auto channel = _activeChat.peer()->asChannel()) {
|
||||
if (channel->isMegagroup() && channel->membersCount() > 0 && channel->membersCount() <= Global::ChatSizeMax()) {
|
||||
if (channel->mgInfo->lastParticipants.empty() || channel->lastParticipantsCountOutdated()) {
|
||||
if (channel->lastParticipantsRequestNeeded()) {
|
||||
session().api().requestLastParticipants(channel);
|
||||
}
|
||||
const auto self = session().user();
|
||||
|
|
|
|||
|
|
@ -1180,7 +1180,7 @@ void Gif::validateGroupedCache(
|
|||
const auto height = geometry.height();
|
||||
const auto options = Option::Smooth
|
||||
| Option::RoundedLarge
|
||||
| (blur ? Option(0) : Option::Blurred)
|
||||
| (blur ? Option::Blurred : Option(0))
|
||||
| ((corners & RectPart::TopLeft) ? Option::RoundedTopLeft : Option::None)
|
||||
| ((corners & RectPart::TopRight) ? Option::RoundedTopRight : Option::None)
|
||||
| ((corners & RectPart::BottomLeft) ? Option::RoundedBottomLeft : Option::None)
|
||||
|
|
@ -1494,7 +1494,8 @@ bool Gif::dataLoaded() const {
|
|||
bool Gif::needInfoDisplay() const {
|
||||
return _parent->data()->isSending()
|
||||
|| _data->uploading()
|
||||
|| _parent->isUnderCursor();
|
||||
|| _parent->isUnderCursor()
|
||||
|| _parent->isLastAndSelfMessage();
|
||||
}
|
||||
|
||||
bool Gif::needCornerStatusDisplay() const {
|
||||
|
|
|
|||
|
|
@ -464,7 +464,9 @@ bool GroupedMedia::computeNeedBubble() const {
|
|||
}
|
||||
|
||||
bool GroupedMedia::needInfoDisplay() const {
|
||||
return (_parent->data()->id < 0 || _parent->isUnderCursor());
|
||||
return (_parent->data()->id < 0
|
||||
|| _parent->isUnderCursor()
|
||||
|| _parent->isLastAndSelfMessage());
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
|||
|
|
@ -435,6 +435,7 @@ bool UnwrappedMedia::needInfoDisplay() const {
|
|||
return (_parent->data()->id < 0)
|
||||
|| (_parent->isUnderCursor())
|
||||
|| (_parent->displayRightAction())
|
||||
|| (_parent->isLastAndSelfMessage())
|
||||
|| (_parent->hasOutLayout()
|
||||
&& !Adaptive::ChatWide()
|
||||
&& _content->alwaysShowOutTimestamp());
|
||||
|
|
|
|||
|
|
@ -523,7 +523,9 @@ bool Photo::dataLoaded() const {
|
|||
}
|
||||
|
||||
bool Photo::needInfoDisplay() const {
|
||||
return (_parent->data()->id < 0 || _parent->isUnderCursor());
|
||||
return (_parent->data()->id < 0
|
||||
|| _parent->isUnderCursor()
|
||||
|| _parent->isLastAndSelfMessage());
|
||||
}
|
||||
|
||||
void Photo::validateGroupedCache(
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ bool PlaybackErrorHappened() {
|
|||
|
||||
void EnumeratePlaybackDevices() {
|
||||
auto deviceNames = QStringList();
|
||||
auto devices = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
|
||||
auto devices = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
|
||||
Assert(devices != nullptr);
|
||||
while (*devices != 0) {
|
||||
auto deviceName8Bit = QByteArray(devices);
|
||||
|
|
@ -92,7 +92,7 @@ void EnumeratePlaybackDevices() {
|
|||
}
|
||||
LOG(("Audio Playback Devices: %1").arg(deviceNames.join(';')));
|
||||
|
||||
if (auto device = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER)) {
|
||||
if (auto device = alcGetString(nullptr, ALC_DEFAULT_ALL_DEVICES_SPECIFIER)) {
|
||||
LOG(("Audio Playback Default Device: %1").arg(QString::fromLocal8Bit(device)));
|
||||
} else {
|
||||
LOG(("Audio Playback Default Device: (null)"));
|
||||
|
|
|
|||
|
|
@ -62,16 +62,12 @@ Instance::Instance() : _inner(new Inner(&_thread)) {
|
|||
|
||||
void Instance::check() {
|
||||
_available = false;
|
||||
if (auto defaultDevice = alcGetString(0, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) {
|
||||
if (auto device = alcCaptureOpenDevice(defaultDevice, kCaptureFrequency, AL_FORMAT_MONO16, kCaptureFrequency / 5)) {
|
||||
auto error = ErrorHappened(device);
|
||||
alcCaptureCloseDevice(device);
|
||||
_available = !error;
|
||||
} else {
|
||||
LOG(("Audio Error: Could not open capture device!"));
|
||||
}
|
||||
if (auto device = alcCaptureOpenDevice(nullptr, kCaptureFrequency, AL_FORMAT_MONO16, kCaptureFrequency / 5)) {
|
||||
auto error = ErrorHappened(device);
|
||||
alcCaptureCloseDevice(device);
|
||||
_available = !error;
|
||||
} else {
|
||||
LOG(("Audio Error: No capture device found!"));
|
||||
LOG(("Audio Error: Could not open capture device!"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,9 +173,7 @@ void Instance::Inner::onInit() {
|
|||
void Instance::Inner::onStart() {
|
||||
|
||||
// Start OpenAL Capture
|
||||
const ALCchar *dName = alcGetString(0, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||
DEBUG_LOG(("Audio Info: Capture device name '%1'").arg(dName));
|
||||
d->device = alcCaptureOpenDevice(dName, kCaptureFrequency, AL_FORMAT_MONO16, kCaptureFrequency / 5);
|
||||
d->device = alcCaptureOpenDevice(nullptr, kCaptureFrequency, AL_FORMAT_MONO16, kCaptureFrequency / 5);
|
||||
if (!d->device) {
|
||||
LOG(("Audio Error: capture device not present!"));
|
||||
emit error();
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "mtproto/details/mtproto_dump_to_text.h"
|
||||
|
||||
#include "base/zlib_help.h"
|
||||
#include "scheme-dump_to_text.h"
|
||||
#include "scheme.h"
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
namespace MTP::details {
|
||||
|
||||
bool DumpToTextCore(DumpToTextBuffer &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#include "statusnotifieritem.h"
|
||||
#include <QtCore/QTemporaryFile>
|
||||
#include <QtDBus/QDBusObjectPath>
|
||||
#include <dbusmenuexporter.h>
|
||||
#endif
|
||||
|
||||
namespace Platform {
|
||||
|
|
@ -38,13 +40,41 @@ public:
|
|||
public slots:
|
||||
void psShowTrayMenu();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
void onSNIOwnerChanged(
|
||||
const QString &service,
|
||||
const QString &oldOwner,
|
||||
const QString &newOwner);
|
||||
|
||||
void psLinuxUndo();
|
||||
void psLinuxRedo();
|
||||
void psLinuxCut();
|
||||
void psLinuxCopy();
|
||||
void psLinuxPaste();
|
||||
void psLinuxDelete();
|
||||
void psLinuxSelectAll();
|
||||
|
||||
void psLinuxBold();
|
||||
void psLinuxItalic();
|
||||
void psLinuxUnderline();
|
||||
void psLinuxStrikeOut();
|
||||
void psLinuxMonospace();
|
||||
void psLinuxClearFormat();
|
||||
|
||||
void onVisibleChanged(bool visible);
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
protected:
|
||||
void initHook() override;
|
||||
void unreadCounterChangedHook() override;
|
||||
void updateGlobalMenuHook() override;
|
||||
|
||||
void initTrayMenuHook() override;
|
||||
bool hasTrayIcon() const override;
|
||||
|
||||
void workmodeUpdated(DBIWorkMode mode) override;
|
||||
void createGlobalMenu() override;
|
||||
|
||||
QSystemTrayIcon *trayIcon = nullptr;
|
||||
QMenu *trayIconMenu = nullptr;
|
||||
|
|
@ -68,9 +98,32 @@ private:
|
|||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
StatusNotifierItem *_sniTrayIcon = nullptr;
|
||||
std::unique_ptr<QTemporaryFile> _trayIconFile = nullptr;
|
||||
std::unique_ptr<QTemporaryFile> _trayToolTipIconFile = nullptr;
|
||||
|
||||
void setSNITrayIcon(const QIcon &icon);
|
||||
DBusMenuExporter *_mainMenuExporter = nullptr;
|
||||
QDBusObjectPath _mainMenuPath;
|
||||
|
||||
QMenu *psMainMenu = nullptr;
|
||||
QAction *psLogout = nullptr;
|
||||
QAction *psUndo = nullptr;
|
||||
QAction *psRedo = nullptr;
|
||||
QAction *psCut = nullptr;
|
||||
QAction *psCopy = nullptr;
|
||||
QAction *psPaste = nullptr;
|
||||
QAction *psDelete = nullptr;
|
||||
QAction *psSelectAll = nullptr;
|
||||
QAction *psContacts = nullptr;
|
||||
QAction *psAddContact = nullptr;
|
||||
QAction *psNewGroup = nullptr;
|
||||
QAction *psNewChannel = nullptr;
|
||||
|
||||
QAction *psBold = nullptr;
|
||||
QAction *psItalic = nullptr;
|
||||
QAction *psUnderline = nullptr;
|
||||
QAction *psStrikeOut = nullptr;
|
||||
QAction *psMonospace = nullptr;
|
||||
QAction *psClearFormat = nullptr;
|
||||
|
||||
void setSNITrayIcon(int counter, bool muted, bool firstShow = false);
|
||||
void attachToSNITrayIcon();
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
|
|
|
|||
|
|
@ -7,18 +7,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "platform/linux/notifications_manager_linux.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#include "platform/linux/specific_linux.h"
|
||||
#include "history/history.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwindow.h"
|
||||
#include "facades.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#include <QtCore/QVersionNumber>
|
||||
#include <QtDBus/QDBusMessage>
|
||||
#include <QtDBus/QDBusReply>
|
||||
#include <QtDBus/QDBusError>
|
||||
#include <QtDBus/QDBusMetaType>
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
namespace Platform {
|
||||
namespace Notifications {
|
||||
|
|
@ -38,50 +40,101 @@ namespace {
|
|||
constexpr auto kService = "org.freedesktop.Notifications"_cs;
|
||||
constexpr auto kObjectPath = "/org/freedesktop/Notifications"_cs;
|
||||
constexpr auto kInterface = kService;
|
||||
constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
|
||||
|
||||
std::vector<QString> GetServerInformation(
|
||||
const std::shared_ptr<QDBusInterface> ¬ificationInterface) {
|
||||
bool InhibitedNotSupported = false;
|
||||
|
||||
std::vector<QString> ComputeServerInformation() {
|
||||
std::vector<QString> serverInformation;
|
||||
const auto serverInformationReply = notificationInterface
|
||||
->call(qsl("GetServerInformation"));
|
||||
|
||||
if (serverInformationReply.type() == QDBusMessage::ReplyMessage) {
|
||||
for (const auto &arg : serverInformationReply.arguments()) {
|
||||
if (static_cast<QMetaType::Type>(arg.type())
|
||||
== QMetaType::QString) {
|
||||
serverInformation.push_back(arg.toString());
|
||||
} else {
|
||||
LOG(("Native notification error: "
|
||||
"all elements in GetServerInformation "
|
||||
"should be strings"));
|
||||
}
|
||||
}
|
||||
} else if (serverInformationReply.type() == QDBusMessage::ErrorMessage) {
|
||||
LOG(("Native notification error: %1")
|
||||
.arg(serverInformationReply.errorMessage()));
|
||||
const auto message = QDBusMessage::createMethodCall(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
qsl("GetServerInformation"));
|
||||
|
||||
const auto reply = QDBusConnection::sessionBus().call(message);
|
||||
|
||||
if (reply.type() == QDBusMessage::ReplyMessage) {
|
||||
ranges::transform(
|
||||
reply.arguments(),
|
||||
ranges::back_inserter(serverInformation),
|
||||
&QVariant::toString
|
||||
);
|
||||
} else if (reply.type() == QDBusMessage::ErrorMessage) {
|
||||
LOG(("Native notification error: %1").arg(reply.errorMessage()));
|
||||
} else {
|
||||
LOG(("Native notification error: "
|
||||
"error while getting information about notification daemon"));
|
||||
"invalid reply from GetServerInformation"));
|
||||
}
|
||||
|
||||
return serverInformation;
|
||||
}
|
||||
|
||||
QStringList GetCapabilities(
|
||||
const std::shared_ptr<QDBusInterface> ¬ificationInterface) {
|
||||
const QDBusReply<QStringList> capabilitiesReply = notificationInterface
|
||||
->call(qsl("GetCapabilities"));
|
||||
std::vector<QString> GetServerInformation() {
|
||||
static const auto ServerInformation = ComputeServerInformation();
|
||||
return ServerInformation;
|
||||
}
|
||||
|
||||
if (capabilitiesReply.isValid()) {
|
||||
return capabilitiesReply.value();
|
||||
QStringList ComputeCapabilities() {
|
||||
const auto message = QDBusMessage::createMethodCall(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
qsl("GetCapabilities"));
|
||||
|
||||
const QDBusReply<QStringList> reply = QDBusConnection::sessionBus().call(
|
||||
message);
|
||||
|
||||
if (reply.isValid()) {
|
||||
return reply.value();
|
||||
} else {
|
||||
LOG(("Native notification error: %1")
|
||||
.arg(capabilitiesReply.error().message()));
|
||||
LOG(("Native notification error: %1").arg(reply.error().message()));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList GetCapabilities() {
|
||||
static const auto Capabilities = ComputeCapabilities();
|
||||
return Capabilities;
|
||||
}
|
||||
|
||||
bool Inhibited() {
|
||||
auto message = QDBusMessage::createMethodCall(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kPropertiesInterface.utf16(),
|
||||
qsl("Get"));
|
||||
|
||||
message.setArguments({
|
||||
qsl("org.freedesktop.Notifications"),
|
||||
qsl("Inhibited")
|
||||
});
|
||||
|
||||
const QDBusReply<QVariant> reply = QDBusConnection::sessionBus().call(
|
||||
message);
|
||||
|
||||
constexpr auto notSupportedErrors = {
|
||||
QDBusError::ServiceUnknown,
|
||||
QDBusError::InvalidArgs,
|
||||
};
|
||||
|
||||
if (reply.isValid()) {
|
||||
return reply.value().toBool();
|
||||
} else if (ranges::contains(notSupportedErrors, reply.error().type())) {
|
||||
InhibitedNotSupported = true;
|
||||
} else {
|
||||
if (reply.error().type() == QDBusError::AccessDenied) {
|
||||
InhibitedNotSupported = true;
|
||||
}
|
||||
|
||||
LOG(("Native notification error: %1").arg(reply.error().message()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVersionNumber ParseSpecificationVersion(
|
||||
const std::vector<QString> &serverInformation) {
|
||||
if (serverInformation.size() >= 4) {
|
||||
|
|
@ -94,10 +147,31 @@ QVersionNumber ParseSpecificationVersion(
|
|||
return QVersionNumber();
|
||||
}
|
||||
|
||||
QString GetImageKey(const QVersionNumber &specificationVersion) {
|
||||
if (!specificationVersion.isNull()) {
|
||||
const auto majorVersion = specificationVersion.majorVersion();
|
||||
const auto minorVersion = specificationVersion.minorVersion();
|
||||
|
||||
if ((majorVersion == 1 && minorVersion >= 2) || majorVersion > 1) {
|
||||
return qsl("image-data");
|
||||
} else if (majorVersion == 1 && minorVersion == 1) {
|
||||
return qsl("image_data");
|
||||
} else if ((majorVersion == 1 && minorVersion < 1)
|
||||
|| majorVersion < 1) {
|
||||
return qsl("icon_data");
|
||||
} else {
|
||||
LOG(("Native notification error: unknown specification version"));
|
||||
}
|
||||
} else {
|
||||
LOG(("Native notification error: specification version is null"));
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NotificationData::NotificationData(
|
||||
const std::shared_ptr<QDBusInterface> ¬ificationInterface,
|
||||
const base::weak_ptr<Manager> &manager,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
@ -105,12 +179,14 @@ NotificationData::NotificationData(
|
|||
PeerId peerId,
|
||||
MsgId msgId,
|
||||
bool hideReplyButton)
|
||||
: _notificationInterface(notificationInterface)
|
||||
: _dbusConnection(QDBusConnection::sessionBus())
|
||||
, _manager(manager)
|
||||
, _title(title)
|
||||
, _imageKey(GetImageKey(ParseSpecificationVersion(
|
||||
GetServerInformation())))
|
||||
, _peerId(peerId)
|
||||
, _msgId(msgId) {
|
||||
const auto capabilities = GetCapabilities(_notificationInterface);
|
||||
const auto capabilities = GetCapabilities();
|
||||
|
||||
if (capabilities.contains(qsl("body-markup"))) {
|
||||
_body = subtitle.isEmpty()
|
||||
|
|
@ -127,19 +203,16 @@ NotificationData::NotificationData(
|
|||
if (capabilities.contains(qsl("actions"))) {
|
||||
_actions << qsl("default") << QString();
|
||||
|
||||
_notificationInterface->connection().connect(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
qsl("ActionInvoked"),
|
||||
this,
|
||||
SLOT(notificationClicked(uint,QString)));
|
||||
_actions
|
||||
<< qsl("mail-mark-read")
|
||||
<< tr::lng_context_mark_read(tr::now);
|
||||
|
||||
if (capabilities.contains(qsl("inline-reply")) && !hideReplyButton) {
|
||||
_actions << qsl("inline-reply")
|
||||
_actions
|
||||
<< qsl("inline-reply")
|
||||
<< tr::lng_notification_reply(tr::now);
|
||||
|
||||
_notificationInterface->connection().connect(
|
||||
_dbusConnection.connect(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
|
|
@ -148,9 +221,18 @@ NotificationData::NotificationData(
|
|||
SLOT(notificationReplied(uint,QString)));
|
||||
} else {
|
||||
// icon name according to https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
|
||||
_actions << qsl("mail-reply-sender")
|
||||
_actions
|
||||
<< qsl("mail-reply-sender")
|
||||
<< tr::lng_notification_reply(tr::now);
|
||||
}
|
||||
|
||||
_dbusConnection.connect(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
qsl("ActionInvoked"),
|
||||
this,
|
||||
SLOT(actionInvoked(uint,QString)));
|
||||
}
|
||||
|
||||
if (capabilities.contains(qsl("action-icons"))) {
|
||||
|
|
@ -172,10 +254,9 @@ NotificationData::NotificationData(
|
|||
}
|
||||
|
||||
_hints["category"] = qsl("im.received");
|
||||
|
||||
_hints["desktop-entry"] = GetLauncherBasename();
|
||||
|
||||
_notificationInterface->connection().connect(
|
||||
_dbusConnection.connect(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
|
|
@ -184,65 +265,56 @@ NotificationData::NotificationData(
|
|||
SLOT(notificationClosed(uint)));
|
||||
}
|
||||
|
||||
bool NotificationData::show(bool hideNameAndPhoto) {
|
||||
const QDBusReply<uint> notifyReply = _notificationInterface->call(
|
||||
qsl("Notify"),
|
||||
bool NotificationData::show() {
|
||||
const auto iconName = _imageKey.isEmpty() || !_hints.contains(_imageKey)
|
||||
? GetIconName()
|
||||
: QString();
|
||||
|
||||
auto message = QDBusMessage::createMethodCall(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
qsl("Notify"));
|
||||
|
||||
message.setArguments({
|
||||
AppName.utf16(),
|
||||
uint(0),
|
||||
hideNameAndPhoto
|
||||
? qsl("telegram")
|
||||
: QString(),
|
||||
iconName,
|
||||
_title,
|
||||
_body,
|
||||
_actions,
|
||||
_hints,
|
||||
-1);
|
||||
-1
|
||||
});
|
||||
|
||||
if (notifyReply.isValid()) {
|
||||
_notificationId = notifyReply.value();
|
||||
const QDBusReply<uint> reply = _dbusConnection.call(
|
||||
message);
|
||||
|
||||
if (reply.isValid()) {
|
||||
_notificationId = reply.value();
|
||||
} else {
|
||||
LOG(("Native notification error: %1")
|
||||
.arg(notifyReply.error().message()));
|
||||
LOG(("Native notification error: %1").arg(reply.error().message()));
|
||||
}
|
||||
|
||||
return notifyReply.isValid();
|
||||
return reply.isValid();
|
||||
}
|
||||
|
||||
bool NotificationData::close() {
|
||||
const QDBusReply<void> closeReply = _notificationInterface
|
||||
->call(qsl("CloseNotification"), _notificationId);
|
||||
void NotificationData::close() {
|
||||
auto message = QDBusMessage::createMethodCall(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16(),
|
||||
qsl("CloseNotification"));
|
||||
|
||||
if (!closeReply.isValid()) {
|
||||
LOG(("Native notification error: %1")
|
||||
.arg(closeReply.error().message()));
|
||||
}
|
||||
message.setArguments({
|
||||
_notificationId
|
||||
});
|
||||
|
||||
return closeReply.isValid();
|
||||
_dbusConnection.send(message);
|
||||
}
|
||||
|
||||
void NotificationData::setImage(const QString &imagePath) {
|
||||
const auto specificationVersion = ParseSpecificationVersion(
|
||||
GetServerInformation(_notificationInterface));
|
||||
|
||||
QString imageKey;
|
||||
|
||||
if (!specificationVersion.isNull()) {
|
||||
const auto majorVersion = specificationVersion.majorVersion();
|
||||
const auto minorVersion = specificationVersion.minorVersion();
|
||||
|
||||
if ((majorVersion == 1 && minorVersion >= 2) || majorVersion > 1) {
|
||||
imageKey = qsl("image-data");
|
||||
} else if (majorVersion == 1 && minorVersion == 1) {
|
||||
imageKey = qsl("image_data");
|
||||
} else if ((majorVersion == 1 && minorVersion < 1)
|
||||
|| majorVersion < 1) {
|
||||
imageKey = qsl("icon_data");
|
||||
} else {
|
||||
LOG(("Native notification error: unknown specification version"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
LOG(("Native notification error: specification version is null"));
|
||||
if (_imageKey.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -253,20 +325,21 @@ void NotificationData::setImage(const QString &imagePath) {
|
|||
(const char*)image.constBits(),
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
image.byteCount());
|
||||
#else
|
||||
#else // Qt < 5.10.0
|
||||
image.sizeInBytes());
|
||||
#endif
|
||||
#endif // Qt >= 5.10.0
|
||||
|
||||
ImageData imageData;
|
||||
imageData.width = image.width();
|
||||
imageData.height = image.height();
|
||||
imageData.rowStride = image.bytesPerLine();
|
||||
imageData.hasAlpha = true;
|
||||
imageData.bitsPerSample = 8;
|
||||
imageData.channels = 4;
|
||||
imageData.data = imageBytes;
|
||||
const auto imageData = ImageData{
|
||||
image.width(),
|
||||
image.height(),
|
||||
image.bytesPerLine(),
|
||||
true,
|
||||
8,
|
||||
4,
|
||||
imageBytes
|
||||
};
|
||||
|
||||
_hints[imageKey] = QVariant::fromValue(imageData);
|
||||
_hints[_imageKey] = QVariant::fromValue(imageData);
|
||||
}
|
||||
|
||||
void NotificationData::notificationClosed(uint id) {
|
||||
|
|
@ -278,19 +351,23 @@ void NotificationData::notificationClosed(uint id) {
|
|||
}
|
||||
}
|
||||
|
||||
void NotificationData::notificationClicked(uint id, const QString &actionId) {
|
||||
void NotificationData::actionInvoked(uint id, const QString &actionName) {
|
||||
if (id != _notificationId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (actionId != qsl("default") && actionId != qsl("mail-reply-sender")) {
|
||||
return;
|
||||
if (actionName == qsl("default")
|
||||
|| actionName == qsl("mail-reply-sender")) {
|
||||
const auto manager = _manager;
|
||||
crl::on_main(manager, [=] {
|
||||
manager->notificationActivated(_peerId, _msgId);
|
||||
});
|
||||
} else if (actionName == qsl("mail-mark-read")) {
|
||||
const auto manager = _manager;
|
||||
crl::on_main(manager, [=] {
|
||||
manager->notificationReplied(_peerId, _msgId, {});
|
||||
});
|
||||
}
|
||||
|
||||
const auto manager = _manager;
|
||||
crl::on_main(manager, [=] {
|
||||
manager->notificationActivated(_peerId, _msgId);
|
||||
});
|
||||
}
|
||||
|
||||
void NotificationData::notificationReplied(uint id, const QString &text) {
|
||||
|
|
@ -306,7 +383,8 @@ QDBusArgument &operator<<(
|
|||
QDBusArgument &argument,
|
||||
const NotificationData::ImageData &imageData) {
|
||||
argument.beginStructure();
|
||||
argument << imageData.width
|
||||
argument
|
||||
<< imageData.width
|
||||
<< imageData.height
|
||||
<< imageData.rowStride
|
||||
<< imageData.hasAlpha
|
||||
|
|
@ -321,7 +399,8 @@ const QDBusArgument &operator>>(
|
|||
const QDBusArgument &argument,
|
||||
NotificationData::ImageData &imageData) {
|
||||
argument.beginStructure();
|
||||
argument >> imageData.width
|
||||
argument
|
||||
>> imageData.width
|
||||
>> imageData.height
|
||||
>> imageData.rowStride
|
||||
>> imageData.hasAlpha
|
||||
|
|
@ -331,20 +410,39 @@ const QDBusArgument &operator>>(
|
|||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
bool SkipAudio() {
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
if (Supported()
|
||||
&& GetCapabilities().contains(qsl("inhibitions"))
|
||||
&& !InhibitedNotSupported) {
|
||||
return Inhibited();
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipToast() {
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
if (Supported()
|
||||
&& GetCapabilities().contains(qsl("inhibitions"))
|
||||
&& !InhibitedNotSupported) {
|
||||
return Inhibited();
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Supported() {
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
static const auto Available = QDBusInterface(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16()
|
||||
).isValid();
|
||||
|
||||
static const auto Available = !GetServerInformation().empty();
|
||||
return Available;
|
||||
#else
|
||||
#else // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
return false;
|
||||
#endif
|
||||
#endif // TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
}
|
||||
|
||||
std::unique_ptr<Window::Notifications::Manager> Create(
|
||||
|
|
@ -353,34 +451,36 @@ std::unique_ptr<Window::Notifications::Manager> Create(
|
|||
if (Global::NativeNotifications() && Supported()) {
|
||||
return std::make_unique<Manager>(system);
|
||||
}
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
Manager::Private::Private(Manager *manager, Type type)
|
||||
Manager::Private::Private(not_null<Manager*> manager, Type type)
|
||||
: _cachedUserpics(type)
|
||||
, _manager(manager)
|
||||
, _notificationInterface(
|
||||
std::make_shared<QDBusInterface>(
|
||||
kService.utf16(),
|
||||
kObjectPath.utf16(),
|
||||
kInterface.utf16())) {
|
||||
, _manager(manager) {
|
||||
qDBusRegisterMetaType<NotificationData::ImageData>();
|
||||
|
||||
const auto specificationVersion = ParseSpecificationVersion(
|
||||
GetServerInformation(_notificationInterface));
|
||||
const auto serverInformation = GetServerInformation();
|
||||
const auto capabilities = GetCapabilities();
|
||||
|
||||
const auto capabilities = GetCapabilities(_notificationInterface);
|
||||
if (!serverInformation.empty()) {
|
||||
LOG(("Notification daemon product name: %1")
|
||||
.arg(serverInformation[0]));
|
||||
|
||||
LOG(("Notification daemon vendor name: %1")
|
||||
.arg(serverInformation[1]));
|
||||
|
||||
LOG(("Notification daemon version: %1")
|
||||
.arg(serverInformation[2]));
|
||||
|
||||
if (!specificationVersion.isNull()) {
|
||||
LOG(("Notification daemon specification version: %1")
|
||||
.arg(specificationVersion.toString()));
|
||||
.arg(serverInformation[3]));
|
||||
}
|
||||
|
||||
if (!capabilities.empty()) {
|
||||
const auto capabilitiesString = capabilities.join(", ");
|
||||
LOG(("Notification daemon capabilities: %1").arg(capabilitiesString));
|
||||
if (!capabilities.isEmpty()) {
|
||||
LOG(("Notification daemon capabilities: %1")
|
||||
.arg(capabilities.join(", ")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +493,6 @@ void Manager::Private::showNotification(
|
|||
bool hideNameAndPhoto,
|
||||
bool hideReplyButton) {
|
||||
auto notification = std::make_shared<NotificationData>(
|
||||
_notificationInterface,
|
||||
_manager,
|
||||
title,
|
||||
subtitle,
|
||||
|
|
@ -421,7 +520,7 @@ void Manager::Private::showNotification(
|
|||
i = _notifications.insert(peer->id, QMap<MsgId, Notification>());
|
||||
}
|
||||
_notifications[peer->id].insert(msgId, notification);
|
||||
if (!notification->show(hideNameAndPhoto)) {
|
||||
if (!notification->show()) {
|
||||
i = _notifications.find(peer->id);
|
||||
if (i != _notifications.cend()) {
|
||||
i->remove(msgId);
|
||||
|
|
@ -465,7 +564,7 @@ Manager::Private::~Private() {
|
|||
clearAll();
|
||||
}
|
||||
|
||||
Manager::Manager(Window::Notifications::System *system)
|
||||
Manager::Manager(not_null<Window::Notifications::System*> system)
|
||||
: NativeManager(system)
|
||||
, _private(std::make_unique<Private>(this, Private::Type::Rounded)) {
|
||||
}
|
||||
|
|
@ -501,7 +600,7 @@ void Manager::doClearAllFast() {
|
|||
void Manager::doClearFromHistory(not_null<History*> history) {
|
||||
_private->clearFromHistory(history);
|
||||
}
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Platform
|
||||
|
|
|
|||
|
|
@ -12,28 +12,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/weak_ptr.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#include <QtDBus/QDBusInterface>
|
||||
#include <QtDBus/QDBusConnection>
|
||||
#include <QtDBus/QDBusArgument>
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
namespace Platform {
|
||||
namespace Notifications {
|
||||
|
||||
inline bool SkipAudio() {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool SkipToast() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
class NotificationData : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NotificationData(
|
||||
const std::shared_ptr<QDBusInterface> ¬ificationInterface,
|
||||
const base::weak_ptr<Manager> &manager,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
@ -47,8 +38,8 @@ public:
|
|||
NotificationData(NotificationData &&other) = delete;
|
||||
NotificationData &operator=(NotificationData &&other) = delete;
|
||||
|
||||
bool show(bool hideNameAndPhoto);
|
||||
bool close();
|
||||
bool show();
|
||||
void close();
|
||||
void setImage(const QString &imagePath);
|
||||
|
||||
struct ImageData {
|
||||
|
|
@ -59,13 +50,14 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
std::shared_ptr<QDBusInterface> _notificationInterface;
|
||||
QDBusConnection _dbusConnection;
|
||||
base::weak_ptr<Manager> _manager;
|
||||
|
||||
QString _title;
|
||||
QString _body;
|
||||
QStringList _actions;
|
||||
QVariantMap _hints;
|
||||
QString _imageKey;
|
||||
|
||||
uint _notificationId;
|
||||
PeerId _peerId;
|
||||
|
|
@ -73,7 +65,7 @@ private:
|
|||
|
||||
private slots:
|
||||
void notificationClosed(uint id);
|
||||
void notificationClicked(uint id, const QString &actionId);
|
||||
void actionInvoked(uint id, const QString &actionName);
|
||||
void notificationReplied(uint id, const QString &text);
|
||||
};
|
||||
|
||||
|
|
@ -91,7 +83,7 @@ class Manager
|
|||
: public Window::Notifications::NativeManager
|
||||
, public base::has_weak_ptr {
|
||||
public:
|
||||
Manager(Window::Notifications::System *system);
|
||||
Manager(not_null<Window::Notifications::System*> system);
|
||||
void clearNotification(PeerId peerId, MsgId msgId);
|
||||
~Manager();
|
||||
|
||||
|
|
@ -116,7 +108,7 @@ private:
|
|||
class Manager::Private {
|
||||
public:
|
||||
using Type = Window::Notifications::CachedUserpics::Type;
|
||||
explicit Private(Manager *manager, Type type);
|
||||
explicit Private(not_null<Manager*> manager, Type type);
|
||||
|
||||
void showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
|
|
@ -138,13 +130,12 @@ private:
|
|||
|
||||
Window::Notifications::CachedUserpics _cachedUserpics;
|
||||
base::weak_ptr<Manager> _manager;
|
||||
std::shared_ptr<QDBusInterface> _notificationInterface;
|
||||
};
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Platform
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
Q_DECLARE_METATYPE(Platform::Notifications::NotificationData::ImageData)
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
|
|
|||
|
|
@ -26,7 +26,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
#include <QtDBus/QDBusInterface>
|
||||
#endif
|
||||
#include <QtDBus/QDBusConnection>
|
||||
#include <QtDBus/QDBusMessage>
|
||||
#include <QtDBus/QDBusReply>
|
||||
#include <QtDBus/QDBusError>
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -44,9 +48,10 @@ namespace {
|
|||
|
||||
constexpr auto kDesktopFile = ":/misc/kotatogramdesktop.desktop"_cs;
|
||||
constexpr auto kSnapLauncherDir = "/var/lib/snapd/desktop/applications/"_cs;
|
||||
constexpr auto kIconName = "telegram"_cs;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
void SandboxAutostart(bool autostart) {
|
||||
void SandboxAutostart(bool autostart, bool silent = false) {
|
||||
QVariantMap options;
|
||||
options["reason"] = tr::lng_settings_auto_start(tr::now);
|
||||
options["autostart"] = autostart;
|
||||
|
|
@ -56,20 +61,29 @@ void SandboxAutostart(bool autostart) {
|
|||
});
|
||||
options["dbus-activatable"] = false;
|
||||
|
||||
const auto requestBackgroundReply = QDBusInterface(
|
||||
auto message = QDBusMessage::createMethodCall(
|
||||
qsl("org.freedesktop.portal.Desktop"),
|
||||
qsl("/org/freedesktop/portal/desktop"),
|
||||
qsl("org.freedesktop.portal.Background")
|
||||
).call(qsl("RequestBackground"), QString(), options);
|
||||
qsl("org.freedesktop.portal.Background"),
|
||||
qsl("RequestBackground"));
|
||||
|
||||
if (requestBackgroundReply.type() == QDBusMessage::ErrorMessage) {
|
||||
LOG(("Flatpak autostart error: %1")
|
||||
.arg(requestBackgroundReply.errorMessage()));
|
||||
} else if (requestBackgroundReply.type() != QDBusMessage::ReplyMessage) {
|
||||
LOG(("Flatpak autostart error: invalid reply"));
|
||||
message.setArguments({
|
||||
QString(),
|
||||
options
|
||||
});
|
||||
|
||||
if (silent) {
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
} else {
|
||||
const QDBusReply<void> reply = QDBusConnection::sessionBus().call(
|
||||
message);
|
||||
|
||||
if (!reply.isValid()) {
|
||||
LOG(("Flatpak autostart error: %1").arg(reply.error().message()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
bool RunShellCommand(const QByteArray &command) {
|
||||
auto result = system(command.constData());
|
||||
|
|
@ -120,7 +134,10 @@ void FallbackFontConfig() {
|
|||
#endif // TDESKTOP_USE_FONT_CONFIG_FALLBACK
|
||||
}
|
||||
|
||||
bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
|
||||
bool GenerateDesktopFile(
|
||||
const QString &targetPath,
|
||||
const QString &args,
|
||||
bool silent = false) {
|
||||
DEBUG_LOG(("App Info: placing .desktop file to %1").arg(targetPath));
|
||||
if (!QDir(targetPath).exists()) QDir().mkpath(targetPath);
|
||||
|
||||
|
|
@ -142,7 +159,9 @@ bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
|
|||
fileText = s.readAll();
|
||||
source.close();
|
||||
} else {
|
||||
LOG(("App Error: Could not open '%1' for read").arg(sourceFile));
|
||||
if (!silent) {
|
||||
LOG(("App Error: Could not open '%1' for read").arg(sourceFile));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -150,23 +169,28 @@ bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
|
|||
if (target.open(QIODevice::WriteOnly)) {
|
||||
#ifdef DESKTOP_APP_USE_PACKAGED
|
||||
fileText = fileText.replace(
|
||||
QRegularExpression(qsl("^Exec=(.*) -- %u$"),
|
||||
QRegularExpression(
|
||||
qsl("^Exec=(.*) -- %u$"),
|
||||
QRegularExpression::MultilineOption),
|
||||
qsl("Exec=\\1")
|
||||
+ (args.isEmpty() ? QString() : ' ' + args));
|
||||
#else
|
||||
#else // DESKTOP_APP_USE_PACKAGED
|
||||
fileText = fileText.replace(
|
||||
QRegularExpression(qsl("^TryExec=.*$"),
|
||||
QRegularExpression(
|
||||
qsl("^TryExec=.*$"),
|
||||
QRegularExpression::MultilineOption),
|
||||
qsl("TryExec=")
|
||||
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName())));
|
||||
+ QFile::encodeName(cExeDir() + cExeName())
|
||||
.replace('\\', qsl("\\\\")));
|
||||
fileText = fileText.replace(
|
||||
QRegularExpression(qsl("^Exec=.*$"),
|
||||
QRegularExpression(
|
||||
qsl("^Exec=.*$"),
|
||||
QRegularExpression::MultilineOption),
|
||||
qsl("Exec=")
|
||||
+ EscapeShell(QFile::encodeName(cExeDir() + cExeName()))
|
||||
.replace('\\', qsl("\\\\"))
|
||||
+ (args.isEmpty() ? QString() : ' ' + args));
|
||||
#endif
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED
|
||||
target.write(fileText.toUtf8());
|
||||
target.close();
|
||||
|
||||
|
|
@ -175,7 +199,9 @@ bool GenerateDesktopFile(const QString &targetPath, const QString &args) {
|
|||
|
||||
return true;
|
||||
} else {
|
||||
LOG(("App Error: Could not open '%1' for write").arg(targetFile));
|
||||
if (!silent) {
|
||||
LOG(("App Error: Could not open '%1' for write").arg(targetFile));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -189,9 +215,7 @@ void SetApplicationIcon(const QIcon &icon) {
|
|||
}
|
||||
|
||||
bool InSandbox() {
|
||||
static const auto Sandbox = QFileInfo::exists(
|
||||
QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation)
|
||||
+ qsl("/flatpak-info"));
|
||||
static const auto Sandbox = QFileInfo::exists(qsl("/.flatpak-info"));
|
||||
return Sandbox;
|
||||
}
|
||||
|
||||
|
|
@ -208,12 +232,18 @@ bool IsXDGDesktopPortalPresent() {
|
|||
"org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop").isValid();
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
return XDGDesktopPortalPresent;
|
||||
}
|
||||
|
||||
bool UseXDGDesktopPortal() {
|
||||
static const auto UsePortal = qEnvironmentVariableIsSet("TDESKTOP_USE_PORTAL")
|
||||
&& IsXDGDesktopPortalPresent();
|
||||
static const auto UsePortal = [&] {
|
||||
const auto envVar = qEnvironmentVariableIsSet("TDESKTOP_USE_PORTAL");
|
||||
const auto portalPresent = IsXDGDesktopPortalPresent();
|
||||
|
||||
return envVar && portalPresent;
|
||||
}();
|
||||
|
||||
return UsePortal;
|
||||
}
|
||||
|
||||
|
|
@ -309,7 +339,6 @@ QString GetLauncherBasename() {
|
|||
return possibleBasenames[0];
|
||||
}();
|
||||
|
||||
LOG(("Launcher filename is %1.desktop").arg(LauncherBasename));
|
||||
return LauncherBasename;
|
||||
}
|
||||
|
||||
|
|
@ -319,6 +348,55 @@ QString GetLauncherFilename() {
|
|||
return LauncherFilename;
|
||||
}
|
||||
|
||||
QString GetIconName() {
|
||||
static const auto IconName = InSandbox()
|
||||
? GetLauncherBasename()
|
||||
: kIconName.utf16();
|
||||
return IconName;
|
||||
}
|
||||
|
||||
std::optional<crl::time> LastUserInputTime() {
|
||||
// TODO: a fallback pure-X11 implementation, this one covers only major DEs on X11 and Wayland
|
||||
// an example: https://stackoverflow.com/q/9049087
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
static auto NotSupported = false;
|
||||
|
||||
if (NotSupported) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static const auto message = QDBusMessage::createMethodCall(
|
||||
qsl("org.freedesktop.ScreenSaver"),
|
||||
qsl("/org/freedesktop/ScreenSaver"),
|
||||
qsl("org.freedesktop.ScreenSaver"),
|
||||
qsl("GetSessionIdleTime"));
|
||||
|
||||
const QDBusReply<uint> reply = QDBusConnection::sessionBus().call(
|
||||
message);
|
||||
|
||||
constexpr auto notSupportedErrors = {
|
||||
QDBusError::ServiceUnknown,
|
||||
QDBusError::NotSupported,
|
||||
};
|
||||
|
||||
if (reply.isValid()) {
|
||||
return (crl::now() - static_cast<crl::time>(reply.value()));
|
||||
} else if (ranges::contains(notSupportedErrors, reply.error().type())) {
|
||||
NotSupported = true;
|
||||
} else {
|
||||
if (reply.error().type() == QDBusError::AccessDenied) {
|
||||
NotSupported = true;
|
||||
}
|
||||
|
||||
LOG(("Unable to get last user input time: %1: %2")
|
||||
.arg(reply.error().name())
|
||||
.arg(reply.error().message()));
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
namespace {
|
||||
|
|
@ -395,15 +473,18 @@ QString getHomeDir() {
|
|||
|
||||
QString psAppDataPath() {
|
||||
// We should not use ~/.TelegramDesktop, since it's a fork.
|
||||
|
||||
// auto home = getHomeDir();
|
||||
// if (!home.isEmpty()) {
|
||||
// auto oldPath = home + qsl(".TelegramDesktop/");
|
||||
// auto oldSettingsBase = oldPath + qsl("tdata/settings");
|
||||
// if (QFile(oldSettingsBase + '0').exists() || QFile(oldSettingsBase + '1').exists()) {
|
||||
// return oldPath;
|
||||
// }
|
||||
// }
|
||||
/*
|
||||
auto home = getHomeDir();
|
||||
if (!home.isEmpty()) {
|
||||
auto oldPath = home + qsl(".TelegramDesktop/");
|
||||
auto oldSettingsBase = oldPath + qsl("tdata/settings");
|
||||
if (QFile(oldSettingsBase + '0').exists()
|
||||
|| QFile(oldSettingsBase + '1').exists()
|
||||
|| QFile(oldSettingsBase + 's').exists()) {
|
||||
return oldPath;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + '/';
|
||||
}
|
||||
|
|
@ -432,8 +513,12 @@ int psFixPrevious() {
|
|||
namespace Platform {
|
||||
|
||||
void start() {
|
||||
LOG(("Launcher filename: %1").arg(GetLauncherFilename()));
|
||||
FallbackFontConfig();
|
||||
|
||||
qputenv("PULSE_PROP_application.name", AppName.utf8());
|
||||
qputenv("PULSE_PROP_application.icon_name", GetIconName().toLatin1());
|
||||
|
||||
#ifdef TDESKTOP_FORCE_GTK_FILE_DIALOG
|
||||
LOG(("Checking for XDG Desktop Portal..."));
|
||||
// this can give us a chance to use a proper file dialog for current session
|
||||
|
|
@ -454,24 +539,29 @@ void start() {
|
|||
void finish() {
|
||||
}
|
||||
|
||||
void RegisterCustomScheme() {
|
||||
void RegisterCustomScheme(bool force) {
|
||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||
auto home = getHomeDir();
|
||||
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty())
|
||||
return; // don't update desktop file for alpha version
|
||||
if (Core::UpdaterDisabled())
|
||||
const auto home = getHomeDir();
|
||||
if (home.isEmpty() || cExeName().isEmpty())
|
||||
return;
|
||||
|
||||
static const auto disabledByEnv = qEnvironmentVariableIsSet(
|
||||
"TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION");
|
||||
|
||||
// don't update desktop file for alpha version or if updater is disabled
|
||||
if ((cAlphaVersion() || Core::UpdaterDisabled() || disabledByEnv)
|
||||
&& !force)
|
||||
return;
|
||||
|
||||
const auto applicationsPath = QStandardPaths::writableLocation(
|
||||
QStandardPaths::ApplicationsLocation) + '/';
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
||||
GenerateDesktopFile(applicationsPath, qsl("-- %u"));
|
||||
|
||||
const auto icons =
|
||||
QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericDataLocation)
|
||||
+ qsl("/icons/");
|
||||
+ qsl("/icons/");
|
||||
|
||||
if (!QDir(icons).exists()) QDir().mkpath(icons);
|
||||
|
||||
|
|
@ -485,10 +575,9 @@ void RegisterCustomScheme() {
|
|||
}
|
||||
if (!iconExists) {
|
||||
if (QFile(qsl(":/gui/art/logo_256.png")).copy(icon)) {
|
||||
DEBUG_LOG(("App Info: Icon copied to 'tdata'"));
|
||||
DEBUG_LOG(("App Info: Icon copied to '%1'").arg(icon));
|
||||
}
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
||||
|
||||
RunShellCommand("update-desktop-database "
|
||||
+ EscapeShell(QFile::encodeName(applicationsPath)));
|
||||
|
|
@ -559,14 +648,14 @@ bool psShowOpenWithMenu(int x, int y, const QString &file) {
|
|||
}
|
||||
|
||||
void psAutoStart(bool start, bool silent) {
|
||||
auto home = getHomeDir();
|
||||
if (home.isEmpty() || cAlphaVersion() || cExeName().isEmpty())
|
||||
const auto home = getHomeDir();
|
||||
if (home.isEmpty() || cExeName().isEmpty())
|
||||
return;
|
||||
|
||||
if (InSandbox()) {
|
||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||
SandboxAutostart(start);
|
||||
#endif
|
||||
SandboxAutostart(start, silent);
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED
|
||||
} else {
|
||||
const auto autostart = [&] {
|
||||
if (InSnap()) {
|
||||
|
|
@ -578,12 +667,12 @@ void psAutoStart(bool start, bool silent) {
|
|||
} else {
|
||||
return QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericConfigLocation)
|
||||
+ qsl("/autostart/");
|
||||
+ qsl("/autostart/");
|
||||
}
|
||||
}();
|
||||
|
||||
if (start) {
|
||||
GenerateDesktopFile(autostart, qsl("-autostart"));
|
||||
GenerateDesktopFile(autostart, qsl("-autostart"), silent);
|
||||
} else {
|
||||
QFile::remove(autostart + GetLauncherFilename());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ QString SingleInstanceLocalServerName(const QString &hash);
|
|||
QString GetLauncherBasename();
|
||||
QString GetLauncherFilename();
|
||||
|
||||
inline std::optional<crl::time> LastUserInputTime() {
|
||||
return std::nullopt;
|
||||
}
|
||||
QString GetIconName();
|
||||
|
||||
inline void IgnoreApplicationActivationRightNow() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
|||
@implementation PinnedDialogButton {
|
||||
rpl::lifetime _lifetime;
|
||||
rpl::lifetime _peerChangedLifetime;
|
||||
base::has_weak_ptr _guard;
|
||||
|
||||
bool isWaitingUserpicLoad;
|
||||
}
|
||||
|
||||
|
|
@ -518,7 +520,7 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
|||
) | rpl::filter([](const Window::Theme::BackgroundUpdate &update) {
|
||||
return update.paletteChanged();
|
||||
}) | rpl::start_with_next([=] {
|
||||
crl::on_main([=] {
|
||||
crl::on_main(&_guard, [=] {
|
||||
if (_number <= kSavedMessagesId || UseEmptyUserpic(_peer)) {
|
||||
[self updateUserpic];
|
||||
} else if (_peer
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ void RemoveQuarantine(const QString &path) {
|
|||
removexattr(local.data(), kQuarantineAttribute, 0);
|
||||
}
|
||||
|
||||
void RegisterCustomScheme() {
|
||||
void RegisterCustomScheme(bool force) {
|
||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
|
||||
DEBUG_LOG(("App Info: set default handler for 'tg' scheme result: %1").arg(result));
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ enum class SystemSettingsType {
|
|||
|
||||
void SetWatchingMediaKeys(bool watching);
|
||||
void SetApplicationIcon(const QIcon &icon);
|
||||
void RegisterCustomScheme();
|
||||
void RegisterCustomScheme(bool force = false);
|
||||
PermissionStatus GetPermissionStatus(PermissionType type);
|
||||
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
|
||||
void OpenSystemSettingsForPermission(PermissionType type);
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ namespace {
|
|||
|
||||
namespace Platform {
|
||||
|
||||
void RegisterCustomScheme() {
|
||||
void RegisterCustomScheme(bool force) {
|
||||
if (cExeName().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ void GroupMembersWidget::refreshMembers() {
|
|||
fillChatMembers(chat);
|
||||
} else if (const auto megagroup = peer()->asMegagroup()) {
|
||||
auto &megagroupInfo = megagroup->mgInfo;
|
||||
if (megagroupInfo->lastParticipants.empty() || megagroup->lastParticipantsCountOutdated()) {
|
||||
if (megagroup->lastParticipantsRequestNeeded()) {
|
||||
Auth().api().requestLastParticipants(megagroup);
|
||||
}
|
||||
fillMegagroupMembers(megagroup);
|
||||
|
|
|
|||
|
|
@ -112,10 +112,12 @@ auto GenerateCodes() {
|
|||
}
|
||||
});
|
||||
});
|
||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||
codes.emplace(qsl("registertg"), [](::Main::Session *session) {
|
||||
Platform::RegisterCustomScheme();
|
||||
Platform::RegisterCustomScheme(true);
|
||||
Ui::Toast::Show("Forced custom scheme register.");
|
||||
});
|
||||
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||
codes.emplace(qsl("export"), [](::Main::Session *session) {
|
||||
session->data().startExport();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3167,7 +3167,7 @@ void writeFileLocation(MediaKey location, const FileLocation &local) {
|
|||
return;
|
||||
}
|
||||
if (i.value().first != location) {
|
||||
for (FileLocations::iterator j = _fileLocations.find(i.value().first), e = _fileLocations.end(); (j != e) && (j.key() == i.value().first);) {
|
||||
for (FileLocations::iterator j = _fileLocations.find(i.value().first), e = _fileLocations.end(); (j != e) && (j.key() == i.value().first); ++j) {
|
||||
if (j.value() == i.value().second) {
|
||||
_fileLocations.erase(j);
|
||||
break;
|
||||
|
|
@ -3682,7 +3682,21 @@ void _readStickerSets(FileKey &stickersKey, Stickers::Order *outOrder = nullptr,
|
|||
|
||||
// Read orders of installed and featured stickers.
|
||||
if (outOrder) {
|
||||
stickers.stream >> *outOrder;
|
||||
auto outOrderCount = quint32();
|
||||
stickers.stream >> outOrderCount;
|
||||
if (!_checkStreamStatus(stickers.stream) || outOrderCount > 1000) {
|
||||
return failed();
|
||||
}
|
||||
outOrder->reserve(outOrderCount);
|
||||
for (auto i = 0; i != outOrderCount; ++i) {
|
||||
auto value = uint64();
|
||||
stickers.stream >> value;
|
||||
if (!_checkStreamStatus(stickers.stream)) {
|
||||
outOrder->clear();
|
||||
return failed();
|
||||
}
|
||||
outOrder->push_back(value);
|
||||
}
|
||||
}
|
||||
if (!_checkStreamStatus(stickers.stream)) {
|
||||
return failed();
|
||||
|
|
|
|||
|
|
@ -117,9 +117,9 @@ QIcon CreateOfficialIcon(Main::Account *account) {
|
|||
|
||||
QIcon CreateIcon(Main::Account *account) {
|
||||
auto result = CreateOfficialIcon(account);
|
||||
if (Platform::IsLinux()) {
|
||||
return QIcon::fromTheme("kotatogram", result);
|
||||
}
|
||||
#ifdef Q_OS_LINUX
|
||||
return QIcon::fromTheme(Platform::GetIconName(), result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
AppVersion 1009019
|
||||
AppVersion 1009020
|
||||
AppVersionStrMajor 1.9
|
||||
AppVersionStrSmall 1.9.19
|
||||
AppVersionStr 1.9.19
|
||||
AppVersionStrSmall 1.9.20
|
||||
AppVersionStr 1.9.20
|
||||
BetaChannel 1
|
||||
AlphaVersion 0
|
||||
AppVersionOriginal 1.9.19.beta
|
||||
AppVersionOriginal 1.9.20.beta
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
option(TDESKTOP_FORCE_GTK_FILE_DIALOG "Force using 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_DESKTOP_FILE_GENERATION "Disable automatic '.desktop' file generation (Linux only)." ${DESKTOP_APP_USE_PACKAGED})
|
||||
option(TDESKTOP_DISABLE_GTK_INTEGRATION "Disable all code for GTK integration (Linux only)." ON)
|
||||
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)
|
||||
set(TDESKTOP_API_ID "0" CACHE STRING "Provide 'api_id' for the Telegram API access.")
|
||||
|
|
@ -43,12 +41,12 @@ if (TDESKTOP_API_ID STREQUAL "0" OR TDESKTOP_API_HASH STREQUAL "")
|
|||
" ")
|
||||
endif()
|
||||
|
||||
if (NOT DESKTOP_APP_SPECIAL_TARGET STREQUAL "")
|
||||
if (NOT DESKTOP_APP_USE_PACKAGED)
|
||||
set(TDESKTOP_FORCE_GTK_FILE_DIALOG ON)
|
||||
endif()
|
||||
|
||||
if (TDESKTOP_FORCE_GTK_FILE_DIALOG)
|
||||
set(TDESKTOP_DISABLE_GTK_INTEGRATION OFF)
|
||||
if (NOT TDESKTOP_FORCE_GTK_FILE_DIALOG)
|
||||
set(TDESKTOP_DISABLE_GTK_INTEGRATION ON)
|
||||
endif()
|
||||
|
||||
if (DESKTOP_APP_DISABLE_SPELLCHECK)
|
||||
|
|
@ -77,10 +75,6 @@ if (TDESKTOP_DISABLE_NETWORK_PROXY)
|
|||
target_compile_definitions(Telegram PRIVATE TDESKTOP_DISABLE_NETWORK_PROXY)
|
||||
endif()
|
||||
|
||||
if (TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION)
|
||||
target_compile_definitions(Telegram PRIVATE TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION)
|
||||
endif()
|
||||
|
||||
if (TDESKTOP_DISABLE_GTK_INTEGRATION)
|
||||
target_compile_definitions(Telegram PRIVATE TDESKTOP_DISABLE_GTK_INTEGRATION)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 17b6a6d53252b3e3ff02b113e352c152bd697896
|
||||
Subproject commit 0f6c9f4acbdc2412a1a941b4ee96b150589b8369
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit dbb92ddbef82988d426ef7a0ffa40a698cdc3fd3
|
||||
Subproject commit 25f44d99915101e7a832cb38bd9b2cee47508c94
|
||||
|
|
@ -1,3 +1,9 @@
|
|||
1.9.20 beta (14.03.20)
|
||||
|
||||
- Fix crash in shared links search.
|
||||
- Fix blurred thumbnails in albums with video files.
|
||||
- Fix a possible crash in animated stickers rendering.
|
||||
|
||||
1.9.19 beta (25.02.20)
|
||||
|
||||
- Bug fixes and other minor improvements.
|
||||
|
|
|
|||
2
cmake
2
cmake
|
|
@ -1 +1 @@
|
|||
Subproject commit 81e27ccc0e7bf27405569ce98582860dfc9ea9bb
|
||||
Subproject commit 9280064cc8a5e8f8acc4cdda3a6a905379d3df0d
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
## Build instructions for GYP/CMake under Ubuntu 14.04
|
||||
## Build instructions for CMake under Ubuntu 14.04
|
||||
|
||||
### Prepare folder
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ You will need GCC 8 installed. To install them and all the required dependencies
|
|||
libgtk2.0-dev libice-dev libsm-dev libicu-dev libdrm-dev dh-autoreconf \
|
||||
autoconf automake build-essential libxml2-dev libass-dev libfreetype6-dev \
|
||||
libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev \
|
||||
libvorbis-dev libenchant-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
|
||||
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
|
||||
libxcb-xfixes0-dev libxcb-keysyms1-dev libxcb-icccm4-dev libatspi2.0-dev \
|
||||
libxcb-render-util0-dev libxcb-util0-dev libxcb-xkb-dev libxrender-dev \
|
||||
libasound-dev libpulse-dev libxcb-sync0-dev libxcb-randr0-dev libegl1-mesa-dev \
|
||||
|
|
@ -198,7 +198,7 @@ Go to ***BuildPath*** and run
|
|||
|
||||
git clone git://repo.or.cz/openal-soft.git
|
||||
cd openal-soft
|
||||
git checkout openal-soft-1.19.1
|
||||
git checkout openal-soft-1.20.1
|
||||
cd build
|
||||
if [ `uname -p` == "i686" ]; then
|
||||
cmake -D LIBTYPE:STRING=STATIC -D ALSOFT_UTILS:BOOL=OFF ..
|
||||
|
|
@ -214,7 +214,7 @@ Go to ***BuildPath*** and run
|
|||
git checkout OpenSSL_1_1_1-stable
|
||||
./config --prefix=/usr/local/desktop-app/openssl-1.1.1
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
sudo make install_sw
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/xkbcommon/libxkbcommon.git
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ You will require **api_id** and **api_hash** to access the Telegram API servers.
|
|||
|
||||
## Install third party software
|
||||
|
||||
Strawberry
|
||||
* Download **Strawberry Perl** installer from [http://strawberryperl.com/](http://strawberryperl.com/) and install to ***BuildPath*\\ThirdParty\\Strawberry**
|
||||
* Download **NASM** installer from [http://www.nasm.us](http://www.nasm.us) and install to ***BuildPath*\\ThirdParty\\NASM**
|
||||
* Download **Yasm** executable from [http://yasm.tortall.net/Download.html](http://yasm.tortall.net/Download.html), rename to *yasm.exe* and put to ***BuildPath*\\ThirdParty\\yasm**
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ By git – in Terminal go to **/home/user/TBuild** and run
|
|||
|
||||
Install dev libraries
|
||||
|
||||
sudo apt-get install libexif-dev liblzma-dev libz-dev libssl-dev libappindicator-dev libunity-dev libenchant-dev
|
||||
sudo apt-get install libexif-dev liblzma-dev libz-dev libssl-dev libappindicator-dev libunity-dev
|
||||
|
||||
#### zlib 1.2.8
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
## Build instructions for Xcode 10.1
|
||||
## Build instructions for Xcode 11
|
||||
|
||||
### Prepare folder
|
||||
|
||||
|
|
@ -8,18 +8,14 @@ Choose a folder for the future build, for example **/Users/user/TBuild**. It wil
|
|||
|
||||
You will require **api_id** and **api_hash** to access the Telegram API servers. To learn how to obtain them [click here][api_credentials].
|
||||
|
||||
### Download libraries
|
||||
|
||||
Download [**xz-5.0.5**](http://tukaani.org/xz/xz-5.0.5.tar.gz) and unpack to ***BuildPath*/Libraries/macos/xz-5.0.5**
|
||||
|
||||
Download [**libiconv-1.15**](http://www.gnu.org/software/libiconv/#downloading) and unpack to ***BuildPath*/Libraries/macos/libiconv-1.15**
|
||||
|
||||
### Clone source code and prepare libraries
|
||||
|
||||
Go to ***BuildPath*** and run
|
||||
|
||||
MAKE_THREADS_CNT=-j8
|
||||
MACOSX_DEPLOYMENT_TARGET=10.12
|
||||
UNGUARDED="-Werror=unguarded-availability-new"
|
||||
MIN_VER="-mmacosx-version-min=10.12"
|
||||
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
brew install automake cmake fdk-aac git lame libass libtool libvorbis libvpx ninja opus sdl shtool texi2html theora wget x264 xvid yasm pkg-config gnu-tar
|
||||
|
|
@ -45,24 +41,29 @@ Go to ***BuildPath*** and run
|
|||
sudo ./setup.py install
|
||||
cd ../..
|
||||
|
||||
mkdir -p Libraries/macos
|
||||
cd Libraries/macos
|
||||
LibrariesPath=`pwd`
|
||||
|
||||
git clone https://github.com/desktop-app/patches.git
|
||||
cd patches
|
||||
git checkout 4f1cffb
|
||||
cd ../
|
||||
cd ..
|
||||
git clone --branch 0.10.0 https://github.com/ericniebler/range-v3
|
||||
|
||||
cd xz-5.0.5
|
||||
CFLAGS="-mmacosx-version-min=10.12" LDFLAGS="-mmacosx-version-min=10.12" ./configure --prefix=/usr/local/macos
|
||||
xz_ver=5.2.4
|
||||
wget https://tukaani.org/xz/xz-$xz_ver.tar.gz
|
||||
tar -xvzf xz-$xz_ver.tar.gz
|
||||
rm xz-$xz_ver.tar.gz
|
||||
cd xz-$xz_ver
|
||||
CFLAGS="$MIN_VER" LDFLAGS="$MIN_VER" ./configure --prefix=/usr/local/macos
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/desktop-app/zlib.git
|
||||
cd zlib
|
||||
CFLAGS="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" LDFLAGS="-mmacosx-version-min=10.12" ./configure --prefix=/usr/local/macos
|
||||
CFLAGS="$MIN_VER $UNGUARDED" LDFLAGS="$MIN_VER" ./configure --prefix=/usr/local/macos
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
cd ..
|
||||
|
|
@ -70,7 +71,7 @@ Go to ***BuildPath*** and run
|
|||
git clone https://github.com/openssl/openssl openssl_1_1_1
|
||||
cd openssl_1_1_1
|
||||
git checkout OpenSSL_1_1_1-stable
|
||||
./Configure --prefix=/usr/local/macos darwin64-x86_64-cc -static -mmacosx-version-min=10.12
|
||||
./Configure --prefix=/usr/local/macos darwin64-x86_64-cc -static $MIN_VER
|
||||
make build_libs $MAKE_THREADS_CNT
|
||||
cd ..
|
||||
|
||||
|
|
@ -78,13 +79,17 @@ Go to ***BuildPath*** and run
|
|||
cd opus
|
||||
git checkout v1.3
|
||||
./autogen.sh
|
||||
CFLAGS="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" CPPFLAGS="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" LDFLAGS="-mmacosx-version-min=10.12" ./configure --prefix=/usr/local/macos
|
||||
CFLAGS="$MIN_VER $UNGUARDED" CPPFLAGS="$MIN_VER $UNGUARDED" LDFLAGS="$MIN_VER" ./configure --prefix=/usr/local/macos
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
cd libiconv-1.15
|
||||
CFLAGS="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" CPPFLAGS="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" LDFLAGS="-mmacosx-version-min=10.12" ./configure --enable-static --prefix=/usr/local/macos
|
||||
libiconv_ver=1.16
|
||||
wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$libiconv_ver.tar.gz
|
||||
tar -xvzf libiconv-$libiconv_ver.tar.gz
|
||||
rm libiconv-$libiconv_ver.tar.gz
|
||||
cd libiconv-$libiconv_ver
|
||||
CFLAGS="$MIN_VER $UNGUARDED" CPPFLAGS="$MIN_VER $UNGUARDED" LDFLAGS="$MIN_VER" ./configure --enable-static --prefix=/usr/local/macos
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
cd ..
|
||||
|
|
@ -97,9 +102,9 @@ Go to ***BuildPath*** and run
|
|||
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/X11/lib/pkgconfig
|
||||
|
||||
./configure --prefix=/usr/local/macos \
|
||||
--extra-cflags="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" \
|
||||
--extra-cxxflags="-mmacosx-version-min=10.12 -Werror=unguarded-availability-new" \
|
||||
--extra-ldflags="-mmacosx-version-min=10.12" \
|
||||
--extra-cflags="$MIN_VER $UNGUARDED" \
|
||||
--extra-cxxflags="$MIN_VER $UNGUARDED" \
|
||||
--extra-ldflags="$MIN_VER" \
|
||||
--enable-protocol=file --enable-libopus \
|
||||
--disable-programs \
|
||||
--disable-doc \
|
||||
|
|
@ -205,7 +210,7 @@ Go to ***BuildPath*** and run
|
|||
cd openal-soft
|
||||
git checkout v1.19
|
||||
cd build
|
||||
CFLAGS='-Werror=unguarded-availability-new' CPPFLAGS='-Werror=unguarded-availability-new' cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/local/macos -D ALSOFT_EXAMPLES=OFF -D LIBTYPE:STRING=STATIC -D CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.12 ..
|
||||
CFLAGS=$UNGUARDED CPPFLAGS=$UNGUARDED cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/local/macos -D ALSOFT_EXAMPLES=OFF -D LIBTYPE:STRING=STATIC -D CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.12 ..
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
cd ../..
|
||||
|
|
@ -241,7 +246,19 @@ Go to ***BuildPath*** and run
|
|||
git apply ../../patches/qtbase_5_12_5.diff
|
||||
cd ..
|
||||
|
||||
./configure -prefix "/usr/local/desktop-app/Qt-5.12.5" -debug-and-release -force-debug-info -opensource -confirm-license -static -opengl desktop -no-openssl -securetransport -nomake examples -nomake tests -platform macx-clang
|
||||
./configure -prefix "/usr/local/desktop-app/Qt-5.12.5" \
|
||||
-debug-and-release \
|
||||
-force-debug-info \
|
||||
-opensource \
|
||||
-confirm-license \
|
||||
-static \
|
||||
-opengl desktop \
|
||||
-no-openssl \
|
||||
-securetransport \
|
||||
-nomake examples \
|
||||
-nomake tests \
|
||||
-platform macx-clang
|
||||
|
||||
make $MAKE_THREADS_CNT
|
||||
sudo make install
|
||||
cd ..
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<url type="help">https://github.com/kotatogram/kotatogram-desktop/issues</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://raw.githubusercontent.com/telegramdesktop/tdesktop/dev/docs/assets/preview.png</image>
|
||||
<image>https://github.com/kotatogram/kotatogram-desktop/blob/dev/docs/assets/ktg_preview.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<keywords>
|
||||
|
|
@ -98,6 +98,7 @@
|
|||
<content_attribute id="money-purchasing">none</content_attribute>
|
||||
<content_attribute id="money-gambling">none</content_attribute>
|
||||
</content_rating>
|
||||
<launchable type="desktop-id">@TDESKTOP_LAUNCHER_BASENAME@.desktop</launchable>
|
||||
<provides>
|
||||
<binary>kotatogram-desktop</binary>
|
||||
</provides>
|
||||
|
|
@ -6,6 +6,13 @@ base: core18
|
|||
grade: stable
|
||||
confinement: strict
|
||||
|
||||
architectures:
|
||||
- build-on: amd64
|
||||
- build-on: i386
|
||||
- build-on: arm64
|
||||
- build-on: armhf
|
||||
- build-on: ppc64el
|
||||
|
||||
apps:
|
||||
kotatogram-desktop:
|
||||
command: bin/desktop-launch kotatogram-desktop
|
||||
|
|
@ -14,9 +21,12 @@ apps:
|
|||
environment:
|
||||
# Use GTK3 cursor theme, icon theme and open/save file dialogs.
|
||||
QT_QPA_PLATFORMTHEME: gtk3
|
||||
# Wayland support is still too bad.
|
||||
# The blocker is https://github.com/ubuntu/snapcraft-desktop-helpers/issues/172
|
||||
DISABLE_WAYLAND: 1
|
||||
plugs:
|
||||
- alsa
|
||||
- audio-playback
|
||||
- audio-record
|
||||
- desktop
|
||||
- desktop-legacy
|
||||
- home
|
||||
|
|
@ -44,6 +54,10 @@ plugs:
|
|||
target: $SNAP/data-dir/sounds
|
||||
default-provider: gtk-common-themes
|
||||
|
||||
layout:
|
||||
/usr/share/alsa:
|
||||
bind: $SNAP/usr/share/alsa
|
||||
|
||||
parts:
|
||||
kotatogram:
|
||||
plugin: cmake
|
||||
|
|
@ -56,17 +70,11 @@ parts:
|
|||
- qtbase5-private-dev
|
||||
- libmapbox-variant-dev
|
||||
- libasound2-dev
|
||||
- libavcodec-dev
|
||||
- libavformat-dev
|
||||
- libavutil-dev
|
||||
- libswscale-dev
|
||||
- libswresample-dev
|
||||
- libdbusmenu-qt5-dev
|
||||
- libhunspell-dev
|
||||
- liblz4-dev
|
||||
- liblzma-dev
|
||||
- libminizip-dev
|
||||
- libopenal-dev
|
||||
- libopus-dev
|
||||
- libpulse-dev
|
||||
- libssl-dev
|
||||
|
|
@ -74,17 +82,11 @@ parts:
|
|||
stage-packages:
|
||||
- qt5-image-formats-plugins
|
||||
- libasound2
|
||||
- libavcodec57
|
||||
- libavformat57
|
||||
- libavutil55
|
||||
- libswscale4
|
||||
- libswresample2
|
||||
- libdbusmenu-qt5-2
|
||||
- libhunspell-1.6-0
|
||||
- liblz4-1
|
||||
- liblzma5
|
||||
- libminizip1
|
||||
- libopenal1
|
||||
- libopus0
|
||||
- libpulse0
|
||||
- libssl1.1
|
||||
|
|
@ -119,9 +121,16 @@ parts:
|
|||
after:
|
||||
- cmake
|
||||
- desktop-qt5
|
||||
- ffmpeg
|
||||
- openal
|
||||
- range-v3
|
||||
- xxhash
|
||||
|
||||
patches:
|
||||
plugin: dump
|
||||
source: Telegram/Patches
|
||||
prime: [-./*]
|
||||
|
||||
desktop-qt5:
|
||||
source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
|
||||
source-subdir: qt
|
||||
|
|
@ -176,6 +185,138 @@ parts:
|
|||
- libtinfo5
|
||||
prime: [-./*]
|
||||
|
||||
ffmpeg:
|
||||
source: https://github.com/FFmpeg/FFmpeg.git
|
||||
source-depth: 1
|
||||
source-branch: release/4.2
|
||||
plugin: autotools
|
||||
build-packages:
|
||||
- libtool
|
||||
- pkg-config
|
||||
- texi2html
|
||||
- yasm
|
||||
- libass-dev
|
||||
- libfreetype6-dev
|
||||
- libgpac-dev
|
||||
- liblzma-dev
|
||||
- libopus-dev
|
||||
- libsdl1.2-dev
|
||||
- libtheora-dev
|
||||
- libva-dev
|
||||
- libvdpau-dev
|
||||
- libvorbis-dev
|
||||
- libxcb1-dev
|
||||
- libxcb-shm0-dev
|
||||
- libxcb-xfixes0-dev
|
||||
- zlib1g-dev
|
||||
stage-packages:
|
||||
- freeglut3
|
||||
- libass9
|
||||
- libfreetype6
|
||||
- libgpac4
|
||||
- liblzma5
|
||||
- libopus0
|
||||
- libslang2
|
||||
- libsdl1.2debian
|
||||
- libtheora0
|
||||
- libva2
|
||||
- libva-drm2
|
||||
- libvdpau1
|
||||
- libvorbis0a
|
||||
- libxcb1
|
||||
- libxcb-shm0
|
||||
- libxcb-xfixes0
|
||||
- zlib1g
|
||||
configflags:
|
||||
- --prefix=/usr
|
||||
- --disable-debug
|
||||
- --disable-programs
|
||||
- --disable-doc
|
||||
- --disable-everything
|
||||
- --disable-neon
|
||||
- --enable-gpl
|
||||
- --enable-version3
|
||||
- --enable-libopus
|
||||
- --enable-decoder=aac
|
||||
- --enable-decoder=aac_latm
|
||||
- --enable-decoder=aasc
|
||||
- --enable-decoder=flac
|
||||
- --enable-decoder=gif
|
||||
- --enable-decoder=h264
|
||||
- --enable-decoder=h264_vdpau
|
||||
- --enable-decoder=mp1
|
||||
- --enable-decoder=mp1float
|
||||
- --enable-decoder=mp2
|
||||
- --enable-decoder=mp2float
|
||||
- --enable-decoder=mp3
|
||||
- --enable-decoder=mp3adu
|
||||
- --enable-decoder=mp3adufloat
|
||||
- --enable-decoder=mp3float
|
||||
- --enable-decoder=mp3on4
|
||||
- --enable-decoder=mp3on4float
|
||||
- --enable-decoder=mpeg4
|
||||
- --enable-decoder=mpeg4_vdpau
|
||||
- --enable-decoder=msmpeg4v2
|
||||
- --enable-decoder=msmpeg4v3
|
||||
- --enable-decoder=opus
|
||||
- --enable-decoder=vorbis
|
||||
- --enable-decoder=wavpack
|
||||
- --enable-decoder=wmalossless
|
||||
- --enable-decoder=wmapro
|
||||
- --enable-decoder=wmav1
|
||||
- --enable-decoder=wmav2
|
||||
- --enable-decoder=wmavoice
|
||||
- --enable-encoder=libopus
|
||||
- --enable-hwaccel=h264_vaapi
|
||||
- --enable-hwaccel=h264_vdpau
|
||||
- --enable-hwaccel=mpeg4_vaapi
|
||||
- --enable-hwaccel=mpeg4_vdpau
|
||||
- --enable-parser=aac
|
||||
- --enable-parser=aac_latm
|
||||
- --enable-parser=flac
|
||||
- --enable-parser=h264
|
||||
- --enable-parser=mpeg4video
|
||||
- --enable-parser=mpegaudio
|
||||
- --enable-parser=opus
|
||||
- --enable-parser=vorbis
|
||||
- --enable-demuxer=aac
|
||||
- --enable-demuxer=flac
|
||||
- --enable-demuxer=gif
|
||||
- --enable-demuxer=h264
|
||||
- --enable-demuxer=mov
|
||||
- --enable-demuxer=mp3
|
||||
- --enable-demuxer=ogg
|
||||
- --enable-demuxer=wav
|
||||
- --enable-muxer=ogg
|
||||
- --enable-muxer=opus
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
patch -p1 < "$SNAPCRAFT_STAGE/ffmpeg.diff"
|
||||
after:
|
||||
- patches
|
||||
|
||||
openal:
|
||||
source: https://github.com/kcat/openal-soft.git
|
||||
source-depth: 1
|
||||
source-tag: openal-soft-1.20.1
|
||||
plugin: cmake
|
||||
build-packages:
|
||||
- libasound2-dev
|
||||
- libpulse-dev
|
||||
- libsndio-dev
|
||||
- portaudio19-dev
|
||||
stage-packages:
|
||||
- libasound2
|
||||
- libpulse0
|
||||
- libportaudio2
|
||||
- libsndio6.1
|
||||
configflags:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DALSOFT_EXAMPLES=OFF
|
||||
- -DALSOFT_TESTS=OFF
|
||||
- -DALSOFT_UTILS=OFF
|
||||
- -DALSOFT_CONFIG=OFF
|
||||
|
||||
range-v3:
|
||||
source: https://github.com/ericniebler/range-v3.git
|
||||
source-depth: 1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue