すでにMacRubyで一度やっているのでそれを修正しながら実装した。
必要な前提はCGSPrivate.hをimportすること。このヘッダはネットのあちこちに転がっている。私は「Warp」のプロジェクトに含まれていたのものを転用させてもらっている。
必要なメソッドは
1,現在のSpacesの行と桁を取得して最大Workspace数を得る
-(void) getSpaceMax{
CFPreferencesAppSynchronize(CFSTR("com.apple.dock"));
_space_row=CFPreferencesGetAppIntegerValue(CFSTR("workspaces-rows"),CFSTR( "com.apple.dock"), nil);
_space_col=CFPreferencesGetAppIntegerValue(CFSTR("workspaces-cols"), CFSTR("com.apple.dock"), nil);
_space_max=_space_row * _space_col;
}
row、col、maxともにインスタンス変数にしてみた。とりあえず、ということで。2,現在のSpacesのWorkspaceのindexを得る
- (NSInteger)spaceNumber {
CGSWorkspace currentSpace;
if (CGSGetWorkspace(_CGSDefaultConnection(), ¤tSpace) == kCGErrorSuccess) {
if (currentSpace == 65538) {
return -1;
}
return currentSpace;
} else {
return -1;
}
}
いわゆるCGプライベート関数を使う。実はこのメソッド、「Warp」からいただいてしまっている。だから「65538」なんていう数字もWarpのソースのまま。現在のWorkspaceをNSLogで出力しながら確認してみると、「1」とか「2」とか順当な値の中にいきなり「65538」が出てくる。理由は今のところ不明。Warpのように65538が出てきたら「-1」を返すようにしても、動作そのものには全く支障がない。そのうち追求してみよう。
3,Workspaceを実際に切り替える
NSString *SwitchSpacesNotification = @"com.apple.switchSpaces";
- (void)postNotificationSpacesSwitch:(NSInteger)object{
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:SwitchSpacesNotification object:[NSString stringWithFormat:@"%d", object]];
}
今のところは単にNotificationをSpacesに向かって通知しているだけ。CGプライベートの「CGError CGSSetWorkspace(const CGSConnection cid, CGSWorkspace workspace);」を使ってみるのは明日以降。あとはマウスホイールのイベントハンドラで処理するだけ。
(void)scrollWheel:(NSEvent *)theEvent{
NSLog(@"%f",theEvent.deltaY);
NSInteger number_space=[self spaceNumber];
NSLog(@"%d",number_space);
if ([theEvent deltaY] < 0.0) {
if (number_space==_space_max) {
number_space=1;
}
else{
number_space++;
}
}
else{
if (number_space==1) {
number_space=_space_max;
}
else{
number_space--;
}
}
[self postNotificationSpacesSwitch:number_space-1];
}
相変わらずVBAのExcelマクロみたいな書き方しかできていないのががっくり。ま、だんだん上手にかけるようになることを自分に期待しよう。「システムよりのものすごく難しそうなこと」に思えた「Workspaceの切り替え」、ど素人でもけっこう簡単にできてしまうところがCocoaの面白さか。
0 件のコメント:
コメントを投稿