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
qiosglobal.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#include "qiosglobal.h"
8#include "qiosscreen.h"
9#include "quiwindow.h"
11
12#include <QtCore/private/qcore_mac_p.h>
13
15
16Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
17Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods", QtCriticalMsg);
19Q_LOGGING_CATEGORY(lcQpaWindowScene, "qt.qpa.window.scene");
20
22{
23 // Returns \c true if the plugin is in full control of the whole application. This means
24 // that we control the application delegate and the top view controller, and can take
25 // actions that impacts all parts of the application. The opposite means that we are
26 // embedded inside a native iOS application, and should be more focused on playing along
27 // with native UIControls, and less inclined to change structures that lies outside the
28 // scope of our QWindows/UIViews.
29 return QIOSEventDispatcher::isQtApplication();
30}
31
33{
34 static bool result = []{
35 // This class is documented to only be available on visionOS
36 return NSClassFromString(@"UIWindowSceneGeometryPreferencesVision");
37 }();
38 return result;
39}
40
41#ifndef Q_OS_TVOS
42Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation)
43{
44 Qt::ScreenOrientation qtOrientation;
45 switch (uiDeviceOrientation) {
46 case UIDeviceOrientationPortraitUpsideDown:
47 qtOrientation = Qt::InvertedPortraitOrientation;
48 break;
49 case UIDeviceOrientationLandscapeLeft:
50 qtOrientation = Qt::LandscapeOrientation;
51 break;
52 case UIDeviceOrientationLandscapeRight:
53 qtOrientation = Qt::InvertedLandscapeOrientation;
54 break;
55 case UIDeviceOrientationFaceUp:
56 case UIDeviceOrientationFaceDown:
57 qWarning("Falling back to Qt::PortraitOrientation for UIDeviceOrientationFaceUp/UIDeviceOrientationFaceDown");
58 qtOrientation = Qt::PortraitOrientation;
59 break;
60 default:
61 qtOrientation = Qt::PortraitOrientation;
62 break;
63 }
64 return qtOrientation;
65}
66
67UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation)
68{
69 UIDeviceOrientation uiOrientation;
70 switch (qtOrientation) {
71 case Qt::LandscapeOrientation:
72 uiOrientation = UIDeviceOrientationLandscapeLeft;
73 break;
74 case Qt::InvertedLandscapeOrientation:
75 uiOrientation = UIDeviceOrientationLandscapeRight;
76 break;
77 case Qt::InvertedPortraitOrientation:
78 uiOrientation = UIDeviceOrientationPortraitUpsideDown;
79 break;
80 case Qt::PrimaryOrientation:
81 case Qt::PortraitOrientation:
82 default:
83 uiOrientation = UIDeviceOrientationPortrait;
84 break;
85 }
86 return uiOrientation;
87}
88#endif
89
90int infoPlistValue(NSString* key, int defaultValue)
91{
92 static NSBundle *bundle = [NSBundle mainBundle];
93 NSNumber* value = [bundle objectForInfoDictionaryKey:key];
94 return value ? [value intValue] : defaultValue;
95}
96
98{
99 UIWindow *uiWindow = window ? reinterpret_cast<UIView *>(window->winId()).window : nullptr;
100 if (!uiWindow) {
101 auto *scenes = [qt_apple_sharedApplication().connectedScenes allObjects];
102 if (scenes.count > 0) {
103 auto *windowScene = static_cast<UIWindowScene*>(scenes[0]);
104 uiWindow = windowScene.keyWindow;
105 if (!uiWindow && windowScene.windows.count)
106 uiWindow = windowScene.windows[0];
107 }
108 }
109 return uiWindow;
110}
111
112UIView *rootViewForScreen(const QPlatformScreen *screen)
113{
114 Q_ASSERT(screen);
115
116 const auto *iosScreen = static_cast<const QIOSScreen *>(screen);
117 for (UIScene *scene in [qt_apple_sharedApplication().connectedScenes allObjects]) {
118 if (![scene isKindOfClass:UIWindowScene.class])
119 continue;
120
121 auto *windowScene = static_cast<UIWindowScene*>(scene);
122
123#if !defined(Q_OS_VISIONOS)
124 if (windowScene.screen != iosScreen->uiScreen())
125 continue;
126#else
127 Q_UNUSED(iosScreen);
128#endif
129
130 UIWindow *uiWindow = qt_objc_cast<QUIWindow*>(windowScene.keyWindow);
131 if (!uiWindow) {
132 for (UIWindow *win in windowScene.windows) {
133 if (qt_objc_cast<QUIWindow*>(win)) {
134 uiWindow = win;
135 break;
136 }
137 }
138 }
139
140 return uiWindow.rootViewController.view;
141 }
142
143 return nullptr;
144}
145
146QT_END_NAMESPACE
147
148// -------------------------------------------------------------------------
149
150@interface QtFirstResponderEvent : UIEvent
151@property (nonatomic, strong) id firstResponder;
152@end
153
154@implementation QtFirstResponderEvent
155- (void)dealloc
156{
157 self.firstResponder = 0;
158 [super dealloc];
159}
160@end
161
162
163@implementation UIView (QtFirstResponder)
164- (UIView*)qt_findFirstResponder
165{
166 if ([self isFirstResponder])
167 return self;
168
169 for (UIView *subview in self.subviews) {
170 if (UIView *firstResponder = [subview qt_findFirstResponder])
171 return firstResponder;
172 }
173
174 return nil;
175}
176@end
177
178@implementation UIResponder (QtFirstResponder)
179
180+ (id)qt_currentFirstResponder
181{
182 if (qt_apple_isApplicationExtension()) {
183 qWarning() << "can't get first responder in application extensions!";
184 return nil;
185 }
186
187 QtFirstResponderEvent *event = [[[QtFirstResponderEvent alloc] init] autorelease];
188 [qt_apple_sharedApplication() sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event];
189 return event.firstResponder;
190}
191
192- (void)qt_findFirstResponder:(id)sender event:(QtFirstResponderEvent *)event
193{
194 Q_UNUSED(sender);
195
196 if ([self isKindOfClass:[UIView class]])
197 event.firstResponder = [static_cast<UIView *>(self) qt_findFirstResponder];
198 else
199 event.firstResponder = [self isFirstResponder] ? self : nil;
200}
201@end
202
203QT_BEGIN_NAMESPACE
204
205FirstResponderCandidate::FirstResponderCandidate(UIResponder *responder)
206 : QScopedValueRollback<UIResponder *>(s_firstResponderCandidate, responder)
207{
208}
209
210UIResponder *FirstResponderCandidate::s_firstResponderCandidate = nullptr;
211
212QT_END_NAMESPACE
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindowScene)
UIView * rootViewForScreen(const QPlatformScreen *)
UIWindow * presentationWindow(QWindow *)
Definition qiosglobal.mm:97
int infoPlistValue(NSString *key, int defaultValue)
Definition qiosglobal.mm:90
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation)
Definition qiosglobal.mm:42
bool isQtApplication()
Definition qiosglobal.mm:21
bool isRunningOnVisionOS()
Definition qiosglobal.mm:32
UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation)
Definition qiosglobal.mm:67
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow)