compositor: Compute overlapped early and base hw cursor decision on that
diff --git a/src/compositor.c b/src/compositor.c
index 7de7a02..cbfba73 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -595,13 +595,30 @@
 	pixman_region32_fini(&repaint);
 }
 
+WL_EXPORT struct wl_list *
+weston_compositor_top(struct weston_compositor *compositor)
+{
+	struct weston_input_device *input_device;
+	struct wl_list *list;
+
+	input_device = (struct weston_input_device *) compositor->input_device;
+
+	/* Insert below pointer */
+	list = &compositor->surface_list;
+	if (list->next == &input_device->sprite->link)
+		list = list->next;
+
+	return list;
+}
+
 static void
 weston_surface_raise(struct weston_surface *surface)
 {
 	struct weston_compositor *compositor = surface->compositor;
+	struct wl_list *list = weston_compositor_top(compositor);
 
 	wl_list_remove(&surface->link);
-	wl_list_insert(&compositor->surface_list, &surface->link);
+	wl_list_insert(list, &surface->link);
 	weston_compositor_repick(compositor);
 	weston_surface_damage(surface);
 }
@@ -707,13 +724,12 @@
 
 static void
 weston_output_set_cursor(struct weston_output *output,
-			 struct wl_input_device *dev, int force_sw)
+			 struct wl_input_device *dev)
 {
-	struct weston_compositor *ec = output->compositor;
 	struct weston_input_device *device =
 		(struct weston_input_device *) dev;
 	pixman_region32_t cursor_region;
-	int use_hardware_cursor = 1, prior_was_hardware;
+	int prior_was_hardware;
 
 	if (device->sprite == NULL)
 		return;
@@ -730,25 +746,20 @@
 		goto out;
 	}
 
-	prior_was_hardware = wl_list_empty(&device->sprite->link);
-	if (force_sw || output->set_hardware_cursor(output, device) < 0) {
+	prior_was_hardware = device->hw_cursor;
+	if (device->sprite->overlapped ||
+	    output->set_hardware_cursor(output, device) < 0) {
 		if (prior_was_hardware) {
 			weston_surface_damage(device->sprite);
 			output->set_hardware_cursor(output, NULL);
 		}
-		use_hardware_cursor = 0;
-	} else if (!prior_was_hardware) {
-		weston_surface_damage_below(device->sprite);
-	}
-
-	/* Remove always to be on top. */
-	wl_list_remove(&device->sprite->link);
-	if (!use_hardware_cursor && ec->focus) {
-		wl_list_insert(&ec->surface_list, &device->sprite->link);
-		device->sprite->output = output;
+		device->hw_cursor = 0;
 	} else {
-		wl_list_init(&device->sprite->link);
-		device->sprite->output = NULL;
+		if (!prior_was_hardware)
+			weston_surface_damage_below(device->sprite);
+		pixman_region32_fini(&device->sprite->damage);
+		pixman_region32_init(&device->sprite->damage);
+		device->hw_cursor = 1;
 	}
 
 out:
@@ -765,21 +776,14 @@
 
 	glViewport(0, 0, output->current->width, output->current->height);
 
-	weston_output_set_cursor(output, ec->input_device,
-			       ec->fade.spring.current >= 0.001);
+	if (ec->fade.spring.current >= 0.001)
+		solid_surface_init(&solid, output, ec->fade.spring.current);
 
 	pixman_region32_init(&new_damage);
 	pixman_region32_init(&opaque);
 	pixman_region32_init(&overlap);
 
-	if (ec->fade.spring.current >= 0.001)
-		solid_surface_init(&solid, output, ec->fade.spring.current);
-
 	wl_list_for_each(es, &ec->surface_list, link) {
-		pixman_region32_subtract(&es->damage, &es->damage, &opaque);
-		pixman_region32_union(&new_damage, &new_damage, &es->damage);
-		pixman_region32_union(&opaque, &opaque, &es->opaque);
-
 		pixman_region32_init(&surface_overlap);
 		pixman_region32_intersect_rect(&surface_overlap,
 					       &overlap, es->x, es->y,
@@ -790,6 +794,14 @@
 					   es->width, es->height);
 	}
 
+	weston_output_set_cursor(output, ec->input_device);
+
+	wl_list_for_each(es, &ec->surface_list, link) {
+		pixman_region32_subtract(&es->damage, &es->damage, &opaque);
+		pixman_region32_union(&new_damage, &new_damage, &es->damage);
+		pixman_region32_union(&opaque, &opaque, &es->opaque);
+	}
+
 	pixman_region32_init(&total_damage);
 	pixman_region32_union(&total_damage, &new_damage,
 			      &output->previous_damage);
@@ -1517,7 +1529,8 @@
 			weston_surface_create(compositor,
 					    device->input_device.x,
 					    device->input_device.y, 32, 32);
-		wl_list_init(&device->sprite->link);
+		wl_list_insert(&compositor->surface_list,
+			       &device->sprite->link);
 	}
 
 	buffer = buffer_resource->data;
diff --git a/src/compositor.h b/src/compositor.h
index d16053d..b995b13 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -96,6 +96,7 @@
 	int32_t hotspot_x, hotspot_y;
 	struct wl_list link;
 	uint32_t modifier_state;
+	int hw_cursor;
 
 	uint32_t num_tp;
 	struct wl_surface *touch_focus;
@@ -339,6 +340,8 @@
 			      struct weston_input_device *device,
 			      uint32_t time,
 			      uint32_t key, uint32_t button, int32_t state);
+struct wl_list *
+weston_compositor_top(struct weston_compositor *compositor);
 
 struct weston_surface *
 weston_surface_create(struct weston_compositor *compositor,
diff --git a/src/shell.c b/src/shell.c
index cf94e8e..9219699 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -952,6 +952,7 @@
 {
 	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
 	struct weston_compositor *compositor = shell->compositor;
+	struct wl_list *list;
 
 	weston_surface_activate(es, device, time);
 
@@ -977,12 +978,13 @@
 		break;
 	default:
 		if (!shell->locked) {
+			list = weston_compositor_top(compositor);
+
 			/* bring panel back to top */
 			struct shell_surface *panel;
 			wl_list_for_each(panel, &shell->panels, link) {
 				wl_list_remove(&panel->surface->link);
-				wl_list_insert(&compositor->surface_list,
-					       &panel->surface->link);
+				wl_list_insert(list, &panel->surface->link);
 			}
 		}
 	}
@@ -1119,7 +1121,7 @@
 		list = &shell->hidden_surface_list;
 		do_configure = 0;
 	} else {
-		list = &compositor->surface_list;
+		list = weston_compositor_top(compositor);
 		do_configure = 1;
 	}