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
+9 -9
View File
@@ -589,8 +589,8 @@ TBarView::DragStart()
if (fExpando && fExpando->Frame().Contains(loc)) { if (fExpando && fExpando->Frame().Contains(loc)) {
ConvertToScreen(&loc); ConvertToScreen(&loc);
BPoint expandoloc = fExpando->ConvertFromScreen(loc); BPoint expandoLocation = fExpando->ConvertFromScreen(loc);
TTeamMenuItem *item = fExpando->ItemAtPoint(expandoloc); TTeamMenuItem *item = fExpando->TeamItemAtPoint(expandoLocation);
if (fLastDragItem) if (fLastDragItem)
init_tracking_hook(fLastDragItem, NULL, NULL); init_tracking_hook(fLastDragItem, NULL, NULL);
@@ -623,14 +623,14 @@ TBarView::MenuTrackingHook(BMenu *menu, void *castToThis)
BPoint location; BPoint location;
menu->GetMouse(&location, &buttons); menu->GetMouse(&location, &buttons);
bool returnvalue = true; bool endMenu = true;
BRect frame(menu->Bounds()); BRect frame(menu->Bounds());
frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin); frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin);
if (frame.Contains(location)) { if (frame.Contains(location)) {
// if current loc is still in the menu // if current loc is still in the menu
// keep tracking // keep tracking
returnvalue = false; endMenu = false;
} else { } else {
// see if the mouse is in the team/be menu item // see if the mouse is in the team/be menu item
menu->ConvertToScreen(&location); menu->ConvertToScreen(&location);
@@ -641,23 +641,23 @@ TBarView::MenuTrackingHook(BMenu *menu, void *castToThis)
if (bemenu && bemenu->LockLooper()) { if (bemenu && bemenu->LockLooper()) {
bemenu->ConvertFromScreen(&location); bemenu->ConvertFromScreen(&location);
if (bemenu->Frame().Contains(location)) if (bemenu->Frame().Contains(location))
returnvalue = false; endMenu = false;
bemenu->UnlockLooper(); bemenu->UnlockLooper();
} }
if (returnvalue && expando) { if (endMenu && expando) {
expando->ConvertFromScreen(&location); expando->ConvertFromScreen(&location);
TTeamMenuItem *item = expando->ItemAtPoint(location); BMenuItem *item = expando->TeamItemAtPoint(location);
if (item) if (item)
returnvalue = false; endMenu = false;
} }
barview->UnlockLooper(); barview->UnlockLooper();
} }
} }
menu->UnlockLooper(); menu->UnlockLooper();
return returnvalue; return endMenu;
} }
+39 -34
View File
@@ -278,8 +278,7 @@ TExpandoMenuBar::MessageReceived(BMessage *message)
break; break;
TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT, TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT,
item->Teams(), item->Teams(), item->Menu()->ConvertToScreen(item->Frame()),
item->Menu()->ConvertToScreen(item->Frame()),
true); true);
break; break;
} }
@@ -305,9 +304,9 @@ TExpandoMenuBar::MouseDown(BPoint where)
&& (modifiers & B_OPTION_KEY) != 0 && (modifiers & B_OPTION_KEY) != 0
&& (modifiers & B_SHIFT_KEY) != 0 && (modifiers & B_SHIFT_KEY) != 0
&& !fBarView->Dragging()) { && !fBarView->Dragging()) {
TTeamMenuItem *item = TeamItemAtPoint(where);
TTeamMenuItem *item = ItemAtPoint(where); if (item != NULL) {
if (item) {
const BList *teams = item->Teams(); const BList *teams = item->Teams();
int32 teamCount = teams->CountItems(); 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 // This feature is broken because the menu bar never receives
// the second click // the second click
#ifdef DOUBLECLICKBRINGSTOFRONT #ifdef DOUBLECLICKBRINGSTOFRONT
@@ -358,34 +355,22 @@ TExpandoMenuBar::MouseDown(BPoint where)
message->FindInt32("modifiers", &modifiers); message->FindInt32("modifiers", &modifiers);
if ((modifiers & B_CONTROL_KEY) != 0 if ((modifiers & B_CONTROL_KEY) != 0
&& ! fBarView->Dragging()) { && ! fBarView->Dragging()) {
int32 lastApp = -1; TTeamMenuItem *item = TeamItemAtPoint(where);
if (item != NULL) {
// find the clicked item // show/hide item's teams
for (int32 i = fFirstApp; i < count; i++) { BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
const TTeamMenuItem *item = (TTeamMenuItem *)ItemAt(i); ? M_MINIMIZE_TEAM : M_BRING_TEAM_TO_FRONT);
showMessage.AddInt32("itemIndex", IndexOf(item));
// check if this item is really a team item (what a cruel way...) Window()->PostMessage(&showMessage, this);
// "lastApp" will always point to the last application in return;
// 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;
}
} }
} }
} }
// Check the bounds of the expand Team icon // Check the bounds of the expand Team icon
if (fShowTeamExpander && fVertical && !fBarView->Dragging()) { if (fShowTeamExpander && fVertical && !fBarView->Dragging()) {
TTeamMenuItem *item = ItemAtPoint(where); TTeamMenuItem *item = TeamItemAtPoint(where);
if (item->Submenu()) { if (item != NULL) {
BRect expanderRect = item->ExpanderBounds(); BRect expanderRect = item->ExpanderBounds();
if (expanderRect.Contains(where)) { if (expanderRect.Contains(where)) {
// Let the update thread wait... // Let the update thread wait...
@@ -429,7 +414,7 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage *message)
case B_EXITED_VIEW: case B_EXITED_VIEW:
if (fBarView->Dragging() && buttons != 0) { if (fBarView->Dragging() && buttons != 0) {
if (!ItemAtPoint(where) if (!TeamItemAtPoint(where)
&& !InBeMenu(where) && !InBeMenu(where)
&& (fSeparatorItem && !fSeparatorItem->Frame().Contains(where)) && (fSeparatorItem && !fSeparatorItem->Frame().Contains(where))
&& !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 * TTeamMenuItem *
TExpandoMenuBar::ItemAtPoint(BPoint point) TExpandoMenuBar::TeamItemAtPoint(BPoint point, BMenuItem **_item)
{ {
TTeamMenuItem *item = NULL; TTeamMenuItem *lastApp = NULL;
int32 count = CountItems(); int32 count = CountItems();
for (int32 i = fFirstApp; i < count; i++) { for (int32 i = fFirstApp; i < count; i++) {
item = (TTeamMenuItem *)ItemAt(i); BMenuItem *item = ItemAt(i);
if (item && item->Frame().Contains(point))
return item; 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; return NULL;
} }
+4 -4
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. names are registered trademarks or trademarks of their respective holders.
All rights reserved. All rights reserved.
*/ */
#ifndef EXPANDOMENUBAR_H #ifndef EXPANDO_MENU_BAR_H
#define EXPANDOMENUBAR_H #define EXPANDO_MENU_BAR_H
// application list // application list
// top level at window // top level at window
@@ -70,8 +70,8 @@ class TExpandoMenuBar : public BMenuBar {
virtual void Draw(BRect update); virtual void Draw(BRect update);
virtual void DrawBackground(BRect update); virtual void DrawBackground(BRect update);
TTeamMenuItem *TeamItemAtPoint(BPoint location, BMenuItem **_item = NULL);
bool InBeMenu(BPoint) const; bool InBeMenu(BPoint) const;
TTeamMenuItem *ItemAtPoint(BPoint loc);
void CheckItemSizes(int32 delta); void CheckItemSizes(int32 delta);
@@ -113,4 +113,4 @@ class TExpandoMenuBar : public BMenuBar {
static BLocker sMonLocker; static BLocker sMonLocker;
}; };
#endif /* EXPANDOMENUBAR_H */ #endif /* EXPANDO_MENU_BAR_H */