summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryce Harrington <bryce@osg.samsung.com>2016-09-10 12:42:02 +0200
committerQuentin Glidic <sardemff7+git@sardemff7.net>2016-09-10 19:34:32 +0200
commit91b01e002e34ebcde5437fc6efda42486490afd4 (patch)
treea57ef3fca00b9258603fb863559a7b11b7708fb5
parent6d5c7a9a884751362b2f358cd8064cb6350f1e1a (diff)
shell: Inhibit idle fade-out behavior
When a client has registered idle inhibition on a surface, don't trigger the fade-out animation on the output(s) the surface is displayed on. But when the surface is destroyed or the inhibitor itself is destroyed by client request, re-queue the fade out animation. Signed-off-by: Bryce Harrington <bryce@osg.samsung.com> Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
-rw-r--r--desktop-shell/shell.c57
-rw-r--r--libweston/compositor.c5
2 files changed, 61 insertions, 1 deletions
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 88a05f69..f72c248a 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -137,6 +137,9 @@ struct shell_surface {
int focus_count;
bool destroying;
+
+ struct wl_listener start_inhibiting_listener;
+ struct wl_listener stop_inhibiting_listener;
};
struct shell_grab {
@@ -2279,6 +2282,7 @@ fade_out_done(struct weston_view_animation *animation, void *data)
}
}
+/** Re-queue the fade animation to be evaluated if client had been inhibiting */
struct shell_surface *
get_shell_surface(struct weston_surface *surface)
{
@@ -2295,6 +2299,35 @@ get_shell_surface(struct weston_surface *surface)
*/
static void
+surface_start_inhibiting_notify(struct wl_listener *listener, void *data)
+{
+ struct shell_surface *shsurf =
+ wl_container_of(listener, shsurf, start_inhibiting_listener);
+ struct weston_surface *surface =
+ weston_desktop_surface_get_surface(shsurf->desktop_surface);
+ struct weston_compositor *compositor = shsurf->shell->compositor;
+
+ if (compositor->state == WESTON_COMPOSITOR_IDLE
+ || compositor->state == WESTON_COMPOSITOR_OFFSCREEN
+ || compositor->state == WESTON_COMPOSITOR_SLEEPING)
+ {
+ surface->inhibit_idling = false;
+ shell_fade(shsurf->shell, FADE_OUT);
+ }
+}
+
+static void
+surface_stop_inhibiting_notify(struct wl_listener *listener, void *data)
+{
+ struct shell_surface *shsurf =
+ wl_container_of(listener, shsurf, stop_inhibiting_listener);
+ struct weston_surface *surface =
+ weston_desktop_surface_get_surface(shsurf->desktop_surface);
+
+ surface->inhibit_idling = true;
+}
+
+static void
desktop_surface_added(struct weston_desktop_surface *desktop_surface,
void *shell)
{
@@ -2341,6 +2374,15 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,
wl_list_init(&shsurf->workspace_transform.link);
+ shsurf->start_inhibiting_listener.notify =
+ surface_start_inhibiting_notify;
+ wl_signal_add(&surface->start_inhibiting_signal,
+ &shsurf->start_inhibiting_listener);
+ shsurf->stop_inhibiting_listener.notify =
+ surface_stop_inhibiting_notify;
+ wl_signal_add(&surface->stop_inhibiting_signal,
+ &shsurf->stop_inhibiting_listener);
+
weston_desktop_surface_set_user_data(desktop_surface, shsurf);
weston_desktop_surface_set_activated(desktop_surface,
shsurf->focus_count > 0);
@@ -2358,6 +2400,12 @@ desktop_surface_removed(struct weston_desktop_surface *desktop_surface,
if (!shsurf)
return;
+ if (surface->inhibit_idling)
+ surface_stop_inhibiting_notify(&shsurf->stop_inhibiting_listener, surface);
+
+ wl_list_remove(&shsurf->start_inhibiting_listener.link);
+ wl_list_remove(&shsurf->stop_inhibiting_listener.link);
+
wl_signal_emit(&shsurf->destroy_signal, shsurf);
if (shsurf->fullscreen.black_view)
@@ -3849,6 +3897,7 @@ shell_fade(struct desktop_shell *shell, enum fade_type type)
{
float tint;
struct shell_output *shell_output;
+ uint32_t inhibit_mask = weston_compositor_inhibited_outputs(shell->compositor);
switch (type) {
case FADE_IN:
@@ -3864,6 +3913,9 @@ shell_fade(struct desktop_shell *shell, enum fade_type type)
/* Create a separate fade surface for each output */
wl_list_for_each(shell_output, &shell->output_list, link) {
+ if (inhibit_mask & (1 << shell_output->output->id))
+ continue;
+
shell_output->fade.type = type;
if (shell_output->fade.view == NULL) {
@@ -3959,12 +4011,17 @@ shell_fade_init(struct desktop_shell *shell)
return;
wl_list_for_each(shell_output, &shell->output_list, link) {
+ uint32_t inhibit_mask = weston_compositor_inhibited_outputs(shell->compositor);
+
if (shell_output->fade.view != NULL) {
weston_log("%s: warning: fade surface already exists\n",
__func__);
continue;
}
+ if (inhibit_mask & (1 << shell_output->output->id))
+ continue;
+
shell_output->fade.view = shell_fade_create_surface_for_output(shell, shell_output);
if (!shell_output->fade.view)
continue;
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 75081a37..bf889200 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -3932,7 +3932,10 @@ bind_subcompositor(struct wl_client *client,
compositor, NULL);
}
-/** Set a DPMS mode on all of the compositor's outputs
+/** Apply a DPMS mode to the compositor's outputs.
+ *
+ * Outputs may skip setting the DPMS state if they are being used to
+ * display an surface that is requesting idle behaviors be inhibited.
*
* \param compositor The compositor instance
* \param state The DPMS state the outputs will be set to