2009年12月16日水曜日

Emacs (NTEmacs) 23.1 をWindows 7上で少し快適に使う - Part.2

さてPart.1「パッチを当てたEmacsをWindows上でコンパイルする」の続きを説明する。前回も述べたが、今回説明する「少し快適に使うためのセッティング」が少しの快適をWindows 7上で動作するEmacsにもたらすのだ、だからこっちの説明が重要。

さて、説明に入る前に前回コンパイルして出来たバイナリと、パッチの当たったソースファイルをダウンロード出来るようにしておいた。コンパイラの最適化オプションなどに興味のない人などはこのバイナリファイルをダウンロードすれば前回の手順をスキップできる。
(2010/03/12:配布用に一部コードを修正中。バイナリはしばらくお待ちください。)
(2010/03/14:再アップロードしました。)
    2. 少し快適に使うためのセッティング
    それでは本題に入ろう。前回、”少し快適”とは「Windows 7で導入された新しいタスクバーに対応すること」と一言で説明した。Windows 7ではまるでMac OS XのDockに似た、そして、さらにそれを使いやすくしたらしい今までとは全く異なる新しいタスクバーが導入されている。その中でもまず目につくのが、タスクバーにアプリケーションをピン留めすることができ(よく使うアプリケーションなどをタスクバーに登録することが出来る)、アプリケーションが起動中でも昔のようにタスクバーにアイコンが増えていくのではなく、ピン留めされたアイコンが変化する動作だ。
    詳しい説明は「Microsoft、Windows 7のタスクバーを解説 (ITmedia)」などを参照してほしい。

    さて前回ビルドしたEmacsでこの機能を使おうとすると以下の現象が発生する。

    まず runemacs.exe でEmacsを起動すると以下のようにタスクバーにEmacsアイコンが出現し、起動していることを示す。




    次回からEmacsをサクッと起動しようとピン留めしてみる(タスクバーに登録する)。Emacsアイコンを右クリックして、「タスクバーにこのプログラムを表示する」を選択。









    そしてEmacsを終了すると、タスクバーは以下の状態になる。




    ここまでは期待通りの動作をしている。そしてこのアイコンをクリックして再度Emacsを起動すると、、、
    ←2つEmacsが起動しているように表示され


    かつ、意味のないコマンドプロンプトが起動してしまいます。もうここまでくると、(NT)Emacsに詳しい方はお気づきかとは思いますが、タスクバーに登録されたアプリケーションは runemacs.exe ではなく、 emacs.exe なのです。
    そして emacs.exe は元々Windowsアプリケーションではなく、コンソールアプリケーションだからこうなってしまう。runemacs.exe はコンソールアプリケーションのEmacsをWindowsアプリケーションのように起動するためのアプリケーション(コマンドプロンプトが出ない)なのです。

    じゃあ、runemacs.exe をタスクバーに登録すればいいじゃんということになりますね。さっそく登録してみます。(その前に、タスクバーにある emacs.exe への登録は消しましょう、ややこしくなるので。右クリックして「タスクバーにこのプログラムを表示しない」でできます。)
    エクスプローラーから runemacs.exe を選択し右クリック、「タスクバーに表示する」で登録されます。














    そして、タスクバーのアイコンをクリックしてEmacsを起動してみましょう。すると、、、

    ←何か別に表示されてる



    せっかくのタスクバーの新機能がいかされず、起動アイコンと起動中アイコンが別々に表示されるという悲しい現象が発生します。

    これが今回私が訴えたかった快適ではなくなっている問題です。
    bug#1849 - Windows 7 Taskbar Support で指摘されていることもこれに関連することです。では、なぜこんなことが起きてしまうのか簡単に説明すると、Windows 7からはアプリケーションにアプリケーション ユーザー モデル ID (AppID)という識別子が導入されました。このIDが同じであると上記の問題は発生せずに1つのアイコンで表示されます。上記の例では、runemacs.exe を右クリックして登録した際にシステムが(暗黙に)定義したAppIDと emacs.exe が持っているAppIDが違うことにより発生しています、と推測しています。
    アプリケーションが明示的にAppIDを定義しないと、システムがある一定の法則にのっとって勝手にAppIDを作るようです。ちなみに、前回Emacsをコンパイルする際にこの問題に対応するEmacsのMAINブランチに入ったパッチを適用しました。そのコードによれば、Emacsは ”GNU.Emacs” というAppIDを明示的に定義しているようです。runemacs.exe や emacs.exe はこのAppIDをシステムに宣言しています。
    では、なぜ問題が発生するのか?ここからは推測ですが、まず、runemacs.exe を右クリックしてタスクバーに登録した場合は runemacs.exe が実行された際にシステムに宣言される "GNU.Emacs" AppIDが、このオペレーションでは適用されないということ。おそらくAppIDのない状態又はシステムが定義したAppIDでタスクバーに登録されているのでしょう。そして、次に runemacs.exe は emacs.exe を呼び出してすぐに終了してしまうために、runemacs.exe を実行してもタスクバーには runemacs.exe のプログラムが表示されず、結果的にユーザに右クリックして「タスクバーにこのプログラムを表示する」を選択する猶予を与えないためでしょう。
    もし、runemacs.exe がすぐに終了しないアプリケーションであれば、内部で "GNU.Emacs" AppIDを定義しているのでタスクバーにアイコンが表示されていれば、タスクバーに "GNU.Emacs" AppID をもったアプリと登録することができ、期待通りの動作をするはずです。(期待通りの動作="GNU.Emacs" AppIDをもった runemacs.exe をタスクバーに登録でき、かつそのアイコンで起動すると emacs.exe はそのアイコン上で起動中と表示されること)


    さて、ここまでは問題となる現象の説明であり「少し快適になる=この問題をなくす」セッティングの説明に入れていませんでした。さっそく(やっと?)、2. 少し快適に使うためのセッティングに入ります。

    MSDNのサイトをいろいろ調べたところ、ショートカットにAppIDを持たせることが出来ると判明。ということは runemacs.exe のショートカットを作って、そのショートカットに "GNU.Emacs" AppID を入れて、タスクバーに登録すればうまくいくんじゃね?という結論に至った。で、実際にごにょごにょすると確かに期待通りの動作が出来た!
    しかーし、ここで少し時間を食ってしまった。なぜならばショートカットに好きなAppIDを持たせる簡単な方法を見つけることが出来なかったため、自前でWindows アプリケーションを作るはめになったからである。まぁ、たいしたコード量じゃないんだが。

    では、まず次のアプリケーションをダウンロードして欲しい。
    「Shortcut AppID Changer by 俺 (ダウンロード先→ShortcutAppIDChanger.zip)」
    このアプリケーションはWindows 7上で動くもので、ショートカットに好きなAppIDを設定することができる。

    さてダウンロードが終わったら手順の説明に入る。
    1. runemacs.exeのショートカットを作る。
    Emacsのインストールフォルダのbinにある runemacs.exe を右クリックし、ショートカットの作成を選択する。すると、同じディレクトリにショートカットが出来るはずだ。

    2. ショートカットの名前を変える。
    これは飛ばしてもいい手順だが、、最終的にこのショートカットをタスクバーに登録すると、(右クリックで表示される)登録された名前はこのショートカットのファイル名となる。手順1で作ったショートカットファイルの名前はおそらく「runemacs.exe - ショートカット」となっているので、これを「emacs」とでも変えておこう。

    3. ショートカットにAppIDを埋め込む
    さて重要なステップにきた。作成したショートカットファイルに "GNU.Emacs" AppID を埋め込む。まず、ShortcutAppIDChanger.exe を起動して欲しい。すると以下のウィンドウが現れるはずだ。
    このウィンドウに先ほど作成したショートカットをドラッグ&ドロップする。すると、「Loaded file name: None」と表示されていたところが、作成したショートカットファイルの名前を表示するようになる。こうなれば、このアプリケーションは正しくショートカットファイルを認識している。
    そして次に、「PKEY_AppUserModel_ID 」と表示されている枠内にあるテキストボックスに設定するAppIDを入力する。今回はもちろん GNU.Emacs だ。以下のような表示になればOK。Loaded file nameのところは皆さんの環境によって違うだろう。
     
     そして、Saveボタンを押す。新しく保存してもよいし、読み込んだショートカットに上書き保存してもよい。保存したら "GNU.Emacs" AppID を持ったショートカットのできあがりである。このアプリケーションはExitボタンでも押して終了する。

    4. AppIDをもったショートカットをタスクバーに登録する
    前述の手順で作成したショートカットファイルを右クリックし、「タスクバーに表示する」を選択する。するとタスクバーにEmacsアイコンが現れる。

    以上で少し快適に使うセッティングは終了だ。
    タスクバーにあるEmacsアイコンをクリックしてEmacsを起動して欲しい。うまくいけば以下のように表示されるはずだ。
    そして、タスクバーはこの状態であり、コマンドプロンプトは表示されていないはずだ。

    これが今回説明したかった EmacsをWindows 7上で少し快適に使う方法 である。
    小さなことかもしれないが、Windows 7の新しいタスクバーに慣れてしまった僕にとっては、頻繁に使うEmacsはタスクバーに登録して使いたかったのだ!!
    へんてこりんな動作無しでね。

    さて、Emacsのブランチに入った変更は runemacs.exe / emacs.exe / emacsclientw.exe にAppIDを設定するコードを埋め込んだこと。今回のような問題はどう対処するのであろうか?それとも私が何か勘違いしているのだろうか?emacsclientを使うとまた違ってくるとか??
    もし、何かご存じの方がいらっしゃれば是非教えていただきたいm(_ _)m

    まぁ、いまのところ期待通りの動作をしているので個人的には満足している。
    次回は、「コンパイラに渡す最適化パラメータについて」又は「.emacsと最低限設定すべき環境変数」について何か書きたいと思っている。

    「Emacs (NTEmacs) 23.1 をWindows 7上で少し快適に使う」はPart.2でとりあえず完!
    では、また次回!!

    1 件のコメント: