Archive for 2007

Free stuff on Amazon: Now four at a time

Friday, December 28th, 2007

This week, rather than having one free song listed on the front page of the Amazon MP3 Store, they have four free songs listed on their Special Deals page.

Interesting how two of the songs (“100 Days, 100 Nights” and “Holiday Twist”) both sound like they’re from the 1960s, but they’re actually brand-new from this year. Also interesting how Los Straitjackets (“Holiday Twist”) have now had a free song on both iTunes (“Sleigh Ride”) and Amazon.

(And yes, I know that iTunes link doesn’t work. I don’t know why; it turns up in the search results.)

Google sure is fast nowadays

Wednesday, December 26th, 2007

I created a page on the Adium wiki at 07:07 PST, and Google had it indexed by 08:01. This screenshot is of a search for “darcs patch bundle binary”.

The times shown in the screenshot are in EST; I created the page at 07:07 PST, and found it among those search results at 08:00 PST.

Dammit, Panda Express!

Sunday, December 23rd, 2007

They have adulterated my beloved Fried Rice.

Panda Express Fried Rice used to contain five things:

  • Rice (duh)
  • Bits of fried egg
  • Carrots, diced
  • Peas
  • Chopped celery (unthrilling, but tolerable)

Today, I bought some fried rice, and look what they’ve added:

  • Chopped red peppers
  • An orange unidentifiable fruit/vegetable chunk; either of another pepper of some kind, or of an underripe tomato
  • Exactly one slice of carrot (crinkle-cut), in addition to the diced carrots [Edit: When I went back to it to finish off the second half of it, I found another slice.]
  • Fucking broccoli

Don’t mess with my rice!

I can only hope that this was simply the result of having some spare parts that they needed to use up, and that another batch of fried rice (or another Panda Express) would not provide such contamination.

UPDATE 2008-01-06: I had lunch at the Costa Mesa store today, and they did not befoul my fried rice in this way. Good to know.

Free stuff on Amazon: Bonus free download

Sunday, December 16th, 2007

If you went to the Amazon MP3 Store on Wednesday and are like me, you stopped scrolling at the free download.

Keep scrolling—I did (just today), and found that there’s a second free download this week. Here’s the direct download link. Be aware that it’s a rap song with some naughty words in it.

The iPhone flashlight

Thursday, December 13th, 2007

If you should have an urgent need for a flashlight, but have only an iPhone or an iPod touch with you, fear not. Now you have an iPhone flashlight.

More Darcs win: Selective recording

Wednesday, December 12th, 2007

Darcs lets you choose which changes you want to include in a patch (commit). For example:

darcs rec                                                   %~/ASL test apps/aslsearch(0)
move ./aslsearch.m ./aslsearch.c
Shall I record this change? (1/?)  [ynWsfqadjkc], or ? for help: y
hunk ./aslsearch.c 1
-#import <Foundation/Foundation.h>
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <vis.h>
-#include <asl.h>
-
Shall I record this change? (2/?)  [ynWsfqadjkc], or ? for help: n
hunk ./aslsearch.c 29
-       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
Shall I record this change? (3/?)  [ynWsfqadjkc], or ? for help: y
hunk ./aslsearch.c 75
-       [pool release];
Shall I record this change? (4/?)  [ynWsfqadjkc], or ? for help: y
hunk ./aslsearch.c 194
+       fprintf(stderr, "key: \e2\80\9c%s\e2\80\9d\noperator: 0x%x\nvalue: \e2\80\9c%s\e2\80\9d\n", key, operator, value);
Shall I record this change? (5/?)  [ynWsfqadjkc], or ? for help: n
hunk ./aslsearch.xcodeproj/project.pbxproj 10
-               8DD76F9A0486AA7600D96B5E /* aslsearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* aslsearch.m */; settings = {ATTRIBUTES = (); }; };
+               8DD76F9A0486AA7600D96B5E /* aslsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* aslsearch.c */; settings = {ATTRIBUTES = (); }; };
Shall I record this change? (6/?)  [ynWsfqadjkc], or ? for help: ?
How to use record...
y: record this patch
n: don't record it
w: wait and decide later, defaulting to no

