Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtCore module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #ifndef QCORE_MAC_P_H |
41 | #define QCORE_MAC_P_H |
42 | |
43 | // |
44 | // W A R N I N G |
45 | // ------------- |
46 | // |
47 | // This file is not part of the Qt API. It exists for the convenience |
48 | // of other Qt classes. This header file may change from version to |
49 | // version without notice, or even be removed. |
50 | // |
51 | // We mean it. |
52 | // |
53 | |
54 | #include "private/qglobal_p.h" |
55 | |
56 | #ifndef __IMAGECAPTURE__ |
57 | # define __IMAGECAPTURE__ |
58 | #endif |
59 | |
60 | // -------------------------------------------------------------------------- |
61 | |
62 | #if defined(QT_BOOTSTRAPPED) |
63 | #include <ApplicationServices/ApplicationServices.h> |
64 | #else |
65 | #include <CoreFoundation/CoreFoundation.h> |
66 | #endif |
67 | |
68 | #ifdef __OBJC__ |
69 | #include <Foundation/Foundation.h> |
70 | #include <functional> |
71 | #endif |
72 | |
73 | #include "qstring.h" |
74 | #include "qscopedpointer.h" |
75 | |
76 | #if defined( __OBJC__) && defined(QT_NAMESPACE) |
77 | #define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__) |
78 | #else |
79 | #define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) |
80 | #endif |
81 | |
82 | #define QT_MAC_WEAK_IMPORT(symbol) extern "C" decltype(symbol) symbol __attribute__((weak_import)); |
83 | |
84 | QT_BEGIN_NAMESPACE |
85 | template <typename T, typename U, U (*RetainFunction)(U), void (*ReleaseFunction)(U)> |
86 | class QAppleRefCounted |
87 | { |
88 | public: |
89 | QAppleRefCounted(const T &t = T()) : value(t) {} |
90 | QAppleRefCounted(QAppleRefCounted &&other) : value(other.value) { other.value = T(); } |
91 | QAppleRefCounted(const QAppleRefCounted &other) : value(other.value) { if (value) RetainFunction(value); } |
92 | ~QAppleRefCounted() { if (value) ReleaseFunction(value); } |
93 | operator T() const { return value; } |
94 | void swap(QAppleRefCounted &other) noexcept(noexcept(qSwap(value, other.value))) |
95 | { qSwap(value, other.value); } |
96 | QAppleRefCounted &operator=(const QAppleRefCounted &other) |
97 | { QAppleRefCounted copy(other); swap(copy); return *this; } |
98 | QAppleRefCounted &operator=(QAppleRefCounted &&other) |
99 | { QAppleRefCounted moved(std::move(other)); swap(moved); return *this; } |
100 | T *operator&() { return &value; } |
101 | protected: |
102 | T value; |
103 | }; |
104 | |
105 | |
106 | #ifdef Q_OS_MACOS |
107 | class QMacRootLevelAutoReleasePool |
108 | { |
109 | public: |
110 | QMacRootLevelAutoReleasePool(); |
111 | ~QMacRootLevelAutoReleasePool(); |
112 | private: |
113 | QScopedPointer<QMacAutoReleasePool> pool; |
114 | }; |
115 | #endif |
116 | |
117 | /* |
118 | Helper class that automates refernce counting for CFtypes. |
119 | After constructing the QCFType object, it can be copied like a |
120 | value-based type. |
121 | |
122 | Note that you must own the object you are wrapping. |
123 | This is typically the case if you get the object from a Core |
124 | Foundation function with the word "Create" or "Copy" in it. If |
125 | you got the object from a "Get" function, either retain it or use |
126 | constructFromGet(). One exception to this rule is the |
127 | HIThemeGet*Shape functions, which in reality are "Copy" functions. |
128 | */ |
129 | template <typename T> |
130 | class QCFType : public QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease> |
131 | { |
132 | public: |
133 | using QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>::QAppleRefCounted; |
134 | template <typename X> X as() const { return reinterpret_cast<X>(this->value); } |
135 | static QCFType constructFromGet(const T &t) |
136 | { |
137 | if (t) |
138 | CFRetain(t); |
139 | return QCFType<T>(t); |
140 | } |
141 | }; |
142 | |
143 | class Q_CORE_EXPORT QCFString : public QCFType<CFStringRef> |
144 | { |
145 | public: |
146 | inline QCFString(const QString &str) : QCFType<CFStringRef>(0), string(str) {} |
147 | inline QCFString(const CFStringRef cfstr = 0) : QCFType<CFStringRef>(cfstr) {} |
148 | inline QCFString(const QCFType<CFStringRef> &other) : QCFType<CFStringRef>(other) {} |
149 | operator QString() const; |
150 | operator CFStringRef() const; |
151 | |
152 | private: |
153 | QString string; |
154 | }; |
155 | |
156 | #ifdef Q_OS_MACOS |
157 | Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key); |
158 | Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); |
159 | Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode(); |
160 | #endif |
161 | |
162 | #ifndef QT_NO_DEBUG_STREAM |
163 | QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool); |
164 | #endif |
165 | |
166 | Q_CORE_EXPORT bool qt_apple_isApplicationExtension(); |
167 | |
168 | #if defined(Q_OS_MACOS) && !defined(QT_BOOTSTRAPPED) |
169 | Q_CORE_EXPORT bool qt_apple_isSandboxed(); |
170 | # ifdef __OBJC__ |
171 | QT_END_NAMESPACE |
172 | @interface NSObject (QtSandboxHelpers) |
173 | - (id)qt_valueForPrivateKey:(NSString *)key; |
174 | @end |
175 | QT_BEGIN_NAMESPACE |
176 | # endif |
177 | #endif |
178 | |
179 | #if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS) |
180 | QT_END_NAMESPACE |
181 | # if defined(Q_OS_MACOS) |
182 | Q_FORWARD_DECLARE_OBJC_CLASS(NSApplication); |
183 | using AppleApplication = NSApplication; |
184 | # else |
185 | Q_FORWARD_DECLARE_OBJC_CLASS(UIApplication); |
186 | using AppleApplication = UIApplication; |
187 | # endif |
188 | QT_BEGIN_NAMESPACE |
189 | Q_CORE_EXPORT AppleApplication *qt_apple_sharedApplication(); |
190 | #endif |
191 | |
192 | // -------------------------------------------------------------------------- |
193 | |
194 | #if !defined(QT_BOOTSTRAPPED) |
195 | #define QT_USE_APPLE_UNIFIED_LOGGING |
196 | |
197 | QT_END_NAMESPACE |
198 | #include <os/log.h> |
199 | QT_BEGIN_NAMESPACE |
200 | |
201 | class Q_CORE_EXPORT AppleUnifiedLogger |
202 | { |
203 | public: |
204 | static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message, |
205 | const QString &subsystem = QString()); |
206 | static bool willMirrorToStderr(); |
207 | private: |
208 | static os_log_type_t logTypeForMessageType(QtMsgType msgType); |
209 | static os_log_t cachedLog(const QString &subsystem, const QString &category); |
210 | }; |
211 | |
212 | #endif |
213 | |
214 | // -------------------------------------------------------------------------- |
215 | |
216 | #if !defined(QT_BOOTSTRAPPED) |
217 | |
218 | QT_END_NAMESPACE |
219 | #include <os/activity.h> |
220 | QT_BEGIN_NAMESPACE |
221 | |
222 | template <typename T> using QAppleOsType = QAppleRefCounted<T, void *, os_retain, os_release>; |
223 | |
224 | class Q_CORE_EXPORT QAppleLogActivity |
225 | { |
226 | public: |
227 | QAppleLogActivity() : activity(nullptr) {} |
228 | QAppleLogActivity(os_activity_t activity) : activity(activity) {} |
229 | ~QAppleLogActivity() { if (activity) leave(); } |
230 | |
231 | QAppleLogActivity(const QAppleLogActivity &) = delete; |
232 | QAppleLogActivity& operator=(const QAppleLogActivity &) = delete; |
233 | |
234 | QAppleLogActivity(QAppleLogActivity&& other) |
235 | : activity(other.activity), state(other.state) { other.activity = nullptr; } |
236 | |
237 | QAppleLogActivity& operator=(QAppleLogActivity &&other) |
238 | { |
239 | if (this != &other) { |
240 | activity = other.activity; |
241 | state = other.state; |
242 | other.activity = nullptr; |
243 | } |
244 | return *this; |
245 | } |
246 | |
247 | QAppleLogActivity&& enter() |
248 | { |
249 | if (activity) |
250 | os_activity_scope_enter(static_cast<os_activity_t>(*this), &state); |
251 | return std::move(*this); |
252 | } |
253 | |
254 | void leave() { |
255 | if (activity) |
256 | os_activity_scope_leave(&state); |
257 | } |
258 | |
259 | operator os_activity_t() |
260 | { |
261 | return reinterpret_cast<os_activity_t>(static_cast<void *>(activity)); |
262 | } |
263 | |
264 | private: |
265 | // Work around API_AVAILABLE not working for templates by using void* |
266 | QAppleOsType<void *> activity; |
267 | os_activity_scope_state_s state; |
268 | }; |
269 | |
270 | #define QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) []() { \ |
271 | if (!(condition)) \ |
272 | return QAppleLogActivity(); \ |
273 | return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \ |
274 | }() |
275 | |
276 | #define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N |
277 | #define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1) |
278 | |
279 | #define QT_OVERLOADED_MACRO(MACRO, ...) _QT_OVERLOADED_MACRO(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__) |
280 | #define _QT_OVERLOADED_MACRO(MACRO, ARGC) _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) |
281 | #define _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC |
282 | |
283 | #define QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) |
284 | #define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent) |
285 | #define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__) |
286 | |
287 | QT_MAC_WEAK_IMPORT(_os_activity_current); |
288 | #define QT_APPLE_LOG_ACTIVITY2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT) |
289 | #define QT_APPLE_LOG_ACTIVITY1(description) QT_APPLE_LOG_ACTIVITY2(true, description) |
290 | #define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__) |
291 | |
292 | #define QT_APPLE_SCOPED_LOG_ACTIVITY(...) QAppleLogActivity scopedLogActivity = QT_APPLE_LOG_ACTIVITY(__VA_ARGS__).enter(); |
293 | |
294 | #endif // !defined(QT_BOOTSTRAPPED) |
295 | |
296 | // ------------------------------------------------------------------------- |
297 | |
298 | #if defined( __OBJC__) |
299 | class QMacNotificationObserver |
300 | { |
301 | public: |
302 | QMacNotificationObserver() {} |
303 | |
304 | template<typename Functor> |
305 | QMacNotificationObserver(id object, NSNotificationName name, Functor callback) { |
306 | observer = [[NSNotificationCenter defaultCenter] addObserverForName:name |
307 | object:object queue:nil usingBlock:^(NSNotification *) { |
308 | callback(); |
309 | } |
310 | ]; |
311 | } |
312 | |
313 | QMacNotificationObserver(const QMacNotificationObserver& other) = delete; |
314 | QMacNotificationObserver(QMacNotificationObserver&& other) : observer(other.observer) { |
315 | other.observer = nil; |
316 | } |
317 | |
318 | QMacNotificationObserver &operator=(const QMacNotificationObserver& other) = delete; |
319 | QMacNotificationObserver &operator=(QMacNotificationObserver&& other) { |
320 | if (this != &other) { |
321 | remove(); |
322 | observer = other.observer; |
323 | other.observer = nil; |
324 | } |
325 | return *this; |
326 | } |
327 | |
328 | void remove() { |
329 | if (observer) |
330 | [[NSNotificationCenter defaultCenter] removeObserver:observer]; |
331 | observer = nil; |
332 | } |
333 | ~QMacNotificationObserver() { remove(); } |
334 | |
335 | private: |
336 | id observer = nil; |
337 | }; |
338 | |
339 | QT_END_NAMESPACE |
340 | @interface QT_MANGLE_NAMESPACE(KeyValueObserver) : NSObject |
341 | @end |
342 | QT_NAMESPACE_ALIAS_OBJC_CLASS(KeyValueObserver); |
343 | QT_BEGIN_NAMESPACE |
344 | |
345 | class Q_CORE_EXPORT QMacKeyValueObserver |
346 | { |
347 | public: |
348 | using Callback = std::function<void()>; |
349 | |
350 | QMacKeyValueObserver() {} |
351 | |
352 | // Note: QMacKeyValueObserver must not outlive the object observed! |
353 | QMacKeyValueObserver(id object, NSString *keyPath, Callback callback, |
354 | NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew) |
355 | : object(object), keyPath(keyPath), callback(new Callback(callback)) |
356 | { |
357 | addObserver(options); |
358 | } |
359 | |
360 | QMacKeyValueObserver(const QMacKeyValueObserver &other) |
361 | : QMacKeyValueObserver(other.object, other.keyPath, *other.callback.get()) {} |
362 | |
363 | QMacKeyValueObserver(QMacKeyValueObserver &&other) { swap(other, *this); } |
364 | |
365 | ~QMacKeyValueObserver() { removeObserver(); } |
366 | |
367 | QMacKeyValueObserver &operator=(const QMacKeyValueObserver &other) { |
368 | QMacKeyValueObserver tmp(other); |
369 | swap(tmp, *this); |
370 | return *this; |
371 | } |
372 | |
373 | QMacKeyValueObserver &operator=(QMacKeyValueObserver &&other) { |
374 | QMacKeyValueObserver tmp(std::move(other)); |
375 | swap(tmp, *this); |
376 | return *this; |
377 | } |
378 | |
379 | void removeObserver(); |
380 | |
381 | private: |
382 | void swap(QMacKeyValueObserver &first, QMacKeyValueObserver &second) { |
383 | std::swap(first.object, second.object); |
384 | std::swap(first.keyPath, second.keyPath); |
385 | std::swap(first.callback, second.callback); |
386 | } |
387 | |
388 | void addObserver(NSKeyValueObservingOptions options); |
389 | |
390 | id object = nil; |
391 | NSString *keyPath = nullptr; |
392 | std::unique_ptr<Callback> callback; |
393 | |
394 | static KeyValueObserver *observer; |
395 | }; |
396 | #endif |
397 | |
398 | // ------------------------------------------------------------------------- |
399 | |
400 | QT_END_NAMESPACE |
401 | |
402 | #endif // QCORE_MAC_P_H |
403 |
Warning: That file was not part of the compilation database. It may have many parsing errors.