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.
This commit is contained in:
Ilya Fedin 2022-05-26 00:33:02 +04:00 committed by John Preston
parent a714fb0070
commit ce35425670
6 changed files with 56 additions and 63 deletions

View file

@ -70,6 +70,13 @@ rpl::producer<HitTestResult> BasicWindowHelper::systemButtonDown() const {
return rpl::never<HitTestResult>();
}
bool BasicWindowHelper::nativeEvent(
const QByteArray &eventType,
void *message,
base::NativeEventResult *result) {
return false;
}
void BasicWindowHelper::setTitle(const QString &title) {
_window->setWindowTitle(title);
}

View file

@ -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<HitTestResult>;
[[nodiscard]] virtual auto systemButtonDown() const
-> rpl::producer<HitTestResult>;
[[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);

View file

@ -18,7 +18,6 @@
#include "styles/palette.h"
#include "styles/style_widgets.h"
#include <QtCore/QAbstractNativeEventFilter>
#include <QtGui/QWindow>
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QApplication>
@ -140,50 +139,6 @@ BOOL(__stdcall *AdjustWindowRectExForDpi)(
} // namespace
class WindowHelper::NativeFilter final : public QAbstractNativeEventFilter {
public:
void registerWindow(HWND handle, not_null<WindowHelper*> helper);
void unregisterWindow(HWND handle);
bool nativeEventFilter(
const QByteArray &eventType,
void *message,
long *result) override;
private:
base::flat_map<HWND, not_null<WindowHelper*>> _windowByHandle;
};
void WindowHelper::NativeFilter::registerWindow(
HWND handle,
not_null<WindowHelper*> 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<MSG*>(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<LRESULT*>(result));
});
}
return filtered;
}
WindowHelper::WindowHelper(not_null<RpWidget*> window)
: BasicWindowHelper(window)
, _handle(GetWindowHandle(window))
@ -196,7 +151,6 @@ WindowHelper::WindowHelper(not_null<RpWidget*> window)
}
WindowHelper::~WindowHelper() {
GetNativeFilter()->unregisterWindow(_handle);
}
void WindowHelper::initInWindow(not_null<RpWindow*> window) {
@ -350,7 +304,6 @@ rpl::producer<HitTestResult> 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<MSG*>(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::NativeFilter*> WindowHelper::GetNativeFilter() {
Expects(QCoreApplication::instance() != nullptr);
static const auto GlobalFilter = [&] {
const auto application = QCoreApplication::instance();
const auto filter = Ui::CreateChild<NativeFilter>(application);
application->installNativeEventFilter(filter);
return filter;
}();
return GlobalFilter;
}
HWND GetWindowHandle(not_null<QWidget*> widget) {
const auto toplevel = widget->window();
toplevel->createWinId();

View file

@ -44,10 +44,12 @@ public:
[[nodiscard]] auto systemButtonDown() const
-> rpl::producer<HitTestResult> 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<NativeFilter*> GetNativeFilter();
const HWND _handle = nullptr;
const not_null<TitleWidget*> _title;

View file

@ -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

View file

@ -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<WindowTitleHitTestFlags(QPoint)> testMethod);
protected:
bool nativeEvent(
const QByteArray &eventType,
void *message,
base::NativeEventResult *result) override;
private:
bool _initialized = false;
const std::unique_ptr<Platform::BasicWindowHelper> _helper;
};