Skip to content

Commit 76064b6

Browse files
authored
Exclude window ID from screen sharing (#755)
Resolves #567 - Inverts the logic for including apps - Does not use the deprecated prop here https://developer.apple.com/documentation/appkit/nswindow/sharingtype-swift.enum/none, plain ID instead <img width="991" height="627" alt="Screenshot 2025-08-12 at 1 15 06 PM" src="https://github.com/user-attachments/assets/e5fc6813-2f88-49c8-a623-cf4cfbc7c87e" />
1 parent f73fa6e commit 76064b6

3 files changed

Lines changed: 17 additions & 6 deletions

File tree

.changes/screenshare-exclude

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
patch type="added" "Added the possibility to exlude macOS windows from screen sharing"

Sources/LiveKit/Track/Capturers/MacOSScreenCapturer.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@ public class MacOSScreenCapturer: VideoCapturer, @unchecked Sendable {
7171
let content = displaySource.scContent as? SCShareableContent,
7272
let nativeDisplay = displaySource.nativeType as? SCDisplay
7373
{
74-
let excludedApps = !options.includeCurrentApplication ? content.applications.filter { app in
75-
Bundle.main.bundleIdentifier == app.bundleIdentifier
76-
} : []
74+
let includedApps = options.includeCurrentApplication ?
75+
content.applications :
76+
content.applications.filter { app in Bundle.main.bundleIdentifier != app.bundleIdentifier }
7777

78-
filter = SCContentFilter(display: nativeDisplay, excludingApplications: excludedApps, exceptingWindows: [])
78+
let excludedWindows = content.windows.filter { window in options.excludeWindowIDs.contains(window.windowID) }
79+
80+
filter = SCContentFilter(display: nativeDisplay, including: includedApps, exceptingWindows: excludedWindows)
7981
} else {
8082
log("Unable to resolve SCContentFilter", .error)
8183
throw LiveKitError(.invalidState, message: "Unable to resolve SCContentFilter")

Sources/LiveKit/Types/Options/ScreenShareCaptureOptions.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ public final class ScreenShareCaptureOptions: NSObject, VideoCaptureOptions, Sen
4141
@objc
4242
public let includeCurrentApplication: Bool
4343

44+
/// Exclude windows by their window ID (macOS only).
45+
@objc
46+
public let excludeWindowIDs: [UInt32]
47+
4448
public static let defaultToBroadcastExtension: Bool = {
4549
#if os(iOS)
4650
return BroadcastBundleInfo.hasExtension
@@ -54,14 +58,16 @@ public final class ScreenShareCaptureOptions: NSObject, VideoCaptureOptions, Sen
5458
showCursor: Bool = true,
5559
appAudio: Bool = false,
5660
useBroadcastExtension: Bool = defaultToBroadcastExtension,
57-
includeCurrentApplication: Bool = false)
61+
includeCurrentApplication: Bool = false,
62+
excludeWindowIDs: [UInt32] = [])
5863
{
5964
self.dimensions = dimensions
6065
self.fps = fps
6166
self.showCursor = showCursor
6267
self.appAudio = appAudio
6368
self.useBroadcastExtension = useBroadcastExtension
6469
self.includeCurrentApplication = includeCurrentApplication
70+
self.excludeWindowIDs = excludeWindowIDs
6571
}
6672

6773
// MARK: - Equal
@@ -73,7 +79,8 @@ public final class ScreenShareCaptureOptions: NSObject, VideoCaptureOptions, Sen
7379
showCursor == other.showCursor &&
7480
appAudio == other.appAudio &&
7581
useBroadcastExtension == other.useBroadcastExtension &&
76-
includeCurrentApplication == other.includeCurrentApplication
82+
includeCurrentApplication == other.includeCurrentApplication &&
83+
excludeWindowIDs == other.excludeWindowIDs
7784
}
7885

7986
override public var hash: Int {
@@ -84,6 +91,7 @@ public final class ScreenShareCaptureOptions: NSObject, VideoCaptureOptions, Sen
8491
hasher.combine(appAudio)
8592
hasher.combine(useBroadcastExtension)
8693
hasher.combine(includeCurrentApplication)
94+
hasher.combine(excludeWindowIDs)
8795
return hasher.finalize()
8896
}
8997
}

0 commit comments

Comments
 (0)