Archive for the ‘mac’ Category

Strange Firefox+Mac WordPress Admin Page

Tuesday, August 26th, 2008

Below is a screencap of what part of my WordPress 2.6.1 admin page looks like when I view it using Firefox 3.0.1 on Leopard.

If you click on it to view it better, you’ll see the problem. The stats graph is shifted about 200 pixels to the right and about 150 pixels down. On Safari it looks perfect, but not on Firefox. This doesn’t happen with Firefox on Windows, so it’s some sort of quirk with the Mac version.

Has anyone else seen this, and do you have any suggestions?

Apple Still Working on MobileMe

Tuesday, August 19th, 2008

I just received an email from Apple regarding MobileMe. Here’s what it said

We have already made many improvements to MobileMe, but we still have many more to make. To recognize our users’ patience, we are giving every MobileMe subscriber as of today a free 60 day extension. This is in addition to the one month extension most subscribers have already received. We are working very hard to make MobileMe a great service we can all be proud of. We know that MobileMe’s launch has not been our finest hour, and we truly appreciate your patience as we turn this around.

It’s good to see the bit in there about this launch not being their “finest hour.” That shows that they recognize how bad this rollout has been. But they better solve it soon or they’ll be giving everyone a free year. We’re already up to 90 days of free service.

I really like MobileMe, though the only part of it that I really use is syncing bookmarks and stuff between my Mac Pro and iBook. I tried to setup the Outlook integration on my Windows laptop the other day, but it didn’t seem to actually do anything. I guess that’s part of what’s broken with the service, maybe.

Strange Seg Fault In Simple Cocoa App

Saturday, July 26th, 2008

I just got Aaron Hillegass’ 3rd edition of Cocoa(R) Programming for Mac(R) OS X (3rd Edition) and am working through it as if I never went through the 2nd edition. (It’s been so long since I did any Cocoa, that seemed like the smart thing to do.) Anyway, I’m in Chapter 4 on memory management and things were going fine. Until all of a sudden, the program started dying with a segmentation fault. After trying to figure out what I’d done wrong, I figured I’d mistyped something and just wasn’t seeing it, so I reverted my changes back to what I had in my Subversion repo. I then started making the changes again. And again the program died with a segfault. 

Any time I’m working through a programming book, I always type all the examples in by hand, rather than downloading pre-written code. I learn better that way. But in cases like this, I don’t have a problem with looking at the author-provided code to see where I went wrong. I downloaded the solutions from Aaron’s site and started comparing. I found the problem pretty quickly.

Originally, the code for creating the NSCalendarDate object for today’s date was

NSCalendarDate *now = [[NSCalendarDate alloc] init];

which, when you later add the code to release it, would have worked fine. But at some point between when I wrote that line of code and when I added the release, Aaron mentioned a convenience method on NSCalendarDate for getting back an autoreleased date object. That code looks like this

NSCalendarDate *now = [NSCalendarDate calendarDate];

I had changed my code to use that instead of the original version. That was in Chapter 3. So, when I hit Chapter 4 and added the call to release the date object, I ended up with my segfault. The chapter assumed that you still had the alloc & init calls, and so made no mention of the calamity that would ensue if you had switched to the other way of getting today’s date.

What made this difficult to find was when the segfault occurred. It didn’t happen when I called release on the date object. It happened on this line

[pool drain];

which is one line before the program ends. That’s boilerplate code there, so it was really strange that it was barfing. The reason this caused the problem is that this way of getting a date is autoreleased, which means that unless I retain it somewhere, it’s going to get deallocated when the NSAutoReleasePool is deallocated. But when I called release on it, I ended up setting it’s retain count to 0, so when the pool was drained, it ended up sending a release message to an object that had already been deallocated, which is a no-no.

Bottom line is that had this been a big program, this could have been really hard to track down. Of course, turning on the Objective-C 2.0 garbage collector would have solved the problem too, but then you have a Leopard-only program.

I Paid My $99 To Apple

