Ticket #4930: menu-kb-nav.patch
File menu-kb-nav.patch, 5.6 KB (added by , 14 years ago) |
---|
-
../src/kits/interface/Menu.cpp
372 372 // when called on input_server initialization, since it tries 373 373 // to send a synchronous message to itself (input_server is 374 374 // a BApplication) 375 376 375 BMenu::sAltAsCommandKey = true; 377 376 key_map* keys = NULL; 378 377 char* chars = NULL; … … 383 382 free(chars); 384 383 free(keys); 385 384 386 BMenuItem* superItem = Superitem(); 387 BMenu* superMenu = Supermenu(); 388 if (AddDynamicItem(B_INITIAL_ADD)) { 389 do { 390 if (superMenu != NULL && !superMenu->_OkToProceed(superItem)) { 391 AddDynamicItem(B_ABORT); 392 fAttachAborted = true; 393 break; 394 } 395 } while (AddDynamicItem(B_PROCESSING)); 396 } 397 398 if (!fAttachAborted) { 399 _CacheFontInfo(); 400 _LayoutItems(0); 401 _UpdateWindowViewSize(false); 402 } 385 _CacheFontInfo(); 386 _LayoutItems(0); 387 _UpdateWindowViewSize(false); 403 388 } 404 389 405 390 … … 515 500 _SelectNextItem(fSelected, true); 516 501 else { 517 502 if (fSelected && fSelected->Submenu()) { 518 _SelectItem(fSelected, true, true); 503 fSelected->Submenu()->_SetStickyMode(true); 504 // fix me: this shouldn't be needed but dynamic menus 505 // aren't getting it set correctly when keyboard 506 // navigating, which aborts the attach 507 _SelectItem(fSelected, true, true, true); 519 508 } else if (dynamic_cast<BMenuBar*>(Supermenu())) { 520 509 // if we have no submenu and we're an 521 510 // item in the top menu below the menubar, … … 1462 1451 1463 1452 1464 1453 bool 1465 BMenu::_Show(bool selectFirstItem )1454 BMenu::_Show(bool selectFirstItem, bool keyDown) 1466 1455 { 1467 1456 // See if the supermenu has a cached menuwindow, 1468 1457 // and use that one if possible. … … 1487 1476 1488 1477 if (window->Lock()) { 1489 1478 fAttachAborted = false; 1490 window->AttachMenu(this);1491 1479 1492 if (ItemAt(0) != NULL) { 1493 float width, height; 1494 ItemAt(0)->GetContentSize(&width, &height); 1495 1496 window->SetSmallStep(ceilf(height)); 1480 BMenuItem* superItem = Superitem(); 1481 BMenu* superMenu = Supermenu(); 1482 if (AddDynamicItem(B_INITIAL_ADD)) { 1483 do { 1484 if (superMenu != NULL 1485 && !superMenu->_OkToProceed(superItem, keyDown)) { 1486 AddDynamicItem(B_ABORT); 1487 fAttachAborted = true; 1488 break; 1489 } 1490 } while (AddDynamicItem(B_PROCESSING)); 1497 1491 } 1498 1492 1493 if (!fAttachAborted) { 1494 window->AttachMenu(this); 1495 1496 if (ItemAt(0) != NULL) { 1497 float width, height; 1498 ItemAt(0)->GetContentSize(&width, &height); 1499 window->SetSmallStep(ceilf(height)); 1500 } 1501 } else { 1499 1502 // Menu didn't have the time to add its items: aborting... 1500 if (fAttachAborted) {1501 window->DetachMenu();1502 // TODO: Probably not needed, we can just let _hide() quit the1503 // window.1504 1503 if (ourWindow) 1505 1504 window->Quit(); 1506 1505 else … … 2499 2498 2500 2499 2501 2500 void 2502 BMenu::_SelectItem(BMenuItem* menuItem, bool showSubmenu, bool selectFirstItem) 2501 BMenu::_SelectItem(BMenuItem* menuItem, bool showSubmenu, 2502 bool selectFirstItem, bool keyDown) 2503 2503 { 2504 2504 // Avoid deselecting and then reselecting the same item 2505 2505 // which would cause flickering … … 2519 2519 if (fSelected != NULL && showSubmenu) { 2520 2520 BMenu* subMenu = fSelected->Submenu(); 2521 2521 if (subMenu != NULL && subMenu->Window() == NULL) { 2522 if (!subMenu->_Show(selectFirstItem )) {2522 if (!subMenu->_Show(selectFirstItem, keyDown)) { 2523 2523 // something went wrong, deselect the item 2524 2524 fSelected->Select(false); 2525 2525 fSelected = NULL; … … 2729 2729 2730 2730 2731 2731 bool 2732 BMenu::_OkToProceed(BMenuItem* item )2732 BMenu::_OkToProceed(BMenuItem* item, bool keyDown) 2733 2733 { 2734 2734 BPoint where; 2735 2735 ulong buttons; … … 2742 2742 // BeOS seems to do something similar. This could also be a bug in 2743 2743 // Deskbar, though. 2744 2744 if ((buttons != 0 && stickyMode) 2745 || ((dynamic_cast<BMenuBar*>(this) == NULL 2746 && (buttons == 0 && !stickyMode)) || _HitTestItems(where) != item)) 2745 || (dynamic_cast<BMenuBar*>(this) == NULL 2746 && (buttons == 0 && !stickyMode)) 2747 || ((_HitTestItems(where) != item) && !keyDown)) 2747 2748 return false; 2748 2749 2749 2750 return true; -
../headers/os/interface/Menu.h
183 183 BMenu& operator=(const BMenu& other); 184 184 185 185 void _InitData(BMessage* archive); 186 bool _Show(bool selectFirstItem = false); 186 bool _Show(bool selectFirstItem = false, 187 bool keyDown = false); 187 188 void _Hide(); 188 189 BMenuItem* _Track(int* action, long start = -1); 189 190 … … 212 213 void _ComputeColumnLayout(int32 index, bool bestFit, 213 214 bool moveItems, BRect& outRect); 214 215 void _ComputeRowLayout(int32 index, bool bestFit, 215 bool moveItems, BRect& outRect); 216 bool moveItems, BRect& outRect); 216 217 void _ComputeMatrixLayout(BRect& outRect); 217 218 218 219 BRect _CalcFrame(BPoint where, bool* scrollOn); … … 235 236 void _Uninstall(); 236 237 void _SelectItem(BMenuItem* item, 237 238 bool showSubmenu = true, 238 bool selectFirstItem = false); 239 bool selectFirstItem = false, 240 bool keyDown = false); 239 241 bool _SelectNextItem(BMenuItem* item, bool forward); 240 242 BMenuItem* _NextItem(BMenuItem* item, bool forward) const; 241 243 void _SetIgnoreHidden(bool on); … … 246 248 uint32& trigger, 247 249 BPrivate::TriggerList& triggers); 248 250 void _UpdateWindowViewSize(const bool &updatePosition); 249 bool _OkToProceed(BMenuItem* item); 251 bool _OkToProceed(BMenuItem* item, 252 bool keyDown = false); 250 253 251 254 bool _CustomTrackingWantsToQuit(); 252 255