diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 944c00b6e5..46b833b73b 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2021,6 +2021,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_group_call_screen_share_start" = "Share Screen"; "lng_group_call_screen_share_stop" = "Stop Sharing"; "lng_group_call_screen_title" = "Screen {index}"; +"lng_group_call_screen_share_audio" = "Share Audio"; "lng_group_call_unmute_small" = "Unmute"; "lng_group_call_more" = "More"; "lng_group_call_unmute" = "Unmute"; diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 19a4fca8e0..eaa14ba757 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1184,6 +1184,16 @@ desktopCaptureSubmit: RoundButton(desktopCaptureCancel) { color: shadowFg; } } +desktopCaptureWithAudio: Checkbox(defaultCheckbox) { + textFg: groupCallMembersFg; + textFgActive: groupCallMembersFg; + rippleBg: groupCallMembersBgRipple; + rippleBgActive: groupCallMembersBgRipple; + style: semiboldTextStyle; +} +desktopCaptureWithAudioCheck: Check(defaultCheck) { + untoggledFg: groupCallActiveFg; +} groupCallNarrowSkip: 9px; groupCallNarrowMembersWidth: 204px; diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index 80cc29975f..e13b853d07 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -613,6 +613,10 @@ QString GroupCall::screenSharingDeviceId() const { return isSharingScreen() ? _screenDeviceId : QString(); } +bool GroupCall::screenSharingWithAudio() const { + return isSharingScreen() && _screenWithAudio; +} + bool GroupCall::mutedByAdmin() const { const auto mute = muted(); return mute == MuteState::ForceMuted || mute == MuteState::RaisedHand; @@ -635,7 +639,9 @@ void GroupCall::toggleVideo(bool active) { : Webrtc::VideoState::Inactive; } -void GroupCall::toggleScreenSharing(std::optional uniqueId) { +void GroupCall::toggleScreenSharing( + std::optional uniqueId, + bool withAudio) { if (!_instance || !_id) { return; } else if (!uniqueId) { @@ -645,10 +651,14 @@ void GroupCall::toggleScreenSharing(std::optional uniqueId) { const auto changed = (_screenDeviceId != *uniqueId); const auto wasSharing = isSharingScreen(); _screenDeviceId = *uniqueId; + _screenWithAudio = withAudio; _screenState = Webrtc::VideoState::Active; if (changed && wasSharing && isSharingScreen()) { _screenCapture->switchToDevice(uniqueId->toStdString()); } + if (_screenInstance) { + _screenInstance->setIsMuted(!withAudio); + } } bool GroupCall::hasVideoWithFrames() const { @@ -2281,9 +2291,7 @@ bool GroupCall::tryCreateScreencast() { _screenInstance = std::make_unique( std::move(descriptor)); -#ifdef Q_OS_WIN - _screenInstance->setIsMuted(false); -#endif // Q_OS_WIN + _screenInstance->setIsMuted(!_screenWithAudio); return true; } diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.h b/Telegram/SourceFiles/calls/group/calls_group_call.h index 64c49901af..4d23110c53 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.h +++ b/Telegram/SourceFiles/calls/group/calls_group_call.h @@ -380,8 +380,11 @@ public: [[nodiscard]] bool isCameraPaused() const; [[nodiscard]] const std::string &cameraSharingEndpoint() const; [[nodiscard]] QString screenSharingDeviceId() const; + [[nodiscard]] bool screenSharingWithAudio() const; void toggleVideo(bool active); - void toggleScreenSharing(std::optional uniqueId); + void toggleScreenSharing( + std::optional uniqueId, + bool withAudio = false); [[nodiscard]] bool hasVideoWithFrames() const; [[nodiscard]] rpl::producer hasVideoWithFramesValue() const; @@ -614,6 +617,7 @@ private: rpl::variable _screenState; rpl::variable _isSharingScreen = false; QString _screenDeviceId; + bool _screenWithAudio = false; base::flags _pendingSelfUpdates; bool _requireARGB32 = true; diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 022b0f2999..eef148ca2c 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -260,12 +260,26 @@ QString Panel::chooseSourceActiveDeviceId() { return _call->screenSharingDeviceId(); } +bool Panel::chooseSourceActiveWithAudio() { + return _call->screenSharingWithAudio(); +} + +bool Panel::chooseSourceWithAudioSupported() { +#ifdef Q_OS_WIN + return true; +#else // Q_OS_WIN + return false; +#endif // Q_OS_WIN +} + rpl::lifetime &Panel::chooseSourceInstanceLifetime() { return lifetime(); } -void Panel::chooseSourceAccepted(const QString &deviceId) { - _call->toggleScreenSharing(deviceId); +void Panel::chooseSourceAccepted( + const QString &deviceId, + bool withAudio) { + _call->toggleScreenSharing(deviceId, withAudio); } void Panel::chooseSourceStop() { @@ -1185,7 +1199,7 @@ void Panel::chooseShareScreenSource() { if (_call->isSharingScreen()) { _call->toggleScreenSharing(std::nullopt); } else { - chooseSourceAccepted(*source); + chooseSourceAccepted(*source, false); } } else { Ui::DesktopCapture::ChooseSource(this); diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.h b/Telegram/SourceFiles/calls/group/calls_group_panel.h index e1cd8dad3e..4cfc3bbcb0 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.h @@ -169,8 +169,12 @@ private: QWidget *chooseSourceParent() override; QString chooseSourceActiveDeviceId() override; + bool chooseSourceActiveWithAudio() override; + bool chooseSourceWithAudioSupported() override; rpl::lifetime &chooseSourceInstanceLifetime() override; - void chooseSourceAccepted(const QString &deviceId) override; + void chooseSourceAccepted( + const QString &deviceId, + bool withAudio) override; void chooseSourceStop() override; const not_null _call; diff --git a/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.cpp b/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.cpp index 2203195b03..76f301e787 100644 --- a/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.cpp +++ b/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/scroll_area.h" #include "ui/widgets/labels.h" #include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" #include "ui/effects/ripple_animation.h" #include "ui/image/image.h" #include "ui/platform/ui_platform_window_title.h" @@ -62,6 +63,8 @@ public: [[nodiscard]] rpl::producer<> activations() const; void setActive(bool active); + [[nodiscard]] bool isWindow() const; + [[nodiscard]] QString deviceIdKey() const; [[nodiscard]] rpl::lifetime &lifetime(); private: @@ -94,6 +97,7 @@ private: void setupGeometryWithParent(not_null parent); void fillSources(); void setupSourcesGeometry(); + void updateButtonsVisibility(); void destroy(); static base::flat_map< @@ -107,6 +111,7 @@ private: const not_null _bottom; const not_null _submit; const not_null _finish; + const not_null _withAudio; std::vector> _sources; Source *_selected = nullptr; @@ -166,6 +171,14 @@ rpl::producer<> Source::activations() const { return _activations.events(); } +bool Source::isWindow() const { + return _source.isWindow(); +} + +QString Source::deviceIdKey() const { + return QString::fromStdString(_source.deviceIdKey()); +} + void Source::setActive(bool active) { if (_active != active) { _active = active; @@ -255,7 +268,13 @@ ChooseSourceProcess::ChooseSourceProcess( CreateChild( _bottom.get(), tr::lng_group_call_screen_share_stop(), - st::desktopCaptureFinish)) { + st::desktopCaptureFinish)) +, _withAudio( + CreateChild( + _bottom.get(), + tr::lng_group_call_screen_share_audio(tr::now), + false, + st::desktopCaptureWithAudio)) { setupPanel(); setupSources(); activate(); @@ -336,7 +355,9 @@ void ChooseSourceProcess::setupPanel() { return; } const auto weak = MakeWeak(_window.get()); - _delegate->chooseSourceAccepted(_selectedId); + _delegate->chooseSourceAccepted( + _selectedId, + !_withAudio->isHidden() && _withAudio->checked()); if (const auto strong = weak.data()) { strong->close(); } @@ -375,6 +396,18 @@ void ChooseSourceProcess::setupPanel() { bottomSkip); }, _bottom->lifetime()); + _withAudio->widthValue( + ) | rpl::start_with_next([=](int width) { + const auto top = (bottomHeight - _withAudio->heightNoMargins()) / 2; + _withAudio->moveToLeft(bottomSkip, top); + }, _withAudio->lifetime()); + + _withAudio->setChecked(_delegate->chooseSourceActiveWithAudio()); + _withAudio->checkedChanges( + ) | rpl::start_with_next([=] { + updateButtonsVisibility(); + }, _withAudio->lifetime()); + const auto sharing = !_delegate->chooseSourceActiveDeviceId().isEmpty(); _finish->setVisible(sharing); _submit->setVisible(!sharing); @@ -420,6 +453,8 @@ void ChooseSourceProcess::fillSources() { auto screensManager = tgcalls::DesktopCaptureSourceManager(Type::Screen); auto windowsManager = tgcalls::DesktopCaptureSourceManager(Type::Window); + _withAudio->setVisible(false); + auto screenIndex = 0; auto windowIndex = 0; const auto active = _delegate->chooseSourceActiveDeviceId(); @@ -435,9 +470,13 @@ void ChooseSourceProcess::fillSources() { const auto id = source.deviceIdKey(); _sources.push_back(std::make_unique(_inner, source, title)); + const auto withAudioSupported = !source.isWindow() + && _delegate->chooseSourceWithAudioSupported(); + const auto raw = _sources.back().get(); if (!active.isEmpty() && active.toStdString() == id) { _selected = raw; + _withAudio->setVisible(withAudioSupported); raw->setActive(true); } _sources.back()->activations( @@ -448,15 +487,8 @@ void ChooseSourceProcess::fillSources() { _selected->setActive(false); } _selected = raw; - _selectedId = QString::fromStdString(id); - if (_selectedId == _delegate->chooseSourceActiveDeviceId()) { - _selectedId = QString(); - _finish->setVisible(true); - _submit->setVisible(false); - } else { - _finish->setVisible(false); - _submit->setVisible(true); - } + _withAudio->setVisible(withAudioSupported); + updateButtonsVisibility(); }, raw->lifetime()); }; for (const auto &source : screensManager.sources()) { @@ -467,6 +499,27 @@ void ChooseSourceProcess::fillSources() { } } +void ChooseSourceProcess::updateButtonsVisibility() { + const auto withAudioSupported = _selected + && !_selected->isWindow() + && _delegate->chooseSourceWithAudioSupported(); + const auto selectedId = _selected + ? _selected->deviceIdKey() + : QString(); + if (selectedId == _delegate->chooseSourceActiveDeviceId() + && (!withAudioSupported + || (_withAudio->checked() + == _delegate->chooseSourceActiveWithAudio()))) { + _selectedId = QString(); + _finish->setVisible(true); + _submit->setVisible(false); + } else { + _selectedId = selectedId; + _finish->setVisible(false); + _submit->setVisible(true); + } +} + void ChooseSourceProcess::setupSourcesGeometry() { if (_sources.empty()) { destroy(); diff --git a/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.h b/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.h index 82f0fb9e5e..03da88a46e 100644 --- a/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.h +++ b/Telegram/SourceFiles/calls/group/ui/desktop_capture_choose_source.h @@ -20,8 +20,12 @@ class ChooseSourceDelegate { public: virtual QWidget *chooseSourceParent() = 0; virtual QString chooseSourceActiveDeviceId() = 0; + virtual bool chooseSourceActiveWithAudio() = 0; + virtual bool chooseSourceWithAudioSupported() = 0; virtual rpl::lifetime &chooseSourceInstanceLifetime() = 0; - virtual void chooseSourceAccepted(const QString &deviceId) = 0; + virtual void chooseSourceAccepted( + const QString &deviceId, + bool withAudio) = 0; virtual void chooseSourceStop() = 0; }; diff --git a/Telegram/ThirdParty/tgcalls b/Telegram/ThirdParty/tgcalls index 3cf1822a70..07e0484a58 160000 --- a/Telegram/ThirdParty/tgcalls +++ b/Telegram/ThirdParty/tgcalls @@ -1 +1 @@ -Subproject commit 3cf1822a70e3b84f6a762755e5249b26e915d321 +Subproject commit 07e0484a583121870316f3039aa2047ed030cd6d diff --git a/Telegram/cmake/lib_tgcalls.cmake b/Telegram/cmake/lib_tgcalls.cmake index d513b1ce3a..02456b1449 100644 --- a/Telegram/cmake/lib_tgcalls.cmake +++ b/Telegram/cmake/lib_tgcalls.cmake @@ -49,9 +49,13 @@ PRIVATE Message.h NetworkManager.cpp NetworkManager.h + SctpDataChannelProviderInterfaceImpl.cpp + SctpDataChannelProviderInterfaceImpl.h StaticThreads.cpp StaticThreads.h ThreadLocalObject.h + TurnCustomizerImpl.cpp + TurnCustomizerImpl.h VideoCaptureInterface.cpp VideoCaptureInterface.h VideoCaptureInterfaceImpl.cpp diff --git a/Telegram/lib_webrtc b/Telegram/lib_webrtc index 5d16a97b57..3bd9b94e92 160000 --- a/Telegram/lib_webrtc +++ b/Telegram/lib_webrtc @@ -1 +1 @@ -Subproject commit 5d16a97b57f0399d552e0c9dd72d27e81f6a8316 +Subproject commit 3bd9b94e928b2ce963290d773926240ec2612d6a diff --git a/docs/building-msvc-x64.md b/docs/building-msvc-x64.md index dc8808ebbd..5b19175c2d 100644 --- a/docs/building-msvc-x64.md +++ b/docs/building-msvc-x64.md @@ -110,9 +110,9 @@ Open **x64 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** cmake --build . --config Release cd .. - git clone https://github.com/kcat/openal-soft.git + git clone https://github.com/telegramdesktop/openal-soft.git cd openal-soft - git checkout openal-soft-1.21.0 + git checkout wasapi_exact_device_time cd build cmake .. ^ -G "Visual Studio 16 2019" ^ diff --git a/docs/building-msvc.md b/docs/building-msvc.md index 7c91562edf..155c6768ce 100644 --- a/docs/building-msvc.md +++ b/docs/building-msvc.md @@ -110,9 +110,9 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** cmake --build . --config Release cd .. - git clone https://github.com/kcat/openal-soft.git + git clone https://github.com/telegramdesktop/openal-soft.git cd openal-soft - git checkout openal-soft-1.21.0 + git checkout wasapi_exact_device_time cd build cmake .. ^ -G "Visual Studio 16 2019" ^