Alastair’s Place

Software development, Cocoa, Objective-C, life. Stuff like that.

Global Warming

Stephen Fry on Global Warming and the differences in attitude between the Britain and the United States:

For another difference we have to face between our cultures is that the average position on global warming in Britain seems to be: ‘It exists, we humans are causing it, we’d better do something about it’, whereas the average position in America might be interpreted as, ‘I’m not convinced and anyway America certainly shouldn’t sign up to do anything about it if China doesn’t.’

It occurs to me that it is almost supremely ironic that a nation like Britain, whose total annual CO2 output is a tiny fraction of global emissions, should consist largely of people who have been fooled into thinking that anything they do could affect climate change, while the United States, which is by all accounts responsible for around 25% of all CO2 emissions and whose citizens might conceivably make a difference if they changed their behaviour, seems largely composed of sceptics. Here in the U.K., our influence on the problem is overstated by the environmental lobby to a frankly ludicrous degree, and often in a fairly underhand manner (For instance, you are more likely to see a graph of CO2 output by country per capita than as a percentage… why? Because it puts the U.K. near the top of the scale rather than near the bottom where it belongs. Perhaps U.S. citizens are better educated and therefore would not fall for that kind of cynical ruse?)

I am slightly sceptical myself, in as much as it is without a doubt much easier to obtain funding for research that supports the man-made climate change conclusion than research that goes against it. And whether or not the conclusion is true, this funding distortion will certainly contribute to some exaggeration.

It is also the case that the world has been a lot warmer at some points in the past, so I often think that the doom-sayers would do well to qualify their remarks by explaining that the primary catastrophe that they are concerned about is the effect on human civilisation and they might also consider stating openly the fact that the Earth’s climate may well have warmed up anyway, just not as fast.

And don’t get me started on the precautionary principle; I don’t find that old chestnut in the least bit persuasive. Why? Because I can use it to justify anything. Well, almost anything.

Let me give an example: there is a risk (only a very tiny risk, but a risk nonetheless) that walking through the streets of Fareham I might encounter a hungry lion. Say it’s escaped from a nearby zoo. Now everyone knows that hungry lions are not the best thing for a human being to bump into. In fact, the consequences of such an encounter would likely be pretty dire (bluntly: I’d most likely die). So, invoking the good old “precautionary principle”, it is now essential that I carry on my person equipment to defend myself against hungry lions. The argument is ridiculous, of course, but it’s the same as most other uses of the precautionary principle; the flaw is that it does not take into account a proper assessment of the risk of the event in question, often because the person invoking the principle has no idea of the magnitude of the risk, though they may appreciate that a particular event may have rather dire consequences if it does in fact happen. You can substitute for the hungry lion any manner of other things. Getting cancer from E/M radiation from mobile phones (or WiFi). The possibility of life on Earth being extinguished by a gamma ray burst. The risk that the sky will, in fact, fall on our heads. The list is endless.

So, do I think we should continue to churn out CO2? You may get the impression from the above that I do. You would be wrong. I think we should move to nuclear power generation as soon as possible. And I think we should spend vastly more money on the international fusion project, at the same time bringing the timetable forward by at least a few decades. But should we panic and enact the kind of legislation that would make every New Luddite proud? No, I don’t think so.

On this the U.S. view is quite right. The way to avoid global warming is innovation. Many of the tools we need are already at our disposal or are actively being worked on. Rather than supporting unsustainable and silly ventures like on-shore wind power, or downright dangerous propositions like biofuels (which still produce CO2 and have the additional downside of markedly distorting the agriculture market to the extent that we now have a wheat shortage), we would better spending our resources furthering research that will end the problem for good.

Commands and Mouse Event Handling in Cocoa

In the Cocoa Event-Handling Guide, it talks about two methods of handling mouse drags, namely with a tracking-loop and what it refers to as the “three-method approach”.

The two have some obvious pros and cons, so sometimes Cocoa programmers use one method and sometimes the other, even in the same program.

Usually you can write your code either way and it will pretty much work. However there are a couple of nasties that I ran into today that I couldn’t find any information on anywhere. Maybe there’re obvious to some of the people who’ve been writing Cocoa programs since before it was even called Cocoa, but they weren’t to me and it wasn’t especially obvious that there was a good way to work around them.

