BathyScaphe ネタ(その5)

なぜ、プレビューインスペクタには「Web ブラウザで開く」ツールバーボタンが無いのか。…何を隠そう、それはツールバーアイコンで悩んでいたからである。「プレビュー で開く」ツールバーボタンは、プレビュー.app 自体のアイコンを拝借している。同じように「Web ブラウザで開く」には、デフォルトの Web ブラウザのアイコンを拝借してくるのが適当だろうと思ったのだが……。


では、どうやって「デフォルト Web ブラウザのアイコン」を取ってくればいいの?

「プレビュー で開く」ボタンの場合は悩む所は無い。「プレビュー」と決まっているから、

NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSString *previewPath;
NSImage *previewIcon;

previewPath = [ws absolutePathForAppBundleWithIdentifier : @"com.apple.Preview"];
previewIcon = [ws iconForFile : previewPath]]; // ゲットだぜ!

のようにすれば良い。しかしデフォルト Web ブラウザは違う。皆が Safari をデフォルトにしている訳ではないのである。どうする?「URL をデフォルト Web ブラウザで開く」みたいなことは一発で出来るのに、その「デフォルト Web ブラウザ」の正体を知る簡便な方法を私は知らないではないか。…皆さんは、知っているのだろうか?*1知らないのは、私ぐらいのものなのだろうか?

調べて見ると…

なかなか、出てこない。古い文献では(Mac OS 8.5 とか!)、Internet Config を叩けと言っている(ように私は解釈した)ものもあった。しかし、Mac OS X ではどうもおすすめされていないようである。Google しようとしても、「default browser」みたいな語句では到底絞りきれず、無関係なページばかりで疲れ果ててしまった。


もうこうなったら、今までに得ている知識と、直感に頼るしかない。私は http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/index.html に向かった。なんとなく、こういう話は Launch Services が役に立ちそうだと思う感覚が、Mac OS X 時代には必要ではなかろうか。


そして、どうにも強引な感が否めないながら、何とか以下のようなコードで取得に成功した2006-01-29 追記:ちょっとアホな所に気付いたのでこっそり直しておいた

NSURL	*dummyURL = [NSURL URLWithString : @"http://www.apple.com/"]; // ダミーの URL
OSStatus	err;
FSRef	outAppRef;
CFURLRef	outAppURL; // いわゆる NSURL との "toll-free bridge" という奴
NSImage	*image_;

err = LSGetApplicationForURL((CFURLRef )dummyURL, kLSRolesAll, &outAppRef, &outAppURL);
if(outAppURL) {
	NSWorkspace *ws = [NSWorkspace sharedWorkspace];
	//NSString *appName = [[(NSURL *)outAppURL absoluteString] lastPathComponent];
	//NSString *appPath = [ws fullPathForApplication : appName];
	CFStringRef appPath =  CFURLCopyFileSystemPath(outAppURL, kCFURLPOSIXPathStyle); // この方がスマートだよね?
	image_ = [ws iconForFile : (NSString *)appPath]; // ゲットだぜ!
}

使ったのは LSGetApplicationForURL() だ。ここに http で始まる URL を渡してやることで、「http スキームを開くデフォルトのアプリケーション」、つまり事実上「デフォルトの Web ブラウザ」のパスが取れる。後はそこからいじり回して、iconForFile: に繋げてやればいいだろう。という考えである。


こうして、手元のプレビューインスペクタでは「Web ブラウザで開く」ボタンが実装された。次の Sneaky とともに、お届けできることだろう。


*1:以下では私が強引にひねり出した方法を書いているが、もっとスマートな方法があったらぜひご教示ください…