Archive for the ‘Vienna’ Category

Vienna 2.1.1 released

Saturday, January 27th, 2007

Vienna is new and improved! Now 10% more code for the same low price. Plus, we’ve added flavonoids! And innovative macro-absorber technology! It’s guaranteed to blow your mind while toning your thighs. If you have liver disease or high blood pressure, do not use Vienna with a bottle of bourbon.

See the release notes for all of the exciting details. Vienna 2.1.1 is available for download now at your local Starbucks or wherever coffee is sold.

Microsoft Vienna

Saturday, January 13th, 2007

No, we’re not porting to Windows. Rather, it appears that Microsoft wants to use the name of our software, Vienna, for a future version of their software.

Hmmm. What’s that famous line from “Jerry Maguire”?

(No, not that line. The other line.)

Bring back STX and ETX

Saturday, December 30th, 2006

Some people think that XML is the greatest invention since sliced bread. (I won’t name names, to protect the non-existent.) In contrast, I think that it’s just a symptom of a disease, a terminal illness infecting the entire computing world. Programmers are supposed to be smart, but we’re actually the ones who are responsible for the spread of the disease. We started and promoted the practice of using printable text to delimit printable text. In my haughty opinion, this was one of the worst ideas in the history of computers (surpassed only by SMTP and MacAppADay). It was doomed to fail from the beginning, kind of like the paradox of the liar. The use of printable text to delimit printable text has been the cause of countless bugs — let’s say 500 billion — and indeed, countless security vulnerabilities. It continues to plague us today.

Having worked on a feed reader, I do know a thing or two about this issue. I can tell you that it’s a major pain to parse XML feeds. Parsing HTML is even worse, but thankfully we can leave the majority of that to WebKit. It’s hard enough when everything is perfect, but we inevitably run into issues where the text is improperly escaped or not properly escaped. This is no fun for anyone.

Since the beginning, ASCII contained a number of non-printing control characters, but for some reason they have fallen out of favor. Among the control characters are STX (0x2) and ETX (0x3). Their position in the list of character codes indicates their importance: they were used to delimit text. With character codes such as these, parsing data into strings becomes trivial:

  1. Start parsing a string when you see a STX code.
  2. Continue until you see a ETX code, you see a non-character code, you reach a preset maximum length, or you run out of data.
  3. If the last code was ETX, you’ve got a good string. Otherwise, you’ve encountered an error, and you can do whatever error handling you like.
  4. There are no more steps. The characters in the string are all literal, no unescaping necessary.

Unicode has added some similar codes such as SOS and ST. I’d like to see even more control codes, to allow for fine-grained specification of the structure of the text. For example, we could have control codes to delimit words, sentences, paragraphs, etc. This would be similar to tags in HTML but without the use of printable characters to represent the tags.

Why don’t we do this now? One objection is that files containing control characters are not human readable. I think that this is a lame excuse, because no computer file is human readable. Although my hard drive is enclosed, preventing me from examining the files on there, I have burned text files to DVD, and no matter how long I stare and squint at the shiny bottom, all I can see is my own reflection. Anyway, a lot of markup is human readable only in the sense that Derrida is human readable: there is a series of legible text characters, but do you really want to wade through all the crap to make sense of it?

Perhaps the real point underlying this objection is that control-character delimited text would not be readable by simple (i.e., dumb) text editors. This is true, but why should we be ruled by the lowest common denominator? Many modern text editors are quite intelligent and could handle the new format easily. They can already parse various forms of syntax and highlight them for the user. Let’s not let backward compatibility hold us back. That’s certainly not the Apple Way. It’s not entirely the Microsoft Way either; after all, the Word file format makes no concession to simple text editors. Neither does the cross-platform Adobe PDF.

The most powerful objection to using control characters as text delimiters is that we shouldn’t force users to learn how to input control characters along with text. I agree, which is why I think the burden should be placed on computer programs — the text editors and command line interpreters — rather than on users. When taking text input from users, an app should do the following:

  1. Use the context to guess the user’s intention.
  2. Give a visual indication of the guess to the user. Syntax coloring is one example, but the possibilities are endless. Be creative.
  3. Make it easy for the user to correct bad guesses.