Saturday, July 12th, 2008

As I said yesterday, I finally got my acceptance letter from Apple that essentially allows me to pay them $99 in order to develop iPhone software. I have just now paid the $99, so now it’s just a matter of waiting for the license or whatever it is that they will send out. Let’s hope it doesn’t take as long as it did for the acceptance letter.

As I write this, I am downloading the iPhone SDK. I played around with the first beta Apple released, but I haven’t really done anything with it since then. That was before they got Interface Builder going, so it should be a lot better now than it was then. I’m looking forward to getting started; now I just need to think of something that needs writing.

07/13/2008 00:37 Update: About 20 minutes after posting this, my Activation Code email arrived from Apple. Fun times ahead.

So *Now* Apple Will Let Me In…

Friday, July 11th, 2008

After months of waiting, I received this email from Apple just a few minutes ago:

Thank you for applying to the iPhone Developer Program.

We have reviewed the information you submitted when you initiated your program enrollment request and we are ready to instruct you on the steps required to complete the enrollment process.

Please click here to review and agree to the Standard License Agreement. You must execute this agreement prior to completing the purchase and activation process for the iPhone Developer Program.

Once you complete and activate your purchase, your enrollment will be complete.

Thank you,

iPhone Developer Program

I guess now that the App Store is live, they can let more people into the program. Now I guess I’ll have to re-download the SDK and pony up.

MiddleClickClose for Safari 3.1.1

Friday, April 25th, 2008

Someone wrote to tell me that MiddleClickClose was no longer working after upgrading to Safari 3.1.1. I hadn’t yet installed the latest version, so this was news to me. I just upgraded, but MCC still worked for me. I’m not sure what the user’s problem was. Maybe he upgraded from Safari 3.0 to 3.1.1, skipping 3.1, which I can see how that would have broken it for him.

I did change the MaxBundleVersion in Info.plist to 5525.18, which is the current version of Safari, so if you’re having problems, install the copy linked below. Or edit the Info.plist file in MiddleClickClose.bundle/Contents yourself.

iTunes Should Remember Window Size

Friday, April 18th, 2008

I subscribe to a lot of podcasts, and lately I’ve been subscribing to lots of video podcasts. I love watching GeekBrief in ginormous HD format. But not all of the videocasts come in that large format, so I have to right-click on them and select ‘Double Size.’ But the next time I watch GeekBrief, it spans both monitors, because iTunes applied my ‘Double Size’ selection to this video as well.

What would be nice is if iTunes remembered your video settings for each subscription instead of one setting for all. This would allow me to set ‘Actual Size’ for GeekBrief, but ‘Double Size’ for The Buzz Report. That would be really nice.

MiddleClickClose Updated

Tuesday, April 8th, 2008

I announced here that I had updated MiddleClickClose to work with Safari 3.1, but that it had problems loading under Safari 3.0. Actually, the problem was that it wouldn’t load on a PPC chip; I was testing on my iBook G4, but I hadn’t generated a universal binary. That was caused by having the iPhone SDK installed. Anyway, I dropped back to Xcode 3.0 and got a universal binary built, and now everything is happy.

If you want the plugin, ensure you have SIMBL installed, download the binary package below, and unzip it in ~/Library/Application Support/SIMBL/Plugins and restart Safari.

As usual, it’s distributed under the GPL.

MiddleClickClose For Safari 3.1

Friday, March 21st, 2008

As I reported two days ago, after I installed Safari 3.1, my MiddleClickClose extension stopped working. Well, I’ve gotten it working again. , but it doesn’t load under Safari < 3.0. So, only install this version if you are using Safari 3.1. If you are using an older Safari, use this one.

As before, I’m releasing this under the GPL.

My, What a Large Amount of Virtual Memory You Are Using

Thursday, March 20th, 2008

I just checked my Activity Monitor to see how much of my 6 gigabytes of RAM was in use. I was shocked (shocked!) to discover that a Java RMI server program (that I wrote) appeared to be using a bit more virtual memory than it should. Take a look at this screenshot of this process:


