Skip to content

Commit 999fffd

Browse files
committed
fix(capture): build the macOS helper again, and own the cover's promise in its thread
PickerSession's static desktopIconWindowIDs shadowed the OpenScreenCaptureCore function it called, so the helper did not compile. The Windows cover captured a local std::promise by reference that show() could destroy while set_value was still running.
1 parent d875416 commit 999fffd

2 files changed

Lines changed: 10 additions & 6 deletions

File tree

‎electron/native/screencapturekit/Sources/OpenScreenScreenCaptureKitHelper/PickerSession.swift‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ final class PickerSession: NSObject, SCContentSharingPickerObserver, @unchecked
9696
// the HUD and the notes window belong to Electron. Measured: a window owned by the
9797
// parent app shows in the capture unless it is listed here.
9898
configuration.excludedWindowIDs =
99-
excludedWindowIDs + Self.desktopIconWindowIDs(hideDesktopIcons: hideDesktopIcons)
99+
excludedWindowIDs + Self.finderDesktopIconWindowIDs(hideDesktopIcons: hideDesktopIcons)
100100
// By app, not by window: a banner is a window created after the pick, so no id
101101
// list taken now could name it.
102102
configuration.excludedBundleIDs = [notificationCenterBundleID]
@@ -174,7 +174,9 @@ final class PickerSession: NSObject, SCContentSharingPickerObserver, @unchecked
174174
/// need the Screen Recording grant the picker exists to avoid. Owner and level are
175175
/// readable without it. The icons stay put for the whole session, so ids taken at pick
176176
/// time hold -- unless Finder relaunches, which gives them new ones.
177-
private static func desktopIconWindowIDs(hideDesktopIcons: Bool) -> [Int] {
177+
/// Not named `desktopIconWindowIDs`: inside this class that name would shadow the
178+
/// OpenScreenCaptureCore function it calls.
179+
private static func finderDesktopIconWindowIDs(hideDesktopIcons: Bool) -> [Int] {
178180
guard hideDesktopIcons,
179181
let entries = CGWindowListCopyWindowInfo([.optionOnScreenOnly], kCGNullWindowID)
180182
as? [[String: Any]]
@@ -193,7 +195,7 @@ final class PickerSession: NSObject, SCContentSharingPickerObserver, @unchecked
193195
layer: entry[kCGWindowLayer as String] as? Int ?? 0
194196
)
195197
}
196-
return desktopIconWindowIDs(candidates).map { Int($0) }
198+
return OpenScreenCaptureCore.desktopIconWindowIDs(candidates).map { Int($0) }
197199
}
198200

199201
private static func display(containing frame: CGRect) -> CGDirectDisplayID? {

‎electron/native/wgc-capture/src/desktop_icon_cover.cpp‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ bool DesktopIconCover::show(HMONITOR monitor) {
6262
return false;
6363
}
6464

65-
std::promise<bool> placed;
66-
std::future<bool> placedResult = placed.get_future();
67-
thread_ = std::thread([this, rect = info.rcMonitor, &placed]() {
65+
// Moved into the thread, not captured by reference: `get()` can return before
66+
// `set_value` has finished with the promise, and this frame is gone by then.
67+
std::promise<bool> promise;
68+
std::future<bool> placedResult = promise.get_future();
69+
thread_ = std::thread([this, rect = info.rcMonitor, placed = std::move(promise)]() mutable {
6870
threadId_ = GetCurrentThreadId();
6971
HINSTANCE instance = GetModuleHandleW(nullptr);
7072
WNDCLASSEXW windowClass{sizeof(windowClass)};

0 commit comments

Comments
 (0)