May 30, 2006
Application Enhancer 2.0

With hours (whew!) to spare before the expiration of the previous public beta of Application Enhancer 2.0, we're proud to present you with the final version of 2.0. We'll follow with the actual modules soon, but until then, keep using the previously released public betas with this new final version of Application Enhancer 2.0.

Application Enhancer 2.0

And lest we neglect the other developers using Application Enhancer, here we have the SDK:

Application Enhancer SDK 2.0

Let us know of any issues you encounter or suggestions you may have!

Posted by brian at 06:49 PM
May 24, 2006
ClearDock, Dock Detox Universal Public Beta

On the second tier of Universal public betas of our haxies, here's the free ones. These ones were more or less just a "checkbox and recompile" kind of ports. As the rest, they will expire on May 31, 2006:

http://unsanity.net/beta/dock-detox-13b1.dmg
http://unsanity.net/beta/cleardock-14b2.dmg

Enjoy.

Posted by slava at 03:26 AM
May 16, 2006
Universally Fatilicious Public Betas (WSX, FM, MeMa, Silk): Overcane of Antflower Milk #3

If you don't want to read my ranting or the horrible technical inaccuracies someone will accuse me of making, skip to the end of this post to get to the direct download links. Also note that ShapeShifter is not part of this public beta push and will probably be one of the last APEs in a fat binary form due to the extensive image code and other things that have to be rewritten a lot for x86.

Welcome to the first public beta of ICBM-compatible haxies. Slava finally received his ICBM and was able to do some production machine testing. As such, we've decided to release some public betas. In this installment, we have four such betas. Windowshade, FruitMenu, Menu Master, and Silk. If anyone is wondering why I keep calling them ICBMs, it's because it is closest to what Apple calls them. They repeatedly and officially call them "Intel-based Macs". However, that takes too long to type and it has a dash. A nice abbreviation would be IBM. That obviously cannot be used. Especially since IBM makes the PowerPC chips. So the next course is to ask "Intel what?" And answer, "Intel chip". And so we have Intel chip-based Macs, which nicely abbreviates to ICBM. Just 4 short letters. Also, the proper term for "Universal Binaries" would be "Fat binaries". After all, why do you think they call it lipo? What's funny about that man page is that they just did a search and replace for "fat". If you look at the man page dated just five months prior you can see all the mentions of "fat". The other issue with the marketing term "Universal" is that it was previously used to describe application programs that worked in multiple languages. I've also seen a few users think "Universal" is something "magic" (as in something really special) when it's "just" two binaries for two (or more) processor architectures "smashed" into each other to make one larger binary. Granted, fat binaries are an absolutely wonderful thing. They prevent Mac OS X from having 13 different SKUs like what's required for Windows 2003 x86, Windows 2003 "64-bit for 64-bit extended systems" (x64), and Windows 2003 for real 64-bit processors like the Itanium. Fat binaries greatly reduce consumer confusion and are an absolutely great thing to have.

Anywho, I thought I'd write about some of the difficulties we faced when porting stuff over from the PPC side of things to the x86 side of things. Well, I can only really speak for myself and mention the issues Slava's told me about. First, Application Enhancer. That was a doozy. Imagine a small Russian man stabbing an effigy of his mother with a turkey baster while screaming, "Non-trivial! Non-trivial! Non-trivial!". Now imagine his Mother coming in and saying, "Слава, поставь отца на место, пора ужинать." Well, at least that's what I imagine but I'm not all there in the head. APE uses a little more than a bit of ASM. Of course, Mac OS X itself uses ASM all over the place. If you want pure speed and tight control over how your code is run, ASM is the way to go. So porting APE required learning i386 ASM. Not the most difficult thing, especially since Slava was used to 68k ASM from the pre-PowerPC days and I'm told their readability is similar. Learning x86 ASM was just a small bump in the road compared to some other things. Because the x86 instruction set is variable length compared to the PowerPC's fixed length instruction set, some extra work and some design changes on the x86 side of APE were required. By far the biggest thing we had to have was Rosetta support. APE Modules needed to load inside applications running under Rosetta. Otherwise there would be a huge consistency and support issues as running applications under Rosetta is otherwise completely seamless. Explaining to users that they could only run APEs in native processes was completely unacceptable. Adding Rosetta support was akin to adding a large new feature. Debugging APE modules in applications running in Rosetta... Now that's scary.

