Closed Bug 141198 Opened 22 years ago Closed 6 years ago

making menus on linux faster and with proper semantics

Categories

(Core :: XUL, defect)

All
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: blizzard, Assigned: blizzard)

References

Details

(Keywords: perf)

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.
Blocks: 140767
Blocks: 91351
Keywords: perf
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...
I think menus are fast enough now on Linux. Closing.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.