]> git.sur5r.net Git - i3/i3/commitdiff
implement configure requests, adapt testcase
authorMichael Stapelberg <michael@stapelberg.de>
Fri, 12 Nov 2010 20:41:10 +0000 (21:41 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Fri, 12 Nov 2010 20:41:10 +0000 (21:41 +0100)
testcase does not pass 100% due to clients not being reparented correctly yet.

include/con.h
include/handlers.h
include/util.h
src/con.c
src/handlers.c
src/main.c
src/render.c
src/util.c
testcases/Makefile
testcases/t/04-floating.t
testcases/t/12-floating-resize.t

index fb862150f0b92d209e4ddcd418c7544dc6e75f24..c4c4a270ba982b6ac313072ffa1a140741cbf517 100644 (file)
@@ -129,4 +129,12 @@ int con_orientation(Con *con);
  */
 Con *con_next_focused(Con *con);
 
+/*
+ * Returns a "relative" Rect which contains the amount of pixels that need to
+ * be added to the original Rect to get the final position (obviously the
+ * amount of pixels for normal, 1pixel and borderless are different).
+ *
+ */
+Rect con_border_style_rect(Con *con);
+
 #endif
index b4a9486a22eb609e77d05e521c303e4eed3f8b8f..185320deeb81e5e11c856a79f51c10c5ace3d885 100644 (file)
@@ -79,6 +79,7 @@ int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_n
  */
 int handle_screen_change(void *prophs, xcb_connection_t *conn,
                          xcb_generic_event_t *e);
+#endif
 
 /**
  * Configure requests are received when the application wants to resize
@@ -90,7 +91,7 @@ int handle_screen_change(void *prophs, xcb_connection_t *conn,
  */
 int handle_configure_request(void *prophs, xcb_connection_t *conn,
                              xcb_configure_request_event_t *event);
-#endif
+
 /**
  * Our window decorations were unmapped. That means, the window will be killed
  * now, so we better clean up before.
index cca6985db674fc3192b325041dcf45e5ef1c80cf..8a399d45b0897761a242736b4c4335ddffb02b8a 100644 (file)
@@ -37,6 +37,7 @@ while (0)
 int min(int a, int b);
 int max(int a, int b);
 bool rect_contains(Rect rect, uint32_t x, uint32_t y);
+Rect rect_add(Rect a, Rect b);
 
 /**
  * Updates *destination with new_value and returns true if it was changed or false
index 4b0b2307dffc75ed929e684df6636df9f5567bd6..02d46db556d0ba13367738f150b4379dd89b3043 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -430,3 +430,20 @@ Con *con_next_focused(Con *con) {
 
     return next;
 }
+
+/*
+ * Returns a "relative" Rect which contains the amount of pixels that need to
+ * be added to the original Rect to get the final position (obviously the
+ * amount of pixels for normal, 1pixel and borderless are different).
+ *
+ */
+Rect con_border_style_rect(Con *con) {
+    if (con->border_style == BS_NORMAL)
+        return (Rect){2, 0, -(2 * 2), -2};
+
+    if (con->border_style == BS_1PIXEL)
+        return (Rect){1, 1, -2, -2};
+
+    if (con->border_style == BS_NONE)
+        return (Rect){0, 0, 0, 0};
+}
index 0e497b042e44c27c81cd5cbe3c0cbbcf6249675e..a339abdf3591352aa286c39760bd53be6d7e2e38 100644 (file)
@@ -274,7 +274,7 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve
     x_push_changes(croot);
     return 1;
 }
-#if 0
+
 /*
  * Configure requests are received when the application wants to resize windows on their own.
  *
@@ -282,108 +282,70 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve
  *
  */
 int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event) {
-        DLOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
-            event->window, event->x, event->y, event->width, event->height);
+    Con *con;
 
-        Client *client = table_get(&by_child, event->window);
-        if (client == NULL) {
-                uint32_t mask = 0;
-                uint32_t values[7];
-                int c = 0;
-#define COPY_MASK_MEMBER(mask_member, event_member) do { \
-                if (event->value_mask & mask_member) { \
-                        mask |= mask_member; \
-                        values[c++] = event->event_member; \
-                } \
-} while (0)
+    DLOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
+        event->window, event->x, event->y, event->width, event->height);
 
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_X, x);
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_Y, y);
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_WIDTH, width);
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_HEIGHT, height);
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_BORDER_WIDTH, border_width);
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_SIBLING, sibling);
-                COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_STACK_MODE, stack_mode);
+    /* For unmanaged windows, we just execute the configure request. As soon as
+     * it gets mapped, we will take over anyways. */
+    if ((con = con_by_window_id(event->window)) == NULL) {
+        DLOG("Configure request for unmanaged window, can do that.\n");
 
-                xcb_configure_window(conn, event->window, mask, values);
-                xcb_flush(conn);
+        uint32_t mask = 0;
+        uint32_t values[7];
+        int c = 0;
+#define COPY_MASK_MEMBER(mask_member, event_member) do { \
+        if (event->value_mask & mask_member) { \
+                mask |= mask_member; \
+                values[c++] = event->event_member; \
+        } \
+} while (0)
 