Application Enhancer was by far the largest and most time consuming part to port over. Especially considering the amount of error checking code we write. The preference panes for the APE Modules were relatively easy. They were mostly just a checkbox away from being loved by an ICBM. But this entirely depends on whether the APE had the pref pane do all the heavy lifting. Some APE modules will make the preference pane "explode" all the data into easy to digest bits since things need to be done as fast as possible on the APE module side of things.

There were a few caveats with porting APE modules. Personally, I found the "change" in objc_msgSend to be my biggest problem APE-side. All normal happy Objective-C calls like [object isEqualTo:object] are transformed into objc_msgSend(object, @selector(isEqualTo:), object...) or some variant of objc_msgSend_*. The [receiver message] type of call is really only accessible to files that are marked as being compiled with the Objective-C "compiler". By default these are .m and .mm files. It's not always possible (or a good idea) to mark files as being Objective-C source code files. For one thing, no APE module can link directly to AppKit (part of Cocoa). It's not that it's not possible but loading AppKit causes an enormous amount of memory to be moved. This can greatly reduce application launch times for non-Cocoa applications. Also, if the host application has an early over-releasing bug (such as PowerMail and Toast did in the way back when that was over 3 years ago) the chances the freed memory being overwritten by another object is exceedingly great, which will result in a crash. Some APE modules address this by creating "sub modules" that only load if the parent is of a particular architecture. However, this can be tedious as it requires an entirely separate code base. Not the most efficient way to do something while weaving in and out of code. Menu Master, it particular, calls objc_msgSend() directly all the time since Cocoa menus are based on Carbon menus. Let's say I want to call a specific method using objc_msgSend but it's Mac OS X 10.4 and later only. I'd need to determine that the object responds to the selector. I'd do this by calling... wait for it... respondsToSelector:. A real-life example is NSMenu's delegate method. If I had an NSMenu object named "lastMenu" I'd test it by running if (objc_msgSend(lastMenu, NSSelectorFromString(CFSTR("respondsToSelector:")), NSSelectorFromString(CFSTR("delegate")))). Now, this would work fine and dandy on the PowerPC. However, respondsToSelector: returns a BOOL type. (Note: BOOL, bool, and Boolean are all different types, do not confuse them.) BOOL is an 8-bit type. objc_msgSend returns a 32-bit type. On the PPC, the upper bits of the 32-bit value would all be zeroed so the conditional check works as expected. However, on the x86 the upper bits are not zeroed. This means it can "randomly" return YES when the answer is an emphatic NO. This can lead to some very ugly crashes. This fix for this is even uglier. It involves typecasting the function pointer itself. So the new check becomes ((signed char(*)(id, SEL, SEL))objc_msgSend)(lastMenu, NSSelectorFromString(CFSTR("respondsToSelector:")), NSSelectorFromString(CFSTR("delegate"))). Fun, huh? When I first ran into this issue in February, I had no idea why I was getting these random crashes. I sent a message out to a mailing list asking for tips. Luckily, someone from Apple responded with a very, very detailed explanation of what was happening and another thing that should be watched. I could not be more appreciative of Greg's response.

Then there's just little convenience things you can do on the PowerPC, like converting a FourCharCode into a C string by using OSType tag='OTTO'; char creatorstr[5]; creatorstr[4]=0; *(OSType*)creatorstr=tag;. Because the x86 is little endian, this will result in some jumbled characters. Luckily for this case, there's a much better alternative in UTCreateStringForOSType(). No ugly pointer math. Ugly pointer math is ugly and makes babies cry.

Yeah, that's just a few of the issues. I had more, but I now realize this thing is getting to be really long.

Onward to the Betas!

After we released Smart Crash Reports and started getting a few crashes in, we were ecstatic. SCR worked and was doing it's job. We immediately fixed the few crashes we saw and released updates. Months passed. We got more reports of the same crashes. At first the thought was maybe the bugs weren't really fixed. We then checked the rest of the crash log. People were still using the really old versions of our software. Sometimes really, really old. With that, we started working on a semi-unified updater. All of these betas include this new updater. By default, it's set to check daily. This can be changed in the respective product's preference pane if you so desire. It's set to check daily because it's beta software. The final release of each piece of software will default to weekly. If you actually desire to change it to something else, please tell us why! If you're behind a proxy, please tell us if manual checking works. It uses the WebKit NSURLDownload class, so hopefully it will work with proxies. That class is just wonderful.

APE 2.0b2

