keeleysam / tenfourfox

Automatically exported from code.google.com/p/tenfourfox
0 stars 0 forks source link

Menu bar intermittent freeze #248

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
24 only. If you're posting in this bug, *include specific steps how to 
reproduce -- me toos DO NOT HELP*.

The only system I could reproduce this on had a long uptime and lots of sleeps 
and restores, but on my sleeping/restarting iBook, I can't replicate it. It has 
been reported on both 10.4 and 10.5. The app remains responsive and operational 
otherwise, and key sequences work, so the problem is within the menu rather 
than the child view.

Original issue reported on code.google.com by classi...@floodgap.com on 24 Oct 2013 at 4:43

GoogleCodeExporter commented 9 years ago
Per users, not related to Personas.

Original comment by classi...@floodgap.com on 25 Oct 2013 at 6:14

GoogleCodeExporter commented 9 years ago
Triggered again. Pressing Shift-Cmd-J to open the browser console correctly 
cleared the pulldown menus and redrew them, but it doesn't make them clickable, 
and switching back doesn't fix it (even though it also redrew them properly). 
It seems to be stuck believing it can ignore clicks on the menu bar because no 
beachball appears, so the message is being delivered and the menu widget is 
saying it doesn't have to act on it. This might be a race condition somewhere.

Original comment by classi...@floodgap.com on 26 Oct 2013 at 7:51

GoogleCodeExporter commented 9 years ago
Context menus do work and open also, so the problem is entirely restricted to 
the menu bar.

Original comment by classi...@floodgap.com on 26 Oct 2013 at 7:54

GoogleCodeExporter commented 9 years ago
I need to trigger this in a debug build but I still have no idea what causes 
it. There is nothing in Console in an opt build.

Original comment by classi...@floodgap.com on 26 Oct 2013 at 7:55

GoogleCodeExporter commented 9 years ago
Working menu in a debug build:
handling an event
menu open/close

When the menu freezes:
trying to deliver this event too
trying to deliver this event too
trying to deliver this event too
trying to deliver this event too
trying to deliver this event too

The first comes from nsMenuX; the second comes from nsCocoaWindow.

Original comment by classi...@floodgap.com on 27 Oct 2013 at 6:11

GoogleCodeExporter commented 9 years ago
The menu event in the normal case should not be handled through nsCocoaWindow.

Original comment by classi...@floodgap.com on 27 Oct 2013 at 6:25

GoogleCodeExporter commented 9 years ago
Testing another idea. I've altered menuNeedsUpdate to always reinstall the 
Carbon menu event handler. It seems it succeeds more than it complains, making 
me wonder if it was being unloaded by something. So far so good but it's 
impossible to test.

Original comment by classi...@floodgap.com on 27 Oct 2013 at 5:46

GoogleCodeExporter commented 9 years ago
It seems that typing causes this to get set off a lot (for reasons I don't 
understand). Added a timeout just in case this is expensive on slow systems. So 
far still can't reproduce it with this change.

Original comment by classi...@floodgap.com on 27 Oct 2013 at 8:06

GoogleCodeExporter commented 9 years ago
Finally triggered again after days of trying to get it to do so, so this is not 
the cause for *this* bug, although it may underlie others. However, I'm 
concerned about its effect on typing, so I'm going to back it out.

Maybe the Z-order of the PopupWindow is wrong and we need to manually reset it.

Original comment by classi...@floodgap.com on 29 Oct 2013 at 12:46

GoogleCodeExporter commented 9 years ago
I have this set up as a speculative fix. It seems to work, but it's impossible 
to predict when the bug will strike. The theory is reasonable, however, because 
the event should not get propagated to the PopupWindow. So I'll add an event 
handler to reset the Z-order if it's getting left clicks since that won't harm 
anything in the working case.

Original comment by classi...@floodgap.com on 30 Oct 2013 at 2:57

GoogleCodeExporter commented 9 years ago
Triggered it here as well for the first time after typing a lot in a web form. 
Maybe of interest: I was able to "cure" it the same way as issue 72/Mozilla bug 
641597, viz. toggling "Tabs on top" (which is still possible without the menu 
bar by right-clicking on the tab bar).

