desktopCaptuer: exempt to overlapping between hidden taskbar and maximized target
On Windows 10, the hidden taskbar won't be totally hidden, but having a 2 pixel margin on the screen. While a maximized app window will use up the full screen, there will be overlapping between a hidden taskbar and a maximized app window, which will impact window capture to that maximized window. If the target window doesn't support GDI methods well, the capture may be black (i.e. Chrome) or still (i.e. Word). Because there is no solid way to identify a hidden taskbar window, we have to make an exemption to the overlapping to a maximized window is 2-pixel X screen-width/height, which is thin enough to be noticed in the cropping result. Bug: chromium:838062 Change-Id: I9e0fbdf43b4445ca9fbbf5ed43bb266ae726a5b8 Reviewed-on: https://webrtc-review.googlesource.com/c/123261 Commit-Queue: Brave Yao <braveyao@webrtc.org> Reviewed-by: Jamie Walch <jamiewalch@chromium.org> Cr-Commit-Position: refs/heads/master@{#26755}
This commit is contained in:
parent
0e449072ba
commit
4e7058e621
@ -117,36 +117,13 @@ BOOL CALLBACK TopWindowVerifier(HWND hwnd, LPARAM param) {
|
||||
|
||||
// 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.
|
||||
if (context->window_capture_helper->IsWindowIntersectWithSelectedWindow(
|
||||
hwnd, context->selected_window, context->selected_window_rect)) {
|
||||
// If intersection is not empty, the selected window is not on top.
|
||||
context->is_top_window = false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
content_rect.IntersectWith(context->selected_window_rect);
|
||||
|
||||
// If intersection is not empty, the selected window is not on top.
|
||||
if (!content_rect.is_empty()) {
|
||||
context->is_top_window = false;
|
||||
return FALSE;
|
||||
}
|
||||
// Otherwise, keep enumerating.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -20,6 +20,9 @@ namespace webrtc {
|
||||
// Prefix used to match the window class for Chrome windows.
|
||||
const wchar_t kChromeWindowClassPrefix[] = L"Chrome_WidgetWin_";
|
||||
|
||||
// The hiddgen taskbar will leave a 2 pixel margin on the screen.
|
||||
const int kHiddenTaskbarMarginOnScreen = 2;
|
||||
|
||||
bool GetWindowRect(HWND window, DesktopRect* result) {
|
||||
RECT rect;
|
||||
if (!::GetWindowRect(window, &rect)) {
|
||||
@ -199,6 +202,58 @@ bool WindowCaptureHelperWin::IsWindowChromeNotification(HWND hwnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// |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.
|
||||
bool WindowCaptureHelperWin::IsWindowIntersectWithSelectedWindow(
|
||||
HWND hwnd,
|
||||
HWND selected_hwnd,
|
||||
const DesktopRect& selected_window_rect) {
|
||||
DesktopRect content_rect;
|
||||
if (!GetWindowContentRect(hwnd, &content_rect)) {
|
||||
// Bail out if failed to get the window area.
|
||||
return true;
|
||||
}
|
||||
content_rect.IntersectWith(selected_window_rect);
|
||||
|
||||
if (content_rect.is_empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When the taskbar is automatically hidden, it will leave a 2 pixel margin on
|
||||
// the screen which will overlap the maximized selected window that will use
|
||||
// up the full screen area. Since there is no solid way to identify a hidden
|
||||
// taskbar window, we have to make an exemption here if the overlapping is
|
||||
// 2 x screen_width/height to a maximized window.
|
||||
bool is_maximized = false;
|
||||
IsWindowMaximized(selected_hwnd, &is_maximized);
|
||||
bool overlaps_hidden_horizontal_taskbar =
|
||||
selected_window_rect.width() == content_rect.width() &&
|
||||
content_rect.height() == kHiddenTaskbarMarginOnScreen;
|
||||
bool overlaps_hidden_vertical_taskbar =
|
||||
selected_window_rect.height() == content_rect.height() &&
|
||||
content_rect.width() == kHiddenTaskbarMarginOnScreen;
|
||||
if (is_maximized && (overlaps_hidden_horizontal_taskbar ||
|
||||
overlaps_hidden_vertical_taskbar)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowCaptureHelperWin::IsWindowOnCurrentDesktop(HWND hwnd) {
|
||||
// Make sure the window is on the current virtual desktop.
|
||||
if (virtual_desktop_manager_) {
|
||||
|
||||
@ -67,6 +67,10 @@ class WindowCaptureHelperWin {
|
||||
|
||||
bool IsAeroEnabled();
|
||||
bool IsWindowChromeNotification(HWND hwnd);
|
||||
bool IsWindowIntersectWithSelectedWindow(
|
||||
HWND hwnd,
|
||||
HWND selected_hwnd,
|
||||
const DesktopRect& selected_window_rect);
|
||||
bool IsWindowOnCurrentDesktop(HWND hwnd);
|
||||
bool IsWindowVisibleOnCurrentDesktop(HWND hwnd);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user