In command line interpreters, by the way, there’s no good reason why the space key needs to separate arguments, as opposed to a key for a non-printable character such as escape. It’s the 21st century, by Jove, and we should be finally be able to use any printable character in a file name, including colons, quotes, slashes, and spaces, without having to do voodoo on the command line just to refer to it! (I won’t even mention hierarchical file systems, which are themselves a bad idea. Oops, I just did. Since I mentioned it, the ideal behavior when a user enters a file name is to quickly find the named file or files, which any decent file system should be able to do, and show a visual preview so that the user can verify or choose the correct file, if necessary.)

This rant has been brought to you by BBEdit. The makers of BBEdit, I assume, take no responsibility or credit for the content here, nor do they endorse the opinions I’ve expressed. (Or do they?)

(No, not as far as I know, which is nothing. In any case, I do endorse BBEdit.)

WordPress Bug Friday: Wasting your bandwidth

Sunday, December 17th, 2006

I intended to post this on Friday. As they say when receiving a crappy Christmas gift, It’s the thought that counts. (They lie.) I should probably give myself a break and just change the official name to WordPress Bug Near Friday. Well, so be it. Make it so. Engage. Energize. Giddyup!

Usually I’m bemoaning the existence of HTTP 304 (Not Modified) responses, but this time the problem was the non-existence of them. (Can there be such a thing as non-existence? Where would you find it? And can you deduct it from your taxes?) I noticed when looking through my web site logs that feed requests from NetNewsWire always received an HTTP 200 (OK) response from WordPress, never 304, which means that NetNewsWire downloaded the entire content of a feed on every request. Since my web site gets more hits from NetNewsWire than from any other browser, that’s quite a lot of bandwidth used. (Relatively speaking, that is. In the grand scheme of things, my page ranking is right below the site for Grasshopper Enthusiasts of Eastern Ontario.)

Brent Simmons, the creator of NetNewsWire, was kind enough to talk to me about the problem, despite the fact that my app, Vienna, has undoubtedly taken away some sales from him. (In fact, I was all set to purchase NetNewsWire myself until I discovered Vienna.) I’m not worried about Brent, though: I heard that NewsGator paid him something like a trillion dollars for NetNewsWire, give or take. Plus he gets as many Café Lattes as he likes. Anyway, he explained that WordPress does not handle entity tags correctly.

In addition to Last-Modified headers, WordPress sends out ETag headers, which are basically gobbledygook strings that identify web content. Some web browsers, such as Vienna, only send conditional If-Modified-Since requests based on Last-Modified dates, but a browser can also store ETags and send them back on subsequent visits to the site as part of conditional If-None-Match requests. If the ETags don’t match the current content on the site, then there is new content that needs to be downloaded. NetNewsWire sends both kinds of conditional request. Unfortunately, WordPress does not parse its own ETags correctly on receiving If-None-Match requests — there seems to be a problem with quoting — so a match is never found, and it always sends a 200 response, along with the full feed content.

Brent passed along a suggestion to remove or comment out the following line in the file wp-includes/classes.php:

@header("ETag: $wp_etag");

After that, WordPress no longer sends out ETags, so it relies totally on Last-Modified dates. I’ve been testing this modification for a week, and NetNewsWire now receives both 200 and 304 responses, as appropriate. Moreover, my bandwidth has been cut by more than half. Thanks, Brent! We should form a tag team wrestling duo to pin down the WordPress developers and make them fix their feed bugs. My wrestling name will be the Penultimate Warrior.

Leopard Tech Talk: Postlude

Thursday, December 14th, 2006