s: don't record the rest of the changes to this file
f: record the rest of the changes to this file

d: record selected patches, skipping all the remaining patches
a: record all the remaining patches
q: cancel record

j: skip to next patch
k: back up to previous patch
c: calculate number of patches
h or ?: show this help

<Space>: accept the current default (which is capitalized)
hunk ./aslsearch.xcodeproj/project.pbxproj 10
-               8DD76F9A0486AA7600D96B5E /* aslsearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* aslsearch.m */; settings = {ATTRIBUTES = (); }; };
+               8DD76F9A0486AA7600D96B5E /* aslsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* aslsearch.c */; settings = {ATTRIBUTES = (); }; };
Shall I record this change? (6/?)  [ynWsfqadjkc], or ? for help: f
hunk ./aslsearch_Prefix.pch 5
-#ifdef __OBJC__
-#      import <Foundation/Foundation.h>
-#endif
-
Shall I record this change? (10/?)  [ynWsfqadjkc], or ? for help: y
hunk ./aslsearch_Prefix.pch 8
+#include <unistd.h>
Shall I record this change? (11/?)  [ynWsfqadjkc], or ? for help: n
What is the patch name? Switched source file from Obj-C to pure C
Do you want to add a long comment? [yn]n
Finished recording patch 'Switched source file from Obj-C to pure C'

(Before you mention the UTF-8 sequences that Darcs called out as invalid ASCII: Yes, I know.)

And an answer: What to do if your table view shows the whole array in every row

Sunday, December 9th, 2007

Before writing my previous post, I had asked some people on IRC for help, including David Smith, who is a fellow Adium developer. He remembered a solution, but uncertainly. One thing he said, though, proved relevant: “You have two NSTableColumns; which one is it [NSTableView] creating the content binding from?”

David was referring to the content binding of NSTableView, which I had dismissed as an artifact of an earlier design of NSTableView, or perhaps a simplified path for those people who had only one column in their table view. (I saw the mention in the docs that the table view binds it automatically to the value of one of its columns’ value bindings, but didn’t make any connections then.)

This latter explanation made the content binding incompatible with my app, since I had two parallel arrays of NSStrings (one array contained keys, and the other contained values). So I continued looking for a solution, and eventually gave up and wrote the post.

After I published it, Scott Anguish posted a comment on it:*

you can’t have simple arrays of strings as the content of an array controller. it doesn’t work. You need to have an array of objects of some sort that have an attribute, even if they’re just NSDictionaries with a single attribute called “string”.

I don’t believe that NSArrayController has a special case for NSString, but Scott’s comment got me thinking. I added a category to NSString that added a -selfString method, then added that name as the model key path in the table columns’ value bindings. I was wondering, you see, whether this would be enough to satisfy NSTableColumn and NSArrayController.

It still didn’t work. At this point, I had the idea to fire up F-Script Anywhere and have a look around. I did that, and was digging down to the table columns when I noticed this:

That’s FSA’s object browser, showing the table view. So the table view’s content binding was bound to the keys array controller, with a model key path of lastMessageKeys.

That’s why the keys were showing up fine—they were in the array that was in the table view’s content binding. The values array was a different array with a different array controller, so NSTableView threw up its hands and simply showed the entire array’s description.

This is the point that Scott came close to: NSTableView expects you to have one array of model objects—no more. My parallel arrays of NSStrings do not qualify, because only one of the array controllers can be the value of the table view’s content binding.

So what role do the columns play? Well, each row in the table view (and by that, I mean *the whole row*) corresponds to one of those model objects. The value in each column is then determined by the model key path in the value binding of the corresponding NSTableColumn.

