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:
parent
a714fb0070
commit
ce35425670
6 changed files with 56 additions and 63 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue