前回まででメニューキャプチャも完成と思いきや 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
- - - -
これでメニューは制覇できただろうか。