午後からお休みをとって帰宅。家庭の用事をあれこれ済ませてもやはり時間の余裕があってMacRubyでできることを調べる。
(旧)cocoaの日々さんの「Spaces - アクティブなspaceの番号を得る(プライベート関数使用)」というアーティクルでCGSGetWorkspace という関数を使えばSpacesをいじれることを学習しました。これは昨晩すでに酔っ払ってから調べがついたため(それでもじゃあCGSGetWorkspaceのGetをSetにすればSpacesを動かせるんじゃないの?え?googleさんよ、とやっていたらやっぱりそのようだ、ということまではわかった)、本日改めて調べてみました。なんのことはない、「MacRuby CGSGetWorkspace」で検索しただけなんですが。
叩けよさらば開かれん、そうすると蛇の道は蛇でしてやっぱりこういうページに行き当たる。
Mouvement dans les spaces avec MacRuby (et Cocoa)
これ、何語?という状態ですが、ありがたいことにコードは読める。なるほど、プライベートな関数は一旦ObjCのclassにして、それをMacRubyから使うのか。
参考のために上記サイトのヘッダとインプリメントをコピーしておきます。
ヘッダ、Spaces.h。
// // Spaces.h // RConsole // // Created by greg on 12/03/10. // Copyright 2010 Grégoire Lejeune. All rights reserved. // #import#import @interface Spaces : NSObject { } - (NSInteger)spaceNumber; - (void)moveWindowToCurrentSpace:(NSWindow *)win; - (void)moveWindow:(NSWindow *)win toSpaceNumber:(NSInteger)space; - (NSInteger)getSpaceNumberOfWindow:(NSWindow *)win; @end
Spaces.m。
// // Spaces.m // RConsole // // Created by greg on 12/03/10. // Copyright 2010 Grégoire Lejeune. All rights reserved. // #import "Spaces.h" @implementation Spaces - (NSInteger)spaceNumber { NSInteger space = -1; CGSGetWorkspace(_CGSDefaultConnection(), &space); return space; } - (NSInteger)getSpaceNumberOfWindow:(NSWindow *)win { NSInteger windowId = [win windowNumber]; NSInteger space = -1; CGSGetWindowWorkspace(_CGSDefaultConnection(), windowId, &space); return space; } - (void)moveWindowToCurrentSpace:(NSWindow *)win { [self moveWindow:win toSpaceNumber:[self spaceNumber]]; } - (void)moveWindow:(NSWindow *)win toSpaceNumber:(NSInteger)space { NSInteger windowId = [win windowNumber]; if(windowId != -1) { CGSMoveWorkspaceWindowList(_CGSDefaultConnection(), &windowId, 1, space); } } @endで、MacRubyでプロジェクトをつくり、WindowにラベルとボタンだけはりつけてControllerを作る。
class MyController < NSWindowController attr_accessor :my_label def init super @my_space=Spaces.new self end def button_action(sender) number=@my_space.spaceNumber my_label.setStringValue number.to_s end endボタンを押すとSpacesの番号が出るはず・・・なんですが-4976594とか表示されます。 はて・・・。intだから整数のはずなんだけど・・・。特にエラーが出るわけでもないので、とりあえずMacRubyからプライベート関数が使えることがわかっただけでも万々歳としよう。 ・・・と考えるわけですが、どう見てもintじゃない数値が返ってくるのは変です。いろいろなサイトで CGSGetWorkspaceについて読んでいくと、返ってくるのはどうやらポインタらしい。ということはnumber.to_sとかしてもだめだ。numberにはアドレスが入っている(という表現でいいのかな)なら、そのアドレスに入っているint型の数値を読まなければ。 で、MacRubyにはPointer型がある、という記事をどこかで読んだ記憶があったので検索。おお、MacRubyのコミッタさんの@watson1978さんのはてなだった。
MacRubyのPointerクラスについてそこでPointer型を使ってコードを書き換えてみる。
def button_action(sender) number=Pointer.new('i') number[0]=@my_space.spaceNumber my_label.setStringValue number[0].to_s endわーい、これでちゃんと1とか2とか表示できるようになった。 ボタンを押すと現在のワークスペースを表示するという。 で、画像の中のボタン2は何かというと、
- (void)setSpaceNumber { NSInteger space = -1; CGSGetWorkspace(_CGSDefaultConnection(), &space); CGSSetWorkspace(_CGSDefaultConnection(),space-1); }こういう関数を書いておいて、
def button2_action(sender) @my_space.setSpaceNumber endこうやってみる。見事、Spacesが瞬時に動くようになりました。ただし、1引いてるだけなのでSpacesの「1」で実行すると恐ろしいことになるに違いない(^^;)。また、設定しているSpaces変更のキーボードショートカット(ctrl-2とか)が一時的に効かなくなります。なんせど素人のやっていることなので危険。
ただ、全く不可能、ということではない、とわかったのが楽しかったです。これで次はマウスのキーイベントか。
0 件のコメント:
コメントを投稿