Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qsckcapturablewindows.mm
Go to the documentation of this file.
1
// Copyright (C) 2026 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qsckcapturablewindows_p.h"
5
6
#
include
<
QtCore
/
private
/
qcore_mac_p
.
h
>
7
#
include
<
QtCore
/
private
/
qexpected_p
.
h
>
8
#
include
<
QtCore
/
qlist
.
h
>
9
10
#
include
<
QtFFmpegMediaPluginImpl
/
private
/
qmacscreencapturekit_p
.
h
>
11
12
#
include
<
QtGui
/
qwindow
.
h
>
13
14
#
include
<
QtMultimedia
/
private
/
qcapturablewindow_p
.
h
>
15
16
#
import
<
AppKit
/
NSWindow
.
h
>
17
18
#
include
<
algorithm
>
19
#
include
<
vector
>
20
21
using
namespace
Qt::Literals::StringLiterals;
22
23
QT_BEGIN_NAMESPACE
24
25
namespace
QFFmpeg
{
26
27
// ScreenCaptureKit reports several windows that cannot be captured, or
28
// are otherwise just black. Such windows include invidividual icons on
29
// the taskbar. Filtering out some of these based on bundle identifier
30
// tends to clean up the list.
31
constexpr
std
::array
windowBundleIdentifierBlacklist
= {
32
"com.apple.controlcenter"
,
33
"com.apple.dock"
,
34
"com.apple.notificationcenterui"
, };
35
36
// Can be called from any thread.
37
QList
<
QCapturableWindow
>
QSckCapturableWindows
::
windows
()
const
38
{
39
QMacAutoReleasePool autoReleasePool;
40
41
// Do a blocking query for ScreenCaptureKit capturable items.
42
q23::expected<QMacScreenCaptureKit::CapturableItems, QString> enumerateResult =
43
QMacScreenCaptureKit::enumerateCapturableItems()
44
.get();
45
if
(!enumerateResult) {
46
qCWarning(qLcMacScreenCapture)
47
<<
"Failed to enumerate capturable windows/displays: "
48
<< enumerateResult.error();
49
return
{};
50
}
51
52
QMacScreenCaptureKit::CapturableItems
const
&capturableItems = *enumerateResult;
53
54
QList<QCapturableWindow> result;
55
56
for
(AVFScopedPointer<SCWindow>
const
&window : capturableItems.windows) {
57
// SCWindows with onScreen set to false usually indicates we cannot
58
// capture it at this time, but it might be capturable in the future.
59
if
(!window.data().onScreen)
60
continue
;
61
62
QString bundleIdentifier = QString::fromNSString(window.data().owningApplication.bundleIdentifier);
63
// An empty bundle-identifier commonly implies this window cannot be captured.
64
if
(bundleIdentifier.isEmpty())
65
continue
;
66
67
bool
bundleIdentifierBlacklisted = std::any_of(
68
windowBundleIdentifierBlacklist.begin(),
69
windowBundleIdentifierBlacklist.end(),
70
[&](
const
char
*identifier) {
71
return
QString::fromLatin1(identifier, -1) == bundleIdentifier;
72
});
73
if
(bundleIdentifierBlacklisted)
74
continue
;
75
76
// No title commonly implies this is not a user-facing window.
77
QString title = QString::fromNSString(window.data().title);
78
if
(title.isEmpty())
79
continue
;
80
81
result.push_back(QCapturableWindowPrivate::create(
82
static_cast
<QCapturableWindowPrivate::Id>(window.data().windowID),
83
std::move(title)));
84
}
85
86
return
result;
87
}
88
89
// Can be called from any thread.
90
bool
QSckCapturableWindows
::
isWindowValid
(
const
QCapturableWindowPrivate &window)
const
91
{
92
QMacAutoReleasePool autoReleasePool;
93
94
if
(window.id == 0)
95
return
false
;
96
97
// Do a blocking query for ScreenCaptureKit capturable items.
98
q23::expected<QMacScreenCaptureKit::CapturableItems, QString> enumerateResult =
99
QMacScreenCaptureKit::enumerateCapturableItems()
100
.get();
101
if
(!enumerateResult) {
102
qCWarning(qLcMacScreenCapture)
103
<<
"Failed to enumerate capturable windows/displays during QSckCapturableWindows::isWindowValid: "
104
<< enumerateResult.error();
105
return
false
;
106
}
107
108
std::vector<AVFScopedPointer<SCWindow>>
const
&windows = enumerateResult->windows;
109
110
return
std
::any_of(
111
windows.begin(),
112
windows.end(),
113
[&](AVFScopedPointer<SCWindow>
const
&item) {
114
return
item.data().windowID ==
static_cast
<CGWindowID>(window.id);
115
});
116
}
117
118
// Can be called from any thread.
119
q23
::
expected
<
QCapturableWindow
,
QString
>
QSckCapturableWindows
::
fromQWindow
(QWindow *window)
const
120
{
121
QMacAutoReleasePool autoReleasePool;
122
123
auto
*nsView =
reinterpret_cast
<NSView*>(window->winId());
124
125
NSWindow *nsWindow = [nsView window];
126
if
(nsWindow ==
nullptr
)
127
return
q23::unexpected{ QStringLiteral(
"NSView had no associated NSWindow"
) };
128
129
auto
cgWindowId = (CGWindowID)[nsWindow windowNumber];
130
if
(cgWindowId == kCGNullWindowID)
131
return
q23::unexpected{ QStringLiteral(
"NSWindow has no CGWindowID"
) };
132
133
return
QCapturableWindowPrivate::create(
134
static_cast
<QCapturableWindowPrivate::Id>(cgWindowId),
135
window->title());
136
}
137
138
std
::
unique_ptr
<
QPlatformCapturableWindows
>
makeQSckCapturableWindows
()
139
{
140
return
std::make_unique<QSckCapturableWindows>();
141
}
142
143
}
// namespace QFFmpeg
144
145
QT_END_NAMESPACE
QFFmpeg::QSckCapturableWindows
Definition
qsckcapturablewindows_p.h:25
QFFmpeg::QSckCapturableWindows::fromQWindow
q23::expected< QCapturableWindow, QString > fromQWindow(QWindow *) const override
Definition
qsckcapturablewindows.mm:119
QFFmpeg::QSckCapturableWindows::isWindowValid
bool isWindowValid(const QCapturableWindowPrivate &window) const override
Definition
qsckcapturablewindows.mm:90
QFFmpeg::QSckCapturableWindows::windows
QList< QCapturableWindow > windows() const override
Definition
qsckcapturablewindows.mm:37
QFFmpeg
Definition
qandroidcacertificates.cpp:26
QFFmpeg::windowBundleIdentifierBlacklist
constexpr std::array windowBundleIdentifierBlacklist
Definition
qsckcapturablewindows.mm:31
QFFmpeg::makeQSckCapturableWindows
std::unique_ptr< QPlatformCapturableWindows > makeQSckCapturableWindows()
Definition
qsckcapturablewindows.mm:138
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtmultimedia
src
plugins
multimedia
ffmpeg
darwin
qsckcapturablewindows.mm
Generated on
for Qt by
1.18.0