The menus work a bit less good now I think, but they no longer have 100% CPU usage

when the menu item under the mouse cursor has a sub-menu.
Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16160 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-01-30 23:40:05 +00:00
parent badb1d4be6
commit ec549309c9
2 changed files with 52 additions and 66 deletions
+21 -21
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2005, Haiku, Inc. * Copyright 2001-2006, Haiku, Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -7,6 +7,7 @@
* Stefano Ceccherini ([email protected]) * Stefano Ceccherini ([email protected])
*/ */
#include <string.h> #include <string.h>
#include <Debug.h> #include <Debug.h>
@@ -1110,22 +1111,23 @@ BMenu::_track(int *action, long start)
ulong buttons; ulong buttons;
BMenuItem *item = NULL; BMenuItem *item = NULL;
int localAction = MENU_ACT_NONE; int localAction = MENU_ACT_NONE;
bigtime_t startTime = system_time(); bigtime_t startTime = system_time();
bigtime_t clickTime = 0; bigtime_t clickTime = 0;
get_click_speed(&clickTime); get_click_speed(&clickTime);
// TODO: Test and reduce the timeout if needed. // TODO: Test and reduce the timeout if needed.
clickTime /= 2; clickTime /= 2;
do { do {
if (!LockLooper()) if (!LockLooper())
break; break;
bigtime_t snoozeAmount = 50000; bigtime_t snoozeAmount = 50000;
BPoint location; BPoint location;
GetMouse(&location, &buttons, true); GetMouse(&location, &buttons, true);
BPoint screenLocation = ConvertToScreen(location);
item = HitTestItems(location, B_ORIGIN); item = HitTestItems(location, B_ORIGIN);
if (item != NULL) { if (item != NULL) {
if (item != fSelected) { if (item != fSelected) {
@@ -1140,18 +1142,18 @@ BMenu::_track(int *action, long start)
SelectItem(item); SelectItem(item);
} }
} else { } else {
if (OverSuper(location)) { if (OverSuper(screenLocation)) {
UnlockLooper(); UnlockLooper();
break; break;
} }
if (fSelected != NULL && !OverSubmenu(fSelected, ConvertToScreen(location))) if (fSelected != NULL && !OverSubmenu(fSelected, screenLocation))
SelectItem(NULL); SelectItem(NULL);
} }
if (fSelected != NULL && fSelected->Submenu() != NULL if (item != NULL && fSelected != NULL && OverSubmenu(fSelected, screenLocation)
&& fSelected->Submenu()->Window() != NULL) { && fSelected->Submenu()->Window() != NULL) {
UnlockLooper(); UnlockLooper();
int submenuAction = MENU_ACT_NONE; int submenuAction = MENU_ACT_NONE;
BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction); BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction);
if (submenuAction == MENU_ACT_CLOSE) { if (submenuAction == MENU_ACT_CLOSE) {
@@ -1159,31 +1161,31 @@ BMenu::_track(int *action, long start)
localAction = submenuAction; localAction = submenuAction;
break; break;
} }
if (!LockLooper()) if (!LockLooper())
break; break;
} }
UnlockLooper(); UnlockLooper();
snooze(snoozeAmount); snooze(snoozeAmount);
} while (buttons != 0); } while (buttons != 0);
if (localAction == MENU_ACT_NONE) { if (localAction == MENU_ACT_NONE) {
if (buttons != 0) if (buttons != 0)
localAction = MENU_ACT_NONE; localAction = MENU_ACT_NONE;
else else
localAction = MENU_ACT_CLOSE; localAction = MENU_ACT_CLOSE;
} }
if (action != NULL) if (action != NULL)
*action = localAction; *action = localAction;
if (LockLooper()) { if (LockLooper()) {
SelectItem(NULL); SelectItem(NULL);
UnlockLooper(); UnlockLooper();
} }
// delete the menu window recycled for all the child menus // delete the menu window recycled for all the child menus
DeleteMenuWindow(); DeleteMenuWindow();
@@ -1543,9 +1545,7 @@ BMenu::OverSuper(BPoint location)
{ {
if (!Supermenu()) if (!Supermenu())
return false; return false;
ConvertToScreen(&location);
return fSuperbounds.Contains(location); return fSuperbounds.Contains(location);
} }
@@ -1557,7 +1557,7 @@ BMenu::OverSubmenu(BMenuItem *item, BPoint loc)
BMenu *subMenu = item->Submenu(); BMenu *subMenu = item->Submenu();
if (subMenu == NULL || subMenu->Window() == NULL) if (subMenu == NULL || subMenu->Window() == NULL)
return false; return false;
if (subMenu->Window()->Frame().Contains(loc)) if (subMenu->Window()->Frame().Contains(loc))
return true; return true;
+31 -45
View File
@@ -1,29 +1,12 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2005, Haiku, Inc. * Copyright 2001-2006, Haiku, Inc.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Marc Flerackers (mflerackers@androme.be)
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Stefano Ceccherini (burton666@libero.it)
// and/or sell copies of the Software, and to permit persons to whom the */
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: Menubar.cpp
// Authors: Marc Flerackers ([email protected])
// Stefano Ceccherini ([email protected])
// Description: BMenuBar is a menu that's at the root of a menu hierarchy.
//------------------------------------------------------------------------------
// TODO: Finish this class // TODO: Finish this class
#include <Application.h> #include <Application.h>
@@ -36,8 +19,8 @@
#include <MenuPrivate.h> #include <MenuPrivate.h>
#include <TokenSpace.h> #include <TokenSpace.h>
struct menubar_data
{ struct menubar_data {
BMenuBar *menuBar; BMenuBar *menuBar;
int32 menuIndex; int32 menuIndex;
@@ -50,28 +33,28 @@ struct menubar_data
BMenuBar::BMenuBar(BRect frame, const char *title, uint32 resizeMask, BMenuBar::BMenuBar(BRect frame, const char *title, uint32 resizeMask,
menu_layout layout, bool resizeToFit) menu_layout layout, bool resizeToFit)
: BMenu(frame, title, resizeMask, : BMenu(frame, title, resizeMask,
B_WILL_DRAW | B_FRAME_EVENTS, layout, resizeToFit), B_WILL_DRAW | B_FRAME_EVENTS, layout, resizeToFit),
fBorder(B_BORDER_FRAME), fBorder(B_BORDER_FRAME),
fTrackingPID(-1), fTrackingPID(-1),
fPrevFocusToken(-1), fPrevFocusToken(-1),
fMenuSem(-1), fMenuSem(-1),
fLastBounds(NULL), fLastBounds(NULL),
fTracking(false) fTracking(false)
{ {
InitData(layout); InitData(layout);
} }
BMenuBar::BMenuBar(BMessage *data) BMenuBar::BMenuBar(BMessage *data)
: BMenu(data), : BMenu(data),
fBorder(B_BORDER_FRAME), fBorder(B_BORDER_FRAME),
fTrackingPID(-1), fTrackingPID(-1),
fPrevFocusToken(-1), fPrevFocusToken(-1),
fMenuSem(-1), fMenuSem(-1),
fLastBounds(NULL), fLastBounds(NULL),
fTracking(false) fTracking(false)
{ {
int32 border; int32 border;
@@ -412,7 +395,9 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
} }
} }
if (fSelected != NULL) { if (fSelected != NULL && OverSubmenu(fSelected, ConvertToScreen(where))) {
// call _track() from the selected sub-menu when the mouse cursor
// is over its window
BMenu *menu = fSelected->Submenu(); BMenu *menu = fSelected->Submenu();
if (menu != NULL) { if (menu != NULL) {
window->Unlock(); window->Unlock();
@@ -423,7 +408,8 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
if (!window->Lock())//WithTimeout(200000) < B_OK) if (!window->Lock())//WithTimeout(200000) < B_OK)
break; break;
} }
} } else if (menuItem == NULL)
SelectItem(NULL);
window->Unlock(); window->Unlock();