すでに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 件のコメント:
コメントを投稿