From ce35425670d01e51aa26849a20ae721c09b38cf9 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Thu, 26 May 2022 00:33:02 +0400 Subject: [PATCH] Simplify Windows native event filter There's no need for a global event filter as it checks for the window hwnd anyway. And, moreover, that creates problems as Qt filters some events to global event filters. --- ui/platform/ui_platform_window.cpp | 7 +++ ui/platform/ui_platform_window.h | 5 ++ ui/platform/win/ui_window_win.cpp | 75 +++++++----------------------- ui/platform/win/ui_window_win.h | 9 ++-- ui/widgets/rp_window.cpp | 15 ++++++ ui/widgets/rp_window.h | 8 ++++ 6 files changed, 56 insertions(+), 63 deletions(-) diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index cf002e5..ec46060 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -70,6 +70,13 @@ rpl::producer BasicWindowHelper::systemButtonDown() const { return rpl::never(); } +bool BasicWindowHelper::nativeEvent( + const QByteArray &eventType, + void *message, + base::NativeEventResult *result) { + return false; +} + void BasicWindowHelper::setTitle(const QString &title) { _window->setWindowTitle(title); } diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index e34f1d7..eadcbca 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -8,6 +8,7 @@ #include "base/flags.h" #include "base/object_ptr.h" +#include "base/qt/qt_common_adapters.h" #include "ui/round_rect.h" namespace style { @@ -48,6 +49,10 @@ public: -> rpl::producer; [[nodiscard]] virtual auto systemButtonDown() const -> rpl::producer; + [[nodiscard]] virtual bool nativeEvent( + const QByteArray &eventType, + void *message, + base::NativeEventResult *result); virtual void setTitle(const QString &title); virtual void setTitleStyle(const style::WindowTitle &st); virtual void setNativeFrame(bool enabled); diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 9042cfb..2566674 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -18,7 +18,6 @@ #include "styles/palette.h" #include "styles/style_widgets.h" -#include #include #include #include @@ -140,50 +139,6 @@ BOOL(__stdcall *AdjustWindowRectExForDpi)( } // namespace -class WindowHelper::NativeFilter final : public QAbstractNativeEventFilter { -public: - void registerWindow(HWND handle, not_null helper); - void unregisterWindow(HWND handle); - - bool nativeEventFilter( - const QByteArray &eventType, - void *message, - long *result) override; - -private: - base::flat_map> _windowByHandle; - -}; - -void WindowHelper::NativeFilter::registerWindow( - HWND handle, - not_null helper) { - _windowByHandle.emplace(handle, helper); -} - -void WindowHelper::NativeFilter::unregisterWindow(HWND handle) { - _windowByHandle.remove(handle); -} - -bool WindowHelper::NativeFilter::nativeEventFilter( - const QByteArray &eventType, - void *message, - long *result) { - auto filtered = false; - const auto msg = static_cast(message); - const auto i = _windowByHandle.find(msg->hwnd); - if (i != end(_windowByHandle)) { - base::Integration::Instance().enterFromEventLoop([&] { - filtered = i->second->handleNativeEvent( - msg->message, - msg->wParam, - msg->lParam, - reinterpret_cast(result)); - }); - } - return filtered; -} - WindowHelper::WindowHelper(not_null window) : BasicWindowHelper(window) , _handle(GetWindowHandle(window)) @@ -196,7 +151,6 @@ WindowHelper::WindowHelper(not_null window) } WindowHelper::~WindowHelper() { - GetNativeFilter()->unregisterWindow(_handle); } void WindowHelper::initInWindow(not_null window) { @@ -350,7 +304,6 @@ rpl::producer WindowHelper::systemButtonDown() const { void WindowHelper::init() { _title->show(); - GetNativeFilter()->registerWindow(_handle, this); style::PaletteChanged( ) | rpl::start_with_next([=] { @@ -479,6 +432,22 @@ void WindowHelper::init() { updateCornersRounding(); } +bool WindowHelper::nativeEvent( + const QByteArray &eventType, + void *message, + base::NativeEventResult *result) { + const auto msg = static_cast(message); + auto lresult = LRESULT(*result); + const auto guard = gsl::finally([&] { + *result = base::NativeEventResult(lresult); + }); + return handleNativeEvent( + msg->message, + msg->wParam, + msg->lParam, + &lresult); +} + bool WindowHelper::handleNativeEvent( UINT msg, WPARAM wParam, @@ -882,18 +851,6 @@ void WindowHelper::updateFrameMargins() { _frameMargins = QMargins(0, -r.top, 0, 0) / window()->devicePixelRatioF(); } -not_null WindowHelper::GetNativeFilter() { - Expects(QCoreApplication::instance() != nullptr); - - static const auto GlobalFilter = [&] { - const auto application = QCoreApplication::instance(); - const auto filter = Ui::CreateChild(application); - application->installNativeEventFilter(filter); - return filter; - }(); - return GlobalFilter; -} - HWND GetWindowHandle(not_null widget) { const auto toplevel = widget->window(); toplevel->createWinId(); diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index 5cd022e..fb651a4 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -44,10 +44,12 @@ public: [[nodiscard]] auto systemButtonDown() const -> rpl::producer override; -private: - class NativeFilter; - friend class NativeFilter; + [[nodiscard]] bool nativeEvent( + const QByteArray &eventType, + void *message, + base::NativeEventResult *result) override; +private: void init(); void updateFrameMargins(); void updateWindowFrameColors(); @@ -70,7 +72,6 @@ private: [[nodiscard]] HitTestResult systemButtonHitTest(int result) const; [[nodiscard]] int titleHeight() const; - static not_null GetNativeFilter(); const HWND _handle = nullptr; const not_null _title; diff --git a/ui/widgets/rp_window.cpp b/ui/widgets/rp_window.cpp index d1c38a6..f1dc292 100644 --- a/ui/widgets/rp_window.cpp +++ b/ui/widgets/rp_window.cpp @@ -17,6 +17,8 @@ RpWindow::RpWindow(QWidget *parent) _helper->initInWindow(this); hide(); + + _initialized = true; } RpWindow::~RpWindow() = default; @@ -99,4 +101,17 @@ void RpWindow::setBodyTitleArea( _helper->setBodyTitleArea(std::move(testMethod)); } +bool RpWindow::nativeEvent( + const QByteArray &eventType, + void *message, + base::NativeEventResult *result) { + if (_initialized && _helper->nativeEvent( + eventType, + message, + result)) { + return true; + } + return RpWidget::nativeEvent(eventType, message, result); +} + } // namespace Ui diff --git a/ui/widgets/rp_window.h b/ui/widgets/rp_window.h index 04b4d99..77311fc 100644 --- a/ui/widgets/rp_window.h +++ b/ui/widgets/rp_window.h @@ -8,6 +8,7 @@ #include "ui/rp_widget.h" #include "base/flags.h" +#include "base/qt/qt_common_adapters.h" namespace style { struct WindowTitle; @@ -67,7 +68,14 @@ public: void close(); void setBodyTitleArea(Fn testMethod); +protected: + bool nativeEvent( + const QByteArray &eventType, + void *message, + base::NativeEventResult *result) override; + private: + bool _initialized = false; const std::unique_ptr _helper; };