Original comment by chtru...@web.de on 30 Oct 2013 at 7:55

GoogleCodeExporter commented 9 years ago
Very interesting! I'm going to ship the speculative fix, which will also log to 
the console if it thinks it's detected the situation. Maybe I can rig something 
like that to occur in that circumstance, though toggling tabs on top actually 
cascades a whole lot of changes and I'm not sure I can kick them off from 
Obj-C. But good to know that there might be a workaround that does not require 
restarting the browser.

Typing a lot is also noteworthy. menuNeedsUpdate gets called a lot for typing, 
but that might just be a coincidence.

Original comment by classi...@floodgap.com on 30 Oct 2013 at 1:10

GoogleCodeExporter commented 9 years ago
Wait. Where are you seeing "Tabs on Top"? I can't find that when I right click. 
Is it coming from an addon?

Original comment by classi...@floodgap.com on 30 Oct 2013 at 1:15

GoogleCodeExporter commented 9 years ago
Oh… it's only visible in the menu if you *don't* use Tabs on top (like me), 
and after re-starting the browser. Brilliant, Mozilla… So the first toggling 
needs to be done in about:config.

Original comment by chtru...@web.de on 30 Oct 2013 at 2:02

GoogleCodeExporter commented 9 years ago
So I'm using 24.1 with the speculative fix. It seems to falsely detect the 
situation a lot (or maybe it really does occur that frequently), but the hack 
is safe if the situation does not exist, so let's see if it prevents the 
problem from occurring.

Original comment by classi...@floodgap.com on 31 Oct 2013 at 3:12

GoogleCodeExporter commented 9 years ago
It finally occurred on the iMac. So let's see what Tabs on Top does to make 
everything work again.

Original comment by classi...@floodgap.com on 1 Nov 2013 at 7:04

GoogleCodeExporter commented 9 years ago
(If anyone can make this happen reliably, I'd sure appreciate it because it's 
making testing damn near impossible.)

Original comment by classi...@floodgap.com on 1 Nov 2013 at 7:05

GoogleCodeExporter commented 9 years ago
... though the good news is that the speculative fix did, indeed, detect the 
situation. So we have a wedge at least.

Original comment by classi...@floodgap.com on 1 Nov 2013 at 7:06

GoogleCodeExporter commented 9 years ago
Toggling Tabs On Top didn't work for me.

Original comment by classi...@floodgap.com on 1 Nov 2013 at 7:52

GoogleCodeExporter commented 9 years ago
Weird. Then we may have two different sorts of menu freezes, or Tabs on Top 
must be toggled through the right-click menu. I'll try toggling it with 
about:config the next time it happens.

Original comment by chtru...@web.de on 1 Nov 2013 at 8:23

GoogleCodeExporter commented 9 years ago
Steven Michaud says we should just be able to send events to [NSApp mainMenu]. 
So maybe we do that when the bug strikes.

Original comment by classi...@floodgap.com on 1 Nov 2013 at 9:42

GoogleCodeExporter commented 9 years ago
It's a GeckoNSMenu and it says it doesn't know what sendEvent is.

I'm beginning to think there's a bug here in the OS we're tripping. For laughs, 
someone who can trigger this bug more easily, open a Terminal window and type

killall -KILL SystemUIServer

Does that make the menu bar wake up again? It shouldn't make anything else go 
bad, it just will restart any menubar extras.

I spent literally two hours today banging on keys and I can't get this to 
trigger reliably. It did happen once.

Original comment by classi...@floodgap.com on 2 Nov 2013 at 10:10

GoogleCodeExporter commented 9 years ago
Finally got it to happen again. Restarting SystemUIServer didn't fix it. The 
menu bar remains responsive in everything else.

Original comment by classi...@floodgap.com on 3 Nov 2013 at 8:14

GoogleCodeExporter commented 9 years ago
We should see if beginMenuTracking still gets an event when the freeze occurs.

Original comment by classi...@floodgap.com on 3 Nov 2013 at 8:51

GoogleCodeExporter commented 9 years ago
I had the brainwave to run Shark on it before I closed the app. Shark shows 
that AppKit _NSHandleCarbonMenuEvent does get called by _DPSNextEvent, but it 
does nothing.

