summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2023-04-26 09:48:40 +0300
committerMarius Vlad <marius.vlad@collabora.com>2023-05-03 18:46:19 +0300
commit0fef26d32431e7bea6413f886e79cd2c1d88eb7c (patch)
treee8c30853f8ad9caa749aeb1dc4be18a9d3fc0aa5
parent998097db427c6aeb61e62cd6cf7ad3821e7d0372 (diff)
shell: Add the ability to dynamically move application window
So far, we could start an application on a different output, but moving them back-and-worth wasn't really supported. This handles a few use-cases like: - move an application's window from one output to another - install black curtain in case we no longer have any other surfaces on that output; - deactivate and switch to the previous active window in case there's one available - the activation is handled by the shell client, while deactivation is done implicitly by the compositor to simplify the shell client This does a bit of rewording of a function that returns true whenever we have only a single application window on a particular output. Bug-AGL: SPEC-4673 Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: I58cde58c6a2e2dade93566bfd7aff5ed697f5450
-rw-r--r--src/desktop.c9
-rw-r--r--src/ivi-compositor.h3
-rw-r--r--src/layout.c3
-rw-r--r--src/shell.c33
4 files changed, 42 insertions, 6 deletions
diff --git a/src/desktop.c b/src/desktop.c
index a8e6171..340f14f 100644
--- a/src/desktop.c
+++ b/src/desktop.c
@@ -243,8 +243,9 @@ desktop_surface_added(struct weston_desktop_surface *dsurface, void *userdata)
}
-static bool
-desktop_surface_check_last_surfaces(struct ivi_output *ivi_output, enum ivi_surface_role role)
+bool
+ivi_surface_count_one(struct ivi_output *ivi_output,
+ enum ivi_surface_role role)
{
int count = 0;
struct ivi_surface *surf;
@@ -331,8 +332,8 @@ desktop_surface_removed(struct weston_desktop_surface *dsurface, void *userdata)
/* check if there's a last 'remote' surface and insert a black
* surface view if there's no background set for that output
*/
- if (desktop_surface_check_last_surfaces(output, IVI_SURFACE_ROLE_REMOTE) ||
- desktop_surface_check_last_surfaces(output, IVI_SURFACE_ROLE_DESKTOP))
+ if (ivi_surface_count_one(output, IVI_SURFACE_ROLE_REMOTE) ||
+ ivi_surface_count_one(output, IVI_SURFACE_ROLE_DESKTOP))
if (!output->background)
insert_black_curtain(output);
diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h
index fb5a0fa..857b816 100644
--- a/src/ivi-compositor.h
+++ b/src/ivi-compositor.h
@@ -518,5 +518,8 @@ get_focused_output(struct weston_compositor *compositor);
void
shell_send_app_on_output(struct ivi_compositor *ivi, const char *app_id,
const char *output_name);
+bool
+ivi_surface_count_one(struct ivi_output *ivi_output,
+ enum ivi_surface_role role);
#endif
diff --git a/src/layout.c b/src/layout.c
index b7ef788..ea293ca 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -1116,7 +1116,8 @@ ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id)
weston_log("Deactiving %s, role %s\n", app_id,
ivi_layout_get_surface_role_name(surf));
- if (surf->role == IVI_SURFACE_ROLE_DESKTOP) {
+ if (surf->role == IVI_SURFACE_ROLE_DESKTOP ||
+ surf->role == IVI_SURFACE_ROLE_REMOTE) {
struct ivi_surface *previous_active;
previous_active = ivi_output->previous_active;
diff --git a/src/shell.c b/src/shell.c
index ac20b4f..07a7e98 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1711,15 +1711,46 @@ shell_set_app_output(struct wl_client *client, struct wl_resource *res,
struct weston_output *woutput = weston_head_get_output(head);
struct ivi_output *ioutput = to_ivi_output(woutput);
struct ivi_surface *surf = ivi_find_app(ivi, app_id);
+ struct ivi_output *desktop_last_output = surf->desktop.last_output;
+ struct ivi_output *current_completed_output =
+ surf->current_completed_output;
if (!app_id || !ioutput)
return;
- if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_REMOTE)) {
+ /* handle the case we're not mapped at all */
+ if (!surf) {
ivi_set_pending_desktop_surface_remote(ioutput, app_id);
shell_send_app_on_output(ivi, app_id, woutput->name);
return;
}
+
+ if (surf->remote.output)
+ surf->hidden_layer_output = surf->remote.output;
+ else
+ surf->hidden_layer_output = desktop_last_output;
+ assert(surf->hidden_layer_output);
+
+ if (ivi_surface_count_one(current_completed_output, IVI_SURFACE_ROLE_REMOTE) ||
+ ivi_surface_count_one(current_completed_output, IVI_SURFACE_ROLE_DESKTOP)) {
+ if (!current_completed_output->background)
+ insert_black_curtain(current_completed_output);
+ } else {
+ ivi_layout_deactivate(ivi, app_id);
+ }
+
+ /* update the remote output */
+ surf->remote.output = ioutput;
+
+ if (surf->role != IVI_SURFACE_ROLE_REMOTE) {
+ wl_list_remove(&surf->link);
+ wl_list_init(&surf->link);
+
+ surf->role = IVI_SURFACE_ROLE_NONE;
+ ivi_set_desktop_surface_remote(surf);
+ }
+
+ shell_send_app_on_output(ivi, app_id, woutput->name);
}
static void