summaryrefslogtreecommitdiffstats
path: root/meta-agl-flutter/recipes-graphics/toyota/files
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2024-06-25 15:39:12 -0400
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2024-06-26 10:42:40 +0000
commitdbb228360317872e7c6fcbd96faaf404535130c3 (patch)
tree361355a3459eb764df0b1a28490615da442fe05d /meta-agl-flutter/recipes-graphics/toyota/files
parent9c99d6680bc5bd3e14085f2b58301ef52144a937 (diff)
Add meta-agl-flutter
Add meta-agl-flutter layer as it is being moved from meta-agl-devel. The files are copies of the state in meta-agl-devel as of commit 97310e35, with only a minor change to the feature template to adjust the location of the layer for bblayers.conf. Bug-AGL: SPEC-5184 Change-Id: I9a14e4ab3a1b1726b0ccc1dbc112d76864dd106c Signed-off-by: Scott Murray <scott.murray@konsulko.com> Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/30016 Tested-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org> Reviewed-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
Diffstat (limited to 'meta-agl-flutter/recipes-graphics/toyota/files')
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch26
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch190
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch117
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch28
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch477
-rw-r--r--meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch33
6 files changed, 871 insertions, 0 deletions
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch
new file mode 100644
index 000000000..a37233b50
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-Disable-on_frame_base_surface-wl_surface_commit.patch
@@ -0,0 +1,26 @@
+From fda28bbd6718bf113061292d8cec15084060c923 Mon Sep 17 00:00:00 2001
+From: Joel Winarske <joel.winarske@gmail.com>
+Date: Wed, 19 Jul 2023 15:21:46 -0700
+Subject: [PATCH] Disable on_frame_base_surface wl_surface_commit
+
+Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
+---
+ shell/wayland/window.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/shell/wayland/window.cc b/shell/wayland/window.cc
+index c74b438..f244f08 100644
+--- a/shell/wayland/window.cc
++++ b/shell/wayland/window.cc
+@@ -257,7 +257,7 @@ void WaylandWindow::on_frame_base_surface(void* data,
+ window->m_fps_counter++;
+ window->m_fps_counter++;
+
+- wl_surface_commit(window->m_base_surface);
++ //wl_surface_commit(window->m_base_surface);
+ }
+
+ uint32_t WaylandWindow::GetFpsCounter() {
+--
+2.41.0
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch
new file mode 100644
index 000000000..fb3a5b3f7
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-activation_area-Add-missing-width-and-height.patch
@@ -0,0 +1,190 @@
+From 2c55093cda17dd16d98a8fb0d26717b29d5d0e75 Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Thu, 28 Dec 2023 19:20:31 +0200
+Subject: [PATCH 1/2] activation_area: Add missing width and height
+
+Setting up an activation area can also require a different rectangle
+size, so allow to set-up one.
+
+Note that there's no actual check if the values are invalid, for
+instance like exceeding the output's dimensions.
+
+Bug-AGL: SPEC-5038
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/configuration/configuration.cc | 8 ++++++++
+ shell/configuration/configuration.h | 2 ++
+ shell/view/flutter_view.cc | 3 ++-
+ shell/wayland/display.cc | 10 +++++-----
+ shell/wayland/display.h | 8 +++++++-
+ shell/wayland/window.cc | 13 +++++++++----
+ shell/wayland/window.h | 4 ++++
+ 7 files changed, 37 insertions(+), 11 deletions(-)
+
+diff --git a/shell/configuration/configuration.cc b/shell/configuration/configuration.cc
+index 2cec924..63b7a82 100644
+--- a/shell/configuration/configuration.cc
++++ b/shell/configuration/configuration.cc
+@@ -104,9 +104,17 @@ void Configuration::getViewParameters(
+
+ instance.view.activation_area_x = static_cast<uint32_t>(val["x"].GetInt());
+ instance.view.activation_area_y = static_cast<uint32_t>(val["y"].GetInt());
++ instance.view.activation_area_width =
++ static_cast<uint32_t>(val["width"].GetInt());
++ instance.view.activation_area_height =
++ static_cast<uint32_t>(val["height"].GetInt());
+
+ SPDLOG_DEBUG("activation area x {}", instance.view.activation_area_x);
+ SPDLOG_DEBUG("activation area y {}", instance.view.activation_area_y);
++ SPDLOG_DEBUG("activation area width {}",
++ instance.view.activation_area_width);
++ SPDLOG_DEBUG("activation area height {}",
++ instance.view.activation_area_height);
+ }
+ }
+
+diff --git a/shell/configuration/configuration.h b/shell/configuration/configuration.h
+index 0e3d721..b0ccbc9 100644
+--- a/shell/configuration/configuration.h
++++ b/shell/configuration/configuration.h
+@@ -44,6 +44,8 @@ class Configuration {
+ uint32_t height;
+ uint32_t activation_area_x;
+ uint32_t activation_area_y;
++ uint32_t activation_area_width;
++ uint32_t activation_area_height;
+ bool fullscreen;
+ bool fullscreen_set;
+ double pixel_ratio;
+diff --git a/shell/view/flutter_view.cc b/shell/view/flutter_view.cc
+index ca51f4e..7b48b85 100644
+--- a/shell/view/flutter_view.cc
++++ b/shell/view/flutter_view.cc
+@@ -67,9 +67,10 @@ FlutterView::FlutterView(Configuration::Config config,
+ m_wayland_window = std::make_shared<WaylandWindow>(
+ m_index, display, m_config.view.window_type,
+ m_wayland_display->GetWlOutput(m_config.view.wl_output_index),
+- m_config.view.wl_output_index, m_config.app_id, m_config.view.fullscreen,
++ m_config.view.wl_output_index, m_config.app_id, m_config.view.fullscreen,
+ m_config.view.width, m_config.view.height, m_config.view.pixel_ratio,
+ m_config.view.activation_area_x, m_config.view.activation_area_y,
++ m_config.view.activation_area_width, m_config.view.activation_area_height,
+ m_backend.get(), m_config.view.ivi_surface_id);
+ }
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index aba050a..0b97954 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -857,16 +857,16 @@ void Display::AglShellDoReady() const {
+
+ void Display::AglShellDoSetupActivationArea(uint32_t x,
+ uint32_t y,
++ uint32_t width,
++ uint32_t height,
+ uint32_t index) {
+- uint32_t width = m_all_outputs[index]->width;
+- uint32_t height = m_all_outputs[index]->height - (2 * y);
+-
+ if (!m_agl.shell)
+ return;
+
+ if (m_all_outputs[index]->transform == WL_OUTPUT_TRANSFORM_90) {
+- width = m_all_outputs[index]->height;
+- height = m_all_outputs[index]->width - (2 * y);
++ uint32_t tmp_width = width;
++ width = height;
++ height = tmp_width;
+ }
+
+ SPDLOG_DEBUG("Using custom rectangle [{}x{}+{}x{}] for activation", width,
+diff --git a/shell/wayland/display.h b/shell/wayland/display.h
+index b919047..a792ad7 100644
+--- a/shell/wayland/display.h
++++ b/shell/wayland/display.h
+@@ -172,6 +172,8 @@ class Display {
+ * @return void
+ * @param[in] x the x position for the activation rectangle
+ * @param[in] y the y position for the activation rectangle
++ * @param[in] width the width position for the activation rectangle
++ * @param[in] height the height position for the activation rectangle
+ * @param[index] the output, as a number
+ * @relation
+ *
+@@ -193,7 +195,11 @@ class Display {
+ * | |
+ * --------------------
+ */
+- void AglShellDoSetupActivationArea(uint32_t x, uint32_t y, uint32_t index);
++ void AglShellDoSetupActivationArea(uint32_t x,
++ uint32_t y,
++ uint32_t width,
++ uint32_t height,
++ uint32_t index);
+
+ /**
+ * @brief Set Engine
+diff --git a/shell/wayland/window.cc b/shell/wayland/window.cc
+index 373b0a2..f816e58 100644
+--- a/shell/wayland/window.cc
++++ b/shell/wayland/window.cc
+@@ -31,6 +31,8 @@ WaylandWindow::WaylandWindow(size_t index,
+ double pixel_ratio,
+ uint32_t activation_area_x,
+ uint32_t activation_area_y,
++ uint32_t activation_area_width,
++ uint32_t activation_area_height,
+ Backend* backend,
+ uint32_t ivi_surface_id)
+ : m_index(index),
+@@ -42,7 +44,8 @@ WaylandWindow::WaylandWindow(size_t index,
+ m_geometry({width, height}),
+ m_window_size({width, height}),
+ m_pixel_ratio(pixel_ratio),
+- m_activation_area({activation_area_x, activation_area_y}),
++ m_activation_area({activation_area_x, activation_area_y,
++ activation_area_width, activation_area_height}),
+ m_type(get_window_type(type)),
+ m_app_id(std::move(app_id)),
+ m_ivi_surface_id(ivi_surface_id),
+@@ -98,10 +101,12 @@ WaylandWindow::WaylandWindow(size_t index,
+ case WINDOW_BG:
+ m_display->AglShellDoBackground(m_base_surface, 0);
+ if (m_activation_area.x > 0 && m_activation_area.y > 0)
+- m_display->AglShellDoSetupActivationArea(m_activation_area.x,
+- m_activation_area.y, 0);
++ m_display->AglShellDoSetupActivationArea(
++ m_activation_area.x, m_activation_area.y, m_activation_area.width,
++ m_activation_area.height, 0);
+ else
+- m_display->AglShellDoSetupActivationArea(0, 160, 0);
++ m_display->AglShellDoSetupActivationArea(0, 160, m_activation_area.width,
++ m_activation_area.height, 0);
+ break;
+ case WINDOW_PANEL_TOP:
+ m_display->AglShellDoPanel(m_base_surface, AGL_SHELL_EDGE_TOP, 0);
+diff --git a/shell/wayland/window.h b/shell/wayland/window.h
+index 998a1c8..f66f70a 100644
+--- a/shell/wayland/window.h
++++ b/shell/wayland/window.h
+@@ -67,6 +67,8 @@ class WaylandWindow {
+ double pixel_ratio,
+ uint32_t activation_area_x,
+ uint32_t activation_area_y,
++ uint32_t activation_area_width,
++ uint32_t activation_area_height,
+ Backend* backend,
+ uint32_t ivi_surface_id);
+
+@@ -166,6 +168,8 @@ class WaylandWindow {
+ struct {
+ uint32_t x;
+ uint32_t y;
++ uint32_t width;
++ uint32_t height;
+ } m_activation_area;
+ struct {
+ int32_t width;
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch
new file mode 100644
index 000000000..6b1b3e4c9
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0001-display-Add-support-for-wl_output-version-4.patch
@@ -0,0 +1,117 @@
+From 10d1d855a0ce4557cb710e73e3e7c9ab0dd0e734 Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Mon, 4 Dec 2023 14:16:36 +0200
+Subject: [PATCH 1/2] display: Add support for wl_output version 4
+
+This allows support for wl_output.name and wl_output.desc be sent out
+by the compositor that supports it.
+
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/display.cc | 34 ++++++++++++++++++++++++++++++----
+ shell/wayland/display.h | 28 ++++++++++++++++++++++++++++
+ 2 files changed, 58 insertions(+), 4 deletions(-)
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index 8e309ef..3ee814a 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -191,9 +191,16 @@ void Display::registry_handle_global(void* data,
+ auto oi = std::make_shared<output_info_t>();
+ std::fill_n(oi.get(), 1, output_info_t{});
+ oi->global_id = name;
+- oi->output = static_cast<struct wl_output*>(
+- wl_registry_bind(registry, name, &wl_output_interface,
+- std::min(static_cast<uint32_t>(2), version)));
++ // be compat with v2 as well
++ if (version >= WL_OUTPUT_NAME_SINCE_VERSION &&
++ version >= WL_OUTPUT_DESCRIPTION_SINCE_VERSION)
++ oi->output = static_cast<struct wl_output*>(
++ wl_registry_bind(registry, name, &wl_output_interface,
++ std::min(static_cast<uint32_t>(4), version)));
++ else
++ oi->output = static_cast<struct wl_output*>(
++ wl_registry_bind(registry, name, &wl_output_interface,
++ std::min(static_cast<uint32_t>(2), version)));
+ wl_output_add_listener(oi->output, &output_listener, oi.get());
+ SPDLOG_DEBUG("Wayland: Output [{}]", d->m_all_outputs.size());
+ d->m_all_outputs.push_back(oi);
+@@ -299,9 +306,28 @@ void Display::display_handle_done(void* data,
+ oi->done = true;
+ }
+
++void Display::display_handle_name(void* data,
++ struct wl_output* /* wl_output */,
++ const char* name) {
++ auto* oi = static_cast<output_info_t*>(data);
++ oi->name = std::string(name);
++}
++
++void Display::display_handle_desc(void* data,
++ struct wl_output* /* wl_output */,
++ const char* desc) {
++ auto* oi = static_cast<output_info_t*>(data);
++ oi->desc = std::string(desc);
++}
++
+ const struct wl_output_listener Display::output_listener = {
+ display_handle_geometry, display_handle_mode, display_handle_done,
+- display_handle_scale};
++ display_handle_scale
++#if defined(WL_OUTPUT_NAME_SINCE_VERSION) && \
++ defined(WL_OUTPUT_DESCRIPTION_SINCE_VERSION)
++ , display_handle_name, display_handle_desc
++#endif
++};
+
+ void Display::shm_format(void* /* data */,
+ struct wl_shm* /* wl_shm */,
+diff --git a/shell/wayland/display.h b/shell/wayland/display.h
+index cc3f4be..a0756f0 100644
+--- a/shell/wayland/display.h
++++ b/shell/wayland/display.h
+@@ -329,6 +329,8 @@ class Display {
+ int32_t scale;
+ MAYBE_UNUSED bool done;
+ int transform;
++ std::string name;
++ std::string desc;
+ } output_info_t;
+
+ struct pointer_event {
+@@ -520,6 +522,32 @@ class Display {
+ */
+ static void display_handle_done(void* data, struct wl_output* wl_output);
+
++ /**
++ * @brief Set the display output name
++ * @param[in,out] data Data of type output_info_t*
++ * @param[in] wl_output No use
++ * @param[in] output_name Display name
++ * @return void
++ * @relation
++ * wayland - since @v4 of wl_output
++ */
++ static void display_handle_name(void* data,
++ struct wl_output* wl_output,
++ const char* output_name);
++
++ /**
++ * @brief Set the display description
++ * @param[in,out] data Data of type output_info_t*
++ * @param[in] wl_output No use
++ * @param[in] desc_name Display description name
++ * @return void
++ * @relation
++ * wayland - since @v4 of wl_output
++ */
++ static void display_handle_desc(void* data,
++ struct wl_output* wl_output,
++ const char* desc_name);
++
+ static const struct wl_shm_listener shm_listener;
+
+ /**
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch
new file mode 100644
index 000000000..f0cf9ddb3
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0002-activation_area-Allow-x-and-y-values-be-zero-for-the.patch
@@ -0,0 +1,28 @@
+From 641ca7ca26c1bfc11e7d0c0f30b731f53467bf1f Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Thu, 28 Dec 2023 20:28:12 +0200
+Subject: [PATCH 2/2] activation_area: Allow x and y values be zero for the
+ activation area
+
+Bug-AGL: SPEC-5038
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/window.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/shell/wayland/window.cc b/shell/wayland/window.cc
+index f816e58..929b9af 100644
+--- a/shell/wayland/window.cc
++++ b/shell/wayland/window.cc
+@@ -100,7 +100,7 @@ WaylandWindow::WaylandWindow(size_t index,
+ break;
+ case WINDOW_BG:
+ m_display->AglShellDoBackground(m_base_surface, 0);
+- if (m_activation_area.x > 0 && m_activation_area.y > 0)
++ if (m_activation_area.x >= 0 && m_activation_area.y >= 0)
+ m_display->AglShellDoSetupActivationArea(
+ m_activation_area.x, m_activation_area.y, m_activation_area.width,
+ m_activation_area.height, 0);
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch
new file mode 100644
index 000000000..792811769
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0002-display-Add-support-for-agl_shell-version-8.patch
@@ -0,0 +1,477 @@
+From d44f07a0c2cc410414bfd7b338ee071c17422a0a Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Mon, 4 Dec 2023 18:17:00 +0200
+Subject: [PATCH 2/2] display: Add support for agl_shell version 8
+
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/display.cc | 156 ++++++++++++++++++++++--
+ shell/wayland/display.h | 58 +++++++++
+ third_party/agl/protocol/agl-shell.xml | 160 ++++++++++++++++++++++++-
+ 3 files changed, 366 insertions(+), 8 deletions(-)
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index 3ee814a..aba050a 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -220,7 +220,7 @@ void Display::registry_handle_global(void* data,
+ if (version >= 2) {
+ d->m_agl.shell = static_cast<struct agl_shell*>(
+ wl_registry_bind(registry, name, &agl_shell_interface,
+- std::min(static_cast<uint32_t>(4), version)));
++ std::min(static_cast<uint32_t>(8), version)));
+ agl_shell_add_listener(d->m_agl.shell, &agl_shell_listener, data);
+ } else {
+ d->m_agl.shell = static_cast<struct agl_shell*>(
+@@ -980,6 +980,148 @@ void Display::agl_shell_bound_fail(void* data, struct agl_shell* shell) {
+ d->m_agl.bound_ok = false;
+ }
+
++void Display::addAppToStack(std::string app_id) {
++ if (app_id == "homescreen")
++ return;
++
++ bool found_app = false;
++ for (auto& i : apps_stack) {
++ if (i == app_id) {
++ found_app = true;
++ break;
++ }
++ }
++
++ if (!found_app) {
++ apps_stack.push_back(app_id);
++ } else {
++ // fixme
++ }
++}
++
++int Display::find_output_by_name(std::string output_name) {
++ int index = 0;
++ for (auto& i : m_all_outputs) {
++ if (i->name == output_name) {
++ return index;
++ }
++ index++;
++ }
++
++ return -1;
++}
++
++void Display::activateApp(std::string app_id) {
++ int default_output_index = 0;
++
++ FML_LOG(INFO) << "got app_id " << app_id;
++
++ // search for a pending application which might have a different output
++ auto iter = pending_app_list.begin();
++ bool found_pending_app = false;
++ while (iter != pending_app_list.end()) {
++ auto app_to_search = iter->first;
++ FML_LOG(INFO) << "searching for " << app_to_search;
++
++ if (app_to_search == app_id) {
++ found_pending_app = true;
++ break;
++ }
++
++ iter++;
++ }
++
++ if (found_pending_app) {
++ auto output_name = iter->second;
++ default_output_index = find_output_by_name(output_name);
++
++ FML_LOG(INFO) << "Found app_id " << app_id << " at all";
++
++ if (default_output_index < 0) {
++ // try with remoting-remote-X which is the streaming
++ std::string new_remote_output = "remoting-" + output_name;
++
++ default_output_index = find_output_by_name(new_remote_output);
++ if (default_output_index < 0) {
++ FML_LOG(INFO) << "Not activating app_id " << app_id << " at all";
++ return;
++ }
++ }
++
++ pending_app_list.erase(iter);
++ }
++
++ FML_LOG(INFO) << "Activating app_id " << app_id << " on output "
++ << default_output_index;
++ agl_shell_activate_app(m_agl.shell, app_id.c_str(),
++ m_all_outputs[default_output_index]->output);
++ wl_display_flush(m_display);
++}
++
++void Display::deactivateApp(std::string app_id) {
++ for (auto& i : apps_stack) {
++ if (i == app_id) {
++ // remove it from apps_stack
++ apps_stack.remove(i);
++ if (!apps_stack.empty())
++ activateApp(apps_stack.back());
++ break;
++ }
++ }
++}
++
++void Display::processAppStatusEvent(const char* app_id,
++ const std::string event_type) {
++ if (!m_agl.shell)
++ return;
++
++ if (event_type == "started") {
++ activateApp(std::string(app_id));
++ } else if (event_type == "terminated") {
++ deactivateApp(std::string(app_id));
++ } else if (event_type == "deactivated") {
++ // not handled
++ }
++}
++
++void Display::agl_shell_app_on_output(void* data,
++ struct agl_shell* agl_shell,
++ const char* app_id,
++ const char* output_name) {
++ auto* d = static_cast<Display*>(data);
++
++ FML_LOG(INFO) << "Gove event app_on_out app_id " << app_id << " output name "
++ << output_name;
++
++ // a couple of use-cases, if there is no app_id in the app_list then it
++ // means this is a request to map the application, from the start to a
++ // different output that the default one. We'd get an
++ // AGL_SHELL_APP_STATE_STARTED which will handle activation.
++ //
++ // if there's an app_id then it means we might have gotten an event to
++ // move the application to another output; so we'd need to process it
++ // by explicitly calling processAppStatusEvent() which would ultimately
++ // activate the application on other output. We'd have to pick-up the
++ // last activated window and activate the default output.
++ //
++ // finally if the outputs are identical probably that's an user-error -
++ // but the compositor won't activate it again, so we don't handle that.
++ std::pair new_pending_app =
++ std::pair(std::string(app_id), std::string(output_name));
++ d->pending_app_list.push_back(new_pending_app);
++
++ auto iter = d->apps_stack.begin();
++ while (iter != d->apps_stack.end()) {
++ if (*iter == std::string(app_id)) {
++ FML_LOG(INFO) << "Gove event to move " << app_id << " to another output "
++ << output_name;
++ d->processAppStatusEvent(app_id, std::string("started"));
++ break;
++ }
++ iter++;
++ }
++}
++
+ void Display::agl_shell_app_state(void* data,
+ struct agl_shell* /* agl_shell */,
+ const char* app_id,
+@@ -991,12 +1133,7 @@ void Display::agl_shell_app_state(void* data,
+ FML_DLOG(INFO) << "Got AGL_SHELL_APP_STATE_STARTED for app_id " << app_id;
+
+ if (d->m_agl.shell) {
+- // we always assume the first output advertised by the wl_output
+- // interface
+- unsigned int default_output_index = 0;
+-
+- agl_shell_activate_app(d->m_agl.shell, app_id,
+- d->m_all_outputs[default_output_index]->output);
++ d->processAppStatusEvent(app_id, std::string("started"));
+ }
+
+ break;
+@@ -1007,6 +1144,10 @@ void Display::agl_shell_app_state(void* data,
+ case AGL_SHELL_APP_STATE_ACTIVATED:
+ FML_DLOG(INFO) << "Got AGL_SHELL_APP_STATE_ACTIVATED for app_id "
+ << app_id;
++ d->addAppToStack(std::string(app_id));
++ break;
++ case AGL_SHELL_APP_STATE_DEACTIVATED:
++ d->processAppStatusEvent(app_id, std::string("deactivated"));
+ break;
+ default:
+ break;
+@@ -1017,6 +1158,7 @@ const struct agl_shell_listener Display::agl_shell_listener = {
+ .bound_ok = agl_shell_bound_ok,
+ .bound_fail = agl_shell_bound_fail,
+ .app_state = agl_shell_app_state,
++ .app_on_output = agl_shell_app_on_output,
+ };
+
+ void Display::ivi_wm_surface_visibility(void* /* data */,
+diff --git a/shell/wayland/display.h b/shell/wayland/display.h
+index a0756f0..b919047 100644
+--- a/shell/wayland/display.h
++++ b/shell/wayland/display.h
+@@ -18,6 +18,7 @@
+ #pragma once
+
+ #include <chrono>
++#include <list>
+ #include <memory>
+ #include <mutex>
+ #include <string>
+@@ -271,6 +272,44 @@ class Display {
+ */
+ std::pair<int32_t, int32_t> GetVideoModeSize(uint32_t index);
+
++ /**
++ * @brief deactivate/hide the application pointed by app_id
++ * @param[in] app_id the app_id
++ * @relation
++ * agl_shell
++ */
++ void deactivateApp(std::string app_id);
++ /**
++ * @brief activate/show the application pointed by app_id
++ * @param[in] app_id the app_id
++ * @relation
++ * agl_shell
++ */
++ void activateApp(std::string app_id);
++ /**
++ * @brief Add app_id to a list of list applications
++ * @param[in] app_id the app_id
++ * @relation
++ * agl_shell
++ */
++ void addAppToStack(std::string app_id);
++ /**
++ * @brief Helper to retrieve the output using its output_name
++ * @param[in] output_name a std::string representing the output
++ * @retval an integer that can used to get the proper output
++ * @relation
++ * agl_sell
++ */
++ int find_output_by_name(std::string output_name);
++ /**
++ * @brief helper to process the application status
++ * @param[in] app_id an array of char
++ * @param[in] event_type a std::string representing the type of event (started/stopped/terminated)
++ * @relation
++ * agl_shell
++ */
++ void processAppStatusEvent(const char* app_id, const std::string event_type);
++
+ private:
+ std::shared_ptr<Engine> m_flutter_engine;
+
+@@ -300,6 +339,9 @@ class Display {
+ uint32_t version = 0;
+ } m_agl;
+
++ std::list<std::string> apps_stack;
++ std::list<std::pair<const std::string, const std::string>> pending_app_list;
++
+ struct ivi_shell {
+ struct ivi_application* application = nullptr;
+ struct ivi_wm* ivi_wm = nullptr;
+@@ -982,6 +1024,22 @@ class Display {
+ const char* app_id,
+ uint32_t state);
+
++ /**
++ * @brief AGL app_app_on_output event
++ * @param[in,out] data Data of type Display
++ * @param[in] shell No use
++ * @param[in] app_id the application id for which this event was sent
++ * @param[in] state the state: CREATED/TERMINATED/ACTIVATED/DEACTIVATED
++ * @return void
++ * @relation
++ * wayland, agl-shell
++ * @note Do nothing
++ */
++ static void agl_shell_app_on_output(void* data,
++ struct agl_shell* agl_shell,
++ const char* app_id,
++ const char* output_name);
++
+ static const struct agl_shell_listener agl_shell_listener;
+
+ /**
+diff --git a/third_party/agl/protocol/agl-shell.xml b/third_party/agl/protocol/agl-shell.xml
+index bf5ab02..e010a80 100644
+--- a/third_party/agl/protocol/agl-shell.xml
++++ b/third_party/agl/protocol/agl-shell.xml
+@@ -22,7 +22,7 @@
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+- <interface name="agl_shell" version="4">
++ <interface name="agl_shell" version="8">
+ <description summary="user interface for Automotive Grade Linux platform">
+ Starting with version 2 of the protocol, the client is required to wait
+ for the 'bound_ok' or 'bound_fail' events in order to proceed further.
+@@ -200,5 +200,163 @@
+ <arg name="width" type="int" summary="width of rectangle"/>
+ <arg name="height" type="int" summary="height of rectangle"/>
+ </request>
++
++ <request name="deactivate_app" since="5">
++ <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 active surface) or temporarily (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>
++
++ <request name="set_app_float" since="6">
++ <description summary="set the window identified by app_id as float">
++ Makes the application identified by app_id as floating. If the
++ application's window is already mapped, in a maximized, normal state,
++ it would transition to the float state.
++
++ For applications that want to modify their own state, this request
++ must be done before the initial surface commit in order to take effect.
++
++ If the application is already in floating state, this request wouldn't
++ do anything.
++
++ There's no persistence of this request, once the application terminated
++ you'll to issue this request again for that particular app_id.
++
++ The x, and y values would be initial position of the window where the
++ window surface will be placed.
++
++ 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="x" type="int" summary="x position"/>
++ <arg name="y" type="int" summary="y position"/>
++ </request>
++
++ <request name="set_app_normal" since="6">
++ <description summary="set the window identified by app_id as normally started">
++ Returns the application identified by app_id as it was in the normal state.
++ This is useful to come back from other states to the maximized state, the
++ normal state applications are started.
++ </description>
++ <arg name="app_id" type="string"/>
++ </request>
++
++ <request name="set_app_fullscreen" since="7">
++ <description summary="">
++ Makes the application identified by app_id as fullscreen. If the
++ application's window is already mapped, in a maximized, normal state,
++ it would transition to the fullscreen state.
++
++ For applications that want to modify their own state, this request
++ must be done before the initial surface commit in order to take effect.
++
++ If the application is already in fullscreen state, this request wouldn't
++ do anything.
++
++ There's no persistence of this request, once the application terminated
++ you'll to issue this request again for that particular app_id.
++
++ 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>
++
++ <request name="set_app_output" since="8">
++ <description summary="Assign an application to a particular output">
++ This would allow the compositor to place an application on a particular
++ output, if that output is indeed available. This can happen before
++ application is started which would make the application start on that
++ particular output. If the application is already started it would
++ move the application to that output.
++
++ There's no persistence of this request, once the application terminated
++ you'll need to issue this request again for that particular app_id.
++
++ 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>
++
++ <event name="app_on_output" since="8">
++ <description summary="Event sent as a reponse to set_app_output">
++ Clients can use this event to be notified when an application
++ wants to be displayed on a certain output. This event is sent in
++ response to the set_app_output request.
++
++ 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_name" type="string"/>
++ </event>
++ </interface>
++
++ <interface name="agl_shell_ext" version="1">
++ <description summary="extended user interface for Automotive Grade Linux platform">
++ This interface allows another client bind to the agl_shell interface,
++ while there's another shell client already present.
++
++ The client should first bind to this interface and then inform the
++ compositor with the 'doas_shell_client' request and it wants to bind to
++ the agl_shell interface. The client is still expected, if using a new
++ version of the agl_shell interface, to wait for the 'bound_ok' and
++ 'bound_fail' events before issueing any other requests/events.
++
++ Note that this interface has its limitations, and the compositor would
++ still refuse the act for 'set_panel' or 'set_background' requests
++ of the agl_shell interface if there's already a client that used them.
++
++ Any other requests or events should be delievered and handled as it would
++ a client bound to the agl_shell interface.
++ </description>
++
++ <enum name="doas_shell_client_status">
++ <entry name="success" value="0"/>
++ <entry name="failed" value="1"/>
++ </enum>
++
++ <request name="destroy" type="destructor">
++ <description summary="destroys the factory object">
++ Call the destructor once you're ready with agl_shell_ext interface.
++ This would reset the state and would make any requests made
++ on the agl_shell interface be terminated. The client would need
++ to bind again the agl_shell_ext and issue a 'doas_shell_client'
++ request.
++ </description>
++ </request>
++
++ <request name="doas_shell_client">
++ <description summary="Informs the compositor it wants to bind to the
++ agl_shell interface">
++ Prior to binding to agl_shell interface, this request would inform
++ the compositor that it wants to gain access the agl_shell interface.
++ The client is expected to wait for 'doas_shell_client_done' event and
++ check for a successful status before going further with binding to
++ the agl_shell interface.
++ </description>
++ </request>
++
++ <event name="doas_done">
++ <description summary="event sent as a reply to doas_shell_client">
++ The client should check the status event to verify that the
++ compositor was able to handle the request.
++ </description>
++ <arg name="status" type="uint" enum="doas_shell_client_status"/>
++ </event>
+ </interface>
+ </protocol>
+--
+2.35.1
+
diff --git a/meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch b/meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch
new file mode 100644
index 000000000..f59add5a8
--- /dev/null
+++ b/meta-agl-flutter/recipes-graphics/toyota/files/0003-activation_area-Remove-the-implicit-width-height-swa.patch
@@ -0,0 +1,33 @@
+From b247f63441f75c47cebd6edd00ecc0c5f94728b6 Mon Sep 17 00:00:00 2001
+From: Marius Vlad <marius.vlad@collabora.com>
+Date: Tue, 2 Jan 2024 15:00:13 +0200
+Subject: [PATCH 3/3] activation_area: Remove the implicit width/height swap
+
+This does more harm than being useful so remove it.
+
+Bug-AGL: SPEC-5038
+Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
+---
+ shell/wayland/display.cc | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/shell/wayland/display.cc b/shell/wayland/display.cc
+index 0b97954..9452dbf 100644
+--- a/shell/wayland/display.cc
++++ b/shell/wayland/display.cc
+@@ -863,12 +863,6 @@ void Display::AglShellDoSetupActivationArea(uint32_t x,
+ if (!m_agl.shell)
+ return;
+
+- if (m_all_outputs[index]->transform == WL_OUTPUT_TRANSFORM_90) {
+- uint32_t tmp_width = width;
+- width = height;
+- height = tmp_width;
+- }
+-
+ SPDLOG_DEBUG("Using custom rectangle [{}x{}+{}x{}] for activation", width,
+ height, x, y);
+
+--
+2.35.1
+