aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Anderson <scott.anderson@collabora.com>2019-12-04 19:58:38 +1300
committerScott Anderson <scott.anderson@collabora.com>2019-12-04 19:58:38 +1300
commit9af877d3a775763d9199ffa897948f5009bd8a7b (patch)
treefea187efd64b7e32406e512fc34941cf962f0fbf
parenta3433100dccaca03c95bc03fd66939fb4eca6670 (diff)
Add basic support for app switching
-rw-r--r--homescreen/homescreen.pro6
-rw-r--r--homescreen/protocol/agl-shell.xml17
-rw-r--r--homescreen/qml/ShortcutArea.qml5
-rw-r--r--homescreen/src/main.cpp25
-rw-r--r--homescreen/src/shell.cpp35
-rw-r--r--homescreen/src/shell.h44
6 files changed, 117 insertions, 15 deletions
diff --git a/homescreen/homescreen.pro b/homescreen/homescreen.pro
index 0ec86d4..0afb53b 100644
--- a/homescreen/homescreen.pro
+++ b/homescreen/homescreen.pro
@@ -27,7 +27,8 @@ SOURCES += \
src/statusbarmodel.cpp \
src/statusbarserver.cpp \
src/applicationlauncher.cpp \
- src/mastervolume.cpp
+ src/mastervolume.cpp \
+ src/shell.cpp
WAYLANDCLIENTSOURCES += \
protocol/agl-shell.xml
@@ -36,7 +37,8 @@ HEADERS += \
src/statusbarmodel.h \
src/statusbarserver.h \
src/applicationlauncher.h \
- src/mastervolume.h
+ src/mastervolume.h \
+ src/shell.h
OTHER_FILES += \
README.md
diff --git a/homescreen/protocol/agl-shell.xml b/homescreen/protocol/agl-shell.xml
index 59548e7..5e31d98 100644
--- a/homescreen/protocol/agl-shell.xml
+++ b/homescreen/protocol/agl-shell.xml
@@ -96,5 +96,22 @@
<arg name="output" type="object" interface="wl_output"/>
<arg name="edge" type="uint" enum="edge"/>
</request>
+
+ <request name="activate_app">
+ <description summary="make client current window">
+ Asks the compositor to make a toplevel to become the current/focued
+ window for window management purposes.
+
+ See xdg_toplevel.set_app_id from the xdg-shell protocol for a
+ description app_id.
+
+ If multiple toplevels have the same app_id, the result is unspecified.
+
+ XXX: Do we need feedback to say it didn't work? (e.g. client does
+ not exist)
+ </description>
+ <arg name="app_id" type="string"/>
+ <arg name="output" type="object" interface="wl_output"/>
+ </request>
</interface>
</protocol>
diff --git a/homescreen/qml/ShortcutArea.qml b/homescreen/qml/ShortcutArea.qml
index 9e404dc..d470231 100644
--- a/homescreen/qml/ShortcutArea.qml
+++ b/homescreen/qml/ShortcutArea.qml
@@ -18,6 +18,7 @@
import QtQuick 2.2
import QtQuick.Layouts 1.1
+import QtQuick.Window 2.2
Item {
id: root
@@ -25,7 +26,7 @@ Item {
ListModel {
id: applicationModel
ListElement {
- appid: 'launcher'
+ appid: "launcher"
name: 'launcher'
application: 'launcher@0.1'
}
@@ -59,7 +60,7 @@ Item {
name: model.name
active: model.name === launcher.current
onClicked: {
- homescreenHandler.tapShortcut(model.appid)
+ shell.activate_app(Window.window, model.appid)
}
}
}
diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp
index ae1fff8..98cec6f 100644
--- a/homescreen/src/main.cpp
+++ b/homescreen/src/main.cpp
@@ -28,6 +28,7 @@
#include <cstdlib>
#include <cstring>
+#include <memory>
#include <wayland-client.h>
#include <weather.h>
@@ -36,6 +37,7 @@
#include "statusbarmodel.h"
#include "afm_user_daemon_proxy.h"
#include "mastervolume.h"
+#include "shell.h"
#include "hmi-debug.h"
#include "wayland-agl-shell-client-protocol.h"
@@ -77,34 +79,35 @@ static const struct wl_registry_listener registry_listener = {
static struct wl_surface *create_component(QPlatformNativeInterface *native,
QQmlComponent *comp, QScreen *screen)
{
- QObject *obj = comp->create();
- obj->setParent(screen);
+ QObject *obj = comp->create();
+ obj->setParent(screen);
- QWindow *win = qobject_cast<QWindow *>(obj);
- return static_cast<struct wl_surface *>(native->nativeResourceForWindow("surface", win));
+ QWindow *win = qobject_cast<QWindow *>(obj);
+ return static_cast<struct wl_surface *>(native->nativeResourceForWindow("surface", win));
}
int main(int argc, char *argv[])
{
setenv("QT_QPA_PLATFORM", "wayland", 1);
QGuiApplication a(argc, argv);
- QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
struct wl_display *wl;
struct wl_registry *registry;
struct agl_shell *agl_shell = nullptr;
- wl = static_cast<struct wl_display *>(native->nativeResourceForIntegration("display"));
+ wl = static_cast<struct wl_display *>(native->nativeResourceForIntegration("display"));
registry = wl_display_get_registry(wl);
wl_registry_add_listener(registry, &registry_listener, &agl_shell);
// Roundtrip to get all globals advertised by the compositor
wl_display_roundtrip(wl);
wl_registry_destroy(registry);
-
+
if (!agl_shell) {
qFatal("Compositor does not support AGL shell protocol");
return 1;
}
+ std::shared_ptr<struct agl_shell> shell{agl_shell, agl_shell_destroy};
// use launch process
QScopedPointer<org::AGL::afm::user, Cleanup> afm_user_daemon_proxy(new org::AGL::afm::user("org.AGL.afm.user",
@@ -171,7 +174,7 @@ int main(int argc, char *argv[])
QQuickWindow *window = qobject_cast<QQuickWindow *>(root);
for (auto o : root_objects) {
- qDebug() << o->dynamicPropertyNames();
+ qDebug() << o->dynamicPropertyNames();
}
QList<QObject *> sobjs = engine.rootObjects();
@@ -185,6 +188,7 @@ int main(int argc, char *argv[])
context->setContextProperty("launcher", launcher);
context->setContextProperty("weather", new Weather(bindingAddress));
context->setContextProperty("bluetooth", new Bluetooth(bindingAddress, engine.rootContext()));
+ context->setContextProperty("shell", new Shell(shell, &a));
QQmlComponent bg_comp(&engine, QUrl("qrc:/background.qml"));
QQmlComponent top_comp(&engine, QUrl("qrc:/toppanel.qml"));
@@ -206,9 +210,8 @@ int main(int argc, char *argv[])
}
// Delay the ready signal until after Qt has done all of its own setup in a.exec()
- QTimer::singleShot(0, [agl_shell](){
- agl_shell_ready(agl_shell);
- agl_shell_destroy(agl_shell);
+ QTimer::singleShot(0, [shell](){
+ agl_shell_ready(shell.get());
});
return a.exec();
diff --git a/homescreen/src/shell.cpp b/homescreen/src/shell.cpp
new file mode 100644
index 0000000..b4dd98d
--- /dev/null
+++ b/homescreen/src/shell.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 Collabora Ltd.
+ *
+ * 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.
+ */
+
+#include <QGuiApplication>
+#include <QDebug>
+#include "shell.h"
+#include <qpa/qplatformnativeinterface.h>
+#include <stdio.h>
+
+void Shell::activate_app(QWindow *win, const QString &app_id)
+{
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ QScreen *screen = win->screen();
+ struct wl_output *output;
+
+ output = static_cast<struct wl_output *>(native->nativeResourceForScreen(
+ "output", const_cast<QScreen *>(screen)));
+
+ agl_shell_activate_app(this->shell.get(),
+ app_id.toStdString().c_str(),
+ output);
+}
diff --git a/homescreen/src/shell.h b/homescreen/src/shell.h
new file mode 100644
index 0000000..c5e0b18
--- /dev/null
+++ b/homescreen/src/shell.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 Collabora Ltd.
+ *
+ * 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.
+ */
+
+#ifndef SHELLHANDLER_H
+#define SHELLHANDLER_H
+
+#include <QObject>
+#include <QString>
+#include <QScreen>
+#include <QWindow>
+#include <memory>
+#include "wayland-agl-shell-client-protocol.h"
+
+/*
+ * Basic type to wrap the agl_shell wayland object into a QObject, so that it
+ * can be used in callbacks from QML.
+ */
+
+class Shell : public QObject
+{
+ Q_OBJECT
+ std::shared_ptr<struct agl_shell> shell;
+public:
+ Shell(std::shared_ptr<struct agl_shell> shell, QObject *parent = nullptr) :
+ QObject(parent), shell(shell)
+ {}
+public slots:
+ void activate_app(QWindow *win, const QString &app_id);
+};
+
+#endif // SHELLHANDLER_H