If you think that America is a free country, try driving through Illinois. Their state motto is Give us all of your spare change. As I mentioned before, one of the Mac OS X Leopard Tech Talks was held in Chicago yesterday. (Except that it wasn’t yesterday when I mentioned it before.) I was there, and I had a good time. As you would expect, security was tight: I was asked for my name before receiving a name tag. Apple was kind enough to provide food and drink for the free event, which was much appreciated, though the NDA prevents me from disclosing the items on the menu. I will, however, reveal the latest secret Leopard feature. I can confirm that seeded builds now include a Spotlight-searchable C++ GUI Programming Guide. Thanks, PC guy!

I believe that I can also reveal, since I discovered this information myself by testing, that Vienna is Leopard-ready. Or at least, nothing appeared broken when I played with it for 5 minutes. Yay!

I met a number of people at the event, including fellow blogger Geoffrey Schmit of Sugar Maple Software. The biggest celebrity was Sal Soghoian, AppleScript product manager for Apple. Indeed, he was so famous that he wasn’t required to wear the standard Apple employee uniform, or the 15 pieces of flair. To their credit, the ‘software evangelists’ who gave the tech talks were open and honest. They answered my questions, and they also convinced me to shave my head and dance with an iPod at airports. I would like to thank them, as well as Apple for bringing the show on the road to a location near me.

All I can really say about the content of the talks is that Leopard has a lot of cool stuff for developers. I’m tempted now to get an ADC Select Membership, so that I can receive seeds. (In case you’re wondering, Leopard seeds are not distributed to the attendees of Leopard Tech Talks.) Perhaps that was their insidious purpose. Anyway, I would recommend attending if there’s a Leopard Tech Talk in your area. Amen!

Leopard Tech Talk: See you in Chicago

Friday, December 1st, 2006

I’ve received a confirmation email from ADC that I can attend the Leopard Tech Talk in Chicago on December 13. Thanks, Apple! I’ll try to ensure that Vienna is Leopard-ready.

If you’d like to meet me there, let me know. I should be conspicuous as the only poor soul without a laptop.

WordPress Bug Friday, nth edition

Friday, November 24th, 2006

Yesterday was Thanksgiving in the United States. Thanksgiving is a day for giving thanks, obviously. More important, it means that we Americans get to be ungrateful boors every other day of the year. Don’t you love holidays? Now that I don’t have to be thankful again (or eat again, for that matter) until next November, I’d like to take this opportunity to rip on WordPress. For the most part, WordPress works admirably. However, as I’ve noted once or twice, it doesn’t play well with syndication, which as you may know is something I’m familiar with. A number of you have WordPress installations on your own web sites, and even those of you who don’t have WordPress installations probably experience these bugs by following the syndicated feeds of this site and others in your favorite feed reader (Vienna, perhaps).

Today’s bug, which still exists in WordPress 2.0.5 (but has been fixed by me on this web site), afflicts comments feeds : for example, the main comments feed for the blog as well as comments feeds for individual posts. In order to prevent spam — as well as egg, bacon, spam, and sausage — I moderate all comments. No matter how long it takes for me to approve a comment (not long, usually, unless I’m asleep: that’s when I’m a Viking), the comment will appear with the date and time it was written. That’s fine, except that if your feed reader is polite like Vienna and sends an If-Modified-Since header in the request for articles, WordPress looks at the date of the latest comment in the database, regardless of whether the comment has been approved. Thus, if your feed reader checks the comments feed after a comment has been written but before it has been approved, the feed will give an HTTP 200 response (“OK”, “Yea!”, “Come hither”) and send the feed data, though thankfully WordPress won’t actually send the unapproved comment. Until another comment is written, however, the feed will give an HTTP 304 response (“Not Modified”, “Can’t Touch This!”, “I have a headache tonight”) on all subsequent checks, so you won’t see the comment in the feed after it’s approved.

By the way, if you wonder why I read the Hypertext Transfer Protocol document, take a glance at section 13.1.4. It’s good stuff, folks! I have yet to see a browser that follows the suggestions given by the RFC. Core Animation should make it easy.