I’m sure it’s just a reporting error, but it was still funny to see.

Safari 3.1 Breaks My Middle Click Close Extension

Wednesday, March 19th, 2008

If you install the new Safari 3.1, my MiddleClickClose extension stops working. The first time you launch Safari, SIMBL complains that the plugin hasn’t been tested with this version of Safari, but that’s easily fixed by putting the proper version 5525.13 in Info.plist for the tag MaxBundleVersion. Once that’s done, the extension loads, but doesn’t seem to do anything. The problem is that the system is no longer delivering a mouseUp event when you middle-click a tab. I’m not sure what’s going on, but I will look into it. I’ve become dependent on my middle-clicks…

Middle Click Close For Safari

Wednesday, January 23rd, 2008

I love Safari on my shiny Mac Pro, particularly because it’s so much faster than Firefox. But one thing I missed from Firefox was being able to do a middle-click on a tab and have it close. After several failed attempts, I finally got some help from Mark Rowe who pointed me to a proper method-swizzling implementation. After switching my code to use that swizzler, everything fell into place. I’ve been happily using it ever since, I just never released it. I got an email the other day asking for it, so here it is.

Unlike my Export to Archive plugin for iPhoto, I didn’t build an installer for this one. It’s easy to install, but you still have to do it yourself. And there’s a dependency: SIMBL. Now, before Leopard shipped the word was that Input Managers would no longer be supported. After Leopard shipped we saw that wasn’t entirely true. So, once you get SIMBL installed and working, using my plugin is easy. This should work on both Tiger and Leopard. I’ve only tested it recently on Leopard, but I originally wrote it on a Tiger system.

  1. Get the binary package: MiddleClickClose.zip
  2. Create ~/Library/Application Support/SIMBL/Plugins if it doesn’t exist
  3. Unzip the MiddleClickClose.zip into this directory. You should end up with a directory called MiddleClickClose.bundle
  4. Restart Safari

If all goes well, you should now be able to use your middle mouse button to close Safari tabs. It works for me. If it doesn’t work for you, run the OSX Console and look for “MiddleClickClose loaded” in the “Console Messages” section.

If you want the source code, download it here.

I should mention that this really is a dirty hack, and may not work with future versions of Leopard. It works for me, but your mileage may vary. I hope it works for you, but it may not.

This code is distributed under the GPL v2.

QuickTime Player Annoys Me

Tuesday, November 27th, 2007

The QuickTime player that Apple ships really, really annoys me. There are two reasons why I hate it: volume and geometry defaults. By this I mean that the player defaults to 100% volume, which is really loud, and top-left-of-window placement, with no way to set either of these in preferences. I don’t know who on the QT team at Apple thought these were good/valid defaults, but regardless of stupid defaults, I should be able to set preferences for these and have them respected. I would prefer the player to startup with a volume in the 25 - 50% range, and centered on my screen, or at least closer to the middle than the top-left. It’s absurd that these things can’t be changed by the user. I notice from Apple’s docs that if you want to embed a QT movie in a webpage you can set the volume…

I wrote an Automator script that changes the volume once the player starts, but there’s no way to set this workflow as a default. In other words, the only way I could use it was to drag a movie I wanted to watch onto the workflow’s icon, rather than just double-clicking on the movie file.

Is anyone else annoyed by this?

Monitor Log Using Console.app

Wednesday, November 14th, 2007

When I’m working on a Linux desktop, I will frequently open a new shell window with tail -f on a log file I need to watch, such as my JBoss log. When I switched to my glorious Mac Pro I did the same thing, but it wasn’t exactly what I wanted.

I discovered that you can execute Console.app from the command line, so I have created a Bash alias that I run when I need to. Here’s what I put in my ~/.alias file:

alias jbtail=’/Applications/Utilities/Console.app/Contents/MacOS/Console /opt/jboss/server/default/log/server.log &’

