2011年3月7日月曜日

Cocoa ObjC DesktopのwindowNumber

昨日の「マウスイベントが起きた場所がどのウィンドウ上でもないならDesktop」という条件判断はかなり精度が低いので、もう少しクリティカルにDesktop上のイベントと判断できるようにしてみる。

CGWindowListCopyWindowInfoではwindowID(=windowNumber)やwindowNameやらを取得できるから、Classの初期化時に一度だけDesktopのwindowIDを探し出してインスタンス変数に収めておけばいいのでは、という方針で行く。

そこでこんな風にやってみる。

CFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll  , kCGNullWindowID);

 for (i=0; i < CFArrayGetCount(list); i++) {
  w = CFArrayGetValueAtIndex(list, i);
  windowName=CFDictionaryGetValue(w, kCGWindowName);
  if([(NSString *)windowName isEqualToString:@"Desktop"]){
   CFNumberGetValue(CFDictionaryGetValue(w, kCGWindowNumber),kCGWindowIDCFNumberType, &spot_window_id);
   desktopID=(NSUInteger)spot_window_id;
   
  }
 }

これでたしかにDesktopのwindowIDが取れるわけだが・・・desktopIDに入るのは「2」ですな、私の環境の場合。残念ながらこれは「Desktopという名前をもつWindowのwindowID」であって、現実のOSXのデスクトップではないらしい。
xcatsan師匠作の「windowList.app」で調べてみると、たしかにDesktopのwindowIDは「2」。しかし現実のデスクトップはwindowIDが「11」の、FinderをOwnerにもつ無名のウィンドウらしい。うへー、名前なしか。どうやって特定しよう。いつでも必ず11だっていうことなら、 #define DESKTOP_ID 11 とかしちゃえば早い。実際に実験してみたらこれでも動く。しかし11じゃないことだってありそうだ。 ということで、Ownerが「Finder」、ウィンドウのサイズがフルスクリーン、という条件で絞り出してみる。
CFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll  , kCGNullWindowID);
 CGRect screenRect=NSRectToCGRect([[NSScreen mainScreen] frame]);

 for (i=0; i < CFArrayGetCount(list); i++) {
  w = CFArrayGetValueAtIndex(list, i);
  windowOwnerName=CFDictionaryGetValue(w, kCGWindowOwnerName);
  //NSLog(@"winName=%@",windowOwnerName);
  if([(NSString *)windowOwnerName isEqualToString:@"Finder"]){
   CGRectMakeWithDictionaryRepresentation(CFDictionaryGetValue(w, kCGWindowBounds), &rect);
   if (CGRectEqualToRect(rect ,screenRect)) {
  
    CFNumberGetValue(CFDictionaryGetValue(w, kCGWindowNumber),kCGWindowIDCFNumberType, &spot_window_id);
    //NSLog(@"Desktop WindowID=%d",spot_window_id);
    desktopID=(NSUInteger)spot_window_id;
   }
  }
 }


これでwindowIDが「11」となった。ちょっとあやふやな方法だけど、フルスクリーンのFinderウィンドウは極めてまれだろうから、一応よしとしよう。

0 件のコメント:

コメントを投稿