window: Track and report input and opaque regions

We just set the input region to the bounding box of the window frame
and set the opaque region to be the opaque rectangle inside the window
if the child widget is opaque.
This commit is contained in:
Kristian Høgsberg 2012-02-23 17:30:45 -05:00
parent dd631c1c36
commit 010f98b083
8 changed files with 63 additions and 22 deletions

View file

@ -315,7 +315,6 @@ gears_create(struct display *display)
gears->d = display;
gears->window = window_create(display);
gears->widget = frame_create(gears->window, gears);
window_set_transparent(gears->window, 1);
window_set_title(gears->window, "Wayland Gears");
gears->display = display_get_egl_display(gears->d);

View file

@ -2272,6 +2272,7 @@ terminal_create(struct display *display, int fullscreen)
terminal->window = window_create(display);
terminal->widget = frame_create(terminal->window, terminal);
window_set_title(terminal->window, "Wayland Terminal");
widget_set_transparent(terminal->widget, 0);
init_state_machine(&terminal->state_machine);
init_color_table(terminal);

View file

@ -62,11 +62,6 @@ redraw_handler(struct widget *widget, void *data)
PopplerPage *page;
double width, height, doc_aspect, window_aspect, scale;
if (view->fullscreen)
window_set_transparent(view->window, 0);
else
window_set_transparent(view->window, 1);
widget_get_allocation(view->widget, &allocation);
surface = window_get_surface(view->window);

View file

