]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Override client’s moves/resizes in configure_notify_event
authorMichael Stapelberg <michael+x200@stapelberg.de>
Tue, 3 Mar 2009 00:14:11 +0000 (01:14 +0100)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Tue, 3 Mar 2009 00:14:11 +0000 (01:14 +0100)
include/data.h
src/handlers.c
src/layout.c

index cba4440bd74cc4401dc72c82a656318465903c44..3c308c6b46837c1dccad051825c0c96095c47bbb 100644 (file)
@@ -192,8 +192,10 @@ struct Client {
         /* Backpointer. A client is inside a container */
         Container *container;
 
-        /* x, y, width, height */
+        /* x, y, width, height of the frame */
         Rect rect;
+        /* x, y, width, height of the child (relative to its frame) */
+        Rect child_rect;
 
         /* Height which was determined by reading the _NET_WM_STRUT_PARTIAL top/bottom of the screen
            reservation */
index 9abea18121309d45f7a7cded5d266fb5d7db1396..ebedbccf2c772ec5bd1a0ddf562259e33ce15dc1 100644 (file)
@@ -324,6 +324,30 @@ int handle_map_notify_event(void *prophs, xcb_connection_t *conn, xcb_map_notify
 int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event) {
         printf("handle_configure_event\n");
         ignore_notify_event = event->sequence;
+        printf("event->x = %d, ->y = %d, ->width = %d, ->height = %d\n", event->x, event->y, event->width, event->height);
+        Client *client = table_get(byChild, event->window);
+        if (client == NULL) {
+                printf("client not managed, ignoring\n");
+                return 1;
+        }
+
+        if (client->container->workspace->fullscreen_client == client) {
+                printf("client in fullscreen, not touching\n");
+                return 1;
+        }
+
+        /* Let’s see if the application has changed size/position on its own *sigh*… */
+        if ((event->x != client->child_rect.x) ||
+            (event->y != client->child_rect.y) ||
+            (event->width != client->child_rect.width) ||
+            (event->height != client->child_rect.height)) {
+                /* Who is your window manager? Who’s that, huh? I AM YOUR WINDOW MANAGER! */
+                printf("Application wanted to resize itself. Fixed that.\n");
+                client->force_reconfigure = true;
+                render_container(conn, client->container);
+                xcb_flush(conn);
+        }
+
         return 1;
 }
 
index a47fef115bcd1c64878067a238cba6a6f11dc6d8..5019552404cb147d2d5f360303ec5083d7583ba8 100644 (file)
@@ -164,32 +164,52 @@ static void resize_client(xcb_connection_t *connection, Client *client) {
                         XCB_CONFIG_WINDOW_Y |
                         XCB_CONFIG_WINDOW_WIDTH |
                         XCB_CONFIG_WINDOW_HEIGHT;
-        Rect rect;
+        Rect *rect = &(client->child_rect);
         switch (client->container->mode) {
                 case MODE_STACK:
-                        rect.x = 2;
-                        rect.y = 0;
-                        rect.width = client->rect.width - (2 + 2);
-                        rect.height = client->rect.height - 2;
+                        rect->x = 2;
+                        rect->y = 0;
+                        rect->width = client->rect.width - (2 + 2);
+                        rect->height = client->rect.height - 2;
                         break;
                 default:
                         if (client->titlebar_position == TITLEBAR_OFF) {
-                                rect.x = 0;
-                                rect.y = 0;
-                                rect.width = client->rect.width;
-                                rect.height = client->rect.height;
+                                rect->x = 0;
+                                rect->y = 0;
+                                rect->width = client->rect.width;
+                                rect->height = client->rect.height;
                         } else {
-                                rect.x = 2;
-                                rect.y = font->height + 2 + 2;
-                                rect.width = client->rect.width - (2 + 2);
-                                rect.height = client->rect.height - ((font->height + 2 + 2) + 2);
+                                rect->x = 2;
+                                rect->y = font->height + 2 + 2;
+                                rect->width = client->rect.width - (2 + 2);
+                                rect->height = client->rect.height - ((font->height + 2 + 2) + 2);
                         }
                         break;
         }
 
-        printf("child will be at %dx%d with size %dx%d\n", rect.x, rect.y, rect.width, rect.height);
+        printf("child will be at %dx%d with size %dx%d\n", rect->x, rect->y, rect->width, rect->height);
 
-        xcb_configure_window(connection, client->child, mask, &(rect.x));
+        xcb_configure_window(connection, client->child, mask, &(rect->x));
+
+        /* After configuring a child window we need to fake a configure_notify_event according
+           to ICCCM 4.2.3. This seems rather broken, especially since X sends exactly the same
+           configure_notify_event automatically according to xtrace. Anyone knows details? */
+        xcb_configure_notify_event_t event;
+
+        event.event = client->child;
+        event.window = client->child;
+        event.response_type = XCB_CONFIGURE_NOTIFY;
+
+        event.x = rect->x;
+        event.y = rect->y;
+        event.width = rect->width;
+        event.height = rect->height;
+
+        event.border_width = 0;
+        event.above_sibling = XCB_NONE;
+        event.override_redirect = false;
+
+        xcb_send_event(connection, false, client->child, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char*)&event);
 }
 
 /*
@@ -221,15 +241,10 @@ void render_container(xcb_connection_t *connection, Container *container) {
                         /* TODO: vertical default layout */
                         if (client->force_reconfigure |
                             HAS_CHANGED(client->rect.width, container->width) |
-                            HAS_CHANGED(client->rect.height, container->height / num_clients)) {
+                            HAS_CHANGED(client->rect.height, container->height / num_clients))
                                 resize_client(connection, client);
-                        } else printf("no reconfigure necessary\n");
-                        printf("after client->rect.width = %d, client->rect.height = %d\n", client->rect.width,
-                                        client->rect.height);
-
 
-                        if (client->force_reconfigure)
-                                client->force_reconfigure = false;
+                        client->force_reconfigure = false;
 
                         current_client++;
                 }