-                return 1;
-        }
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_X, x);
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_Y, y);
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_WIDTH, width);
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_HEIGHT, height);
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_BORDER_WIDTH, border_width);
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_SIBLING, sibling);
+        COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_STACK_MODE, stack_mode);
 
-        if (client->fullscreen) {
-                DLOG("Client is in fullscreen mode\n");
+        xcb_configure_window(conn, event->window, mask, values);
+        xcb_flush(conn);
 
-                Rect child_rect = client->workspace->rect;
-                child_rect.x = child_rect.y = 0;
-                fake_configure_notify(conn, child_rect, client->child);
+        return 1;
+    }
 
-                return 1;
+    DLOG("Configure request!\n");
+    if (con_is_floating(con) && con_is_leaf(con)) {
+        /* we actually need to apply the size/position changes to the *parent*
+         * container */
+        Rect bsr = con_border_style_rect(con);
+        if (con->border_style == BS_NORMAL)
+            bsr.height -= 17;
+        con = con->parent;
+        DLOG("Container is a floating leaf node, will do that.\n");
+        if (event->value_mask & XCB_CONFIG_WINDOW_X) {
+            con->rect.x = event->x + (-1) * bsr.x;
+            DLOG("proposed x = %d, new x is %d\n", event->x, con->rect.x);
         }
-
-        /* Floating clients can be reconfigured */
-        if (client_is_floating(client)) {
-                i3Font *font = load_font(conn, config.font);
-                int mode = (client->container != NULL ? client->container->mode : MODE_DEFAULT);
-                /* TODO: refactor this code. we need a function to translate
-                 * coordinates of child_rect/rect. */
-
-                if (event->value_mask & XCB_CONFIG_WINDOW_X) {
-                        if (mode == MODE_STACK || mode == MODE_TABBED) {
-                                client->rect.x = event->x - 2;
-                        } else {
-                                if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
-                                        client->rect.x = event->x;
-                                else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
-                                        client->rect.x = event->x - 1;
-                                else client->rect.x = event->x - 2;
-                        }
-                }
-                if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
-                        if (mode == MODE_STACK || mode == MODE_TABBED) {
-                                client->rect.y = event->y - 2;
-                        } else {
-                                if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
-                                        client->rect.y = event->y;
-                                else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
-                                        client->rect.y = event->y - 1;
-                                else client->rect.y = event->y - font->height - 2 - 2;
-                        }
-                }
-                if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
-                        if (mode == MODE_STACK || mode == MODE_TABBED) {
-                                client->rect.width = event->width + 2 + 2;
-                        } else {
-                                if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
-                                        client->rect.width = event->width;
-                                else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
-                                        client->rect.width = event->width + (1 + 1);
-                                else client->rect.width = event->width + (2 + 2);
-                        }
-                }
-                if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
-                        if (mode == MODE_STACK || mode == MODE_TABBED) {
-                                client->rect.height = event->height + 2;
-                        } else {
-                                if (client->titlebar_position == TITLEBAR_OFF && client->borderless)
-                                        client->rect.height = event->height;
-                                else if (client->titlebar_position == TITLEBAR_OFF && !client->borderless)
-                                        client->rect.height = event->height + (1 + 1);
-                                else client->rect.height = event->height + (font->height + 2 + 2) + 2;
-                        }
-                }
-
-                DLOG("Accepted new position/size for floating client: (%d, %d) size %d x %d\n",
-                    client->rect.x, client->rect.y, client->rect.width, client->rect.height);
-
-                /* Push the new position/size to X11 */
-                reposition_client(conn, client);
-                resize_client(conn, client);
-                xcb_flush(conn);
-
-                return 1;
+        if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
+            con->rect.y = event->y + (-1) * bsr.y;
+            DLOG("proposed y = %d, new y is %d\n", event->y, con->rect.y);
+        }
+        if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
+            con->rect.width = event->width + (-1) * bsr.width;
+            DLOG("proposed width = %d, new width is %d\n", event->width, con->rect.width);
+        }
+        if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
+            con->rect.height = event->height + (-1) * bsr.height;
+            DLOG("proposed height = %d, new height is %d\n", event->height, con->rect.height);
         }
+        tree_render();
+    }
 
+    return 1;
+#if 0
         /* Dock clients can be reconfigured in their height */
         if (client->dock) {
                 DLOG("Reconfiguring height of this dock client\n");
@@ -413,7 +375,9 @@ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure
         fake_absolute_configure_notify(conn, client);
 
         return 1;
+#endif
 }
+#if 0
 
 /*
  * Configuration notifies are only handled because we need to set up ignore for
index a0eb91922ca820bef9137c338d9e3ceaae1ff210..417c2b27d881713e9005150bffc500aef987ebe5 100644 (file)
@@ -218,6 +218,9 @@ int main(int argc, char *argv[]) {
        for us is _NET_WM_STATE, we honour _NET_WM_STATE_FULLSCREEN */
     xcb_event_set_client_message_handler(&evenths, handle_client_message, NULL);
 