Thus, all the NSTableColumns’ value bindings must be bound to the same array controller and the same controller key, and each column should be bound to a different model key path. Your columns’ value bindings should look like this:

Column “Foo” Column “Bar”
Bind to: Your one array controller
Controller key: arrangedObjects (or whatever)
Model key path: foo Model key path: bar

In my case, of course, this required creating a new model class for a key-value pair, to replace the parallel arrays of NSStrings. This is a good thing, since it brings conceptual purity to my design. Remember, Cocoa is designed around MVC; I didn’t have enough M in my app, which was the problem.

So, in summary, here’s the fix for an NSTableColumn that shows the entire array in every row:

  1. Replace your evil parallel arrays with a model class, and a single array of instances of that class.
  2. Delete all but one of your array controllers, since you now have only one array. Update the remaining controller’s model key path to point to your new array (I assume you renamed it).
  3. Bind all of the table columns to your new One True Array Controller, distinguishing the columns only by the model key path, which identifies which property you want the column to show for each model object.

Many thanks to both David and Scott for their help in discovering the root of the problem.

* Scott posted his comment on the previous post with no last name; he identified himself in a comment on this post.

I have a question

Saturday, December 8th, 2007

See also the follow-up: And an answer: What to do if your table view shows the whole array in every row.

Normally, on this blag, I give answers.

This time, I have a question.

Here’s my problem:

I have a window containing a table view. The table view has two columns, labeled “Keys” and “Values”.

Each column’s value binding is bound to an NSArrayController; each array controller’s contentArray binding is bound to a property of my application delegate; each property’s value is an NSArray of NSStrings.

The Keys column correctly has one of its strings in each row. The Values column incorrectly has its array in every row. This is the problem that has stumped me.

The object class is NSString in both array controllers. There’s no Core Data in this app.

I have 12-tuple-checked the bindings in IB; they are the same between the two array controllers and between the two table columns.

The accessors are automatically generated by my accessor-generator services. Even so (having added some debug logging previously), I double-checked them, and they are the same.

I have logged the contents of both arrays in my setters. Both arrays are arrays of strings, and both contain the same number of strings.

This problem manifests on both Tiger and Leopard.

Here are screenshots of my Bindings Inspectors:

The array controllers' contentArray bindings are bound to the app delegate's lastMessageKeys and lastMessageValues properties. There is no value transformer in use. The options that are turned on are Conditionally Sets Editable and Raises For Not Applicable Keys; the options that are turned off are Always Presents Application Modal Alerts, Deletes Objects On Remove, Handles Content As Compound Value, Selects All When Setting Content, and Validates Immediately.

The table columns' value bindings are bound to the array controllers' arrangedObjects properties. There is no value transformer in use. The options that are turned on are Allows Editing Multiple Values Selection, Conditionally Sets Editable, Creates Sort Descriptor, and Raises For Not Applicable Keys; the options that are turned off are Always Presents Application Modal Alerts, Conditionally Sets Enabled, Continuously Updates Value, and Validates Immediately.

Each screenshot has two Inspectors superimposed on each other, with the upper Inspector set to half opacity; the result is that pixels that are the same look normal, whereas pixels that differ look ghostly. For your ease of reading, I knocked out the parts that differ and staggered them, so you don’t have to try to make out ghostly text.

Any suggestions?

A possible solution to the stolen-focus problem

Wednesday, December 5th, 2007

Jeff Atwood posted an article today titled Please Don’t Steal My Focus, about dialog boxes coming up while you’re typing.

The problem, in a nutshell, is that these dialog boxes steal keyboard focus. Sometimes it’s for a text field; sometimes it’s just for Full Keyboard Access (i.e., a button gets the focus—usually, these are alert boxes). Regardless of what control gets keyboard focus, it gets it by stealing it from your app, which is a problem if the user is typing when that happens. Most likely, either some text will go to the wrong place, or the dialog box will beep for every keystroke; either result will annoy the user.

