Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcore_mac_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 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#ifndef QCORE_MAC_P_H
5#define QCORE_MAC_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "private/qglobal_p.h"
19
20#include <QtCore/qoperatingsystemversion.h>
21
22#include <optional>
23
24#ifdef Q_OS_MACOS
25#include <mach/port.h>
26struct mach_header;
27typedef int kern_return_t;
28typedef mach_port_t io_object_t;
29extern "C" {
30kern_return_t IOObjectRetain(io_object_t object);
31kern_return_t IOObjectRelease(io_object_t object);
32}
33#endif
34
35#ifndef __IMAGECAPTURE__
36# define __IMAGECAPTURE__
37#endif
38
39// --------------------------------------------------------------------------
40
41#if defined(QT_BOOTSTRAPPED)
42#include <ApplicationServices/ApplicationServices.h>
43#else
44#include <CoreFoundation/CoreFoundation.h>
45#endif
46
47#ifdef __OBJC__
48#include <Foundation/Foundation.h>
49#include <functional>
50#endif
51
52#include "qstring.h"
53#include "qpair.h"
54
55#if defined( __OBJC__) && defined(QT_NAMESPACE)
56#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__)
57#else
58#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
59#endif
60
61#define QT_MAC_WEAK_IMPORT(symbol) extern "C" decltype(symbol) symbol __attribute__((weak_import));
62
63#if defined(__OBJC__)
64#define QT_DECLARE_NAMESPACED_OBJC_INTERFACE(classname, definition) \
65 @interface QT_MANGLE_NAMESPACE(classname) : \
66 definition \
67 @end \
68 QT_NAMESPACE_ALIAS_OBJC_CLASS(classname);
69#else
70#define QT_DECLARE_NAMESPACED_OBJC_INTERFACE(classname, definition) \
71 Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(classname)); \
72 using classname = QT_MANGLE_NAMESPACE(classname);
73#endif
74
75#define QT_FORWARD_DECLARE_OBJC_ENUM(name, type) \
76 typedef type name;
77
80
81// @compatibility_alias doesn't work with categories or their methods
82#define QtExtras QT_MANGLE_NAMESPACE(QtExtras)
83
85template <typename T, typename U, auto RetainFunction, auto ReleaseFunction>
87{
88public:
92 noexcept(std::is_nothrow_move_constructible<T>::value)
93 : value(std::move(t)) {}
95 noexcept(std::is_nothrow_move_assignable<T>::value &&
96 std::is_nothrow_move_constructible<T>::value)
97 : value(std::exchange(other.value, T())) {}
100 { if (value) RetainFunction(value); }
101 ~QAppleRefCounted() { if (value) ReleaseFunction(value); }
102 operator T() const { return value; }
103 void swap(QAppleRefCounted &other) noexcept(noexcept(qSwap(value, other.value)))
104 { qSwap(value, other.value); }
108 noexcept(std::is_nothrow_move_assignable<T>::value &&
109 std::is_nothrow_move_constructible<T>::value)
110 { QAppleRefCounted moved(std::move(other)); swap(moved); return *this; }
111 T *operator&() { return &value; }
112protected:
114};
115
117{
118public:
120 Q_CORE_EXPORT ~QMacAutoReleasePool();
121private:
122 Q_DISABLE_COPY(QMacAutoReleasePool)
123 void *pool;
124};
125
126#ifdef Q_OS_MACOS
127class QMacRootLevelAutoReleasePool
128{
129public:
130 Q_NODISCARD_CTOR QMacRootLevelAutoReleasePool();
131 ~QMacRootLevelAutoReleasePool();
132private:
133 std::optional<QMacAutoReleasePool> pool = std::nullopt;
134};
135#endif
136
137/*
138 Helper class that automates reference counting for CFtypes.
139 After constructing the QCFType object, it can be copied like a
140 value-based type.
141
142 Note that you must own the object you are wrapping.
143 This is typically the case if you get the object from a Core
144 Foundation function with the word "Create" or "Copy" in it. If
145 you got the object from a "Get" function, either retain it or use
146 constructFromGet(). One exception to this rule is the
147 HIThemeGet*Shape functions, which in reality are "Copy" functions.
148*/
149template <typename T>
150class QCFType : public QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>
151{
152 using Base = QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>;
153public:
154 using Base::Base;
155 Q_NODISCARD_CTOR explicit QCFType(CFTypeRef r) : Base(static_cast<T>(r)) {}
156 template <typename X> X as() const { return reinterpret_cast<X>(this->value); }
157 static QCFType constructFromGet(const T &t)
158 {
159 if (t)
160 CFRetain(t);
161 return QCFType<T>(t);
162 }
163};
164
165#ifdef Q_OS_MACOS
166template <typename T>
167class QIOType : public QAppleRefCounted<T, io_object_t, IOObjectRetain, IOObjectRelease>
168{
169 using QAppleRefCounted<T, io_object_t, IOObjectRetain, IOObjectRelease>::QAppleRefCounted;
170};
171#endif
172
173class QCFString : public QCFType<CFStringRef>
174{
175public:
176 using QCFType<CFStringRef>::QCFType;
177 Q_NODISCARD_CTOR QCFString(const QString &str) : QCFType<CFStringRef>(0), string(str) {}
178 Q_NODISCARD_CTOR QCFString(const CFStringRef cfstr = 0) : QCFType<CFStringRef>(cfstr) {}
179 Q_NODISCARD_CTOR QCFString(const QCFType<CFStringRef> &other) : QCFType<CFStringRef>(other) {}
180 Q_CORE_EXPORT operator QString() const;
181 Q_CORE_EXPORT operator CFStringRef() const;
182
183private:
185};
186
187#ifdef Q_OS_MACOS
188Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
189Q_CORE_EXPORT bool qt_mac_runningUnderRosetta();
190Q_CORE_EXPORT std::optional<uint32_t> qt_mac_sipConfiguration();
191#ifdef QT_BUILD_INTERNAL
192Q_AUTOTEST_EXPORT void qt_mac_ensureResponsible();
193#endif
194#endif
195
196#ifndef QT_NO_DEBUG_STREAM
198Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QCFString &string);
199#endif
200
201Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
202
203#if !defined(QT_BOOTSTRAPPED)
204Q_CORE_EXPORT bool qt_apple_isSandboxed();
205
206#if defined(__OBJC__)
208@interface NSObject (QtExtras)
209- (id)qt_valueForPrivateKey:(NSString *)key;
210@end
212#endif
213#endif // !QT_BOOTSTRAPPED
214
215#if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS)
217# if defined(Q_OS_MACOS)
218Q_FORWARD_DECLARE_OBJC_CLASS(NSApplication);
219using AppleApplication = NSApplication;
220# else
222using AppleApplication = UIApplication;
223# endif
226#endif
227
228// --------------------------------------------------------------------------
229
230#if !defined(QT_BOOTSTRAPPED)
231#define QT_USE_APPLE_UNIFIED_LOGGING
232
234#include <os/log.h>
236
237class Q_CORE_EXPORT AppleUnifiedLogger
238{
239public:
241 const QString &message)
242 { return messageHandler(msgType, context, message, QString()); }
244 const QString &message, const QString &subsystem);
246private:
247 static os_log_type_t logTypeForMessageType(QtMsgType msgType);
248 static os_log_t cachedLog(const QString &subsystem, const QString &category);
249};
250
251#endif
252
253// --------------------------------------------------------------------------
254
255#if !defined(QT_BOOTSTRAPPED)
256
258#include <os/activity.h>
260
261template <typename T> using QAppleOsType = QAppleRefCounted<T, void *, os_retain, os_release>;
262
263class Q_CORE_EXPORT QAppleLogActivity
264{
265public:
266 QAppleLogActivity() : activity(nullptr) {}
267 QAppleLogActivity(os_activity_t activity) : activity(activity) {}
268 ~QAppleLogActivity() { if (activity) leave(); }
269
270 Q_DISABLE_COPY(QAppleLogActivity)
271
273 : activity(std::exchange(other.activity, nullptr)), state(other.state)
274 {
275 }
276
277 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QAppleLogActivity)
278
280 {
281 if (activity)
282 os_activity_scope_enter(static_cast<os_activity_t>(*this), &state);
283 return std::move(*this);
284 }
285
286 void leave()
287 {
288 if (activity)
289 os_activity_scope_leave(&state);
290 }
291
292 operator os_activity_t()
293 {
294 return reinterpret_cast<os_activity_t>(static_cast<void *>(activity));
295 }
296
298 {
299 activity.swap(other.activity);
300 std::swap(state, other.state);
301 }
302
303private:
304 // Work around API_AVAILABLE not working for templates by using void*
305 QAppleOsType<void *> activity;
306 os_activity_scope_state_s state;
307};
308
309#define QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) []() { \
310 if (!(condition)) \
311 return QAppleLogActivity(); \
312 return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \
313 }()
314
315#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT_3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent)
316#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT_2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT_3(true, description, parent)
317#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__)
318
319QT_MAC_WEAK_IMPORT(_os_activity_current);
320#define QT_APPLE_LOG_ACTIVITY_2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT)
321#define QT_APPLE_LOG_ACTIVITY_1(description) QT_APPLE_LOG_ACTIVITY_2(true, description)
322#define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__)
323
324#define QT_APPLE_SCOPED_LOG_ACTIVITY(...) QAppleLogActivity scopedLogActivity = QT_APPLE_LOG_ACTIVITY(__VA_ARGS__).enter();
325
326#endif // !defined(QT_BOOTSTRAPPED)
327
328// -------------------------------------------------------------------------
329
330class Q_CORE_EXPORT QMacNotificationObserver
331{
332public:
334
335#if defined( __OBJC__)
336 template<typename Functor>
337 QMacNotificationObserver(NSObject *object, NSNotificationName name, Functor callback) {
338 observer = [[NSNotificationCenter defaultCenter] addObserverForName:name
339 object:object queue:nil usingBlock:^(NSNotification *) {
340 callback();
341 }
342 ];
343 }
344#endif
345
348 : observer(std::exchange(other.observer, nullptr))
349 {
350 }
351
353 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMacNotificationObserver)
354
356 {
357 qt_ptr_swap(observer, other.observer);
358 }
359
360 void remove();
362
363private:
364 NSObject *observer = nullptr;
365};
366
368QT_DECLARE_NAMESPACED_OBJC_INTERFACE(KeyValueObserver, NSObject)
370
371class Q_CORE_EXPORT QMacKeyValueObserver
372{
373public:
374 using Callback = std::function<void()>;
375
377
378#if defined( __OBJC__)
379 // Note: QMacKeyValueObserver must not outlive the object observed!
380 QMacKeyValueObserver(NSObject *object, NSString *keyPath, Callback callback,
381 NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew)
382 : object(object), keyPath(keyPath), callback(new Callback(callback))
383 {
384 addObserver(options);
385 }
386#endif
387
389
391
392 ~QMacKeyValueObserver() { removeObserver(); }
393
395 {
397 swap(tmp);
398 return *this;
399 }
400
401 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMacKeyValueObserver)
402
403 void removeObserver();
404
406 {
407 qt_ptr_swap(object, other.object);
408 qt_ptr_swap(keyPath, other.keyPath);
409 callback.swap(other.callback);
410 }
411
412private:
413#if defined( __OBJC__)
414 void addObserver(NSKeyValueObservingOptions options);
415#endif
416
417 NSObject *object = nullptr;
418 NSString *keyPath = nullptr;
419 std::unique_ptr<Callback> callback;
420
421 static KeyValueObserver *observer;
422};
423
424// -------------------------------------------------------------------------
425
426class Q_CORE_EXPORT QMacVersion
427{
428public:
431 QtLibraries
432 };
433
437
438private:
439 QMacVersion() = default;
440 using VersionTuple = std::pair<QOperatingSystemVersion, QOperatingSystemVersion>;
441 static VersionTuple versionsForImage(const mach_header *machHeader);
442 static VersionTuple applicationVersion();
443 static VersionTuple libraryVersion();
444};
445
446// -------------------------------------------------------------------------
447
448#ifdef __OBJC__
449template <typename T>
450typename std::enable_if<std::is_pointer<T>::value, T>::type
451qt_objc_cast(id object)
452{
453 if ([object isKindOfClass:[typename std::remove_pointer<T>::type class]])
454 return static_cast<T>(object);
455
456 return nil;
457}
458#endif
459
460// -------------------------------------------------------------------------
461
463
464#endif // QCORE_MAC_P_H
static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message)
static bool preventsStderrLogging()
static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message, const QString &subsystem)
void swap(QAppleLogActivity &other)
QAppleLogActivity(os_activity_t activity)
Q_NODISCARD_CTOR QAppleRefCounted(T &&t) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition qcore_mac_p.h:91
Q_NODISCARD_CTOR QAppleRefCounted(const QAppleRefCounted &other)
Definition qcore_mac_p.h:98
Q_NODISCARD_CTOR QAppleRefCounted(QAppleRefCounted &&other) noexcept(std::is_nothrow_move_assignable< T >::value &&std::is_nothrow_move_constructible< T >::value)
Definition qcore_mac_p.h:94
Q_NODISCARD_CTOR QAppleRefCounted()
Definition qcore_mac_p.h:89
void swap(QAppleRefCounted &other) noexcept(noexcept(qSwap(value, other.value)))
QAppleRefCounted & operator=(const QAppleRefCounted &other)
QAppleRefCounted & operator=(QAppleRefCounted &&other) noexcept(std::is_nothrow_move_assignable< T >::value &&std::is_nothrow_move_constructible< T >::value)
Q_NODISCARD_CTOR QAppleRefCounted(const T &t)
Definition qcore_mac_p.h:90
Q_NODISCARD_CTOR QCFString(const CFStringRef cfstr=0)
Q_NODISCARD_CTOR QCFString(const QCFType< CFStringRef > &other)
Q_NODISCARD_CTOR QCFString(const QString &str)
static QCFType constructFromGet(const T &t)
Q_NODISCARD_CTOR QCFType(CFTypeRef r)
X as() const
\inmodule QtCore
Q_CORE_EXPORT ~QMacAutoReleasePool()
Definition qcore_mac.mm:302
Q_NODISCARD_CTOR Q_CORE_EXPORT QMacAutoReleasePool()
Definition qcore_mac.mm:258
QMacKeyValueObserver(QMacKeyValueObserver &&other) noexcept
QMacKeyValueObserver & operator=(const QMacKeyValueObserver &other)
std::function< void()> Callback
void swap(QMacKeyValueObserver &other) noexcept
QMacKeyValueObserver()=default
QMacNotificationObserver(const QMacNotificationObserver &other)=delete
QMacNotificationObserver(QMacNotificationObserver &&other)
QMacNotificationObserver & operator=(const QMacNotificationObserver &other)=delete
static QOperatingSystemVersion deploymentTarget(VersionTarget target=ApplicationBinary)
static QOperatingSystemVersion currentRuntime()
static QOperatingSystemVersion buildSDK(VersionTarget target=ApplicationBinary)
\inmodule QtCore
Definition qlogging.h:42
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
const QLoggingCategory & category()
[1]
QString str
[2]
else opt state
[0]
static Q_CONSTINIT QBasicAtomicPointer< void(QtMsgType, const QMessageLogContext &, const QString &) messageHandler)
Combined button and popup list for selecting options.
static void * context
static jboolean copy(JNIEnv *, jobject)
#define Q_NODISCARD_CTOR
AppleApplication * qt_apple_sharedApplication()
Definition qcore_mac.mm:431
#define QT_MAC_WEAK_IMPORT(symbol)
Definition qcore_mac_p.h:61
UIApplication AppleApplication
QAppleRefCounted< T, void *, os_retain, os_release > QAppleOsType
Q_CORE_EXPORT bool qt_apple_isSandboxed()
Definition qcore_mac.mm:499
Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
Definition qcore_mac.mm:308
Q_CORE_EXPORT bool qt_apple_isApplicationExtension()
Definition qcore_mac.mm:424
#define QT_DECLARE_NAMESPACED_OBJC_INTERFACE(classname, definition)
Definition qcore_mac_p.h:70
#define Q_FORWARD_DECLARE_OBJC_CLASS(classname)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
QtMsgType
Definition qlogging.h:29
GLboolean r
[2]
GLenum GLuint id
[7]
GLuint object
[3]
GLenum type
GLenum target
GLuint GLsizei const GLchar * message
GLuint name
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
static QString keyPath(const QString &rKey)
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
Definition qswap.h:29
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Definition qswap.h:20
#define Q_AUTOTEST_EXPORT
#define leave(x)
settings remove("monkey")
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
this swap(other)