All of these products include Application Enhancer 2.0b2. This beta will expire on May 31st. A design decision was made so only fat APE modules will load on the ICBMs. This is due to the fact a non-fat, PPC only, APE module would only load into applications running under Rosetta and the user would have no way to set the settings of the APE module without launching the System Preferences application in Rosetta. Neither of these are a very good user experience as I mentioned yesterday.

Menu Master 1.3.2b2

Menu Master 1.3.2 includes a brand new feature called "Menu Accelerator". This feature (and it's name) was shamelessly stolen from Gus Mueller with his permission. Of course, his code was not suitable at all (and honestly wasn't even looked at) because it's all Cocoa (see above explanation of APEs linking to Cocoa) so just the idea itself was stolen. Basically, you just press Command Option Control M (4 keys) in an application and a new window with all the menu items appear. You can type into this to narrow the results (see image at right). It is supposed to be completely self-explanitory and intuitive. Sadly most of the beta testers said they wouldn't use it. The only people that did really like it had already been using Gus' implementation before and were glad it finally worked in Carbon applications. I should note that Menu Accelerator uses no patching at all. Carbon Events rule! The DataBrowser does not!

Version 1.3.2 beta 2 (May 16th, 2006-ish)

  • Now includes a fat Application Enhancer beta. With tons of fatty goodness and green pea-ness. This beta will expire on May 31st.
  • Heavily updated the Menu Accelerator window. It now shows the shortcuts for menu items and shows the parent menu item (if available) of menu items.
  • Menu Accelerator now kind of remembers recently searched for strings.
  • Added the Unsanity Updater. It's set to check daily by default.
  • Some other fixes that I can't remember because I forgot to right them down.
  • Sadly dropped Mac OS X 10.2.x support.

Version 1.3.2 beta 1 (March 5th, 2006)

  • Fixed a potential infinite recursive loop that would lead to a stack overflow induce crashed if a menu was populated by an event that Menu Master sent, which then caused the event to be sent again as Menu Master rescanned the newly updated menu.
  • Addressed a problem that prevented some keyboard shortcuts from being set on menu extras that changed their status based on the modifier keys being held down. This may have a side effect of preventing shortcuts to be set on menu items in menu extras that only appear if a specific modifier key is held down. You can't win them all.
  • Worked around a problem that caused a crash in the DVD Player. This was similar to the previous Quicken 2006 problem.
  • Changed the way new shortcuts are displayed in the preference pane.
  • No longer uses the first parent menu's menu item index when saving menu item paths. This was purely cosmetic and related to the above change.
  • Addressed a crash in NoteTaker due to the way NoteTaker's style menu is laid out and handled.

Get it at http://www.unsanity.net/beta/menumaster-132b2.dmg (2.65 megs)

WindowShade X 4.0.3b1 (May 16, 2006, from Slava with Love)

  • This update is free for all registered users.
  • WindowShade X is now a Universal haxie, working on both PowerPC and Intel based Macs.
  • Included the automatic version checker.
  • Redesigned the interface of the preference pane.
  • Some other pending fixes.
  • Includes Application Enhancer 2.0b1.
  • Includes Smart Crash Reports 1.1.

Get it at http://www.unsanity.net/beta/windowshade-x-403b1.dmg (3.56megs)

FruitMenu version 3.4.4b1 (May 16, 2006, from Slava with Love)

  • FruitMenu is now a Universal haxie, working on both PowerPC and Intel based Macs.
  • Included the automatic version checker.
  • Redesigned the interface of the preference pane.
  • Small fixes.
  • Includes Application Enhancer 2.0b1.
  • Includes Smart Crash Reports 1.1.

Get it at http://www.unsanity.net/beta/fruitmenu-344b1.dmg (2.70megs)

Silk

Version 2.1.3b4

  • Nothing Special here. Updated to APE 2.0b2.
  • Removing *some* logging. It still logs a lot for WebKit applications. This is intentional.

Version 2.1.3b3

  • Now includes a fat Application Enhancer beta. With tons of fatty goodness and green pea-ness.
  • Fixed a crash when opening the about window and then quitting the System Preferences application (reported via Smart Crash Reports).

