summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-03-02 08:14:40 -0500
committerKristian Høgsberg <krh@bitplanet.net>2012-03-02 08:14:40 -0500
commitf98d903b6d3bc87ecaa652596a306373597aeab6 (patch)
tree99ace232081812a57fbb9544dab9e16f1a0fdf0f
parentb9747d02c61adb28261c03ffdb584ce8fbed22b5 (diff)
parent32bed57d5a27aee6ba6df1a5b101f5fbd1af44b6 (diff)
Merge branch 'layers'
I was integrating patches on the 'layers' branch and had a fixed version of the fullscreen patch there. My master branch had the fullscreen patch with the resize bug, and when I pushed I meant to push the layers branch to master. Conflicts: src/shell.c
-rw-r--r--src/compositor-drm.c5
-rw-r--r--src/compositor-wayland.c5
-rw-r--r--src/compositor-x11.c5
-rw-r--r--src/compositor.c235
-rw-r--r--src/compositor.h26
-rw-r--r--src/shell.c234
6 files changed, 247 insertions, 263 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index cfaad15..d2a5652 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -214,7 +214,8 @@ drm_output_prepare_scanout_surface(struct drm_output *output)
}
static void
-drm_output_repaint(struct weston_output *output_base)
+drm_output_repaint(struct weston_output *output_base,
+ pixman_region32_t *damage)
{
struct drm_output *output = (struct drm_output *) output_base;
struct drm_compositor *compositor =
@@ -235,7 +236,7 @@ drm_output_repaint(struct weston_output *output_base)
drm_output_prepare_scanout_surface(output);
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
- weston_surface_draw(surface, &output->base);
+ weston_surface_draw(surface, &output->base, damage);
glFlush();
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index f8b5a32..f23c357 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -329,7 +329,8 @@ static const struct wl_callback_listener frame_listener = {
};
static void
-wayland_output_repaint(struct weston_output *output_base)
+wayland_output_repaint(struct weston_output *output_base,
+ pixman_region32_t *damage)
{
struct wayland_output *output = (struct wayland_output *) output_base;
struct wayland_compositor *compositor =
@@ -344,7 +345,7 @@ wayland_output_repaint(struct weston_output *output_base)
}
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
- weston_surface_draw(surface, &output->base);
+ weston_surface_draw(surface, &output->base, damage);
draw_border(output);
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 53998d2..c227063 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -186,7 +186,8 @@ x11_compositor_fini_egl(struct x11_compositor *compositor)
}
static void
-x11_output_repaint(struct weston_output *output_base)
+x11_output_repaint(struct weston_output *output_base,
+ pixman_region32_t *damage)
{
struct x11_output *output = (struct x11_output *)output_base;
struct x11_compositor *compositor =
@@ -200,7 +201,7 @@ x11_output_repaint(struct weston_output *output_base)
}
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
- weston_surface_draw(surface, &output->base);
+ weston_surface_draw(surface, &output->base, damage);
eglSwapBuffers(compositor->base.display, output->egl_surface);
diff --git a/src/compositor.c b/src/compositor.c
index 069ea74..0c99a5f 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -211,6 +211,7 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->surface.resource.destroy_listener_list);
wl_list_init(&surface->link);
+ wl_list_init(&surface->layer_link);
wl_list_init(&surface->buffer_link);
surface->surface.resource.client = NULL;
@@ -225,6 +226,7 @@ weston_surface_create(struct weston_compositor *compositor)
pixman_region32_init(&surface->damage);
pixman_region32_init(&surface->opaque);
+ pixman_region32_init(&surface->clip);
undef_region(&surface->input);
pixman_region32_init(&surface->transform.opaque);
wl_list_init(&surface->frame_callback_list);
@@ -281,17 +283,15 @@ surface_to_global_float(struct weston_surface *surface,
WL_EXPORT void
weston_surface_damage_below(struct weston_surface *surface)
{
- struct weston_surface *below;
-
- if (surface->output == NULL)
- return;
-
- if (surface->link.next == &surface->compositor->surface_list)
- return;
+ struct weston_compositor *compositor = surface->compositor;
+ pixman_region32_t damage;
- below = container_of(surface->link.next, struct weston_surface, link);
- pixman_region32_union(&below->damage, &below->damage,
- &surface->transform.boundingbox);
+ pixman_region32_init(&damage);
+ pixman_region32_subtract(&damage, &surface->transform.boundingbox,
+ &surface->clip);
+ pixman_region32_union(&compositor->damage,
+ &compositor->damage, &damage);
+ pixman_region32_fini(&damage);
}
static void
@@ -510,21 +510,6 @@ weston_surface_damage(struct weston_surface *surface)
weston_compositor_schedule_repaint(surface->compositor);
}
-static void
-weston_surface_flush_damage(struct weston_surface *surface)
-{
- struct weston_surface *below;
-
- if (surface->output &&
- surface->link.next != &surface->compositor->surface_list) {
- below = container_of(surface->link.next,
- struct weston_surface, link);
-
- pixman_region32_union(&below->damage,
- &below->damage, &surface->damage);
- }
-}
-
WL_EXPORT void
weston_surface_configure(struct weston_surface *surface,
GLfloat x, GLfloat y, int width, int height)
@@ -613,11 +598,18 @@ weston_compositor_repick(struct weston_compositor *compositor)
static void
weston_surface_unmap(struct weston_surface *surface)
{
+ struct wl_input_device *device = surface->compositor->input_device;
+
weston_surface_damage_below(surface);
- weston_surface_flush_damage(surface);
surface->output = NULL;
wl_list_remove(&surface->link);
+ wl_list_remove(&surface->layer_link);
weston_compositor_repick(surface->compositor);
+
+ if (device->keyboard_focus == &surface->surface)
+ wl_input_device_set_keyboard_focus(device, NULL,
+ weston_compositor_get_time());
+
weston_compositor_schedule_repaint(surface->compositor);
}
@@ -647,6 +639,7 @@ destroy_surface(struct wl_resource *resource)
pixman_region32_fini(&surface->transform.boundingbox);
pixman_region32_fini(&surface->damage);
pixman_region32_fini(&surface->opaque);
+ pixman_region32_fini(&surface->clip);
if (!region_is_undefined(&surface->input))
pixman_region32_fini(&surface->input);
@@ -762,7 +755,8 @@ texture_region(struct weston_surface *es, pixman_region32_t *region)
}
WL_EXPORT void
-weston_surface_draw(struct weston_surface *es, struct weston_output *output)
+weston_surface_draw(struct weston_surface *es, struct weston_output *output,
+ pixman_region32_t *damage)
{
struct weston_compositor *ec = es->compositor;
GLfloat *v;
@@ -771,12 +765,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
int n;
pixman_region32_init(&repaint);
- pixman_region32_intersect(&repaint, &es->transform.boundingbox,
- &output->region);
- pixman_region32_intersect(&repaint, &repaint, &es->damage);
-
- /* Clear damage, assume outputs do not overlap. */
- pixman_region32_subtract(&es->damage, &es->damage, &output->region);
+ pixman_region32_intersect(&repaint,
+ &es->transform.boundingbox, damage);
+ pixman_region32_subtract(&repaint, &repaint, &es->clip);
if (!pixman_region32_not_empty(&repaint))
goto out;
@@ -826,37 +817,15 @@ out:
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 (compositor->fade.surface &&
- list->next == &compositor->fade.surface->link)
- list = list->next;
- if (list->next == &input_device->sprite->link)
- list = list->next;
- if (input_device->drag_surface &&
- list->next == &input_device->drag_surface->link)
- list = list->next;
-
- return list;
-}
-
-static void
-weston_surface_raise(struct weston_surface *surface)
+WL_EXPORT void
+weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
{
struct weston_compositor *compositor = surface->compositor;
- struct wl_list *list = weston_compositor_top(compositor);
- wl_list_remove(&surface->link);
- wl_list_insert(list, &surface->link);
+ wl_list_remove(&surface->layer_link);
+ wl_list_insert(below, &surface->layer_link);
weston_compositor_repick(compositor);
+ weston_surface_damage_below(surface);
weston_surface_damage(surface);
}
@@ -883,14 +852,9 @@ WL_EXPORT void
weston_output_damage(struct weston_output *output)
{
struct weston_compositor *compositor = output->compositor;
- struct weston_surface *es;
-
- if (wl_list_empty(&compositor->surface_list))
- return;
- es = container_of(compositor->surface_list.next,
- struct weston_surface, link);
- pixman_region32_union(&es->damage, &es->damage, &output->region);
+ pixman_region32_union(&compositor->damage,
+ &compositor->damage, &output->region);
weston_compositor_schedule_repaint(compositor);
}
@@ -935,9 +899,10 @@ weston_output_repaint(struct weston_output *output, int msecs)
{
struct weston_compositor *ec = output->compositor;
struct weston_surface *es;
+ struct weston_layer *layer;
struct weston_animation *animation, *next;
struct weston_frame_callback *cb, *cnext;
- pixman_region32_t opaque, new_damage, total_damage;
+ pixman_region32_t opaque, new_damage, output_damage;
int32_t width, height;
weston_compositor_update_drag_surfaces(ec);
@@ -948,13 +913,14 @@ weston_output_repaint(struct weston_output *output, int msecs)
output->border.top + output->border.bottom;
glViewport(0, 0, width, height);
- pixman_region32_init(&new_damage);
- pixman_region32_init(&opaque);
-
- wl_list_for_each(es, &ec->surface_list, link)
- /* Update surface transform now to avoid calling it ever
- * again from the repaint sub-functions. */
- weston_surface_update_transform(es);
+ /* Rebuild the surface list and update surface transforms up front. */
+ wl_list_init(&ec->surface_list);
+ wl_list_for_each(layer, &ec->layer_list, link) {
+ wl_list_for_each(es, &layer->surface_list, layer_link) {
+ weston_surface_update_transform(es);
+ wl_list_insert(ec->surface_list.prev, &es->link);
+ }
+ }
if (output->assign_planes)
/*
@@ -965,33 +931,36 @@ weston_output_repaint(struct weston_output *output, int msecs)
*/
output->assign_planes(output);
+ pixman_region32_init(&new_damage);
+ pixman_region32_init(&opaque);
+
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);
+ empty_region(&es->damage);
+ pixman_region32_copy(&es->clip, &opaque);
pixman_region32_union(&opaque, &opaque, &es->transform.opaque);
}
- pixman_region32_init(&total_damage);
- pixman_region32_union(&total_damage, &new_damage,
- &output->previous_damage);
- pixman_region32_intersect(&output->previous_damage,
- &new_damage, &output->region);
+ pixman_region32_union(&ec->damage, &ec->damage, &new_damage);
+
+ pixman_region32_init(&output_damage);
+ pixman_region32_union(&output_damage,
+ &ec->damage, &output->previous_damage);
+ pixman_region32_copy(&output->previous_damage, &ec->damage);
+ pixman_region32_intersect(&output_damage,
+ &output_damage, &output->region);
+ pixman_region32_subtract(&ec->damage, &ec->damage, &output->region);
pixman_region32_fini(&opaque);
pixman_region32_fini(&new_damage);
- wl_list_for_each(es, &ec->surface_list, link) {
- pixman_region32_copy(&es->damage, &total_damage);
- pixman_region32_subtract(&total_damage,
- &total_damage, &es->transform.opaque);
- }
-
if (output->dirty)
weston_output_update_matrix(output);
- output->repaint(output);
+ output->repaint(output, &output_damage);
- pixman_region32_fini(&total_damage);
+ pixman_region32_fini(&output_damage);
output->repaint_needed = 0;
@@ -1026,6 +995,13 @@ weston_output_finish_frame(struct weston_output *output, int msecs)
}
WL_EXPORT void
+weston_layer_init(struct weston_layer *layer, struct wl_list *below)
+{
+ wl_list_init(&layer->surface_list);
+ wl_list_insert(below, &layer->link);
+}
+
+WL_EXPORT void
weston_compositor_schedule_repaint(struct weston_compositor *compositor)
{
struct weston_output *output;
@@ -1064,7 +1040,8 @@ weston_compositor_fade(struct weston_compositor *compositor, float tint)
surface = weston_surface_create(compositor);
weston_surface_configure(surface, 0, 0, 8192, 8192);
weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0);
- wl_list_insert(&compositor->surface_list, &surface->link);
+ wl_list_insert(&compositor->fade_layer.surface_list,
+ &surface->layer_link);
weston_surface_assign_output(surface);
compositor->fade.surface = surface;
pixman_region32_init(&surface->input);
@@ -1512,7 +1489,6 @@ WL_EXPORT void
weston_surface_activate(struct weston_surface *surface,
struct weston_input_device *device, uint32_t time)
{
- weston_surface_raise(surface);
wl_input_device_set_keyboard_focus(&device->input_device,
&surface->surface, time);
wl_data_device_set_keyboard_focus(&device->input_device);
@@ -1837,13 +1813,14 @@ input_device_attach(struct wl_client *client,
if (!buffer_resource && device->sprite->output) {
wl_list_remove(&device->sprite->link);
+ wl_list_remove(&device->sprite->layer_link);
device->sprite->output = NULL;
return;
}
if (!device->sprite->output) {
- wl_list_insert(&compositor->surface_list,
- &device->sprite->link);
+ wl_list_insert(&compositor->cursor_layer.surface_list,
+ &device->sprite->layer_link);
weston_surface_assign_output(device->sprite);
}
@@ -1856,12 +1833,25 @@ input_device_attach(struct wl_client *client,
buffer->width, buffer->height);
weston_buffer_attach(buffer, &device->sprite->surface);
+ weston_surface_damage(device->sprite);
}
const static struct wl_input_device_interface input_device_interface = {
input_device_attach,
};
+static void
+handle_drag_surface_destroy(struct wl_listener *listener,
+ struct wl_resource *resource, uint32_t time)
+{
+ struct weston_input_device *device;
+
+ device = container_of(listener, struct weston_input_device,
+ drag_surface_destroy_listener);
+
+ device->drag_surface = NULL;
+}
+
static void unbind_input_device(struct wl_resource *resource)
{
wl_list_remove(&resource->link);
@@ -1898,6 +1888,8 @@ weston_input_device_init(struct weston_input_device *device,
device->modifier_state = 0;
device->num_tp = 0;
+ device->drag_surface_destroy_listener.func = handle_drag_surface_destroy;
+
wl_list_insert(ec->input_device_list.prev, &device->link);
}
@@ -1913,6 +1905,42 @@ weston_input_device_release(struct weston_input_device *device)
wl_input_device_release(&device->input_device);
}
+static void
+device_setup_new_drag_surface(struct weston_input_device *device,
+ struct weston_surface *surface)
+{
+ struct wl_input_device *input_device = &device->input_device;
+
+ device->drag_surface = surface;
+
+ weston_surface_set_position(device->drag_surface,
+ input_device->x, input_device->y);
+
+ wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
+ &device->drag_surface_destroy_listener.link);
+}
+
+static void
+device_release_drag_surface(struct weston_input_device *device)
+{
+ undef_region(&device->drag_surface->input);
+ wl_list_remove(&device->drag_surface_destroy_listener.link);
+ device->drag_surface = NULL;
+}
+
+static void
+device_map_drag_surface(struct weston_input_device *device)
+{
+ if (device->drag_surface->output ||
+ !device->drag_surface->buffer)
+ return;
+
+ wl_list_insert(&device->sprite->layer_link,
+ &device->drag_surface->layer_link);
+ weston_surface_assign_output(device->drag_surface);
+ empty_region(&device->drag_surface->input);
+}
+
static void
weston_input_update_drag_surface(struct wl_input_device *input_device,
int dx, int dy)
@@ -1931,27 +1959,20 @@ weston_input_update_drag_surface(struct wl_input_device *input_device,
surface_changed = 1;
if (!input_device->drag_surface || surface_changed) {
- undef_region(&device->drag_surface->input);
- device->drag_surface = NULL;
+ device_release_drag_surface(device);
if (!surface_changed)
return;
}
if (!device->drag_surface || surface_changed) {
- device->drag_surface = (struct weston_surface *)
+ struct weston_surface *surface = (struct weston_surface *)
input_device->drag_surface;
-
- weston_surface_set_position(device->drag_surface,
- input_device->x, input_device->y);
+ device_setup_new_drag_surface(device, surface);
}
- if (device->drag_surface->output == NULL &&
- device->drag_surface->buffer) {
- wl_list_insert(&device->sprite->link,
- &device->drag_surface->link);
- weston_surface_assign_output(device->drag_surface);
- empty_region(&device->drag_surface->input);
- }
+ /* the client may not have attached a buffer to the drag surface
+ * when we setup it up, so check if map is needed on every update */
+ device_map_drag_surface(device);
/* the client may have attached a buffer with a different size to
* the drag surface, causing the input region to be reset */
@@ -2293,6 +2314,7 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
ec->bind_display(ec->display, ec->wl_display);
wl_list_init(&ec->surface_list);
+ wl_list_init(&ec->layer_list);
wl_list_init(&ec->input_device_list);
wl_list_init(&ec->output_list);
wl_list_init(&ec->binding_list);
@@ -2301,6 +2323,9 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
ec->fade.animation.frame = fade_frame;
wl_list_init(&ec->fade.animation.link);
+ weston_layer_init(&ec->fade_layer, &ec->layer_list);
+ weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
+
ec->screenshooter = screenshooter_create(ec);
wl_data_device_manager_init(ec->wl_display);
diff --git a/src/compositor.h b/src/compositor.h
index 8c57e4f..6f46249 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -91,7 +91,8 @@ struct weston_output {
struct weston_mode *current;
struct wl_list mode_list;
- void (*repaint)(struct weston_output *output);
+ void (*repaint)(struct weston_output *output,
+ pixman_region32_t *damage);
void (*destroy)(struct weston_output *output);
void (*assign_planes)(struct weston_output *output);
@@ -106,6 +107,7 @@ struct weston_input_device {
struct weston_compositor *compositor;
struct weston_surface *sprite;
struct weston_surface *drag_surface;
+ struct wl_listener drag_surface_destroy_listener;
int32_t hotspot_x, hotspot_y;
struct wl_list link;
uint32_t modifier_state;
@@ -162,6 +164,11 @@ enum {
struct screenshooter;
+struct weston_layer {
+ struct wl_list surface_list;
+ struct wl_list link;
+};
+
struct weston_compositor {
struct wl_shm *shm;
struct weston_xserver *wxs;
@@ -180,8 +187,12 @@ struct weston_compositor {
/* There can be more than one, but not right now... */
struct wl_input_device *input_device;
+ struct weston_layer fade_layer;
+ struct weston_layer cursor_layer;
+
struct wl_list output_list;
struct wl_list input_device_list;
+ struct wl_list layer_list;
struct wl_list surface_list;
struct wl_list binding_list;
struct wl_list animation_list;
@@ -198,8 +209,8 @@ struct weston_compositor {
int idle_time; /* effective timeout, s */
/* Repaint state. */
- struct timespec previous_swap;
struct wl_array vertices, indices;
+ pixman_region32_t damage;
uint32_t focus;
@@ -260,11 +271,13 @@ struct weston_surface {
struct wl_surface surface;
struct weston_compositor *compositor;
GLuint texture;
+ pixman_region32_t clip;
pixman_region32_t damage;
pixman_region32_t opaque;
pixman_region32_t input;
int32_t pitch;
struct wl_list link;
+ struct wl_list layer_link;
struct wl_list buffer_link;
struct weston_shader *shader;
GLfloat color[4];
@@ -341,7 +354,8 @@ void
weston_surface_activate(struct weston_surface *surface,
struct weston_input_device *device, uint32_t time);
void
-weston_surface_draw(struct weston_surface *es, struct weston_output *output);
+weston_surface_draw(struct weston_surface *es,
+ struct weston_output *output, pixman_region32_t *damage);
void
notify_motion(struct wl_input_device *device,
@@ -369,6 +383,9 @@ notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
int x, int y, int touch_type);
void
+weston_layer_init(struct weston_layer *layer, struct wl_list *below);
+
+void
weston_output_finish_frame(struct weston_output *output, int msecs);
void
weston_output_damage(struct weston_output *output);
@@ -421,6 +438,9 @@ weston_surface_configure(struct weston_surface *surface,
GLfloat x, GLfloat y, int width, int height);
void
+weston_surface_restack(struct weston_surface *surface, struct wl_list *below);
+
+void
weston_surface_set_position(struct weston_surface *surface,
GLfloat x, GLfloat y);
diff --git a/src/shell.c b/src/shell.c
index 5abfdb5..2b61202 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -42,6 +42,12 @@ struct wl_shell {
struct weston_compositor *compositor;
struct weston_shell shell;
+ struct weston_layer fullscreen_layer;
+ struct weston_layer panel_layer;
+ struct weston_layer toplevel_layer;
+ struct weston_layer background_layer;
+ struct weston_layer lock_layer;
+
struct {
struct weston_process process;
struct wl_client *client;
@@ -56,7 +62,6 @@ struct wl_shell {
struct shell_surface *lock_surface;
struct wl_listener lock_surface_listener;
- struct wl_list hidden_surface_list;
struct wl_list backgrounds;
struct wl_list panels;
@@ -93,7 +98,6 @@ struct shell_surface {
struct shell_surface *parent;
enum shell_surface_type type;
- enum shell_surface_type prev_type;
int32_t saved_x, saved_y;
bool saved_position_valid;
@@ -379,6 +383,8 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
shsurf->fullscreen.black_surface = NULL;
shsurf->fullscreen_output = NULL;
shsurf->surface->force_configure = 1;
+ weston_surface_set_position(shsurf->surface,
+ shsurf->saved_x, shsurf->saved_y);
}
static int
@@ -412,7 +418,6 @@ reset_shell_surface_type(struct shell_surface *surface)
break;
}
- surface->prev_type = surface->type;
surface->type = SHELL_SURFACE_NONE;
return 0;
}
@@ -545,11 +550,15 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
center_on_output(surface, output);
if (!shsurf->fullscreen.black_surface)
- shsurf->fullscreen.black_surface = create_black_surface(surface->compositor,
- output->x, output->y,
- output->current->width, output->current->height);
- wl_list_remove(&shsurf->fullscreen.black_surface->link);
- wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
+ shsurf->fullscreen.black_surface =
+ create_black_surface(surface->compositor,
+ output->x, output->y,
+ output->current->width,
+ output->current->height);
+
+ wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
+ wl_list_insert(&surface->layer_link,
+ &shsurf->fullscreen.black_surface->layer_link);
shsurf->fullscreen.black_surface->output = output;
switch (shsurf->fullscreen.type) {
@@ -580,22 +589,17 @@ shell_stack_fullscreen(struct shell_surface *shsurf)
{
struct weston_surface *surface = shsurf->surface;
struct wl_shell *shell = shell_surface_get_shell(shsurf);
- struct wl_list *list;
- wl_list_remove(&surface->link);
- wl_list_remove(&shsurf->fullscreen.black_surface->link);
+ wl_list_remove(&surface->layer_link);
+ wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
- if (shell->locked) {
- wl_list_insert(&shell->hidden_surface_list, &surface->link);
- wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
- } else {
- list = weston_compositor_top(surface->compositor);
- wl_list_insert(list, &surface->link);
- wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link);
+ wl_list_insert(&shell->fullscreen_layer.surface_list,
+ &surface->layer_link);
+ wl_list_insert(&surface->layer_link,
+ &shsurf->fullscreen.black_surface->layer_link);
- weston_surface_damage(surface);
- weston_surface_damage(shsurf->fullscreen.black_surface);
- }
+ weston_surface_damage(surface);
+ weston_surface_damage(shsurf->fullscreen.black_surface);
}
static void
@@ -623,17 +627,15 @@ shell_surface_set_fullscreen(struct wl_client *client,
if (reset_shell_surface_type(shsurf))
return;
- if (shsurf->prev_type != SHELL_SURFACE_FULLSCREEN) {
- shsurf->saved_x = es->geometry.x;
- shsurf->saved_y = es->geometry.y;
- shsurf->saved_position_valid = true;
- }
-
shsurf->fullscreen_output = shsurf->output;
shsurf->fullscreen.type = method;
shsurf->fullscreen.framerate = framerate;
shsurf->type = SHELL_SURFACE_FULLSCREEN;
+ shsurf->saved_x = es->geometry.x;
+ shsurf->saved_y = es->geometry.y;
+ shsurf->saved_position_valid = true;
+
if (es->output)
shsurf->surface->force_configure = 1;
@@ -860,7 +862,6 @@ shell_get_shell_surface(struct wl_client *client,
weston_matrix_init(&shsurf->rotation.rotation);
shsurf->type = SHELL_SURFACE_NONE;
- shsurf->prev_type = SHELL_SURFACE_NONE;
wl_client_add_resource(client, &shsurf->resource);
}
@@ -884,6 +885,11 @@ launch_screensaver(struct wl_shell *shell)
if (!shell->screensaver.path)
return;
+ if (shell->screensaver.process.pid != 0) {
+ fprintf(stderr, "old screensaver still running\n");
+ return;
+ }
+
weston_client_launch(shell->compositor,
&shell->screensaver.process,
shell->screensaver.path,
@@ -905,12 +911,12 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
struct wl_list *list;
if (shell->lock_surface)
- list = &shell->lock_surface->surface->link;
+ list = &shell->lock_surface->surface->layer_link;
else
- list = &shell->compositor->surface_list;
+ list = &shell->lock_layer.surface_list;
- wl_list_remove(&surface->surface->link);
- wl_list_insert(list, &surface->surface->link);
+ wl_list_remove(&surface->surface->layer_link);
+ wl_list_insert(list, &surface->surface->layer_link);
surface->surface->output = surface->output;
weston_surface_damage(surface->surface);
}
@@ -918,8 +924,8 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
static void
hide_screensaver(struct wl_shell *shell, struct shell_surface *surface)
{
- wl_list_remove(&surface->surface->link);
- wl_list_init(&surface->surface->link);
+ wl_list_remove(&surface->surface->layer_link);
+ wl_list_init(&surface->surface->layer_link);
surface->surface->output = NULL;
}
@@ -940,7 +946,7 @@ desktop_shell_set_background(struct wl_client *client,
wl_list_for_each(priv, &shell->backgrounds, link) {
if (priv->output == output_resource->data) {
priv->surface->output = NULL;
- wl_list_remove(&priv->surface->link);
+ wl_list_remove(&priv->surface->layer_link);
wl_list_remove(&priv->link);
break;
}
@@ -978,7 +984,7 @@ desktop_shell_set_panel(struct wl_client *client,
wl_list_for_each(priv, &shell->panels, link) {
if (priv->output == output_resource->data) {
priv->surface->output = NULL;
- wl_list_remove(&priv->surface->link);
+ wl_list_remove(&priv->surface->layer_link);
wl_list_remove(&priv->link);
break;
}
@@ -1038,8 +1044,6 @@ desktop_shell_set_lock_surface(struct wl_client *client,
static void
resume_desktop(struct wl_shell *shell)
{
- struct weston_surface *surface;
- struct wl_list *list;
struct shell_surface *tmp;
wl_list_for_each(tmp, &shell->screensaver.surfaces, link)
@@ -1047,21 +1051,12 @@ resume_desktop(struct wl_shell *shell)
terminate_screensaver(shell);
- wl_list_for_each(surface, &shell->hidden_surface_list, link)
- weston_surface_assign_output(surface);
-
- if (wl_list_empty(&shell->backgrounds)) {
- list = &shell->compositor->surface_list;
- } else {
- struct shell_surface *background;
- background = container_of(shell->backgrounds.prev,
- struct shell_surface, link);
- list = background->surface->link.prev;
- }
-
- if (!wl_list_empty(&shell->hidden_surface_list))
- wl_list_insert_list(list, &shell->hidden_surface_list);
- wl_list_init(&shell->hidden_surface_list);
+ wl_list_remove(&shell->lock_layer.link);
+ wl_list_insert(&shell->compositor->cursor_layer.link,
+ &shell->fullscreen_layer.link);
+ wl_list_insert(&shell->fullscreen_layer.link,
+ &shell->panel_layer.link);
+ wl_list_insert(&shell->panel_layer.link, &shell->toplevel_layer.link);
shell->locked = false;
weston_compositor_repick(shell->compositor);
@@ -1383,7 +1378,6 @@ 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);
@@ -1392,35 +1386,23 @@ activate(struct weston_shell *base, struct weston_surface *es,
switch (get_shell_surface_type(es)) {
case SHELL_SURFACE_BACKGROUND:
- /* put background back to bottom */
- wl_list_remove(&es->link);
- wl_list_insert(compositor->surface_list.prev, &es->link);
- break;
case SHELL_SURFACE_PANEL:
- /* already put on top */
+ case SHELL_SURFACE_LOCK:
break;
+
case SHELL_SURFACE_SCREENSAVER:
/* always below lock surface */
- if (shell->lock_surface) {
- wl_list_remove(&es->link);
- wl_list_insert(&shell->lock_surface->surface->link,
- &es->link);
- }
+ if (shell->lock_surface)
+ weston_surface_restack(es,
+ &shell->lock_surface->surface->layer_link);
break;
case SHELL_SURFACE_FULLSCREEN:
/* should on top of panels */
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(list, &panel->surface->link);
- }
- }
+ weston_surface_restack(es,
+ &shell->toplevel_layer.surface_list);
+ break;
}
}
@@ -1451,9 +1433,6 @@ static void
lock(struct weston_shell *base)
{
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
- struct wl_list *surface_list = &shell->compositor->surface_list;
- struct weston_surface *cur;
- struct weston_surface *tmp;
struct weston_input_device *device;
struct shell_surface *shsurf;
struct weston_output *output;
@@ -1469,28 +1448,15 @@ lock(struct weston_shell *base)
shell->locked = true;
- /* Move all surfaces from compositor's list to our hidden list,
- * except the background. This way nothing else can show or
- * receive input events while we are locked. */
-
- if (!wl_list_empty(&shell->hidden_surface_list)) {
- fprintf(stderr,
- "%s: Assertion failed: hidden_surface_list is not empty.\n",
- __func__);
- }
-
- wl_list_for_each_safe(cur, tmp, surface_list, link) {
- /* skip input device sprites, cur->surface is uninitialised */
- if (cur->surface.resource.client == NULL)
- continue;
-
- if (get_shell_surface_type(cur) == SHELL_SURFACE_BACKGROUND)
- continue;
+ /* Hide all surfaces by removing the fullscreen, panel and
+ * toplevel layers. This way nothing else can show or receive
+ * input events while we are locked. */
- cur->output = NULL;
- wl_list_remove(&cur->link);
- wl_list_insert(shell->hidden_surface_list.prev, &cur->link);
- }
+ wl_list_remove(&shell->panel_layer.link);
+ wl_list_remove(&shell->toplevel_layer.link);
+ wl_list_remove(&shell->fullscreen_layer.link);
+ wl_list_insert(&shell->compositor->cursor_layer.link,
+ &shell->lock_layer.link);
launch_screensaver(shell);
@@ -1558,24 +1524,14 @@ map(struct weston_shell *base, struct weston_surface *surface,
{
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
struct weston_compositor *compositor = shell->compositor;
- struct wl_list *list;
struct shell_surface *shsurf;
enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
- int do_configure;
int panel_height = 0;
shsurf = get_shell_surface(surface);
if (shsurf)
surface_type = shsurf->type;
- if (shell->locked) {
- list = &shell->hidden_surface_list;
- do_configure = 0;
- } else {
- list = weston_compositor_top(compositor);
- do_configure = 1;
- }
-
surface->geometry.width = width;
surface->geometry.height = height;
surface->geometry.dirty = 1;
@@ -1618,19 +1574,19 @@ map(struct weston_shell *base, struct weston_surface *surface,
switch (surface_type) {
case SHELL_SURFACE_BACKGROUND:
/* background always visible, at the bottom */
- wl_list_insert(compositor->surface_list.prev, &surface->link);
- do_configure = 1;
+ wl_list_insert(&shell->background_layer.surface_list,
+ &surface->layer_link);
break;
case SHELL_SURFACE_PANEL:
/* panel always on top, hidden while locked */
- wl_list_insert(list, &surface->link);
+ wl_list_insert(&shell->panel_layer.surface_list,
+ &surface->layer_link);
break;
case SHELL_SURFACE_LOCK:
/* lock surface always visible, on top */
- wl_list_insert(&compositor->surface_list, &surface->link);
-
+ wl_list_insert(&shell->lock_layer.surface_list,
+ &surface->layer_link);
weston_compositor_wake(compositor);
- do_configure = 1;
break;
case SHELL_SURFACE_SCREENSAVER:
/* If locked, show it. */
@@ -1641,32 +1597,20 @@ map(struct weston_shell *base, struct weston_surface *surface,
if (!shell->lock_surface)
compositor->state = WESTON_COMPOSITOR_IDLE;
}
- do_configure = 0;
break;
case SHELL_SURFACE_FULLSCREEN:
- do_configure = 1;
- break;
case SHELL_SURFACE_NONE:
- do_configure = 0;
break;
default:
- /* everything else just below the panel */
- if (!wl_list_empty(&shell->panels)) {
- struct shell_surface *panel =
- container_of(shell->panels.prev,
- struct shell_surface, link);
- wl_list_insert(&panel->surface->link, &surface->link);
- } else {
- wl_list_insert(list, &surface->link);
- }
+ wl_list_insert(&shell->toplevel_layer.surface_list,
+ &surface->layer_link);
+ break;
}
- if (do_configure) {
- weston_surface_assign_output(surface);
- weston_compositor_repick(compositor);
- if (surface_type == SHELL_SURFACE_MAXIMIZED)
- surface->output = shsurf->output;
- }
+ weston_surface_assign_output(surface);
+ weston_compositor_repick(compositor);
+ if (surface_type == SHELL_SURFACE_MAXIMIZED)
+ surface->output = shsurf->output;
switch (surface_type) {
case SHELL_SURFACE_TOPLEVEL:
@@ -1697,10 +1641,8 @@ configure(struct weston_shell *base, struct weston_surface *surface,
struct shell_surface *shsurf;
shsurf = get_shell_surface(surface);
- if (shsurf) {
+ if (shsurf)
surface_type = shsurf->type;
- prev_surface_type = shsurf->prev_type;
- }
surface->geometry.x = x;
surface->geometry.y = y;
@@ -1724,18 +1666,6 @@ configure(struct weston_shell *base, struct weston_surface *surface,
get_output_panel_height(shell,surface->output);
break;
case SHELL_SURFACE_TOPLEVEL:
- if (prev_surface_type != SHELL_SURFACE_TOPLEVEL) {
- if (shsurf->saved_position_valid &&
- shsurf->saved_x != surface->geometry.x &&
- shsurf->saved_y != surface->geometry.y) {
- weston_surface_set_position(surface,
- shsurf->saved_x,
- shsurf->saved_y);
- } else if (!shsurf->saved_position_valid) {
- weston_surface_set_position(surface, 10 + random() % 400,
- 10 + random() % 400);
- }
- }
break;
default:
break;
@@ -2071,11 +2001,17 @@ shell_init(struct weston_compositor *ec)
shell->shell.configure = configure;
shell->shell.destroy = shell_destroy;
- wl_list_init(&shell->hidden_surface_list);
wl_list_init(&shell->backgrounds);
wl_list_init(&shell->panels);
wl_list_init(&shell->screensaver.surfaces);
+ weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
+ weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
+ weston_layer_init(&shell->toplevel_layer, &shell->panel_layer.link);
+ weston_layer_init(&shell->background_layer,
+ &shell->toplevel_layer.link);
+ wl_list_init(&shell->lock_layer.surface_list);
+
shell_configuration(shell);
if (wl_display_add_global(ec->wl_display, &wl_shell_interface,