diff --git a/ui/gl/gl_window.cpp b/ui/gl/gl_window.cpp index ed06f93..843915a 100644 --- a/ui/gl/gl_window.cpp +++ b/ui/gl/gl_window.cpp @@ -8,9 +8,15 @@ #include "ui/gl/gl_detection.h" #include "ui/widgets/window.h" +#include "base/event_filter.h" #include "base/platform/base_platform_info.h" #include "base/debug_log.h" +#ifdef Q_OS_WIN +#include "ui/platform/win/ui_window_win.h" +#endif // Q_OS_WIN + +#include #include namespace Ui::GL { @@ -98,6 +104,24 @@ std::unique_ptr Window::createNativeBodyWrap() { raw->show(); raw->update(); +#ifdef Q_OS_WIN + // In case a child native window fully covers the parent window, + // the system never sends a WM_PAINT message to the parent window. + // + // In this case if you minimize / hide the parent window, it receives + // QExposeEvent with isExposed() == false in window state change handler. + // + // But it never receives QExposeEvent with isExposed() == true, because + // window state change handler doesn't send it, instead the WM_PAINT is + // supposed to send it. No WM_PAINT -> no expose -> broken UI updating. + 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()); + } + return base::EventFilterResult::Continue; + }); + _window->sizeValue( ) | rpl::start_with_next([=](QSize size) { auto geometry = QRect(QPoint(), size); @@ -111,6 +135,7 @@ std::unique_ptr Window::createNativeBodyWrap() { } raw->setGeometry(geometry); }, raw->lifetime()); +#endif // Q_OS_WIN return result; } diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index bde97e8..2c9876f 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -604,6 +604,16 @@ HWND GetWindowHandle(not_null window) { window)); } +void SendWMPaintForce(not_null widget) { + const auto toplevel = widget->window(); + toplevel->createWinId(); + SendWMPaintForce(toplevel->windowHandle()); +} + +void SendWMPaintForce(not_null window) { + ::InvalidateRect(GetWindowHandle(window), nullptr, FALSE); +} + std::unique_ptr CreateSpecialWindowHelper( not_null window) { return std::make_unique(window); diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index 23bcc49..9abfe60 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -61,5 +61,8 @@ private: [[nodiscard]] HWND GetWindowHandle(not_null widget); [[nodiscard]] HWND GetWindowHandle(not_null window); +void SendWMPaintForce(not_null widget); +void SendWMPaintForce(not_null window); + } // namespace Platform } // namespace Ui