Implement and use new DesktopCapturer APIs in WebRTC
This change replaces all GetWindowList / GetScreenList with GetScreenList, SelectWindow / SelectScreen with SelectSource, and BringSelectedWindowToFront with FocusOnSelectedSource in WebRTC. BUG=webrtc:6513 Review-Url: https://codereview.webrtc.org/2479553006 Cr-Commit-Position: refs/heads/master@{#14960}
This commit is contained in:
parent
bcc5d87f09
commit
fce4905987
@ -58,20 +58,20 @@ void CroppingWindowCapturer::SetExcludedWindow(WindowId window) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CroppingWindowCapturer::GetWindowList(WindowList* windows) {
|
||||
return window_capturer_->GetWindowList(windows);
|
||||
bool CroppingWindowCapturer::GetSourceList(SourceList* sources) {
|
||||
return window_capturer_->GetSourceList(sources);
|
||||
}
|
||||
|
||||
bool CroppingWindowCapturer::SelectWindow(WindowId id) {
|
||||
if (window_capturer_->SelectWindow(id)) {
|
||||
bool CroppingWindowCapturer::SelectSource(SourceId id) {
|
||||
if (window_capturer_->SelectSource(id)) {
|
||||
selected_window_ = id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CroppingWindowCapturer::BringSelectedWindowToFront() {
|
||||
return window_capturer_->BringSelectedWindowToFront();
|
||||
bool CroppingWindowCapturer::FocusOnSelectedSource() {
|
||||
return window_capturer_->FocusOnSelectedSource();
|
||||
}
|
||||
|
||||
void CroppingWindowCapturer::OnCaptureResult(
|
||||
|
||||
@ -34,11 +34,9 @@ class CroppingWindowCapturer : public WindowCapturer,
|
||||
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
|
||||
void CaptureFrame() override;
|
||||
void SetExcludedWindow(WindowId window) override;
|
||||
|
||||
// WindowCapturer implementation.
|
||||
bool GetWindowList(WindowList* windows) override;
|
||||
bool SelectWindow(WindowId id) override;
|
||||
bool BringSelectedWindowToFront() override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
bool FocusOnSelectedSource() override;
|
||||
|
||||
// DesktopCapturer::Callback implementation, passed to |screen_capturer_| to
|
||||
// intercept the capture result.
|
||||
@ -67,7 +65,7 @@ class CroppingWindowCapturer : public WindowCapturer,
|
||||
DesktopCapturer::Callback* callback_;
|
||||
std::unique_ptr<WindowCapturer> window_capturer_;
|
||||
std::unique_ptr<ScreenCapturer> screen_capturer_;
|
||||
WindowId selected_window_;
|
||||
SourceId selected_window_;
|
||||
WindowId excluded_window_;
|
||||
};
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_frame.h"
|
||||
@ -59,6 +60,9 @@ class DesktopCapturer {
|
||||
|
||||
typedef intptr_t SourceId;
|
||||
|
||||
static_assert(std::is_same<SourceId, ScreenId>::value,
|
||||
"SourceId should be a same type as ScreenId.");
|
||||
|
||||
struct Source {
|
||||
// The unique id to represent a Source of current DesktopCapturer.
|
||||
SourceId id;
|
||||
|
||||
@ -157,9 +157,8 @@ CGWindowID FullScreenChromeWindowDetector::FindFullScreenWindow(
|
||||
if (full_screen_window_id == kCGNullWindowID)
|
||||
return kCGNullWindowID;
|
||||
|
||||
for (WindowCapturer::WindowList::iterator it = previous_window_list_.begin();
|
||||
it != previous_window_list_.end(); ++it) {
|
||||
if (static_cast<CGWindowID>(it->id) != full_screen_window_id)
|
||||
for (const auto& window : previous_window_list_) {
|
||||
if (static_cast<CGWindowID>(window.id) != full_screen_window_id)
|
||||
continue;
|
||||
|
||||
LOG(LS_WARNING) << "The full-screen window exists in the list.";
|
||||
@ -183,7 +182,7 @@ void FullScreenChromeWindowDetector::UpdateWindowListIfNeeded(
|
||||
return;
|
||||
}
|
||||
|
||||
GetWindowList(¤t_window_list_);
|
||||
GetWindowList(¤t_window_list_, false);
|
||||
last_update_time_ns_ = rtc::TimeNanos();
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/modules/desktop_capture/window_capturer.h"
|
||||
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
#include "webrtc/system_wrappers/include/atomic32.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -57,8 +57,8 @@ class FullScreenChromeWindowDetector {
|
||||
// |previous_window_list_| is taken at least 500ms before the next Capture()
|
||||
// call. If we only save the last result, we may get false positive (i.e.
|
||||
// full-screen window exists in the list) if Capture() is called too soon.
|
||||
WindowCapturer::WindowList current_window_list_;
|
||||
WindowCapturer::WindowList previous_window_list_;
|
||||
DesktopCapturer::SourceList current_window_list_;
|
||||
DesktopCapturer::SourceList previous_window_list_;
|
||||
int64_t last_update_time_ns_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(FullScreenChromeWindowDetector);
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
bool GetWindowList(WindowCapturer::WindowList* windows) {
|
||||
bool GetWindowList(DesktopCapturer::SourceList* windows,
|
||||
bool ignore_minimized) {
|
||||
// Only get on screen, non-desktop windows.
|
||||
CFArrayRef window_array = CGWindowListCopyWindowInfo(
|
||||
kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
|
||||
@ -24,6 +25,12 @@ bool GetWindowList(WindowCapturer::WindowList* windows) {
|
||||
if (!window_array)
|
||||
return false;
|
||||
|
||||
MacDesktopConfiguration desktop_config;
|
||||
if (ignore_minimized) {
|
||||
desktop_config = MacDesktopConfiguration::GetCurrent(
|
||||
MacDesktopConfiguration::TopLeftOrigin);
|
||||
}
|
||||
|
||||
// Check windows to make sure they have an id, title, and use window layer
|
||||
// other than 0.
|
||||
CFIndex count = CFArrayGetCount(window_array);
|
||||
@ -45,7 +52,14 @@ bool GetWindowList(WindowCapturer::WindowList* windows) {
|
||||
|
||||
int id;
|
||||
CFNumberGetValue(window_id, kCFNumberIntType, &id);
|
||||
WindowCapturer::Window window;
|
||||
|
||||
// Skip windows that are minimized and not full screen.
|
||||
if (ignore_minimized && IsWindowMinimized(id) &&
|
||||
!IsWindowFullScreen(desktop_config, window)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DesktopCapturer::Source window;
|
||||
window.id = id;
|
||||
if (!rtc::ToUtf8(window_title, &(window.title)) ||
|
||||
window.title.empty()) {
|
||||
|
||||
@ -13,17 +13,17 @@
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
|
||||
#include "webrtc/modules/desktop_capture/window_capturer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A helper function to get the on-screen windows.
|
||||
bool GetWindowList(WindowCapturer::WindowList* windows);
|
||||
// Another helper function to get the on-screen windows.
|
||||
bool GetWindowList(DesktopCapturer::SourceList* windows, bool ignore_minimized);
|
||||
|
||||
// Returns true if the window is occupying a full screen.
|
||||
bool IsWindowFullScreen(const MacDesktopConfiguration& desktop_config,
|
||||
CFDictionaryRef window);
|
||||
CFDictionaryRef window);
|
||||
|
||||
// Returns true if the window is minimized.
|
||||
bool IsWindowMinimized(CGWindowID id);
|
||||
|
||||
@ -94,17 +94,17 @@ TEST_F(MouseCursorMonitorTest, MAYBE(FromWindow)) {
|
||||
if (!window_capturer.get())
|
||||
return;
|
||||
|
||||
WindowCapturer::WindowList windows;
|
||||
EXPECT_TRUE(window_capturer->GetWindowList(&windows));
|
||||
DesktopCapturer::SourceList sources;
|
||||
EXPECT_TRUE(window_capturer->GetSourceList(&sources));
|
||||
|
||||
// Iterate over all windows and try capturing mouse cursor for each of them.
|
||||
for (size_t i = 0; i < windows.size(); ++i) {
|
||||
for (size_t i = 0; i < sources.size(); ++i) {
|
||||
cursor_image_.reset();
|
||||
position_received_ = false;
|
||||
|
||||
std::unique_ptr<MouseCursorMonitor> capturer(
|
||||
MouseCursorMonitor::CreateForWindow(
|
||||
DesktopCaptureOptions::CreateDefault(), windows[i].id));
|
||||
DesktopCaptureOptions::CreateDefault(), sources[i].id));
|
||||
assert(capturer.get());
|
||||
|
||||
capturer->Init(this, MouseCursorMonitor::SHAPE_AND_POSITION);
|
||||
|
||||
@ -55,10 +55,8 @@ class ScreenCapturerLinux : public ScreenCapturer,
|
||||
// DesktopCapturer interface.
|
||||
void Start(Callback* delegate) override;
|
||||
void CaptureFrame() override;
|
||||
|
||||
// ScreenCapturer interface.
|
||||
bool GetScreenList(ScreenList* screens) override;
|
||||
bool SelectScreen(ScreenId id) override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
|
||||
private:
|
||||
Display* display() { return options_.x_display()->display(); }
|
||||
@ -267,16 +265,14 @@ void ScreenCapturerLinux::CaptureFrame() {
|
||||
callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
|
||||
}
|
||||
|
||||
bool ScreenCapturerLinux::GetScreenList(ScreenList* screens) {
|
||||
RTC_DCHECK(screens->size() == 0);
|
||||
bool ScreenCapturerLinux::GetSourceList(SourceList* sources) {
|
||||
RTC_DCHECK(sources->size() == 0);
|
||||
// TODO(jiayl): implement screen enumeration.
|
||||
Screen default_screen;
|
||||
default_screen.id = 0;
|
||||
screens->push_back(default_screen);
|
||||
sources->push_back({0});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScreenCapturerLinux::SelectScreen(ScreenId id) {
|
||||
bool ScreenCapturerLinux::SelectSource(SourceId id) {
|
||||
// TODO(jiayl): implement screen selection.
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -10,13 +10,14 @@
|
||||
|
||||
#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
bool GetScreenList(ScreenCapturer::ScreenList* screens) {
|
||||
assert(screens->size() == 0);
|
||||
bool GetScreenList(DesktopCapturer::SourceList* screens) {
|
||||
RTC_DCHECK(screens->size() == 0);
|
||||
|
||||
BOOL enum_result = TRUE;
|
||||
for (int device_index = 0;; ++device_index) {
|
||||
@ -32,14 +33,12 @@ bool GetScreenList(ScreenCapturer::ScreenList* screens) {
|
||||
if (!(device.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||
continue;
|
||||
|
||||
ScreenCapturer::Screen screen;
|
||||
screen.id = device_index;
|
||||
screens->push_back(screen);
|
||||
screens->push_back({device_index, std::string()});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsScreenValid(ScreenId screen, std::wstring* device_key) {
|
||||
bool IsScreenValid(DesktopCapturer::SourceId screen, std::wstring* device_key) {
|
||||
if (screen == kFullDesktopScreenId) {
|
||||
*device_key = L"";
|
||||
return true;
|
||||
@ -54,7 +53,8 @@ bool IsScreenValid(ScreenId screen, std::wstring* device_key) {
|
||||
return !!enum_result;
|
||||
}
|
||||
|
||||
DesktopRect GetScreenRect(ScreenId screen, const std::wstring& device_key) {
|
||||
DesktopRect GetScreenRect(DesktopCapturer::SourceId screen,
|
||||
const std::wstring& device_key) {
|
||||
if (screen == kFullDesktopScreenId) {
|
||||
return DesktopRect::MakeXYWH(GetSystemMetrics(SM_XVIRTUALSCREEN),
|
||||
GetSystemMetrics(SM_YVIRTUALSCREEN),
|
||||
|
||||
@ -11,24 +11,25 @@
|
||||
#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURE_UTILS_H_
|
||||
#define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURE_UTILS_H_
|
||||
|
||||
#include "webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Output the list of active screens into |screens|. Returns true if succeeded,
|
||||
// or false if it fails to enumerate the display devices.
|
||||
bool GetScreenList(ScreenCapturer::ScreenList* screens);
|
||||
bool GetScreenList(DesktopCapturer::SourceList* screens);
|
||||
|
||||
// Returns true if |screen| is a valid screen. The screen device key is
|
||||
// returned through |device_key| if the screen is valid. The device key can be
|
||||
// used in GetScreenRect to verify the screen matches the previously obtained
|
||||
// id.
|
||||
bool IsScreenValid(ScreenId screen, std::wstring* device_key);
|
||||
bool IsScreenValid(DesktopCapturer::SourceId screen, std::wstring* device_key);
|
||||
|
||||
// Get the rect of the screen identified by |screen|, relative to the primary
|
||||
// display's top-left. If the screen device key does not match |device_key|, or
|
||||
// the screen does not exist, or any error happens, an empty rect is returned.
|
||||
DesktopRect GetScreenRect(ScreenId screen, const std::wstring& device_key);
|
||||
DesktopRect GetScreenRect(DesktopCapturer::SourceId screen,
|
||||
const std::wstring& device_key);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
@ -109,15 +109,15 @@ void ScreenCapturerWinDirectx::CaptureFrame() {
|
||||
callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinDirectx::GetScreenList(ScreenList* screens) {
|
||||
bool ScreenCapturerWinDirectx::GetSourceList(SourceList* sources) {
|
||||
int screen_count = DxgiDuplicatorController::Instance()->ScreenCount();
|
||||
for (int i = 0; i < screen_count; i++) {
|
||||
screens->push_back(Screen{i});
|
||||
sources->push_back({i});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinDirectx::SelectScreen(ScreenId id) {
|
||||
bool ScreenCapturerWinDirectx::SelectSource(SourceId id) {
|
||||
if (id == current_screen_id_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -39,8 +39,8 @@ class ScreenCapturerWinDirectx : public ScreenCapturer {
|
||||
void SetSharedMemoryFactory(
|
||||
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetScreenList(ScreenList* screens) override;
|
||||
bool SelectScreen(ScreenId id) override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
|
||||
private:
|
||||
// Returns desktop size of selected screen.
|
||||
@ -52,7 +52,7 @@ class ScreenCapturerWinDirectx : public ScreenCapturer {
|
||||
|
||||
DxgiDuplicatorController::Context context_;
|
||||
|
||||
ScreenId current_screen_id_ = kFullDesktopScreenId;
|
||||
SourceId current_screen_id_ = kFullDesktopScreenId;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerWinDirectx);
|
||||
};
|
||||
|
||||
@ -98,11 +98,11 @@ void ScreenCapturerWinGdi::CaptureFrame() {
|
||||
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinGdi::GetScreenList(ScreenList* screens) {
|
||||
return webrtc::GetScreenList(screens);
|
||||
bool ScreenCapturerWinGdi::GetSourceList(SourceList* sources) {
|
||||
return webrtc::GetScreenList(sources);
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinGdi::SelectScreen(ScreenId id) {
|
||||
bool ScreenCapturerWinGdi::SelectSource(SourceId id) {
|
||||
bool valid = IsScreenValid(id, ¤t_device_key_);
|
||||
if (valid)
|
||||
current_screen_id_ = id;
|
||||
|
||||
@ -40,8 +40,8 @@ class ScreenCapturerWinGdi : public ScreenCapturer {
|
||||
void SetSharedMemoryFactory(
|
||||
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetScreenList(ScreenList* screens) override;
|
||||
bool SelectScreen(ScreenId id) override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
|
||||
private:
|
||||
typedef HRESULT (WINAPI * DwmEnableCompositionFunc)(UINT);
|
||||
@ -58,7 +58,7 @@ class ScreenCapturerWinGdi : public ScreenCapturer {
|
||||
|
||||
Callback* callback_ = nullptr;
|
||||
std::unique_ptr<SharedMemoryFactory> shared_memory_factory_;
|
||||
ScreenId current_screen_id_ = kFullDesktopScreenId;
|
||||
SourceId current_screen_id_ = kFullDesktopScreenId;
|
||||
std::wstring current_device_key_;
|
||||
|
||||
ScopedThreadDesktop desktop_;
|
||||
|
||||
@ -126,11 +126,11 @@ void ScreenCapturerWinMagnifier::CaptureFrame() {
|
||||
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinMagnifier::GetScreenList(ScreenList* screens) {
|
||||
return webrtc::GetScreenList(screens);
|
||||
bool ScreenCapturerWinMagnifier::GetSourceList(SourceList* sources) {
|
||||
return webrtc::GetScreenList(sources);
|
||||
}
|
||||
|
||||
bool ScreenCapturerWinMagnifier::SelectScreen(ScreenId id) {
|
||||
bool ScreenCapturerWinMagnifier::SelectSource(SourceId id) {
|
||||
bool valid = IsScreenValid(id, ¤t_device_key_);
|
||||
|
||||
// Set current_screen_id_ even if the fallback capturer is being used, so we
|
||||
|
||||
@ -52,8 +52,8 @@ class ScreenCapturerWinMagnifier : public ScreenCapturer {
|
||||
void SetSharedMemoryFactory(
|
||||
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetScreenList(ScreenList* screens) override;
|
||||
bool SelectScreen(ScreenId id) override;
|
||||
bool GetSourceList(SourceList* screens) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
void SetExcludedWindow(WindowId window) override;
|
||||
|
||||
private:
|
||||
|
||||
@ -48,14 +48,12 @@ class WindowCapturerMac : public WindowCapturer {
|
||||
full_screen_chrome_window_detector);
|
||||
~WindowCapturerMac() override;
|
||||
|
||||
// WindowCapturer interface.
|
||||
bool GetWindowList(WindowList* windows) override;
|
||||
bool SelectWindow(WindowId id) override;
|
||||
bool BringSelectedWindowToFront() override;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
void Start(Callback* callback) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
bool FocusOnSelectedSource() override;
|
||||
|
||||
private:
|
||||
Callback* callback_ = nullptr;
|
||||
@ -76,63 +74,18 @@ WindowCapturerMac::WindowCapturerMac(
|
||||
|
||||
WindowCapturerMac::~WindowCapturerMac() {}
|
||||
|
||||
bool WindowCapturerMac::GetWindowList(WindowList* windows) {
|
||||
// Only get on screen, non-desktop windows.
|
||||
CFArrayRef window_array = CGWindowListCopyWindowInfo(
|
||||
kCGWindowListExcludeDesktopElements,
|
||||
kCGNullWindowID);
|
||||
if (!window_array)
|
||||
return false;
|
||||
MacDesktopConfiguration desktop_config = MacDesktopConfiguration::GetCurrent(
|
||||
MacDesktopConfiguration::TopLeftOrigin);
|
||||
// Check windows to make sure they have an id, title, and use window layer
|
||||
// other than 0.
|
||||
CFIndex count = CFArrayGetCount(window_array);
|
||||
for (CFIndex i = 0; i < count; ++i) {
|
||||
CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
|
||||
CFArrayGetValueAtIndex(window_array, i));
|
||||
CFStringRef window_title = reinterpret_cast<CFStringRef>(
|
||||
CFDictionaryGetValue(window, kCGWindowName));
|
||||
CFNumberRef window_id = reinterpret_cast<CFNumberRef>(
|
||||
CFDictionaryGetValue(window, kCGWindowNumber));
|
||||
CFNumberRef window_layer = reinterpret_cast<CFNumberRef>(
|
||||
CFDictionaryGetValue(window, kCGWindowLayer));
|
||||
if (window_title && window_id && window_layer) {
|
||||
// Skip windows with layer=0 (menu, dock).
|
||||
int layer;
|
||||
CFNumberGetValue(window_layer, kCFNumberIntType, &layer);
|
||||
if (layer != 0)
|
||||
continue;
|
||||
|
||||
int id;
|
||||
CFNumberGetValue(window_id, kCFNumberIntType, &id);
|
||||
|
||||
// Skip windows that are minimized and not full screen.
|
||||
if (IsWindowMinimized(id) &&
|
||||
!IsWindowFullScreen(desktop_config, window)) { continue;}
|
||||
|
||||
WindowCapturer::Window window;
|
||||
window.id = id;
|
||||
if (!rtc::ToUtf8(window_title, &(window.title)) ||
|
||||
window.title.empty()) {
|
||||
continue;
|
||||
}
|
||||
windows->push_back(window);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(window_array);
|
||||
return true;
|
||||
bool WindowCapturerMac::GetSourceList(SourceList* sources) {
|
||||
return webrtc::GetWindowList(sources, true);
|
||||
}
|
||||
|
||||
bool WindowCapturerMac::SelectWindow(WindowId id) {
|
||||
bool WindowCapturerMac::SelectSource(SourceId id) {
|
||||
if (!IsWindowValid(id))
|
||||
return false;
|
||||
window_id_ = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerMac::BringSelectedWindowToFront() {
|
||||
bool WindowCapturerMac::FocusOnSelectedSource() {
|
||||
if (!window_id_)
|
||||
return false;
|
||||
|
||||
|
||||
@ -24,14 +24,11 @@ class WindowCapturerNull : public WindowCapturer {
|
||||
WindowCapturerNull();
|
||||
~WindowCapturerNull() override;
|
||||
|
||||
// WindowCapturer interface.
|
||||
bool GetWindowList(WindowList* windows) override;
|
||||
bool SelectWindow(WindowId id) override;
|
||||
bool BringSelectedWindowToFront() override;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
void Start(Callback* callback) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
|
||||
private:
|
||||
Callback* callback_ = nullptr;
|
||||
@ -42,17 +39,12 @@ class WindowCapturerNull : public WindowCapturer {
|
||||
WindowCapturerNull::WindowCapturerNull() {}
|
||||
WindowCapturerNull::~WindowCapturerNull() {}
|
||||
|
||||
bool WindowCapturerNull::GetWindowList(WindowList* windows) {
|
||||
bool WindowCapturerNull::GetSourceList(SourceList* sources) {
|
||||
// Not implemented yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WindowCapturerNull::SelectWindow(WindowId id) {
|
||||
// Not implemented yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WindowCapturerNull::BringSelectedWindowToFront() {
|
||||
bool WindowCapturerNull::SelectSource(SourceId id) {
|
||||
// Not implemented yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -43,12 +43,11 @@ class WindowCapturerTest : public testing::Test,
|
||||
|
||||
// Verify that we can enumerate windows.
|
||||
TEST_F(WindowCapturerTest, Enumerate) {
|
||||
WindowCapturer::WindowList windows;
|
||||
EXPECT_TRUE(capturer_->GetWindowList(&windows));
|
||||
DesktopCapturer::SourceList sources;
|
||||
EXPECT_TRUE(capturer_->GetSourceList(&sources));
|
||||
|
||||
// Verify that window titles are set.
|
||||
for (WindowCapturer::WindowList::iterator it = windows.begin();
|
||||
it != windows.end(); ++it) {
|
||||
for (auto it = sources.begin(); it != sources.end(); ++it) {
|
||||
EXPECT_FALSE(it->title.empty());
|
||||
}
|
||||
}
|
||||
@ -61,24 +60,23 @@ TEST_F(WindowCapturerTest, Enumerate) {
|
||||
// have a python script showing Tk dialog, but launching code will differ
|
||||
// between platforms).
|
||||
TEST_F(WindowCapturerTest, Capture) {
|
||||
WindowCapturer::WindowList windows;
|
||||
DesktopCapturer::SourceList sources;
|
||||
capturer_->Start(this);
|
||||
EXPECT_TRUE(capturer_->GetWindowList(&windows));
|
||||
EXPECT_TRUE(capturer_->GetSourceList(&sources));
|
||||
|
||||
// Verify that we can select and capture each window.
|
||||
for (WindowCapturer::WindowList::iterator it = windows.begin();
|
||||
it != windows.end(); ++it) {
|
||||
for (auto it = sources.begin(); it != sources.end(); ++it) {
|
||||
frame_.reset();
|
||||
if (capturer_->SelectWindow(it->id)) {
|
||||
if (capturer_->SelectSource(it->id)) {
|
||||
capturer_->CaptureFrame();
|
||||
}
|
||||
|
||||
// If we failed to capture a window make sure it no longer exists.
|
||||
if (!frame_.get()) {
|
||||
WindowCapturer::WindowList new_list;
|
||||
EXPECT_TRUE(capturer_->GetWindowList(&new_list));
|
||||
for (WindowCapturer::WindowList::iterator new_list_it = new_list.begin();
|
||||
new_list_it != new_list.end(); ++new_list_it) {
|
||||
DesktopCapturer::SourceList new_list;
|
||||
EXPECT_TRUE(capturer_->GetSourceList(&new_list));
|
||||
for (auto new_list_it = new_list.begin(); new_list_it != new_list.end();
|
||||
++new_list_it) {
|
||||
EXPECT_FALSE(it->id == new_list_it->id);
|
||||
}
|
||||
continue;
|
||||
|
||||
@ -26,8 +26,8 @@ namespace webrtc {
|
||||
namespace {
|
||||
|
||||
BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
|
||||
WindowCapturer::WindowList* list =
|
||||
reinterpret_cast<WindowCapturer::WindowList*>(param);
|
||||
DesktopCapturer::SourceList* list =
|
||||
reinterpret_cast<DesktopCapturer::SourceList*>(param);
|
||||
|
||||
// Skip windows that are invisible, minimized, have no title, or are owned,
|
||||
// unless they have the app window style set.
|
||||
@ -62,7 +62,7 @@ BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WindowCapturer::Window window;
|
||||
DesktopCapturer::Source window;
|
||||
window.id = reinterpret_cast<WindowId>(hwnd);
|
||||
|
||||
const size_t kTitleLength = 500;
|
||||
@ -85,14 +85,12 @@ class WindowCapturerWin : public WindowCapturer {
|
||||
WindowCapturerWin();
|
||||
~WindowCapturerWin() override;
|
||||
|
||||
// WindowCapturer interface.
|
||||
bool GetWindowList(WindowList* windows) override;
|
||||
bool SelectWindow(WindowId id) override;
|
||||
bool BringSelectedWindowToFront() override;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
void Start(Callback* callback) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
bool FocusOnSelectedSource() override;
|
||||
|
||||
private:
|
||||
Callback* callback_ = nullptr;
|
||||
@ -115,15 +113,15 @@ class WindowCapturerWin : public WindowCapturer {
|
||||
WindowCapturerWin::WindowCapturerWin() {}
|
||||
WindowCapturerWin::~WindowCapturerWin() {}
|
||||
|
||||
bool WindowCapturerWin::GetWindowList(WindowList* windows) {
|
||||
WindowList result;
|
||||
bool WindowCapturerWin::GetSourceList(SourceList* sources) {
|
||||
SourceList result;
|
||||
LPARAM param = reinterpret_cast<LPARAM>(&result);
|
||||
if (!EnumWindows(&WindowsEnumerationHandler, param))
|
||||
return false;
|
||||
windows->swap(result);
|
||||
sources->swap(result);
|
||||
|
||||
std::map<HWND, DesktopSize> new_map;
|
||||
for (const auto& item : *windows) {
|
||||
for (const auto& item : *sources) {
|
||||
HWND hwnd = reinterpret_cast<HWND>(item.id);
|
||||
new_map[hwnd] = window_size_map_[hwnd];
|
||||
}
|
||||
@ -132,7 +130,7 @@ bool WindowCapturerWin::GetWindowList(WindowList* windows) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerWin::SelectWindow(WindowId id) {
|
||||
bool WindowCapturerWin::SelectSource(SourceId id) {
|
||||
HWND window = reinterpret_cast<HWND>(id);
|
||||
if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window))
|
||||
return false;
|
||||
@ -143,7 +141,7 @@ bool WindowCapturerWin::SelectWindow(WindowId id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerWin::BringSelectedWindowToFront() {
|
||||
bool WindowCapturerWin::FocusOnSelectedSource() {
|
||||
if (!window_)
|
||||
return false;
|
||||
|
||||
|
||||
@ -88,14 +88,12 @@ class WindowCapturerLinux : public WindowCapturer,
|
||||
WindowCapturerLinux(const DesktopCaptureOptions& options);
|
||||
~WindowCapturerLinux() override;
|
||||
|
||||
// WindowCapturer interface.
|
||||
bool GetWindowList(WindowList* windows) override;
|
||||
bool SelectWindow(WindowId id) override;
|
||||
bool BringSelectedWindowToFront() override;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
void Start(Callback* callback) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
bool FocusOnSelectedSource() override;
|
||||
|
||||
// SharedXDisplay::XEventHandler interface.
|
||||
bool HandleXEvent(const XEvent& event) override;
|
||||
@ -154,8 +152,8 @@ WindowCapturerLinux::~WindowCapturerLinux() {
|
||||
x_display_->RemoveEventHandler(ConfigureNotify, this);
|
||||
}
|
||||
|
||||
bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
|
||||
WindowList result;
|
||||
bool WindowCapturerLinux::GetSourceList(SourceList* sources) {
|
||||
SourceList result;
|
||||
|
||||
XErrorTrap error_trap(display());
|
||||
|
||||
@ -178,7 +176,7 @@ bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
|
||||
::Window app_window =
|
||||
GetApplicationWindow(children[num_children - 1 - i]);
|
||||
if (app_window && !IsDesktopElement(app_window)) {
|
||||
Window w;
|
||||
Source w;
|
||||
w.id = app_window;
|
||||
if (GetWindowTitle(app_window, &w.title))
|
||||
result.push_back(w);
|
||||
@ -189,12 +187,12 @@ bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
|
||||
XFree(children);
|
||||
}
|
||||
|
||||
windows->swap(result);
|
||||
sources->swap(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerLinux::SelectWindow(WindowId id) {
|
||||
bool WindowCapturerLinux::SelectSource(SourceId id) {
|
||||
if (!x_server_pixel_buffer_.Init(display(), id))
|
||||
return false;
|
||||
|
||||
@ -215,7 +213,7 @@ bool WindowCapturerLinux::SelectWindow(WindowId id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCapturerLinux::BringSelectedWindowToFront() {
|
||||
bool WindowCapturerLinux::FocusOnSelectedSource() {
|
||||
if (!selected_window_)
|
||||
return false;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user