blob: a523d1be45ac80848642dbfd9714973b17b80b4f [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qiosglobal.h"
#include "qiosapplicationdelegate.h"
#include "qiosviewcontroller.h"
#include "qiosscreen.h"
#include <QtCore/private/qcore_mac_p.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
bool isQtApplication()
{
if (qt_apple_isApplicationExtension())
return false;
// Returns \c true if the plugin is in full control of the whole application. This means
// that we control the application delegate and the top view controller, and can take
// actions that impacts all parts of the application. The opposite means that we are
// embedded inside a native iOS application, and should be more focused on playing along
// with native UIControls, and less inclined to change structures that lies outside the
// scope of our QWindows/UIViews.
static bool isQt = ([qt_apple_sharedApplication().delegate isKindOfClass:[QIOSApplicationDelegate class]]);
return isQt;
}
#ifndef Q_OS_TVOS
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation)
{
Qt::ScreenOrientation qtOrientation;
switch (uiDeviceOrientation) {
case UIDeviceOrientationPortraitUpsideDown:
qtOrientation = Qt::InvertedPortraitOrientation;
break;
case UIDeviceOrientationLandscapeLeft:
qtOrientation = Qt::LandscapeOrientation;
break;
case UIDeviceOrientationLandscapeRight:
qtOrientation = Qt::InvertedLandscapeOrientation;
break;
case UIDeviceOrientationFaceUp:
case UIDeviceOrientationFaceDown:
qWarning("Falling back to Qt::PortraitOrientation for UIDeviceOrientationFaceUp/UIDeviceOrientationFaceDown");
qtOrientation = Qt::PortraitOrientation;
break;
default:
qtOrientation = Qt::PortraitOrientation;
break;
}
return qtOrientation;
}
UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation)
{
UIDeviceOrientation uiOrientation;
switch (qtOrientation) {
case Qt::LandscapeOrientation:
uiOrientation = UIDeviceOrientationLandscapeLeft;
break;
case Qt::InvertedLandscapeOrientation:
uiOrientation = UIDeviceOrientationLandscapeRight;
break;
case Qt::InvertedPortraitOrientation:
uiOrientation = UIDeviceOrientationPortraitUpsideDown;
break;
case Qt::PrimaryOrientation:
case Qt::PortraitOrientation:
default:
uiOrientation = UIDeviceOrientationPortrait;
break;
}
return uiOrientation;
}
#endif
int infoPlistValue(NSString* key, int defaultValue)
{
static NSBundle *bundle = [NSBundle mainBundle];
NSNumber* value = [bundle objectForInfoDictionaryKey:key];
return value ? [value intValue] : defaultValue;
}
QT_END_NAMESPACE
// -------------------------------------------------------------------------
@interface QtFirstResponderEvent : UIEvent
@property (nonatomic, strong) id firstResponder;
@end
@implementation QtFirstResponderEvent
- (void)dealloc
{
self.firstResponder = 0;
[super dealloc];
}
@end
@implementation UIView (QtFirstResponder)
- (UIView*)qt_findFirstResponder
{
if ([self isFirstResponder])
return self;
for (UIView *subview in self.subviews) {
if (UIView *firstResponder = [subview qt_findFirstResponder])
return firstResponder;
}
return nil;
}
@end
@implementation UIResponder (QtFirstResponder)
+ (id)currentFirstResponder
{
if (qt_apple_isApplicationExtension()) {
qWarning() << "can't get first responder in application extensions!";
return nil;
}
QtFirstResponderEvent *event = [[[QtFirstResponderEvent alloc] init] autorelease];
[qt_apple_sharedApplication() sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event];
return event.firstResponder;
}
- (void)qt_findFirstResponder:(id)sender event:(QtFirstResponderEvent *)event
{
Q_UNUSED(sender);
if ([self isKindOfClass:[UIView class]])
event.firstResponder = [static_cast<UIView *>(self) qt_findFirstResponder];
else
event.firstResponder = [self isFirstResponder] ? self : nil;
}
@end
QT_BEGIN_NAMESPACE
FirstResponderCandidate::FirstResponderCandidate(UIResponder *responder)
: QScopedValueRollback<UIResponder *>(s_firstResponderCandidate, responder)
{
}
UIResponder *FirstResponderCandidate::s_firstResponderCandidate = 0;
QT_END_NAMESPACE