Anyway, to fix the bug in WordPress 2.0.5, you need to modify the function get_lastcommentmodified in the file wp-includes/comment-functions.php. Replace the switch statement with the code below. You’re just adding $wpdb->comments.comment_approved = '1' AND to each of the cases.


switch(strtolower($timezone)) {
    case 'gmt':
        $lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE $wpdb->comments.comment_approved = '1' AND comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
        break;
    case 'blog':
        $lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE $wpdb->comments.comment_approved = '1' AND comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
        break;
    case 'server':
        $lastcommentmodified = $wpdb->get_var("SELECT DATE_ADD(comment_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->comments WHERE $wpdb->comments.comment_approved = '1' AND comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
        break;
}

Alas, WordPress Bug Friday is already over again, too soon! Remember that there are now only 30 shopping days left until Christmas. You can get me anything from the store.

The WebView: Reloaded

Sunday, November 19th, 2006

I know, I’ve been neglecting my blog again. My excuse is that I’ve been working on a secret project, so secret that if I told you, I’d have to buy you a pitcher of margaritas and hope you forgot. It’s not quite Top Secret: more like Middle Secret. (No, it wasn’t TomKat’s wedding.)

As promised, I’ll talk about Cocoa programming, specifically, WebKit programming. (Technically, WebKit is not Cocoa — at least, it’s not included by Cocoa.h — but you can use it in your Cocoa projects, sopleasedonotsueme!) As usual, the story begins with a bug report from a Vienna user. I swear, Vienna is no more buggy than your average app, or ant hill. At any rate, I don’t think that this bug was really our fault. The user reported that after a lost internet connection was restored, Vienna’s web browser couldn’t reload a page that had initially failed to load. However, Vienna’s reload button just uses the WebKit action -[WebView reload:], and Safari, which also uses WebKit, can reload a page once the internet connection is restored.

The class reference for WebView says that its reload: method Reloads the current page. That’s helpful. Luckily, WebKit is open source. In the file WebView.m, we find the implementation for the action:


- (IBAction)reload:(id)sender
{
    [[self mainFrame] reload];
}

Ok, that makes sense. Yet the class reference for WebFrame, which is slightly more helpful, says that its reload method Reloads the initial request passed as an argument to loadRequest:. Vienna does pass an NSURLRequest as an argument when calling loadRequest: on the mainFrame of the WebView. Why doesn’t the page get reloaded? Returning to the source, the file WebFrame.m contains the implementation:


- (void)reload
{
    [_private->frameLoader reload];
}

In WebFrame.h, we see that _private is an instance variable:


@interface WebFrame : NSObject
{
@private
    WebFramePrivate *_private;
}

Back in WebFrame.h, we can see that frameLoader is, in turn, an ivar of the class WebFramePrivate:


@interface WebFramePrivate : NSObject
{
@public
    WebFrameView *webFrameView;
    WebFrameLoader *frameLoader;

Finally, in WebFrameLoader.m we see the problem:


- (void)reload
{
    WebDataSource *ds = [self dataSource];
    if (ds == nil)
        return;

    NSMutableURLRequest *initialRequest = [ds request];

The WebFrame does not keep a reference to the NSURLRequest! The initial request comes from the data source, but the documentation for -[WebFrame loadRequest:] indicates that that there is no (committed) data source until data has been received. Obviously, no data has been received if there was no internet connection. When there is no data source, reloading the page does, well, nothing. In other words, the description of -[WebFrame reload] should be amended with, Now, where did I put that initial request? I thought I had it around here somewhere. Check under the bed.

The solution to this problem is to keep your own reference to the NSURLRequest and override -[WebView reload:], as follows.


-(IBAction)reload:(id)sender {
    if ([[self mainFrame] dataSource] == nil) {
        [[self mainFrame] loadRequest:myRequest];
    } else {
        [super reload:sender];
    }
}

I’ve created a demonstration project that contrasts this with the default reload: method. To see how they work (or don’t, as the case may be), build and run the application, turn off your net connection, press the Load button, turn your connection back on, and then experiment with the Reload buttons. You can see in the run log that both dataSource and provisionalDataSource are nil.

Die Sauerkraut ist in mein Lederhosen.

Vienna 2.1 and WordPress 2.0.5

Friday, November 10th, 2006

Ok, I lied. I won’t be talking about Cocoa programming in this post, except insofar as Vienna is a Cocoa program. This is really more of an announcement than a discussion, though. The Emergency Broadcast System has instructed me to annoy you with a series of loud beeps. If this had been an actual emergency, I would have been looting your valuables right now.

Beep! Beep! Beep! People of Earth, your attention, please. The developers of Vienna formally announce the release of … Vienna. Specifically, Vienna 2.1, the exciting sequel to Vienna 2.0. In a surprising turn of events, the incumbent, build 2107, has been upset by the challenger, build 2108. Sadly, build 2107 refuses to concede and is demanding a recount. Meanwhile, build 2109 is already setting up an exploratory committee for the next release. The release notes for Vienna 2.1 can be found in the forum. For those who prefer pictures over text, check out the illustrated list of features.

I would like to thank Steve Palmer for letting me mess with and mess up his app. Hopefully I’ve fixed more things than I’ve broken. I’d like to thank the Academy (Plato’s). It’s an honor just to nominate myself. Thanks to my cats, for helping me type. Thanks to caffeine, in all its forms. Thanks to my user agent, “Vienna/2.1.0.2108″. Finally, I’d like to thank all the little people: Dr. Ruth, Dustin Hoffman, Kerri Strug, Prince, and Ronnie James Dio. (Cue the band.)

My other important announcement is that the blog may be unavailable for a minute or two while I update from WordPress 2.0.4 to 2.0.5. By the time you read this post, it’ll all be over. That wasn’t so bad, was it? Just a little pinprick. Ahhhhhh! If you notice any problems after the update, please contact me. This is a recording. So long, and thanks for all the fish.

Modifier keys for opening external links

Thursday, November 2nd, 2006

This is the first of a series of posts (two) on the method -[NSWorkspace openURLs: withAppBundleIdentifier: options: additionalEventParamDescriptor: launchIdentifiers:], described in the NSWorkspace Class Reference. The first post will consist entirely of naming the method, because just typing it has given me carpal tunnel syndrome.

My cat graciously offered to type, so we’ll press ahead. Vienna has a built-in WebKit browser that allows you to follow links in a feed without switching to another app. There is a preference to choose whether to open links in Vienna or in your default web browser (in my case, Safari). Opening an array of URLs in your default web browser can be accomplished by calling the above mentioned method with the parameter withAppBundleIdentifier: set to nil.

Occasionally I want to override Vienna’s link opening preference. For example, I might want to bookmark some pages in Safari while still doing most of my web browsing in Vienna. (Note to self: implement feature in Vienna to add page to bookmarks.) My very first contribution to the Vienna project was a patch to override the preferred link opening behavior with a keyboard shortcut. I used the shift key, because at that point the option key was reserved for another purpose. The patch would do the opposite of your preference when you shift-clicked a link in the article pane or typed shift-return in the articles list. In other words, it would give you chicken salad, on rye, untoasted, and a cup of tea.

Using the shift key for this feature was a mistake, I later discovered. I received a bug report in the forum from a user who had minimized a Safari window to the Dock. When the user pressed the shift key in Vienna to open a link, the page did indeed open in Safari … extremely … slowly. My new Vienna feature had inadvertently activated the Mac OS X super-slow-motion effect for opening minimized windows. (The only purpose of this effect, as far as I can tell, is to mildly impress Windows users.) I faced another apparent example of relativistic weirdness, as if the shift key created time dilation by accelerating the rest of the system to near light speed, leaving Safari to lumber along like a gorilla. You maniacs! You blew it up! Super slowly!

To make a long story even longer, I fixed the bug in Vienna by switching the modifier key from shift to option. All recent builds of Vienna use the option key to override the browsing preference. My advice to you is to avoid using the shift key in your application as a modifier to open external links. Thank you very little.