Fix ticket #8497.
- Rework Deskbar's handling for the autoraise/autohide cases to not need event masks. This prevents various problems that would occur if one happened to be working in another window that overlapped part of Deskbar, as reported in #8497. Instead, we now use a message filter to redirect the messages as needed.
This commit is contained in:
@@ -509,7 +509,6 @@ TBarApp::MessageReceived(BMessage* message)
|
||||
fSettings.autoHide = !fSettings.autoHide;
|
||||
|
||||
fBarWindow->Lock();
|
||||
fBarView->UpdateEventMask();
|
||||
fBarView->HideDeskbar(fSettings.autoHide);
|
||||
fBarWindow->Unlock();
|
||||
break;
|
||||
|
||||
@@ -70,6 +70,65 @@ const int32 kDefaultRecentAppCount = 10;
|
||||
const int32 kMenuTrackMargin = 20;
|
||||
|
||||
|
||||
class BarViewMessageFilter : public BMessageFilter
|
||||
{
|
||||
public:
|
||||
BarViewMessageFilter(TBarView* barView);
|
||||
virtual ~BarViewMessageFilter();
|
||||
|
||||
virtual filter_result Filter(BMessage* message, BHandler** target);
|
||||
|
||||
private:
|
||||
TBarView* fBarView;
|
||||
};
|
||||
|
||||
|
||||
BarViewMessageFilter::BarViewMessageFilter(TBarView* barView)
|
||||
:
|
||||
BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
|
||||
fBarView(barView)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BarViewMessageFilter::~BarViewMessageFilter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
BarViewMessageFilter::Filter(BMessage* message, BHandler** target)
|
||||
{
|
||||
if (message->what == B_MOUSE_DOWN || message->what == B_MOUSE_MOVED) {
|
||||
BPoint where = message->FindPoint("be:view_where");
|
||||
uint32 transit = message->FindInt32("be:transit");
|
||||
BMessage *dragMessage = NULL;
|
||||
if (message->HasMessage("be:drag_message")) {
|
||||
dragMessage = new BMessage();
|
||||
message->FindMessage("be:drag_message", dragMessage);
|
||||
}
|
||||
switch (message->what)
|
||||
{
|
||||
case B_MOUSE_DOWN:
|
||||
{
|
||||
fBarView->MouseDown(where);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_MOUSE_MOVED:
|
||||
{
|
||||
fBarView->MouseMoved(where, transit, dragMessage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
delete dragMessage;
|
||||
}
|
||||
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
|
||||
TBarView::TBarView(BRect frame, bool vertical, bool left, bool top,
|
||||
uint32 state, float)
|
||||
: BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
|
||||
@@ -112,7 +171,8 @@ TBarView::AttachedToWindow()
|
||||
SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR));
|
||||
SetFont(be_plain_font);
|
||||
|
||||
UpdateEventMask();
|
||||
Window()->AddCommonFilter(new BarViewMessageFilter(this));
|
||||
|
||||
UpdatePlacement();
|
||||
|
||||
fTrackingHookData.fTrackingHook = MenuTrackingHook;
|
||||
@@ -185,9 +245,6 @@ TBarView::MessageReceived(BMessage* message)
|
||||
void
|
||||
TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
|
||||
{
|
||||
if (Window() == NULL || EventMask() == 0)
|
||||
return;
|
||||
|
||||
desk_settings* settings = ((TBarApp*)be_app)->Settings();
|
||||
bool alwaysOnTop = settings->alwaysOnTop;
|
||||
bool autoRaise = settings->autoRaise;
|
||||
@@ -209,12 +266,18 @@ TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
|
||||
&& Window()->Frame().Contains(where)) {
|
||||
// cursor is on a screen edge within the window frame
|
||||
|
||||
if (!alwaysOnTop && autoRaise && !isTopMost)
|
||||
if (!alwaysOnTop && autoRaise && !isTopMost) {
|
||||
RaiseDeskbar(true);
|
||||
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
}
|
||||
|
||||
if (autoHide && IsHidden())
|
||||
HideDeskbar(false);
|
||||
} else {
|
||||
TBarWindow* window = (TBarWindow*)Window();
|
||||
if (window->IsShowingMenu())
|
||||
return;
|
||||
|
||||
// cursor is not on screen edge
|
||||
BRect preventHideArea = Window()->Frame().InsetByCopy(
|
||||
-kMaxPreventHidingDist, -kMaxPreventHidingDist);
|
||||
@@ -223,8 +286,10 @@ TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
|
||||
return;
|
||||
|
||||
// cursor to bar distance above threshold
|
||||
if (!alwaysOnTop && autoRaise && isTopMost)
|
||||
if (!alwaysOnTop && autoRaise && isTopMost) {
|
||||
RaiseDeskbar(false);
|
||||
SetEventMask(0);
|
||||
}
|
||||
|
||||
if (autoHide && !IsHidden())
|
||||
HideDeskbar(true);
|
||||
@@ -512,21 +577,6 @@ TBarView::SaveSettings()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TBarView::UpdateEventMask()
|
||||
{
|
||||
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
|
||||
#if 0
|
||||
desk_settings* settings = ((TBarApp*)be_app)->Settings();
|
||||
if (settings->autoRaise || settings->autoHide)
|
||||
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
else
|
||||
SetEventMask(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TBarView::UpdatePlacement()
|
||||
{
|
||||
|
||||
@@ -89,7 +89,6 @@ class TBarView : public BView {
|
||||
virtual void MouseDown(BPoint where);
|
||||
|
||||
void SaveSettings();
|
||||
void UpdateEventMask();
|
||||
void UpdatePlacement();
|
||||
void ChangeState(int32 state, bool vertical, bool left, bool top);
|
||||
void RaiseDeskbar(bool raise);
|
||||
|
||||
@@ -90,7 +90,8 @@ TBarWindow::TBarWindow()
|
||||
B_WILL_ACCEPT_FIRST_CLICK | B_NOT_ZOOMABLE | B_NOT_CLOSABLE
|
||||
| B_NOT_MINIMIZABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE
|
||||
| B_AVOID_FRONT | B_ASYNCHRONOUS_CONTROLS,
|
||||
B_ALL_WORKSPACES)
|
||||
B_ALL_WORKSPACES),
|
||||
fShowingMenu(false)
|
||||
{
|
||||
desk_settings* settings = ((TBarApp*)be_app)->Settings();
|
||||
if (settings->alwaysOnTop)
|
||||
@@ -139,13 +140,7 @@ TBarWindow::MenusBeginning()
|
||||
sDeskbarMenu->NeedsToRebuild();
|
||||
sDeskbarMenu->ResetTargets();
|
||||
|
||||
fBarView->SetEventMask(0);
|
||||
// This works around a BeOS bug - the menu is quit with every
|
||||
// B_MOUSE_DOWN the window receives.
|
||||
//
|
||||
// Is this bug still here? I commented this line out and didn't
|
||||
// notice anything different
|
||||
|
||||
fShowingMenu = true;
|
||||
BWindow::MenusBeginning();
|
||||
}
|
||||
|
||||
@@ -153,6 +148,7 @@ TBarWindow::MenusBeginning()
|
||||
void
|
||||
TBarWindow::MenusEnded()
|
||||
{
|
||||
fShowingMenu = false;
|
||||
BWindow::MenusEnded();
|
||||
|
||||
if (sDeskbarMenu->LockLooper()) {
|
||||
@@ -160,8 +156,6 @@ TBarWindow::MenusEnded()
|
||||
sDeskbarMenu->RemoveItems(0, sDeskbarMenu->CountItems(), true);
|
||||
sDeskbarMenu->UnlockLooper();
|
||||
}
|
||||
|
||||
fBarView->UpdateEventMask();
|
||||
}
|
||||
|
||||
|
||||
@@ -520,7 +514,7 @@ TBarWindow::CountItems(BMessage* message)
|
||||
void
|
||||
TBarWindow::AddItem(BMessage* message)
|
||||
{
|
||||
DeskbarShelf shelf = B_DESKBAR_TRAY;
|
||||
DeskbarShelf shelf = B_DESKBAR_TRAY;
|
||||
entry_ref ref;
|
||||
int32 id = 999;
|
||||
BMessage reply;
|
||||
@@ -596,6 +590,13 @@ TBarWindow::GetIconFrame(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TBarWindow::IsShowingMenu() const
|
||||
{
|
||||
return fShowingMenu;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TBarWindow::_IsFocusMessage(BMessage* message)
|
||||
{
|
||||
|
||||
@@ -83,12 +83,15 @@ public:
|
||||
|
||||
void GetIconFrame(BMessage* message);
|
||||
|
||||
bool IsShowingMenu() const;
|
||||
|
||||
private:
|
||||
bool _IsFocusMessage(BMessage* message);
|
||||
|
||||
private:
|
||||
static TDeskbarMenu* sDeskbarMenu;
|
||||
TBarView* fBarView;
|
||||
bool fShowingMenu;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user