From: Marius Vlad Date: Wed, 26 Apr 2023 06:48:40 +0000 (+0300) Subject: shell: Add the ability to dynamically move application window X-Git-Tag: 17.90.0~28 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=src%2Fagl-compositor.git;a=commitdiff_plain;h=0fef26d32431e7bea6413f886e79cd2c1d88eb7c 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 Change-Id: I58cde58c6a2e2dade93566bfd7aff5ed697f5450 --- 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