CroppingWindowCapturerWin: filter out cloaked window.
A cloaked window is composited but not visible to the user. When Win10 feature 'Cortana' is enabled it creates a window that is always invisible and its z-order is top most. Because of that the cropping capturer detects occlusion everywhere preventing it from capturing anything. The solution is to ignore all cloaked windows like if ::IsWindowVisible would return false. Bug: chromium:978885 Change-Id: Id5aa8dc81dcf4979ffb30dd808fa2a553934c6e6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/143980 Commit-Queue: Julien Isorce <julien.isorce@chromium.org> Reviewed-by: Sergey Ulanov <sergeyu@chromium.org> Reviewed-by: Guido Urdaneta <guidou@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28510}
This commit is contained in:

committed by
Commit Bot

parent
a0eefc17f7
commit
5e25facefd
@ -10,6 +10,9 @@
|
||||
|
||||
#include "modules/desktop_capture/win/window_capture_utils.h"
|
||||
|
||||
// Just for the DWMWINDOWATTRIBUTE enums (DWMWA_CLOAKED).
|
||||
#include <dwmapi.h>
|
||||
|
||||
#include "modules/desktop_capture/win/scoped_gdi_object.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
@ -137,15 +140,15 @@ bool IsWindowMaximized(HWND window, bool* result) {
|
||||
}
|
||||
|
||||
// WindowCaptureHelperWin implementation.
|
||||
WindowCaptureHelperWin::WindowCaptureHelperWin()
|
||||
: dwmapi_library_(nullptr),
|
||||
func_(nullptr),
|
||||
virtual_desktop_manager_(nullptr) {
|
||||
WindowCaptureHelperWin::WindowCaptureHelperWin() {
|
||||
// Try to load dwmapi.dll dynamically since it is not available on XP.
|
||||
dwmapi_library_ = LoadLibraryW(L"dwmapi.dll");
|
||||
if (dwmapi_library_) {
|
||||
func_ = reinterpret_cast<DwmIsCompositionEnabledFunc>(
|
||||
GetProcAddress(dwmapi_library_, "DwmIsCompositionEnabled"));
|
||||
dwm_get_window_attribute_func_ =
|
||||
reinterpret_cast<DwmGetWindowAttributeFunc>(
|
||||
GetProcAddress(dwmapi_library_, "DwmGetWindowAttribute"));
|
||||
}
|
||||
|
||||
if (rtc::IsWindows10OrLater()) {
|
||||
@ -268,7 +271,25 @@ bool WindowCaptureHelperWin::IsWindowOnCurrentDesktop(HWND hwnd) {
|
||||
|
||||
bool WindowCaptureHelperWin::IsWindowVisibleOnCurrentDesktop(HWND hwnd) {
|
||||
return !::IsIconic(hwnd) && ::IsWindowVisible(hwnd) &&
|
||||
IsWindowOnCurrentDesktop(hwnd);
|
||||
IsWindowOnCurrentDesktop(hwnd) && !IsWindowCloaked(hwnd);
|
||||
}
|
||||
|
||||
// A cloaked window is composited but not visible to the user.
|
||||
// Example: Cortana or the Action Center when collapsed.
|
||||
bool WindowCaptureHelperWin::IsWindowCloaked(HWND hwnd) {
|
||||
if (!dwm_get_window_attribute_func_) {
|
||||
// Does not apply.
|
||||
return false;
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
if (dwm_get_window_attribute_func_(hwnd, DWMWA_CLOAKED, &res, sizeof(res)) !=
|
||||
S_OK) {
|
||||
// Cannot tell so assume not cloacked for backward compatibility.
|
||||
return false;
|
||||
}
|
||||
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -60,6 +60,10 @@ bool GetDcSize(HDC hdc, DesktopSize* size);
|
||||
bool IsWindowMaximized(HWND window, bool* result);
|
||||
|
||||
typedef HRESULT(WINAPI* DwmIsCompositionEnabledFunc)(BOOL* enabled);
|
||||
typedef HRESULT(WINAPI* DwmGetWindowAttributeFunc)(HWND hwnd,
|
||||
DWORD dwAttribute,
|
||||
PVOID pvAttribute,
|
||||
DWORD cbAttribute);
|
||||
class WindowCaptureHelperWin {
|
||||
public:
|
||||
WindowCaptureHelperWin();
|
||||
@ -73,13 +77,16 @@ class WindowCaptureHelperWin {
|
||||
const DesktopRect& selected_window_rect);
|
||||
bool IsWindowOnCurrentDesktop(HWND hwnd);
|
||||
bool IsWindowVisibleOnCurrentDesktop(HWND hwnd);
|
||||
bool IsWindowCloaked(HWND hwnd);
|
||||
|
||||
private:
|
||||
HMODULE dwmapi_library_;
|
||||
DwmIsCompositionEnabledFunc func_;
|
||||
HMODULE dwmapi_library_ = nullptr;
|
||||
DwmIsCompositionEnabledFunc func_ = nullptr;
|
||||
DwmGetWindowAttributeFunc dwm_get_window_attribute_func_ = nullptr;
|
||||
|
||||
// Only used on Win10+.
|
||||
Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_;
|
||||
Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_ =
|
||||
nullptr;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(WindowCaptureHelperWin);
|
||||
};
|
||||
|
Reference in New Issue
Block a user