compositor: call configure on surfaces with a null buffer too
This way the shell can know when a surface has been unmapped by
checking the value returned by weston_surface_is_mapped(surface).
The configure handlers have now width and height parameters, so
they do not need anymore to check manually the buffer size.
If a surface's buffer is NULL the width and height passed to the
configure are both 0.
Configure is now only called after an attach. The variable
weston_surface.pending.newly_attached is set to 1 on attach, and
after the configure call is reset to 0.
diff --git a/src/compositor.c b/src/compositor.c
index 5ff68d7..8f523a8 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -290,6 +290,7 @@
surface->pending.buffer_transform = surface->buffer_transform;
surface->output = NULL;
surface->plane = &compositor->primary_plane;
+ surface->pending.newly_attached = 0;
pixman_region32_init(&surface->damage);
pixman_region32_init(&surface->opaque);
@@ -1279,12 +1280,10 @@
surface->pending.sx = sx;
surface->pending.sy = sy;
surface->pending.buffer = buffer;
+ surface->pending.newly_attached = 1;
if (buffer) {
wl_signal_add(&buffer->resource.destroy_signal,
&surface->pending.buffer_destroy_listener);
- surface->pending.remove_contents = 0;
- } else {
- surface->pending.remove_contents = 1;
}
}
@@ -1397,6 +1396,8 @@
{
struct weston_surface *surface = resource->data;
pixman_region32_t opaque;
+ int buffer_width = 0;
+ int buffer_height = 0;
if (surface->pending.sx || surface->pending.sy ||
(surface->pending.buffer &&
@@ -1407,14 +1408,21 @@
surface->buffer_transform = surface->pending.buffer_transform;
/* wl_surface.attach */
- if (surface->pending.buffer || surface->pending.remove_contents)
+ if (surface->pending.buffer || surface->pending.newly_attached)
weston_surface_attach(surface, surface->pending.buffer);
- if (surface->buffer_ref.buffer && surface->configure)
+ if (surface->buffer_ref.buffer) {
+ buffer_width = weston_surface_buffer_width(surface);
+ buffer_height = weston_surface_buffer_height(surface);
+ }
+
+ if (surface->configure && surface->pending.newly_attached)
surface->configure(surface, surface->pending.sx,
- surface->pending.sy);
+ surface->pending.sy, buffer_width, buffer_height);
+
surface->pending.sx = 0;
surface->pending.sy = 0;
+ surface->pending.newly_attached = 0;
/* wl_surface.damage */
pixman_region32_union(&surface->damage, &surface->damage,
@@ -2158,11 +2166,14 @@
static void
pointer_cursor_surface_configure(struct weston_surface *es,
- int32_t dx, int32_t dy)
+ int32_t dx, int32_t dy, int32_t width, int32_t height)
{
struct weston_seat *seat = es->private;
int x, y;
+ if (width == 0)
+ return;
+
assert(es == seat->sprite);
seat->hotspot_x -= dx;
@@ -2172,8 +2183,7 @@
y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y;
weston_surface_configure(seat->sprite, x, y,
- es->buffer_ref.buffer->width,
- es->buffer_ref.buffer->height);
+ width, height);
empty_region(&es->pending.input);
@@ -2240,7 +2250,8 @@
seat->hotspot_y = y;
if (surface->buffer_ref.buffer)
- pointer_cursor_surface_configure(surface, 0, 0);
+ pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
+ weston_surface_buffer_height(surface));
}
static const struct wl_pointer_interface pointer_interface = {
@@ -2618,14 +2629,13 @@
}
static void
-drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
empty_region(&es->pending.input);
weston_surface_configure(es,
es->geometry.x + sx, es->geometry.y + sy,
- es->buffer_ref.buffer->width,
- es->buffer_ref.buffer->height);
+ width, height);
}
static int
diff --git a/src/compositor.h b/src/compositor.h
index 676e0d9..00d3b22 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -455,7 +455,7 @@
/* All the pending state, that wl_surface.commit will apply. */
struct {
/* wl_surface.attach */
- int remove_contents;
+ int newly_attached;
struct wl_buffer *buffer;
struct wl_listener buffer_destroy_listener;
int32_t sx;
@@ -482,7 +482,7 @@
* a new buffer has been set up for this surface. The integer params
* are the sx and sy paramerters supplied to surface::attach .
*/
- void (*configure)(struct weston_surface *es, int32_t sx, int32_t sy);
+ void (*configure)(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height);
void *private;
};
diff --git a/src/shell.c b/src/shell.c
index 6573038..3da5321 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1636,7 +1636,7 @@
}
static void
-black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy);
+black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height);
static struct weston_surface *
create_black_surface(struct weston_compositor *ec,
@@ -2032,7 +2032,7 @@
}
static void
-shell_surface_configure(struct weston_surface *, int32_t, int32_t);
+shell_surface_configure(struct weston_surface *, int32_t, int32_t, int32_t, int32_t);
static struct shell_surface *
get_shell_surface(struct weston_surface *surface)
@@ -2193,10 +2193,13 @@
}
static void
-configure_static_surface(struct weston_surface *es, struct weston_layer *layer)
+configure_static_surface(struct weston_surface *es, struct weston_layer *layer, int32_t width, int32_t height)
{
struct weston_surface *s, *next;
+ if (width == 0)
+ return;
+
wl_list_for_each_safe(s, next, &layer->surface_list, layer_link) {
if (s->output == es->output && s != es) {
weston_surface_unmap(s);
@@ -2204,9 +2207,7 @@
}
}
- weston_surface_configure(es, es->output->x, es->output->y,
- weston_surface_buffer_width(es),
- weston_surface_buffer_height(es));
+ weston_surface_configure(es, es->output->x, es->output->y, width, height);
if (wl_list_empty(&es->layer_link)) {
wl_list_insert(&layer->surface_list, &es->layer_link);
@@ -2215,11 +2216,11 @@
}
static void
-background_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+background_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct desktop_shell *shell = es->private;
- configure_static_surface(es, &shell->background_layer);
+ configure_static_surface(es, &shell->background_layer, width, height);
}
static void
@@ -2248,11 +2249,11 @@
}
static void
-panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+panel_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct desktop_shell *shell = es->private;
- configure_static_surface(es, &shell->panel_layer);
+ configure_static_surface(es, &shell->panel_layer, width, height);
}
static void
@@ -2281,10 +2282,13 @@
}
static void
-lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct desktop_shell *shell = surface->private;
+ if (width == 0)
+ return;
+
center_on_output(surface, get_default_output(shell->compositor));
if (!weston_surface_is_mapped(surface)) {
@@ -2738,7 +2742,7 @@
/* no-op func for checking black surface */
static void
-black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
}
@@ -3178,14 +3182,16 @@
}
static void
-shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct shell_surface *shsurf = get_shell_surface(es);
struct desktop_shell *shell = shsurf->shell;
- int32_t width = weston_surface_buffer_width(es);
- int32_t height = weston_surface_buffer_height(es);
+
int type_changed = 0;
+ if (width == 0)
+ return;
+
if (shsurf->next_type != SHELL_SURFACE_NONE &&
shsurf->type != shsurf->next_type) {
set_surface_type(shsurf);
@@ -3298,10 +3304,13 @@
}
static void
-screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct desktop_shell *shell = surface->private;
+ if (width == 0)
+ return;
+
/* XXX: starting weston-screensaver beforehand does not work */
if (!shell->locked)
return;
@@ -3369,13 +3378,14 @@
}
static void
-input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct weston_mode *mode;
- int32_t width = weston_surface_buffer_width(surface);
- int32_t height = weston_surface_buffer_height(surface);
float x, y;
+ if (width == 0)
+ return;
+
if (!weston_surface_is_mapped(surface))
return;
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index 9006b19..a125bbc 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -124,17 +124,13 @@
static void
tablet_shell_surface_configure(struct weston_surface *surface,
- int32_t sx, int32_t sy)
+ int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct tablet_shell *shell = get_shell(surface->compositor);
- int32_t width, height;
- if (weston_surface_is_mapped(surface))
+ if (weston_surface_is_mapped(surface) || width == 0)
return;
- width = surface->buffer_ref.buffer->width;
- height = surface->buffer_ref.buffer->height;
-
weston_surface_configure(surface, 0, 0, width, height);
if (surface == shell->lockscreen_surface) {
diff --git a/tests/weston-test.c b/tests/weston-test.c
index 83a7124..08833e0 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -74,7 +74,7 @@
}
static void
-test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct weston_test_surface *test_surface = surface->private;
struct weston_test *test = test_surface->test;
@@ -85,8 +85,8 @@
surface->geometry.x = test_surface->x;
surface->geometry.y = test_surface->y;
- surface->geometry.width = surface->buffer_ref.buffer->width;
- surface->geometry.height = surface->buffer_ref.buffer->height;
+ surface->geometry.width = width;
+ surface->geometry.height = height;
surface->geometry.dirty = 1;
if (!weston_surface_is_mapped(surface))