+    /* Configure request = window tried to change size on its own */
+    xcb_event_set_configure_request_handler(&evenths, handle_configure_request, NULL);
+
     /* Setup NetWM atoms */
     #define GET_ATOM(name) \
         do { \
index 469ceaa891ea75b8ef3d8d1b268094ebea5799bf..523b9188ac26ed08681baeb295e01db451ab70d3 100644 (file)
@@ -51,12 +51,8 @@ void render_con(Con *con) {
         /* depending on the border style, the rect of the child window
          * needs to be smaller */
         Rect *inset = &(con->window_rect);
-
-        if (con->border_style == BS_NORMAL)
-            *inset = (Rect){2, 0, con->rect.width - (2 * 2), con->rect.height - 2};
-        else if (con->border_style == BS_1PIXEL)
-            *inset = (Rect){1, 1, con->rect.width - 2, con->rect.height - 1};
-        else *inset = (Rect){0, 0, con->rect.width, con->rect.height};
+        *inset = (Rect){0, 0, con->rect.width, con->rect.height};
+        *inset = rect_add(*inset, con_border_style_rect(con));
 
         /* Obey the aspect ratio, if any */
         if (con->proportional_height != 0 &&
index c8f4ee389492962b8817b8be39737dcbed20362a..fc3ada5fdfa1b66a18625bab3501866b489e71de 100644 (file)
@@ -38,6 +38,13 @@ bool rect_contains(Rect rect, uint32_t x, uint32_t y) {
                 y <= (rect.y + rect.height));
 }
 
+Rect rect_add(Rect a, Rect b) {
+        return (Rect){a.x + b.x,
+                      a.y + b.y,
+                      a.width + b.width,
+                      a.height + b.height};
+}
+
 /*
  * Updates *destination with new_value and returns true if it was changed or false
  * if it was the same
index 06a7cfa13a2d94a99cc3e56e1ac8cec741d9a481..6d7898b856bd9b5841d555a90115c74f784a4f92 100644 (file)
@@ -1,5 +1,5 @@
 test:
-       PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1)" -It/lib t/34*.t
+       PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1)" -It/lib t/12*.t
 
 all: test
 
index 9607b2e2d7c7921c257dac4b4e3e2305b85d752f..d16fa8b73834c4e6d7541d8dd38e59629aa87f18 100644 (file)
@@ -1,7 +1,7 @@
 #!perl
 # vim:ts=4:sw=4:expandtab
 
-use i3test tests => 10;
+use i3test tests => 11;
 use X11::XCB qw(:all);
 use Time::HiRes qw(sleep);
 
@@ -29,8 +29,8 @@ sleep(0.25);
 my ($absolute, $top) = $window->rect;
 
 ok($window->mapped, 'Window is mapped');
-ok($absolute->{width} >= 75, 'i3 raised the width to 75');
-ok($absolute->{height} >= 50, 'i3 raised the height to 50');
+cmp_ok($absolute->{width}, '>=', 75, 'i3 raised the width to 75');
+cmp_ok($absolute->{height}, '>=', 50, 'i3 raised the height to 50');
 
 ok($absolute->{x} != 0 && $absolute->{y} != 0, 'i3 did not map it to (0x0)');
 
@@ -51,10 +51,11 @@ sleep(0.25);
 
 ($absolute, $top) = $window->rect;
 
-ok($absolute->{width} == 80, "i3 let the width at 80");
-ok($absolute->{height} == 90, "i3 let the height at 90");
+cmp_ok($absolute->{width}, '==', 80, "i3 let the width at 80");
+cmp_ok($absolute->{height}, '==', 90, "i3 let the height at 90");
 
-ok($top->{x} == 1 && $top->{y} == 1, "i3 mapped it to (1,1)");
+cmp_ok($top->{x}, '==', 1, 'i3 mapped it to x=1');
+cmp_ok($top->{y}, '==', 1, 'i3 mapped it to y=1');
 
 $window->unmap;
 
index a5fb3c573af6a4b64a49e77439c3a0d02cead42d..42ca43c097efcc695765de3a7bb300a3a4212e86 100644 (file)
@@ -12,9 +12,6 @@ BEGIN {
     use_ok('X11::XCB::Connection') or BAIL_OUT('Cannot load X11::XCB::Connection');
 }
 
-SKIP: {
-    skip "border styles not yet implemented", 14;
-
 my $x = X11::XCB::Connection->new;
 
 my $i3 = i3("/tmp/nestedcons");
@@ -31,7 +28,7 @@ my $window = $x->root->create_child(
     rect => [ 0, 0, 30, 30],
     background_color => '#C0C0C0',
     # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
+    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
 );
 
 isa_ok($window, 'X11::XCB::Window');
@@ -70,13 +67,11 @@ sub test_resize {
 test_resize;
 
 # Test borderless
-$i3->command('bb')->recv;
+$i3->command('border none')->recv;
 
 test_resize;
 
 # Test with 1-px-border
-$i3->command('bp')->recv;
+$i3->command('border 1pixel')->recv;
 
 test_resize;
-
-}