Implement FocusOnSelectedSource for WgcCapturerWin.
Previously, windows captured by WgcCapturerWin may have been occluded by other windows with no functionality to bring them to the top of the z order. This change implements FocusOnSelectedSource for WgcCapturerWin to afford consumers this functionality, and match the experience offered by current capturers. Bug: webrtc:12664 Change-Id: I8bc067ade90fba0be66a9be57d3429ba54ba1ae0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215241 Reviewed-by: Jamie Walch <jamiewalch@chromium.org> Commit-Queue: Austin Orion <auorion@microsoft.com> Cr-Commit-Position: refs/heads/master@{#33809}
This commit is contained in:
parent
88f4b33196
commit
0fd0d5867b
@ -147,7 +147,10 @@ if (rtc_include_tests) {
|
||||
if (rtc_enable_win_wgc) {
|
||||
sources += [ "win/wgc_capturer_win_unittest.cc" ]
|
||||
}
|
||||
deps += [ ":desktop_capture_mock" ]
|
||||
deps += [
|
||||
":desktop_capture_mock",
|
||||
"../../system_wrappers:metrics",
|
||||
]
|
||||
public_configs = [ ":x11_config" ]
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
#include "modules/desktop_capture/win/wgc_capture_source.h"
|
||||
|
||||
#include <windows.graphics.capture.interop.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "modules/desktop_capture/win/screen_capture_utils.h"
|
||||
@ -26,6 +28,18 @@ WgcCaptureSource::WgcCaptureSource(DesktopCapturer::SourceId source_id)
|
||||
: source_id_(source_id) {}
|
||||
WgcCaptureSource::~WgcCaptureSource() = default;
|
||||
|
||||
bool WgcCaptureSource::IsCapturable() {
|
||||
// If we can create a capture item, then we can capture it. Unfortunately,
|
||||
// we can't cache this item because it may be created in a different COM
|
||||
// apartment than where capture will eventually start from.
|
||||
ComPtr<WGC::IGraphicsCaptureItem> item;
|
||||
return SUCCEEDED(CreateCaptureItem(&item));
|
||||
}
|
||||
|
||||
bool WgcCaptureSource::FocusOnSource() {
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT WgcCaptureSource::GetCaptureItem(
|
||||
ComPtr<WGC::IGraphicsCaptureItem>* result) {
|
||||
HRESULT hr = S_OK;
|
||||
@ -36,14 +50,6 @@ HRESULT WgcCaptureSource::GetCaptureItem(
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool WgcCaptureSource::IsCapturable() {
|
||||
// If we can create a capture item, then we can capture it. Unfortunately,
|
||||
// we can't cache this item because it may be created in a different COM
|
||||
// apartment than where capture will eventually start from.
|
||||
ComPtr<WGC::IGraphicsCaptureItem> item;
|
||||
return SUCCEEDED(CreateCaptureItem(&item));
|
||||
}
|
||||
|
||||
WgcCaptureSourceFactory::~WgcCaptureSourceFactory() = default;
|
||||
|
||||
WgcWindowSourceFactory::WgcWindowSourceFactory() = default;
|
||||
@ -73,6 +79,14 @@ bool WgcWindowSource::IsCapturable() {
|
||||
return WgcCaptureSource::IsCapturable();
|
||||
}
|
||||
|
||||
bool WgcWindowSource::FocusOnSource() {
|
||||
if (!IsWindowValidAndVisible(reinterpret_cast<HWND>(GetSourceId())))
|
||||
return false;
|
||||
|
||||
return ::BringWindowToTop(reinterpret_cast<HWND>(GetSourceId())) &&
|
||||
::SetForegroundWindow(reinterpret_cast<HWND>(GetSourceId()));
|
||||
}
|
||||
|
||||
HRESULT WgcWindowSource::CreateCaptureItem(
|
||||
ComPtr<WGC::IGraphicsCaptureItem>* result) {
|
||||
if (!ResolveCoreWinRTDelayload())
|
||||
|
||||
@ -31,6 +31,7 @@ class WgcCaptureSource {
|
||||
virtual ~WgcCaptureSource();
|
||||
|
||||
virtual bool IsCapturable();
|
||||
virtual bool FocusOnSource();
|
||||
HRESULT GetCaptureItem(
|
||||
Microsoft::WRL::ComPtr<
|
||||
ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>* result);
|
||||
@ -93,6 +94,7 @@ class WgcWindowSource final : public WgcCaptureSource {
|
||||
~WgcWindowSource() override;
|
||||
|
||||
bool IsCapturable() override;
|
||||
bool FocusOnSource() override;
|
||||
|
||||
private:
|
||||
HRESULT CreateCaptureItem(
|
||||
|
||||
@ -77,6 +77,13 @@ bool WgcCapturerWin::SelectSource(DesktopCapturer::SourceId id) {
|
||||
return capture_source_->IsCapturable();
|
||||
}
|
||||
|
||||
bool WgcCapturerWin::FocusOnSelectedSource() {
|
||||
if (!capture_source_)
|
||||
return false;
|
||||
|
||||
return capture_source_->FocusOnSource();
|
||||
}
|
||||
|
||||
void WgcCapturerWin::Start(Callback* callback) {
|
||||
RTC_DCHECK(!callback_);
|
||||
RTC_DCHECK(callback);
|
||||
|
||||
@ -94,6 +94,7 @@ class WgcCapturerWin : public DesktopCapturer {
|
||||
// DesktopCapturer interface.
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
bool FocusOnSelectedSource() override;
|
||||
void Start(Callback* callback) override;
|
||||
void CaptureFrame() override;
|
||||
|
||||
|
||||
@ -335,10 +335,17 @@ INSTANTIATE_TEST_SUITE_P(SourceAgnostic,
|
||||
CaptureType::kScreenCapture));
|
||||
|
||||
// Monitor specific tests.
|
||||
TEST_F(WgcCapturerWinTest, FocusOnMonitor) {
|
||||
SetUpForScreenCapture();
|
||||
EXPECT_TRUE(capturer_->SelectSource(0));
|
||||
|
||||
// You can't set focus on a monitor.
|
||||
EXPECT_FALSE(capturer_->FocusOnSelectedSource());
|
||||
}
|
||||
|
||||
TEST_F(WgcCapturerWinTest, CaptureAllMonitors) {
|
||||
SetUpForScreenCapture();
|
||||
// 0 (or a NULL HMONITOR) leads to WGC capturing all displays.
|
||||
EXPECT_TRUE(capturer_->SelectSource(0));
|
||||
EXPECT_TRUE(capturer_->SelectSource(kFullDesktopScreenId));
|
||||
|
||||
capturer_->Start(this);
|
||||
DoCapture();
|
||||
@ -347,6 +354,22 @@ TEST_F(WgcCapturerWinTest, CaptureAllMonitors) {
|
||||
}
|
||||
|
||||
// Window specific tests.
|
||||
TEST_F(WgcCapturerWinTest, FocusOnWindow) {
|
||||
capturer_ = WgcCapturerWin::CreateRawWindowCapturer(
|
||||
DesktopCaptureOptions::CreateDefault());
|
||||
window_info_ = CreateTestWindow(kWindowTitle);
|
||||
source_id_ = GetScreenIdFromSourceList();
|
||||
|
||||
EXPECT_TRUE(capturer_->SelectSource(source_id_));
|
||||
EXPECT_TRUE(capturer_->FocusOnSelectedSource());
|
||||
|
||||
HWND hwnd = reinterpret_cast<HWND>(source_id_);
|
||||
EXPECT_EQ(hwnd, ::GetActiveWindow());
|
||||
EXPECT_EQ(hwnd, ::GetForegroundWindow());
|
||||
EXPECT_EQ(hwnd, ::GetFocus());
|
||||
DestroyTestWindow(window_info_);
|
||||
}
|
||||
|
||||
TEST_F(WgcCapturerWinTest, SelectMinimizedWindow) {
|
||||
SetUpForWindowCapture();
|
||||
MinimizeTestWindow(reinterpret_cast<HWND>(source_id_));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user