@ -85,6 +85,7 @@ struct display {
struct wl_list input_list;
struct wl_list output_list;
cairo_surface_t *active_frame, *inactive_frame, *shadow;
int frame_radius;
struct xkb_desc *xkb;
cairo_surface_t **pointer_surfaces;
@ -111,6 +112,8 @@ struct window {
struct window *parent;
struct wl_surface *surface;
struct wl_shell_surface *shell_surface;
struct wl_region *input_region;
struct wl_region *opaque_region;
char *title;
struct rectangle allocation, saved_allocation, server_allocation;
struct rectangle pending_allocation;
@ -152,6 +155,7 @@ struct widget {
widget_motion_handler_t motion_handler;
widget_button_handler_t button_handler;
void *user_data;
int opaque;
};
struct input {
@ -827,6 +831,9 @@ window_attach_surface(struct window *window)
return;
}
wl_surface_set_input_region(window->surface, window->input_region);
wl_surface_set_opaque_region(window->surface, window->opaque_region);
wl_surface_damage(window->surface, 0, 0,
window->allocation.width,
window->allocation.height);
@ -953,6 +960,11 @@ window_destroy(struct window *window)
input->focus_widget = NULL;
}
if (window->input_region)
wl_region_destroy(window->input_region);
if (window->opaque_region)
wl_region_destroy(window->opaque_region);
if (window->frame)
frame_destroy(window->frame);
@ -1002,6 +1014,7 @@ widget_create(struct window *window, void *data)
widget->user_data = data;
widget->allocation = window->allocation;
wl_list_init(&widget->child_list);
widget->opaque = 0;
return widget;
}
@ -1063,6 +1076,12 @@ widget_set_allocation(struct widget *widget,
widget_set_size(widget, width, height);
}
void
widget_set_transparent(struct widget *widget, int transparent)
{
widget->opaque = !transparent;
}
void *
widget_get_user_data(struct widget *widget)
{
@ -1140,7 +1159,9 @@ frame_resize_handler(struct widget *widget,
struct frame *frame = data;
struct widget *child = frame->child;
struct rectangle allocation;
struct display *display = widget->window->display;
int decoration_width, decoration_height;
int opaque_margin;
if (widget->window->type == TYPE_TOPLEVEL) {
decoration_width = 20 + frame->margin * 2;
@ -1150,6 +1171,15 @@ frame_resize_handler(struct widget *widget,
allocation.y = 50 + frame->margin;
allocation.width = width - decoration_width;
allocation.height = height - decoration_height;
widget->window->input_region =
wl_compositor_create_region(display->compositor);
wl_region_add(widget->window->input_region,
frame->margin, frame->margin,
width - 2 * frame->margin,
height - 2 * frame->margin);
opaque_margin = frame->margin + display->frame_radius;
} else {
decoration_width = 0;
decoration_height = 0;
@ -1158,6 +1188,16 @@ frame_resize_handler(struct widget *widget,
allocation.y = 0;
allocation.width = width;
allocation.height = height;
opaque_margin = 0;
}
if (child->opaque) {
widget->window->opaque_region =
wl_compositor_create_region(display->compositor);
wl_region_add(widget->window->opaque_region,
opaque_margin, opaque_margin,
width - 2 * opaque_margin,
height - 2 * opaque_margin);
}
widget_set_allocation(child, allocation.x, allocation.y,
@ -2024,6 +2064,16 @@ idle_resize(struct task *task, uint32_t events)
window->pending_allocation.width,
window->pending_allocation.height);
if (window->input_region) {
wl_region_destroy(window->input_region);
window->input_region = NULL;
}
if (window->opaque_region) {
wl_region_destroy(window->opaque_region);
window->opaque_region = NULL;
}
if (widget->resize_handler)
widget->resize_handler(widget,
widget->allocation.width,
@ -2238,12 +2288,6 @@ window_set_close_handler(struct window *window,
window->close_handler = handler;
}
void
window_set_transparent(struct window *window, int transparent)
{
window->transparent = transparent;
}
void
window_set_title(struct window *window, const char *title)
{
@ -2300,6 +2344,8 @@ window_create_internal(struct display *display, struct window *parent)
window->saved_allocation = window->allocation;
window->transparent = 1;
window->type = TYPE_TOPLEVEL;
window->input_region = NULL;
window->opaque_region = NULL;
if (display->dpy)
#ifdef HAVE_CAIRO_EGL
@ -2709,14 +2755,14 @@ display_handle_global(struct wl_display *display, uint32_t id,
static void
display_render_frame(struct display *d)
{
int radius = 8;
cairo_t *cr;
d->frame_radius = 8;
d->shadow = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
cr = cairo_create(d->shadow);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
rounded_rect(cr, 16, 16, 112, 112, radius);
rounded_rect(cr, 16, 16, 112, 112, d->frame_radius);
cairo_fill(cr);
cairo_destroy(cr);
blur_surface(d->shadow, 64);
@ -2726,7 +2772,7 @@ display_render_frame(struct display *d)
cr = cairo_create(d->active_frame);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0.8, 0.8, 0.4, 1);
rounded_rect(cr, 16, 16, 112, 112, radius);
rounded_rect(cr, 16, 16, 112, 112, d->frame_radius);
cairo_fill(cr);
cairo_destroy(cr);
@ -2735,7 +2781,7 @@ display_render_frame(struct display *d)
cr = cairo_create(d->inactive_frame);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1);
rounded_rect(cr, 16, 16, 112, 112, radius);
rounded_rect(cr, 16, 16, 112, 112, d->frame_radius);
cairo_fill(cr);
cairo_destroy(cr);
}

View file

@ -321,6 +321,8 @@ widget_set_allocation(struct widget *widget,
void
widget_set_size(struct widget *widget, int32_t width, int32_t height);
void
widget_set_transparent(struct widget *widget, int transparent);
void
widget_schedule_resize(struct widget *widget, int32_t width, int32_t height);
void *

View file

@ -188,7 +188,6 @@ create_wscreensaver_instance(struct wscreensaver *screensaver,
return NULL;
}
window_set_transparent(mi->window, 0);
window_set_title(mi->window, progname);
if (screensaver->interface) {

View file

@ -1168,7 +1168,8 @@ surface_attach(struct wl_client *client,
if (es->geometry.width != buffer->width ||
es->geometry.height != buffer->height) {
undef_region(&es->input);
undef_region(&es->opaque);
pixman_region32_fini(&es->opaque);
pixman_region32_init(&es->opaque);
}
if (es->output == NULL) {
@ -1268,7 +1269,7 @@ surface_set_input_region(struct wl_client *client,
struct wl_resource *region_resource)
{
struct weston_surface *surface = resource->data;
struct weston_region *region = region_resource->data;
struct weston_region *region;
if (region_resource) {
region = region_resource->data;

View file

@ -222,11 +222,9 @@ static int
test(void)
{
struct weston_matrix m;
struct weston_matrix n;
double det, errsup;
randomize_matrix(&m);
n = m;
det = determinant(&m);
errsup = test_inverse(&m);
@ -237,7 +235,7 @@ test(void)
return TEST_NOT_INVERTIBLE_OK;
printf("test fail, det: %g, error sup: %g\n", det, errsup);
/* print_matrix(&n);*/
return TEST_FAIL;
}