aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2020-04-06 22:30:55 +0300
committerMarius Vlad <marius.vlad@collabora.com>2020-05-12 21:56:35 +0300
commitd0b4585202c46be21b415c664b9d010057c37686 (patch)
tree6be0a37532ed10562c7da081abd6b4b5ef3a787d
parent410d47884ffedce08a987b948429d9d13bc4f551 (diff)
agl-shell-desktop: Add the ability to hide client windows
This would be particularly useful to pop-up kind of window(s). It implements the 'deactivate_app' request. For the pop-up role we just remove the view from the layer while for the desktop we store the previous surface and re-use it if that's set. Otherwise we just display the background surface. As we now allow to hide client windows, we need to able to activate/show them back so this also adds a slight modification to take care to handle the pop-up role separately when calling the 'activate_app' request. Bug-AGL: SPEC-3269 Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: Iec5ccbe2815f4b0e32086fd49856f5f338147f79
-rw-r--r--protocol/agl-shell-desktop.xml16
-rw-r--r--src/ivi-compositor.h4
-rw-r--r--src/layout.c102
-rw-r--r--src/shell.c12
4 files changed, 132 insertions, 2 deletions
diff --git a/protocol/agl-shell-desktop.xml b/protocol/agl-shell-desktop.xml
index 28b2756..6d53f92 100644
--- a/protocol/agl-shell-desktop.xml
+++ b/protocol/agl-shell-desktop.xml
@@ -76,5 +76,21 @@
<arg name="y" type="int"/>
<arg name="output" type="object" interface="wl_output"/>
</request>
+
+ <request name="deactivate_app">
+ <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 activate surface) or temporarly (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>
</interface>
</protocol>
diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h
index bdd91ff..b76da85 100644
--- a/src/ivi-compositor.h
+++ b/src/ivi-compositor.h
@@ -130,6 +130,7 @@ struct ivi_output {
struct weston_geometry area;
struct ivi_surface *active;
+ struct ivi_surface *previous_active;
/* Temporary: only used during configuration */
size_t add_len;
@@ -290,4 +291,7 @@ ivi_layout_panel_committed(struct ivi_surface *surface);
void
ivi_layout_popup_committed(struct ivi_surface *surface);
+void
+ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id);
+
#endif
diff --git a/src/layout.c b/src/layout.c
index 55509e4..0e7aaaf 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -206,6 +206,7 @@ ivi_layout_activate_complete(struct ivi_output *output,
weston_layer_entry_remove(&output->active->view->layer_link);
}
+ output->previous_active = output->active;
output->active = surf;
weston_layer_entry_insert(&ivi->normal.view_list, &view->layer_link);
@@ -313,12 +314,33 @@ ivi_layout_popup_committed(struct ivi_surface *surface)
weston_layer_entry_insert(&ivi->popup.view_list, &view->layer_link);
weston_view_update_transform(view);
- weston_view_schedule_repaint(view);
+ weston_view_damage_below(view);
wsurface->is_mapped = true;
surface->view->is_mapped = true;
}
+static void
+ivi_layout_popup_re_add(struct ivi_surface *surface)
+{
+ assert(surface->role == IVI_SURFACE_ROLE_POPUP);
+ struct weston_view *view = surface->view;
+ struct ivi_compositor *ivi = surface->ivi;
+
+ if (weston_view_is_mapped(view)) {
+ struct weston_desktop_surface *dsurface = surface->dsurface;
+ struct weston_surface *wsurface =
+ weston_desktop_surface_get_surface(dsurface);
+
+ weston_layer_entry_remove(&view->layer_link);
+
+ wsurface->is_mapped = false;
+ view->is_mapped = false;
+ }
+
+ ivi_layout_popup_committed(surface);
+}
+
void
ivi_layout_panel_committed(struct ivi_surface *surface)
{
@@ -408,6 +430,12 @@ ivi_layout_activate(struct ivi_output *output, const char *app_id)
#ifdef AGL_COMP_DEBUG
weston_log("Found app_id %s\n", app_id);
#endif
+
+ if (surf->role == IVI_SURFACE_ROLE_POPUP) {
+ ivi_layout_popup_re_add(surf);
+ return;
+ }
+
if (surf == output->active)
return;
@@ -444,3 +472,75 @@ ivi_layout_activate(struct ivi_output *output, const char *app_id)
}
}
+
+static struct ivi_output *
+ivi_layout_get_output_from_surface(struct ivi_surface *surf)
+{
+ struct ivi_output *ivi_output = NULL;
+
+ switch (surf->role) {
+ case IVI_SURFACE_ROLE_DESKTOP:
+ if (surf->desktop.pending_output)
+ ivi_output = surf->desktop.pending_output;
+ else
+ ivi_output = surf->desktop.last_output;
+ break;
+ case IVI_SURFACE_ROLE_POPUP:
+ ivi_output = surf->popup.output;
+ break;
+ default:
+ case IVI_SURFACE_ROLE_BACKGROUND:
+ case IVI_SURFACE_ROLE_PANEL:
+ case IVI_SURFACE_ROLE_NONE:
+ break;
+ }
+
+ return ivi_output;
+}
+
+void
+ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id)
+{
+ struct ivi_surface *surf;
+ struct ivi_output *ivi_output;
+
+ surf = ivi_find_app(ivi, app_id);
+ if (!surf)
+ return;
+
+ ivi_output = ivi_layout_get_output_from_surface(surf);
+ weston_log("deactiving %s\n", app_id);
+
+ if (surf->role == IVI_SURFACE_ROLE_DESKTOP) {
+ struct ivi_surface *previous_active;
+
+ previous_active = ivi_output->previous_active;
+ if (!previous_active) {
+ /* we don't have a previous active it means we should
+ * display the bg */
+ if (ivi_output->active) {
+ struct weston_view *view;
+
+ view = ivi_output->active->view;
+ view->is_mapped = false;
+ view->surface->is_mapped = false;
+
+ weston_layer_entry_remove(&view->layer_link);
+ weston_output_damage(ivi_output->output);
+ }
+ } else {
+ struct weston_desktop_surface *dsurface;
+ const char *previous_active_app_id;
+
+ dsurface = previous_active->dsurface;
+ previous_active_app_id =
+ weston_desktop_surface_get_app_id(dsurface);
+ ivi_layout_activate(ivi_output, previous_active_app_id);
+ }
+ } else if (surf->role == IVI_SURFACE_ROLE_POPUP) {
+ struct weston_view *view = surf->view;
+
+ weston_layer_entry_remove(&view->layer_link);
+ weston_view_damage_below(view);
+ }
+}
diff --git a/src/shell.c b/src/shell.c
index cf1214a..768b6d2 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -522,6 +522,15 @@ shell_activate_app(struct wl_client *client,
ivi_layout_activate(output, app_id);
}
+static void
+shell_deactivate_app(struct wl_client *client,
+ struct wl_resource *shell_res,
+ const char *app_id)
+{
+ struct desktop_client *dclient = wl_resource_get_user_data(shell_res);
+ ivi_layout_deactivate(dclient->ivi, app_id);
+}
+
static const struct agl_shell_interface agl_shell_implementation = {
.ready = shell_ready,
.set_background = shell_set_background,
@@ -546,7 +555,8 @@ shell_desktop_set_app_property(struct wl_client *client,
static const struct agl_shell_desktop_interface agl_shell_desktop_implementation = {
.activate_app = shell_activate_app,
- .set_app_property = shell_desktop_set_app_property
+ .set_app_property = shell_desktop_set_app_property,
+ .deactivate_app = shell_deactivate_app,
};
static void