summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2012-11-03 19:09:50 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-11-21 14:02:38 +0000
commit5eb95b986d7231678886b6c0db565c507c9de903 (patch)
tree31b78c2e21ad0b96263258727fd013b00e49c376
parent5454711a0365522e44c5ad6258e9319898b2c1fc (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.h1
-rw-r--r--src/libxcwm/event_loop.c58
-rw-r--r--src/libxcwm/image.c5
-rw-r--r--src/libxcwm/window.c6
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);
}