From 285b7163ad41e00841d0dc28b48fe10902a350bc Mon Sep 17 00:00:00 2001 From: John Scipione Date: Tue, 8 Oct 2013 20:09:41 -0400 Subject: [PATCH] MenuField: Filter out additional MouseDown messages. ...while mouse is down on a menufield This makes it so that you can't open 2 menufields simultaneously by clicking and holding the right mouse button on one menufield while clicking a second with the the left mouse button opening it. This matches the behavior on BeOS R5. Should help with #6408 comment:9 --- headers/os/interface/MenuField.h | 7 ++- src/kits/interface/MenuField.cpp | 79 ++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 10 deletions(-) diff --git a/headers/os/interface/MenuField.h b/headers/os/interface/MenuField.h index dacd017178..55491d356e 100644 --- a/headers/os/interface/MenuField.h +++ b/headers/os/interface/MenuField.h @@ -10,6 +10,7 @@ class BMenuBar; +class BMessageFilter; class BMenuField : public BView { @@ -141,6 +142,9 @@ private: float _MenuBarOffset() const; float _MenuBarWidth() const; + void _DoneTracking(BPoint point); + void _Track(BPoint point, uint32); + private: char* fLabel; BMenu* fMenu; @@ -152,8 +156,9 @@ private: thread_id fMenuTaskID; LayoutData* fLayoutData; + BMessageFilter* fMouseDownFilter; - uint32 _reserved[3]; + uint32 _reserved[2]; }; #endif // _MENU_FIELD_H diff --git a/src/kits/interface/MenuField.cpp b/src/kits/interface/MenuField.cpp index ec50f3a0f2..7b41472b2e 100644 --- a/src/kits/interface/MenuField.cpp +++ b/src/kits/interface/MenuField.cpp @@ -19,19 +19,28 @@ #include #include +#include #include #include #include #include #include #include -#include +#include +#include #include #include #include +#ifdef CALLED +# undef CALLED +#endif +#ifdef TRACE +# undef TRACE +#endif + //#define TRACE_MENU_FIELD #ifdef TRACE_MENU_FIELD # include @@ -146,6 +155,38 @@ struct BMenuField::LayoutData { }; +// #pragma mark - MouseDownFilter + + +class MouseDownFilter : public BMessageFilter +{ +public: + MouseDownFilter(); + virtual ~MouseDownFilter(); + + virtual filter_result Filter(BMessage* message, BHandler** target); +}; + + +MouseDownFilter::MouseDownFilter() + : + BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE) +{ +} + + +MouseDownFilter::~MouseDownFilter() +{ +} + + +filter_result +MouseDownFilter::Filter(BMessage* message, BHandler** target) +{ + return message->what == B_MOUSE_DOWN ? B_SKIP_MESSAGE : B_DISPATCH_MESSAGE; +} + + // #pragma mark - BMenuField @@ -268,6 +309,7 @@ BMenuField::~BMenuField() wait_for_thread(fMenuTaskID, &dummy); delete fLayoutData; + delete fMouseDownFilter; } @@ -431,8 +473,13 @@ BMenuField::MouseDown(BPoint where) fMenuTaskID = spawn_thread((thread_func)_thread_entry, "_m_task_", B_NORMAL_PRIORITY, this); - if (fMenuTaskID >= 0) - resume_thread(fMenuTaskID); + if (fMenuTaskID >= 0 && resume_thread(fMenuTaskID) == B_OK) { + if (fMouseDownFilter->Looper() == NULL) + Window()->AddCommonFilter(fMouseDownFilter); + + MouseDownThread::TrackMouse(this, &BMenuField::_DoneTracking, + &BMenuField::_Track); + } } @@ -494,16 +541,16 @@ BMenuField::WindowActivated(bool state) void -BMenuField::MouseUp(BPoint point) +BMenuField::MouseMoved(BPoint point, uint32 code, const BMessage* message) { - BView::MouseUp(point); + BView::MouseMoved(point, code, message); } void -BMenuField::MouseMoved(BPoint point, uint32 code, const BMessage* message) +BMenuField::MouseUp(BPoint point) { - BView::MouseMoved(point, code, message); + BView::MouseUp(point); } @@ -956,6 +1003,7 @@ BMenuField::InitObject(const char* label) fFixedSizeMB = false; fMenuTaskID = -1; fLayoutData = new LayoutData; + fMouseDownFilter = new MouseDownFilter(); SetLabel(label); @@ -1285,7 +1333,20 @@ BMenuField::_MenuBarWidth() const } -// #pragma mark - +void +BMenuField::_DoneTracking(BPoint point) +{ + Window()->RemoveCommonFilter(fMouseDownFilter); +} + + +void +BMenuField::_Track(BPoint point, uint32) +{ +} + + +// #pragma mark - BMenuField::LabelLayoutItem BMenuField::LabelLayoutItem::LabelLayoutItem(BMenuField* parent) @@ -1405,7 +1466,7 @@ BMenuField::LabelLayoutItem::Instantiate(BMessage* from) } -// #pragma mark - +// #pragma mark - BMenuField::MenuBarLayoutItem BMenuField::MenuBarLayoutItem::MenuBarLayoutItem(BMenuField* parent)