diff --git a/src/kits/interface/PopUpMenu.cpp b/src/kits/interface/PopUpMenu.cpp index 504b8b76a4..750dc90337 100644 --- a/src/kits/interface/PopUpMenu.cpp +++ b/src/kits/interface/PopUpMenu.cpp @@ -7,6 +7,7 @@ * Stefano Ceccherini (burton666@libero.it) */ + #include #include #include @@ -14,28 +15,26 @@ #include -struct popup_menu_data -{ +struct popup_menu_data { BPopUpMenu *object; BWindow *window; BMenuItem *selected; - + BPoint where; BRect rect; - + bool async; bool autoInvoke; bool startOpened; bool useRect; - + sem_id lock; }; BPopUpMenu::BPopUpMenu(const char *title, bool radioMode, bool autoRename, - menu_layout layout) - : - BMenu(title, layout), + menu_layout layout) + : BMenu(title, layout), fUseWhere(false), fAutoDestruct(false), fTrackThread(-1) @@ -49,8 +48,7 @@ BPopUpMenu::BPopUpMenu(const char *title, bool radioMode, bool autoRename, BPopUpMenu::BPopUpMenu(BMessage *archive) - : - BMenu(archive), + : BMenu(archive), fUseWhere(false), fAutoDestruct(false), fTrackThread(-1) @@ -86,9 +84,9 @@ BPopUpMenu::Instantiate(BMessage *data) BMenuItem * -BPopUpMenu::Go(BPoint where, bool delivers_message, bool open_anyway, bool async) +BPopUpMenu::Go(BPoint where, bool deliversMessage, bool openAnyway, bool async) { - return _go(where, delivers_message, open_anyway, NULL, async); + return _go(where, deliversMessage, openAnyway, NULL, async); } @@ -232,7 +230,7 @@ BPopUpMenu::ScreenLocation() { if (fUseWhere) return fWhere; - + BMenuItem *superItem = Superitem(); BMenu *superMenu = Supermenu(); BMenuItem *selectedItem = FindItem(superItem->Label()); @@ -247,8 +245,7 @@ BPopUpMenu::ScreenLocation() } -// #pragma mark - -// private methods +// #pragma mark - private methods void BPopUpMenu::_ReservedPopUpMenu1() {} @@ -276,25 +273,22 @@ BPopUpMenu::_go(BPoint where, bool autoInvoke, bool startOpened, } BMenuItem *selected = NULL; - + // Can't use Window(), as the BPopUpMenu isn't attached BLooper *looper = BLooper::LooperForThread(find_thread(NULL)); BWindow *window = dynamic_cast(looper); - - if (window == NULL) - return NULL; - + popup_menu_data *data = new popup_menu_data; sem_id sem = create_sem(0, "window close lock"); - + data->window = window; // Asynchronous menu: we set the BWindow menu's semaphore // and let BWindow block when needed - if (async) { + if (async && window != NULL) { _set_menu_sem_(window, sem); } - + data->object = this; data->autoInvoke = autoInvoke; data->useRect = _specialRect != NULL; @@ -305,16 +299,16 @@ BPopUpMenu::_go(BPoint where, bool autoInvoke, bool startOpened, data->startOpened = startOpened; data->selected = selected; data->lock = sem; - + // Spawn the tracking thread fTrackThread = spawn_thread(entry, "popup", B_NORMAL_PRIORITY, data); - + if (fTrackThread >= 0) resume_thread(fTrackThread); else { // Something went wrong. Cleanup and return NULL delete_sem(sem); - if (async) + if (async && window != NULL) _set_menu_sem_(window, B_BAD_SEM_ID); delete data; return NULL; @@ -327,21 +321,19 @@ BPopUpMenu::_go(BPoint where, bool autoInvoke, bool startOpened, // TODO: usually it's not a good idea to check for a particular error // code. Though here we just want to wait till the semaphore is deleted // (it will return B_BAD_SEM_ID in that case), not provide locking or whatever. - while (acquire_sem_etc(sem, 1, B_TIMEOUT, 50000) != B_BAD_SEM_ID) + while (acquire_sem_etc(sem, 1, B_TIMEOUT, 50000) != B_BAD_SEM_ID) { window->UpdateIfNeeded(); - + } } - + status_t unused; while (wait_for_thread(fTrackThread, &unused) == B_INTERRUPTED) ; - - selected = data->selected; - - delete data; + selected = data->selected; + delete data; } - + return selected; } @@ -355,53 +347,52 @@ BPopUpMenu::entry(void *arg) BRect *rect = NULL; bool autoInvoke = data->autoInvoke; bool startOpened = data->startOpened; - + if (data->useRect) rect = &data->rect; - + data->selected = menu->start_track(where, autoInvoke, startOpened, rect); - + // Reset the window menu semaphore if (data->async && data->window) _set_menu_sem_(data->window, B_BAD_SEM_ID); - + delete_sem(data->lock); - + // Commit suicide if needed if (menu->fAutoDestruct) delete menu; - + if (data->async) delete data; - + return 0; } BMenuItem * BPopUpMenu::start_track(BPoint where, bool autoInvoke, - bool startOpened, BRect *_specialRect) + bool startOpened, BRect *_specialRect) { fWhere = where; - + // I know, this doesn't look senseful, but don't be fooled, // fUseWhere is used in ScreenLocation(), which is a virtual // called by BMenu::Track() fUseWhere = true; - + // Show the menu's window Show(); - + // Wait some time then track the menu snooze(50000); BMenuItem *result = Track(startOpened, _specialRect); if (result != NULL && autoInvoke) result->Invoke(); - + fUseWhere = false; - + Hide(); - be_app->ShowCursor(); fTrackThread = -1;