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:
Axel Dörfler 2006-04-02 11:21:15 +00:00
parent 265242ecfa
commit 243fcbe279
3 changed files with 52 additions and 47 deletions

View File

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

View File

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

View File

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