(Make certain all of that is on one line!) Obviously you should change the path to the log to be something you want to monitor. You can change the alias name to something else if you like. After editing the file, either logout or type . ./.alias (notice the dots) and that will load up the alias. Now you can type jbtail (or whatever you chose to call it) and Console.app will open for you watching changes to that log file.

What’s really nice about this method as opposed to just using Terminal.app is that Console.app remembers things like window geometry, fonts and, most importantly, which monitor it last ran on. This is really nice for people like me who have two monitors. I always want this log to show up on my second monitor, and once I’ve placed it there, future invocations of my alias will open it right where I left it.

If you already have a .bash_profile or .profile file in your home directory, look for a line that looks like this

test -r ~/.alias && . ~/.alias

If you see that, you’re all set. If not, adding it will ensure that your aliases get loaded when you next login. You could add the alias=… line directly to .profile or .bash_profile if you like, and skip the .alias file altogether. I have several aliases and I like to keep them in their own file.

Objective-C Strings Are Not C Strings

Wednesday, October 10th, 2007

I got bitten today by the fact that Objective-C strings in Cocoa programming are not the same things as plain old C strings. The problem is that Objective-C is essentially an object-oriented veneer on top of plain old C; sometimes it matters that you remember this, and other times it doesn’t. This was one of the times it mattered.

A little background. A while back I wrote and released ExportToArchive, a somewhat useful plugin for iPhoto. It allows you to select photos from your iPhoto library and export them into a few different archive formats. About three days after releasing it, I got an email from a guy who had just tried to export his entire library, 756 photos, into a single archive. He was perplexed because iPhoto just seemed to hang/lock up. The problem was that when I wrote the thing, I never considered that anyone would try to archive more than a few photos at a time. Thus, once you made your selections and started the export, I copied each file to a temporary directory, and then archived the copies. That works great for 10 or 20 photos, but not so well for 756.

The answer to that problem was not to copy the files, but to make a symlink of each photo into that temporary directory and then archive the files by dereferencing the links. It’s still going to take a while to archive the photos, but there will no longer be a copy phase, which should make things faster.

Which leads to today’s adventure. There’s not a native Obj-C or Cocoa method to create a symlink. There is a method on NSFileManager called linkPath:toPath:handler: but that creates a hard link, which won’t span file systems. So I was forced to use the C function symlink which takes two arguments: the source path and the destination path. This seemed easy. I would pass the absolute path name to the original file as the source argument, and the generated name for the link as the second. Easy-peasy.

Well, not really. Since symlink is a C function it, like most other C functions, tells you bugger-all about why a failure occurs. The return value when I tried to call it was -1 which means, “something bad happened.” I then had to consult the C value errno to get more info. The value of errno was 22 which, according to the header file errno.h means:

#define EINVAL 22 /* Invalid argument */

An invalid argument. OK. How about telling me which argument is invalid since I did, after all, pass in two arguments.

I tried escaping spaces and quoting the entire string, but nothing worked. Finally, it dawned on me: Objective-C strings are not C strings. symlink was expecting a plain old C string, but I was passing in something completely different: instances of the Obj-C class, NSString. So, the way to fix this was to pass in C strings, and how do you get C strings from NSString instances? Right, call UTF8string on them. Thus my call to symlink went from

rc = symlink([source UTF8String], [dest UTF8String]);

to

rc = symlink([source UTF8String], [dest UTF8String]);

and all seems to be working properly now.

I’m going to do a bit more testing on this, but I will probably release this new version tomorrow.

Export to Archive iPhoto Plugin

Wednesday, August 29th, 2007

Ever since I switched to my exquisite Mac Pro, I’ve been using iPhoto. A few weeks ago when Apple announced the new iLife ‘08, I bought it. Last week while using iPhoto, I wanted to zip up a bunch of photos so I could move them to another machine. But I couldn’t find anything like this in iPhoto. There’s an exporter, but it doesn’t support zip files. You can right-click on a photo and select “Show File”, but that’s clunky and wouldn’t work well if you had multiple files you wanted to zip up.

