compositor: Compute overlapped early and base hw cursor decision on that
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 26 Jan 2012 06:03:58 +0000 (01:03 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 26 Jan 2012 06:03:58 +0000 (01:03 -0500)
src/compositor.c
src/compositor.h
src/shell.c

index 7de7a02..cbfba73 100644 (file)
@@ -595,13 +595,30 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
        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 @@ solid_surface_release(struct weston_surface *surface)
 
 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 @@ weston_output_set_cursor(struct weston_output *output,
                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 @@ weston_output_repaint(struct weston_output *output)
 
        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 @@ weston_output_repaint(struct weston_output *output)
                                           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 @@ input_device_attach(struct wl_client *client,
                        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;
index d16053d..b995b13 100644 (file)
@@ -96,6 +96,7 @@ struct weston_input_device {
        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 @@ weston_compositor_run_binding(struct weston_compositor *compositor,
                              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,
index cf94e8e..9219699 100644 (file)
@@ -952,6 +952,7 @@ activate(struct weston_shell *base, struct weston_surface *es,
 {
        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 @@ activate(struct weston_shell *base, struct weston_surface *es,
                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 @@ map(struct weston_shell *base,
                list = &shell->hidden_surface_list;
                do_configure = 0;
        } else {
-               list = &compositor->surface_list;
+               list = weston_compositor_top(compositor);
                do_configure = 1;
        }