1/*
2 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/desktop_capture/mac/window_list_utils.h"
12
13#include <ApplicationServices/ApplicationServices.h>
14
15#include "webrtc/base/macutils.h"
16
17namespace webrtc {
18
19bool GetWindowList(WindowCapturer::WindowList* windows) {
20  // Only get on screen, non-desktop windows.
21  CFArrayRef window_array = CGWindowListCopyWindowInfo(
22      kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
23      kCGNullWindowID);
24  if (!window_array)
25    return false;
26
27  // Check windows to make sure they have an id, title, and use window layer
28  // other than 0.
29  CFIndex count = CFArrayGetCount(window_array);
30  for (CFIndex i = 0; i < count; ++i) {
31    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
32        CFArrayGetValueAtIndex(window_array, i));
33    CFStringRef window_title = reinterpret_cast<CFStringRef>(
34        CFDictionaryGetValue(window, kCGWindowName));
35    CFNumberRef window_id = reinterpret_cast<CFNumberRef>(
36        CFDictionaryGetValue(window, kCGWindowNumber));
37    CFNumberRef window_layer = reinterpret_cast<CFNumberRef>(
38        CFDictionaryGetValue(window, kCGWindowLayer));
39    if (window_title && window_id && window_layer) {
40      // Skip windows with layer=0 (menu, dock).
41      int layer;
42      CFNumberGetValue(window_layer, kCFNumberIntType, &layer);
43      if (layer != 0)
44        continue;
45
46      int id;
47      CFNumberGetValue(window_id, kCFNumberIntType, &id);
48      WindowCapturer::Window window;
49      window.id = id;
50      if (!rtc::ToUtf8(window_title, &(window.title)) ||
51          window.title.empty()) {
52        continue;
53      }
54      windows->push_back(window);
55    }
56  }
57
58  CFRelease(window_array);
59  return true;
60}
61
62}  // namespace webrtc
63