So I wrote an exporter plugin to handle this. It’s called Export To Archive, and it supports three archive types: Zip, GZip and BZip2, depending on which flavor you prefer. I personally like bzip2, because the compression is much better than the others, but YMMV.

Once you install the plugin, you select the photos and/or events you want to export, then select Export… from the File menu (if using an older iPhoto, the Export… menu item is under the Share menu). The “Export Photos” dialog opens with a new tab labeled “Archive.” Selecting this tab reveals a pane that looks like this.

The dropdown reveals the other two archive types. Select the type you want and then press the Export button. You will be presented with a “Save As” dialog where you can enter the name of the new archive file. You don’t need to specify an extension as the plugin will append the correct extension based on the archive type. After you enter the name you want and press OK, you should see a progress dialog and then you are taken back to your photo library. If everything went as planned, you have a shiny new archive where you told the plugin to put one. If not, you should get an error message telling you what happened.

The plugin does not keep any directory paths that might have existed in your iPhoto library. I considered making a directory for each “event” (iPhoto 7.x only) but I believe a photo can be in multiple events, so this seemed like a bad idea. Maybe later.

Also, if you select multiple photos with the same name (but from different directories, obviously), then I handle it like Safari does when downloading the same file twice. I append an underscore with a number to the filename before the extension. So if you had two files called 100_1234.jpg, then one would be called 100_1234.jpg and the other would be 100_1234_1.jpg. If there were three files, the second would have _2 appended, etc. This seems like a reasonable solution to this issue.

I should mention one more thing about the compression methods. If you use Zip, then any resource fork info is lost. This probably isn’t a problem, but I felt I should mention it. It’s how the /usr/bin/zip program works. If you choose either GZip or BZip2, then the photos are first put into a tar file and then compressed. The /usr/bin/tar program that comes with OSX does preserve resource fork info into the archive. If you look in the archive, you will see that for every file, there is a similarly-named file that is vastly smaller than the original. If you expand the archive on a Mac, then you only end up with the files you asked for. But on other systems, the resource fork “phantom files” will be expanded to the disk along with the photo files. The file names start with ._ so on Unix systems they will be hidden. On Windows, you will probably see them. Either way, it’s extra crud. I tried to figure out a way to get rid of these files, but there doesn’t seem to be one. And maybe we don’t want to get rid of them, anyway. Thus, if you are going to move your archive to another Mac, you might want to choose GZip or BZip2. If you’re going to it to some other system, choose Zip.

Want it? There are a couple of ways to get it, depending on which version of iPhoto you have.

Both of these installers install the plugin for everyone on the system. PackageMaker.app that Apple provides doesn’t seem to provide a way to install it for just the curent user. This means that the plugin will go to one of two places, depending again on your iPhoto version

  • iPhoto 7.x: /Library/Application Support/iPhoto/Plugins
  • iPhoto < 7.x: /Applications/iPhoto.app/Contents/PlugIns

If you’re running iPhoto 7.x and you’d rather install it just for yourself, you can download this zip file and install it by hand. You should put it in ~/Library/Application Support/iPhoto/Plugins.

This is a universal binary. I have tested this on a Mac Pro with iPhoto 7.x, and on an iBook G4, with iPhoto 5.x. If you have some other config and it doesn’t work for you, let me know, providing a crash dump, if you have one. I don’t know that I can make it work, but I could look into it.

If you’d like the source code, get it here. You’ll need Xcode 2.4.1 to open the project.

That’s about it. This is free software, released under the GNU GPL. If you like it, tell your friends. If there’s a feature you want, let me know, or implement it yourself and provide me a patch to include in the source.

09/12/2007 Update: I’ve now had two three reports of the plugin not working with iPhoto 6.x. That’s the version I was unable to test with, so if you have iPhoto 6, use caution. And if you have iPhoto 6 and it crashes on you, would you send me the crash dump? It can be found in ~/Library/Logs/CrashReporter/iPhoto.crash.log

