src/statusbarmodel.cpp \
src/statusbarserver.cpp \
src/applicationlauncher.cpp \
- src/mastervolume.cpp
+ src/mastervolume.cpp \
+ src/shell.cpp
WAYLANDCLIENTSOURCES += \
protocol/agl-shell.xml
src/statusbarmodel.h \
src/statusbarserver.h \
src/applicationlauncher.h \
- src/mastervolume.h
+ src/mastervolume.h \
+ src/shell.h
OTHER_FILES += \
README.md
<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>
import QtQuick 2.2
import QtQuick.Layouts 1.1
+import QtQuick.Window 2.2
Item {
id: root
ListModel {
id: applicationModel
ListElement {
- appid: 'launcher'
+ appid: "launcher"
name: 'launcher'
application: 'launcher@0.1'
}
name: model.name
active: model.name === launcher.current
onClicked: {
- homescreenHandler.tapShortcut(model.appid)
+ shell.activate_app(Window.window, model.appid)
}
}
}
#include <cstdlib>
#include <cstring>
+#include <memory>
#include <wayland-client.h>
#include <weather.h>
#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"
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, ®istry_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",
QQuickWindow *window = qobject_cast<QQuickWindow *>(root);
for (auto o : root_objects) {
- qDebug() << o->dynamicPropertyNames();
+ qDebug() << o->dynamicPropertyNames();
}
QList<QObject *> sobjs = engine.rootObjects();
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"));
}
// 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();
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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