[PATCH 4/6] src/compositor.c shell.c: restroe app run on default and unplugged output

Xiong Zhang xiong.y.zhang at intel.com
Thu Oct 17 04:10:51 CEST 2013


if the unplugged output is the first default output, the second output
will move to the first working as default output. Mark the surface on
unplaugged output as dirty, so the next output repaint, these surface
will reassign output and get the right output.
At the same time when moving output, the surface on moved output should
be moved also.

Signed-off-by: Xiong Zhang <xiong.y.zhang at intel.com>
---
 src/compositor.c | 17 +++++++++++++++++
 src/shell.c      | 44 +++++++++++++++++++++++++++++---------------
 2 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 990a378..155cfa3 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2836,6 +2836,13 @@ weston_output_transform_scale_init(struct weston_output *output, uint32_t transf
 WL_EXPORT void
 weston_output_move(struct weston_output *output, int x, int y)
 {
+	struct weston_surface *surface;
+	struct weston_layer   *layer;
+	int offset_x, offset_y;
+
+	offset_x = x - output->x;
+	offset_y = y - output->y;
+
 	output->x = x;
 	output->y = y;
 
@@ -2843,6 +2850,16 @@ weston_output_move(struct weston_output *output, int x, int y)
 	pixman_region32_init_rect(&output->region, x, y,
 				  output->width,
 				  output->height);
+	output->dirty = 1;
+
+	wl_list_for_each(layer, &output->compositor->layer_list, link) {
+		wl_list_for_each(surface, &layer->surface_list, layer_link) {
+			if (surface->output == output)
+				weston_surface_set_position(surface,
+						surface->geometry.x + offset_x,
+						surface->geometry.y + offset_y);
+		}
+	}
 }
 
 WL_EXPORT void
diff --git a/src/shell.c b/src/shell.c
index c9035d4..a32c37b 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -4493,11 +4493,18 @@ clamp_coordinate(struct weston_output *target_output,
 	return result;
 }
 
+/* if destroyed output is default output, marking surface run on this output */
+/* is dirty, so that the next repaint will assign this surface to right output */
+/* if destroyed output isn't default output, move surface run on this output */
+/* to default output */
 static void
 handle_surface_on_destroyed_output(struct weston_surface *surface,
 					struct weston_output *target_output)
 {
 	int32_t rel_x, rel_y;
+	struct weston_output *default_output;
+
+	default_output = get_default_output(surface->compositor);
 
 	clamp_coordinate(target_output, surface->output,
 			&surface->geometry.x,
@@ -4506,9 +4513,12 @@ handle_surface_on_destroyed_output(struct weston_surface *surface,
 	rel_x = surface->geometry.x - surface->output->x;
 	rel_y = surface->geometry.y - surface->output->y;
 
-	weston_surface_set_position(surface,
-				target_output->x + rel_x,
-				target_output->y + rel_y);
+	if (target_output == default_output)
+		weston_surface_set_position(surface,
+					target_output->x + rel_x,
+					target_output->y + rel_y);
+	else
+		weston_surface_geometry_dirty(surface);
 }
 
 static void
@@ -4535,13 +4545,15 @@ handle_output_destroy(struct wl_listener *listener, void *data)
 	free(output_listener);
 
 	default_output = get_default_output(wc);
-	/* if default output is the only output in output_list, or destroyed
-	   output is default output, return*/
-	if ((default_output->link.prev == default_output->link.next) ||
-		(default_output == output))
+	/* if default output is the only output in output_list, return*/
+	if (default_output->link.prev == default_output->link.next)
 		return;
 
-	target_output = default_output;
+	if (default_output != output)
+		target_output = default_output;
+	else
+		target_output = container_of(output->link.next,
+					struct weston_output, link);
 
 	/*if surface on destroyed output, move it to target output*/
 	for (i = 0; i < shell->workspaces.num; i++) {
@@ -4602,15 +4614,17 @@ handle_output_destroy(struct wl_listener *listener, void *data)
 					seat->pointer->x = wl_fixed_from_double(pointer_x);
 					seat->pointer->y = wl_fixed_from_double(pointer_y);
 				}
-				dx = wl_fixed_from_int(target_output->x - output->x);
-				dy = wl_fixed_from_int(target_output->y - output->y);
-				seat->pointer->x += dx;
-				seat->pointer->y += dy;
-				if (seat->pointer->sprite)
-					handle_surface_on_destroyed_output(seat->pointer->sprite, target_output);
+				if (target_output == default_output) {
+					dx = wl_fixed_from_int(target_output->x - output->x);
+					dy = wl_fixed_from_int(target_output->y - output->y);
+					seat->pointer->x += dx;
+					seat->pointer->y += dy;
+					if (seat->pointer->sprite)
+						handle_surface_on_destroyed_output(seat->pointer->sprite, target_output);
+				}
 				seat->pointer->grab->interface->focus(seat->pointer->grab);
 				seat->pointer->grab->interface->motion(seat->pointer->grab,
-									weston_compositor_get_time());
+										weston_compositor_get_time());
 			}
 		}
 	}
-- 
1.8.3.2



More information about the wayland-devel mailing list