09/13/2007 Update: I’ve now had several reports that the plugin doesn’t work with iPhoto 6.x, so if you’re using that version, don’t install it. I am trying to figure out how I can test against 6.x, since I don’t have a machine with that version. Stay tuned for updates.

Uninstallation Instructions
If you need to uninstall, delete the ExportToArchive.iPhotoExporter directory. Depending on the version of iPhoto you are using, it will be in one of two places:

iPhoto 7
/Library/Application Support/iPhoto/Plugins
iPhoto 5 or 6
/Applications/iPhoto.app/Contents/PlugIns

Delete the ExportToArchive.iPhotoExporter directory from whichever place it’s been installed to, and once you restart iPhoto, you should be fine.

iWork vs. CVS

Monday, August 27th, 2007

I recently bought the new iWork ‘08 suite from Apple and have started using the tools for stuff I used to use NeoOffice for. But I noticed something yesterday that is disconcerting.

Like a lot of people, I store my documents in a CVS repository that is backed up to another disk. I checked in a few documents created with Pages and Numbers, and everything seemed fine. That is, until I re-saved any of the documents.

The problem lies in the fact that a “document” for Pages or Numbers (and probably for Keynote as well) is not a monolithic file like a .doc file from Word. They are directory structures (”bundles” is the Apple term) that the Finder and the applications that use them treat specially. Any program in the /Applications folder is the same type of thing. When you check something into a CVS repository, CVS creates a hidden CVS directory in each sub-directory of the thing being checked in. After checking in one of these documents, I went into the document through Terminal and verified that the CVS directories had been created. So far, so good.

When things went awry was when I re-saved a document. Instead of just changing the necessary files inside the “document,” Numbers deleted and re-created the entire directory structure. Thus, those CVS directories were toast. There’s no good way to recover from this, because those files now look like non-CVS files, but the server already knows about them. To my knowledge, there’s no painless way to handle this situation.

I don’t believe that Subversion is in any better position. When using SVN, you get a .svn directory created in each sub-directory of the document, but those will also get whacked when the document is re-saved. I haven’t tested that assumption, but it seems logical.

I tried to come up with a solution to this, but I’m stumped. I looked into cvswrappers just to see if it could help, but it doesn’t look like it. I also considered a pre-commit script and a post-checkout analog (if there is one), but this didn’t seem like it would really get us there.

The only solution I see is for Apple to stop whacking the directory structure and just change the files inside it that it needs to, and stop molesting the version-control special files. Maybe they can implement this behavior when they add support for OpenOffice and the OpenDocument format…

Capturing Middle-Mouse Click in Safari

Thursday, July 12th, 2007

I have been a consistent user of the nightly builds of the WebKit project for some time now. For those of you who don’t know, WebKit is essentially the work-in-progress that will be the next production version of Safari. I like the nightlies because they are extremely fast, and while they occasionally have problems, that’s OK.

The point of that discussion was to say that I have stopped using Firefox on my Mac, because the nightly builds of WebKit are so much faster. But there’s one problem. In Firefox I could click a tab with my middle-mouse button, and it would close. Safari doesn’t have that feature, and that’s the one feature from Firefox that I really miss.

So, I’ve been trying to solve this problem using SIMBL. What SIMBL does is let you write a standard Cocoa bundle and have it load into another program, like Safari. Once loaded, you can replace methods in the application with your own versions, in a way known as “method swizzling.” I have successfully written a Cocoa bundle, made the approrpriate changes to make it loadable by SIMBL, and have loaded it into Safari/WebKit. I have logging statements at various points in the bundle, and I can see these on the system console, thus I know it’s loading.

