From 1b5b2e4c354df94fd0246f305a2b88d0013c81de Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Tue, 18 Apr 2006 20:32:10 +0000 Subject: [PATCH] MenuItems don't flicker anymore when a submenu opens (fixes bug 484). Implemented popupmenu's 'clickToOpenRect' feature, used by tracker's dirmenus, for example (fixes bug 523 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17168 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/Menu.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 3b2a599c9f..7072ceec9a 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1149,6 +1149,7 @@ BMenu::_track(int *action, bigtime_t trackTime, long start) bigtime_t closeTime = openTime; fState = MENU_ACT_NONE; + while (true) { bool locked = LockLooper(); if (!locked) @@ -1168,7 +1169,7 @@ BMenu::_track(int *action, bigtime_t trackTime, long start) openTime = system_time(); fState = MENU_ACT_NONE; snoozeAmount = 20000; - } else if (system_time() > kHysteresis + openTime && item->Submenu() + } else if (system_time() > kHysteresis + openTime && item->Submenu() != NULL && item->Submenu()->Window() == NULL) { // Open the submenu if it's not opened yet, but only if // the mouse pointer stayed over there for some time @@ -1214,7 +1215,8 @@ BMenu::_track(int *action, bigtime_t trackTime, long start) localAction = MENU_ACT_CLOSE; break; } else if (buttons == 0 && !IsStickyMode()) { - if (IsStickyPrefOn() && system_time() < trackTime + 1000000) + if (IsStickyPrefOn() && (system_time() < trackTime + 1000000 + || (fExtraRect != NULL && fExtraRect->Contains(location)))) SetStickyMode(true); else { localAction = MENU_ACT_CLOSE; @@ -1446,8 +1448,6 @@ BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, break; } - // This is for BMenuBar - if (_width) { if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) { if (Parent()) @@ -1724,17 +1724,22 @@ void BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem) { // TODO: make use of "selectFirstItem" - if (fSelected != NULL) { - fSelected->Select(false); - BMenu *subMenu = fSelected->Submenu(); - if (subMenu != NULL && subMenu->Window() != NULL) - subMenu->_hide(); + + // Avoid deselecting and then reselecting the same item + // which would cause flickering + if (menuItem != fSelected) { + if (fSelected != NULL) { + fSelected->Select(false); + BMenu *subMenu = fSelected->Submenu(); + if (subMenu != NULL && subMenu->Window() != NULL) + subMenu->_hide(); + } + + fSelected = menuItem; + if (fSelected != NULL) + fSelected->Select(true); } - if (menuItem != NULL) - menuItem->Select(true); - - fSelected = menuItem; if (fSelected != NULL && showSubmenu == 0) { BMenu *subMenu = fSelected->Submenu(); if (subMenu != NULL && subMenu->Window() == NULL)