File indexing completed on 2024-12-22 05:25:49

0001 /*
0002  * Copyright 2018 by Marco Martin <mart@kde.org>
0003  * Copyright 2018 David Edmundson <davidedmundson@kde.org>
0004  *
0005  * Licensed under the Apache License, Version 2.0 (the "License");
0006  * you may not use this file except in compliance with the License.
0007  * You may obtain a copy of the License at
0008  *
0009  *    http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  *
0017  */
0018 
0019 #include <QQuickView>
0020 #include <QCommandLineParser>
0021 #include <QCommandLineOption>
0022 #include <QQmlContext>
0023 #include <QtQml>
0024 #include <QDebug>
0025 #include <QCursor>
0026 #include <QtWebView/QtWebView>
0027 
0028 #ifdef Q_OS_ANDROID
0029 #include <QGuiApplication>
0030 #include <QtAndroid>
0031 #define FLAG_TRANSLUCENT_STATUS 0x04000000
0032 #define FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 0x80000000
0033 #include "keyfilter.h"
0034 #else
0035 #include <QApplication>
0036 #include <KDBusService>
0037 #endif
0038 
0039 #include "speechintent.h"
0040 #include "appsettings.h"
0041 #include "version.h"
0042 
0043 int main(int argc, char *argv[])
0044 {
0045     //QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
0046 
0047     QStringList arguments;
0048     for (int a = 0; a < argc; ++a) {
0049         arguments << QString::fromLocal8Bit(argv[a]);
0050     }
0051 
0052     QCommandLineParser parser;
0053 
0054     auto widthOption = QCommandLineOption(QStringLiteral("width"), QStringLiteral("Width of the screen"), QStringLiteral("width"));
0055     auto heightOption = QCommandLineOption(QStringLiteral("height"), QStringLiteral("Height of the screen"), QStringLiteral("height"));
0056     auto hideTextInputOption = QCommandLineOption(QStringLiteral("hideTextInput"), QStringLiteral("Hide the input box"));
0057     auto dpiOption = QCommandLineOption(QStringLiteral("dpi"), QStringLiteral("dpi"), QStringLiteral("dpi"));
0058     auto skillOption = QCommandLineOption(QStringLiteral("skill"), QStringLiteral("Single skill to load"), QStringLiteral("skill"));
0059     auto maximizeOption = QCommandLineOption(QStringLiteral("maximize"), QStringLiteral("When set, start maximized."));
0060     auto rotateScreen = QCommandLineOption(QStringLiteral("rotateScreen"), QStringLiteral("When set, rotate the screen by set degrees."), QStringLiteral("degrees"));
0061     auto helpOption = QCommandLineOption(QStringLiteral("help"), QStringLiteral("Show this help message"));
0062     parser.addOptions({widthOption, heightOption, hideTextInputOption, skillOption,
0063                        dpiOption, maximizeOption,
0064                        rotateScreen, helpOption});
0065     parser.process(arguments);
0066 
0067 
0068     qputenv("QT_WAYLAND_FORCE_DPI", parser.value(dpiOption).toLatin1());
0069 
0070     QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
0071     QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
0072 
0073 #ifdef Q_OS_ANDROID
0074     QGuiApplication app(argc, argv);
0075 #else
0076     QApplication app(argc, argv);
0077 #endif
0078 
0079     app.setApplicationName(QStringLiteral("mycroft.gui"));
0080     app.setOrganizationDomain(QStringLiteral("kde.org"));
0081     app.setWindowIcon(QIcon::fromTheme(QStringLiteral("mycroft")));
0082     
0083 #ifdef Q_OS_ANDROID
0084     KeyFilter *kf = new KeyFilter;
0085     app.installEventFilter(kf);
0086 #endif
0087 
0088     // NOTE: Have to manually implement a --help option because the parser.addHelpOption() would
0089     //       be triggered at parser.process() time, but it requires the QApplication. But the
0090     //       'dpi' option for the GUI creates a chicken-and-the-egg issue.
0091     if (parser.isSet(helpOption)) {
0092         parser.showHelp();
0093         return 0;
0094     }
0095     QtWebView::initialize();
0096 
0097     QQuickView view;
0098     view.setResizeMode(QQuickView::SizeRootObjectToView);
0099     int width = parser.value(widthOption).toInt();
0100     int height = parser.value(heightOption).toInt();
0101     int rotation = parser.value(rotateScreen).toInt();
0102     bool maximize = parser.isSet(maximizeOption);
0103 
0104     QQmlApplicationEngine engine;
0105     engine.rootContext()->setContextProperty(QStringLiteral("deviceWidth"), width);
0106     engine.rootContext()->setContextProperty(QStringLiteral("deviceHeight"), height);
0107     engine.rootContext()->setContextProperty(QStringLiteral("deviceMaximized"), maximize);
0108     engine.rootContext()->setContextProperty(QStringLiteral("hideTextInput"), parser.isSet(hideTextInputOption));
0109     engine.rootContext()->setContextProperty(QStringLiteral("globalScreenRotation"), parser.isSet(rotateScreen) ? rotation : 0);
0110     engine.rootContext()->setContextProperty(QStringLiteral("versionNumber"), QStringLiteral(mycroftguiapp_VERSION_STRING));
0111     
0112 #ifdef Q_OS_ANDROID
0113     engine.rootContext()->setContextProperty(QStringLiteral("keyFilter"), kf);
0114     engine.rootContext()->setContextProperty(QStringLiteral("isAndroid"), true);
0115 #else
0116     engine.rootContext()->setContextProperty(QStringLiteral("keyFilter"), 0);
0117     engine.rootContext()->setContextProperty(QStringLiteral("isAndroid"), false);
0118 #endif
0119 
0120     QString singleSkill = parser.value(skillOption);
0121     if (singleSkill.endsWith(QStringLiteral(".home"))) {
0122         singleSkill = singleSkill.left(singleSkill.indexOf(QStringLiteral(".home")));
0123         engine.rootContext()->setContextProperty(QStringLiteral("singleSkill"), singleSkill);
0124         engine.rootContext()->setContextProperty(QStringLiteral("singleSkillHome"), parser.value(skillOption));
0125     } else {
0126         engine.rootContext()->setContextProperty(QStringLiteral("singleSkill"), singleSkill);
0127         engine.rootContext()->setContextProperty(QStringLiteral("singleSkillHome"), QString());
0128     }
0129 
0130 #ifndef Q_OS_ANDROID
0131     if (parser.isSet(skillOption)) {
0132         app.setApplicationName(QStringLiteral("mycroft.gui.") + singleSkill);
0133         KDBusService service(KDBusService::Unique);
0134     }
0135 #endif
0136 
0137     AppSettings *appSettings = new AppSettings(&view);
0138     engine.rootContext()->setContextProperty(QStringLiteral("applicationSettings"), appSettings);
0139 
0140     qmlRegisterType<SpeechIntent>("org.kde.private.mycroftgui", 1, 0, "SpeechIntent");
0141 
0142     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
0143 
0144 #ifdef Q_OS_ANDROID
0145     QtAndroid::runOnAndroidThread([=]() {
0146         QAndroidJniObject window = QtAndroid::androidActivity().callObjectMethod("getWindow", "()Landroid/view/Window;");
0147         window.callMethod<void>("addFlags", "(I)V", FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
0148         window.callMethod<void>("clearFlags", "(I)V", FLAG_TRANSLUCENT_STATUS);
0149         window.callMethod<void>("setStatusBarColor", "(I)V", QColor("#303030").rgba());
0150         window.callMethod<void>("setNavigationBarColor", "(I)V", QColor("#303030").rgba());
0151     });
0152 #endif
0153     
0154     return app.exec();
0155 }