aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud Ferraris <arnaud.ferraris@collabora.com>2022-01-18 12:52:43 +0100
committerArnaud Ferraris <arnaud.ferraris@collabora.com>2022-01-20 17:25:38 +0100
commita3c4beb8a9d1a01a4a29434e8319be7ce3f0d42f (patch)
treef3e10f66b51ae1064e91275f3920e0a1e2258a38
parent20970d846906a070305d8e96cf0735bf7fd831b1 (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.pro2
-rw-r--r--homescreen/src/main.cpp85
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, &registry_listener, &shell);
+ wl_registry_add_listener(registry, &registry_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();
}