diff options
author | Arnaud Ferraris <arnaud.ferraris@collabora.com> | 2022-01-18 12:52:43 +0100 |
---|---|---|
committer | Arnaud Ferraris <arnaud.ferraris@collabora.com> | 2022-01-20 17:25:38 +0100 |
commit | a3c4beb8a9d1a01a4a29434e8319be7ce3f0d42f (patch) | |
tree | f3e10f66b51ae1064e91275f3920e0a1e2258a38 | |
parent | 20970d846906a070305d8e96cf0735bf7fd831b1 (diff) |
Use agl-shell-desktop protocol to keep track of closed windows
Currently, we have no way of knowing when the main window of an
application is closed unless this action terminates the app. Hooking up
the `agl-shell-desktop` protocol allows us to be notified when this
happens, so we can instruct `homescreenhandler` to switch back to the
previously active app.
Bug-AGL: SPEC-4222
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
Change-Id: I26dfaccce8894c2599afd9b14349b0703727d47a
-rw-r--r-- | homescreen/homescreen.pro | 2 | ||||
-rw-r--r-- | homescreen/src/main.cpp | 85 |
2 files changed, 68 insertions, 19 deletions
diff --git a/homescreen/homescreen.pro b/homescreen/homescreen.pro index 3f94c11..80f0f49 100644 --- a/homescreen/homescreen.pro +++ b/homescreen/homescreen.pro @@ -52,7 +52,7 @@ RESOURCES += \ qml/qml.qrc AGL_SHELL_PATH = $$system(pkg-config --variable=pkgdatadir agl-compositor-0.0.20-protocols) -WAYLANDCLIENTSOURCES += $$AGL_SHELL_PATH/agl-shell.xml +WAYLANDCLIENTSOURCES += $$AGL_SHELL_PATH/agl-shell.xml $$AGL_SHELL_PATH/agl-shell-desktop.xml target.path = $${PREFIX}/usr/bin target.files += $${OUT_PWD}/$${TARGET} diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp index 75ed97c..cf7f02e 100644 --- a/homescreen/src/main.cpp +++ b/homescreen/src/main.cpp @@ -40,19 +40,64 @@ #include <wayland-client.h> #include "wayland-agl-shell-client-protocol.h" +#include "wayland-agl-shell-desktop-client-protocol.h" #include "shell.h" +struct shell_data { + struct agl_shell *shell; + struct agl_shell_desktop *shell_desktop; +}; + +static void +agl_shell_desktop_application(void *data, + struct agl_shell_desktop *agl_shell_desktop, + const char *app_id) +{ + HomescreenHandler *homescreenHandler = static_cast<HomescreenHandler *>(data); + + if (homescreenHandler) + homescreenHandler->addAppToStack(app_id); +} + +static void +agl_shell_desktop_state_app(void *data, + struct agl_shell_desktop *agl_shell_desktop, + const char *app_id, + const char *app_data, + uint32_t state, + uint32_t role) +{ + HomescreenHandler *homescreenHandler = static_cast<HomescreenHandler *>(data); + + if (homescreenHandler && state == AGL_SHELL_DESKTOP_APP_STATE_DESTROYED) + homescreenHandler->appTerminated(app_id); +} + +static const struct agl_shell_desktop_listener shell_desktop_listener = { + agl_shell_desktop_application, + agl_shell_desktop_state_app +}; + static void global_add(void *data, struct wl_registry *reg, uint32_t name, const char *interface, uint32_t) { - struct agl_shell **shell = static_cast<struct agl_shell **>(data); + struct shell_data *shell_data = static_cast<struct shell_data *>(data); + + if (!shell_data) + return; if (strcmp(interface, agl_shell_interface.name) == 0) { - *shell = static_cast<struct agl_shell *>( + shell_data->shell = static_cast<struct agl_shell *>( wl_registry_bind(reg, name, &agl_shell_interface, 1) ); } + + if (strcmp(interface, agl_shell_desktop_interface.name) == 0) { + shell_data->shell_desktop = static_cast<struct agl_shell_desktop *>( + wl_registry_bind(reg, name, &agl_shell_desktop_interface, 1) + ); + } } static void @@ -84,25 +129,22 @@ getWlOutput(QPlatformNativeInterface *native, QScreen *screen) } -static struct agl_shell * -register_agl_shell(QPlatformNativeInterface *native) +static void +register_agl_shell(QPlatformNativeInterface *native, struct shell_data *shell_data) { struct wl_display *wl; struct wl_registry *registry; - struct agl_shell *shell = nullptr; wl = static_cast<struct wl_display *>( native->nativeResourceForIntegration("display") ); registry = wl_display_get_registry(wl); - wl_registry_add_listener(registry, ®istry_listener, &shell); + wl_registry_add_listener(registry, ®istry_listener, shell_data); /* Roundtrip to get all globals advertised by the compositor */ wl_display_roundtrip(wl); wl_registry_destroy(registry); - - return shell; } static struct wl_surface * @@ -210,14 +252,14 @@ int main(int argc, char *argv[]) QGuiApplication a(argc, argv); const char *screen_name; bool is_demo_val = false; + struct shell_data shell_data = { nullptr, nullptr }; QPlatformNativeInterface *native = qApp->platformNativeInterface(); - struct agl_shell *agl_shell = nullptr; screen_name = getenv("HOMESCREEN_START_SCREEN"); const char *is_demo = getenv("HOMESCREEN_DEMO_CI"); if (is_demo && strcmp(is_demo, "1") == 0) - is_demo_val = true; + is_demo_val = true; QCoreApplication::setOrganizationDomain("LinuxFoundation"); QCoreApplication::setOrganizationName("AutomotiveGradeLinux"); @@ -226,15 +268,20 @@ int main(int argc, char *argv[]) /* we need to have an app_id */ a.setDesktopFileName("homescreen"); - agl_shell = register_agl_shell(native); - if (!agl_shell) { - fprintf(stderr, "agl_shell extension is not advertised. " - "Are you sure that agl-compositor is running?\n"); - exit(EXIT_FAILURE); + register_agl_shell(native, &shell_data); + if (!shell_data.shell) { + fprintf(stderr, "agl_shell extension is not advertised. " + "Are you sure that agl-compositor is running?\n"); + exit(EXIT_FAILURE); + } + if (!shell_data.shell_desktop) { + fprintf(stderr, "agl_shell_desktop extension is not advertised. " + "Are you sure that agl-compositor is running?\n"); + exit(EXIT_FAILURE); } - std::shared_ptr<struct agl_shell> shell{agl_shell, agl_shell_destroy}; - Shell *aglShell = new Shell(shell, &a); + std::shared_ptr<struct agl_shell> agl_shell{shell_data.shell, agl_shell_destroy}; + Shell *aglShell = new Shell(agl_shell, &a); // import C++ class to QML qmlRegisterType<StatusBarModel>("HomeScreen", 1, 0, "StatusBarModel"); @@ -245,6 +292,8 @@ int main(int argc, char *argv[]) HomescreenHandler* homescreenHandler = new HomescreenHandler(aglShell, launcher); homescreenHandler->init(); + agl_shell_desktop_add_listener(shell_data.shell_desktop, &shell_desktop_listener, homescreenHandler); + QQmlApplicationEngine engine; QQmlContext *context = engine.rootContext(); @@ -260,7 +309,7 @@ int main(int argc, char *argv[]) /* instead of loading main.qml we load one-by-one each of the QMLs, * divided now between several surfaces: panels, background. */ - load_agl_shell_app(native, &engine, agl_shell, screen_name, is_demo_val); + load_agl_shell_app(native, &engine, shell_data.shell, screen_name, is_demo_val); return a.exec(); } |