However, tonight I think I can finally announce I have a working fix for the menu bar freeze in issue 248, which I was able to trigger while writing this very blog post (indeed, it does seem heavy keyboarding is to blame); based on discussion with Steven Michaud at Mozilla (thanks, Steven!!) it looks like it's an operating system bug that we're now triggering more easily, and it's probably happened at least to a limited extent to every previous version of TenFourFox. 10.4 and it looks like 10.5 can get into a situation where it misdelivers events to the wrong control under circumstances I don't yet understand, so it was falsely feeding the mousedown on the menubar to the (invisible) popup window control we use for context menus and click-hold menus, never getting to the menubar. The result is the menubar appears to freeze even though everything else works. This is another case where the Mac's menubar being always at the top of the screen makes things very easy, because catching a click up there should never happen (the OS should have routed it to the menus first), and so interception was straightforward.
I couldn't figure out why that was happening, but I could figure out how to get around it. Analysis of Shark tracing on a working process and a stuck process show they both activate an internal undocumented Carbon API function called _NSHandleCarbonMenuEvent, but it doesn't activate any additional functions in the stuck browser while succeeding in the working browser. Disassembling the Carbon library using otool shows that it takes a single argument (in register r3) which I guessed was a Carbon EventRef. Apple doesn't document Carbon EventRefs and wants programmers to treat them as opaque types, but they do somewhat document older Mac OS EventRecords which still exist in OS X, and _NSHandleCarbonMenuEvent actually calls a documented conversion routine called ConvertEventRefToEventRecord to get an EventRecord that we could spy on. Stepping through it in the debugger, we could confirm that the single argument was indeed an EventRef and the Carbon event kind is stored at byte offset 16 (at least for PowerPC -- I don't know if this is true for x86).
After I was able to trigger the freeze again, I was able to see that the event _NSHandleCarbonMenuEvent was getting was a kind 2 event (a mouseup), not the kind 1 event (mousedown) it should have been receiving. My first thought was to monkeypatch the event type in memory, but since it was already getting the mouseup, we could just inject the orphaned mousedown instead. But how to get the orphaned Cocoa NSEvent our popup window intercepted into the Carbon system menu handler? Using Magic Hat to dump NSEvent, I discovered Apple has an undocumented [NSEvent _eventRef] method in 10.4 for getting the underlying Carbon EventRef (it works with 10.5, too, though 10.5 can just use [NSEvent eventRef]). So, when we get that misdirected event, we use that undocumented Objective-C method to get the EventRef and just feed it back into our undocumented Carbon function _NSHandleCarbonMenuEvent. It seems so simple when I put it that way. Ain't hacking operating systems great?
I don't know if this will work for 10.5, but I can't see any reason why not. We should have test builds up this weekend to make sure it takes care of the problem.
In other news, being a guy with more money than sense (I don't have very much sense at all), I'm expanding my stable of Power Macs. And if you like Power Macs as much as I do, this is the best time to do it. Intel Macs are starting to clog the market in the wake of 10.7/10.8 and people can't even give away Power Macs practically, so prices have plummeted on the used market and I'm stocking up.
My primary machine is still my quad G5, and I use an 12" iBook G4/1.33 on the road (occasionally with an ARM Chromebook with Crouton loaded over ChromeOS). However, the G5 sits in the office in the back of the house, and it's nice to have a second terminal around, so I have a 1GHz iMac G4 out in the commons where I eat and pay bills and such.
I think the iMac G4 is the best looking Power Mac ever made, hands down, better than the Twentieth Anniversary Macintosh which is a real looker (I have a TAM on my bedside table), and the 15" one I have has a perfect arm (not sagging!) and LCD, case and mechanism. But 1GHz is a little poky and a 256K L2 cache is even worse; my iBook G4, which on paper should be 33% faster, is about 50% faster despite having a slower frontside bus because it has double the L2 (Apple has always criminally undercached their designs; see also G5). So when a 1.5GHz G4 Mac mini cropped up on eBay in great shape with 1GB RAM and a 17" Apple Studio Display, I struck and nabbed the set for about $125. But which one is the better Power Mac?
- CPU: No question, the 1.5GHz G4 mini is already faster on clock speed, but also has 512K of L2 and the same 167MHz system bus; easily it's close to 75% faster and maybe more depending on the task. Even the top-end 1.25GHz iMac G4 still has just 256K of cache, so overclocking is of questionable utility; plus, all of the 17" and 20" iMac G4s are starting to show sagging in the arm due to the screen weight. iMac 0, mini 1.
- RAM: The mini is limited to 1GB in one stick. The iMac came with 512MB, 256MB in each slot; I have 1GB in the user-serviceable slot for 1.25GB and I have a stick ready to put in the top. This requires a little bit of disassembly, but the potential is there. iMac 1, mini 1.
- Video: The mini has an 64MB ATI Radeon 9200, while the iMac is still plodding along with a 32MB GeForce4 MX. Plus, 15 inches of screen real estate can be a little confining and using the iMac with an external monitor is heartbreaking. iMac 1, mini 2.
- Expandability: On first blush this looks like a tough call, but after some thought there is a clear winner. Both take relatively standard hard disks and optical drives, and both have 48-bit LBA. Neither machine has PCI slots; both have Ethernet and can come with WiFi, though only the mini offers Bluetooth as a built-in option (as it happens, this one has both WiFi and Bluetooth). Now, you could add WiFi or Bluetooth to either machine, but you need USB ports for that, and that's where the iMac nudges by: it has 3 USB 2.0 ports and two FireWire 400 ports, lots of room for stuff. The mini has only two USB 2.0 and one FW400 port, and one of the USB ports is occupied by the Apple Studio Display controller because the G4 mini doesn't have ADC. You could get around that by getting a different monitor or a hub, of course, but you're still losing a port for the keyboard and mouse, and your cost and inconvenience keeps going up. And, after all that, the G4 iMac has an external video port, too, and can use the Apple Pro Speakers (of which I have several pairs). iMac 2, mini 2.
- Serviceability: The mini is not too hard to work on (once you get over those hideous cracking noises prying open the case), but has a lot of screws to lose, and getting to the optical drive or hard disk can take a little bit of time. On the other hand, the weird form factor of the iMac means you need a lot of workspace and have to protect the LCD and bezel from getting scratched, and if you pull the guts out from the "cone" to get to the hard disk or the second RAM slot you usually need to reapply thermal paste to the heat sink. Neither is unrepairable, but neither is a paragon of repairability either compared with, say, an Outrigger Power Mac or the easy case opening of the Power Mac G3 and G4; call this a wash.
- Hotness: The 17" ASD has a real cool retro vibe, but the iMac G4 is just gorgeous. Pair it with the Pro Speakers and a nice white Pro Keyboard, and it looks great. The arm still supports the screen perfectly. Everyone who comes to my house comments on how nice it looks and how computers in general don't look that good anymore. And that matters. iMac 3, mini 2.