Right now the way that the CaptureRollupEvents method works in the widget API is pretty crappy, especially on Linux and is probably one of the reasons why menus aren't very fast on this platform. First, for a description of what happens. When you create a menu or popup window (personal toolbar, context menu) on Linux, the procedure looks looks something like this: o Create new popup window o Call CaptureRollupEvents Sometimes the CaptureRollupEvents() call happens before the popup window is actually visible and in X windows, you can't grab on a window that isn't visible. Therefore, the widget code tries to grab, fails and waits until the widget becomes visible before trying again. The XGrabPointer and XGrabKeyboard functions aren't cheap and they both require server round trips. This always shows up on profiles of "why menus are so slow on Linux." Now, here's a description of what happens when you navigate to a sub menu or another menu item. o Create new popup o Call CaptureRollupEvents(aCapture == 0) o Call CaptureRollupEvents(aCapture == 1) This means that with every submenu that is opened we generate a lot of X traffic ungrabbing on the old popup window and regrabbing (possibly twice!) on every sub menu. Obviously, this means that submenu navigation is pretty slow. There is a two part solution to this. The fist part requires changes to the linux front end. The second requires changes to come XP code and probably a minor change to each of the platform front ends. The XP changes would require that instead of calling CaptureRollupEvents with the flag to turn off capture followed by CaptureRollupEvents on the new window, we should either add a flag saying that this is a transitional change or we should be able to call CaptureRollupEvents with the new target and the widget code in question is able to handle the change without the explicit remove beforehand. The linux front end has to explicitly grab on the parent of the popup windows instead of grabbing on the popup windows themselves. This way the idea of a a grab "session" is maintained since the popup windows in the series are transitory. There is another important function that is described in but 140767. That is that the menu bar that the menus drop down from should still be able to receive button motion events when the popups in question are still grabbing. This way you can slide down the list of menus and choose another one. Right now grabs of the popups block all events to the parent window, including the menu bar. It would be nice to come up with a way to allow some windows in the parent window to still be marked as being able to receive the events. I don't know what is required to do this, exactly, but maybe if we added a new member to CaptureRollupEvents that specified a parent that could get events? Ideas are welcome. Anyway, this is what is required to get menus working faster on Linux.
So it turns out that the menu bar that is just part of the surrounding area and is drawn. It doesn't have its own native window to draw on and, what I really need, grab on. How hard would it be to make the menu bar frame (is that the right word?) to have its own native window so that we can grab on it properly?
I've looked at this in the past and it seems pretty difficult to do because of the way menus were designed. I'm sure its possible but may require some changes here and there.
The first step is to get a single native window assigned to the menu bar. Once that has happened, it shouldn't be too hard to use it as the grab window and to allow it to get events wile the child menus to as well. Of course, the comment from pink and hyatt in nsMenuBar::GetWidget() is pretty ominous. What about the mac? Doesn't it use native menus and not use this method at all?
mac uses a native menu impl for toplevel menus, but uses xpmenus for things like context menus and the bookmarks popup
Does this menu bar code get used at all on the mac? Also, what do you have to say about possible changes to the rollup code to fix this problem?
this code is not used at all on the mac. it uses moz/widget/src/mac/nsMenuBar[X] instead. as far as that comment, we did that for a reason (it does sound ominous, you're right). I'd be pretty wary of touching it unless you know you got it right. a possible way around this would be to give the menubar its own widget and not get the one from the surrounding view (which is what the old code appeared to do, and ended up fetching the entire toplevel window). hewitt and hyatt can better comment on the impact of giving the menubar its own widget. they own that code now.
Yeah, that's exactly what I want to do - give it its own widget.
What seems odd to me is that the context menu generated from a right-click is so much slower than a much larger menu, like the pulldown bookmarks menu (which for me is the height of my 1600x1200 screen) It is just slow enough that don't feel like the computer has responded to you, and if something else is sucking down your CPU, such as several pages with annoying flash ads, it may take several seconds to respond. Sometimes I assume the click didn't "take" and end up clicking several times until I suss out the situation.
Context menus have to do a lot of work to figure out the context...
You need to log in before you can comment on or make changes to this bug.