libweston: require connected heads for input devices
The use case driving this change is a clone mode setup, where the user
is hotplugging or unplugging a cloned touchscreen. Even if the output
and head are force-enabled, the touch device should still follow the
connector connection status. If there is no video signal for the
touchscreen (disconnected connector), then the touch input should be
ignored as well.
When the output is force-enabled, we need to trigger
output_heads_changed from connector status changes. If the head or
output are not force-enabled, the compositor will likely attach and
detach the head as appropriate. In clone mode, the attach or detach
needs to trigger output_heads_changed directly. In other cases, it may
be handled through the output getting enabled or disabled which are
different signals.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
diff --git a/libweston/compositor.c b/libweston/compositor.c
index a9de4ac..dbf61ef 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -4463,15 +4463,40 @@
head->name = strdup(name);
}
+/** Send output heads changed signal
+ *
+ * \param output The output that changed.
+ *
+ * Notify that the enabled output gained and/or lost heads, or that the
+ * associated heads may have changed their connection status. This does not
+ * include cases where the output becomes enabled or disabled. The registered
+ * callbacks are called after the change has successfully happened.
+ *
+ * If connection status change causes the compositor to attach or detach a head
+ * to an enabled output, the registered callbacks may be called multiple times.
+ */
+static void
+weston_output_emit_heads_changed(struct weston_output *output)
+{
+ wl_signal_emit(&output->compositor->output_heads_changed_signal,
+ output);
+}
+
/** Idle task for emitting heads_changed_signal */
static void
weston_compositor_call_heads_changed(void *data)
{
struct weston_compositor *compositor = data;
+ struct weston_head *head;
compositor->heads_changed_source = NULL;
wl_signal_emit(&compositor->heads_changed_signal, compositor);
+
+ wl_list_for_each(head, &compositor->head_list, compositor_link) {
+ if (head->output && head->output->enabled)
+ weston_output_emit_heads_changed(head->output);
+ }
}
/** Schedule a call on idle to heads_changed callback
@@ -4678,6 +4703,8 @@
weston_log("Output '%s' updated to have head(s) %s\n",
output->name, head_names);
free(head_names);
+
+ weston_output_emit_heads_changed(output);
}
return 0;
@@ -4723,6 +4750,8 @@
weston_log("Output '%s' updated to have head(s) %s\n",
output->name, head_names);
free(head_names);
+
+ weston_output_emit_heads_changed(output);
}
}
}
@@ -6255,6 +6284,7 @@
wl_signal_init(&ec->output_moved_signal);
wl_signal_init(&ec->output_resized_signal);
wl_signal_init(&ec->heads_changed_signal);
+ wl_signal_init(&ec->output_heads_changed_signal);
wl_signal_init(&ec->session_signal);
ec->session_active = 1;