compositor: Move views when outputs are moved

Previously, when an output was moved due to another output being
unplugged, the views on the first output would remain in the same
position.

This patch adds an output_move signal that the views listen too in
order to repostion themselves in the event of an unplug.

Signed-off-by: Zhang, Xiong Y <xiong.y.zhang@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
diff --git a/src/compositor.c b/src/compositor.c
index 36985d7..2f2c838 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -345,6 +345,26 @@
 static struct weston_subsurface *
 weston_surface_to_subsurface(struct weston_surface *surface);
 
+static void
+weston_view_output_move_handler(struct wl_listener *listener,
+				void *data)
+{
+	struct weston_view *ev;
+	struct weston_output *output = data;
+
+	ev = container_of(listener, struct weston_view,
+			  output_move_listener);
+
+	/* the child window's view->geometry is a relative coordinate to
+	 * parent view, no need to move child_view. */
+	if (ev->geometry.parent)
+		return;
+
+	weston_view_set_position(ev,
+				 ev->geometry.x + output->move_x,
+				 ev->geometry.y + output->move_y);
+}
+
 WL_EXPORT struct weston_view *
 weston_view_create(struct weston_surface *surface)
 {
@@ -380,6 +400,8 @@
 
 	view->output = NULL;
 
+	view->output_move_listener.notify = weston_view_output_move_handler;
+
 	return view;
 }
 
@@ -727,6 +749,7 @@
 	}
 }
 
+
 static void
 weston_surface_assign_output(struct weston_surface *es)
 {
@@ -793,6 +816,13 @@
 	}
 	pixman_region32_fini(&region);
 
+	if (ev->output_mask != 0)
+		wl_list_remove(&ev->output_move_listener.link);
+
+	if (mask != 0)
+		wl_signal_add(&new_output->move_signal,
+			      &ev->output_move_listener);
+
 	ev->output = new_output;
 	ev->output_mask = mask;
 
@@ -1233,6 +1263,8 @@
 	wl_list_init(&view->layer_link);
 	wl_list_remove(&view->link);
 	wl_list_init(&view->link);
+	wl_list_remove(&view->output_move_listener.link);
+	wl_list_init(&view->output_move_listener.link);
 	view->output_mask = 0;
 	weston_surface_assign_output(view->surface);
 
@@ -3152,8 +3184,8 @@
 	output->height /= scale;
 }
 
-WL_EXPORT void
-weston_output_move(struct weston_output *output, int x, int y)
+static void
+weston_output_init_geometry(struct weston_output *output, int x, int y)
 {
 	output->x = x;
 	output->y = y;
@@ -3165,6 +3197,41 @@
 }
 
 WL_EXPORT void
+weston_output_move(struct weston_output *output, int x, int y)
+{
+	pixman_region32_t old_region;
+	struct wl_resource *resource;
+
+	output->move_x = x - output->x;
+	output->move_y = y - output->y;
+
+	if (output->move_x == 0 && output->move_y == 0)
+		return;
+
+	pixman_region32_init(&old_region);
+	pixman_region32_copy(&old_region, &output->region);
+
+	weston_output_init_geometry(output, x, y);
+
+	output->dirty = 1;
+
+	/* Move views on this output. */
+	wl_signal_emit(&output->move_signal, output);
+
+	/* Notify clients of the change for output position. */
+	wl_resource_for_each(resource, &output->resource_list)
+		wl_output_send_geometry(resource,
+					output->x,
+					output->y,
+					output->mm_width,
+					output->mm_height,
+					output->subpixel,
+					output->make,
+					output->model,
+					output->transform);
+}
+
+WL_EXPORT void
 weston_output_init(struct weston_output *output, struct weston_compositor *c,
 		   int x, int y, int mm_width, int mm_height, uint32_t transform,
 		   int32_t scale)
@@ -3180,11 +3247,12 @@
 	weston_output_transform_scale_init(output, transform, scale);
 	weston_output_init_zoom(output);
 
-	weston_output_move(output, x, y);
+	weston_output_init_geometry(output, x, y);
 	weston_output_damage(output);
 
 	wl_signal_init(&output->frame_signal);
 	wl_signal_init(&output->destroy_signal);
+	wl_signal_init(&output->move_signal);
 	wl_list_init(&output->animation_list);
 	wl_list_init(&output->resource_list);
 
diff --git a/src/compositor.h b/src/compositor.h
index 6bd637e..530de71 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -194,6 +194,8 @@
 	int dirty;
 	struct wl_signal frame_signal;
 	struct wl_signal destroy_signal;
+	struct wl_signal move_signal;
+	int move_x, move_y;
 	uint32_t frame_time;
 	int disable_planes;
 
@@ -803,6 +805,8 @@
 	 * displayed on.
 	 */
 	uint32_t output_mask;
+
+	struct wl_listener output_move_listener;
 };
 
 struct weston_surface {