]> git.sur5r.net Git - i3/i3/commitdiff
When assigning children to containers, reset their x window state
authorMichael Stapelberg <michael@stapelberg.de>
Sat, 17 Apr 2010 14:41:20 +0000 (16:41 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 17 Apr 2010 14:41:20 +0000 (16:41 +0200)
include/x.h
src/manage.c
src/x.c

index 85dfc3ce3d1be462368616dcb898de7416b1d7c3..1e564d4fe0ddae1bbe96cd2b774ff6134e9b65eb 100644 (file)
@@ -6,6 +6,7 @@
 #define _X_H
 
 void x_con_init(Con *con);
+void x_reinit(Con *con);
 void x_con_kill(Con *con);
 void x_window_kill(xcb_window_t window);
 void x_draw_decoration(Con *con);
index ce11a2c1a64e1bd87bce3dc3f9ccf3e6c3aae89e..940013e29efb69d0973051b2e696a2647957d7f4 100644 (file)
@@ -110,12 +110,16 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
         goto out;
 
     /* Check if the window is already managed */
-    if (con_by_window_id(window) != NULL)
+    if (con_by_window_id(window) != NULL) {
+        LOG("already managed\n");
         goto out;
+    }
 
     /* Get the initial geometry (position, size, …) */
-    if ((geom = xcb_get_geometry_reply(conn, geomc, 0)) == NULL)
+    if ((geom = xcb_get_geometry_reply(conn, geomc, 0)) == NULL) {
+        LOG("could not get geometry\n");
         goto out;
+    }
 
     LOG("reparenting!\n");
     uint32_t mask = 0;
@@ -159,6 +163,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
         }
     }
     nc->window = cwindow;
+    x_reinit(nc);
 
     xcb_void_cookie_t rcookie = xcb_reparent_window_checked(conn, window, nc->frame, 0, 0);
     if (xcb_request_check(conn, rcookie) != NULL) {
diff --git a/src/x.c b/src/x.c
index 7ba56c6519def260aef753ee3e9cd5623e69f1a5..f73fc8463684f3d47fd1a48a3fe80e08b63dd6e7 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -86,6 +86,25 @@ void x_con_init(Con *con) {
     LOG("adding new state for window id 0x%08x\n", state->id);
 }
 
+/*
+ * Re-initializes the associated X window state for this container. You have
+ * to call this when you assign a client to an empty container to ensure that
+ * its state gets updated correctly.
+ *
+ */
+void x_reinit(Con *con) {
+    struct con_state *state;
+
+    if ((state = state_for_frame(con->frame)) == NULL) {
+        ELOG("window state not found\n");
+        return;
+    }
+
+    LOG("resetting state %p to initial\n", state);
+    state->initial = true;
+    memset(&(state->window_rect), 0, sizeof(Rect));
+}
+
 void x_con_kill(Con *con) {
     con_state *state;
 
@@ -202,8 +221,10 @@ static void x_push_node(Con *con) {
     LOG("Pushing changes for node %p / %s\n", con, con->name);
     state = state_for_frame(con->frame);
 
-    /* map/unmap if map state changed */
-    if (state->mapped != con->mapped) {
+    /* map/unmap if map state changed, also ensure that the child window
+     * is changed if we are mapped *and* in initial state (meaning the
+     * container was empty before, but now got a child) */
+    if (state->mapped != con->mapped || (con->mapped && state->initial)) {
         if (!con->mapped) {
             LOG("unmapping container\n");
             xcb_unmap_window(conn, con->frame);