From 1544915bb427ec076c075e9150c8c0214584f0ac Mon Sep 17 00:00:00 2001 From: Bryan Ferguson Date: Thu, 8 Aug 2019 16:41:02 -0700 Subject: [PATCH] Avoid capturing extraneous windows in CroppingWindowCapturerWin This change reduces cases where capturing a window with the cropping capturer captures unrelated windows from the same process. For instance: - Capturing an Explorer window could include portions of taskbar UI, e.g. when an auto-hide taskbar or window preview thumbnails are shown overtop. - Capturing a window from a process with multiple windows could include menus/tooltips from another window. Instead of capturing any window with an empty/matching title created by the same process, the cropping capturer will capture any window created by the same thread. While not foolproof, this heuristic seems to capture menus/tooltips from the window of interest while excluding those from other top-level windows in practice (assuming those were created by a separate thread / independent message pump). Bug: webrtc:10856 Change-Id: I2072c79da9e0158475b442a43b5b96d6ad307bc2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148641 Reviewed-by: Jamie Walch Commit-Queue: Jamie Walch Cr-Commit-Position: refs/heads/master@{#28824} --- .../cropping_window_capturer_win.cc | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/modules/desktop_capture/cropping_window_capturer_win.cc b/modules/desktop_capture/cropping_window_capturer_win.cc index d87e867afb..8c8f507a56 100644 --- a/modules/desktop_capture/cropping_window_capturer_win.cc +++ b/modules/desktop_capture/cropping_window_capturer_win.cc @@ -37,7 +37,8 @@ struct TopWindowVerifierContext { RTC_DCHECK_NE(selected_window, excluded_window); GetWindowTextW(selected_window, selected_window_title, kTitleLength); - GetWindowThreadProcessId(selected_window, &selected_window_process_id); + selected_window_thread_id = + GetWindowThreadProcessId(selected_window, &selected_window_process_id); } const HWND selected_window; @@ -46,6 +47,7 @@ struct TopWindowVerifierContext { WindowCaptureHelperWin* window_capture_helper; WCHAR selected_window_title[kTitleLength]; DWORD selected_window_process_id; + DWORD selected_window_thread_id; bool is_top_window; }; @@ -93,19 +95,15 @@ BOOL CALLBACK TopWindowVerifier(HWND hwnd, LPARAM param) { return TRUE; } - // If |hwnd| has no title or has same title as the selected window (i.e. - // Window Media Player consisting of several sibling windows) and belongs to - // the same process, assume it's a tooltip or context menu or sibling window - // from the selected window and ignore it. - WCHAR window_title[kTitleLength]; - GetWindowTextW(hwnd, window_title, kTitleLength); - if (wcsnlen_s(window_title, kTitleLength) == 0 || - wcscmp(window_title, context->selected_window_title) == 0) { - DWORD enumerated_window_process_id; - GetWindowThreadProcessId(hwnd, &enumerated_window_process_id); - if (context->selected_window_process_id == enumerated_window_process_id) { - return TRUE; - } + // Ignore windows that belong to the same thread since we want to capture + // them. This check works for tooltips & context menus. + DWORD enumerated_window_process_id = 0; + DWORD enumerated_window_thread_id = + GetWindowThreadProcessId(hwnd, &enumerated_window_process_id); + if (enumerated_window_thread_id != 0 && + enumerated_window_process_id == context->selected_window_process_id && + enumerated_window_thread_id == context->selected_window_thread_id) { + return TRUE; } // Checks whether current window |hwnd| intersects with