diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc b/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc index 6b046d8149..5730e43d56 100644 --- a/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc +++ b/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc @@ -90,20 +90,35 @@ BOOL CALLBACK TopWindowVerifier(HWND hwnd, LPARAM param) { } } - DesktopRect window_rect; - // TODO(zijiehe): Window content rectangle should be preferred to avoid - // falling back to window capturer when the border or shadow of another window - // covering the target window. - if (!GetWindowRect(hwnd, &window_rect)) { + // Checks whether current window |hwnd| intersects with + // |context|->selected_window. + // |content_rect| is preferred because, + // 1. WindowCapturerWin is using GDI capturer, which cannot capture DX output. + // So ScreenCapturer should be used as much as possible to avoid + // uncapturable cases. Note: lots of new applications are using DX output + // (hardware acceleration) to improve the performance which cannot be + // captured by WindowCapturerWin. See bug http://crbug.com/741770. + // 2. WindowCapturerWin is still useful because we do not want to expose the + // content on other windows if the target window is covered by them. + // 3. Shadow and borders should not be considered as "content" on other + // windows because they do not expose any useful information. + // + // So we can bear the false-negative cases (target window is covered by the + // borders or shadow of other windows, but we have not detected it) in favor + // of using ScreenCapturer, rather than let the false-positive cases (target + // windows is only covered by borders or shadow of other windows, but we treat + // it as overlapping) impact the user experience. + DesktopRect content_rect; + if (!GetWindowContentRect(hwnd, &content_rect)) { // Bail out if failed to get the window area. context->is_top_window = false; return FALSE; } - window_rect.IntersectWith(context->selected_window_rect); + content_rect.IntersectWith(context->selected_window_rect); // If intersection is not empty, the selected window is not on top. - if (!window_rect.is_empty()) { + if (!content_rect.is_empty()) { context->is_top_window = false; return FALSE; } @@ -206,11 +221,10 @@ bool CroppingWindowCapturerWin::ShouldUseScreenCapturer() { // Check if the window is occluded by any other window, excluding the child // windows, context menus, and |excluded_window_|. - // TODO(zijiehe): Content rectangle should be preferred to avoid falling back - // to window capturer when border or shadow of another window covering the - // target window. + // |content_rect| is preferred, see the comments in TopWindowVerifier() + // function. TopWindowVerifierContext context( - selected, reinterpret_cast(excluded_window()), window_region_rect_); + selected, reinterpret_cast(excluded_window()), content_rect); const LPARAM enum_param = reinterpret_cast(&context); EnumWindows(&TopWindowVerifier, enum_param); if (!context.is_top_window) {