Archive for the 'SystemUIServer' Category

2012/01/05 文字入力モードを制御

GUI Scripting経由でSystemUIServerを制御して、IMの文字入力モードを変更するAppleScriptです。

実行には、GUI Scriptingがオンになっている必要があります。また、現時点ではMac OS X 10.6.8と10.7.2で確認してある状態です(10.5は微妙。10.4ではダメだと思います)。

→ 後日確認したところ、Mac OS X 10.5.8と10.4.11では動きませんでした。予想どおり。

文字入力モードをAppleScriptからコントロールするのは、普通に考えれば無理そうです。

真っ先に思いつくのが、AppleScriptObjCによるGUIつきアプリケーションを作成して、そのアプリケーションのWindow上にNSTextFieldを作成し、入力文字種類を制御するやりかたです。これなら、文字入力を制御できているといえなくもありません。

サードパーティのIMまで目を向けると、ジャストシステムのATOKはATOKダイレクトAPIなるAPIをユーザーに公開しており、コントロールできなくもなさそうな雰囲気はしているのですが、メーカーが想定している使い方しかさせてもらえなさそうな雰囲気も漂っています。

AppleScriptObjC経由で、ことえりのステータスを変更ないしは固定するようなプログラムを呼び出す方法も考えられなくもないですが……すぐには情報が見つかりませんでした。

そこで、きわめてAppleScript的に、GUI Scripting経由でコントロールしてみようということになりました。

画面上部のメニュー右側に表示されるMenu Extraは、SystemUIServerというプログラムが管轄しています(Mac OS X 10.6/10.7)。

menu1.jpg

このため、SystemUIServerのメニューの各アイテムにAppleScriptからアクセスすると、最低限、どのような内容を表示しているか取得できそうです。ユーザーによってMenu Extraの内容や並び順はカスタマイズされまくっているので、Menu Extra同士の識別ができなくてはなりません。

descriptionという属性を調べることで、どのプログラムが表示しているものか識別できそうです。Apple純正のMenu Extraしか値を取得できていない状態ですが、今回の目的のためにはこれで十分です。

並び順からいって、「text input」というのがIMのMenu Extraを表しているようです。

スクリプト名:System UI Serverから何がmenu extraを表示しているかを取得
activate application “SystemUIServer”
tell application “System Events”
  tell process “SystemUIServer”
    tell menu bar 1
      set aList to description of every menu bar item
    end tell
  end tell
end tell
–> {”time machine”, “bluetooth”, “iChat”, “displays”, “AirMac Menu Extra”, “システムサウンド音量”, “AppleScript”, “バッテリーメニュー。 完全充電まで 5 時間 39 分 .”, “clock”, “text input”, “user”}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

次に、どのプログラムがどのような情報を表示しているのか「value」属性を調べてみました。「英字」「ひらがな」「カタカナ」といった情報が取得できます。けっこういい感じです。

スクリプト名:System UI Serverから各menu extraが何を表示しているかを取得
activate application “SystemUIServer”
tell application “System Events”
  tell process “SystemUIServer”
    tell menu bar 1
      set aList to value of every menu bar item
    end tell
  end tell
end tell
–> {missing value, missing value, missing value, missing value, “Extreme net の 4 本のうち 4 本の信号”, missing value, missing value, missing value, “1月4日(水) 23:49″, “英字”, missing value}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

ちなみに、このvalueをAppleScriptから変更できないか試してみたのですが、valueはあくまで現状を反映させたものであり、書き換えてみても何も起きませんでした。

そこで、これまたGUI Scripting的なアプローチで、この「text input」のmenu extraをクリックして、表示されたメニューから指定のアイテムをクリックするという操作を行ってみました。

スクリプト名:System UI Serverを操作してIMの文字入力状態を変更する

setInputState(“英字”) of me
–setInputState(”ひらがな”) of me

–IMの入力状態を設定する
on setInputState(aState)
  activate application “SystemUIServer”
  
tell application “System Events”
    tell process “SystemUIServer”
      tell menu bar 1
        set aList to every menu bar item whose description is “text input”
        
set anItem to first item of aList
        
set curVal to value of anItem
        
        
if aState = curVal then return –変更の必要がなければリターン
        
        
tell anItem
          click
          
tell menu 1
            set mList to every menu item whose title is aState
            
set m1Item to first item of mList
            
tell m1Item
              click
            end tell
          end tell
        end tell
        
      end tell
    end tell
  end tell
  
end setInputState

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

人間、やればできるもんです。できないかと思っていたのですが、やってみたら案外手軽にできてしまいました。

ただし、複数のIMがインストールされている環境では、それぞれを識別するのはちょっと難しそうで……

menu2.jpg

もうちょっと調べてみないとなんともいえないところでしょうか。