ページ

2008年6月18日水曜日

メニューのキャプチャ(その10)Spotlight

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前回まででメニューキャプチャも完成と思いきや Spotlight のキャプチャがうまくできない。またもや WindowList で原因を調査してみよう。

下図のように Spotlight を使っている状態でウィンドウ情報を取って見る。


Spotlight は2つ現れていて、表の中の一番上のウィンドウがメニューバーのアイコンを表している。表の下から2番目の Spotlightが結果表示のウィンドウを表している。これを見ると Layerは23で通常のメニュー(kCGPopUpMenuWindowLevel=101)と異なっている。


なるほど。だから今までのコードではうまくキャプチャできないのか。Layer=23がヘッダファイルに無いか調べてみる。
CGWindowLevel.h

#define kCGBaseWindowLevel  CGWindowLevelForKey(kCGBaseWindowLevelKey) /* INT32_MIN */
#define kCGMinimumWindowLevel CGWindowLevelForKey(kCGMinimumWindowLevelKey) /* (kCGBaseWindowLevel + 1) */
#define kCGDesktopWindowLevel CGWindowLevelForKey(kCGDesktopWindowLevelKey) /* kCGMinimumWindowLevel */
#define kCGDesktopIconWindowLevel CGWindowLevelForKey(kCGDesktopIconWindowLevelKey) /* kCGMinimumWindowLevel + 20 */
#define kCGBackstopMenuLevel CGWindowLevelForKey(kCGBackstopMenuLevelKey) /* -20 */
#define kCGNormalWindowLevel CGWindowLevelForKey(kCGNormalWindowLevelKey) /* 0 */
#define kCGFloatingWindowLevel CGWindowLevelForKey(kCGFloatingWindowLevelKey) /* 3 */
#define kCGTornOffMenuWindowLevel CGWindowLevelForKey(kCGTornOffMenuWindowLevelKey) /* 3 */
#define kCGDockWindowLevel CGWindowLevelForKey(kCGDockWindowLevelKey) /* 20 */
#define kCGMainMenuWindowLevel CGWindowLevelForKey(kCGMainMenuWindowLevelKey) /* 24 */
#define kCGStatusWindowLevel CGWindowLevelForKey(kCGStatusWindowLevelKey) /* 25 */
#define kCGModalPanelWindowLevel CGWindowLevelForKey(kCGModalPanelWindowLevelKey) /* 8 */
#define kCGPopUpMenuWindowLevel CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey) /* 101 */
#define kCGDraggingWindowLevel CGWindowLevelForKey(kCGDraggingWindowLevelKey) /* 500 */
#define kCGScreenSaverWindowLevel CGWindowLevelForKey(kCGScreenSaverWindowLevelKey) /* 1000 */
#define kCGCursorWindowLevel CGWindowLevelForKey(kCGCursorWindowLevelKey) /* 2000 */
#define kCGOverlayWindowLevel CGWindowLevelForKey(kCGOverlayWindowLevelKey) /* 102 */
#define kCGHelpWindowLevel CGWindowLevelForKey(kCGHelpWindowLevelKey) /* 200 */
#define kCGUtilityWindowLevel CGWindowLevelForKey(kCGUtilityWindowLevelKey) /* 19 */

#define kCGAssistiveTechHighWindowLevel CGWindowLevelForKey(kCGAssistiveTechHighWindowLevelKey) /* 1500 */


あ、23が見当たらない。。

まあいいか。定義は無いが Layer=23を狙い撃ちしてみよう。下記コードを追加する。
   } else if (layer == 23) {
[menu_windows addObject:[NSNumber numberWithInt:window_id]];
CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(window, kCGWindowBounds), &rect);
if (CGRectEqualToRect(rect_all,CGRectZero)) {
rect_all = rect;
} else {
rect_all = CGRectUnion(rect, rect_all);
}
is_spotlight = YES;
}

layer=23 の場合もキャプチャ対象とした上でフラグ is_spotlight を立てておく。

その上でその後のステータスバーの処理へ合流させる。
  } else if (is_status_bar || is_spotlight) {
        :



これだけでOK。結果はこんな感じ。


ソース:MenuCapture-07.zip
- - - -
これでメニューは制覇できただろうか。