We’ve had the same problem for a long time in Adium: we’ll throw up a dialog box, but the user is typing a message, and notices that half his message isn’t in the inputline. We believe we’ve fixed most of these, but we still get complaints about this problem from time to time.

Currently, we solve the problem by simply ordering the dialog front without making it key. This works for most people, but it doesn’t help people who really do need Full Keyboard Access, since you have to click on the dialog box to dismiss it (or make it key) if it isn’t key. We (by which I mean Mac programmers, not just Adium) need a better solution.

I propose an addition to NSAlert. Here’s how it would work:

  1. From the creation of the NSAlert instance, it watches for key events.
  2. When any key goes down, the alert resets the timer (if one is present) and sets a flag.
  3. When all keys are up, the alert creates and starts the timer (with an interval of, say, a couple of seconds).
  4. If you tell the alert to show, it checks the flag. If the flag is clear, it simply performs makeKeyAndOrderFront: like usual. If the flag is set, it only orders front, and it sets a second flag.
  5. When the timer fires, the alert clears the first flag, and if the second flag is set, makes itself key.

From the user’s perspective, this results in the alert waiting a couple of seconds for them to pause in their typing before it takes keyboard focus.

Does anybody know of an existing free implementation of this, or plan to write it themselves?

Blog spam count: 2007-10

Tuesday, December 4th, 2007

Spam comments blocked by Negative Turing Test in October 2007 (and November 1–3):

20,221

Blast from the past

Monday, December 3rd, 2007

The NeXT keyboard had volume and brightness keys.

This casts Apple’s recent keyboards in a whole new light for me.

(Image courtesy of Patrick Gibson. I cropped and spotlit it using Acorn.)

I originally saw this keyboard on Wikipedia, but Patrick was nice enough to take a better photo—thanks!

I think somebody mixed up their phishing emails

Sunday, December 2nd, 2007

From: Bank Of America Security Dept. Subject: IMPORTANT: Security Issues [Incident: 0409252]. Body: You have just received a virtual postcard from a family member!
What is this, scamming for victims with ADD?

From svn to darcs: Listing unknown files

Sunday, December 2nd, 2007

If you’re an svn user looking at darcs, you may wonder how to find unknown files—that is, files that you’ve created in your working directory, but haven’t yet told your VCS about (with svn add or darcs add). In svn, the command is svn st, but in darcs, the procedure is not obvious.

The darcs command that most seems like what you need is darcs whatsnew, or, as I type it, simply darcs what. Like svn st, this shows you all files that have been added, removed, or modified; it also includes a diff, so not only is it your substitute for svn st, it’s also your substitute for svn diff. But it doesn’t show you unknown files.

Until you use the -l (that’s a lowercase L) option.

darcs what -l changes the output greatly, as it’s in a completely different format: one similar to that of svn st. The format is actually that of darcs what -s (summary mode); the difference is that -l also lists unknown files.

There are some differences between darcs what -l and svn st. Some of these differences are:

  • darcs uses fewer columns than svn: It has one status column, whereas svn has six.
  • darcs uses ‘a’ to indicate an unknown file, whereas svn uses ‘?’.
  • darcs uses ‘R’ to indicate a file that you’ve removed, whereas svn uses ‘D’ to indicate a file that you’ve deleted. (svn supports remove and rm as synonyms for its delete command, but darcs does not support delete nor rm as synonyms for its remove command.)

Thanks

Friday, November 30th, 2007
  • To Brent Simmons and Mike Lee.
  • To Matt Drance, who gave me a ride back to my hotel tonight.
  • To Colin Barrett, who gave me a ride back to my hotel (more or less) on Tuesday. (We did not go directly to the hotel.)
  • To Bill Bumgarner, who brought 33 pounds of delicious pork. I think our row of tables needed two more to seat all the people who came for it.
  • To Blake C., who is still the biggest fan of this blag.
  • To everybody, who knew exactly what I was talking about every time I said “blag”. I loved that.
  • To Wil Shipley and Brent for picking up a couple of tabs.
  • To Brent, for supplying me with Yellow Cab’s phone number, so that I could call us a cab back to the hotel. Also for paying the fare.
  • To John Geleynse for the invitation, and to Evan Schoenberg for forwarding it on.
  • To everybody who helped me with stuff at the event (including, but not limited to, Deric Horn, Michael Jurewitz, and Peter Ammon).