What are these problems? Well, consider this… your application is tracking the mouse because the user is manipulating some object in your document. Now, your user is feeling mean, and during tracking hits ⌘X, Cut (if that one works in your app, try hitting ⌘Z, Undo, instead).

I’m guessing that a substantial number of apps just fell over. Or at least behaved in a less than ideal way. And even those that didn’t might well find that their behaviour is inconsistent because some parts of their app use a tracking-loop and others use the three-method approach.

So, let’s explain what happens:

Case 1: The Modal Tracking Loop

This is often the easiest way to implement mouse tracking code. It also happens to have slightly better performance in many cases, particularly on slower machines. As a result, it’s quite widespread, even within the Cocoa frameworks themselves.

Most probably the code you have is using some variation on what’s written in the documentation, i.e. something like this:

- (void)mouseDown:(NSEvent *)theEvent {
  NSPoint pos;

  while ((theEvent = [[self window] nextEventMatchingMask:
    NSLeftMouseUpMask | NSLeftMouseDraggedMask])) {

    NSPoint pos = [self convertPoint:[theEvent locationInWindow]
                            fromView:nil];

    if ([theEvent type] == NSLeftMouseUp)
      break;

    // Do some other processing...
  }
}

If you do this, what you’ll find is that your application runs all the commands corresponding to the mnemonics the user pressed after he or she lets go of the mouse button. Quite what your user intended to do isn’t clear, but there’s a good chance it wasn’t that, particularly if they’ve hit e.g. ⌘Z more than once during the tracking loop.

Fortunately, the solution here is rather simple; all you need to do is discard any keypresses you don’t want to handle. The necessary changes are highlighted in italics:

- (void)mouseDown:(NSEvent *)theEvent {
  NSPoint pos;

  while ((theEvent = [[self window] nextEventMatchingMask:
    NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSKeyDownMask])) {

    NSPoint pos = [self convertPoint:[theEvent locationInWindow]
                            fromView:nil];

    if ([theEvent type] == NSLeftMouseUp)
      break;
    else if ([theEvent type] == NSKeyDown) {
      NSBeep ();
      continue;
    }

    // Do some other processing...
  }
}

Depending on your application, you may also want to discard NSKeyUp events, though you probably don’t want to beep for those.

Case 2: The Three-Method Approach

Let’s start by explaining what happens. If you use the three-method tracking approach, keyboard events are processed as normal during tracking. And that means that NSApplication will look up mnemonics and dispatch the appropriate messages. So if, for instance, you’re working on a drawing application and your user is dragging that blue circle that they just created when, in a fit of pique, they hit ⌘X with the mouse button still down, your Cut code is going to run, removing the object that your mouse tracking code is trying to move. In a well-written application, things might not break, but it isn’t pretty, and it probably wasn’t what the user wanted to do.

Even if your application gracefully handles this problem, the chances are that somewhere else in your code you’re using the other mouse tracking approach, so the behaviour of your application is very probably inconsistent.

This problem had me worried for a while. All I could find searching the web were solutions like this, which is really ugly and would only really work for tiny applications because you’d end up with all potentially disruptive methods implemented on every view that might be tracking the mouse.

But no, as is usually the case with Cocoa, the solution is quite simple when you know it. All you need to do is something like this (again, the additional code is in italics):

@interface MyView : NSView {
  ...
  BOOL isBeingManipulated;
  ...
}

...
- (BOOL)performKeyEquivalent:(NSEvent *)anEvent;
...

@end

@implementation MyView

- (BOOL)performKeyEquivalent:(NSEvent *)anEvent
{
  if (isBeingManipulated) {
    if ([anEvent type] == NSKeyDown) // Can get NSKeyUp here too
      NSBeep ();
    return YES; // Claim we handled it
  }

  return NO;
}

...

- (void)mouseDown:(NSEvent *)anEvent
{
  isBeingManipulated = YES;
  ...
}

- (void)mouseUp:(NSEvent *)anEvent
{
  isBeingManipulated = NO;
  ...
}

@end

Obviously this is all heavily simplified for the purposes of this post. In a real application, you might want to check the event type, you may not always want to set the isBeingManipulated variable, and you may even find that you want to handle some key equivalents but not others.

MT 4.0

Just updated. Comments, predictably, are broken again.

