window: Track and report input and opaque regions
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 23 Feb 2012 22:30:45 +0000 (17:30 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 23 Feb 2012 22:30:54 +0000 (17:30 -0500)
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.

clients/gears.c
clients/terminal.c
clients/view.c
clients/window.c
clients/window.h
clients/wscreensaver.c
src/compositor.c
tests/matrix-test.c

index 3b4f3d3..2353837 100644 (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);
index 7eb1dc2..e57a77d 100644 (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);
index 95f80e3..918d22f 100644 (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);
index 8c5d17b..c8c6ebe 100644 (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,
@@ -2239,12 +2289,6 @@ window_set_close_handler(struct window *window,
 }
 
 void
-window_set_transparent(struct window *window, int transparent)
-{
-       window->transparent = transparent;
-}
-
-void
 window_set_title(struct window *window, const char *title)
 {
        free(window->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);
 }
index 301c86e..d381673 100644 (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 *
index 414b8c9..53c4512 100644 (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) {
index b45a818..80ee2ba 100644 (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;
index 6fdab83..8e9d13f 100644 (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;
 }