diff options
author | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-12-19 15:29:14 -0200 |
---|---|---|
committer | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-12-28 14:26:32 -0200 |
commit | 9c5153e02f379238a203e27acf8a74735906e16f (patch) | |
tree | 7a0dab23728dcfa72b7d1b0aa0635ecda7145797 | |
parent | 34a86fc44fb78ecce0e291a79ad964475a5b000f (diff) |
xwayland: Fix opaque and input region settings
This patch brings back a feature we removed previously (#1 opaque region box)
and fix the input region settings, which was broken.
Tested-by: Scott Moreau <oreaus@gmail.com>
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
-rw-r--r-- | clients/xwm.c | 56 | ||||
-rw-r--r-- | protocol/xserver.xml | 24 | ||||
-rw-r--r-- | src/xwayland/window-manager.c | 49 |
3 files changed, 98 insertions, 31 deletions
diff --git a/clients/xwm.c b/clients/xwm.c index 58e16f7..0805991 100644 --- a/clients/xwm.c +++ b/clients/xwm.c @@ -39,6 +39,7 @@ struct xwm { struct wl_registry *registry; struct wl_display *wl_display; + struct wl_compositor *compositor; struct wm *wm; struct wm_xwin *wm_xwin; struct display *display; @@ -793,20 +794,18 @@ xwm_window_draw_decoration(struct xwm_window *window) { struct xwm_wm *wm = window->wm; struct theme *t = wm->theme; + struct wl_region *region; cairo_t *cr; int x, y, width, height; const char *title; uint32_t flags = 0; if (window->frame_id == XCB_WINDOW_NONE) { -#if 0 - if (window->surface != NULL) { - window->surface->opaque_rect[0] = 0.0; - window->surface->opaque_rect[1] = 1.0; - window->surface->opaque_rect[2] = 0.0; - window->surface->opaque_rect[3] = 1.0; - } -#endif + xwm_window_get_frame_size(window, &width, &height); + region = wl_compositor_create_region(wm->xwm->compositor); + wl_region_add(region, 0, 0, width, height); + wm_xwin_set_opaque_override(window->xwin, region); + wl_region_destroy(region); return; } @@ -840,28 +839,20 @@ xwm_window_draw_decoration(struct xwm_window *window) xcb_flush(window->wm->conn); cairo_destroy(cr); -#if 0 - if (window->surface) { - pixman_region32_fini(&window->surface->pending.opaque); - pixman_region32_init_rect(&window->surface->pending.opaque, 0, 0, - width, height); - - /* We leave an extra pixel around the X window area to - * make sure we don't sample from the undefined alpha - * channel when filtering. */ - pixman_region32_intersect_rect(&window->surface->pending.opaque, - &window->surface->pending.opaque, - x - 1, y - 1, - window->width + 2, - window->height + 2); - window->surface->geometry.dirty = 1; - - pixman_region32_init_rect(&window->surface->input, - t->margin, t->margin, - width - 2 * t->margin, - height - 2 * t->margin); - } -#endif + + region = wl_compositor_create_region(wm->xwm->compositor); + /* We leave an extra pixel around the X window area to make sure we + * don't sample from the undefined alpha channel when filtering. */ + wl_region_add(region, x - 1, y - 1, + window->width + 2, window->height + 2); + wm_xwin_set_opaque_override(window->xwin_frame, region); + wl_region_destroy(region); + + region = wl_compositor_create_region(wm->xwm->compositor); + wl_region_add(region, t->margin, t->margin, + width - 2 * t->margin, height - 2 * t->margin); + wm_xwin_set_input_region(window->xwin_frame, region); + wl_region_destroy(region); } static void @@ -1594,7 +1585,10 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, { struct xwm *xwm = data; - if (!strcmp(interface, "wm")) { + if (strcmp(interface, "wl_compositor") == 0) { + xwm->compositor = wl_registry_bind(registry, id, + &wl_compositor_interface, 1); + } else if (!strcmp(interface, "wm")) { xwm->wm = wl_registry_bind(registry, id, &wm_interface, 1); wm_add_listener(xwm->wm, &wm_listener, xwm); diff --git a/protocol/xserver.xml b/protocol/xserver.xml index e92b0e6..dc9c0a3 100644 --- a/protocol/xserver.xml +++ b/protocol/xserver.xml @@ -130,6 +130,30 @@ <arg name="flags" type="uint"/> </request> + <request name="set_opaque_override"> + <description summary="set opaque override region"> + Textures coming from X windows usually have their X window as RGBx, + i.e. 32 bit with an undefined alpha channel for the content part while + the decorations are rendered with a well-defined alpha channel. On + this case set_opaque_override is needed for marking a rectangle in a + texture and force the alpha = 1.0. + + This is different from the wl_surface.set_opaque_region, where that + one is meant only as a hint for optimization while this is a necessity + for painting XWayland windows right. Therefore X must never use + wl_surface.set_opaque_region either. + </description> + + <arg name="region" type="object" interface="wl_region"/> + </request> + + <request name="set_input_region"> + <description summary="set window input region"> + </description> + + <arg name="region" type="object" interface="wl_region" allow-null="true"/> + </request> + <request name="move"> </request> diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 19f1309..eb27228 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -156,6 +156,52 @@ wm_xwin_handle_set_window(struct wl_client *client, } static void +wm_xwin_handle_opaque_override(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *region_resource) +{ + struct xserver_window *window = resource->data; + struct weston_surface *surface = + (struct weston_surface *) window->surface; + struct weston_region *region; + + if (!region_resource) { + weston_log("Region resource not provided\n"); + return; + } + region = region_resource->data; + + if (!surface) + return; + + pixman_region32_copy(&surface->pending.opaque, ®ion->region); + surface->geometry.dirty = 1; +} + +static void +wm_xwin_handle_input_region(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *region_resource) +{ + struct xserver_window *window = resource->data; + struct weston_surface *surface = + (struct weston_surface *) window->surface; + struct weston_region *region; + + if (!region_resource) { + weston_log("Region resource not provided\n"); + return; + } + region = region_resource->data; + + if (!surface) + return; + + pixman_region32_copy(&surface->pending.input, ®ion->region); + surface->geometry.dirty = 1; +} + +static void wm_xwin_handle_move(struct wl_client *client, struct wl_resource *resource) { struct xserver_window *window = resource->data; @@ -207,6 +253,8 @@ wm_xwin_handle_destroy(struct wl_client *client, struct wl_resource *resource) const struct wm_xwin_interface wm_xwin_implementation = { wm_xwin_handle_map, wm_xwin_handle_set_window, + wm_xwin_handle_opaque_override, + wm_xwin_handle_input_region, wm_xwin_handle_move, wm_xwin_handle_resize, wm_xwin_handle_destroy @@ -287,6 +335,7 @@ wm_handle_create_xwindow(struct wl_client *client, return; } + window->surface = NULL; window->shsurf = NULL; window->wxs = wxs; window->xid = xid; |