diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-03 19:09:50 +0000 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-21 14:02:38 +0000 |
commit | 5eb95b986d7231678886b6c0db565c507c9de903 (patch) | |
tree | 31b78c2e21ad0b96263258727fd013b00e49c376 | |
parent | 5454711a0365522e44c5ad6258e9319898b2c1fc (diff) |
Get image of window with alpha channel, if available
Use xcb_composite_name_pixmap() to name the off-screen pixmap for the window,
replacing it with a new one when the window is mapped or resized. Also name the
composite pixmap for adopted windows.
(We need to be more careful than currently in MAP_NOTIFY. Always update the
name of the off-fscreen pixmap in MAP_NOTIFY, but only generate a
XCWM_EVENT_WINDOW_CREATE for override-redirect windows (since one was already
generated in MAP_REQUEST for non-override-redirect windows)
Ensure border width is zero, as border is included in composite pixmap image of
the window.
-rw-r--r-- | include/xcwm/window.h | 1 | ||||
-rw-r--r-- | src/libxcwm/event_loop.c | 58 | ||||
-rw-r--r-- | src/libxcwm/image.c | 5 | ||||
-rw-r--r-- | src/libxcwm/window.c | 6 |
4 files changed, 57 insertions, 13 deletions
diff --git a/include/xcwm/window.h b/include/xcwm/window.h index ad28790..6f1b98c 100644 --- a/include/xcwm/window.h +++ b/include/xcwm/window.h @@ -105,6 +105,7 @@ struct xcwm_window_t { int initial_damage; /* Set to 1 for override-redirect windows */ void *local_data; /* Area for data client cares about */ unsigned int opacity; + xcb_pixmap_t composite_pixmap_id; }; /** diff --git a/src/libxcwm/event_loop.c b/src/libxcwm/event_loop.c index 3c0d50b..75be677 100644 --- a/src/libxcwm/event_loop.c +++ b/src/libxcwm/event_loop.c @@ -30,6 +30,7 @@ #include <pthread.h> #include <xcwm/xcwm.h> +#include <xcb/composite.h> #include "xcwm_internal.h" /* Definition of abstract data type for event */ @@ -102,6 +103,24 @@ _xcwm_event_stop_loop(void) return 1; } +static void +_xcwm_window_composite_pixmap_release(xcwm_window_t *window) +{ + if (window->composite_pixmap_id) + { + xcb_free_pixmap(window->context->conn, window->composite_pixmap_id); + window->composite_pixmap_id = 0; + } +} + +static void +_xcwm_window_composite_pixmap_update(xcwm_window_t *window) +{ + _xcwm_window_composite_pixmap_release(window); + window->composite_pixmap_id = xcb_generate_id(window->context->conn); + xcb_composite_name_window_pixmap(window->context->conn, window->window_id, window->composite_pixmap_id); +} + /* Generate a XCWM_EVENT_WINDOW_CREATE event for all existing mapped top-level windows when we start @@ -136,6 +155,8 @@ _xcwm_windows_adopt(xcwm_context_t *context, xcwm_event_cb_t callback_ptr) continue; } + _xcwm_window_composite_pixmap_update(window); + xcwm_event_t *return_evt = malloc(sizeof(xcwm_event_t)); if (!return_evt) { continue; @@ -366,15 +387,28 @@ run_event_loop(void *thread_arg_struct) (xcb_map_notify_event_t *)evt; return_evt = malloc(sizeof(xcwm_event_t)); /* notify->event holds parent of the window */ - return_evt->window = - _xcwm_window_create(context, notify->window, - notify->event); - if (!return_evt->window) { - free(return_evt); - break; + + xcwm_window_t *window = + _xcwm_get_window_node_by_window_id(notify->window); + if (!window) + { + /* + No MAP_REQUEST for override-redirect windows, so + need to create the xcwm_window_t for it now + */ + printf("MAP_NOTIFY without MAP_REQUEST\n"); + window = + _xcwm_window_create(context, notify->window, + notify->event); + + _xcwm_window_composite_pixmap_update(window); + + return_evt->window = window; + return_evt->event_type = XCWM_EVENT_WINDOW_CREATE; + callback_ptr(return_evt); } - return_evt->event_type = XCWM_EVENT_WINDOW_CREATE; - callback_ptr(return_evt); + + _xcwm_window_composite_pixmap_update(window); break; } @@ -415,6 +449,8 @@ run_event_loop(void *thread_arg_struct) callback_ptr(return_evt); + _xcwm_window_composite_pixmap_release(window); + // Release memory for the window _xcwm_window_release(window); break; @@ -422,6 +458,12 @@ run_event_loop(void *thread_arg_struct) case XCB_CONFIGURE_NOTIFY: { + xcb_configure_notify_event_t *request = + (xcb_configure_notify_event_t *)evt; + xcwm_window_t *window = + _xcwm_get_window_node_by_window_id(request->window); + if (window) + _xcwm_window_composite_pixmap_update(window); break; } diff --git a/src/libxcwm/image.c b/src/libxcwm/image.c index 7b476fa..8389720 100644 --- a/src/libxcwm/image.c +++ b/src/libxcwm/image.c @@ -47,7 +47,7 @@ xcwm_image_copy_full(xcwm_window_t *window) xcb_flush(window->context->conn); /* Get the full image of the window */ image = xcb_image_get(window->context->conn, - window->window_id, + window->composite_pixmap_id, 0, 0, geom_reply->width, @@ -75,7 +75,6 @@ xcwm_image_copy_full(xcwm_window_t *window) xcwm_image_t * xcwm_image_copy_damaged(xcwm_window_t *window) { - xcb_image_t *image; xcb_flush(window->context->conn); @@ -87,7 +86,7 @@ xcwm_image_copy_damaged(xcwm_window_t *window) /* Get the image of the damaged area of the window */ image = xcb_image_get(window->context->conn, - window->window_id, + window->composite_pixmap_id, window->dmg_bounds->x, window->dmg_bounds->y, window->dmg_bounds->width, diff --git a/src/libxcwm/window.c b/src/libxcwm/window.c index eaa38ce..201584f 100644 --- a/src/libxcwm/window.c +++ b/src/libxcwm/window.c @@ -128,6 +128,7 @@ _xcwm_window_create(xcwm_context_t *context, xcb_window_t new_window, window->bounds->width = geom->width; window->bounds->height = geom->height; window->opacity = ~0; + window->composite_pixmap_id = 0; /* Find an set the parent */ window->parent = _xcwm_get_window_node_by_window_id(parent); @@ -545,14 +546,15 @@ _xcwm_resize_window(xcb_connection_t *conn, xcb_window_t window, int x, int y, int width, int height) { - uint32_t values[] = { x, y, width, height }; + uint32_t values[] = { x, y, width, height, 0 }; xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | - XCB_CONFIG_WINDOW_HEIGHT, + XCB_CONFIG_WINDOW_HEIGHT | + XCB_CONFIG_WINDOW_BORDER_WIDTH, values); xcb_flush(conn); } |