July 30, 2005
Menu Extra Enabler and x86: Time for the Possum Lodge Word Game

A new version of Menu Extra Enabler was released yesterday. You can download it here. It was released to fix a bug in SystemUIServer (and not a bug in MEE).

If the login time delays the launch of SystemUIServer long enough, the Bluetooth Menu Extra will not load if Bluetooth is enabled. In fact, it "erases" all menu extras to the right of the Bluetooth menu item. However the user might not know their items are erased as the SystemUIServer doesn't read back the prefs it saved until it launches again. So we got a lot of reports blaming this on ShapeShifter since it optionally kills the SystemUIServer when a theme is applied. A few blamed it on Cee Pee You as well since it killed the SystemUIServer on install. Neither were the cause of the problem. In fact, the "problem" could have occurred days before you did either of these since it only happens when logging into OS X and at no other time. It also happened whether or not any third-party menu extras were in use and even if MEE wasn't installed at all. It is very likely to happen after installing a Mac OS X update. Simply because they force a reboot and applications take longer to launch after they've been modified do to Mac OS X having to create a new cache for the applications. The sad part is that after installing this version of MEE, if the bug was previously triggered but the SystemUIServer has not been quit yet, then all your menu extras will disappear. But they'll never disappear again as long as MEE remains installed. You can prevent this by moving a menu extra in the menu bar to a new location by holding down the command key on the keyboard. Just move one to a new position. This makes the SystemUIServer write out new preferences. Again, this disappearing was not cause by MEE.

My first attempt at fixing this was to prevent the saving of menu extras if the new list only contains items to the left of the Bluetooth menu extra and the BT Menu extra itself. This had a problem if the user manually removed menu extras to the right of it (since prefs are saved on a timer, the user could remove multiple menu extras before the prefs were saved). It was also a problem as it seemed extremely hackish and required a lot of code (about 50 lines). I was not happy with this at all. Not only did it not fix the problem (just the outcome) since the BT menu extra still wouldn't load in these cases, it also would break depending on the user's actions. It annoyed me so much, it even woke me up from sleep after I had done the horrible hack I just listed. So then I tried it again, from scratch, when I woke up.

As far as I can tell, this is the course of events.

1. User enables bluetooth and the bluetooth menu extra.
2. User Logs in with a bunch of login items (iChat, Extensis Suitcase, TextEdit, Console, Word, whatever) just enough so that it delays the initialization of SystemUIServer.
3. The SystemUIServer registers for notifications. It calls -[[SUISDocklingServer alloc] initWithController:docklingServer] in -[SUISStartupObject init].
4. -[SUISStartupObject applicationDidFinishLaunching:] is called. Which then places a call in a timer to -[SUISStartupObject _loadMenuBarExtras] after a 2 second delay.
5. the Dockling Server issues a notification/calls a callback in SystemUIServer.
6. Callback calls -[SUISStartupObject addMenuExtra:position:reserved:data:] on the Bluetooth Menu Extra
7. -[SUISStartupObject addMenuExtra:position:reserved:data:] calls -[SUISStartupObject createMenuExtra:atPosition:write:data:] on the Bluetooth menu extra.
8. -[SUISStartupObject createMenuExtra:atPosition:write:data:] calls -[NSMenuExtra initWithBundle:] on the Bluetooth menu extra.
9. SUIS then saves the menuBarPlugins array to the preferences (now only containing the Bluetooth.menu).
10. -[SUISStartupObject _loadMenuBarExtras] is called.
11. All subsequent calls to -[SUISStartupObject createMenuExtra:atPosition:write:data:] with the Bluetooth menu extra return NULL as _alreadyHasExtra: returns true so the BT menu extra isn't loaded (via _loadMenuBarExtras) when this bug hits. It is never loaded since there was no valid NSMenuToolbar available when addMenuExtra:position:reserved:data: was called.

I figured out all of this after 5 hours of straight debugging. The new fix that uses this information is only 5 lines of code and it is future proof and doesn't depend on the user doing something.

In other news, I had time so I've made a version of Menu Extra Enabler and Cee Pee You for the Intel DevKits. And the people from Rogue Amoeba made a version of MemoryCell for the Intel DevKits as well. MEE and Cee Pee You are, for the most part, direct recompiles of the PPC versions. There have been no changes to the code at all.

Menu Extra Enabler for x86 and PPC(FAT)
Cee Pee You for x86 and PPC (FAT)
MemoryCell for x86 (FAT) (from Rogue Amoeba)

For another note, yes, this only took about 2 mintues to convert for Cee Pee You and MEE. However, Xcode is very lame in that I can't set the SDK on a per target basis... only once per project. And I *really* hate native targets. So very much. In fact, for MEE I am using a legacy target for MEE PPC and a Native Target for MEE x86 then via a script in MEE PPC, I instruct lipo to join them.

It's all good.

Digg This!

 Posted by rosyna at July 30, 2005 11:17 PM

Trackback Pings:

TrackBack URL for this entry:
http://www.unsanity.org/mt-tb.cgi/330.




Related:
Comments

Woot for the Red Green reference (Canadian comedy kicks eh?). You guys think APE will go over nicely to X86?

-- SirG3

Posted by: SirG3 on August 2, 2005 4:23 PM

Good writeup. Explains a lot. Thanks.

-John

Posted by: John Wallace on January 7, 2006 10:15 AM
Post a comment




Remember Me?

(you may use HTML tags for style)