diff --git a/clients/gears.c b/clients/gears.c index 3b4f3d36..2353837d 100644 --- a/clients/gears.c +++ b/clients/gears.c @@ -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); diff --git a/clients/terminal.c b/clients/terminal.c index 7eb1dc2b..e57a77de 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -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); diff --git a/clients/view.c b/clients/view.c index 95f80e39..918d22fe 100644 --- a/clients/view.c +++ b/clients/view.c @@ -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); diff --git a/clients/window.c b/clients/window.c index 8c5d17bc..c8c6ebea 100644 --- a/clients/window.c +++ b/clients/window.c @@ -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); } diff --git a/clients/window.h b/clients/window.h index 301c86e6..d3816732 100644 --- a/clients/window.h +++ b/clients/window.h @@ -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 * diff --git a/clients/wscreensaver.c b/clients/wscreensaver.c index 414b8c9d..53c4512b 100644 --- a/clients/wscreensaver.c +++ b/clients/wscreensaver.c @@ -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) { diff --git a/src/compositor.c b/src/compositor.c index b45a8181..80ee2ba2 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -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; diff --git a/tests/matrix-test.c b/tests/matrix-test.c index 6fdab839..8e9d13f1 100644 --- a/tests/matrix-test.c +++ b/tests/matrix-test.c @@ -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; }