diff options
-rw-r--r-- | sample/app/app.pro | 9 | ||||
-rw-r--r-- | sample/app/eventhandler.cpp | 114 | ||||
-rw-r--r-- | sample/app/eventhandler.h | 9 | ||||
-rw-r--r-- | sample/app/main.qml | 12 | ||||
-rw-r--r-- | sample/app/protocol/agl-shell-desktop.xml | 96 |
5 files changed, 228 insertions, 12 deletions
diff --git a/sample/app/app.pro b/sample/app/app.pro index c72fd28..5710f3b 100644 --- a/sample/app/app.pro +++ b/sample/app/app.pro @@ -14,10 +14,11 @@ # limitations under the License. TARGET = onstestapp -QT = quick quickcontrols2 qml +QT = quick quickcontrols2 qml gui-private -CONFIG += c++11 link_pkgconfig -PKGCONFIG += qlibwindowmanager qlibhomescreen +CONFIG += c++11 link_pkgconfig wayland-scanner pkgdatadir +#PKGCONFIG += qlibwindowmanager qlibhomescreen +PKGCONFIG += wayland-client DESTDIR = $${OUT_PWD}/../package/root/bin SOURCES = main.cpp \ @@ -31,3 +32,5 @@ HEADERS += \ LIBS += -ljson-c +WAYLANDCLIENTSOURCES += \ + protocol/agl-shell-desktop.xml diff --git a/sample/app/eventhandler.cpp b/sample/app/eventhandler.cpp index 4e55619..388291f 100644 --- a/sample/app/eventhandler.cpp +++ b/sample/app/eventhandler.cpp @@ -16,39 +16,128 @@ #include <functional> #include <QUrl> +#include <QGuiApplication> #include <QJsonDocument> #include <QJsonObject> #include <QQuickWindow> -//#include <QtQml/QQmlContext> +#include <QtQml/QQmlContext> #include <QQmlContext> #include <QtQml/QQmlApplicationEngine> +#include <qpa/qplatformnativeinterface.h> + #include "eventhandler.h" +static struct wl_output * +getWlOutput(QScreen *screen) +{ + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + void *output = native->nativeResourceForScreen("output", screen); + return static_cast<struct ::wl_output*>(output); +} + +static void +global_add(void *data, struct wl_registry *reg, uint32_t name, + const char *interface, uint32_t version) +{ + struct agl_shell_desktop **shell = + static_cast<struct agl_shell_desktop **>(data); + + if (strcmp(interface, agl_shell_desktop_interface.name) == 0) { + *shell = static_cast<struct agl_shell_desktop *>( + wl_registry_bind(reg, name, &agl_shell_desktop_interface, version) + ); + } +} + +static void global_remove(void *data, struct wl_registry *reg, uint32_t id) +{ + (void) data; + (void) reg; + (void) id; +} + +static const struct wl_registry_listener registry_listener = { + global_add, + global_remove, +}; + +static void +application_id_event(void *data, struct agl_shell_desktop *agl_shell_desktop, + const char *app_id) +{ + EventHandler *ev_handler = static_cast<EventHandler *>(data); + (void) agl_shell_desktop; + + // should probably add here to a list the application or trigger emit + // for QML code, also note that we get here our own application + if (strcmp(app_id, APP_ID) == 0) + return; + + qInfo() << "app_id: " << app_id; + + if (strcmp(app_id, "onescreenapp") == 0) + emit ev_handler->signalOnReplyShowWindow(app_id); +} + +static const struct agl_shell_desktop_listener agl_shell_desk_listener = { + application_id_event, +}; + +static struct agl_shell_desktop * +register_agl_shell_desktop(void) +{ + struct wl_display *wl; + struct wl_registry *registry; + struct agl_shell_desktop *shell = nullptr; + + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + + wl = static_cast<struct wl_display *>(native->nativeResourceForIntegration("display")); + registry = wl_display_get_registry(wl); + + wl_registry_add_listener(registry, ®istry_listener, &shell); + // Roundtrip to get all globals advertised by the compositor + wl_display_roundtrip(wl); + wl_registry_destroy(registry); + + return shell; +} + + void* EventHandler::myThis = 0; const char _drawing_name[] = "drawing_name"; EventHandler::EventHandler(QObject *parent) : - QObject(parent), - mp_hs(NULL), - mp_wm(NULL), - mp_qw(NULL) + QObject(parent), mp_qw(NULL) { } EventHandler::~EventHandler() { +#if 0 if (mp_hs != NULL) { delete mp_hs; } if (mp_wm != NULL) { delete mp_wm; } +#endif + if (shell_desktop) + agl_shell_desktop_destroy(shell_desktop); } void EventHandler::init(int port, const char *token) { + (void) port; + (void) token; + + shell_desktop = register_agl_shell_desktop(); + if (shell_desktop) + agl_shell_desktop_add_listener(shell_desktop, &agl_shell_desk_listener, this); + +#if 0 myThis = this; mp_wm = new QLibWindowmanager(); mp_wm->init(port, token); @@ -95,23 +184,36 @@ void EventHandler::init(int port, const char *token) }); HMI_DEBUG(APP_ID, "LayoutHander::init() finished."); +#endif } void EventHandler::setQuickWindow(QQuickWindow *qw) { mp_qw = qw; - QObject::connect(mp_qw, SIGNAL(frameSwapped()), mp_wm, SLOT(slotActivateSurface())); + //QObject::connect(mp_qw, SIGNAL(frameSwapped()), mp_wm, SLOT(slotActivateSurface())); } void EventHandler::showWindow(QString id, QString json) { + if (shell_desktop) { + struct wl_output *output = getWlOutput(qApp->screens().first()); + agl_shell_desktop_activate_app(shell_desktop, id.toStdString().c_str(), output); + } + + qInfo() << "data from json: " << json.toStdString().c_str(); +#if 0 if(json.isNull()) mp_hs->tapShortcut(id); else mp_hs->showWindow(id.toStdString().c_str(), json_tokener_parse(json.toStdString().c_str())); +#endif } void EventHandler::hideWindow(QString id) { + if (shell_desktop) + agl_shell_desktop_deactivate_app(shell_desktop, id.toStdString().c_str()); +#if 0 mp_hs->hideWindow(id.toStdString().c_str()); +#endif } diff --git a/sample/app/eventhandler.h b/sample/app/eventhandler.h index af66644..c57c806 100644 --- a/sample/app/eventhandler.h +++ b/sample/app/eventhandler.h @@ -21,8 +21,14 @@ #include <string> #include <QVariant> +#if 0 #include <qlibhomescreen.h> #include <qlibwindowmanager.h> +#endif + +#include <wayland-client.h> +#include "wayland-agl-shell-desktop-client-protocol.h" + #include "hmi-debug.h" #define ROLE_NAME "onstestapp" @@ -51,8 +57,11 @@ signals: void signalOnReplyShowWindow(QVariant val); private: +#if 0 QLibHomeScreen *mp_hs; QLibWindowmanager* mp_wm; +#endif + struct agl_shell_desktop *shell_desktop = nullptr; QQuickWindow *mp_qw; }; diff --git a/sample/app/main.qml b/sample/app/main.qml index b9f415b..4d23921 100644 --- a/sample/app/main.qml +++ b/sample/app/main.qml @@ -7,8 +7,8 @@ import AGL.Demo.Controls 1.0 ApplicationWindow { id: root visible: true - width: 1080 - height: 1487 + width: Screen.width + height: Screen.height property string onsId: qsTr("onscreenapp") property string onsTitle: qsTr("One Button title") @@ -339,7 +339,13 @@ ApplicationWindow { else postmsg += "}" - eventHandler.showWindow(onsId, postmsg); + // if the application is not already started, start it + // if the application is not started, the first time we start + // it will by shown by default + eventHandler.start(onsId, postmsg) + + // we just need to display + eventHandler.showWindow(onsId, postmsg) } function qmlOnReplyShowWindow(text) { diff --git a/sample/app/protocol/agl-shell-desktop.xml b/sample/app/protocol/agl-shell-desktop.xml new file mode 100644 index 0000000..6d53f92 --- /dev/null +++ b/sample/app/protocol/agl-shell-desktop.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="agl_shell_desktop"> + <copyright> + Copyright © 2020 Collabora, Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + </copyright> + <interface name="agl_shell_desktop" version="1"> + <description summary="Private extension to allow applications activate other apps"> + This extension can be used by regular application to instruct to compositor + to activate or switch to other running (regular) applications. The client + is responsbile for filtering their own app_id when receiving application id. + + Note that other (regular) applications can bind to this interface and there is + no mechanism to place to restrict or limit that. + </description> + + <enum name="app_role"> + <entry name="popup" value="0"/> + <entry name="fullscreen" value="1"/> + </enum> + + <event name="application"> + <description summary="advertise application id"> + The compositor may choose to advertise one or more application ids which + can be used to activate/switch to. + + When this global is bound, the compositor will send all application ids + available for activation, but may send additional application id at any + time (when they've been mapped in the compositor). + </description> + <arg name="app_id" type="string"/> + </event> + + <request name="activate_app"> + <description summary="make client current window"> + Ask the compositor to make a toplevel to become the current/focused + window for window management purposes. + + See xdg_toplevel.set_app_id from the xdg-shell protocol for a + description of app_id. + </description> + <arg name="app_id" type="string"/> + <arg name="output" type="object" interface="wl_output"/> + </request> + + <request name="set_app_property"> + <description summary="set properties for a client identified by app_id"> + Ask the compositor to make a toplevel obey the app_role and, depending + on the role, to use the the x and y values as initial positional values. + The x and y values would only make sense for certain roles. + + See xdg_toplevel.set_app_id from the xdg-shell protocol for a + description of app_id. + </description> + <arg name="app_id" type="string"/> + <arg name="role" type="uint" enum="app_role"/> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="output" type="object" interface="wl_output"/> + </request> + + <request name="deactivate_app"> + <description summary="de-activate/hide window identified by app_id"> + Ask the compositor to hide the toplevel window for window + management purposes. Depending on the window role, this request + will either display the previously active window (or the background + in case there's no previously activate surface) or temporarly (or + until a 'activate_app' is called upon) hide the surface. All + the surfaces are identifiable by using the app_id, and no actions are + taken in case the app_id is not/was not present. + + See xdg_toplevel.set_app_id from the xdg-shell protocol for a + description of app_id. + </description> + <arg name="app_id" type="string"/> + </request> + </interface> +</protocol> |