It looks like non-authenticated comments work, and OpenID comments work, but TypeKey comments… don’t. :–(

How frustrating. Anyway, for now, if you have a TypeKey ID, use it with OpenID instead.

OK, So I Said I Wouldn’t… but I Did Anyway

OK, so I said I wasn’t going to buy an iPhone yet. Yesterday I changed my mind and went to visit the O2 shop in Fareham, where the (very attractive) sales assistants were busy demonstrating the iPhone to the (very short) queue of people at the door.

Worse—for my wallet, that is—my existing phone is pay-as-you-go and I’d only recently topped it up with credit. Why not a contract phone, you ask? Well, quite simply, I’m not part of the current mobile-obsessed culture here in the U.K. and I never really have been. So how do I justify the cost of an iPhone contract? Good question. I’ll have to think on that :–)

Anyway, because of the substantial amount of credit on my old phone, I haven’t ported the number. So if you have my number, you’ll need to update it. Sorry about that.

A few observations about my new iPhone:

  • Mobile Safari has already crashed a few times on me.
  • Mail doesn’t support S/MIME. That’s annoying, because I use S/MIME quite extensively.
  • Mail doesn’t seem to support threading, which is a shame. Maybe I’m just missing the setting?
  • Mobile Safari doesn’t do SVG yet.
  • EDGE is just fine, speed-wise. OK, it isn’t as fast as my home broadband connection, but it’s perfectly usable even for web browsing. I was using it today, as a matter of fact.
  • The Google Maps application really is as good as you’d hope. OK, no GPS, but since you can only really use GPS if you have line-of-sight to sufficient satellites, putting GPS in a phone is of questionable utility anyway. I think people forget that in-car satellite navigation systems contain rather more than just a GPS receiver.
  • The camera is perfectly adequate. If I want high quality photos, I’ll use my SLR thank-you very much.
  • iTunes doesn’t seem to have any ringtones options here in the U.K. right now. I don’t actually want a silly ringtone, so this isn’t a huge deficiency, though I do have a couple of bits of music that would make good non-silly ringtones. And doubtless when we do get ringtone support, we’ll have to put up with the indefensibly silly “a ringtone is something different from playing a section of your music” nonsense here too.

Anyway, it’s very nice and it’s a huge improvement over previous phones I’ve owned.

Leopard

Much has already been written, both about Leopard’s features and about the fact that we developers didn’t get to see the final build before it was released. Actually, even if we had been able to grab a copy of the final build before release, it wouldn’t have made that much difference really; if problems show up (as happened to my company this time around) in the final seed, or even in the GM if they provide it before the release, there really isn’t that much time to correct them before either Mac OS X or your apps need to ship.

In this case, the problem we’re seeing seems to be with the Leopard kernel, though it’s possible that it’s actually a disk firmware bug that’s being triggered more readily by Leopard than Tiger.

Anyway, as a result, we’ve had to join the rather humiliating position that Filemaker are in, by declaring our applications not fully compatible with Leopard. I say “not fully” because, unlike Filemaker, at least our customers can run our applications from a bootable CD, and since that bootable CD will contain Tiger, not Leopard, it’s really not as bad as it sounds.

Having griped a little, let me just say: I’ve installed Leopard on a few of my machines now, and it’s looking very nice indeed. Superficial first impressions are that, in spite of all the new UI glitz, Leopard is actually faster than Tiger. Which would make it the third update in a row where Mac OS X seemed to get faster, not slower (contrast that with Microsoft’s recent efforts).

As for the UI changes… well, broadly speaking I quite like them. I’m still not entirely sold on the squarer corners on the windows, though I’m already finding the ones on Tiger too rounded after only a few hours of using Leopard full-time. And I’m glad they toned down the extra shadows on the Dock a bit, though I’d have liked to have seen what it was like without them. As for folder icons… well, they are nice, but I understand the complaints from others that the badges for the system folders are too subtle.

Like it or loathe it, I’m sure we’ll all get used to the new UI, and in a couple of weeks’ time, Tiger will look dated.

Well, It’s Finally Released

We’ve just released iPartition 3. This version’s development, testing and even release seems to have dragged on and on; originally I’d hoped that we’d get it out much sooner, but in retrospect it isn’t surprising given the amount of work involved in some of the new features.

