PoC: Qt Compositor-ized homescreen 25/9525/1 sandbox/tasuku/qt-compositor-ized
authorTasuku Suzuki <tasuku.suzuki@qt.io>
Fri, 26 May 2017 02:09:59 +0000 (11:09 +0900)
committerTasuku Suzuki <tasuku.suzuki@qt.io>
Fri, 26 May 2017 02:13:16 +0000 (11:13 +0900)
Change-Id: Icec91030f8f4a8bf001b30ba9b7547751abfafed
Signed-off-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
homescreen/qml/Home.qml
homescreen/qml/ShortcutArea.qml
homescreen/qml/SystemUI.qml [new file with mode: 0644]
homescreen/qml/main.qml
homescreen/qml/qml.qrc
homescreen/src/applicationmodel.cpp
homescreen/src/main.cpp

index a312670..7effe19 100644 (file)
@@ -54,17 +54,7 @@ Item {
             onPressAndHold: currentId = applicationModel.id(newIndex = index)
             onReleased: {
                 if (currentId === '') {
-                    pid = launcher.launch(applicationModel.id(loc.index))
-                    if (1 < pid) {
-                        layoutHandler.makeMeVisible(pid)
-
-                        applicationArea.visible = true
-                        appLauncherAreaLauncher.visible = false
-                        layoutHandler.showAppLayer(pid)
-                    }
-                    else {
-                        console.warn("app cannot be launched!")
-                    }
+                    launcher.show(applicationModel.id(loc.index))
                 } else {
                     currentId = ''
                 }
index 14c7b6b..bdbd59a 100644 (file)
@@ -57,24 +57,8 @@ Item {
                 name: model.name
                 active: model.application === launcher.current
                 onClicked: {
-                    if (0 === model.index) {
-                        appLauncherAreaLauncher.visible = true
-                        applicationArea.visible = false
-                        layoutHandler.hideAppLayer()
-                        launcher.current = ''
-                    }
-                    else {
-                        pid = launcher.launch(model.application)
-                        if (1 < pid) {
-                            applicationArea.visible = true
-                            appLauncherAreaLauncher.visible = false
-                            layoutHandler.makeMeVisible(pid)
-                            layoutHandler.showAppLayer(pid)
-                        }
-                        else {
-                            console.warn("app cannot be launched!")
-                        }
-                    }
+                    if (model.index < 3) // disable navi to launch
+                        launcher.show(model.index === 0 ? '' : model.application)
                 }
             }
         }
diff --git a/homescreen/qml/SystemUI.qml b/homescreen/qml/SystemUI.qml
new file mode 100644 (file)
index 0000000..1e1c6be
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2016 The Qt Company Ltd.
+ * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import QtQuick 2.2
+import QtQuick.Window 2.1
+import QtQuick.Layouts 1.1
+import QtQuick.Controls 2.1
+import QtWayland.Compositor 1.0
+import HomeScreen 1.0
+import QtGraphicalEffects 1.0
+
+Window {
+    id: root
+    visible: true
+    flags: Qt.FramelessWindowHint
+    width: container.width * container.scale
+    height: container.height * container.scale
+    title: 'HomeScreen'
+    property alias applicationStack: applicationStack
+
+    property var app2item: new Object
+    property string appLaunching
+
+    Component {
+        id: chrome
+        ShellSurfaceItem {
+            onSurfaceDestroyed: destroy()
+        }
+    }
+
+    function show(shellSurface) {
+        var a2i = root.app2item
+        var item = chrome.createObject(root, {"shellSurface": shellSurface})
+        a2i[appLaunching] = item
+        root.app2item = a2i
+        shellSurface.sendConfigure(Qt.size(applicationStack.width, applicationStack.height), WlShellSurface.NoneEdge)
+        if (applicationStack.depth == 1) {
+            applicationStack.push(item)
+        } else {
+            applicationStack.replace(item)
+        }
+        appLaunching = ''
+    }
+
+    ApplicationLauncher {
+        id: launcher
+
+        function show(app) {
+            if (current === app) return
+            if (app.length > 0) {
+                if (root.appLaunching.length > 0)
+                    return
+                if (app2item[app]) {
+                    if (applicationStack.depth == 1) {
+                        applicationStack.push(app2item[app])
+                    } else {
+                        applicationStack.replace(app2item[app])
+                    }
+                    current = app
+                } else {
+                    root.appLaunching = app
+                    if (launch(app) < 0) {
+                        root.appLaunching = ''
+                    }
+                }
+            } else if (applicationStack.depth > 1) {
+                applicationStack.pop()
+                current = ''
+            }
+        }
+    }
+
+    Component {
+        id: home
+        Home {
+            width: parent.width
+            height: parent.height
+        }
+    }
+
+    Transition {
+        id: inTransition
+        NumberAnimation {
+            properties: "opacity, scale"
+            from: 0
+            to:1
+            duration: 250
+        }
+    }
+    Transition {
+        id: outTransition
+        NumberAnimation {
+            properties: "opacity"
+            from: 1
+            to:0
+            duration: 250
+        }
+        NumberAnimation {
+            properties: "scale"
+            from: 1
+            to:5
+            duration: 250
+        }
+    }
+
+    Image {
+        id: container
+        anchors.centerIn: parent
+        width: 1080
+        height: 1920
+        rotation: 270
+        source: './images/AGL_HMI_Background_NoCar-01.png'
+
+        ColumnLayout {
+            anchors.fill: parent
+            spacing: 0
+            TopArea {
+                id: topArea
+                Layout.fillWidth: true
+                Layout.preferredHeight: 218
+            }
+
+            Item {
+                id: applicationArea
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+                Layout.preferredHeight: 1920 - 218 - 215
+                clip: true
+                StackView {
+                    id: applicationStack
+                    anchors.fill: parent
+                    initialItem: home
+
+                    pushEnter: inTransition
+                    pushExit: outTransition
+                    replaceEnter: inTransition
+                    replaceExit: outTransition
+                    popEnter: inTransition
+                    popExit: outTransition
+                }
+            }
+
+            MediaArea {
+                id: mediaArea
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+                Layout.preferredHeight: 215
+                MouseArea {
+                    z: 100
+                    anchors.fill: parent
+                    onClicked: {
+                        notificationLayer.shown = true
+                    }
+                }
+            }
+        }
+    }
+
+    MouseArea {
+        id: notificationLayer
+        property bool shown: false
+        anchors.fill: container
+        scale: container.scale
+        visible: opacity > 0
+        opacity: 0
+        rotation: 270
+        z: 100
+
+        onClicked: shown = false
+
+        Rectangle {
+            anchors.fill: parent
+            color: 'black'
+            opacity: 0.75
+        }
+
+        states: [
+            State {
+                name: "notify"
+                when: notificationLayer.shown
+                PropertyChanges {
+                    target: notificationLayer
+                    opacity: 1.0
+                }
+                PropertyChanges {
+                    target: timer
+                    running: true
+                }
+            }
+        ]
+
+        transitions: [
+            Transition {
+                NumberAnimation {
+                    properties: 'opacity'
+                    duration: 250
+                    easing.type: Easing.OutExpo
+                }
+            }
+        ]
+
+        Column {
+            anchors.centerIn: parent
+            spacing: 20
+            Rectangle {
+                width: 600
+                height: 250
+                radius: 20
+                color: 'white'
+
+                Label {
+                    anchors.centerIn: parent
+                    text: "Message 1"
+                    font.pixelSize: 96
+                    color: 'blue'
+                    antialiasing: true
+                }
+            }
+            Rectangle {
+                width: 600
+                height: 250
+                radius: 20
+                color: 'white'
+
+                Label {
+                    anchors.centerIn: parent
+                    text: "Restart"
+                    font.pixelSize: 96
+                    color: 'red'
+                    antialiasing: true
+                    MouseArea {
+                        anchors.fill: parent
+                        onClicked: Qt.quit()
+                    }
+                }
+            }
+            Timer {
+                id: timer
+                interval: 3000
+                onTriggered: notificationLayer.shown = false
+            }
+        }
+    }
+}
index 11bd9d5..86b3ee9 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2016 The Qt Company Ltd.
- * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH
+ * Copyright (C) 2017 The Qt Company Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-import QtQuick 2.2
+import QtQuick 2.6
 import QtQuick.Window 2.1
-import QtQuick.Layouts 1.1
-import HomeScreen 1.0
-
-Window {
-    visible: true
-    flags: Qt.FramelessWindowHint
-    width: container.width * container.scale
-    height: container.height * container.scale
-    title: 'HomeScreen'
-
-    ApplicationLauncher {
-        id: launcher
+import QtWayland.Compositor 1.0
+
+WaylandCompositor {
+    id: compositor
+
+    WaylandOutput {
+        id: screen
+        compositor: compositor
+        sizeFollowsWindow: true
+        transform: WaylandOutput.Transform90
+        window: SystemUI {
+            id: systemUI
+        }
     }
 
-    Image {
-        id: container
-        anchors.centerIn: parent
-        width: 1080
-        height: 1920
-        scale: 1.0
-        source: './images/AGL_HMI_Background_NoCar-01.png'
-
-        ColumnLayout {
-            anchors.fill: parent
-            spacing: 0
-            TopArea {
-                id: topArea
-                Layout.fillWidth: true
-                Layout.preferredHeight: 218
-            }
-
-            Item {
-                id: applicationArea
-                Layout.fillWidth: true
-                Layout.fillHeight: true
-                Layout.preferredHeight: 1920 - 218 - 215
-
-                visible: false
-            }
-
-            Home {
-                id: appLauncherAreaLauncher
-                Layout.fillWidth: true
-                Layout.fillHeight: true
-                Layout.preferredHeight: 1920 - 218 - 215
-                visible: true
-            }
-
-            MediaArea {
-                id: mediaArea
-                Layout.fillWidth: true
-                Layout.fillHeight: true
-                Layout.preferredHeight: 215
-            }
-        }
+    WlShell {
+        onWlShellSurfaceCreated: systemUI.show(shellSurface)
     }
 }
index c25e266..1f69726 100644 (file)
@@ -11,5 +11,6 @@
         <file>StatusArea.qml</file>
         <file>TopArea.qml</file>
         <file>IconItem.qml</file>
+        <file>SystemUI.qml</file>
     </qresource>
 </RCC>
index 417bc4c..c940149 100644 (file)
@@ -54,10 +54,19 @@ ApplicationModel::Private::Private()
 {
     QString apps = afm_user_daemon_proxy->runnables(QStringLiteral(""));
     QJsonDocument japps = QJsonDocument::fromJson(apps.toUtf8());
+    // disable apps which don't work with the compositor right now
+    QStringList notShow = {
+        "navigation@0.1"
+        , "phone@0.1"
+        , "controls@0.1"
+        , "poi@0.1"
+        , "mixer@0.1"
+    };
     for (auto const &app : japps.array()) {
         QJsonObject const &jso = app.toObject();
         auto const name = jso["name"].toString();
         auto const id = jso["id"].toString();
+        if (notShow.contains(id)) continue;
         auto const icon = get_icon_name(jso);
         this->data.append(AppInfo(icon, name, id));
         qDebug() << "name:" << name << "icon:" << icon << "id:" << id;
index 215e7c6..7eba5bb 100644 (file)
@@ -52,7 +52,11 @@ void noOutput(QtMsgType, const QMessageLogContext &, const QString &)
 
 int main(int argc, char *argv[])
 {
-    QGuiApplication a(argc, argv);
+    qputenv("QT_QPA_PLATFORM", "eglfs");
+    qputenv("QT_QPA_EGLFS_INTEGRATION","eglfs_kms");
+    qputenv("QT_QPA_EGLFS_KMS_CONFIG","/home/root/kmsconfig");
+
+    QGuiApplication app(argc, argv);
 
     QScopedPointer<org::AGL::afm::user, Cleanup> afm_user_daemon_proxy(new org::AGL::afm::user("org.AGL.afm.user",
                                                                                                "/org/AGL/afm/user",
@@ -72,7 +76,7 @@ int main(int argc, char *argv[])
     QCommandLineOption quietOption(QStringList() << "q" << "quiet",
         QCoreApplication::translate("main", "Be quiet. No outputs."));
     parser.addOption(quietOption);
-    parser.process(a);
+    parser.process(app);
 
     if (parser.isSet(quietOption))
     {
@@ -118,5 +122,6 @@ int main(int argc, char *argv[])
     // Initalize PA client
     client->init();
 
-    return a.exec();
+    QObject::connect(&engine, &QQmlApplicationEngine::quit, &app, &QGuiApplication::quit);
+    return app.exec();
 }