From 27fd82a3650b51a4f60c5045eacd186ff3e9890b Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 21 Jul 2021 21:16:46 +0300 Subject: [PATCH 01/20] Set correct alpha size in QWindow format. This somehow fixes Direct3D 11 ANGLE backend colors issue. --- ui/gl/gl_detection.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 10a47ed..5973083 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -44,7 +44,6 @@ Capabilities CheckCapabilities(QWidget *widget) { return {}; } auto format = QSurfaceFormat(); - format.setAlphaBufferSize(8); if (widget) { if (!widget->window()->windowHandle()) { widget->window()->createWinId(); @@ -57,6 +56,11 @@ Capabilities CheckCapabilities(QWidget *widget) { LOG_ONCE(("OpenGL: Not supported for window.")); return {}; } + format = widget->window()->windowHandle()->format(); + format.setAlphaBufferSize(8); + widget->window()->windowHandle()->setFormat(format); + } else { + format.setAlphaBufferSize(8); } auto tester = QOpenGLWidget(widget); tester.setFormat(format); @@ -104,6 +108,7 @@ Capabilities CheckCapabilities(QWidget *widget) { return {}; } } + const auto supported = context->format(); switch (supported.profile()) { case QSurfaceFormat::NoProfile: { @@ -121,6 +126,7 @@ Capabilities CheckCapabilities(QWidget *widget) { LOG_ONCE(("OpenGL Profile: Compatibility.")); } break; } + [[maybe_unused]] static const auto extensionsLogged = [&] { const auto renderer = reinterpret_cast( functions->glGetString(GL_RENDERER)); @@ -138,6 +144,7 @@ Capabilities CheckCapabilities(QWidget *widget) { LOG(("OpenGL Extensions: %1").arg(list.join(", "))); return true; }(); + const auto version = u"%1.%2"_q .arg(supported.majorVersion()) .arg(supported.majorVersion()); From e68f76e6ab9457652d6de0712120695d2fbb81b8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 21 Jul 2021 21:18:04 +0300 Subject: [PATCH 02/20] List and allow to query EGL extensions on Windows. --- ui/gl/gl_detection.cpp | 28 ++++++++++++++++++++++++++++ ui/gl/gl_detection.h | 3 +++ 2 files changed, 31 insertions(+) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 5973083..7b3f851 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -17,6 +17,12 @@ #include #include +#ifdef Q_OS_WIN +#include +#include +#include +#endif // Q_OS_WIN + #define LOG_ONCE(x) [[maybe_unused]] static auto logged = [&] { LOG(x); return true; }(); namespace Ui::GL { @@ -142,6 +148,15 @@ Capabilities CheckCapabilities(QWidget *widget) { list.append(QString::fromLatin1(extension)); } LOG(("OpenGL Extensions: %1").arg(list.join(", "))); + +#ifdef Q_OS_WIN + auto egllist = QStringList(); + for (const auto &extension : EGLExtensions(context)) { + egllist.append(QString::fromLatin1(extension)); + } + LOG(("EGL Extensions: %1").arg(egllist.join(", "))); +#endif // Q_OS_WIN + return true; }(); @@ -225,6 +240,19 @@ ANGLE CurrentANGLE() { return ResolvedANGLE; } +QList EGLExtensions(not_null context) { + const auto native = QGuiApplication::platformNativeInterface(); + Assert(native != nullptr); + + const auto display = static_cast( + native->nativeResourceForContext( + QByteArrayLiteral("egldisplay"), + context)); + return display + ? QByteArray(eglQueryString(display, EGL_EXTENSIONS)).split(' ') + : QList(); +} + #endif // Q_OS_WIN } // namespace Ui::GL diff --git a/ui/gl/gl_detection.h b/ui/gl/gl_detection.h index c50cab7..6c1ef91 100644 --- a/ui/gl/gl_detection.h +++ b/ui/gl/gl_detection.h @@ -40,4 +40,7 @@ void ConfigureANGLE(); // Requires Ui::Integration being set. void ChangeANGLE(ANGLE backend); [[nodiscard]] ANGLE CurrentANGLE(); +[[nodiscard]] QList EGLExtensions( + not_null context); + } // namespace Ui::GL From 2439235e429263a5c8fe8e65b4a3a32455128443 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 22 Jul 2021 15:49:33 +0300 Subject: [PATCH 03/20] Remove CurrentSingleComponentFormat. --- ui/gl/gl_image.cpp | 10 ---------- ui/gl/gl_image.h | 2 -- ui/gl/gl_shader.cpp | 6 +++--- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/ui/gl/gl_image.cpp b/ui/gl/gl_image.cpp index 633d108..3db6653 100644 --- a/ui/gl/gl_image.cpp +++ b/ui/gl/gl_image.cpp @@ -155,14 +155,4 @@ TexturedRect Image::texturedRect( }; } -GLint CurrentSingleComponentFormat() { - const auto context = QOpenGLContext::currentContext(); - Assert(context != nullptr); - - const auto format = context->format(); - return (format.renderableType() == QSurfaceFormat::OpenGLES) - ? GL_LUMINANCE - : GL_RED; -} - } // namespace Ui::GL diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index fe8fd3e..75c24ec 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -134,8 +134,6 @@ private: }; -[[nodiscard]] GLint CurrentSingleComponentFormat(); - #ifdef Q_OS_WIN inline constexpr auto kFormatRGBA = GL_BGRA_EXT; inline constexpr auto kSwizzleRedBlue = false; diff --git a/ui/gl/gl_shader.cpp b/ui/gl/gl_shader.cpp index 3079a52..2f47edd 100644 --- a/ui/gl/gl_shader.cpp +++ b/ui/gl/gl_shader.cpp @@ -89,9 +89,9 @@ uniform sampler2D u_texture; uniform sampler2D v_texture; )", .body = R"( - float y = texture2D(y_texture, v_texcoord).r - 0.0625; - float u = texture2D(u_texture, v_texcoord).r - 0.5; - float v = texture2D(v_texture, v_texcoord).r - 0.5; + float y = texture2D(y_texture, v_texcoord).a - 0.0625; + float u = texture2D(u_texture, v_texcoord).a - 0.5; + float v = texture2D(v_texture, v_texcoord).a - 0.5; result = vec4( 1.164 * y + 1.596 * v, 1.164 * y - 0.392 * u - 0.813 * v, From 12429c198d9176e109af282d28198ef1bd143971 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 23 Jul 2021 10:09:00 +0300 Subject: [PATCH 04/20] Provide custom gpu_driver_bug_list.json on Windows. --- qt_conf/gpu_driver_bug_list.json | 250 +++++++++++++++++++++++++++++++ qt_conf/win.qrc | 3 + ui/gl/gl_detection.cpp | 10 ++ 3 files changed, 263 insertions(+) create mode 100644 qt_conf/gpu_driver_bug_list.json diff --git a/qt_conf/gpu_driver_bug_list.json b/qt_conf/gpu_driver_bug_list.json new file mode 100644 index 0000000..9f4b7da --- /dev/null +++ b/qt_conf/gpu_driver_bug_list.json @@ -0,0 +1,250 @@ +{ + "name": "Qt built-in + some Chromium GPU driver blacklist", + "version": "5.6", + "entries": [ + { + "id": 1, + "description": "Desktop OpenGL is unreliable on some Intel HD laptops (QTBUG-43263)", + "vendor_id": "0x8086", + "device_id": [ "0x0A16" ], + "os": { + "type": "win" + }, + "driver_version": { + "op": "<=", + "value": "10.18.10.3277" + }, + "features": [ + "disable_desktopgl" + ] + }, + { + "id": 2, + "description": "Intel Q965/Q963 - GMA 3000 has insufficient support of opengl and directx", + "vendor_id": "0x8086", + "device_id": [ "0x2992" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", + "disable_angle" + ] + }, + { + "id": 3, + "description": "No OpenGL on Intel G33/G31 (QTBUG-47522)", + "vendor_id": "0x8086", + "device_id": [ "0x29C2" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + }, + { + "id": 4, + "description": "Intel HD Graphics 3000 crashes when initializing the OpenGL driver (QTBUG-42240)", + "vendor_id": "0x8086", + "device_id": [ "0x0102", "0x0106", "0x010A", "0x0112", "0x0116", "0x0122", "0x0126" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + }, + { + "id": 5, + "description": "Intel GMA 3150 (QTBUG-43243), Mobile Intel 945GM (QTBUG-47435) crash", + "vendor_id": "0x8086", + "device_id": [ "0xA001", "0xA011", "0x27A0" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", "disable_angle" + ] + }, + { + "id": 6, + "description": "Intel(R) HD Graphics 4000 / 5500 cause crashes on orientation changes in fullscreen mode (QTBUG-49541)", + "vendor_id": "0x8086", + "device_id": [ "0x0166", "0x1616" ], + "os": { + "type": "win" + }, + "features": [ + "disable_rotation" + ] + }, + { + "id": 7, + "description": "AMD FirePro V5900 driver causes crashes in Direct3D on Windows.", + "vendor_id": "0x1002", + "device_id": ["0x6707"], + "os": { + "type": "win" + }, + "features": [ + "disable_angle" + ] + }, + { + "id": 8, + "description": "Standard VGA: Insufficent support for OpenGL, D3D9 and D3D11", + "vendor_id": "0x0000", + "device_id": ["0x0000"], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl", "disable_d3d11", "disable_d3d9" + ] + }, + { + "id": 9, + "description": "Intel 945 crash (QTBUG-40991)", + "vendor_id": "0x8086", + "device_id": [ "0x27A2" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + }, + { + "id": 10, + "description": "Intel(R) HD Graphics IronLake (Arrandale) crashes on makeCurrent QTBUG-53888", + "vendor_id": "0x8086", + "device_id": [ "0x0046" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + }, + { + "id": 11, + "description": "Intel driver version 8.15.10.1749 causes GPU process hangs (QTBUG-56360)", + "vendor_id": "0x8086", + "os": { + "type": "win" + }, + "driver_version": { + "op": "=", + "value": "8.15.10.1749" + }, + "features": [ + "disable_desktopgl", "disable_d3d11", "disable_d3d9" + ] + }, + { + "id": 12, + "description": "Intel HD Graphics crash in conjunction with shader caches (QTBUG-64697) - disable for all Intel GPUs", + "vendor_id": "0x8086", + "os": { + "type": "win" + }, + "features": [ + "disable_program_cache" + ] + }, + { + "id": 13, + "description": "Disable DesktopGL on Windows with Mobile Intel(R) 4 Series Express Chipset Family graphics card (QTBUG-58772)", + "vendor_id": "0x8086", + "device_id": [ "0x2A42" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + }, + + { + "id": 70, + "description": "Disable D3D11 on older nVidia drivers", + "cr_bugs": [349929], + "os": { + "type": "win" + }, + "vendor_id": "0x10de", + "driver_version": { + "op": "<=", + "value": "8.17.12.6973" + }, + "features": [ + "disable_d3d11" + ] + }, + { + "id": 86, + "description": "Disable use of Direct3D 11 on Matrox video cards", + "cr_bugs": [395861], + "os": { + "type": "win" + }, + "vendor_id": "0x102b", + "features": [ + "disable_d3d11" + ] + }, + { + "id": 87, + "description": "Disable use of Direct3D 11 on older AMD drivers", + "cr_bugs": [402134], + "os": { + "type": "win" + }, + "vendor_id": "0x1002", + "driver_version": { + "op": "<", + "value": "8.17.10.1070" + }, + "features": [ + "disable_d3d11" + ] + }, + { + "id": 92, + "description": "Old Intel drivers cannot reliably support D3D11", + "cr_bugs": [363721], + "os": { + "type": "win" + }, + "vendor_id": "0x8086", + "driver_version": { + "op": "<=", + "value": "9.18.0.0" + }, + "features": [ + "disable_d3d11" + ] + }, + { + "id": 100, + "description": "Disable Direct3D11 on systems with AMD switchable graphics", + "cr_bugs": [451420, 721121, 755722], + "os": { + "type": "win", + "version": { + "op": "<", + "value": "10" + } + }, + "driver_version": { + "op": "<", + "value": "20.19.0.32837" + }, + "multi_gpu_style": "amd_switchable", + "features": [ + "disable_d3d11" + ] + } + ] +} diff --git a/qt_conf/win.qrc b/qt_conf/win.qrc index df8db39..fcc0acf 100644 --- a/qt_conf/win.qrc +++ b/qt_conf/win.qrc @@ -2,4 +2,7 @@ qt_win.conf + + gpu_driver_bug_list.json + diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 7b3f851..2f1433d 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -49,6 +49,16 @@ Capabilities CheckCapabilities(QWidget *widget) { LOG_ONCE(("OpenGL: Force-disabled.")); return {}; } + + static const auto BugListInited = [] { + if (!QFile::exists(":/misc/gpu_driver_bug_list.json")) { + return false; + } + LOG(("OpenGL: Using custom 'gpu_driver_bug_list.json'.")); + qputenv("QT_OPENGL_BUGLIST", ":/misc/gpu_driver_bug_list.json"); + return true; + }(); + auto format = QSurfaceFormat(); if (widget) { if (!widget->window()->windowHandle()) { From 1ed242718ee2dd6363ff738acb9151e649500ed7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 23 Jul 2021 15:12:16 +0300 Subject: [PATCH 05/20] Fix linker warning in MSVC. --- ui/gl/gl_detection.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index 2f1433d..dc7be2a 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -20,6 +20,8 @@ #ifdef Q_OS_WIN #include #include + +#define KHRONOS_STATIC #include #endif // Q_OS_WIN From 8de7b873f91c720914c537007c1e2fb5174677bb Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 23 Jul 2021 18:52:15 +0300 Subject: [PATCH 06/20] Remove 'osx' special target code. --- ui/platform/mac/ui_window_mac.h | 8 -------- ui/platform/mac/ui_window_mac.mm | 23 ----------------------- 2 files changed, 31 deletions(-) diff --git a/ui/platform/mac/ui_window_mac.h b/ui/platform/mac/ui_window_mac.h index f4c9622..31dda13 100644 --- a/ui/platform/mac/ui_window_mac.h +++ b/ui/platform/mac/ui_window_mac.h @@ -41,14 +41,6 @@ private: const not_null _body; bool _titleVisible = true; -#ifdef OS_OSX - struct WindowDrag { - QPoint windowStartPosition; - QPoint dragStartPosition; - }; - std::optional _drag; -#endif // OS_OSX - }; } // namespace Platform diff --git a/ui/platform/mac/ui_window_mac.mm b/ui/platform/mac/ui_window_mac.mm index fe297a2..9ce90e5 100644 --- a/ui/platform/mac/ui_window_mac.mm +++ b/ui/platform/mac/ui_window_mac.mm @@ -367,7 +367,6 @@ void WindowHelper::setGeometry(QRect rect) { } void WindowHelper::setupBodyTitleAreaEvents() { -#ifndef OS_OSX const auto controls = _private->controlsRect(); qApp->installNativeEventFilter(new EventFilter(window(), [=](void *nswindow) { const auto point = body()->mapFromGlobal(QCursor::pos()); @@ -380,28 +379,6 @@ void WindowHelper::setupBodyTitleAreaEvents() { } return false; })); -#else // OS_OSX - // OS X 10.10 doesn't have performWindowDragWithEvent yet. - body()->events() | rpl::start_with_next([=](not_null e) { - const auto hitTest = [&] { - return bodyTitleAreaHit( - static_cast(e.get())->pos()); - }; - if (e->type() == QEvent::MouseButtonRelease - && (static_cast(e.get())->button() - == Qt::LeftButton)) { - _drag = std::nullopt; - } else if (e->type() == QEvent::MouseButtonPress - && hitTest() - && (static_cast(e.get())->button() - == Qt::LeftButton)) { - _drag = { window()->pos(), static_cast(e.get())->globalPos() }; - } else if (e->type() == QEvent::MouseMove && _drag && !window()->isFullScreen()) { - const auto delta = static_cast(e.get())->globalPos() - _drag->dragStartPosition; - window()->move(_drag->windowStartPosition + delta); - } - }, body()->lifetime()); -#endif // OS_OSX } void WindowHelper::close() { From 2d251e063cd063f9ba5a1c6e2596a1feb1630b49 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 23 Jul 2021 19:35:59 +0300 Subject: [PATCH 07/20] Fix build on macOS. --- ui/gl/gl_detection.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/gl/gl_detection.h b/ui/gl/gl_detection.h index 6c1ef91..b197bcc 100644 --- a/ui/gl/gl_detection.h +++ b/ui/gl/gl_detection.h @@ -8,6 +8,8 @@ #include "base/flags.h" +class QOpenGLContext; + namespace Ui::GL { enum class Backend { From 49166a8b7243fd8926d1808da87c803670b02474 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 23 Jul 2021 20:41:38 +0300 Subject: [PATCH 08/20] Fix build on Linux. --- ui/gl/gl_detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index dc7be2a..d46682f 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -52,7 +52,7 @@ Capabilities CheckCapabilities(QWidget *widget) { return {}; } - static const auto BugListInited = [] { + [[maybe_unused]] static const auto BugListInited = [] { if (!QFile::exists(":/misc/gpu_driver_bug_list.json")) { return false; } From 17123c08ab88819908480e718bbb25f4e51598f3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 26 Jul 2021 14:08:04 +0300 Subject: [PATCH 09/20] Define 'KHRONOS_STATIC' globally. --- ui/gl/gl_detection.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/gl/gl_detection.cpp b/ui/gl/gl_detection.cpp index d46682f..33c929a 100644 --- a/ui/gl/gl_detection.cpp +++ b/ui/gl/gl_detection.cpp @@ -20,8 +20,6 @@ #ifdef Q_OS_WIN #include #include - -#define KHRONOS_STATIC #include #endif // Q_OS_WIN From 95cafc5064104a2c4a63df72c08f7bd42b62dd7f Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Mon, 26 Jul 2021 02:56:40 +0400 Subject: [PATCH 10/20] Fix cursor with custom titlebar on Linux --- ui/platform/ui_platform_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 42949a3..674394a 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -282,7 +282,7 @@ bool DefaultWindowHelper::eventFilter(QObject *obj, QEvent *e) { // doesn't work with RpWidget::events() for some reason if (e->type() == QEvent::MouseMove && obj->isWidgetType() - && static_cast(window()) == static_cast(obj)) { + && window()->isAncestorOf(static_cast(obj))) { const auto mouseEvent = static_cast(e); const auto currentPoint = mouseEvent->windowPos().toPoint(); const auto edges = edgesFromPos(currentPoint); From 7a7187612424d22ba869549c63ea8d52d43ea196 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Wed, 28 Jul 2021 00:07:09 +0400 Subject: [PATCH 11/20] Add possibility to enable native window frame to Ui::Window --- CMakeLists.txt | 1 + .../linux/ui_linux_wayland_integration.cpp | 50 +++++- .../linux/ui_linux_wayland_integration.h | 10 +- .../ui_linux_wayland_integration_dummy.cpp | 10 ++ ui/platform/linux/ui_window_linux.cpp | 8 + ui/platform/mac/ui_window_mac.mm | 4 + ui/platform/ui_platform_window.cpp | 34 ++-- ui/platform/ui_platform_window.h | 5 + ui/platform/win/ui_window_win.cpp | 151 +++++++++++++----- ui/platform/win/ui_window_win.h | 5 +- ui/widgets/window.cpp | 4 + ui/widgets/window.h | 1 + 12 files changed, 229 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 55310c8..dc98be1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -253,6 +253,7 @@ elseif(LINUX) target_link_libraries(lib_ui PUBLIC desktop-app::lib_waylandshells + desktop-app::external_kwayland ) endif() diff --git a/ui/platform/linux/ui_linux_wayland_integration.cpp b/ui/platform/linux/ui_linux_wayland_integration.cpp index 4d78307..01f1e80 100644 --- a/ui/platform/linux/ui_linux_wayland_integration.cpp +++ b/ui/platform/linux/ui_linux_wayland_integration.cpp @@ -24,23 +24,71 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +#include +#include + Q_DECLARE_METATYPE(QMargins); using QtWaylandClient::QWaylandIntegration; using QtWaylandClient::QWaylandWindow; +using namespace KWayland::Client; namespace Ui { namespace Platform { -WaylandIntegration::WaylandIntegration() { +struct WaylandIntegration::Private { + std::unique_ptr connection; + Registry registry; + QEventLoop interfacesLoop; + bool interfacesAnnounced = false; +}; + +WaylandIntegration::WaylandIntegration() +: _private(std::make_unique()) { + _private->connection = std::unique_ptr{ + ConnectionThread::fromApplication(), + }; + + _private->registry.create(_private->connection.get()); + _private->registry.setup(); + + QObject::connect( + _private->connection.get(), + &ConnectionThread::connectionDied, + &_private->registry, + &Registry::destroy); + + QObject::connect( + &_private->registry, + &Registry::interfacesAnnounced, + [=] { + _private->interfacesAnnounced = true; + if (_private->interfacesLoop.isRunning()) { + _private->interfacesLoop.quit(); + } + }); } +WaylandIntegration::~WaylandIntegration() = default; + WaylandIntegration *WaylandIntegration::Instance() { if (!::Platform::IsWayland()) return nullptr; static WaylandIntegration instance; return &instance; } +void WaylandIntegration::waitForInterfaceAnnounce() { + Expects(!_private->interfacesLoop.isRunning()); + if (!_private->interfacesAnnounced) { + _private->interfacesLoop.exec(); + } +} + +bool WaylandIntegration::xdgDecorationSupported() { + return _private->registry.hasInterface( + Registry::Interface::XdgDecorationUnstableV1); +} + bool WaylandIntegration::windowExtentsSupported() { // initialize shell integration before querying if (const auto integration = static_cast( diff --git a/ui/platform/linux/ui_linux_wayland_integration.h b/ui/platform/linux/ui_linux_wayland_integration.h index ed877f2..c975539 100644 --- a/ui/platform/linux/ui_linux_wayland_integration.h +++ b/ui/platform/linux/ui_linux_wayland_integration.h @@ -14,15 +14,21 @@ namespace Platform { class WaylandIntegration { public: - static WaylandIntegration *Instance(); + [[nodiscard]] static WaylandIntegration *Instance(); - bool windowExtentsSupported(); + void waitForInterfaceAnnounce(); + [[nodiscard]] bool xdgDecorationSupported(); + [[nodiscard]] bool windowExtentsSupported(); void setWindowExtents(QWindow *window, const QMargins &extents); void unsetWindowExtents(QWindow *window); bool showWindowMenu(QWindow *window); private: WaylandIntegration(); + ~WaylandIntegration(); + + struct Private; + const std::unique_ptr _private; }; } // namespace Platform diff --git a/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp b/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp index 972b09c..13fafdb 100644 --- a/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp +++ b/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp @@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { namespace Platform { +struct WaylandIntegration::Private { +}; + WaylandIntegration::WaylandIntegration() { } @@ -21,6 +24,13 @@ WaylandIntegration *WaylandIntegration::Instance() { return &instance; } +void WaylandIntegration::waitForInterfaceAnnounce() { +} + +bool WaylandIntegration::xdgDecorationSupported() { + return false; +} + bool WaylandIntegration::windowExtentsSupported() { return false; } diff --git a/ui/platform/linux/ui_window_linux.cpp b/ui/platform/linux/ui_window_linux.cpp index c98869a..a353c32 100644 --- a/ui/platform/linux/ui_window_linux.cpp +++ b/ui/platform/linux/ui_window_linux.cpp @@ -6,6 +6,8 @@ // #include "ui/platform/linux/ui_window_linux.h" +#include "ui/platform/linux/ui_linux_wayland_integration.h" + namespace Ui { namespace Platform { @@ -14,5 +16,11 @@ std::unique_ptr CreateSpecialWindowHelper( return nullptr; } +bool NativeWindowFrameSupported() { + const auto waylandIntegration = WaylandIntegration::Instance(); + return !waylandIntegration + || waylandIntegration->xdgDecorationSupported(); +} + } // namespace Platform } // namespace Ui diff --git a/ui/platform/mac/ui_window_mac.mm b/ui/platform/mac/ui_window_mac.mm index 9ce90e5..c8d8372 100644 --- a/ui/platform/mac/ui_window_mac.mm +++ b/ui/platform/mac/ui_window_mac.mm @@ -412,5 +412,9 @@ std::unique_ptr CreateSpecialWindowHelper( return std::make_unique(window); } +bool NativeWindowFrameSupported() { + return false; +} + } // namespace Platform } // namespace Ui diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 674394a..7583efb 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -44,6 +44,9 @@ void BasicWindowHelper::setTitle(const QString &title) { void BasicWindowHelper::setTitleStyle(const style::WindowTitle &st) { } +void BasicWindowHelper::setNativeFrame(bool enabled) { +} + void BasicWindowHelper::setMinimumSize(QSize size) { _window->setMinimumSize(size); } @@ -161,17 +164,21 @@ void DefaultWindowHelper::init() { rpl::combine( window()->sizeValue(), - _title->heightValue() - ) | rpl::start_with_next([=](QSize size, int titleHeight) { + _title->heightValue(), + _title->shownValue() + ) | rpl::start_with_next([=]( + QSize size, + int titleHeight, + bool titleShown) { const auto area = resizeArea(); const auto sizeWithoutMargins = size - .shrunkBy({ 0, titleHeight, 0, 0 }) + .shrunkBy({ 0, titleShown ? titleHeight : 0, 0, 0 }) .shrunkBy(area); const auto topLeft = QPoint( area.left(), - area.top() + titleHeight); + area.top() + (titleShown ? titleHeight : 0)); _body->setGeometry(QRect(topLeft, sizeWithoutMargins)); }, _body->lifetime()); @@ -233,7 +240,9 @@ bool DefaultWindowHelper::hasShadow() const { } QMargins DefaultWindowHelper::resizeArea() const { - if (window()->isMaximized() || window()->isFullScreen()) { + if (window()->isMaximized() + || window()->isFullScreen() + || _nativeFrame) { return QMargins(); } @@ -310,16 +319,23 @@ void DefaultWindowHelper::setTitleStyle(const style::WindowTitle &st) { _title->st()->height); } +void DefaultWindowHelper::setNativeFrame(bool enabled) { + _nativeFrame = enabled; + window()->windowHandle()->setFlag(Qt::FramelessWindowHint, !enabled); + _title->setVisible(!enabled); + updateWindowExtents(); +} + void DefaultWindowHelper::setMinimumSize(QSize size) { const auto sizeWithMargins = size - .grownBy({ 0, _title->height(), 0, 0 }) + .grownBy({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 }) .grownBy(resizeArea()); window()->setMinimumSize(sizeWithMargins); } void DefaultWindowHelper::setFixedSize(QSize size) { const auto sizeWithMargins = size - .grownBy({ 0, _title->height(), 0, 0 }) + .grownBy({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 }) .grownBy(resizeArea()); window()->setFixedSize(sizeWithMargins); _title->setResizeEnabled(false); @@ -327,7 +343,7 @@ void DefaultWindowHelper::setFixedSize(QSize size) { void DefaultWindowHelper::setGeometry(QRect rect) { window()->setGeometry(rect - .marginsAdded({ 0, _title->height(), 0, 0 }) + .marginsAdded({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 }) .marginsAdded(resizeArea())); } @@ -376,7 +392,7 @@ void DefaultWindowHelper::paintBorders(QPainter &p) { } void DefaultWindowHelper::updateWindowExtents() { - if (hasShadow()) { + if (hasShadow() && !_nativeFrame) { Platform::SetWindowExtents( window()->windowHandle(), resizeArea()); diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index 58a1c8a..60e102d 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -30,6 +30,7 @@ public: [[nodiscard]] virtual not_null body(); virtual void setTitle(const QString &title); virtual void setTitleStyle(const style::WindowTitle &st); + virtual void setNativeFrame(bool enabled); virtual void setMinimumSize(QSize size); virtual void setFixedSize(QSize size); virtual void setStaysOnTop(bool enabled); @@ -67,6 +68,7 @@ public: not_null body() override; void setTitle(const QString &title) override; void setTitleStyle(const style::WindowTitle &st) override; + void setNativeFrame(bool enabled) override; void setMinimumSize(QSize size) override; void setFixedSize(QSize size) override; void setGeometry(QRect rect) override; @@ -86,6 +88,7 @@ private: const not_null _title; const not_null _body; bool _extentsSet = false; + bool _nativeFrame = false; }; @@ -100,5 +103,7 @@ private: return std::make_unique(window); } +bool NativeWindowFrameSupported(); + } // namespace Platform } // namespace Ui diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 2f853c3..26bad2b 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -148,7 +148,7 @@ WindowHelper::WindowHelper(not_null window) , _handle(GetWindowHandle(window)) , _title(Ui::CreateChild(window.get())) , _body(Ui::CreateChild(window.get())) -, _shadow(window, st::windowShadowFg->c) { +, _shadow(std::in_place, window, st::windowShadowFg->c) { Expects(_handle != nullptr); GetNativeFilter()->registerWindow(_handle, this); @@ -172,18 +172,36 @@ void WindowHelper::setTitleStyle(const style::WindowTitle &st) { _title->setStyle(st); } +void WindowHelper::setNativeFrame(bool enabled) { + _nativeFrame = enabled; + _title->setVisible(!enabled); + if (enabled) { + _shadow.reset(); + } else { + _shadow.emplace(window(), st::windowShadowFg->c); + _shadow->setResizeEnabled(!fixedSize()); + } + updateMargins(); + fixMaximizedWindow(); +} + void WindowHelper::setMinimumSize(QSize size) { - window()->setMinimumSize(size.width(), _title->height() + size.height()); + const auto titleHeight = _title->isVisible() ? _title->height() : 0; + window()->setMinimumSize(size.width(), titleHeight + size.height()); } void WindowHelper::setFixedSize(QSize size) { - window()->setFixedSize(size.width(), _title->height() + size.height()); + const auto titleHeight = _title->isVisible() ? _title->height() : 0; + window()->setFixedSize(size.width(), titleHeight + size.height()); _title->setResizeEnabled(false); - _shadow.setResizeEnabled(false); + if (_shadow) { + _shadow->setResizeEnabled(false); + } } void WindowHelper::setGeometry(QRect rect) { - window()->setGeometry(rect.marginsAdded({ 0, _title->height(), 0, 0 })); + const auto titleHeight = _title->isVisible() ? _title->height() : 0; + window()->setGeometry(rect.marginsAdded({ 0, titleHeight, 0, 0 })); } void WindowHelper::showFullScreen() { @@ -205,19 +223,25 @@ void WindowHelper::showNormal() { void WindowHelper::init() { style::PaletteChanged( ) | rpl::start_with_next([=] { - _shadow.setColor(st::windowShadowFg->c); + if (_shadow) { + _shadow->setColor(st::windowShadowFg->c); + } Ui::ForceFullRepaint(window()); }, window()->lifetime()); rpl::combine( window()->sizeValue(), - _title->heightValue() - ) | rpl::start_with_next([=](QSize size, int titleHeight) { + _title->heightValue(), + _title->shownValue() + ) | rpl::start_with_next([=]( + QSize size, + int titleHeight, + bool titleShown) { _body->setGeometry( 0, - titleHeight, + titleShown ? titleHeight : 0, size.width(), - size.height() - titleHeight); + size.height() - (titleShown ? titleHeight : 0)); }, _body->lifetime()); updateMargins(); @@ -256,22 +280,27 @@ bool WindowHelper::handleNativeEvent( if (LOWORD(wParam) == WA_CLICKACTIVE) { Ui::MarkInactivePress(window(), true); } - if (LOWORD(wParam) != WA_INACTIVE) { - _shadow.update(WindowShadow::Change::Activate); - } else { - _shadow.update(WindowShadow::Change::Deactivate); + if (_shadow) { + if (LOWORD(wParam) != WA_INACTIVE) { + _shadow->update(WindowShadow::Change::Activate); + } else { + _shadow->update(WindowShadow::Change::Deactivate); + } } window()->update(); } return false; case WM_NCPAINT: { - if (::Platform::IsWindows8OrGreater()) { + if (::Platform::IsWindows8OrGreater() || _nativeFrame) { return false; } if (result) *result = 0; } return true; case WM_NCCALCSIZE: { + if (_nativeFrame) { + return false; + } WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); if (GetWindowPlacement(_handle, &wp) @@ -315,6 +344,9 @@ bool WindowHelper::handleNativeEvent( } return true; case WM_NCACTIVATE: { + if (_nativeFrame) { + return false; + } if (IsCompositionEnabled()) { const auto res = DefWindowProc(_handle, msg, wParam, -1); if (result) *result = res; @@ -326,16 +358,18 @@ bool WindowHelper::handleNativeEvent( case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: { - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - if (GetWindowPlacement(_handle, &wp) - && (wp.showCmd == SW_SHOWMAXIMIZED - || wp.showCmd == SW_SHOWMINIMIZED)) { - _shadow.update(WindowShadow::Change::Hidden); - } else { - _shadow.update( - WindowShadow::Change::Moved | WindowShadow::Change::Resized, - (WINDOWPOS*)lParam); + if (_shadow) { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + if (GetWindowPlacement(_handle, &wp) + && (wp.showCmd == SW_SHOWMAXIMIZED + || wp.showCmd == SW_SHOWMINIMIZED)) { + _shadow->update(WindowShadow::Change::Hidden); + } else { + _shadow->update( + WindowShadow::Change::Moved | WindowShadow::Change::Resized, + (WINDOWPOS*)lParam); + } } } return false; @@ -354,30 +388,36 @@ bool WindowHelper::handleNativeEvent( window()->windowHandle()->windowStateChanged(state); } updateMargins(); - const auto changes = (wParam == SIZE_MINIMIZED - || wParam == SIZE_MAXIMIZED) - ? WindowShadow::Change::Hidden - : (WindowShadow::Change::Resized - | WindowShadow::Change::Shown); - _shadow.update(changes); + if (_shadow) { + const auto changes = (wParam == SIZE_MINIMIZED + || wParam == SIZE_MAXIMIZED) + ? WindowShadow::Change::Hidden + : (WindowShadow::Change::Resized + | WindowShadow::Change::Shown); + _shadow->update(changes); + } } } return false; case WM_SHOWWINDOW: { - const auto style = GetWindowLongPtr(_handle, GWL_STYLE); - const auto changes = WindowShadow::Change::Resized - | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) - ? WindowShadow::Change::Shown - : WindowShadow::Change::Hidden); - _shadow.update(changes); + if (_shadow) { + const auto style = GetWindowLongPtr(_handle, GWL_STYLE); + const auto changes = WindowShadow::Change::Resized + | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) + ? WindowShadow::Change::Shown + : WindowShadow::Change::Hidden); + _shadow->update(changes); + } } return false; case WM_MOVE: { - _shadow.update(WindowShadow::Change::Moved); + if (_shadow) { + _shadow->update(WindowShadow::Change::Moved); + } } return false; case WM_NCHITTEST: { - if (!result) { + if (!result || _nativeFrame) { return false; } @@ -389,7 +429,7 @@ bool WindowHelper::handleNativeEvent( p.y - r.top + _marginsDelta.top()); if (!window()->rect().contains(mapped)) { *result = HTTRANSPARENT; - } else if (!_title->geometry().contains(mapped)) { + } else if (!_title->isVisible() || !_title->geometry().contains(mapped)) { *result = HTCLIENT; } else switch (_title->hitTest(_title->pos() + mapped)) { case HitTestResult::Client: @@ -409,6 +449,9 @@ bool WindowHelper::handleNativeEvent( } return true; case WM_NCRBUTTONUP: { + if (_nativeFrame) { + return false; + } SendMessage(_handle, WM_SYSCOMMAND, SC_MOUSEMENU, lParam); } return true; @@ -519,8 +562,11 @@ void WindowHelper::updateMargins() { _marginsDelta = QMargins(); } - if (_isFullScreen) { + if (_isFullScreen || _nativeFrame) { margins = QMargins(); + if (_nativeFrame) { + _marginsDelta = QMargins(); + } } if (const auto native = QGuiApplication::platformNativeInterface()) { native->setWindowProperty( @@ -573,6 +619,25 @@ void WindowHelper::updateSystemMenu(Qt::WindowState state) { } } +void WindowHelper::fixMaximizedWindow() { + auto r = RECT(); + GetClientRect(_handle, &r); + const auto style = GetWindowLongPtr(_handle, GWL_STYLE); + const auto styleEx = GetWindowLongPtr(_handle, GWL_EXSTYLE); + AdjustWindowRectEx(&r, style, false, styleEx); + if (style & WS_MAXIMIZE) { + auto w = RECT(); + GetWindowRect(_handle, &w); + if (const auto hMonitor = MonitorFromRect(&w, MONITOR_DEFAULTTONEAREST)) { + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + const auto m = mi.rcWork; + SetWindowPos(_handle, 0, 0, 0, m.right - m.left - _marginsDelta.left() - _marginsDelta.right(), m.bottom - m.top - _marginsDelta.top() - _marginsDelta.bottom(), SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION); + } + } +} + not_null WindowHelper::GetNativeFilter() { Expects(QCoreApplication::instance() != nullptr); @@ -619,5 +684,9 @@ std::unique_ptr CreateSpecialWindowHelper( return std::make_unique(window); } +bool NativeWindowFrameSupported() { + return true; +} + } // namespace Platform } // namespace Ui diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index 9abfe60..cee1b22 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -24,6 +24,7 @@ public: not_null body() override; void setTitle(const QString &title) override; void setTitleStyle(const style::WindowTitle &st) override; + void setNativeFrame(bool enabled) override; void setMinimumSize(QSize size) override; void setFixedSize(QSize size) override; void setGeometry(QRect rect) override; @@ -38,6 +39,7 @@ private: void updateMargins(); void updateSystemMenu(); void updateSystemMenu(Qt::WindowState state); + void fixMaximizedWindow(); [[nodiscard]] bool handleNativeEvent( UINT msg, WPARAM wParam, @@ -50,11 +52,12 @@ private: const HWND _handle = nullptr; const not_null _title; const not_null _body; - WindowShadow _shadow; + std::optional _shadow; bool _updatingMargins = false; QMargins _marginsDelta; HMENU _menu = nullptr; bool _isFullScreen = false; + bool _nativeFrame = false; }; diff --git a/ui/widgets/window.cpp b/ui/widgets/window.cpp index 3423701..90888b3 100644 --- a/ui/widgets/window.cpp +++ b/ui/widgets/window.cpp @@ -36,6 +36,10 @@ void Window::setTitleStyle(const style::WindowTitle &st) { _helper->setTitleStyle(st); } +void Window::setNativeFrame(bool enabled) { + _helper->setNativeFrame(enabled); +} + void Window::setMinimumSize(QSize size) { _helper->setMinimumSize(size); } diff --git a/ui/widgets/window.h b/ui/widgets/window.h index 336ff4f..2962c07 100644 --- a/ui/widgets/window.h +++ b/ui/widgets/window.h @@ -39,6 +39,7 @@ public: void setTitle(const QString &title); void setTitleStyle(const style::WindowTitle &st); + void setNativeFrame(bool enabled); void setMinimumSize(QSize size); void setFixedSize(QSize size); void setStaysOnTop(bool enabled); From d452ae8ba6fcfc83accb6a1213a15d3e3a301740 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 28 Jul 2021 16:22:02 +0300 Subject: [PATCH 12/20] Rename Ui::Window to Ui::RpWindow. --- CMakeLists.txt | 4 +-- ui/gl/gl_window.cpp | 30 +++++++++++----------- ui/gl/gl_window.h | 18 ++++++------- ui/platform/mac/ui_window_mac.mm | 2 +- ui/platform/ui_platform_window.cpp | 2 +- ui/widgets/{window.cpp => rp_window.cpp} | 32 ++++++++++++------------ ui/widgets/{window.h => rp_window.h} | 6 ++--- 7 files changed, 47 insertions(+), 47 deletions(-) rename ui/widgets/{window.cpp => rp_window.cpp} (58%) rename ui/widgets/{window.h => rp_window.h} (93%) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc98be1..f463fed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,8 @@ PRIVATE ui/widgets/menu/menu_toggle.h ui/widgets/popup_menu.cpp ui/widgets/popup_menu.h + ui/widgets/rp_window.cpp + ui/widgets/rp_window.h ui/widgets/scroll_area.cpp ui/widgets/scroll_area.h ui/widgets/side_bar_button.cpp @@ -188,8 +190,6 @@ PRIVATE ui/widgets/shadow.h ui/widgets/tooltip.cpp ui/widgets/tooltip.h - ui/widgets/window.cpp - ui/widgets/window.h ui/wrap/fade_wrap.cpp ui/wrap/fade_wrap.h ui/wrap/padding_wrap.cpp diff --git a/ui/gl/gl_window.cpp b/ui/gl/gl_window.cpp index 2cc0f86..f2cc816 100644 --- a/ui/gl/gl_window.cpp +++ b/ui/gl/gl_window.cpp @@ -7,7 +7,7 @@ #include "ui/gl/gl_window.h" #include "ui/gl/gl_detection.h" -#include "ui/widgets/window.h" +#include "ui/widgets/rp_window.h" #include "base/event_filter.h" #include "base/platform/base_platform_info.h" #include "base/debug_log.h" @@ -38,40 +38,40 @@ Backend Window::backend() const { return _backend; } -not_null Window::window() const { +not_null Window::window() const { return _window.get(); } -not_null Window::widget() const { +not_null Window::widget() const { return _body.get(); } -std::unique_ptr Window::createWindow() { - auto result = std::make_unique(); +std::unique_ptr Window::createWindow() { + auto result = std::make_unique(); if constexpr (!kUseNativeChild) { - const auto capabilities = Ui::GL::CheckCapabilities(result.get()); + const auto capabilities = 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; + LOG(("OpenGL: %1 (Window)").arg(use ? "[TRUE]" : "[FALSE]")); + _backend = use ? Backend::OpenGL : Backend::Raster; if (!use) { // We have to create a new window, if OpenGL initialization failed. - result = std::make_unique(); + result = std::make_unique(); } } return result; } -std::unique_ptr Window::createNativeBodyWrap() { +std::unique_ptr Window::createNativeBodyWrap() { if constexpr (!kUseNativeChild) { return nullptr; } const auto create = [] { - auto result = std::make_unique(); + auto result = std::make_unique(); result->setWindowFlags(Qt::FramelessWindowHint | Qt::Window); result->setAttribute(Qt::WA_NativeWindow); result->setAttribute(Qt::WA_DontCreateNativeAncestors); @@ -81,14 +81,14 @@ std::unique_ptr Window::createNativeBodyWrap() { }; auto result = create(); - const auto capabilities = Ui::GL::CheckCapabilities(result.get()); + const auto capabilities = 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; + LOG(("OpenGL: %1 (WindowBody)").arg(use ? "[TRUE]" : "[FALSE]")); + _backend = use ? Backend::OpenGL : Backend::Raster; if (!use) { // We have to create a new window, if OpenGL initialization failed. @@ -117,7 +117,7 @@ std::unique_ptr Window::createNativeBodyWrap() { const auto childWindow = raw->windowHandle(); base::install_event_filter(childWindow, [=](not_null event) { if (event->type() == QEvent::Expose && childWindow->isExposed()) { - Ui::Platform::SendWMPaintForce(_window.get()); + Platform::SendWMPaintForce(_window.get()); } return base::EventFilterResult::Continue; }); diff --git a/ui/gl/gl_window.h b/ui/gl/gl_window.h index bfa4199..797fcdf 100644 --- a/ui/gl/gl_window.h +++ b/ui/gl/gl_window.h @@ -8,7 +8,7 @@ namespace Ui { -class Window; +class RpWindow; class RpWidget; } // namespace Ui @@ -22,17 +22,17 @@ public: ~Window(); [[nodiscard]] Backend backend() const; - [[nodiscard]] not_null window() const; - [[nodiscard]] not_null widget() const; + [[nodiscard]] not_null window() const; + [[nodiscard]] not_null widget() const; private: - [[nodiscard]] std::unique_ptr createWindow(); - [[nodiscard]] std::unique_ptr createNativeBodyWrap(); + [[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; + Backend _backend = Backend(); + const std::unique_ptr _window; + const std::unique_ptr _bodyNativeWrap; + const not_null _body; }; diff --git a/ui/platform/mac/ui_window_mac.mm b/ui/platform/mac/ui_window_mac.mm index c8d8372..3bea72e 100644 --- a/ui/platform/mac/ui_window_mac.mm +++ b/ui/platform/mac/ui_window_mac.mm @@ -7,7 +7,7 @@ #include "ui/platform/mac/ui_window_mac.h" #include "ui/platform/mac/ui_window_title_mac.h" -#include "ui/widgets/window.h" +#include "ui/widgets/rp_window.h" #include "base/platform/base_platform_info.h" #include "styles/palette.h" diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 7583efb..aa3b0f1 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -8,7 +8,7 @@ #include "ui/platform/ui_platform_window_title.h" #include "ui/platform/ui_platform_utility.h" -#include "ui/widgets/window.h" +#include "ui/widgets/rp_window.h" #include "ui/widgets/shadow.h" #include "ui/painter.h" #include "styles/style_widgets.h" diff --git a/ui/widgets/window.cpp b/ui/widgets/rp_window.cpp similarity index 58% rename from ui/widgets/window.cpp rename to ui/widgets/rp_window.cpp index 90888b3..7adad8f 100644 --- a/ui/widgets/window.cpp +++ b/ui/widgets/rp_window.cpp @@ -4,13 +4,13 @@ // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // -#include "ui/widgets/window.h" +#include "ui/widgets/rp_window.h" #include "ui/platform/ui_platform_window.h" namespace Ui { -Window::Window(QWidget *parent) +RpWindow::RpWindow(QWidget *parent) : RpWidget(parent) , _helper(Platform::CreateWindowHelper(this)) { Expects(_helper != nullptr); @@ -18,57 +18,57 @@ Window::Window(QWidget *parent) hide(); } -Window::~Window() = default; +RpWindow::~RpWindow() = default; -not_null Window::body() { +not_null RpWindow::body() { return _helper->body(); } -not_null Window::body() const { +not_null RpWindow::body() const { return _helper->body().get(); } -void Window::setTitle(const QString &title) { +void RpWindow::setTitle(const QString &title) { _helper->setTitle(title); } -void Window::setTitleStyle(const style::WindowTitle &st) { +void RpWindow::setTitleStyle(const style::WindowTitle &st) { _helper->setTitleStyle(st); } -void Window::setNativeFrame(bool enabled) { +void RpWindow::setNativeFrame(bool enabled) { _helper->setNativeFrame(enabled); } -void Window::setMinimumSize(QSize size) { +void RpWindow::setMinimumSize(QSize size) { _helper->setMinimumSize(size); } -void Window::setFixedSize(QSize size) { +void RpWindow::setFixedSize(QSize size) { _helper->setFixedSize(size); } -void Window::setStaysOnTop(bool enabled) { +void RpWindow::setStaysOnTop(bool enabled) { _helper->setStaysOnTop(enabled); } -void Window::setGeometry(QRect rect) { +void RpWindow::setGeometry(QRect rect) { _helper->setGeometry(rect); } -void Window::showFullScreen() { +void RpWindow::showFullScreen() { _helper->showFullScreen(); } -void Window::showNormal() { +void RpWindow::showNormal() { _helper->showNormal(); } -void Window::close() { +void RpWindow::close() { _helper->close(); } -void Window::setBodyTitleArea( +void RpWindow::setBodyTitleArea( Fn testMethod) { _helper->setBodyTitleArea(std::move(testMethod)); } diff --git a/ui/widgets/window.h b/ui/widgets/rp_window.h similarity index 93% rename from ui/widgets/window.h rename to ui/widgets/rp_window.h index 2962c07..49524fd 100644 --- a/ui/widgets/window.h +++ b/ui/widgets/rp_window.h @@ -29,10 +29,10 @@ inline constexpr bool is_flag_type(WindowTitleHitTestFlag) { } using WindowTitleHitTestFlags = base::flags; -class Window : public RpWidget { +class RpWindow : public RpWidget { public: - explicit Window(QWidget *parent = nullptr); - ~Window(); + explicit RpWindow(QWidget *parent = nullptr); + ~RpWindow(); [[nodiscard]] not_null body(); [[nodiscard]] not_null body() const; From 868f2671fa9f0bf180eef0795d5c31d4ee4e3770 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 29 Jul 2021 18:12:44 +0300 Subject: [PATCH 13/20] Fix Ui::RpWidget geometry constraints. --- ui/platform/ui_platform_window.cpp | 21 ++++++++++++--------- ui/platform/ui_platform_window.h | 2 ++ ui/platform/win/ui_window_win.cpp | 20 ++++++++++++-------- ui/platform/win/ui_window_win.h | 1 + 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index aa3b0f1..959a03d 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -146,6 +146,7 @@ DefaultWindowHelper::DefaultWindowHelper(not_null window) } void DefaultWindowHelper::init() { + _title->show(); // Be consistent with _nativeFrame == false. window()->setWindowFlag(Qt::FramelessWindowHint); if (WindowExtentsSupported()) { @@ -327,24 +328,18 @@ void DefaultWindowHelper::setNativeFrame(bool enabled) { } void DefaultWindowHelper::setMinimumSize(QSize size) { - const auto sizeWithMargins = size - .grownBy({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 }) - .grownBy(resizeArea()); + const auto sizeWithMargins = size.grownBy(bodyPadding()); window()->setMinimumSize(sizeWithMargins); } void DefaultWindowHelper::setFixedSize(QSize size) { - const auto sizeWithMargins = size - .grownBy({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 }) - .grownBy(resizeArea()); + const auto sizeWithMargins = size.grownBy(bodyPadding()); window()->setFixedSize(sizeWithMargins); _title->setResizeEnabled(false); } void DefaultWindowHelper::setGeometry(QRect rect) { - window()->setGeometry(rect - .marginsAdded({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 }) - .marginsAdded(resizeArea())); + window()->setGeometry(rect.marginsAdded(bodyPadding())); } void DefaultWindowHelper::paintBorders(QPainter &p) { @@ -404,6 +399,14 @@ void DefaultWindowHelper::updateWindowExtents() { } } +int DefaultWindowHelper::titleHeight() const { + return _title->isHidden() ? 0 : _title->height(); +} + +QMargins DefaultWindowHelper::bodyPadding() const { + return resizeArea() + QMargins{ 0, titleHeight(), 0, 0 }; +} + void DefaultWindowHelper::updateCursor(Qt::Edges edges) { if (((edges & Qt::LeftEdge) && (edges & Qt::TopEdge)) || ((edges & Qt::RightEdge) && (edges & Qt::BottomEdge))) { diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index 60e102d..46bced2 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -84,6 +84,8 @@ private: void paintBorders(QPainter &p); void updateWindowExtents(); void updateCursor(Qt::Edges edges); + [[nodiscard]] int titleHeight() const; + [[nodiscard]] QMargins bodyPadding() const; const not_null _title; const not_null _body; diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 26bad2b..a1b2c59 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -151,7 +151,6 @@ WindowHelper::WindowHelper(not_null window) , _shadow(std::in_place, window, st::windowShadowFg->c) { Expects(_handle != nullptr); - GetNativeFilter()->registerWindow(_handle, this); init(); } @@ -186,13 +185,11 @@ void WindowHelper::setNativeFrame(bool enabled) { } void WindowHelper::setMinimumSize(QSize size) { - const auto titleHeight = _title->isVisible() ? _title->height() : 0; - window()->setMinimumSize(size.width(), titleHeight + size.height()); + window()->setMinimumSize(size.width(), titleHeight() + size.height()); } void WindowHelper::setFixedSize(QSize size) { - const auto titleHeight = _title->isVisible() ? _title->height() : 0; - window()->setFixedSize(size.width(), titleHeight + size.height()); + window()->setFixedSize(size.width(), titleHeight() + size.height()); _title->setResizeEnabled(false); if (_shadow) { _shadow->setResizeEnabled(false); @@ -200,8 +197,7 @@ void WindowHelper::setFixedSize(QSize size) { } void WindowHelper::setGeometry(QRect rect) { - const auto titleHeight = _title->isVisible() ? _title->height() : 0; - window()->setGeometry(rect.marginsAdded({ 0, titleHeight, 0, 0 })); + window()->setGeometry(rect.marginsAdded({ 0, titleHeight(), 0, 0 })); } void WindowHelper::showFullScreen() { @@ -221,6 +217,9 @@ void WindowHelper::showNormal() { } void WindowHelper::init() { + _title->show(); // Be consistent with _nativeFrame == false. + GetNativeFilter()->registerWindow(_handle, this); + style::PaletteChanged( ) | rpl::start_with_next([=] { if (_shadow) { @@ -429,7 +428,8 @@ bool WindowHelper::handleNativeEvent( p.y - r.top + _marginsDelta.top()); if (!window()->rect().contains(mapped)) { *result = HTTRANSPARENT; - } else if (!_title->isVisible() || !_title->geometry().contains(mapped)) { + } else if (_title->isHidden() + || !_title->geometry().contains(mapped)) { *result = HTCLIENT; } else switch (_title->hitTest(_title->pos() + mapped)) { case HitTestResult::Client: @@ -502,6 +502,10 @@ bool WindowHelper::fixedSize() const { return window()->minimumSize() == window()->maximumSize(); } +int WindowHelper::titleHeight() const { + return _title->isHidden() ? 0 : _title->height(); +} + void WindowHelper::updateMargins() { if (_updatingMargins) return; diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index cee1b22..da61530 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -47,6 +47,7 @@ private: LRESULT *result); [[nodiscard]] bool fixedSize() const; + [[nodiscard]] int titleHeight() const; static not_null GetNativeFilter(); const HWND _handle = nullptr; From 3f85ce53d68bae6ca090e3389dec035f1fae0db7 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Fri, 30 Jul 2021 18:13:53 +0400 Subject: [PATCH 14/20] Fix titlebar position when switching to custom frame --- ui/platform/ui_platform_window.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 959a03d..5034375 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -153,8 +153,10 @@ void DefaultWindowHelper::init() { window()->setAttribute(Qt::WA_TranslucentBackground); } - window()->widthValue( - ) | rpl::start_with_next([=](int width) { + rpl::combine( + window()->widthValue(), + _title->shownValue() + ) | rpl::start_with_next([=](int width, bool shown) { const auto area = resizeArea(); _title->setGeometry( area.left(), From 381bfc43c5ce414b1390e905bdac29772cbbb830 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sun, 8 Aug 2021 00:34:42 +0400 Subject: [PATCH 15/20] Subscribe window widget resize to window state changes --- ui/platform/ui_platform_window.cpp | 20 +++++++++++++------- ui/platform/ui_platform_window.h | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 5034375..8204170 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -155,8 +155,12 @@ void DefaultWindowHelper::init() { rpl::combine( window()->widthValue(), + _windowState.value(), _title->shownValue() - ) | rpl::start_with_next([=](int width, bool shown) { + ) | rpl::start_with_next([=]( + int width, + Qt::WindowStates windowState, + bool shown) { const auto area = resizeArea(); _title->setGeometry( area.left(), @@ -167,10 +171,12 @@ void DefaultWindowHelper::init() { rpl::combine( window()->sizeValue(), + _windowState.value(), _title->heightValue(), _title->shownValue() ) | rpl::start_with_next([=]( QSize size, + Qt::WindowStates windowState, int titleHeight, bool titleShown) { const auto area = resizeArea(); @@ -207,8 +213,10 @@ void DefaultWindowHelper::init() { } }, window()->lifetime()); - window()->shownValue( - ) | rpl::start_with_next([=](bool shown) { + rpl::combine( + window()->shownValue(), + _windowState.value() + ) | rpl::start_with_next([=](bool shown, Qt::WindowStates windowState) { if (shown) { updateWindowExtents(); } @@ -223,10 +231,8 @@ void DefaultWindowHelper::init() { if (mouseEvent->button() == Qt::LeftButton && edges) { window()->windowHandle()->startSystemResize(edges); } - } else if (e->type() == QEvent::Move - || e->type() == QEvent::Resize - || e->type() == QEvent::WindowStateChange) { - updateWindowExtents(); + } else if (e->type() == QEvent::WindowStateChange) { + _windowState = window()->windowState(); } }, window()->lifetime()); diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index 46bced2..c6d77b1 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -91,6 +91,7 @@ private: const not_null _body; bool _extentsSet = false; bool _nativeFrame = false; + rpl::variable _windowState = Qt::WindowNoState; }; From 98c7979e676ccac979f8447a25783afd646c52de Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sun, 8 Aug 2021 00:44:30 +0400 Subject: [PATCH 16/20] Get rid of _nativeFrame variable, _title->isHidden is enough --- ui/platform/ui_platform_window.cpp | 7 +++---- ui/platform/ui_platform_window.h | 1 - ui/platform/win/ui_window_win.cpp | 17 ++++++++--------- ui/platform/win/ui_window_win.h | 1 - 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 8204170..c2f5fc4 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -146,7 +146,7 @@ DefaultWindowHelper::DefaultWindowHelper(not_null window) } void DefaultWindowHelper::init() { - _title->show(); // Be consistent with _nativeFrame == false. + _title->show(); window()->setWindowFlag(Qt::FramelessWindowHint); if (WindowExtentsSupported()) { @@ -251,7 +251,7 @@ bool DefaultWindowHelper::hasShadow() const { QMargins DefaultWindowHelper::resizeArea() const { if (window()->isMaximized() || window()->isFullScreen() - || _nativeFrame) { + || _title->isHidden()) { return QMargins(); } @@ -329,7 +329,6 @@ void DefaultWindowHelper::setTitleStyle(const style::WindowTitle &st) { } void DefaultWindowHelper::setNativeFrame(bool enabled) { - _nativeFrame = enabled; window()->windowHandle()->setFlag(Qt::FramelessWindowHint, !enabled); _title->setVisible(!enabled); updateWindowExtents(); @@ -395,7 +394,7 @@ void DefaultWindowHelper::paintBorders(QPainter &p) { } void DefaultWindowHelper::updateWindowExtents() { - if (hasShadow() && !_nativeFrame) { + if (hasShadow() && !_title->isHidden()) { Platform::SetWindowExtents( window()->windowHandle(), resizeArea()); diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index c6d77b1..3580b11 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -90,7 +90,6 @@ private: const not_null _title; const not_null _body; bool _extentsSet = false; - bool _nativeFrame = false; rpl::variable _windowState = Qt::WindowNoState; }; diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index a1b2c59..3440f0f 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -172,7 +172,6 @@ void WindowHelper::setTitleStyle(const style::WindowTitle &st) { } void WindowHelper::setNativeFrame(bool enabled) { - _nativeFrame = enabled; _title->setVisible(!enabled); if (enabled) { _shadow.reset(); @@ -217,7 +216,7 @@ void WindowHelper::showNormal() { } void WindowHelper::init() { - _title->show(); // Be consistent with _nativeFrame == false. + _title->show(); GetNativeFilter()->registerWindow(_handle, this); style::PaletteChanged( @@ -290,14 +289,14 @@ bool WindowHelper::handleNativeEvent( } return false; case WM_NCPAINT: { - if (::Platform::IsWindows8OrGreater() || _nativeFrame) { + if (::Platform::IsWindows8OrGreater() || _title->isHidden()) { return false; } if (result) *result = 0; } return true; case WM_NCCALCSIZE: { - if (_nativeFrame) { + if (_title->isHidden()) { return false; } WINDOWPLACEMENT wp; @@ -343,7 +342,7 @@ bool WindowHelper::handleNativeEvent( } return true; case WM_NCACTIVATE: { - if (_nativeFrame) { + if (_title->isHidden()) { return false; } if (IsCompositionEnabled()) { @@ -416,7 +415,7 @@ bool WindowHelper::handleNativeEvent( } return false; case WM_NCHITTEST: { - if (!result || _nativeFrame) { + if (!result || _title->isHidden()) { return false; } @@ -449,7 +448,7 @@ bool WindowHelper::handleNativeEvent( } return true; case WM_NCRBUTTONUP: { - if (_nativeFrame) { + if (_title->isHidden()) { return false; } SendMessage(_handle, WM_SYSCOMMAND, SC_MOUSEMENU, lParam); @@ -566,9 +565,9 @@ void WindowHelper::updateMargins() { _marginsDelta = QMargins(); } - if (_isFullScreen || _nativeFrame) { + if (_isFullScreen || _title->isHidden()) { margins = QMargins(); - if (_nativeFrame) { + if (_title->isHidden()) { _marginsDelta = QMargins(); } } diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index da61530..d4c4055 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -58,7 +58,6 @@ private: QMargins _marginsDelta; HMENU _menu = nullptr; bool _isFullScreen = false; - bool _nativeFrame = false; }; From 7f15ac5f0e615fa2eb6aed9f71fdb574867d0a3e Mon Sep 17 00:00:00 2001 From: kvtb <76634406+kvtb@users.noreply.github.com> Date: Fri, 6 Aug 2021 06:36:05 +0000 Subject: [PATCH 17/20] fix compiling tdesktop with -DDESKTOP_APP_DISABLE_WAYLAND_INTEGRATION=ON --- ui/platform/linux/ui_linux_wayland_integration_dummy.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp b/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp index 13fafdb..0239433 100644 --- a/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp +++ b/ui/platform/linux/ui_linux_wayland_integration_dummy.cpp @@ -17,6 +17,8 @@ struct WaylandIntegration::Private { WaylandIntegration::WaylandIntegration() { } + +WaylandIntegration::~WaylandIntegration() = default; WaylandIntegration *WaylandIntegration::Instance() { if (!::Platform::IsWayland()) return nullptr; From 5c0066958bdd43ac44c2572c6590695b04dd6c5a Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 10 Aug 2021 13:12:21 +0300 Subject: [PATCH 18/20] Fix window shadow after native frame switch. --- ui/platform/win/ui_window_win.cpp | 13 +++++++++++++ ui/platform/win/ui_window_win.h | 1 + 2 files changed, 14 insertions(+) diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 3440f0f..1b3fac5 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -178,11 +178,22 @@ void WindowHelper::setNativeFrame(bool enabled) { } else { _shadow.emplace(window(), st::windowShadowFg->c); _shadow->setResizeEnabled(!fixedSize()); + initialShadowUpdate(); } updateMargins(); fixMaximizedWindow(); } +void WindowHelper::initialShadowUpdate() { + using Change = WindowShadow::Change; + const auto noShadowStates = (Qt::WindowMinimized | Qt::WindowMaximized); + if ((window()->windowState() & noShadowStates) || window()->isHidden()) { + _shadow->update(Change::Hidden); + } else { + _shadow->update(Change::Moved | Change::Resized | Change::Shown); + } +} + void WindowHelper::setMinimumSize(QSize size) { window()->setMinimumSize(size.width(), titleHeight() + size.height()); } @@ -265,6 +276,8 @@ void WindowHelper::init() { window()->windowHandle(), &QWindow::windowStateChanged, handleStateChanged); + + initialShadowUpdate(); } bool WindowHelper::handleNativeEvent( diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index d4c4055..955e156 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -39,6 +39,7 @@ private: void updateMargins(); void updateSystemMenu(); void updateSystemMenu(Qt::WindowState state); + void initialShadowUpdate(); void fixMaximizedWindow(); [[nodiscard]] bool handleNativeEvent( UINT msg, From 024f6fc1a970778a5a6393a8fcd847fd52760097 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 10 Aug 2021 15:04:30 +0300 Subject: [PATCH 19/20] Fix window frame glitches on Windows 7. --- ui/platform/win/ui_window_win.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 1b3fac5..2c72ddb 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -101,6 +101,24 @@ HRESULT WinApiSetWindowTheme( return method ? method(hWnd, pszSubAppName, pszSubIdList) : HRESULT(); } +void FixAeroSnap(HWND handle) { + SetWindowLongPtr( + handle, + GWL_STYLE, + GetWindowLongPtr(handle, GWL_STYLE) | WS_CAPTION | WS_THICKFRAME); +} + +[[nodiscard]] HWND ResolveWindowHandle(not_null widget) { + if (!::Platform::IsWindows8OrGreater()) { + widget->setWindowFlag(Qt::FramelessWindowHint); + } + const auto result = GetWindowHandle(widget); + if (!::Platform::IsWindows8OrGreater()) { + FixAeroSnap(result); + } + return result; +} + } // namespace class WindowHelper::NativeFilter final : public QAbstractNativeEventFilter { @@ -145,7 +163,7 @@ bool WindowHelper::NativeFilter::nativeEventFilter( WindowHelper::WindowHelper(not_null window) : BasicWindowHelper(window) -, _handle(GetWindowHandle(window)) +, _handle(ResolveWindowHandle(window)) , _title(Ui::CreateChild(window.get())) , _body(Ui::CreateChild(window.get())) , _shadow(std::in_place, window, st::windowShadowFg->c) { @@ -172,6 +190,12 @@ void WindowHelper::setTitleStyle(const style::WindowTitle &st) { } void WindowHelper::setNativeFrame(bool enabled) { + if (!::Platform::IsWindows8OrGreater()) { + window()->windowHandle()->setFlag(Qt::FramelessWindowHint, !enabled); + if (!enabled) { + FixAeroSnap(_handle); + } + } _title->setVisible(!enabled); if (enabled) { _shadow.reset(); From 1b590f9e16eb9571a039f072d6fea66c607e419f Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 11 Aug 2021 11:05:27 +0300 Subject: [PATCH 20/20] Expose topShownLayer from LayerStackWidget/LaayerManager. --- ui/layers/layer_manager.cpp | 4 ++++ ui/layers/layer_manager.h | 2 ++ ui/layers/layer_widget.cpp | 11 +++++++++++ ui/layers/layer_widget.h | 1 + 4 files changed, 18 insertions(+) diff --git a/ui/layers/layer_manager.cpp b/ui/layers/layer_manager.cpp index b5ca389..91e3e9e 100644 --- a/ui/layers/layer_manager.cpp +++ b/ui/layers/layer_manager.cpp @@ -59,6 +59,10 @@ bool LayerManager::setFocus() { return true; } +const LayerWidget *LayerManager::topShownLayer() const { + return _layer ? _layer->topShownLayer() : nullptr; +} + void LayerManager::ensureLayerCreated() { if (_layer) { return; diff --git a/ui/layers/layer_manager.h b/ui/layers/layer_manager.h index 4f53169..cce68dc 100644 --- a/ui/layers/layer_manager.h +++ b/ui/layers/layer_manager.h @@ -36,6 +36,8 @@ public: void raise(); bool setFocus(); + const LayerWidget *topShownLayer() const; + private: void ensureLayerCreated(); void destroyLayer(); diff --git a/ui/layers/layer_widget.cpp b/ui/layers/layer_widget.cpp index 5eb99f7..8e70249 100644 --- a/ui/layers/layer_widget.cpp +++ b/ui/layers/layer_widget.cpp @@ -458,6 +458,17 @@ bool LayerStackWidget::layerShown() const { return _specialLayer || currentLayer() || _mainMenu; } +const LayerWidget *LayerStackWidget::topShownLayer() const { + if (const auto result = currentLayer()) { + return result; + } else if (const auto special = _specialLayer.data()) { + return special; + } else if (const auto menu = _mainMenu.data()) { + return menu; + } + return nullptr; +} + void LayerStackWidget::setStyleOverrides( const style::Box *boxSt, const style::Box *layerSt) { diff --git a/ui/layers/layer_widget.h b/ui/layers/layer_widget.h index f45f16e..7d7e337 100644 --- a/ui/layers/layer_widget.h +++ b/ui/layers/layer_widget.h @@ -144,6 +144,7 @@ public: const ::Window::SectionShow ¶ms); bool layerShown() const; + const LayerWidget *topShownLayer() const; ~LayerStackWidget();