May 13, 2010

Windows 7のAeroPeek(タスクバーのプレビュー)にアドオンから手を出してみる

Windows 7では、特定のアプリケーションのウィンドウが複数開かれている状態でタスクバー上のボタンをポイントすると、各ウィンドウのプレビューが一覧表示されるようになっている。これはAero Peekという機能だ。Firefox 3.6以降ではこのAero Peekのためのコードが入ってて、about:configでbrowser.taskbar.previews.enableをtrueに変更して機能を有効にすると、ウィンドウごとではなくタブごとのプレビューが表示されるようになる。Trunkではデフォルトで有効になってるので、次のメジャーリリースでもそうなるんだろう。

この機能について、ツリー型タブで対応してくれという要望が何件か来ていたので、0.10.2010043001以降では折り畳まれたツリーの中にあるタブのプレビューは表示しないようにしてみた。これを実現するにあたって調べたことを書き記しておく。

FirefoxでウィンドウごとではなくタブごとのプレビューをAero Peekに表示させるためのコードのうち、アドオンから簡単に触れるのはWindowsPreviewPerTab.jsmにあるコードだ。以下のようにするとプレビューのマネージャにアクセスすることができる。

Components.utils.import('resource://gre/modules/WindowsPreviewPerTab.jsm');
alert(AeroPeek); // "[object Object]"

ツリー型タブの新機能(?)の「折り畳まれたタブに対応するプレビューを隠す」は、ここからどうやれば実現できるのか。

まずAeroPeek.windowsの中から、処理対象のウィンドウに対応する項目を探す。このプロパティは各ウィンドウに対応するオブジェクトの配列になっていて、オブジェクトのwinプロパティにFirefoxのブラウザウィンドウのDOMWindowオブジェクトがそのまま入ってる。なので、以下のようにすれば今のウィンドウに対応するオブジェクトを見つけられる。

AeroPeek.windows.some(function(aTabWindow) {
  if (aTabWindow.win == window) {
    // 現在のウィンドウに対する操作
    return true;
  }
  return false;
});

また、このオブジェクトはpreviewsというプロパティの中に各タブのプレビューに対応するオブジェクトを持っている。以下のようにすれば、プレビューからタブのDOMElementを辿ることができる。

aTabWindow.previews.forEach(function(aPreview) {
  var tab = aPreview.controller.wrappedJSObject.tab;
  // タブに応じた操作
});

プレビューのオブジェクトはvisibleという真偽値のプロパティを持っていて、これの値がtrueだとAero Peekのプレビューが表示され、falseだと非表示になる。ツリー型タブの場合、タブが折り畳まれているかどうかによってこの値を上書きするようにしている。

var tab = aPreview.controller.wrappedJSObject.tab;
aPreview.visible = !TreeStyleTabService.isCollapsed(tab);

初期状態では、visibleの値はbrowser.taskbar.previews.enableの値と同じになっている。アドオンでvisibletrueにするとユーザがAero Peekを設定で無効化してても問答無用でプレビューが表示されてしまうので、誤ってtrueにしてしまわないように気をつけないといけない。僕はうっかりこれをやってしまった。

で、プレビューの表示・非表示を切り替えた後は、表示されるプレビューの総数が変わったことをマネージャに通知してやる。

AeroPeek.checkPreviewCount();

Firefoxは、プレビューの数が多すぎる時は強制的にプレビューを非表示にするようになってる。その切り替えの判断は、このメソッドが呼ばれた時に行われている。

以上をまとめると、こうなる。

AeroPeek.windows.some(function(aTabWindow) {
  if (aTabWindow.win == window) {
    aTabWindow.previews.forEach(function(aPreview) {
      var tab = aPreview.controller.wrappedJSObject.tab;
      aPreview.visible = !TreeStyleTabService.isCollapsed(tab);
    });
    AeroPeek.checkPreviewCount();
    return true;
  }
  return false;
});

ツリー型タブでは、これをツリーの開閉が行われる度に実行している。開閉の捕捉はカスタムイベントで行ってる。

プレビューの並び順とかも変えれそうな気がなんとなくしてるので、やる気が出てきたらまたいじってみようと思ってる。ただ、他のアドオンもここに手を出すと衝突しまくりそうではある。

エントリを編集します。

wikieditish message: Ready to edit this entry.











拡張機能