Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

PyObjCでAppleRemoteをRimo用にリモコンしてみる

RubyCocoa で AppleRemote リッスンして Safari のプレゼンツールうごかす - 冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。 - subtech
FirefoxをApple Remote Controllerで動かすプログラム - smellman's Broken Diary
Pythonなマカーになったのでこの辺の影響を受けてみた。
PyObjCApple Remote ClassはFirefoxをApple Remote Controllerで動かすプログラム - smellman's Broken Diary
の通りにやればすんなり入ります。
適当なのでFireFox限定になっちゃってるけど。
rimo.tvにアクセスした状態で以下を実行する。
操作はこんな感じ

  1. 上 チャンネル1
  2. 下 チャンネル2
  3. 右 チャンネル3
  4. 左 チャンネル4
import objc
from Foundation import *
objc.loadBundle("AppleRemote", globals(), bundle_path=objc.pathForFramework(u'/Library/Frameworks/AppleRemote.framework'))

class AppleRemoteDelegate(NSObject):
    
    @objc.signature('v@:ii')
    def appleRemoteButton_pressedDown_(self, buttonIdentifer, pressedDown):
        print "bt: " + str(buttonIdentifer) + ", press: " + str(pressedDown)
        if pressedDown == 1:
            self.command(buttonIdentifer)

    def command(self, bt):
        if bt == 0:
            self.runcommand("18")
        elif bt == 1:
            self.runcommand("19")
        elif bt == 4:
            self.runcommand("20")
        elif bt == 5:
            self.runcommand("21")
        else:
            pass

    def runcommand(self, cd):
        scp = NSAppleScript.alloc().initWithSource_("""
        tell application "Firefox"
            activate
        end tell
        delay 1
        tell application "System Events"
            if UI elements enabled then
                key code %s 
            end if
        end tell
        """ % cd)
        scp.executeAndReturnError_()

def main():
    global app
    app = NSApplication.sharedApplication()
    ap = AppleRemote.alloc().init()
    de = AppleRemoteDelegate.alloc().init()
    ap.setDelegate_(de)
    ap.startListening_(0)
    app.run()

if __name__ == '__main__':
    main()

結局AppleScriptで。
rimoにもっとショートカットがあるかと思ってたらないでやんの。
なのでたいしたこと出来てません。
つまんないね><
まあでもAppleRemoteの参考っちゅー事で。

AppleScriptを使わないでシステムにキーイベントを送付するにはQuartzAPIを叩きます。
でもQuartz Python Bindingは最初の2.3でしか動作しないので結局Frameworkで使うしかない(多分)。
特に難しくはなくCGPostKeyboardEventを使えばいいだけ。
最も短いサンプル

#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>


@interface Key : NSObject {

}

- (void)test;

@end
@implementation Key

- (void)test
{
	CGPostKeyboardEvent((CGCharCode)NULL, (CGKeyCode)101, true);
}
@end

F9を押すのでデフォルトだとExposeが動く。
こいつをobj.loadBudleすればPyObjCからアクセスできる。

ぶっちゃけ、「とあるアプリケーションにだけキーイベントを送る」って方法がわからんのです。
なのでGlobalにシステムにイベント送っちゃってるの。
まだMac買って2週間経ってないので許して!!!

うくく。