Since SF cannot be reached currently, this fix gets into the Haiku tree first:
ExpandoMenuBar::ItemAtPoint() was broken, which could cause a crash when doing the "vulcan death grip" over a window item. This fixes bug #379. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16964 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
265242ecfa
commit
243fcbe279
@ -589,8 +589,8 @@ TBarView::DragStart()
|
||||
|
||||
if (fExpando && fExpando->Frame().Contains(loc)) {
|
||||
ConvertToScreen(&loc);
|
||||
BPoint expandoloc = fExpando->ConvertFromScreen(loc);
|
||||
TTeamMenuItem *item = fExpando->ItemAtPoint(expandoloc);
|
||||
BPoint expandoLocation = fExpando->ConvertFromScreen(loc);
|
||||
TTeamMenuItem *item = fExpando->TeamItemAtPoint(expandoLocation);
|
||||
|
||||
if (fLastDragItem)
|
||||
init_tracking_hook(fLastDragItem, NULL, NULL);
|
||||
@ -623,14 +623,14 @@ TBarView::MenuTrackingHook(BMenu *menu, void *castToThis)
|
||||
BPoint location;
|
||||
menu->GetMouse(&location, &buttons);
|
||||
|
||||
bool returnvalue = true;
|
||||
bool endMenu = true;
|
||||
BRect frame(menu->Bounds());
|
||||
frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin);
|
||||
|
||||
if (frame.Contains(location)) {
|
||||
// if current loc is still in the menu
|
||||
// keep tracking
|
||||
returnvalue = false;
|
||||
endMenu = false;
|
||||
} else {
|
||||
// see if the mouse is in the team/be menu item
|
||||
menu->ConvertToScreen(&location);
|
||||
@ -641,23 +641,23 @@ TBarView::MenuTrackingHook(BMenu *menu, void *castToThis)
|
||||
if (bemenu && bemenu->LockLooper()) {
|
||||
bemenu->ConvertFromScreen(&location);
|
||||
if (bemenu->Frame().Contains(location))
|
||||
returnvalue = false;
|
||||
endMenu = false;
|
||||
|
||||
bemenu->UnlockLooper();
|
||||
}
|
||||
|
||||
if (returnvalue && expando) {
|
||||
if (endMenu && expando) {
|
||||
expando->ConvertFromScreen(&location);
|
||||
TTeamMenuItem *item = expando->ItemAtPoint(location);
|
||||
BMenuItem *item = expando->TeamItemAtPoint(location);
|
||||
if (item)
|
||||
returnvalue = false;
|
||||
endMenu = false;
|
||||
}
|
||||
barview->UnlockLooper();
|
||||
}
|
||||
}
|
||||
|
||||
menu->UnlockLooper();
|
||||
return returnvalue;
|
||||
return endMenu;
|
||||
}
|
||||
|
||||
|
||||
|
@ -278,8 +278,7 @@ TExpandoMenuBar::MessageReceived(BMessage *message)
|
||||
break;
|
||||
|
||||
TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT,
|
||||
item->Teams(),
|
||||
item->Menu()->ConvertToScreen(item->Frame()),
|
||||
item->Teams(), item->Menu()->ConvertToScreen(item->Frame()),
|
||||
true);
|
||||
break;
|
||||
}
|
||||
@ -305,9 +304,9 @@ TExpandoMenuBar::MouseDown(BPoint where)
|
||||
&& (modifiers & B_OPTION_KEY) != 0
|
||||
&& (modifiers & B_SHIFT_KEY) != 0
|
||||
&& !fBarView->Dragging()) {
|
||||
TTeamMenuItem *item = TeamItemAtPoint(where);
|
||||
|
||||
TTeamMenuItem *item = ItemAtPoint(where);
|
||||
if (item) {
|
||||
if (item != NULL) {
|
||||
const BList *teams = item->Teams();
|
||||
int32 teamCount = teams->CountItems();
|
||||
|
||||
@ -325,8 +324,6 @@ TExpandoMenuBar::MouseDown(BPoint where)
|
||||
}
|
||||
}
|
||||
|
||||
const int32 count = CountItems();
|
||||
|
||||
// This feature is broken because the menu bar never receives
|
||||
// the second click
|
||||
#ifdef DOUBLECLICKBRINGSTOFRONT
|
||||
@ -358,34 +355,22 @@ TExpandoMenuBar::MouseDown(BPoint where)
|
||||
message->FindInt32("modifiers", &modifiers);
|
||||
if ((modifiers & B_CONTROL_KEY) != 0
|
||||
&& ! fBarView->Dragging()) {
|
||||
int32 lastApp = -1;
|
||||
|
||||
// find the clicked item
|
||||
for (int32 i = fFirstApp; i < count; i++) {
|
||||
const TTeamMenuItem *item = (TTeamMenuItem *)ItemAt(i);
|
||||
|
||||
// check if this item is really a team item (what a cruel way...)
|
||||
// "lastApp" will always point to the last application in
|
||||
// the list - the other entries might be windows (due to the team expander)
|
||||
if (item->Submenu())
|
||||
lastApp = i;
|
||||
|
||||
if (item->Frame().Contains(where)) {
|
||||
// show/hide item's teams
|
||||
BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
|
||||
? M_MINIMIZE_TEAM : M_BRING_TEAM_TO_FRONT);
|
||||
showMessage.AddInt32("itemIndex", lastApp);
|
||||
Window()->PostMessage(&showMessage, this);
|
||||
return;
|
||||
}
|
||||
TTeamMenuItem *item = TeamItemAtPoint(where);
|
||||
if (item != NULL) {
|
||||
// show/hide item's teams
|
||||
BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
|
||||
? M_MINIMIZE_TEAM : M_BRING_TEAM_TO_FRONT);
|
||||
showMessage.AddInt32("itemIndex", IndexOf(item));
|
||||
Window()->PostMessage(&showMessage, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the bounds of the expand Team icon
|
||||
if (fShowTeamExpander && fVertical && !fBarView->Dragging()) {
|
||||
TTeamMenuItem *item = ItemAtPoint(where);
|
||||
if (item->Submenu()) {
|
||||
TTeamMenuItem *item = TeamItemAtPoint(where);
|
||||
if (item != NULL) {
|
||||
BRect expanderRect = item->ExpanderBounds();
|
||||
if (expanderRect.Contains(where)) {
|
||||
// Let the update thread wait...
|
||||
@ -429,7 +414,7 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage *message)
|
||||
|
||||
case B_EXITED_VIEW:
|
||||
if (fBarView->Dragging() && buttons != 0) {
|
||||
if (!ItemAtPoint(where)
|
||||
if (!TeamItemAtPoint(where)
|
||||
&& !InBeMenu(where)
|
||||
&& (fSeparatorItem && !fSeparatorItem->Frame().Contains(where))
|
||||
&& !Frame().Contains(where))
|
||||
@ -461,17 +446,37 @@ TExpandoMenuBar::InBeMenu(BPoint loc) const
|
||||
}
|
||||
|
||||
|
||||
/** Returns the team menu item that belongs to the item under the
|
||||
* specified \a point.
|
||||
* If \a _item is given, it will return the exact menu item under
|
||||
* that point (which might be a window item when the expander is on).
|
||||
*/
|
||||
|
||||
TTeamMenuItem *
|
||||
TExpandoMenuBar::ItemAtPoint(BPoint point)
|
||||
TExpandoMenuBar::TeamItemAtPoint(BPoint point, BMenuItem **_item)
|
||||
{
|
||||
TTeamMenuItem *item = NULL;
|
||||
TTeamMenuItem *lastApp = NULL;
|
||||
int32 count = CountItems();
|
||||
|
||||
for (int32 i = fFirstApp; i < count; i++) {
|
||||
item = (TTeamMenuItem *)ItemAt(i);
|
||||
if (item && item->Frame().Contains(point))
|
||||
return item;
|
||||
BMenuItem *item = ItemAt(i);
|
||||
|
||||
if (dynamic_cast<TTeamMenuItem *>(item) != NULL)
|
||||
lastApp = (TTeamMenuItem *)item;
|
||||
|
||||
if (item && item->Frame().Contains(point)) {
|
||||
if (_item != NULL)
|
||||
*_item = item;
|
||||
|
||||
return lastApp;
|
||||
}
|
||||
}
|
||||
|
||||
// no item found
|
||||
|
||||
if (_item != NULL)
|
||||
*_item = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ of Be Incorporated in the United States and other countries. Other brand product
|
||||
names are registered trademarks or trademarks of their respective holders.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef EXPANDOMENUBAR_H
|
||||
#define EXPANDOMENUBAR_H
|
||||
#ifndef EXPANDO_MENU_BAR_H
|
||||
#define EXPANDO_MENU_BAR_H
|
||||
|
||||
// application list
|
||||
// top level at window
|
||||
@ -70,8 +70,8 @@ class TExpandoMenuBar : public BMenuBar {
|
||||
virtual void Draw(BRect update);
|
||||
virtual void DrawBackground(BRect update);
|
||||
|
||||
TTeamMenuItem *TeamItemAtPoint(BPoint location, BMenuItem **_item = NULL);
|
||||
bool InBeMenu(BPoint) const;
|
||||
TTeamMenuItem *ItemAtPoint(BPoint loc);
|
||||
|
||||
void CheckItemSizes(int32 delta);
|
||||
|
||||
@ -113,4 +113,4 @@ class TExpandoMenuBar : public BMenuBar {
|
||||
static BLocker sMonLocker;
|
||||
};
|
||||
|
||||
#endif /* EXPANDOMENUBAR_H */
|
||||
#endif /* EXPANDO_MENU_BAR_H */
|
||||
|
Loading…
Reference in New Issue
Block a user