Version 2.1.3b2

  • Added automatic updating functionality with a large hammer.
  • Fixes a potential over release of memory if font substitution was enabled but no fonts were set to be substituted.
  • No longer have to relaunch System Preferences after entering your registration information in order to see it.
  • Greatly reduces the dependence on font families. Silk no longer substitutes fonts based on the stored Font Family ID. This means substitution and changing the theme font should continue to work even if you have duplicate fonts with the same name but different Font Family IDs.
  • If the specified theme font is no longer available, Silk no longer replaces the theme font with Geneva (or some other random font).
  • Fixed a problem with the new WebKit substitution that would cause WebKit based applications to choose the next font alphabetically on the system if the specified font was not on the system. This bug resulted in some weird effects.

Version 2.1.3b1

  • Addresses a display problem with synthetic font styles in a future version of WebKit if font substitution is enabled.
  • Fixes the minimum font size settings in applications that use WebKit.
  • Addressed a potential problem with the font in the location field in Safari.

Get it at http://www.unsanity.net/beta/silk-213b4.dmg (3.31megs)

Requests for Comments and Other Forms of Love

We'd really like to know what people think about the new APE Preference pane. We tried to clean it up quite a bit and make it easier to use. We'd also like to know what y'alls opinion is of the updating process. That is, what is your feeling on updaters in general? Finally, I'm curious to know which "first tab" preference pane design you like better. The one in FruitMenu and WSX or the one in Menu Master and Silk? Also, if anyone finds any utility in Menu Accelerator. You can answer all these questions and more in the comments here or by emailing us directly. Probably at beta at this company dot com. But only email that if what you need to say can't be said in public on the internets.

Reposting the Links Because it's the Thing to do this Summer (along with seeing Snakes on a Plane!)

WindowShade: Get it at http://www.unsanity.net/beta/windowshade-x-403b1.dmg (3.56megs)
FruitMenu: Get it at http://www.unsanity.net/beta/fruitmenu-344b1.dmg (2.70megs)
Menu Master: Get it at http://www.unsanity.net/beta/menumaster-14b3.dmg (2.65 megs)
Silk: Get it at http://www.unsanity.net/beta/silk-213b4.dmg (3.31megs)



You will see Snakes on a Plane! starring the lovely Samuel L. Jackson.

Posted by rosyna at 08:46 AM
May 15, 2006
Dastardly Dialogs: Overcane of Antflower Milk #2.5

In the five years or so that Mac OS X has been around, I've seen some some very useless dialogs presented to the user (me). However, this particular dialog just boggles my mind.

When we first started getting emails from users about their new ICBMs, I didn't believe this dialog was actually produced by a piece of Apple-made software. So I started asking for screenshots of the dialog. A few users responded to my request and sent me screenshots that all said the same thing. "Could Apple really have approved a dialog written so badly?" I thought. A week or so later I got my iCBM from Apple in exchange for the Developer Transition Kit dealie and was able to confirm that, yes, this was in fact a dialog produced by Apple software.

You may be asking what's so bad about this hideous dialog. First, let's go over the three things that every single error dialog should have.

  1. What happened?
  2. Why did it happened?
  3. How can I, the user, resolve this problem?

This dialog lacks a clear #1. The title, "Preferences Error", describes nothing. A much better title would have been something along the lines of, "Cannot open the FontCard Preference Pane". Please note two things about my suggestion. One, the lack of the "s" at the end of "Preference". Two, the addition of the article before the name of the preference pane. #1 is further explained in the first line of the dialog text, "You cannot open FontCard preferences pane on this computer." The line itself has two problems as well. One, there is no article in front of the word "FontCard". That's not the way we fly our goat to the supermarket on Thursdays here. No, siree, Bob. Two, nowhere on OS X does Apple call them "preferences panes". If you get info on one in the Finder, it says "Mac OS X Preference Pane" (note the case). If you look at the extension, it is "prefPane". The name of the folder where they are stored is Library/PreferencePanes/. Just where did that extra "S" come from? Is the plural of "preferences pane" supposed to be "preferences panes you eat with a fpoon?" (That extra 'S' has to come from somewhere.) It also would have been super nifty if Apple had badged the System Preferences icon in the dialog with the icon preference pane that was clicked on or vice-versa.

I'm not even sure it's trying to answer #2. It says it cannot be opened but doesn't say why it cannot be opened. There's nothing about architecture or processor mentioned. Heck monkey, just saying "... because it cannot run on ICBMs", "... because it was not designed for this processor architecture", or even "...because it cannot be emulated" would at least give the user a "Why". Sadly, it just says that something specific failed for some unknown reason. Go have a candy.

