Qt 6.x
The Qt SDK
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#ifdef Q_OS_MACOS
23#include <mach/port.h>
24struct mach_header;
25typedef int kern_return_t;
26typedef mach_port_t io_object_t;
27extern "C" {
28kern_return_t IOObjectRetain(io_object_t object);
29kern_return_t IOObjectRelease(io_object_t object);
30}
31#endif
32
33#ifndef __IMAGECAPTURE__
34# define __IMAGECAPTURE__
35#endif
36
37// --------------------------------------------------------------------------
38
39#if defined(QT_BOOTSTRAPPED)
40#include <ApplicationServices/ApplicationServices.h>
41#else
42#include <CoreFoundation/CoreFoundation.h>
43#endif
44
45#ifdef __OBJC__
46#include <Foundation/Foundation.h>
47#include <functional>
48#endif
49
50#include "qstring.h"
51#include "qscopedpointer.h"
52#include "qpair.h"
53
54#if defined( __OBJC__) && defined(QT_NAMESPACE)
55#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__)
56#else
57#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
58#endif
59
60#define QT_MAC_WEAK_IMPORT(symbol) extern "C" decltype(symbol) symbol __attribute__((weak_import));
61
62#if defined(__OBJC__)
63#define QT_DECLARE_NAMESPACED_OBJC_INTERFACE(classname, definition) \
64 @interface QT_MANGLE_NAMESPACE(classname) : \
65 definition \
66 @end \
67 QT_NAMESPACE_ALIAS_OBJC_CLASS(classname);
68#else
69#define QT_DECLARE_NAMESPACED_OBJC_INTERFACE(classname, definition) \
70 Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(classname)); \
71 using classname = QT_MANGLE_NAMESPACE(classname);
72#endif
73
74#define QT_FORWARD_DECLARE_OBJC_ENUM(name, type) \
75 typedef type name;
76
79
80// @compatibility_alias doesn't work with categories or their methods
81#define QtExtras QT_MANGLE_NAMESPACE(QtExtras)
82
84template <typename T, typename U, auto RetainFunction, auto ReleaseFunction>
86{
87public:
91 noexcept(std::is_nothrow_move_constructible<T>::value)
92 : value(std::move(t)) {}
94 noexcept(std::is_nothrow_move_assignable<T>::value &&
95 std::is_nothrow_move_constructible<T>::value)
96 : value(std::exchange(other.value, T())) {}
99 { if (value) RetainFunction(value); }
100 ~QAppleRefCounted() { if (value) ReleaseFunction(value); }
101 operator T() const { return value; }
102 void swap(QAppleRefCounted &other) noexcept(noexcept(qSwap(value, other.value)))
103 { qSwap(value, other.value); }
105 { QAppleRefCounted copy(other); swap(copy); return *this; }
107 noexcept(std::is_nothrow_move_assignable<T>::value &&
108 std::is_nothrow_move_constructible<T>::value)
109 { QAppleRefCounted moved(std::move(other)); swap(moved); return *this; }
110 T *operator&() { return &value; }
111protected:
113};
114
116{
117public:
119 Q_CORE_EXPORT ~QMacAutoReleasePool();
120private:
121 Q_DISABLE_COPY(QMacAutoReleasePool)
122 void *pool;
123};
124
125#ifdef Q_OS_MACOS
126class QMacRootLevelAutoReleasePool
127{
128public:
129 Q_NODISCARD_CTOR QMacRootLevelAutoReleasePool();
130 ~QMacRootLevelAutoReleasePool();
131private:
133};
134#endif
135
136/*
137 Helper class that automates reference counting for CFtypes.
138 After constructing the QCFType object, it can be copied like a
139 value-based type.
140
141 Note that you must own the object you are wrapping.
142 This is typically the case if you get the object from a Core
143 Foundation function with the word "Create" or "Copy" in it. If
144 you got the object from a "Get" function, either retain it or use
145 constructFromGet(). One exception to this rule is the
146 HIThemeGet*Shape functions, which in reality are "Copy" functions.
147*/
148template <typename T>
149class QCFType : public QAppleRefCounted<T, CFTypeRef, CFRetain, CFRelease>
150{
152public:
153 using Base::Base;
154 Q_NODISCARD_CTOR explicit QCFType(CFTypeRef r) : Base(static_cast<T>(r)) {}
155 template <typename X> X as() const { return reinterpret_cast<X>(this->value); }
156 static QCFType constructFromGet(const T &t)
157 {
158 if (t)
159 CFRetain(t);
160 return QCFType<T>(t);
161 }
162};
163
164#ifdef Q_OS_MACOS
165template <typename T>
166class QIOType : public QAppleRefCounted<T, io_object_t, IOObjectRetain, IOObjectRelease>
167{
168 using QAppleRefCounted<T, io_object_t, IOObjectRetain, IOObjectRelease>::QAppleRefCounted;
169};
170#endif
171
172class QCFString : public QCFType<CFStringRef>
173{
174public:
175 using QCFType<CFStringRef>::QCFType;
176 Q_NODISCARD_CTOR QCFString(const QString &str) : QCFType<CFStringRef>(0), string(str) {}
177 Q_NODISCARD_CTOR QCFString(const CFStringRef cfstr = 0) : QCFType<CFStringRef>(cfstr) {}
179 Q_CORE_EXPORT operator QString() const;
180 Q_CORE_EXPORT operator CFStringRef() const;
181
182private:
184};
185
186#ifdef Q_OS_MACOS
187Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
188Q_CORE_EXPORT bool qt_mac_runningUnderRosetta();
189Q_CORE_EXPORT std::optional<uint32_t> qt_mac_sipConfiguration();
190#ifdef QT_BUILD_INTERNAL
191Q_AUTOTEST_EXPORT void qt_mac_ensureResponsible();
192#endif
193#endif
194
195#ifndef QT_NO_DEBUG_STREAM
197Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QCFString &string);
198#endif
199
200Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
201
202#if !defined(QT_BOOTSTRAPPED)
203Q_CORE_EXPORT bool qt_apple_isSandboxed();
204
205#if defined(__OBJC__)
207@interface NSObject (QtSandboxHelpers)
208- (id)qt_valueForPrivateKey:(NSString *)key;
209@end
211#endif
212#endif // !QT_BOOTSTRAPPED
213
214#if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS)
216# if defined(Q_OS_MACOS)
217Q_FORWARD_DECLARE_OBJC_CLASS(NSApplication);
218using AppleApplication = NSApplication;
219# else
221using AppleApplication = UIApplication;
222# endif
225#endif
226
227// --------------------------------------------------------------------------
228
229#if !defined(QT_BOOTSTRAPPED)
230#define QT_USE_APPLE_UNIFIED_LOGGING
231
233#include <os/log.h>
235
236class Q_CORE_EXPORT AppleUnifiedLogger
237{
238public:
240 const QString &subsystem = QString());
242private:
243 static os_log_type_t logTypeForMessageType(QtMsgType msgType);
244 static os_log_t cachedLog(const QString &subsystem, const QString &category);
245};
246
247#endif
248
249// --------------------------------------------------------------------------
250
251#if !defined(QT_BOOTSTRAPPED)
252
254#include <os/activity.h>
256
258
259class Q_CORE_EXPORT QAppleLogActivity
260{
261public:
262 QAppleLogActivity() : activity(nullptr) {}
263 QAppleLogActivity(os_activity_t activity) : activity(activity) {}
264 ~QAppleLogActivity() { if (activity) leave(); }
265
266 Q_DISABLE_COPY(QAppleLogActivity)
267
269 : activity(std::exchange(other.activity, nullptr)), state(other.state)
270 {
271 }
272
273 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QAppleLogActivity)
274
276 {
277 if (activity)
278 os_activity_scope_enter(static_cast<os_activity_t>(*this), &state);
279 return std::move(*this);
280 }
281
282 void leave()
283 {
284 if (activity)
285 os_activity_scope_leave(&state);
286 }
287
288 operator os_activity_t()
289 {
290 return reinterpret_cast<os_activity_t>(static_cast<void *>(activity));
291 }
292
294 {
295 activity.swap(other.activity);
296 std::swap(state, other.state);
297 }
298
299private:
300 // Work around API_AVAILABLE not working for templates by using void*
301 QAppleOsType<void *> activity;
302 os_activity_scope_state_s state;
303};
304
305#define QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) []() { \
306 if (!(condition)) \
307 return QAppleLogActivity(); \
308 return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \
309 }()
310
311#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT_3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent)
312#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT_2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT_3(true, description, parent)
313#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__)
314
315QT_MAC_WEAK_IMPORT(_os_activity_current);
316#define QT_APPLE_LOG_ACTIVITY_2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT)
317#define QT_APPLE_LOG_ACTIVITY_1(description) QT_APPLE_LOG_ACTIVITY_2(true, description)
318#define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__)
319
320#define QT_APPLE_SCOPED_LOG_ACTIVITY(...) QAppleLogActivity scopedLogActivity = QT_APPLE_LOG_ACTIVITY(__VA_ARGS__).enter();
321
322#endif // !defined(QT_BOOTSTRAPPED)
323
324// -------------------------------------------------------------------------
325
326class Q_CORE_EXPORT QMacNotificationObserver
327{
328public:
330
331#if defined( __OBJC__)
332 template<typename Functor>
333 QMacNotificationObserver(NSObject *object, NSNotificationName name, Functor callback) {
334 observer = [[NSNotificationCenter defaultCenter] addObserverForName:name
335 object:object queue:nil usingBlock:^(NSNotification *) {
336 callback();
337 }
338 ];
339 }
340#endif
341
344 : observer(std::exchange(other.observer, nullptr))
345 {
346 }
347
349 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMacNotificationObserver)
350
352 {
353 qt_ptr_swap(observer, other.observer);
354 }
355
356 void remove();
358
359private:
360 NSObject *observer = nullptr;
361};
362
364QT_DECLARE_NAMESPACED_OBJC_INTERFACE(KeyValueObserver, NSObject)
366
367class Q_CORE_EXPORT QMacKeyValueObserver
368{
369public:
370 using Callback = std::function<void()>;
371
373
374#if defined( __OBJC__)
375 // Note: QMacKeyValueObserver must not outlive the object observed!
376 QMacKeyValueObserver(NSObject *object, NSString *keyPath, Callback callback,
377 NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew)
378 : object(object), keyPath(keyPath), callback(new Callback(callback))
379 {
380 addObserver(options);
381 }
382#endif
383
385
387
388 ~QMacKeyValueObserver() { removeObserver(); }
389
391 {
393 swap(tmp);
394 return *this;
395 }
396
397 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMacKeyValueObserver)
398
399 void removeObserver();
400
402 {
403 qt_ptr_swap(object, other.object);
404 qt_ptr_swap(keyPath, other.keyPath);
405 callback.swap(other.callback);
406 }
407
408private:
409#if defined( __OBJC__)
410 void addObserver(NSKeyValueObservingOptions options);
411#endif
412
413 NSObject *object = nullptr;
414 NSString *keyPath = nullptr;
415 std::unique_ptr<Callback> callback;
416
417 static KeyValueObserver *observer;
418};
419
420// -------------------------------------------------------------------------
421
422class Q_CORE_EXPORT QMacVersion
423{
424public:
427 QtLibraries
428 };
429
433
434private:
435 QMacVersion() = default;
437 static VersionTuple versionsForImage(const mach_header *machHeader);
438 static VersionTuple applicationVersion();
439 static VersionTuple libraryVersion();
440};
441
442// -------------------------------------------------------------------------
443
445
446#endif // QCORE_MAC_P_H
static bool preventsStderrLogging()
static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message, const QString &subsystem=QString())
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:90
Q_NODISCARD_CTOR QAppleRefCounted(const QAppleRefCounted &other)
Definition qcore_mac_p.h:97
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:93
Q_NODISCARD_CTOR QAppleRefCounted()
Definition qcore_mac_p.h:88
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:89
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:301
Q_NODISCARD_CTOR Q_CORE_EXPORT QMacAutoReleasePool()
Definition qcore_mac.mm:257
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:39
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
const QLoggingCategory & category()
[1]
QString str
[2]
qSwap(pi, e)
else opt state
[0]
Combined button and popup list for selecting options.
static void * context
static jboolean copy(JNIEnv *, jobject)
#define Q_NODISCARD_CTOR
std::pair< T1, T2 > QPair
AppleApplication * qt_apple_sharedApplication()
Definition qcore_mac.mm:430
#define QT_MAC_WEAK_IMPORT(symbol)
Definition qcore_mac_p.h:60
UIApplication AppleApplication
Q_CORE_EXPORT bool qt_apple_isSandboxed()
Definition qcore_mac.mm:498
Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
Definition qcore_mac.mm:307
Q_CORE_EXPORT bool qt_apple_isApplicationExtension()
Definition qcore_mac.mm:423
#define QT_DECLARE_NAMESPACED_OBJC_INTERFACE(classname, definition)
Definition qcore_mac_p.h:69
#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 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
#define X(name)
static QString keyPath(const QString &rKey)
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
Definition qswap.h:43
#define Q_AUTOTEST_EXPORT
#define leave(x)
settings remove("monkey")
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
this swap(other)