Once the bundle was loading, I needed to pick the objects and their methods that I thought would be most likely to let me do what I needed, and then swizzle in my changes. Using F-Script Anywhere I was able to identify a single tab as an instance of TabButton. Using class-dump I was able to generate header files for Safari that would let me see the methods on TabButton and it’s parents. My first thought was to override mouseUp:. This works, and I can now trap mouse events when you click on any tab. According to the Apple docs, once I get a mouse event, I should be able to call [theEvent buttonNumber] to figure out which button was pressed. Well, maybe. No matter if I clicked with the left- or middle-mouse button, [theEvent buttonNumber] always returned 0. Further digging in the docs turned up an event called NSOtherMouseUp that is sent when a button “other” than left- or right-mouse is clicked. Supposedly, I should be able to override otherMouseUp: to get those events. I have successfully swizzled this method, but it never gets called. I know that TabButton had a version of this method, because when I swizzle, I can tell if there was already a method there, and there was. I’m just not sure why it isn’t being called.

So what did I get working? Well, after working a long time trying to get the middle-mouse detection working, I decided to punt for the moment. I added some code to the mouseUp method to check the event for modifiers and if the user held down Command while clicking, then I will close the tab. This is close to what I want, but nearly as sexy as just middle-mouse clicking. In case you’re interested, my TabButton.m looks like this:

 	 1 #import "TabButton.h" 	 2 #import "WebKit/WebKit.h" 	 3  	 4 @implementation TabButton (MCCSwizzle) 	 5 - (void)_mcc_mouseUp:(NSEvent *) theEvent 	 6 { 	 7   NSLog(@"_mcc_mouseDown"); 	 8   int buttonNumber = [theEvent buttonNumber]; 	 9  	10   NSLog(@"buttonNumber: %d", buttonNumber); 	11   NSLog(@"type: %d", [theEvent type]); 	12   NSLog(@"modifierFlags: %d", [theEvent modifierFlags]); 	13  	14   if ([theEvent modifierFlags] & NSCommandKeyMask) { 	15     NSLog(@"Cmd-Click!"); 	16     [self closeTab: theEvent]; 	17   } else { 	18     [self _safari_mouseUp: theEvent]; 	19   } 	20 } 	21 @end 	

and then the swizzling looks like this:

 	 1 #import  	 2 #import "AppController.h" 	 3 #import "MiddleClickClose.h" 	 4  	 5 typedef struct objc_method *Method; 	 6  	 7 struct objc_method { 	 8   SEL method_name; 	 9   char *method_types; 	10   IMP method_imp; 	11 }; 	12  	13 BOOL MCCRenameSelector(Class _class, SEL _oldSelector, SEL _newSelector) 	14 { 	15   NSLog(@"OLD: %s", _oldSelector); 	16   NSLog(@"NEW: %s", _newSelector); 	17  	18   Method method = nil; 	19  	20   // Look for the methods 	21   method = (Method)class_getInstanceMethod(_class, _oldSelector); 	22   if (method == nil) 	23     return NO; 	24  	25   // Point the method to a new function 	26   method->method_name = _newSelector; 	27   return YES; 	28 } 	29  	30 @implementation MiddleClickClose 	31 + (void) load 	32 { 	33   int rc; 	34  	35   rc = MCCRenameSelector([TabButton class], @selector(mouseUp:), 	36                                    @selector (_safari_mouseUp:)); 	37   NSLog(@"RC: %d", rc); 	38  	39   rc = MCCRenameSelector([TabButton class], @selector(_mcc_mouseUp:), 	40                                                  @selector(mouseUp:)); 	41   NSLog(@"RC: %d", rc); 	42  	43   rc = MCCRenameSelector([TabButton class], @selector(rightMouseUp:), 	44                                    @selector (_safari_rightMouseUp:)); 	45   NSLog(@"RC: %d", rc); 	46  	47   rc = MCCRenameSelector([TabButton class], @selector(_mcc_rightMouseUp:), 	48                                                  @selector(rightMouseUp:)); 	49   NSLog(@"RC: %d", rc); 	50  	51   NSLog(@"MiddleClickClose loaded"); 	52 } 	53  	54 + (MiddleClickClose*) sharedInstance 	55 { 	56   static MiddleClickClose* plugin = nil; 	57  	58   if (plugin == nil) 	59   { 	60     plugin = [[MiddleClickClose alloc] init]; 	61   } 	62  	63   return plugin; 	64 } 	65 @end 	

