Tags : hack
このTagsの登録数:6件 表示 : 1 - 6 / 6
NSTabView のボーダーを消す
NSTabView はボーダーが付いていて、用途によっては見栄えが良くない。これをなくすには Tabless にして背景を描かない設定にしないといけないが、Tab を選択するボタンを自作するのは面倒なので残しておきたい。そんな要望にお応えするハック。NSTabView のサブクラスを作ってボーダーを描くメソッドを潰してしまえば良い。_drawBorder:inRect: というメソッドだ。
@implementation MyTabView
//ボーダーを描かない
- (void)_drawBorder:(id)something inRect:(NSRect)aRect
{
//do nothing
}
@end
こんな感じのクラスを作って nib でカスタムクラスにすれば下図のような描画になる。かなりお手軽だ。Tab を選択するボタンが孤立した感じになるので、引数の NSRect を使って適当に装飾してみるのもいいかもしれない。ちなみに第一引数は NSDynamicSystemColor という NSColor のサブクラスだった。ウインドウの背景色なのではないかと思う。
class-dump の Universal Binary 暫定対応
Xcode を 2.1 にアップデートしたら多くのファイルが Universal Binary になっていた。で、これを class-dump しようとしたらうまく行かない。ソースを覗くと僕でもなんとかなりそうだったので暫定的に対応させた。CDMachOFile クラスの - (void)process にパッチを当てる。処理するファイルが Universal Binary だった場合、PPC Binary を探してポインタをずらすようにした。詳細はアーカイブに同梱しているのでそちらを参照してください。
実行ファイル+変更部分のソースをダウンロード→ class-dump-3.0-for-fat.zip
追記:
Universal Binary に対応した 3.1 が出ています。
Safari 2.0 の feed のテーマを変更する方法
Safari 2.0 で、RSS などを feed: プロトコルで表示するときの、テーマの変更方法が分かった。
デフォルトのテーマはここにある。
/System/Library/PrivateFrameworks/SyndicationUI.framework
/Versions/A/Resources/Themes/default.syndtheme
もしくはこちら。
/System/Library/PrivateFrameworks/SyndicationUI.framework
/Themes/default.syndtheme
これを
/Users/あなた/Library/Syndication/Themes
というフォルダを作ってその中にコピーする。Syndication フォルダは、取得した feed のデータベースのために作成されているはずだ。
コピーした default.syndtheme のフォルダ名を変更する(例:sample.syndtheme)。
sample.syndtheme/Contents/Info.plist を Property List Editor(推奨)かテキストエディタで開いて、「CFBundleName」をフォルダ名と同じにする(例:sample)。更に「CFBundleIdentifier」を変更する(例:com.mycompany.Syndication.theme.sample)。これがとても重要。
それからもちろんデザインの変更。sample.syndtheme/Contents/Resources の中がテーマのファイル。Articles.css がメインの CSS だ。拡張子 syntmpl の各ファイルで HTML レベルの変更も可能みたいだ。自由度はかなり高い(面倒そうだが)。
これでファイルの配置は完了。最後に Terminal での儀式。
defaults write "com.apple.Syndication" "Theme.ID" "テーマのCFBundleIdentifier"と打ち込む。さっきの例なら「defaults write "com.apple.Syndication" "Theme.ID" "com.mycompany.Syndication.theme.sample"」となる。Safari を立ち上げ直して feed を開いて確認してみよう。ちなみに元に戻す方法は、Terminal で、
defaults delete "com.apple.Syndication" "Theme.ID"
WebView の gif アニメを切る方法
WebPreferences に setAllowsAnimatedImages: というのがあるが今のところ効かない。以下は SafariStand で実装した方法。
10.3.9 では、WebKit の WebInternalImage (10.3.8 では WebImageRenderer) というクラスをハックする。startAnimationIfNecessary というメソッドがあって、ここを潰してしまえば良い。ただし、潰しただけでは最初のフレームのままなので、最後のフレームを表示させるようにした。描画の更新を明示してないので多少見苦しい。適切なタイミングで再描画させるか、あるいは、最初から最後のフレームを表示させる方がスマートだがとりあえず。
#import <objc/objc-runtime.h>
IMP gStartAnimationIfNecessary=NULL; //global
//----
Class tmpClas=objc_msgSend(objc_getClass("WebInternalImage"), @selector(class));
if(tmpClas){
gStartAnimationIfNecessary=Replace_MethodImp_WithFunc(tmpClas,
@selector(startAnimationIfNecessary), _stop_gif_animation);
}
//----
void _stop_gif_animation(id self, SEL _cmd)
{
if(/* アニメしない設定 */){
int lastFrame=(int)objc_msgSend(self, @selector(frameCount));
if(lastFrame > 1){
objc_msgSend(self, @selector(setCurrentFrame:), lastFrame-2);
}
}else{
gStartAnimationIfNecessary(self, _cmd);
}
}
Replace_MethodImp_WithFunc() は自前の関数で以下の通り。
IMP Replace_MethodImp_WithFunc(Class aClass, SEL origSel, const void* repFunc)
{
struct objc_method *origMethod;
IMP oldImp = NULL;
extern void _objc_flush_caches(Class);
if ((origMethod = class_getInstanceMethod(aClass, origSel))){
oldImp = origMethod->method_imp;
// Replace the method in place
origMethod->method_imp = repFunc;
// Flush the method cache
_objc_flush_caches(aClass);
}
//return original func pointer
return oldImp;
}
iLife の機能を勝手に使ってみる
iLife '05 の各アプリはライブラリに相互アクセスできるようになっている。例えば iPhoto でスライドショーの BGM を選ぶときに iTunes のライブラリが表示されたり。で、これの実装方法が、app パッケージに MediaBrowser.framework というのが入っていて、これで実現させているみたいなのだ。class-dump で調べると、 MediaBrowserView という NSView のサブクラスが定義してあって、これを配置するだけでとりあえず機能した。上部の3個のボタンは自前で付けたもの。それ以外の部分が MediaBrowserView。ご覧のように検索機能は使えるし、プレビューも出来ている。
問題は MediaBrowser.framework を再配布するわけにはいかないから、iLife '05 をインストールしてないと使えないというところ。なので framework をリンクさせずに実行時に NSBundle を作って load させるようにした。
iWorkにも同じような機能が付いているみたいなので同じ framework を使っている可能性は高いです。そのうち SDK が出るかもしれません。
Xcode プロジェクトを置いておくので興味のある人はどうぞ。ビルドしたアプリも入っているので、Xcode を入れてなくても試すことができます。ただし、iLife '05(の iPhoto)を入れてないと試せません。
→MediaBrowserTest.dmg をダウンロード
更新されたファイルが即座に Spotlight データベースに反映されるという特徴を殺してしまうのはどうか。すぐに索引更新させずに、キューに溜め込んでおいて定期的、あるいは手動でまとめて更新する。
利点はいろいろある。
・一時的に作成したファイルは索引を作らないまま削除される可能性が高いので無駄に索引を作らない
・システム環境設定のプライバシーよりも細かな無視設定が可能
・更新されたファイルのログが取れる
技術的な問題は、
・このハック自体可能かどうか
・データベースの整合性が保たれるかどうか
・パフォーマンス
といったところか。