From 685db2ab5e830b88dba32b47c636dee701d49b1b Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 21 Jun 2021 10:27:11 +0400 Subject: [PATCH] Simplify native child OpenGL window creation. --- CMakeLists.txt | 2 + ui/gl/gl_window.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++ ui/gl/gl_window.h | 39 ++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 ui/gl/gl_window.cpp create mode 100644 ui/gl/gl_window.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 28b5e9f..3a22f9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,8 @@ PRIVATE ui/gl/gl_shader.h ui/gl/gl_surface.cpp ui/gl/gl_surface.h + ui/gl/gl_window.cpp + ui/gl/gl_window.h ui/image/image_prepare.cpp ui/image/image_prepare.h ui/layers/box_content.cpp diff --git a/ui/gl/gl_window.cpp b/ui/gl/gl_window.cpp new file mode 100644 index 0000000..497aba1 --- /dev/null +++ b/ui/gl/gl_window.cpp @@ -0,0 +1,106 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/gl/gl_window.h" + +#include "ui/gl/gl_detection.h" +#include "ui/widgets/window.h" +#include "base/platform/base_platform_info.h" +#include "base/debug_log.h" + +namespace Ui::GL { +namespace { + +constexpr auto kUseNativeChild = ::Platform::IsWindows(); + +} // namespace + +Window::Window() +: _window(std::make_unique()) +, _bodyNativeWrap(createNativeBodyWrap()) +, _body(_bodyNativeWrap ? _bodyNativeWrap.get() : _window->body().get()) { +} + +Window::~Window() = default; + +Backend Window::backend() const { + return _backend; +} + +not_null Window::window() const { + return _window.get(); +} + +not_null Window::widget() const { + return _body.get(); +} + +std::unique_ptr Window::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 (Ui::GL::Window)").arg(use ? "[TRUE]" : "[FALSE]")); + _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 Window::createNativeBodyWrap() { + 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 (Ui::GL::WindowBody)").arg(use ? "[TRUE]" : "[FALSE]")); + _backend = use ? Ui::GL::Backend::OpenGL : Ui::GL::Backend::Raster; + + if (!use) { + // We have to create a new window, if OpenGL initialization failed. + result = create(); + } + + const auto nativeParent = _window->body(); + nativeParent->setAttribute(Qt::WA_OpaquePaintEvent); + nativeParent->setAttribute(Qt::WA_NoSystemBackground); + + const auto raw = result.get(); + raw->setParent(nativeParent); + raw->show(); + raw->update(); + _window->sizeValue( + ) | rpl::start_with_next([=](QSize size) { + raw->setGeometry(QRect(QPoint(), size)); + }, raw->lifetime()); + + return result; +} + +} // namespace Ui::GL diff --git a/ui/gl/gl_window.h b/ui/gl/gl_window.h new file mode 100644 index 0000000..bfa4199 --- /dev/null +++ b/ui/gl/gl_window.h @@ -0,0 +1,39 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + + +namespace Ui { +class Window; +class RpWidget; +} // namespace Ui + +namespace Ui::GL { + +enum class Backend; + +class Window final { +public: + Window(); + ~Window(); + + [[nodiscard]] Backend backend() const; + [[nodiscard]] not_null window() const; + [[nodiscard]] not_null widget() const; + +private: + [[nodiscard]] std::unique_ptr createWindow(); + [[nodiscard]] std::unique_ptr createNativeBodyWrap(); + + Ui::GL::Backend _backend = Ui::GL::Backend(); + const std::unique_ptr _window; + const std::unique_ptr _bodyNativeWrap; + const not_null _body; + +}; + +} // namespace Ui::GL