diff options
author | Marius Vlad <marius.vlad@collabora.com> | 2023-04-26 09:48:40 +0300 |
---|---|---|
committer | Marius Vlad <marius.vlad@collabora.com> | 2023-05-03 18:46:19 +0300 |
commit | 0fef26d32431e7bea6413f886e79cd2c1d88eb7c (patch) | |
tree | e8c30853f8ad9caa749aeb1dc4be18a9d3fc0aa5 | |
parent | 998097db427c6aeb61e62cd6cf7ad3821e7d0372 (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.c | 9 | ||||
-rw-r--r-- | src/ivi-compositor.h | 3 | ||||
-rw-r--r-- | src/layout.c | 3 | ||||
-rw-r--r-- | src/shell.c | 33 |
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 |