The #3 point is what really gets me slightly irked. It answers it alright, it says "Contact the developer of this software for a newer version." Implying that the developer has already made a newer version and it's the user's job to demand it from them. This demanding nature is what got me interested in the dialog in the first place. The dialog doesn't tell the user to check to see if one is available, it says (strong implies) that is there is a newer version. It would have been much better if Apple had at least suggested such a version may not be available.

Also, I thought Apple was repeatedly saying that all PowerPC software would just work on the ICBMs thanks to Rosetta. What, this isn't true? No, it isn't. All plugins must match the architecture of the application that loads the plugin. This means a PowerPC preference pane can only load in a PowerPC System Preferences running under Rosetta. A PowerPC Photoshop plugin will only work when Photoshop is running in Rosetta. It doesn't matter if the host is Fat or not. If it's not running under Rosetta, the PowerPC plugin can not load. And that's what this error is all about. A PowerPC plugin (a preference pane) does not match the architecture the host (System Preferences) is running in. If the user were to get info on the System Preferences application and check "Open in Rosetta", then they could use the PowerPC plugin. Assuming the author of the plugin didn't first check if the host was running under Rosetta and bailed out. While I thought that Apple had made the plugin-must-match-host problem perfectly clear, emails and comments from users along with other postings on the internets clearly show this not to be the case. When Photoshop goes native, we're going to see a lot of very confused (and potentially angry) users. I say Photoshop because it probably has the largest user base of applications running on Mac OS X that have a major market for plugins.

May I Play Devil's Advocate for a Moment?

On my recent post in the "Overcane of Antflower Milk" "series", people accused me of being too hard on Apple... of being too negative. So I'm going to show what the opposite stance might look like.

When software is purchased, it's purchased for the features it has at the time of purchase. It isn't purchased for what features it may have in the future or what versions of the Operating System it may run on in the future. Someone decided that the software was for them and paid for it. The features, the compatibility, the everything. It all fit at the time it was purchased. Software is not a precious metal that goes up in value as time passes. In fact, it's becoming common practice for larger companies to release a new version for an upgrade fee and not release any updates for it other than a few major bug fixes. Minor bug fixes are saved for the next major release.

Let's look at Adobe Photoshop, for example. Adobe Photoshop 7 was released around 7/12/2002. It had one update to 7.0.1. Then Adobe Photoshop CS was released around 2/12/2004, a year and a half later. That version had no point release updates. Adobe Photoshop CS2 was release around 4/28/2005, about 14 months later. It's had no point updates in the last year.

Let's compare to iPhoto from iLife '05. It had a 5.0.3 update before iLife '06 was release. iMovie had a 5.0.2 update, iDVD a 5.0.1 update. Logic Pro 7.0 had a 7.0.1 update before it was updated to 7.1, which had a $19 upgrade fee. 7.1 had a 7.1.1 update before 7.2 was released which had a $49 upgrade fee.

Microsoft has already stated they won't have a native version of Office 2004 for the ICBMs. Quark has stated that QuarkXPress 7 will be the first version to run native on the ICBMs. I'm not sure what's going on with DiskWarrior, about the only useful utility for fixing hard drive problems I've ever used. On a side note, I wonder if they'll have difficulty with licensing Mac OS X due to the risk of running it on generic PCs.

My point in all of this? Every major software company that writes software for Mac OS X is charging for an Intel chip-based Mac native version of their software. And almost every single one (including Apple) releases just one or two just minor point releases between major updates, excluding security related patches. These point updates only exist to make the experience the user gets actually match the experience the user bought. Why is it that smaller software companies aren't extended the same courtesy? Why is it that users absolutely demand free updates to get their software to work on the ICBMs? And why do they expect these much, much smaller companies to deliver a product much, much sooner than the large companies? Why is it that a company with 1-5 programmers isn't even granted a month before the demands start when companies with 150+ programmers are given all the time in the world? How does not having an update for ICBM compatibility at all change the reasons the software was purchased in the first place? After all, the far, far majority of the people demanding the updates purchased the software before even IBM knew Apple was going to switch to Intel and long before the user knew about the switch. The lack of knowledge didn't prevent them from purchasing the software. So why does it matter all of a sudden now? Would these questions be different if the users demanding the software were willing to pay for the updates they demand?

That's a lot of questions. I don't expect answers, they're all rhetorical and covered in rhubarb. As I said, this is just me presenting from the other side of the debate.

Posted by rosyna at 04:37 AM