1678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org/*
2678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *
4678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  Use of this source code is governed by a BSD-style license
5678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  that can be found in the LICENSE file in the root of the source
6678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  tree. An additional intellectual property rights grant can be found
7678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  in the file PATENTS.  All contributing project authors may
8678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org */
10678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
11678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/modules/desktop_capture/mac/window_list_utils.h"
12678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
13678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include <ApplicationServices/ApplicationServices.h>
14678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
15678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/base/macutils.h"
16678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
17678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgnamespace webrtc {
18678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
19678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgbool GetWindowList(WindowCapturer::WindowList* windows) {
20678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  // Only get on screen, non-desktop windows.
21678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_array = CGWindowListCopyWindowInfo(
22678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
23678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      kCGNullWindowID);
24678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (!window_array)
25678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    return false;
26678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
27678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  // Check windows to make sure they have an id, title, and use window layer
28678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  // other than 0.
29678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFIndex count = CFArrayGetCount(window_array);
30678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  for (CFIndex i = 0; i < count; ++i) {
31678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
32678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFArrayGetValueAtIndex(window_array, i));
33678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFStringRef window_title = reinterpret_cast<CFStringRef>(
34678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowName));
35678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberRef window_id = reinterpret_cast<CFNumberRef>(
36678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowNumber));
37678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberRef window_layer = reinterpret_cast<CFNumberRef>(
38678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowLayer));
39678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (window_title && window_id && window_layer) {
40678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      // Skip windows with layer=0 (menu, dock).
41678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      int layer;
42678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFNumberGetValue(window_layer, kCFNumberIntType, &layer);
43678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      if (layer != 0)
44678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        continue;
45678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
46678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      int id;
47678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFNumberGetValue(window_id, kCFNumberIntType, &id);
48678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      WindowCapturer::Window window;
49678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      window.id = id;
50678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      if (!rtc::ToUtf8(window_title, &(window.title)) ||
51678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org          window.title.empty()) {
52678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        continue;
53678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      }
54678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      windows->push_back(window);
55678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    }
56678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
57678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
58678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_array);
59678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return true;
60678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
61678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
62678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}  // namespace webrtc
63