Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qiosintegration.mm
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// Qt-Security score:significant reason:default
4
5#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
6
9#include "qiosglobal.h"
10#include "qioswindow.h"
11#include "qiosscreen.h"
13#if QT_CONFIG(clipboard)
14#include "qiosclipboard.h"
15#endif
17#include "qiostheme.h"
18#include "qiosservices.h"
20
21#if defined(Q_OS_VISIONOS)
22#include "qiosswiftintegration.h"
23#endif
24
25#include <QtGui/qpointingdevice.h>
26#include <QtGui/private/qguiapplication_p.h>
27#include <QtGui/private/qrhibackingstore_p.h>
28
29#include <qoffscreensurface.h>
30#include <qpa/qplatformoffscreensurface.h>
31
32#include <QtGui/private/qcoretextfontdatabase_p.h>
33#include <QtGui/private/qmacmimeregistry_p.h>
34#include <QtGui/qutimimeconverter.h>
35#include <QDir>
36#include <QOperatingSystemVersion>
37
38#if QT_CONFIG(opengl)
39#include "qioscontext.h"
40#endif
41
42#import <AudioToolbox/AudioServices.h>
43
44#include <QtDebug>
45
47
48using namespace Qt::StringLiterals;
49
50class QCoreTextFontEngine;
51
53{
54 return static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
55}
56
57QIOSIntegration::QIOSIntegration()
58 : m_fontDatabase(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>)
59#if QT_CONFIG(clipboard)
60 , m_clipboard(new QIOSClipboard)
61#endif
62 , m_inputContext(0)
63 , m_accessibility(0)
64 , m_optionalPlugins(new QFactoryLoader(QIosOptionalPluginInterface_iid, "/platforms/darwin"_L1))
65{
66 if (Q_UNLIKELY(!qt_apple_isApplicationExtension() && !qt_apple_sharedApplication())) {
67 qFatal("Error: You are creating QApplication before calling UIApplicationMain.\n"
68 "If you are writing a native iOS application, and only want to use Qt for\n"
69 "parts of the application, a good place to create QApplication is from within\n"
70 "'applicationDidFinishLaunching' inside your UIApplication delegate.\n");
71 }
72
73 // Set current directory to app bundle folder
74 QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
75}
76
77void QIOSIntegration::initialize()
78{
79 QIOSScreen::initializeScreens();
80
81 // Depends on a primary screen being present
82 m_inputContext = new QIOSInputContext;
83
84 QPointingDevice::Capabilities touchCapabilities = QPointingDevice::Capability::Position | QPointingDevice::Capability::NormalizedPosition;
85#if !defined(Q_OS_VISIONOS)
86 if (UIScreen.mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
87 touchCapabilities |= QPointingDevice::Capability::Pressure;
88#endif
89 m_touchDevice = new QPointingDevice("touchscreen", 0, QInputDevice::DeviceType::TouchScreen,
90 QPointingDevice::PointerType::Finger, touchCapabilities, 10, 0);
91 QWindowSystemInterface::registerInputDevice(m_touchDevice);
92#if QT_CONFIG(tabletevent)
93 QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
94 m_pencilDevice = new QPointingDevice(
95 "Apple Pencil", 0, QInputDevice::DeviceType::Stylus, QPointingDevice::PointerType::Pen,
96 QInputDevice::Capability::Position | QInputDevice::Capability::Pressure
97 | QInputDevice::Capability::XTilt | QInputDevice::Capability::YTilt,
98 1, 0);
99 QWindowSystemInterface::registerInputDevice(m_pencilDevice);
100#endif
101 QMacMimeRegistry::initializeMimeTypes();
102
103 qsizetype size = QList<QPluginParsedMetaData>(m_optionalPlugins->metaData()).size();
104 for (qsizetype i = 0; i < size; ++i)
105 qobject_cast<QIosOptionalPluginInterface *>(m_optionalPlugins->instance(i))->initPlugin();
106}
107
108QIOSIntegration::~QIOSIntegration()
109{
110 delete m_fontDatabase;
111 m_fontDatabase = 0;
112
113#if QT_CONFIG(clipboard)
114 delete m_clipboard;
115 m_clipboard = 0;
116#endif
117
118 QMacMimeRegistry::destroyMimeTypes();
119
120 delete m_inputContext;
121 m_inputContext = 0;
122
123 foreach (QScreen *screen, QGuiApplication::screens())
124 QWindowSystemInterface::handleScreenRemoved(screen->handle());
125
126 delete m_platformServices;
127 m_platformServices = 0;
128
129 delete m_accessibility;
130 m_accessibility = 0;
131
132 delete m_optionalPlugins;
133 m_optionalPlugins = 0;
134}
135
136bool QIOSIntegration::hasCapability(Capability cap) const
137{
138 switch (cap) {
139#if QT_CONFIG(opengl)
140 case BufferQueueingOpenGL:
141 return true;
142 case OpenGL:
143 case ThreadedOpenGL:
144 return true;
145#endif
146 case ThreadedPixmaps:
147 return true;
148 case MultipleWindows:
149 return true;
150 case WindowManagement:
151 return false;
152 case ApplicationState:
153 return true;
154 case ForeignWindows:
155 return true;
156 default:
157 return QPlatformIntegration::hasCapability(cap);
158 }
159}
160
161QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const
162{
163 return new QIOSWindow(window);
164}
165
166QPlatformWindow *QIOSIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
167{
168 return new QIOSWindow(window, nativeHandle);
169}
170
171QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const
172{
173 return new QRhiBackingStore(window);
174}
175
176#if QT_CONFIG(opengl)
177// Used when the QWindow's surface type is set by the client to QSurface::OpenGLSurface
178QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
179{
180 return new QIOSContext(context);
181}
182#endif
183
184class QIOSOffscreenSurface : public QPlatformOffscreenSurface
185{
186public:
187 QIOSOffscreenSurface(QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) {}
188
189 QSurfaceFormat format() const override
190 {
191 Q_ASSERT(offscreenSurface());
192 return offscreenSurface()->requestedFormat();
193 }
194 bool isValid() const override { return true; }
195};
196
197QPlatformOffscreenSurface *QIOSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
198{
199 return new QIOSOffscreenSurface(surface);
200}
201
203{
204 return QIOSEventDispatcher::create();
205}
206
208{
209 return m_fontDatabase;
210}
211
212#if QT_CONFIG(clipboard)
213QPlatformClipboard *QIOSIntegration::clipboard() const
214{
215 return m_clipboard;
216}
217#endif
218
220{
221 return m_inputContext;
222}
223
225{
226 if (!m_platformServices)
227 m_platformServices = new QIOSServices;
228
229 return m_platformServices;
230}
231
232QVariant QIOSIntegration::styleHint(StyleHint hint) const
233{
234 switch (hint) {
235 case StartDragTime:
236 return 300;
237 case PasswordMaskDelay:
238 // this number is based on timing the native delay
239 // since there is no API to get it
240 return 2000;
241 case ShowIsMaximized:
242 return true;
243 case SetFocusOnTouchRelease:
244 return true;
245 default:
246 return QPlatformIntegration::styleHint(hint);
247 }
248}
249
251{
252 return QStringList(QLatin1StringView(QIOSTheme::name));
253}
254
256{
257 if (name == QLatin1StringView(QIOSTheme::name))
258 return new QIOSTheme;
259
260 return QPlatformIntegration::createPlatformTheme(name);
261}
262
264{
265 return m_touchDevice;
266}
267
268#if QT_CONFIG(tabletevent)
269QPointingDevice *QIOSIntegration::pencilDevice()
270{
271 return m_pencilDevice;
272}
273#endif
274
275#if QT_CONFIG(accessibility)
276QPlatformAccessibility *QIOSIntegration::accessibility() const
277{
278 if (!m_accessibility)
279 m_accessibility = new QIOSPlatformAccessibility;
280 return m_accessibility;
281}
282#endif
283
285{
286 return const_cast<QIOSIntegration *>(this);
287}
288
290{
291#if !TARGET_IPHONE_SIMULATOR
292 AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
293#endif
294}
295
297{
298 UIApplication.sharedApplication.applicationIconBadgeNumber = number;
299}
300
301// ---------------------------------------------------------
302
303#if defined(Q_OS_VISIONOS)
304void QIOSIntegration::openImmersiveSpace()
305{
306 [ImmersiveSpaceManager openImmersiveSpace];
307}
308
309void QIOSIntegration::dismissImmersiveSpace()
310{
311 [ImmersiveSpaceManager dismissImmersiveSpace];
312}
313
314void QIOSIntegration::setImmersiveSpaceCompositorLayer(CompositorLayer *layer)
315{
316 m_immersiveSpaceCompositorLayer = layer;
317}
318
319void QIOSIntegration::configureCompositorLayer(cp_layer_renderer_capabilities_t capabilities,
320 cp_layer_renderer_configuration_t configuration)
321{
322 if (m_immersiveSpaceCompositorLayer)
323 m_immersiveSpaceCompositorLayer->configure(capabilities, configuration);
324}
325
326void QIOSIntegration::renderCompositorLayer(cp_layer_renderer_t renderer)
327{
328 if (m_immersiveSpaceCompositorLayer)
329 m_immersiveSpaceCompositorLayer->render(renderer);
330}
331
332void QIOSIntegration::handleSpatialEvents(const char *jsonString)
333{
334 if (m_immersiveSpaceCompositorLayer) {
335 QJsonParseError error;
336 QJsonDocument doc = QJsonDocument::fromJson(QByteArray(jsonString), &error);
337 if (error.error != QJsonParseError::NoError) {
338 qWarning() << "Error parsing JSON: " << error.errorString();
339 return;
340 }
341 m_immersiveSpaceCompositorLayer->handleSpatialEvents(doc.object());
342 }
343}
344
345#endif
346
347// ---------------------------------------------------------
348
349void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
350{
351 if (!window || !window->handle())
352 return 0;
353
354 QByteArray lowerCaseResource = resource.toLower();
355
356 QIOSWindow *platformWindow = static_cast<QIOSWindow *>(window->handle());
357
358 if (lowerCaseResource == "uiview")
359 return reinterpret_cast<void *>(platformWindow->winId());
360
361 return 0;
362}
363
364// ---------------------------------------------------------
365
366QT_END_NAMESPACE
367
368#include "moc_qiosintegration.cpp"
QVariant styleHint(StyleHint hint) const override
QPlatformTheme * createPlatformTheme(const QString &name) const override
void beep() const override
static QIOSIntegration * instance()
void setApplicationBadge(qint64 number) override
QPointingDevice * touchDevice()
QStringList themeNames() const override
QPlatformNativeInterface * nativeInterface() const override
QAbstractEventDispatcher * createEventDispatcher() const override
Factory function for the GUI event dispatcher.
QPlatformServices * services() const override
QPlatformInputContext * inputContext() const override
Returns the platforms input context.
QPlatformFontDatabase * fontDatabase() const override
Accessor for the platform integration's fontdatabase.
static const char * name
Definition qiostheme.h:42
#define QIosOptionalPluginInterface_iid