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.
Kristian Høgsberg 13 years ago
parent dd631c1c36
commit 010f98b083
  1. 1
      clients/gears.c
  2. 1
      clients/terminal.c
  3. 5
      clients/view.c
  4. 66
      clients/window.c
  5. 2
      clients/window.h
  6. 1
      clients/wscreensaver.c
  7. 5
      src/compositor.c
  8. 4
      tests/matrix-test.c

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

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

@ -62,11 +62,6 @@ redraw_handler(struct widget *widget, void *data)
PopplerPage *page; PopplerPage *page;
double width, height, doc_aspect, window_aspect, scale; 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); widget_get_allocation(view->widget, &allocation);
surface = window_get_surface(view->window); surface = window_get_surface(view->window);

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

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

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

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

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

Loading…
Cancel
Save