[PATCH 8/9] compositor: Handle background and panel surface in clone mode
Xiong Zhang
xiong.y.zhang at intel.com
Thu Feb 13 23:17:43 PST 2014
The background and panel view of slave output can't exist on
layer_list and view_list, otherwise panel is mess.
When unplugging a master, one slave may become master, the slave's
background and panel view should be moved to view_list.
When plugging a master, one old master may become slave, the old
master's background and panel view should be removed from view_list
Signed-off-by: Xiong Zhang <xiong.y.zhang at intel.com>
---
desktop-shell/shell.c | 70 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 57 insertions(+), 13 deletions(-)
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 096d618..2bc1856 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -60,6 +60,8 @@ struct shell_output {
struct desktop_shell *shell;
struct weston_output *output;
uint32_t mark_dirty;
+ struct weston_view *panel_view;
+ struct weston_view *background_view;
struct wl_listener role_change_listener;
struct wl_listener destroy_listener;
struct wl_list link;
@@ -2066,15 +2068,16 @@ static int
get_output_panel_height(struct desktop_shell *shell,
struct weston_output *output)
{
- struct weston_view *view;
+ struct shell_output *shell_output;
int panel_height = 0;
if (!output)
return 0;
- wl_list_for_each(view, &shell->panel_layer.view_list, layer_link) {
- if (view->surface->output == output) {
- panel_height = view->surface->height;
+ wl_list_for_each(shell_output, &shell->output_list, link) {
+ if (shell_output->output == output) {
+ panel_height =
+ shell_output->panel_view->surface->height;
break;
}
}
@@ -3654,7 +3657,8 @@ configure_static_view(struct weston_view *ev, struct weston_layer *layer)
weston_view_set_position(ev, ev->output->x, ev->output->y);
- if (wl_list_empty(&ev->layer_link)) {
+ if (wl_list_empty(&ev->layer_link) &&
+ !ev->output->is_slave) {
wl_list_insert(&layer->view_list, &ev->layer_link);
weston_compositor_schedule_repaint(ev->surface->compositor);
}
@@ -3681,6 +3685,7 @@ desktop_shell_set_background(struct wl_client *client,
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
struct weston_view *view, *next;
+ struct shell_output *shell_output;
if (surface->configure) {
wl_resource_post_error(surface_resource,
@@ -3697,6 +3702,12 @@ desktop_shell_set_background(struct wl_client *client,
surface->configure_private = shell;
surface->output = wl_resource_get_user_data(output_resource);
view->output = surface->output;
+
+ wl_list_for_each(shell_output, &shell->output_list, link) {
+ if (shell_output->output == view->output)
+ shell_output->background_view = view;
+ }
+
desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
@@ -3724,6 +3735,7 @@ desktop_shell_set_panel(struct wl_client *client,
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
struct weston_view *view, *next;
+ struct shell_output *shell_output;
if (surface->configure) {
wl_resource_post_error(surface_resource,
@@ -3740,6 +3752,12 @@ desktop_shell_set_panel(struct wl_client *client,
surface->configure_private = shell;
surface->output = wl_resource_get_user_data(output_resource);
view->output = surface->output;
+
+ wl_list_for_each(shell_output, &shell->output_list, link) {
+ if (shell_output->output == view->output)
+ shell_output->panel_view = view;
+ }
+
desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
@@ -5625,15 +5643,30 @@ handle_output_role_change(struct wl_listener *listener, void *data)
container_of(listener, struct shell_output,
role_change_listener);
struct weston_output *output = (struct weston_output *)data;
+ struct desktop_shell *shell = shell_output->shell;
/* Output change from master to slave. */
- if (output->is_slave)
+ if (output->is_slave) {
+ wl_list_remove(&shell_output->background_view->layer_link);
+ wl_list_init(&shell_output->background_view->layer_link);
+ wl_list_remove(&shell_output->panel_view->layer_link);
+ wl_list_init(&shell_output->panel_view->layer_link);
+
/* Mark views on this old master as dirty.
* But we will use new master as target output,
* At this point, new master doesn't have panel view
* and background view. So the desktop shell doesn't ready.
* So we delay the mark dirty work until desktop shell ready. */
shell_output->mark_dirty = 1;
+ } else {
+ /* Output change from slave to master. */
+ wl_list_insert(&shell->background_layer.view_list,
+ &shell_output->background_view->layer_link);
+ wl_list_insert(&shell->panel_layer.view_list,
+ &shell_output->panel_view->layer_link);
+
+ output->repaint_scheduled = 0;
+ }
}
static void
@@ -5734,6 +5767,24 @@ shell_destroy(struct wl_listener *listener, void *data)
struct workspace **ws;
struct shell_output *shell_output, *tmp;
+ wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) {
+ /* Restore slave output's panel view and background view to
+ * correct layer, otherwise when client destroy slave output's
+ * panel surface and background surface, segment failure will
+ * happen in weston_view_destroy(). */
+ if (wl_list_empty(&shell_output->background_view->layer_link))
+ wl_list_insert(&shell->background_layer.view_list,
+ &shell_output->background_view->layer_link);
+ if (wl_list_empty(&shell_output->panel_view->layer_link))
+ wl_list_insert(&shell->panel_layer.view_list,
+ &shell_output->panel_view->layer_link);
+
+ wl_list_remove(&shell_output->destroy_listener.link);
+ wl_list_remove(&shell_output->role_change_listener.link);
+ wl_list_remove(&shell_output->link);
+ free(shell_output);
+ }
+
/* Force state to unlocked so we don't try to fade */
shell->locked = false;
if (shell->child.client)
@@ -5744,13 +5795,6 @@ shell_destroy(struct wl_listener *listener, void *data)
input_panel_destroy(shell);
- wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) {
- wl_list_remove(&shell_output->destroy_listener.link);
- wl_list_remove(&shell_output->role_change_listener.link);
- wl_list_remove(&shell_output->link);
- free(shell_output);
- }
-
wl_list_remove(&shell->output_create_listener.link);
wl_array_for_each(ws, &shell->workspaces.array)
--
1.8.3.2
More information about the wayland-devel
mailing list