mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix(patch-conflict): merge PipScreenCaptureCoordinatorProxy with non-shareable window filtering
Upstream added PipScreenCaptureCoordinatorProxy to ScreenCaptureKitDeviceMac for Picture-in-Picture window exclusion. Merged this with our existing non-shareable window filtering logic, combining both excluded window lists and preserving both features. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7153177
This commit is contained in:
@@ -46,10 +46,10 @@ index e2771b7b281274cdcb601a5bc78a948ad592087b..48d116823a28213e50775f378e6ce04c
|
||||
// OnStop is called by StopAndDeAllocate.
|
||||
virtual void OnStop() = 0;
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aabccbdd31 100644
|
||||
index d26b570eeebbd85cf713cb8dac1463a941170b56..b344fc2c818803712f553409f5aadefb13f40ed0 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -27,6 +27,61 @@
|
||||
@@ -28,6 +28,61 @@
|
||||
std::optional<float>,
|
||||
bool)>;
|
||||
using ErrorCallback = base::RepeatingClosure;
|
||||
@@ -111,7 +111,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
|
||||
namespace {
|
||||
API_AVAILABLE(macos(12.3))
|
||||
@@ -123,18 +178,22 @@ @interface ScreenCaptureKitDeviceHelper
|
||||
@@ -148,18 +203,22 @@ @interface ScreenCaptureKitDeviceHelper
|
||||
: NSObject <SCStreamDelegate, SCStreamOutput>
|
||||
|
||||
- (instancetype)initWithSampleCallback:(SampleCallback)sampleCallback
|
||||
@@ -134,18 +134,21 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
_errorCallback = errorCallback;
|
||||
}
|
||||
return self;
|
||||
@@ -224,28 +283,50 @@ class API_AVAILABLE(macos(12.3)) ScreenCaptureKitDeviceMac
|
||||
base::OnceCallback<void(content::DesktopMediaID::Id, SCStream*)>;
|
||||
@@ -251,12 +310,11 @@ class API_AVAILABLE(macos(12.3)) ScreenCaptureKitDeviceMac
|
||||
|
||||
explicit ScreenCaptureKitDeviceMac(const DesktopMediaID& source,
|
||||
- SCContentFilter* filter,
|
||||
+ [[maybe_unused]] SCContentFilter* filter,
|
||||
StreamCallback stream_created_callback)
|
||||
explicit ScreenCaptureKitDeviceMac(
|
||||
const DesktopMediaID& source,
|
||||
- SCContentFilter* filter,
|
||||
+ [[maybe_unused]] SCContentFilter* filter,
|
||||
StreamCallback stream_created_callback,
|
||||
std::unique_ptr<content::PipScreenCaptureCoordinatorProxy>
|
||||
pip_screen_capture_coordinator_proxy)
|
||||
: source_(source),
|
||||
- filter_(filter),
|
||||
stream_created_callback_(std::move(stream_created_callback)),
|
||||
device_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) {
|
||||
SampleCallback sample_callback = base::BindPostTask(
|
||||
device_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
|
||||
pip_screen_capture_coordinator_proxy_(
|
||||
@@ -265,16 +323,29 @@ explicit ScreenCaptureKitDeviceMac(
|
||||
device_task_runner_,
|
||||
base::BindRepeating(&ScreenCaptureKitDeviceMac::OnStreamSample,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
@@ -161,6 +164,9 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
initWithSampleCallback:sample_callback
|
||||
+ cancelCallback:cancel_callback
|
||||
errorCallback:error_callback];
|
||||
if (pip_screen_capture_coordinator_proxy_) {
|
||||
pip_screen_capture_coordinator_proxy_->AddObserver(this);
|
||||
}
|
||||
+ if (@available(macOS 15.0, *)) {
|
||||
+ auto picker_callback = base::BindPostTask(
|
||||
+ device_task_runner_,
|
||||
@@ -172,9 +178,10 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
}
|
||||
ScreenCaptureKitDeviceMac(const ScreenCaptureKitDeviceMac&) = delete;
|
||||
ScreenCaptureKitDeviceMac& operator=(const ScreenCaptureKitDeviceMac&) =
|
||||
delete;
|
||||
- ~ScreenCaptureKitDeviceMac() override = default;
|
||||
+ ~ScreenCaptureKitDeviceMac() override {
|
||||
@@ -284,6 +355,15 @@ explicit ScreenCaptureKitDeviceMac(
|
||||
if (pip_screen_capture_coordinator_proxy_) {
|
||||
pip_screen_capture_coordinator_proxy_->RemoveObserver(this);
|
||||
}
|
||||
+ if (@available(macOS 15.0, *)) {
|
||||
+ auto* picker = [SCContentSharingPicker sharedPicker];
|
||||
+ ScreenCaptureKitDeviceMac::active_streams_--;
|
||||
@@ -184,11 +191,10 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
+ [[SCContentSharingPicker sharedPicker] removeObserver:picker_helper_];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
void OnShareableContentCreated(SCShareableContent* content) {
|
||||
DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
@@ -313,7 +394,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
@@ -355,7 +435,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -197,7 +203,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
// Update the content size. This step is neccessary when used together
|
||||
// with SCContentSharingPicker. If the Chrome picker is used, it will
|
||||
// change to retina resolution if applicable.
|
||||
@@ -322,6 +403,9 @@ void CreateStream(SCContentFilter* filter) {
|
||||
@@ -364,6 +444,9 @@ void CreateStream(SCContentFilter* filter) {
|
||||
filter.contentRect.size.height * filter.pointPixelScale);
|
||||
}
|
||||
|
||||
@@ -207,7 +213,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
gfx::RectF dest_rect_in_frame;
|
||||
actual_capture_format_ = capture_params().requested_format;
|
||||
actual_capture_format_.pixel_format = media::PIXEL_FORMAT_NV12;
|
||||
@@ -335,6 +419,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
@@ -377,6 +460,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
stream_ = [[SCStream alloc] initWithFilter:filter
|
||||
configuration:config
|
||||
delegate:helper_];
|
||||
@@ -215,7 +221,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
{
|
||||
NSError* error = nil;
|
||||
bool add_stream_output_result =
|
||||
@@ -495,7 +580,7 @@ void OnStreamError() {
|
||||
@@ -536,7 +620,7 @@ void OnStreamError() {
|
||||
if (fullscreen_module_) {
|
||||
fullscreen_module_->Reset();
|
||||
}
|
||||
@@ -224,7 +230,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
} else {
|
||||
client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
|
||||
FROM_HERE, "Stream delegate called didStopWithError");
|
||||
@@ -518,23 +603,41 @@ void OnUpdateConfigurationError() {
|
||||
@@ -619,23 +703,41 @@ void OnPipWindowIdChanged(
|
||||
}
|
||||
|
||||
// IOSurfaceCaptureDeviceBase:
|
||||
@@ -281,7 +287,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
}
|
||||
void OnStop() override {
|
||||
DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
@@ -593,7 +696,7 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
@@ -694,7 +796,7 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
|
||||
private:
|
||||
const DesktopMediaID source_;
|
||||
@@ -290,7 +296,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
StreamCallback stream_created_callback_;
|
||||
const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
|
||||
|
||||
@@ -610,6 +713,10 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
@@ -711,6 +813,10 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
// Helper class that acts as output and delegate for `stream_`.
|
||||
ScreenCaptureKitDeviceHelper* __strong helper_;
|
||||
|
||||
@@ -301,7 +307,7 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
// This is used to detect when a captured presentation enters fullscreen mode.
|
||||
// If this happens, the module will call the ResetStreamTo function.
|
||||
std::unique_ptr<ScreenCaptureKitFullscreenModule> fullscreen_module_;
|
||||
@@ -622,6 +729,8 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
@@ -725,6 +831,8 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
base::WeakPtrFactory<ScreenCaptureKitDeviceMac> weak_factory_{this};
|
||||
};
|
||||
|
||||
@@ -311,10 +317,10 @@ index c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1..5506583824e10d664f32c71d63fda1aa
|
||||
|
||||
// Although ScreenCaptureKit is available in 12.3 there were some bugs that
|
||||
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
index 2f871f0ef51e49d1f78e56b125bbf721dd3562e2..02da1596d4f1251f8e8a8bcba0b9372feb066647 100644
|
||||
index 9887b022744234f11322806982962390d79031ac..631022789ffb51b45b120520977bea7239f28636 100644
|
||||
--- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
+++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
@@ -316,8 +316,16 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
@@ -321,8 +321,16 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -332,7 +338,7 @@ index 2f871f0ef51e49d1f78e56b125bbf721dd3562e2..02da1596d4f1251f8e8a8bcba0b9372f
|
||||
// For the other capturers, when a bug reports the type of capture it's
|
||||
// easy enough to determine which capturer was used, but it's a little
|
||||
// fuzzier with window capture.
|
||||
@@ -333,13 +341,15 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
@@ -338,13 +346,15 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
}
|
||||
#endif // defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
|
||||
|
||||
@@ -7,25 +7,26 @@ Subject: feat: filter out non-shareable windows in the current application in
|
||||
This patch ensures that windows protected via win.setContentProtection(true) do not appear in full display captures via desktopCapturer. This patch could be upstreamed but as the check is limited to in-process windows it doesn't make a lot of sense for Chromium itself. This patch currently has a limitation that it only function for windows created / protected BEFORE the stream is started. There is theoretical future work we can do via polling / observers to automatically update the SCContentFilter when new windows are made but for now this will solve 99+% of the problem and folks can re-order their logic a bit to get it working for their use cases.
|
||||
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
index 404085d1ccf3ea7f4d11941efa64dc1a193552e0..c2d8bbafa39c05f25641f2fd3491ef7f84f4f6a1 100644
|
||||
index 35c4bdb8041cba27c4cb16229705eed8f6746c71..d26b570eeebbd85cf713cb8dac1463a941170b56 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -266,8 +266,17 @@ void OnShareableContentCreated(SCShareableContent* content) {
|
||||
// fallback. See https://crbug.com/325530044.
|
||||
if (source_.id == display.displayID ||
|
||||
@@ -307,8 +307,18 @@ void OnShareableContentCreated(SCShareableContent* content) {
|
||||
source_.id == webrtc::kFullDesktopScreenId) {
|
||||
NSArray<SCWindow*>* excluded_windows = GetExcludedWindows(
|
||||
content, pip_screen_capture_coordinator_proxy_.get());
|
||||
+ NSArray<NSWindow*>* exclude_ns_windows = [[[NSApplication sharedApplication] windows] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSWindow* win, NSDictionary *bindings) {
|
||||
+ return [win sharingType] == NSWindowSharingNone;
|
||||
+ }]];
|
||||
+ NSArray<SCWindow*>* exclude_windows = [[content windows] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SCWindow* win, NSDictionary *bindings) {
|
||||
+ NSArray<SCWindow*>* non_shareable_windows = [[content windows] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SCWindow* win, NSDictionary *bindings) {
|
||||
+ for (NSWindow* excluded : exclude_ns_windows) {
|
||||
+ if ((CGWindowID)[excluded windowNumber] == [win windowID]) return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }]];
|
||||
+ NSArray<SCWindow*>* all_excluded_windows = [excluded_windows arrayByAddingObjectsFromArray:non_shareable_windows];
|
||||
filter = [[SCContentFilter alloc] initWithDisplay:display
|
||||
- excludingWindows:@[]];
|
||||
+ excludingWindows:exclude_windows];
|
||||
- excludingWindows:excluded_windows];
|
||||
+ excludingWindows:all_excluded_windows];
|
||||
stream_config_content_size_ =
|
||||
gfx::Size(display.width, display.height);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user