On Fri, Jan 28, 2011 at 3:05 PM, Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> wrote: > Stephan Aßmus <superstippi@xxxxxx> wrote: >> That is certainly a fix which "works", however there is some code in >> BMenu which is supposed to flash the selected menu item [...] >> All in all, I am not so happy with this solution. > > Same thoughts here. OK. Warning long text below: I wonder if we could resolve all these menu issues by first describing the ideal behavior, taking the existing API into account. I think we can all agree that in general how menus in BMenuBar works is fine (excluding some bugs of course, like the keyboard navigation issues.) So that leaves pop-up menus, both as context menus and as used in BMenuField. The main problem is context menus. Here are the two Go() method signatures on BPopUpMenu (from the Be Book): BMenuItem* Go(BPoint screenPoint, bool deliversMessage = false, bool openAnyway = false, bool asynchronous = false); BMenuItem* Go(BPoint screenPoint, bool deliversMessage, bool openAnyway, BRect clickToOpenRect, bool asynchronous = false); When an application calls Go() on BPopUpMenu it will provide a BPoint where the left-top of the menu window should be. Nothing too crazy there, with the exception that if the menu would show off the screen, it is moved within screen boundaries, which means the left-top is no longer at screenPoint, and may in fact be under the mouse cursor. This is where things can get messy. No one (including Pete Goodeve) wants menu items accidentially invoked in this case. So the menu should always stay on screen in that case and not invoke the item under the cursor when the mouse button is released. How to achieve that is the issue I guess. Two of the other parameters to Go(), deliversMessage and asynchronous, don't affect the menu behavior as far as mouse tracking goes, so they can be ignored here. That leaves openAnyway and the clickToOpenRect. If openAnyway is true we always do sticky mode and leave the menu on the screen, so no problem there. If it is false then we can turn on sticky mode only if the mouse is released inside the clickToOpenRect. The moving of the menu window if opened near a screen edge should not affect the clickToOpenRect. If openAnyway is false and there is no clickToOpenRect provided then the menu should never be sticky (except in the case above of the menu opening under the mouse.) This is the default behavior inherited from BeOS (for better or worse) if only the screenPoint is provided. If my understanding is wrong on the above at all, let me know. So given all that I think the only issue that remains is not invoking items if the menu opens under the cursor. That is what I was trying to do in r40132 (http://dev.haiku-os.org/changeset/40132) but clearly I did not know enough about the code at that point. With further thought I think the proper solution is to just turn on sticky mode if the menu opens under the mouse and the mouse button is released within the double-click period. So somewhat of a hybrid between this commit and r40132. Does that sound reasonable? Another option in addition to the above is a Haiku user preference to always force sticky mode in pop-up menus. People like Pete can leave this off but the rest of us can leave it on. The other question is whether these changes would cause problems with BMenuField or BMenus in a BMenuBar. I don't think so, but would obviously need to test to be sure. As for a general refactoring of the menu code: it is still needed I think, but we should try to get the behavior right first, and then have well designed tests (automated if possible) to make sure that behavior is maintained when refactoring. Sorry for the long email but this is not a simple issue and I'm kind of tired of trying different things which someone (whether Pete, you guys or someone else) finds fault with. -- Regards, Ryan