After I restarted the app and sampled it some more, _NSHandleCarbonMenuEvent 
does call MenuSelect when a menu opens.

Looking at the assembly for _NSHandleCarbonMenuEvent, it looks like it takes a 
single argument (only r3 is in play apparently). It returns true or false and 
seems to work like this:

- Failure status is saved in r30. It defaults to 0 (didn't handle).
- Call _ConvertEventRefToEventRecord. It looks like it analyzes it for 
something (see below).
- If this "analysis" passes, it calls _FindWindow (lwz r3,74(r1); addi 
r4,r1,80). If _FindWindow does not return true, it bails out.
- If _FindWindow returns true, then:
  - it fires off a whole bunch of Objective-C message sends.
  - It calls _MenuSelect, again with lwz r3,74(r1).
  - It computes off the return code (srawi. r29,r3,16); if the result is zero, it aborts menu selection (but sets r30 to true) and exits.
  - If it's nonzero, it determines the hit Carbon menu, converts it to a NSMenu, and sends it an Objective-C message. It sets r30 to true.

The analysis it does seems to be based on a uint16 (lhz r0, 16(r1)) in the 
event field, which seems to be an event type. If the type is 1, then it falls 
through to _FindWindow. If the type is not, it goes to a secondary check where 
type 3 or 5 is understood as a key event and the key equivalent is checked; if 
it passes, r30 is set to true and an Objective-C message is sent. Otherwise, it 
fails with r30 false.

So we ought to be able to manipulate this ourselves. I can't tell yet if this 
is wrong event type or FindWindow is returning false, but I suspect the latter 
case.

Original comment by classi...@floodgap.com on 3 Nov 2013 at 9:59

GoogleCodeExporter commented 9 years ago
Irritatingly, NSEvent in 10.4 does not support [NSEvent eventRef], so we're 
going to have to figure out a way around this. We can then synthesize a menu 
event and send it into _NSHandleCarbonMenuEvent.

Original comment by classi...@floodgap.com on 3 Nov 2013 at 10:05

GoogleCodeExporter commented 9 years ago
Source for NSHandleCarbonMenuEvent so I don't need to run it again.

Original comment by classi...@floodgap.com on 3 Nov 2013 at 10:56

Attachments:

GoogleCodeExporter commented 9 years ago
Attached a debugger. That's not the problem. The problem is that 
ConvertEventRefToEventRecord is generating a bogus event type:

(gdb) finish
Run till exit from #0  0x932bee8c in ConvertEventRefToEventRecord ()
0x937a4000 in _NSHandleCarbonMenuEvent ()
1: x/i $pc  0x937a4000 <_NSHandleCarbonMenuEvent+36>:   lhz     r0,64(r1)
(gdb) si
0x937a4004 in _NSHandleCarbonMenuEvent ()
1: x/i $pc  0x937a4004 <_NSHandleCarbonMenuEvent+40>:   li      r30,0
(gdb) i reg r0
r0             0xf      15
(gdb) si
0x937a4008 in _NSHandleCarbonMenuEvent ()
1: x/i $pc  0x937a4008 <_NSHandleCarbonMenuEvent+44>:   cmpwi   cr7,r0,1
(gdb) i reg r0
r0             0xf      15
(gdb) si
0x937a400c in _NSHandleCarbonMenuEvent ()
1: x/i $pc  0x937a400c <_NSHandleCarbonMenuEvent+48>:   bne+    cr7,0x937a4194 
<_NSHandleCarbonMenuEvent+440>
(gdb) 
0x937a4194 in _NSHandleCarbonMenuEvent ()
1: x/i $pc  0x937a4194 <_NSHandleCarbonMenuEvent+440>:  cmpwi   cr7,r0,3
(gdb) 

Original comment by classi...@floodgap.com on 4 Nov 2013 at 1:57

GoogleCodeExporter commented 9 years ago
Event kind seems to be r3+16.
0x932bef98 in ConvertEventRefToEventRecord ()
1: x/i $pc  0x932bef98 <ConvertEventRefToEventRecord+284>:      mr      r3,r30
(gdb) 
0x932bef9c in ConvertEventRefToEventRecord ()
1: x/i $pc  0x932bef9c <ConvertEventRefToEventRecord+288>:      mr      r4,r29
(gdb) 
0x932befa0 in ConvertEventRefToEventRecord ()
1: x/i $pc  0x932befa0 <ConvertEventRefToEventRecord+292>:      bl      
0x9338a918 <ConvertMouseEventToEventRecord>
(gdb) x/16w $r29
0xefffe4e0:     0x00000000      0x0000027a      0x995c025a      0x068c0000
0xefffe4f0:     0x00000000      0x24002224      0xefffe950      0xefffea00
0xefffe500:     0xa07c1a80      0x00000001      0x00000000      0x00000001
0xefffe510:     0xa37c15cc      0x6d6f7573      0x00000002      0x937a15cc
(gdb) x/16w $r30
0x22dbe1c0:     0x00000000      0x00000000      0x00000000      0x6d6f7573
0x22dbe1d0:     0x00000002      0x80000001      0x4125273e      0xcb193f6c
0x22dbe1e0:     0x00000000      0x00000000      0x00000001      0x00000002
0x22dbe1f0:     0x00000000      0x00000000      0x00020000      0x000000ac
(gdb) si
0x9338a918 in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a918 <ConvertMouseEventToEventRecord>:        mflr    r0
(gdb) si
0x9338a91c in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a91c <ConvertMouseEventToEventRecord+4>:      stmw    
r28,-16(r1)
(gdb) 
0x9338a920 in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a920 <ConvertMouseEventToEventRecord+8>:      stw     r0,8(r1)
(gdb) 
0x9338a924 in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a924 <ConvertMouseEventToEventRecord+12>:     mr      r29,r4
(gdb) 
0x9338a928 in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a928 <ConvertMouseEventToEventRecord+16>:     stwu    
r1,-96(r1)
(gdb) 
0x9338a92c in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a92c <ConvertMouseEventToEventRecord+20>:     mr      r28,r3
(gdb) 
0x9338a930 in ConvertMouseEventToEventRecord ()
1: x/i $pc  0x9338a930 <ConvertMouseEventToEventRecord+24>:     bl      
0x932b7c7c <GetEventKind>
(gdb) 
0x932b7c7c in GetEventKind ()
1: x/i $pc  0x932b7c7c <GetEventKind>:  mr.     r3,r3
(gdb) 
0x932b7c80 in GetEventKind ()
1: x/i $pc  0x932b7c80 <GetEventKind+4>:        li      r0,0
(gdb) 
0x932b7c84 in GetEventKind ()
1: x/i $pc  0x932b7c84 <GetEventKind+8>:        beq-    0x932b7c8c 
<GetEventKind+16>
(gdb) 
0x932b7c88 in GetEventKind ()
1: x/i $pc  0x932b7c88 <GetEventKind+12>:       lwz     r0,16(r3)
(gdb) 
0x932b7c8c in GetEventKind ()
1: x/i $pc  0x932b7c8c <GetEventKind+16>:       mr      r3,r0
(gdb) 
0x932b7c90 in GetEventKind ()
1: x/i $pc  0x932b7c90 <GetEventKind+20>:       blr
(gdb) i reg r3
r3             0x2      2

The event type is set by ConvertMouseEventToEventRecord.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 2:57

GoogleCodeExporter commented 9 years ago
God bless Magic Hat. It found that 10.4 NSEvent has a secret _eventRef method. 
We'll use the documented [x eventRef] for 10.5 and [x _eventRef] for 10.4.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 3:17

GoogleCodeExporter commented 9 years ago
And now it makes sense. The kind 2 mouse events we're getting are mouseups. We 
want a kind 1.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 3:23

GoogleCodeExporter commented 9 years ago
We get a kind 2 and a kind 15 when I click and release the menu bar with the 
menu bar frozen. To get this to work, we should make the kind 2 into a kind 1, 
and the kind 15 into a kind 2. 

This is almost certainly an OS bug that we have to just work around. Now that 
we can get to the NSEvent's _eventRef, we just set that and fire it back to 
_NSHandleCarbonMenuEvent, and hope it works.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 3:26

GoogleCodeExporter commented 9 years ago
Actually, that should be type 5 (it computes out as kind 15).

The other idea might be to create a whole new NSEvent and post that. It would 
certainly be less hideously kludgy. The question is whether calling super would 
get it back to the menubar.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 4:54

GoogleCodeExporter commented 9 years ago
New, clean NSEvent:

  NSEvent* event = [NSEvent mouseEventWithType:(NSEventType)aNativeMessage
                                      location:windowPoint
                                 modifierFlags:aModifierFlags
                                     timestamp:[NSDate timeIntervalSinceReferenceDate]
                                  windowNumber:[[mView window] windowNumber]
                                       context:nil
                                   eventNumber:0
                                    clickCount:1
                                      pressure:0.0];

We could also try CGEventPostToPSN(&psn,e) with a new, clean CGEvent. This 
might be a better one to start with, since we *know* it will get to the event 
loop. We just have to make sure we convert NSPoint to CGPoint correctly.

CGEventRef CGEventCreateMouseEvent (
   nullptr, // CGEventSourceRef source,
   kCGEventOtherMouseDown, //or up CGEventType mouseType,
   CGPoint mouseCursorPosition,
   kCGMouseButtonLeft // CGMouseButton mouseButton
);
CFRelease(e);

Original comment by classi...@floodgap.com on 4 Nov 2013 at 5:05

GoogleCodeExporter commented 9 years ago
And don't forget

if (type == kCGEventLeftMouseDown) {
   eventNumber++;
   CGEventSetIntegerValueField (event, kCGMouseEventNumber, eventNumber);
}
if (type == kCGEventLeftMouseUp) {
   CGEventSetIntegerValueField (event, kCGMouseEventNumber, eventNumber);
}

or maybe we just 

CGError CGPostMouseEvent (
   CGPoint mouseCursorPosition,
   false, // boolean_t updateMouseCursorPosition,
   1, // CGButtonCount buttonCount,
   true, // boolean_t mouseButtonDown,
   true // button 1
);

despite Apple's warning, because then we don't have to know the PSN and we 
don't have to release the event.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 5:31

GoogleCodeExporter commented 9 years ago
duh,

    NSPoint myNSPoint;
    CGPoint cocoaPoint = *(CGPoint*)&myNSPoint;

Original comment by classi...@floodgap.com on 4 Nov 2013 at 5:40

GoogleCodeExporter commented 9 years ago
Next time it freezes, I'm going to write something to post to its PSN and see 
if it wakes up.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 5:41

GoogleCodeExporter commented 9 years ago
I'm not certain that this is related, but I reported what may be the same or a 
similar issue that I first noticed while running Tenfourbird 17.0.5:  
http://en.sourceforge.jp/forum/forum.php?thread_id=33807&forum_id=28579.  I 
don't believe I've experienced the problem in Tfb 17.0.9 or 17.0.10, but the 
menu locked up infrequently enough that I wouldn't be at all surprised if the 
issue remains unresolved in Tfb 17.0.10.  I was unable to determine what 
triggered the menu lockup.

Original comment by rlrar...@gmail.com on 4 Nov 2013 at 4:37

GoogleCodeExporter commented 9 years ago
It might not be. There have been other freeze bugs with different causes; see 
chtrusch's comment.

That said, this is looking like an OS bug, so this particular issue probably 
does affect all preceding versions including 17 at least to a limited extent. 
However, it's just idle speculation without steps to reproduce.

Original comment by classi...@floodgap.com on 4 Nov 2013 at 5:41

GoogleCodeExporter commented 9 years ago
Solution found!

The PopupWindow is actually indeed getting the kind 1 event, so we just feed it 
back into _NSHandleCarbonMenuEvent; the type 2 mouseup gets there normally. The 
menu responds correctly. Managed to trip this while typing a blog post. It 
works fine.

Original comment by classi...@floodgap.com on 7 Nov 2013 at 2:45

GoogleCodeExporter commented 9 years ago
No further reports; can't reproduce any more on any of my systems.

Original comment by classi...@floodgap.com on 19 Nov 2013 at 2:15