ページ

2009年10月15日木曜日

Safari用独自プラグインを作る(3) - Posing を試す

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: Safari用独自プラグインを作る(2) - Posing と Method Swizzling

+[NSObject poseAsClass:] は 10.5 以降で Deprecated 扱いになっているようだが使ったことが無いので一応試しておこう。

Posing のコードは下記が参考になる。
junk(SafariWheelTab)

前回までにつくったひな形に NSWindow のサブクラスを一つ追加する。

XCWindow.h

#import 
@interface XCWindow : NSWindow {
}
@end

XCWindow.m
@implementation XCWindow
- (void)sendEvent:(NSEvent *)theEvent
{
 if ([theEvent type] == NSRightMouseDown) {
  NSLog(@"[1] NSRightMouseDown");
 }
 [super sendEvent:theEvent];
}
@end

これを +[load]メソッドで NSWindow と置き換える。
PluginController.m
#import "PluginController.h"
#import "XCWindow.h"
@implementation PluginController
+(void)load
{
 NSLog(@"+[PluginController load] was called");
 [XCWindow poseAsClass:[NSWindow class]];
}
@end

ビルドして所定の場所へ置いて Safariを再起動する。ウィンドウの上で右クリックすると..


出た。

ところでPosingを重ねた場合どんな挙動になるんだろうか。最初の Posingが無視されると他のプラグインが同じクラスを置き換えた場合困ったことになる。試しにもう一つクラスを用意して Posingを重ねてみた。

XCWindow2.m
@implementation XCWindow2

- (void)sendEvent:(NSEvent *)theEvent
{
 if ([theEvent type] == NSRightMouseDown) {
  NSLog(@"[2] NSRightMouseDown");
 }
 [super sendEvent:theEvent];
}
@end

PluginController.m
#import "PluginController.h"
#import "XCWindow.h"
#import "XCWindow2.h"
@implementation PluginController
+(void)load
{
 NSLog(@"+[PluginController load] was called");
 [XCWindow poseAsClass:[NSWindow class]];
 [XCWindow2 poseAsClass:[NSWindow class]];
}
@end

実行してみると...


両方ともちゃんと呼び出されている。順番は後から Posingした方が先に呼び出されている。

(参考)
  【コラム】ダイナミックObjective-C (12) ポージングで乗っ取り | エンタープライズ | マイコミジャーナル