I should say that much of the credit for the new filesystem support (we now resize NTFS and FAT, as well as HFS+), not to mention the excellent work on supporting Boot Camp, belongs to my friend and colleague, Chris Suter (Chris, where’s your blog? You’ve been talking about starting one for ages), who some people might recognise from his sporadic presence on various Apple developer mailing lists. My work for this release has been mainly on the interface, though some of the FAT code is mine.

I shouldn’t minimise, though; a lot of work went into the interface, not least all the time I spent re-drawing various icons as vector graphics (I think I’m right in saying that all the icons visible in iPartition’s windows are now scalable vectors, and they continue to look pleasing to the eye even at high UI scale factors). We even flirted with using a scalable backdrop for the distribution disk image, but that doesn’t work on 10.3 so we decided to leave that for now.

The new UI should be more accessible than the old one was for people using screen readers and the like too; it certainly seems to work better in Voice Over. Plus I’m very proud of the new look pie chart; it uses space much more effectively in the window and is simply gorgeous to look at:

ipartition-pie.png

Somehow a static image doesn’t quite do it justice. But you can always download the demo and make yourself a disk image so you can play with it.

Of course, we’ve already had an e-mail to complain that the new features are such a small upgrade that it isn’t worth the time we’ve spent on them, never mind the upgrade price. You’d think it was just a case of five minutes work writing code to shell out to diskutil or something, as opposed to the reality, which is that writing filesystem related code is a hard, unforgiving slog. You can’t afford to make mistakes, but it’s complicated so you inevitably will anyway; testing is difficult at best, not to mention slow; and just to make life better, there are usually all sorts of idiosyncrasies that (a) users don’t appreciate, and (b) you have to deal with.

To give some idea, according to our version control system, I started the FAT code nearly two years ago now, and the NTFS code is nearly a year old itself. So this release is the culmination of all of that effort, from both me and Chris. We hope our customers like it. Time will tell.

Today Is Not Going Well…

This morning, just as I was coming off the market roundabout at the junction of the A32 and A27 in Fareham, some idiot in a lorry drove into the side of my car. The roundabout there has three lanes, once of which goes off, so at the eastern exit there are two lanes, both of which go onto the A27. I was in the left-hand lane, in my MG. The lorry driver, on the roundabout, was in the right-most lane (for the benefit of those reading this outside the U.K., we drive on the left). As we came off the roundabout, he drove into the left hand lane, apparently ignorant of the fact that my car was alongside his vehicle.

The annoying thing is that I could see it happening, and all I could do about it was try to put my foot down hard to get out of the way. Braking wouldn’t have helped (instead of hitting my car towards the rear, he’d have hit the front of it), and doing nothing wasn’t really an option either given where we were (there are railings to the left of the left-hand lane… and I didn’t particular want to end up squashed between them and his lorry; on reflection, I may actually have had a lucky escape, though we weren’t travelling very fast at the time).

Anyway, my car got off quite lightly under the circumstances; the damage seems to be limited to a (rather awkward looking) dent in the driver’s side rear wheel-arch, plus some scraped paintwork. There didn’t seem to be any visible damage to the lorry; maybe some scraped paint on the front-left corner of the cab, but then that could easily have been there already. Particularly as the lorry in question seemed to have a couple of bits of broken indicator tied on with what looked like washing line.

Plus, I have a feeling from the looks of my inbox, that I have other problems to deal with today as well.

AAARGH!

Piracy

From Daring Fireball:

Piracy

This is why it’s a mistake, a huge mistake, to call copyright infringement and bootlegging “piracy”.

Er, what?

Software pirates have long played up to the skull-and-crossbones image. I remember way back in the ’80s, there were groups with the word “Pirate” in their names (on the Atari ST, for instance, the Pompey Pirates). They were proud to be called “pirates”.

The whole phenomenon of people pretending to be offended at the use of words like “pirate” or “theft” in relation to copyright infringement is a recent development, and quite frankly it’s ridiculous. Nobody is actually offended by these terms; it’s just that one or two pro-piracy people have realised that “copyright infringement” sounds like the kind of law-breaking that nice people might engage in, whereas “piracy” and “theft” don’t.

The same people also realise that they have to make sure that a substantial proportion of the population is engaged in copyright theft, otherwise it might be practical to start prosecuting people for it. Currently you can only really do that for show, and you’ll never recover your costs.