Let me know if you did something for me this week and I forgot to thank you, or if you want me to remove you from the list for some reason.

I cannot leap tall buildings in a single bound

Wednesday, November 28th, 2007

And despite Google Transit’s insistence, I cannot legally cross all those lawns:

Google Transit told me that to get from my location in Cupertino to 1 Infinite Loop, I can simply walk in a straight line (which it depicts as an arc)—crossing through a residential block and apparently jumping over most of the Apple Campus.

How much of an Alex is it?

Saturday, November 24th, 2007

Those of you who listen to MacBreak Weekly are familiar with the imaginary unit of currency, the Alex.

For those of you who don’t listen to MBW: Alex Lindsay, one of the co-hosts, typically goes in for very expensive software—upward of a kilobuck. So his co-hosts defined one Alex as equal to $700 USD (roughly the price of Photoshop at the time). With this, the hosts express the prices of the software that they spotlight each week in fractions of an Alex: a $10 program, for example, would be stated as costing “¹⁄₇₀th of an Alex”. Something that is free costs “zero Alexes”.

To that end, here’s a table of prices expressed in both USD and Alexes. If you ever have an urge to tell a friend how much some piece of software costs, simply look up the price on this table and give it to your friend as a fraction of one Alex. Alternatively, use this converter service, which I created with ThisService.

If you want a more complete table, here’s one from $1 to $14,000.

USD Alex
1.00 ¹⁄₇₀₀
2.00 ¹⁄₃₅₀
3.00 ³⁄₇₀₀
4.00 ¹⁄₁₇₅
5.00 ¹⁄₁₄₀
6.00 ³⁄₃₅₀
7.00 ¹⁄₁₀₀
8.00 ²⁄₁₇₅
9.00 ⁹⁄₇₀₀
10.00 ¹⁄₇₀
15.00 ³⁄₁₄₀
20.00 ¹⁄₃₅
25.00 ¹⁄₂₈
30.00 ³⁄₇₀
35.00 ¹⁄₂₀
40.00 ²⁄₃₅
45.00 ⁹⁄₁₄₀
50.00 ¹⁄₁₄
55.00 ¹¹⁄₁₄₀
60.00 ³⁄₃₅
65.00 ¹³⁄₁₄₀
70.00 ¹⁄₁₀
75.00 ³⁄₂₈
80.00 ⁴⁄₃₅
85.00 ¹⁷⁄₁₄₀
90.00 ⁹⁄₇₀
95.00 ¹⁹⁄₁₄₀
100.00 ¹⁄₇
150.00 ³⁄₁₄
200.00 ²⁄₇
250.00 ⁵⁄₁₄
300.00 ³⁄₇
350.00 ¹⁄₂
400.00 ⁴⁄₇
450.00 ⁹⁄₁₄
500.00 ⁵⁄₇
550.00 ¹¹⁄₁₄
600.00 ⁶⁄₇
650.00 ¹³⁄₁₄
700.00 ¹⁄₁
750.00 ¹⁵⁄₁₄
800.00 ⁸⁄₇
850.00 ¹⁷⁄₁₄
900.00 ⁹⁄₇
950.00 ¹⁹⁄₁₄
1000.00 ¹⁰⁄₇

Cool new feature in iPod Touch Software 1.1.2

Thursday, November 15th, 2007

Your iPod touch's row in iTunes' source list now has an icon that indicates your battery status and whether the battery is charging.

Why you should use spaces before your method arguments

Monday, November 12th, 2007

