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.zh...@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 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel