diff --git a/src/compositor.c b/src/compositor.c index 7de7a02c..cbfba737 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -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; diff --git a/src/compositor.h b/src/compositor.h index d16053dd..b995b13a 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -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, diff --git a/src/shell.c b/src/shell.c index cf94e8e1..92196994 100644 --- a/src/shell.c +++ b/src/shell.c @@ -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; }