You can select a rectangle that intersects the spaces. You can't do this with tabs.

Backstory: I had moved the method being called there from a file of NSCalendarDate additions to a file to NSDate additions, so I needed to remove “Calendar”, and wanted to also take out the now-extraneous alignment spacing. One rectangular edit did the job, thanks to using spaces for the alignment.

Of course, you should always use tabs for that initial indent.

How to make X11 work better on Leopard

Monday, November 5th, 2007

On the X.org XDarwin page, Ben Byer of the XDarwin team is providing a fixed-up version of Leopard’s X11 for download. I’ve installed it and I’m pleased so far.

It’s a mixed bag so far, but then, that’s why it’s alpha. Let’s go through the items from my X11 on Leopard is broken post and see how far they’ve come in the week since the Leopard launch. I’ll list the fixed ones first, then the unfixed ones:

  • Option-click [and ⌘-click] is broken

    Fixed. Both work as expected: option-click middle-clicks and ⌘-click right-clicks.

  • Windows don’t stop at the menu bar

    Fixed.

  • Applications menu doesn’t work with arguments

    Fixed.

  • xterm ignores .Xdefaults when invoked through the Applications menu

    (I never got around to adding this one to the previous post; sorry.) Fixed.

  • Wireshark is broken (from the comments on the previous post)

    Fixed, according to Bert JW Regeer’s comment.


  • .xinitrc is ignored (sort of)

    Not fixed.

  • xterm ignores .Xdefaults when invoked by login

    Not fixed.

  • Two X11s

    Not fixed. I’m not sure that this is fixable; it’s just an unfortunate side effect of the factorization of X11 into an xterm-launcher and a server.

  • It still looks like Tiger

    Not fixed.

  • X11 doesn’t activate like it’s supposed to (reported by Alan Boyd)

    Not fixed.

New Leopard Dock separator

Monday, October 29th, 2007

If you’re like me, you reject Leopard’s new 3D-looking Dock out of hand, preferring the new 2D smoke look also introduced in Leopard. All it takes is a simple defaults command to switch the Dock from 3D to 2D mode.

I think the new 2D Dock looks a lot cooler than the Dock in Tiger, except for one part that, for me, sticks out like a sore thumb.

It’s the separator between the applications and not-applications sections.

Here’s what Tiger’s separator looks like:

It's just a black line completely bisecting the Dock's background.

Simple; gets the job done.

Leopard, on the other hand, has a goofy-looking zebra crossing instead:

A zebra crossing, in case you don't know, is a series of white (or in this case, light gray) lines. It's named for the alternating black and white stripes of the zebra, which the zebra crossing vaguely resembles.

I can’t have that. So I fired up Lineform and created a new separator that I think looks a lot better:

My separator is a glowing white line.

Obviously, it’s modeled after the white LEDs that have replaced the black arrowheads to mean “application is running”.

In case you prefer this separator as much as I do, here’s how to install it:

  1. Download this image. I’ll assume you downloaded it to ~/Downloads.
  2. If you keep your Dock on the left or right edge of the screen, open the image in Preview and rotate it.
    • If your Dock is on the right edge, rotate the image left (⌘L).
    • If your Dock is on the left edge, rotate the image right (⌘R).
  3. Rename the image file. If your Dock is on the bottom, name it separatorstraight.png; otherwise, name it separatorstraight-horizontal.png.
  4. Open a second Finder window.
  5. Hit ⇧⌘G and go to /System/Library/CoreServices/Dock.app/Contents/Resources.
  6. Make a backup of the separatorstraight.png or separatorstraight-horizontal.png file from that folder.
  7. Move (⌘-drag) the image file from ~/Downloads to the Resources folder.
  8. Authenticate, if necessary.
  9. Open a terminal window and killall Dock. The Dock will relaunch automatically.

I haven’t made a 3D version. If you want one, post a comment. It shouldn’t be too hard to make, thanks to vector graphics.