[PATCH libxcwm 12/15] Adopt existing windows at startup

Jon TURNEY jon.turney at dronecode.org.uk
Mon Nov 5 14:50:13 PST 2012


The helps when testing changes to a libxcwm-based WM, as you don't need to
restart the clients to see the effect.

Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
---
 src/libxcwm/event_loop.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/src/libxcwm/event_loop.c b/src/libxcwm/event_loop.c
index d6f3bc2..6bf6db1 100644
--- a/src/libxcwm/event_loop.c
+++ b/src/libxcwm/event_loop.c
@@ -102,6 +102,60 @@ _xcwm_event_stop_loop(void)
     return 1;
 }
 
+/*
+  Generate a XCWM_EVENT_WINDOW_CREATE event for all
+  existing mapped top-level windows when we start
+*/
+static void
+_xcwm_windows_adopt(xcwm_context_t *context, xcwm_event_cb_t callback_ptr)
+{
+    xcb_query_tree_cookie_t tree_cookie = xcb_query_tree(context->conn, context->root_window->window_id);
+    xcb_query_tree_reply_t *reply = xcb_query_tree_reply(context->conn, tree_cookie, NULL);
+    if (NULL == reply) {
+        return;
+    }
+
+    int len = xcb_query_tree_children_length(reply);
+    xcb_window_t *children = xcb_query_tree_children(reply);
+
+    int i;
+    for (i = 0; i < len; i ++) {
+        xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(context->conn, children[i]);
+        xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(context->conn, cookie, NULL);
+
+        if (!attr) {
+            fprintf(stderr, "Couldn't get attributes for window 0x%08x\n", children[i]);
+            continue;
+        }
+
+        if (attr->map_state == XCB_MAP_STATE_VIEWABLE) {
+            printf("window 0x%08x viewable\n", children[i]);
+
+            xcwm_window_t *window = _xcwm_window_create(context, children[i], context->root_window->window_id);
+            if (!window) {
+                continue;
+            }
+
+            xcwm_event_t *return_evt = malloc(sizeof(xcwm_event_t));
+            if (!return_evt) {
+                continue;
+            }
+
+            return_evt->window = window;
+            return_evt->event_type = XCWM_EVENT_WINDOW_CREATE;
+
+            callback_ptr(return_evt);
+        }
+        else {
+            printf("window 0x%08x non-viewable\n", children[i]);
+        }
+
+        free(attr);
+    }
+
+    free(reply);
+}
+
 void *
 run_event_loop(void *thread_arg_struct)
 {
@@ -119,6 +173,8 @@ run_event_loop(void *thread_arg_struct)
 
     free(thread_arg_struct);
 
+    _xcwm_windows_adopt(context, callback_ptr);
+
     /* Start the event loop, and flush if first */
     xcb_flush(event_conn);
 
-- 
1.7.9



More information about the xorg-devel mailing list