From b70276912ee193b7b6ffe23ef1da4403a75563ce Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 20 Jun 2021 10:36:23 +0400 Subject: [PATCH] Use native child window in group calls on Windows. --- Telegram/SourceFiles/calls/calls.style | 8 +-- .../calls/group/calls_group_panel.cpp | 68 ++++++++++++++++--- .../calls/group/calls_group_panel.h | 5 +- Telegram/lib_ui | 2 +- 4 files changed, 68 insertions(+), 15 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 138cc0e61..f900421e1 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1082,11 +1082,11 @@ groupCallMenuVolumePadding: margins(17px, 6px, 17px, 5px); groupCallMenuVolumeMargin: margins(55px, 0px, 15px, 0px); groupCallMenuVolumeSlider: MediaSlider(defaultContinuousSlider) { activeFg: groupCallMembersFg; - inactiveFg: groupCallMemberInactiveIcon; + inactiveFg: groupCallMembersBgOver; activeFgOver: groupCallMembersFg; - inactiveFgOver: groupCallMemberInactiveIcon; - activeFgDisabled: groupCallMemberInactiveIcon; - receivedTillFg: groupCallMemberInactiveIcon; + inactiveFgOver: groupCallMembersBgOver; + activeFgDisabled: groupCallMembersBgOver; + receivedTillFg: groupCallMembersBgOver; width: 7px; seekSize: size(7px, 7px); } diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 23ca8847f..76e6fa5c3 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -76,6 +76,7 @@ constexpr auto kMicrophoneTooltipAfterLoudCount = 3; constexpr auto kDropLoudAfterQuietCount = 5; constexpr auto kMicrophoneTooltipLevelThreshold = 0.2; constexpr auto kMicrophoneTooltipCheckInterval = crl::time(500); +constexpr auto kUseNativeChild = Platform::IsWindows(); } // namespace @@ -135,11 +136,13 @@ void Panel::MicLevelTester::check() { Panel::Panel(not_null call) : _call(call) , _peer(call->peer()) -, _window(createWindow()) -, _layerBg(std::make_unique(_window->body())) +, _window(std::make_unique()) +, _nativeBodyWindow(createBodyWidget()) +, _body(_nativeBodyWindow ? _nativeBodyWindow.get() : _window->body().get()) +, _layerBg(std::make_unique(widget())) #ifndef Q_OS_MAC , _controls(std::make_unique( - _window->body(), + widget(), st::groupCallTitle)) #endif // !Q_OS_MAC , _viewport(std::make_unique(widget(), PanelMode::Wide, _backend)) @@ -190,21 +193,68 @@ Panel::~Panel() { std::unique_ptr Panel::createWindow() { auto result = std::make_unique(); + if constexpr (!kUseNativeChild) { + const auto capabilities = Ui::GL::CheckCapabilities(result.get()); + const auto use = Platform::IsMac() + ? true + : Platform::IsWindows() + ? capabilities.supported + : capabilities.transparency; + LOG(("OpenGL: %1 (Calls::Group::Panel)").arg(Logs::b(use))); + _backend = use ? Ui::GL::Backend::OpenGL : Ui::GL::Backend::Raster; + + if (!use) { + // We have to create a new window, if OpenGL initialization failed. + result = std::make_unique(); + } + } + return result; +} + +std::unique_ptr Panel::createBodyWidget() { + if constexpr (!kUseNativeChild) { + return nullptr; + } + const auto create = [] { + auto result = std::make_unique(); + result->setWindowFlags(Qt::FramelessWindowHint | Qt::Window); + result->setAttribute(Qt::WA_NativeWindow); + result->setAttribute(Qt::WA_DontCreateNativeAncestors); + result->setAttribute(Qt::WA_OpaquePaintEvent); + result->setAttribute(Qt::WA_NoSystemBackground); + return result; + }; + + auto result = create(); const auto capabilities = Ui::GL::CheckCapabilities(result.get()); const auto use = Platform::IsMac() ? true : Platform::IsWindows() ? capabilities.supported : capabilities.transparency; - LOG(("OpenGL: %1 (Calls::Group::Viewport)").arg(Logs::b(use))); + LOG(("OpenGL: %1 (Calls::Group::Panel)").arg(Logs::b(use))); _backend = use ? Ui::GL::Backend::OpenGL : Ui::GL::Backend::Raster; - if (use) { - return result; + if (!use) { + // We have to create a new window, if OpenGL initialization failed. + result = create(); } - // We have to create a new window, if OpenGL initialization failed. - return std::make_unique(); + const auto raw = result.get(); + raw->setParent(_window->body()); + raw->show(); + raw->update(); + _window->sizeValue( + ) | rpl::start_with_next([=](QSize size) { + raw->setGeometry(QRect(QPoint(), size)); + }, raw->lifetime()); + + _window->body()->paintRequest( + ) | rpl::start_with_next([=](QRect clip) { + QPainter(_window->body()).fillRect(clip, QColor(255, 0, 0)); + }, _window->body()->lifetime()); + + return result; } void Panel::setupRealCallViewers() { @@ -2234,7 +2284,7 @@ bool Panel::handleClose() { } not_null Panel::widget() const { - return _window->body(); + return _body.get(); } } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.h b/Telegram/SourceFiles/calls/group/calls_group_panel.h index ddc053bfb..537598110 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.h @@ -97,7 +97,8 @@ private: }; class MicLevelTester; - std::unique_ptr createWindow(); + [[nodiscard]] std::unique_ptr createWindow(); + [[nodiscard]] std::unique_ptr createBodyWidget(); [[nodiscard]] not_null widget() const; [[nodiscard]] PanelMode mode() const; @@ -179,6 +180,8 @@ private: Ui::GL::Backend _backend = Ui::GL::Backend(); const std::unique_ptr _window; + const std::unique_ptr _nativeBodyWindow; + const not_null _body; const std::unique_ptr _layerBg; rpl::variable _mode; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 825ef11f1..bd989cb67 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 825ef11f1a5c6b00cd571c24525c84dca431eaa2 +Subproject commit bd989cb67f5076b07556e8422cf6f8be6ba8d8ae