Line 35 renames Safari’s original mouseUp: method to _safari_mouseUp: and then line 39 renames my _mcc_mouseUp: method to mouseUp:. The otherMouseUp: method is handled on lines 43 and 47, but as I said otherMouseUp never gets called.

What’s especially frustrating about this is that I know Safari knows how to bag a middle-click, because I frequently will middle-click on a link in a web page, and Safari will open that link in a new tab. So, why can’t I get a middle-click in the TabButton instance? Does anyone have any ideas on this? I’d appreciate any pointers. I feel like I’m thiiiiiiiiiiis close to getting this working, but there’s some small piece of info that is eluding me.

03/03/2008 Update: I got this working and have released it under the GPL. Read about it and get it over here.

Third Time’s The Charm on Mac RAM — I Hope

Thursday, July 5th, 2007

Being at the end of a UPS route is hard. Tuesday morning I saw from the UPS website that my third set of RAM from Crucial was “out for delivery” from the local hub. What this means is that it’s on a truck, heading for my house. Unfortunately, we’re at the tail-end of said route, and I have yet to receive a UPS delivery before 4:00 PM. We were going to be leaving around 5:00 and since UPS is a “drop and run” courier, if it got there after we left, it would have been sitting on the porch for several hours until we got home. Fortunately, it arrived about 4:45. So it got inside the house, but wouldn’t get inside the Mac until later.

When I got home Tuesday night, I installed the RAM. So far, it’s working perfectly. Of course, the first set worked perfectly for a week or so, so I’ll have to just keep an eye on it. Thus, once again, my Activity Monitor looks like this

Mac Pro RAM Woes

Wednesday, June 27th, 2007

You may remember how excited I was about a month ago when I got the 2GB RAM upgrade from Crucial for my Mac Pro. Well, about two weeks ago I happened to notice in Activity Monitor that I only had 3GB of RAM. That wasn’t right; I had 4GB. I started testing, and discovered a problem with the RAM. System Profiler was reporting 6 512MB sticks of RAM, instead of 4 512MB and 2 1GB sticks. I tried moving the sticks around to various banks, but never got it to see more than 3GB. Also, there are four LED’s on each of the risers that correspond to the four RAM banks. When you boot the system, these lights come on for about 2 seconds, then go out. There was one Crucial stick whose LED stayed on. No matter which bank I put that stick in, its light stayed on.

Saddened by this, I called Crucial. I spent just a few minutes on the phone with them before they agreed that there was clearly a problem, and that they would replace them. They have excellent customer and technical support. I shipped the two sticks back to them and waited.

Two days ago UPS arrived with my replacement sticks. I shut down my Mac and put the two new sticks in banks 3 and 4 of riser A, leaving the 512MB sticks in banks 1 and 2 of risers A and B, and booted. I logged-in, brought up Activity Monitor, only to see 3GB reported. System Profiler says 6 512MB sticks, just like before. The new RAM is doing exactly what the first set of RAM did. I tried every combination of placement of the sticks I could think of, including removing ALL the Apple RAM, and just putting the Crucial sticks into banks 1 and 2 of riser A. In that case, the Mac only saw 1G of RAM.

So it was back to Crucial tech support. They agreed it sounded like a bad stick (again) and are going to replace them again. I just shipped back the two latest sticks, and am once again waiting on a shipment from Crucial. I hope this one works. If it doesn’t, I’m just going to pony up the 2x extra and buy direct from Apple.

The Crucial guy said it was “hard to believe” that I got two bad sticks in a row, and I agree. But what else could it be? If I only had two banks for RAM in the computer, then you could blame it on the computer itself. But I’ve got eight banks to play with, and have tried them all. I don’t think it’s a problem with the Mac itself. I could be wrong, but I don’t think so.